diff --git a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/EBSDSegmentFeaturesFilter.cpp b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/EBSDSegmentFeaturesFilter.cpp index 3544ee0b37..9980f2927e 100644 --- a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/EBSDSegmentFeaturesFilter.cpp +++ b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/EBSDSegmentFeaturesFilter.cpp @@ -64,7 +64,7 @@ Parameters EBSDSegmentFeaturesFilter::parameters() const params.insertSeparator(Parameters::Separator{"Input Parameter(s)"}); params.insert(std::make_unique(k_MisorientationTolerance_Key, "Misorientation Tolerance (Degrees)", "Tolerance (in degrees) used to determine if neighboring Cells belong to the same Feature", 5.0f)); - params.insert(std::make_unique(k_RandomizeFeatureIds_Key, "Randomize Feature IDs", "Specifies if feature IDs should be randomized during calculations", false)); + params.insert(std::make_unique(k_RandomizeFeatureIds_Key, "Randomize Feature Ids", "Specifies if feature IDs should be randomized during calculations", false)); params.insert(std::make_unique(k_NeighborScheme_Key, "Neighbor Scheme", "How many neighbors to use", segment_features::k_6NeighborIndex, segment_features::k_OperationChoices)); params.insertSeparator(Parameters::Separator{"Optional Data Mask"}); diff --git a/src/Plugins/OrientationAnalysis/test/CAxisSegmentFeaturesTest.cpp b/src/Plugins/OrientationAnalysis/test/CAxisSegmentFeaturesTest.cpp index f4e58e7d07..09eac1a513 100644 --- a/src/Plugins/OrientationAnalysis/test/CAxisSegmentFeaturesTest.cpp +++ b/src/Plugins/OrientationAnalysis/test/CAxisSegmentFeaturesTest.cpp @@ -1,110 +1,262 @@ #include -#include "simplnx/UnitTest/UnitTestCommon.hpp" - #include "OrientationAnalysis/Filters/CAxisSegmentFeaturesFilter.hpp" #include "OrientationAnalysis/OrientationAnalysis_test_dirs.hpp" +#include "OrientationAnalysisTestUtils.hpp" + +#include "simplnx/Core/Application.hpp" +#include "simplnx/Parameters/ArrayCreationParameter.hpp" +#include "simplnx/Parameters/Dream3dImportParameter.hpp" +#include "simplnx/Parameters/GeometrySelectionParameter.hpp" +#include "simplnx/UnitTest/UnitTestCommon.hpp" #include namespace fs = std::filesystem; using namespace nx::core; using namespace nx::core::Constants; +namespace caxis_segment_features_constants +{ +inline constexpr StringLiteral k_InputGeometryName = "DataContainer"; +inline const DataPath k_InputGeometryPath({k_InputGeometryName}); +inline constexpr StringLiteral k_CellDataName = "CellData"; +inline constexpr StringLiteral k_EnsembleName = "CellEnsembleData"; +inline const DataPath k_QuatsArrayPath = k_InputGeometryPath.createChildPath(k_CellDataName).createChildPath("Quats"); +inline const DataPath k_PhasesArrayPath = k_InputGeometryPath.createChildPath(k_CellDataName).createChildPath("Phases"); +inline const DataPath k_MaskArrayPath = k_InputGeometryPath.createChildPath(k_CellDataName).createChildPath("Mask (Y Pos)"); + +inline const DataPath k_CrystalStructuresArrayPath = k_InputGeometryPath.createChildPath(k_EnsembleName).createChildPath("CrystalStructures"); + +inline const DataPath k_ActivesArrayPath = k_InputGeometryPath.createChildPath(k_Grain_Data).createChildPath(k_ActiveName); -namespace +inline const DataPath k_FeatureIdsArrayPath = k_InputGeometryPath.createChildPath(k_CellDataName).createChildPath(k_FeatureIds); + +inline const DataPath k_FeatureIdsFacePath = k_InputGeometryPath.createChildPath(k_CellDataName).createChildPath("CAxis_FeatureIds_Face"); +inline const DataPath k_FeatureIdsAllPath = k_InputGeometryPath.createChildPath(k_CellDataName).createChildPath("CAxis_FeatureIds_All"); +inline const DataPath k_FeatureIdsMaskFacePath = k_InputGeometryPath.createChildPath(k_CellDataName).createChildPath("CAxis_FeatureIds_Mask_Face"); +inline const DataPath k_FeatureIdsMaskAllPath = k_InputGeometryPath.createChildPath(k_CellDataName).createChildPath("CAxis_FeatureIds_Mask_All"); +} // namespace caxis_segment_features_constants + +TEST_CASE("OrientationAnalysis::CAxisSegmentFeatures:Face", "[OrientationAnalysis][CAxisSegmentFeatures]") { -const std::string k_ComputedFeatureIds = "NX_FeatureIds"; -const std::string k_ComputedCellFeatureData = "NX_CellFeatureData"; -} // namespace + const nx::core::UnitTest::TestFileSentinel testDataSentinel(nx::core::unit_test::k_CMakeExecutable, nx::core::unit_test::k_TestFilesDir, "segment_features_test_data.tar.gz", + "segment_features_test_data"); + // Read Exemplar DREAM3D File Filter + auto exemplarFilePath = fs::path(fmt::format("{}/segment_features_test_data/segment_features_test_data.dream3d", unit_test::k_TestFilesDir)); + DataStructure dataStructure = UnitTest::LoadDataStructure(exemplarFilePath); + + // EBSD Segment Features/Semgent Features (Misorientation) Filter + { + CAxisSegmentFeaturesFilter filter; + Arguments args; + + // Create default Parameters for the filter. + args.insertOrAssign(CAxisSegmentFeaturesFilter::k_MisorientationTolerance_Key, std::make_any(5.0F)); + args.insertOrAssign(CAxisSegmentFeaturesFilter::k_NeighborScheme_Key, std::make_any(0)); + + args.insertOrAssign(CAxisSegmentFeaturesFilter::k_UseMask_Key, std::make_any(false)); + args.insertOrAssign(CAxisSegmentFeaturesFilter::k_MaskArrayPath_Key, std::make_any(caxis_segment_features_constants::k_MaskArrayPath)); + + args.insertOrAssign(CAxisSegmentFeaturesFilter::k_SelectedImageGeometryPath_Key, std::make_any(caxis_segment_features_constants::k_InputGeometryPath)); + args.insertOrAssign(CAxisSegmentFeaturesFilter::k_QuatsArrayPath_Key, std::make_any(caxis_segment_features_constants::k_QuatsArrayPath)); + args.insertOrAssign(CAxisSegmentFeaturesFilter::k_CellPhasesArrayPath_Key, std::make_any(caxis_segment_features_constants::k_PhasesArrayPath)); + args.insertOrAssign(CAxisSegmentFeaturesFilter::k_CrystalStructuresArrayPath_Key, std::make_any(caxis_segment_features_constants::k_CrystalStructuresArrayPath)); + + args.insertOrAssign(CAxisSegmentFeaturesFilter::k_FeatureIdsArrayName_Key, std::make_any(k_FeatureIds)); + args.insertOrAssign(CAxisSegmentFeaturesFilter::k_CellFeatureAttributeMatrixName_Key, std::make_any(k_Grain_Data)); + args.insertOrAssign(CAxisSegmentFeaturesFilter::k_ActiveArrayName_Key, std::make_any(k_ActiveName)); + args.insertOrAssign(CAxisSegmentFeaturesFilter::k_RandomizeFeatureIds_Key, std::make_any(false)); + + // Preflight the filter and check result + auto preflightResult = filter.preflight(dataStructure, args); + SIMPLNX_RESULT_REQUIRE_VALID(preflightResult.outputActions); + + // Execute the filter and check the result + auto executeResult = filter.execute(dataStructure, args); + SIMPLNX_RESULT_REQUIRE_VALID(executeResult.result); + } + + { + UInt8Array& actives = dataStructure.getDataRefAs(caxis_segment_features_constants::k_ActivesArrayPath); + size_t numFeatures = actives.getNumberOfTuples(); + REQUIRE(numFeatures == 57); + } + + // Loop and compare each array from the 'Exemplar Data / CellData' to the 'Data Container / CellData' group + { + const auto& generatedDataArray = dataStructure.getDataRefAs(caxis_segment_features_constants::k_FeatureIdsArrayPath); + const auto& exemplarDataArray = dataStructure.getDataRefAs(caxis_segment_features_constants::k_FeatureIdsFacePath); + + UnitTest::CompareDataArrays(generatedDataArray, exemplarDataArray); + } -TEST_CASE("OrientationAnalysis::CAxisSegmentFeaturesFilter: Valid Filter Execution", "[OrientationAnalysis][CAxisSegmentFeaturesFilter]") + UnitTest::CheckArraysInheritTupleDims(dataStructure, SmallIn100::k_TupleCheckIgnoredPaths); +} + +TEST_CASE("OrientationAnalysis::CAxisSegmentFeatures:All", "[OrientationAnalysis][CAxisSegmentFeatures]") { - UnitTest::LoadPlugins(); - const nx::core::UnitTest::TestFileSentinel testDataSentinel(nx::core::unit_test::k_CMakeExecutable, nx::core::unit_test::k_TestFilesDir, "caxis_data.tar.gz", "caxis_data"); + const nx::core::UnitTest::TestFileSentinel testDataSentinel(nx::core::unit_test::k_CMakeExecutable, nx::core::unit_test::k_TestFilesDir, "segment_features_test_data.tar.gz", + "segment_features_test_data"); + // Read Exemplar DREAM3D File Filter + auto exemplarFilePath = fs::path(fmt::format("{}/segment_features_test_data/segment_features_test_data.dream3d", unit_test::k_TestFilesDir)); + DataStructure dataStructure = UnitTest::LoadDataStructure(exemplarFilePath); + + // EBSD Segment Features/Semgent Features (Misorientation) Filter + { + CAxisSegmentFeaturesFilter filter; + Arguments args; + + // Create default Parameters for the filter. + args.insertOrAssign(CAxisSegmentFeaturesFilter::k_MisorientationTolerance_Key, std::make_any(5.0F)); + args.insertOrAssign(CAxisSegmentFeaturesFilter::k_NeighborScheme_Key, std::make_any(1)); + + args.insertOrAssign(CAxisSegmentFeaturesFilter::k_UseMask_Key, std::make_any(false)); + args.insertOrAssign(CAxisSegmentFeaturesFilter::k_MaskArrayPath_Key, std::make_any(caxis_segment_features_constants::k_MaskArrayPath)); + + args.insertOrAssign(CAxisSegmentFeaturesFilter::k_SelectedImageGeometryPath_Key, std::make_any(caxis_segment_features_constants::k_InputGeometryPath)); + args.insertOrAssign(CAxisSegmentFeaturesFilter::k_QuatsArrayPath_Key, std::make_any(caxis_segment_features_constants::k_QuatsArrayPath)); + args.insertOrAssign(CAxisSegmentFeaturesFilter::k_CellPhasesArrayPath_Key, std::make_any(caxis_segment_features_constants::k_PhasesArrayPath)); + args.insertOrAssign(CAxisSegmentFeaturesFilter::k_CrystalStructuresArrayPath_Key, std::make_any(caxis_segment_features_constants::k_CrystalStructuresArrayPath)); + + args.insertOrAssign(CAxisSegmentFeaturesFilter::k_FeatureIdsArrayName_Key, std::make_any(k_FeatureIds)); + args.insertOrAssign(CAxisSegmentFeaturesFilter::k_CellFeatureAttributeMatrixName_Key, std::make_any(k_Grain_Data)); + args.insertOrAssign(CAxisSegmentFeaturesFilter::k_ActiveArrayName_Key, std::make_any(k_ActiveName)); + args.insertOrAssign(CAxisSegmentFeaturesFilter::k_RandomizeFeatureIds_Key, std::make_any(false)); + + // Preflight the filter and check result + auto preflightResult = filter.preflight(dataStructure, args); + SIMPLNX_RESULT_REQUIRE_VALID(preflightResult.outputActions); + + // Execute the filter and check the result + auto executeResult = filter.execute(dataStructure, args); + SIMPLNX_RESULT_REQUIRE_VALID(executeResult.result); + } + + { + UInt8Array& actives = dataStructure.getDataRefAs(caxis_segment_features_constants::k_ActivesArrayPath); + size_t numFeatures = actives.getNumberOfTuples(); + REQUIRE(numFeatures == 37); + } + // Loop and compare each array from the 'Exemplar Data / CellData' to the 'Data Container / CellData' group + { + const auto& generatedDataArray = dataStructure.getDataRefAs(caxis_segment_features_constants::k_FeatureIdsArrayPath); + const auto& exemplarDataArray = dataStructure.getDataRefAs(caxis_segment_features_constants::k_FeatureIdsAllPath); + + UnitTest::CompareDataArrays(generatedDataArray, exemplarDataArray); + } + + UnitTest::CheckArraysInheritTupleDims(dataStructure, SmallIn100::k_TupleCheckIgnoredPaths); +} + +TEST_CASE("OrientationAnalysis::CAxisSegmentFeatures:MaskFace", "[OrientationAnalysis][CAxisSegmentFeatures]") +{ + const nx::core::UnitTest::TestFileSentinel testDataSentinel(nx::core::unit_test::k_CMakeExecutable, nx::core::unit_test::k_TestFilesDir, "segment_features_test_data.tar.gz", + "segment_features_test_data"); // Read Exemplar DREAM3D File Filter - auto exemplarFilePath = fs::path(fmt::format("{}/caxis_data/6_6_caxis_segment_features.dream3d", unit_test::k_TestFilesDir)); + auto exemplarFilePath = fs::path(fmt::format("{}/segment_features_test_data/segment_features_test_data.dream3d", unit_test::k_TestFilesDir)); DataStructure dataStructure = UnitTest::LoadDataStructure(exemplarFilePath); - // CAxis Segment Features Filter + // EBSD Segment Features/Semgent Features (Misorientation) Filter { - // Instantiate the filter, a DataStructure object and an Arguments Object CAxisSegmentFeaturesFilter filter; Arguments args; // Create default Parameters for the filter. - args.insertOrAssign(CAxisSegmentFeaturesFilter::k_SelectedImageGeometryPath_Key, std::make_any(k_DataContainerPath)); - args.insertOrAssign(CAxisSegmentFeaturesFilter::k_MisorientationTolerance_Key, std::make_any(5.0f)); + args.insertOrAssign(CAxisSegmentFeaturesFilter::k_MisorientationTolerance_Key, std::make_any(5.0F)); + args.insertOrAssign(CAxisSegmentFeaturesFilter::k_NeighborScheme_Key, std::make_any(0)); + args.insertOrAssign(CAxisSegmentFeaturesFilter::k_UseMask_Key, std::make_any(true)); - args.insertOrAssign(CAxisSegmentFeaturesFilter::k_RandomizeFeatureIds_Key, std::make_any(false)); - args.insertOrAssign(CAxisSegmentFeaturesFilter::k_QuatsArrayPath_Key, std::make_any(k_QuatsArrayPath)); - args.insertOrAssign(CAxisSegmentFeaturesFilter::k_CellPhasesArrayPath_Key, std::make_any(k_PhasesArrayPath)); - args.insertOrAssign(CAxisSegmentFeaturesFilter::k_MaskArrayPath_Key, std::make_any(k_MaskArrayPath)); - args.insertOrAssign(CAxisSegmentFeaturesFilter::k_CrystalStructuresArrayPath_Key, std::make_any(k_CrystalStructuresArrayPath)); - args.insertOrAssign(CAxisSegmentFeaturesFilter::k_FeatureIdsArrayName_Key, std::make_any(k_ComputedFeatureIds)); - args.insertOrAssign(CAxisSegmentFeaturesFilter::k_CellFeatureAttributeMatrixName_Key, std::make_any(k_ComputedCellFeatureData)); + args.insertOrAssign(CAxisSegmentFeaturesFilter::k_MaskArrayPath_Key, std::make_any(caxis_segment_features_constants::k_MaskArrayPath)); + + args.insertOrAssign(CAxisSegmentFeaturesFilter::k_SelectedImageGeometryPath_Key, std::make_any(caxis_segment_features_constants::k_InputGeometryPath)); + args.insertOrAssign(CAxisSegmentFeaturesFilter::k_QuatsArrayPath_Key, std::make_any(caxis_segment_features_constants::k_QuatsArrayPath)); + args.insertOrAssign(CAxisSegmentFeaturesFilter::k_CellPhasesArrayPath_Key, std::make_any(caxis_segment_features_constants::k_PhasesArrayPath)); + args.insertOrAssign(CAxisSegmentFeaturesFilter::k_CrystalStructuresArrayPath_Key, std::make_any(caxis_segment_features_constants::k_CrystalStructuresArrayPath)); + + args.insertOrAssign(CAxisSegmentFeaturesFilter::k_FeatureIdsArrayName_Key, std::make_any(k_FeatureIds)); + args.insertOrAssign(CAxisSegmentFeaturesFilter::k_CellFeatureAttributeMatrixName_Key, std::make_any(k_Grain_Data)); args.insertOrAssign(CAxisSegmentFeaturesFilter::k_ActiveArrayName_Key, std::make_any(k_ActiveName)); + args.insertOrAssign(CAxisSegmentFeaturesFilter::k_RandomizeFeatureIds_Key, std::make_any(false)); // Preflight the filter and check result auto preflightResult = filter.preflight(dataStructure, args); - SIMPLNX_RESULT_REQUIRE_VALID(preflightResult.outputActions) + SIMPLNX_RESULT_REQUIRE_VALID(preflightResult.outputActions); // Execute the filter and check the result auto executeResult = filter.execute(dataStructure, args); - SIMPLNX_RESULT_REQUIRE_VALID(executeResult.result) + SIMPLNX_RESULT_REQUIRE_VALID(executeResult.result); } + { - DataPath activeArrayDataPath = k_DataContainerPath.createChildPath(k_ComputedCellFeatureData).createChildPath(k_ActiveName); - UInt8Array& actives = dataStructure.getDataRefAs(activeArrayDataPath); + UInt8Array& actives = dataStructure.getDataRefAs(caxis_segment_features_constants::k_ActivesArrayPath); size_t numFeatures = actives.getNumberOfTuples(); - REQUIRE(numFeatures == 31229); + REQUIRE(numFeatures == 31); } // Loop and compare each array from the 'Exemplar Data / CellData' to the 'Data Container / CellData' group { - const auto& generatedFeatureIds = dataStructure.getDataRefAs(k_CellAttributeMatrix.createChildPath(k_ComputedFeatureIds)); - const auto& exemplarFeatureIds = dataStructure.getDataRefAs(k_FeatureIdsArrayPath); - UnitTest::CompareDataArrays(generatedFeatureIds, exemplarFeatureIds); + const auto& generatedDataArray = dataStructure.getDataRefAs(caxis_segment_features_constants::k_FeatureIdsArrayPath); + const auto& exemplarDataArray = dataStructure.getDataRefAs(caxis_segment_features_constants::k_FeatureIdsMaskFacePath); + + UnitTest::CompareDataArrays(generatedDataArray, exemplarDataArray); } - UnitTest::CheckArraysInheritTupleDims(dataStructure); + UnitTest::CheckArraysInheritTupleDims(dataStructure, SmallIn100::k_TupleCheckIgnoredPaths); } -TEST_CASE("OrientationAnalysis::CAxisSegmentFeaturesFilter: Invalid Filter Execution", "[OrientationAnalysis][CAxisSegmentFeaturesFilter]") +TEST_CASE("OrientationAnalysis::CAxisSegmentFeatures:MaskAll", "[OrientationAnalysis][CAxisSegmentFeatures]") { - UnitTest::LoadPlugins(); - const nx::core::UnitTest::TestFileSentinel testDataSentinel(nx::core::unit_test::k_CMakeExecutable, nx::core::unit_test::k_TestFilesDir, "caxis_data.tar.gz", "caxis_data"); - + const nx::core::UnitTest::TestFileSentinel testDataSentinel(nx::core::unit_test::k_CMakeExecutable, nx::core::unit_test::k_TestFilesDir, "segment_features_test_data.tar.gz", + "segment_features_test_data"); // Read Exemplar DREAM3D File Filter - auto exemplarFilePath = fs::path(fmt::format("{}/caxis_data/7_0_find_caxis_data.dream3d", unit_test::k_TestFilesDir)); + auto exemplarFilePath = fs::path(fmt::format("{}/segment_features_test_data/segment_features_test_data.dream3d", unit_test::k_TestFilesDir)); DataStructure dataStructure = UnitTest::LoadDataStructure(exemplarFilePath); - auto& crystalStructs = dataStructure.getDataRefAs(k_CrystalStructuresArrayPath); - crystalStructs[1] = 1; - - // Instantiate the filter, a DataStructure object and an Arguments Object - CAxisSegmentFeaturesFilter filter; - Arguments args; - - // Invalid crystal structure type : should fail in execute - args.insertOrAssign(CAxisSegmentFeaturesFilter::k_SelectedImageGeometryPath_Key, std::make_any(k_DataContainerPath)); - args.insertOrAssign(CAxisSegmentFeaturesFilter::k_MisorientationTolerance_Key, std::make_any(5.0f)); - args.insertOrAssign(CAxisSegmentFeaturesFilter::k_UseMask_Key, std::make_any(false)); - args.insertOrAssign(CAxisSegmentFeaturesFilter::k_RandomizeFeatureIds_Key, std::make_any(false)); - args.insertOrAssign(CAxisSegmentFeaturesFilter::k_QuatsArrayPath_Key, std::make_any(k_QuatsArrayPath)); - args.insertOrAssign(CAxisSegmentFeaturesFilter::k_CellPhasesArrayPath_Key, std::make_any(k_PhasesArrayPath)); - args.insertOrAssign(CAxisSegmentFeaturesFilter::k_CrystalStructuresArrayPath_Key, std::make_any(k_CrystalStructuresArrayPath)); - args.insertOrAssign(CAxisSegmentFeaturesFilter::k_FeatureIdsArrayName_Key, std::make_any(k_ComputedFeatureIds)); - args.insertOrAssign(CAxisSegmentFeaturesFilter::k_CellFeatureAttributeMatrixName_Key, std::make_any(k_ComputedCellFeatureData)); - args.insertOrAssign(CAxisSegmentFeaturesFilter::k_ActiveArrayName_Key, std::make_any(k_ActiveName)); - - // Preflight the filter and check result - auto preflightResult = filter.preflight(dataStructure, args); - SIMPLNX_RESULT_REQUIRE_VALID(preflightResult.outputActions) - - // Execute the filter and check the result - auto executeResult = filter.execute(dataStructure, args); - SIMPLNX_RESULT_REQUIRE_INVALID(executeResult.result) - - UnitTest::CheckArraysInheritTupleDims(dataStructure); + // EBSD Segment Features/Semgent Features (Misorientation) Filter + { + CAxisSegmentFeaturesFilter filter; + Arguments args; + + // Create default Parameters for the filter. + args.insertOrAssign(CAxisSegmentFeaturesFilter::k_MisorientationTolerance_Key, std::make_any(5.0F)); + args.insertOrAssign(CAxisSegmentFeaturesFilter::k_NeighborScheme_Key, std::make_any(1)); + + args.insertOrAssign(CAxisSegmentFeaturesFilter::k_UseMask_Key, std::make_any(true)); + args.insertOrAssign(CAxisSegmentFeaturesFilter::k_MaskArrayPath_Key, std::make_any(caxis_segment_features_constants::k_MaskArrayPath)); + + args.insertOrAssign(CAxisSegmentFeaturesFilter::k_SelectedImageGeometryPath_Key, std::make_any(caxis_segment_features_constants::k_InputGeometryPath)); + args.insertOrAssign(CAxisSegmentFeaturesFilter::k_QuatsArrayPath_Key, std::make_any(caxis_segment_features_constants::k_QuatsArrayPath)); + args.insertOrAssign(CAxisSegmentFeaturesFilter::k_CellPhasesArrayPath_Key, std::make_any(caxis_segment_features_constants::k_PhasesArrayPath)); + args.insertOrAssign(CAxisSegmentFeaturesFilter::k_CrystalStructuresArrayPath_Key, std::make_any(caxis_segment_features_constants::k_CrystalStructuresArrayPath)); + + args.insertOrAssign(CAxisSegmentFeaturesFilter::k_FeatureIdsArrayName_Key, std::make_any(k_FeatureIds)); + args.insertOrAssign(CAxisSegmentFeaturesFilter::k_CellFeatureAttributeMatrixName_Key, std::make_any(k_Grain_Data)); + args.insertOrAssign(CAxisSegmentFeaturesFilter::k_ActiveArrayName_Key, std::make_any(k_ActiveName)); + args.insertOrAssign(CAxisSegmentFeaturesFilter::k_RandomizeFeatureIds_Key, std::make_any(false)); + + // Preflight the filter and check result + auto preflightResult = filter.preflight(dataStructure, args); + SIMPLNX_RESULT_REQUIRE_VALID(preflightResult.outputActions); + + // Execute the filter and check the result + auto executeResult = filter.execute(dataStructure, args); + SIMPLNX_RESULT_REQUIRE_VALID(executeResult.result); + } + + { + UInt8Array& actives = dataStructure.getDataRefAs(caxis_segment_features_constants::k_ActivesArrayPath); + size_t numFeatures = actives.getNumberOfTuples(); + REQUIRE(numFeatures == 25); + } + + // Loop and compare each array from the 'Exemplar Data / CellData' to the 'Data Container / CellData' group + { + const auto& generatedDataArray = dataStructure.getDataRefAs(caxis_segment_features_constants::k_FeatureIdsArrayPath); + const auto& exemplarDataArray = dataStructure.getDataRefAs(caxis_segment_features_constants::k_FeatureIdsMaskAllPath); + + UnitTest::CompareDataArrays(generatedDataArray, exemplarDataArray); + } + + UnitTest::CheckArraysInheritTupleDims(dataStructure, SmallIn100::k_TupleCheckIgnoredPaths); } diff --git a/src/Plugins/OrientationAnalysis/test/CMakeLists.txt b/src/Plugins/OrientationAnalysis/test/CMakeLists.txt index 179f6a63fb..c66f7d16cc 100644 --- a/src/Plugins/OrientationAnalysis/test/CMakeLists.txt +++ b/src/Plugins/OrientationAnalysis/test/CMakeLists.txt @@ -150,6 +150,7 @@ if(EXISTS "${DREAM3D_DATA_DIR}" AND SIMPLNX_DOWNLOAD_TEST_FILES) download_test_data(DREAM3D_DATA_DIR ${DREAM3D_DATA_DIR} ARCHIVE_NAME neighbor_orientation_correlation.tar.gz SHA512 122367452174ade2f24dde7a4610bddc4f147a223722d9b30c1df9eaa2cd2bf25e1c7957aba83f3f9de79b4eadd79339b848f9530d1ebf44c69244ea5442cf85) download_test_data(DREAM3D_DATA_DIR ${DREAM3D_DATA_DIR} ARCHIVE_NAME PoleFigure_Exemplars_v4.tar.gz SHA512 86235279c61ac40405ec00d74703855aa84f7985114dfe4f7bb14a84a73f59092df3f5c087220ceb62325186dfaa08d843ec86dd0710800e376d95e4047cefbe) download_test_data(DREAM3D_DATA_DIR ${DREAM3D_DATA_DIR} ARCHIVE_NAME read_ang_test.tar.gz SHA512 de7cd89d925da01f291f44686964ec89d469659d0005219f9869afe26b8f62af278461ac3f5deb3afe7f3e65ec074ab3a1357d77a1a5f92eb3a1ea8cc5e4b236) + download_test_data(DREAM3D_DATA_DIR ${DREAM3D_DATA_DIR} ARCHIVE_NAME segment_features_test_data.tar.gz SHA512 317d69384330d40c673f8e1a42df003dede5ac85331b2549e9f45467f7af6b74284f8dad1120427690719ebcd5066830e17031533381cc2cc0cc8622a422b914) download_test_data(DREAM3D_DATA_DIR ${DREAM3D_DATA_DIR} ARCHIVE_NAME Small_IN100_Ang_Files.tar.gz SHA512 79e9f6948d4e8e06187e11216a67596fa786ffd2700e51f594ad014090383eb8bcc003e14de2e88082aa9ae512cc4fc9cee22c80066fc54f38c3ebc75267eb5b) download_test_data(DREAM3D_DATA_DIR ${DREAM3D_DATA_DIR} ARCHIVE_NAME Small_IN100_dream3d_v3.tar.gz SHA512 bfa9547e787b0f8e8122702da0eb4e519f48a48bf4f94aad020f72479d071d32dfc96a1425705874c68507a61ed391d28606d9c4f4acd559043ef0ace64fd33f) download_test_data(DREAM3D_DATA_DIR ${DREAM3D_DATA_DIR} ARCHIVE_NAME Small_IN100_h5ebsd.tar.gz SHA512 31e606285ea9e8235dcb5f608fd2b252a5ab1492abd975e5ec33a21d083aa9720fe16fb8f752742c140f40e963d692f1a46256b9d36e96b1b09796c1e4ea3db9) diff --git a/src/Plugins/OrientationAnalysis/test/EBSDSegmentFeaturesFilterTest.cpp b/src/Plugins/OrientationAnalysis/test/EBSDSegmentFeaturesFilterTest.cpp index 2e5829dcb2..6d6b423d7f 100644 --- a/src/Plugins/OrientationAnalysis/test/EBSDSegmentFeaturesFilterTest.cpp +++ b/src/Plugins/OrientationAnalysis/test/EBSDSegmentFeaturesFilterTest.cpp @@ -10,51 +10,161 @@ #include "simplnx/Parameters/GeometrySelectionParameter.hpp" #include "simplnx/UnitTest/UnitTestCommon.hpp" +#include + #include namespace fs = std::filesystem; using namespace nx::core; using namespace nx::core::Constants; -TEST_CASE("OrientationAnalysis::EBSDSegmentFeatures: Valid Execution", "[OrientationAnalysis][EBSDSegmentFeatures]") +namespace ebsd_segment_features_constants +{ +inline constexpr StringLiteral k_InputGeometryName = "DataContainer"; +inline const DataPath k_InputGeometryPath({k_InputGeometryName}); +inline constexpr StringLiteral k_CellDataName = "CellData"; +inline constexpr StringLiteral k_EnsembleName = "CellEnsembleData"; +inline const DataPath k_QuatsArrayPath = k_InputGeometryPath.createChildPath(k_CellDataName).createChildPath("Quats"); +inline const DataPath k_PhasesArrayPath = k_InputGeometryPath.createChildPath(k_CellDataName).createChildPath("Phases"); +inline const DataPath k_MaskArrayPath = k_InputGeometryPath.createChildPath(k_CellDataName).createChildPath("Mask (Y Pos)"); + +inline const DataPath k_CrystalStructuresArrayPath = k_InputGeometryPath.createChildPath(k_EnsembleName).createChildPath("CrystalStructures"); + +inline const DataPath k_ActivesArrayPath = k_InputGeometryPath.createChildPath(k_Grain_Data).createChildPath(k_ActiveName); + +inline const DataPath k_FeatureIdsArrayPath = k_InputGeometryPath.createChildPath(k_CellDataName).createChildPath(k_FeatureIds); + +inline const DataPath k_FeatureIdsFacePath = k_InputGeometryPath.createChildPath(k_CellDataName).createChildPath("Ebsd_FeatureIds_Face"); +inline const DataPath k_FeatureIdsAllPath = k_InputGeometryPath.createChildPath(k_CellDataName).createChildPath("Ebsd_FeatureIds_All"); +inline const DataPath k_FeatureIdsMaskFacePath = k_InputGeometryPath.createChildPath(k_CellDataName).createChildPath("Ebsd_FeatureIds_Mask_Face"); +inline const DataPath k_FeatureIdsMaskAllPath = k_InputGeometryPath.createChildPath(k_CellDataName).createChildPath("Ebsd_FeatureIds_Mask_All"); +} // namespace ebsd_segment_features_constants + +TEST_CASE("OrientationAnalysis::EBSDSegmentFeatures:Face", "[OrientationAnalysis][EBSDSegmentFeatures]") { UnitTest::LoadPlugins(); - const nx::core::UnitTest::TestFileSentinel testDataSentinel(nx::core::unit_test::k_CMakeExecutable, nx::core::unit_test::k_TestFilesDir, "6_6_ebsd_segment_features.tar.gz", - "6_6_ebsd_segment_features.dream3d"); + const nx::core::UnitTest::TestFileSentinel testDataSentinel(nx::core::unit_test::k_CMakeExecutable, nx::core::unit_test::k_TestFilesDir, "segment_features_test_data.tar.gz", + "segment_features_test_data"); + // Read Exemplar DREAM3D File Filter + auto exemplarFilePath = fs::path(fmt::format("{}/segment_features_test_data/segment_features_test_data.dream3d", unit_test::k_TestFilesDir)); + DataStructure dataStructure = UnitTest::LoadDataStructure(exemplarFilePath); + + // EBSD Segment Features/Semgent Features (Misorientation) Filter + { + EBSDSegmentFeaturesFilter filter; + Arguments args; + + // Create default Parameters for the filter. + args.insertOrAssign(EBSDSegmentFeaturesFilter::k_MisorientationTolerance_Key, std::make_any(5.0F)); + args.insertOrAssign(EBSDSegmentFeaturesFilter::k_NeighborScheme_Key, std::make_any(0)); + + args.insertOrAssign(EBSDSegmentFeaturesFilter::k_UseMask_Key, std::make_any(false)); + args.insertOrAssign(EBSDSegmentFeaturesFilter::k_MaskArrayPath_Key, std::make_any(ebsd_segment_features_constants::k_MaskArrayPath)); + + args.insertOrAssign(EBSDSegmentFeaturesFilter::k_SelectedImageGeometryPath_Key, std::make_any(ebsd_segment_features_constants::k_InputGeometryPath)); + args.insertOrAssign(EBSDSegmentFeaturesFilter::k_QuatsArrayPath_Key, std::make_any(ebsd_segment_features_constants::k_QuatsArrayPath)); + args.insertOrAssign(EBSDSegmentFeaturesFilter::k_CellPhasesArrayPath_Key, std::make_any(ebsd_segment_features_constants::k_PhasesArrayPath)); + args.insertOrAssign(EBSDSegmentFeaturesFilter::k_CrystalStructuresArrayPath_Key, std::make_any(ebsd_segment_features_constants::k_CrystalStructuresArrayPath)); + + args.insertOrAssign(EBSDSegmentFeaturesFilter::k_FeatureIdsArrayName_Key, std::make_any(k_FeatureIds)); + args.insertOrAssign(EBSDSegmentFeaturesFilter::k_CellFeatureAttributeMatrixName_Key, std::make_any(k_Grain_Data)); + args.insertOrAssign(EBSDSegmentFeaturesFilter::k_ActiveArrayName_Key, std::make_any(k_ActiveName)); + args.insertOrAssign(EBSDSegmentFeaturesFilter::k_RandomizeFeatureIds_Key, std::make_any(false)); + + // Preflight the filter and check result + auto preflightResult = filter.preflight(dataStructure, args); + SIMPLNX_RESULT_REQUIRE_VALID(preflightResult.outputActions); + + // Execute the filter and check the result + auto executeResult = filter.execute(dataStructure, args); + SIMPLNX_RESULT_REQUIRE_VALID(executeResult.result); + } + + { + UInt8Array& actives = dataStructure.getDataRefAs(ebsd_segment_features_constants::k_ActivesArrayPath); + size_t numFeatures = actives.getNumberOfTuples(); + REQUIRE(numFeatures == 83); + } + + // Loop and compare each array from the 'Exemplar Data / CellData' to the 'Data Container / CellData' group + { + const auto& generatedDataArray = dataStructure.getDataRefAs(ebsd_segment_features_constants::k_FeatureIdsArrayPath); + const auto& exemplarDataArray = dataStructure.getDataRefAs(ebsd_segment_features_constants::k_FeatureIdsFacePath); + + UnitTest::CompareDataArrays(generatedDataArray, exemplarDataArray); + } - const nx::core::UnitTest::TestFileSentinel testDataSentinel1(nx::core::unit_test::k_CMakeExecutable, nx::core::unit_test::k_TestFilesDir, "Small_IN100_dream3d_v3.tar.gz", "Small_IN100.dream3d"); + UnitTest::CheckArraysInheritTupleDims(dataStructure, SmallIn100::k_TupleCheckIgnoredPaths); +} - auto* filterList = Application::Instance()->getFilterList(); +TEST_CASE("OrientationAnalysis::EBSDSegmentFeatures:All", "[OrientationAnalysis][EBSDSegmentFeatures]") +{ + UnitTest::LoadPlugins(); + const nx::core::UnitTest::TestFileSentinel testDataSentinel(nx::core::unit_test::k_CMakeExecutable, nx::core::unit_test::k_TestFilesDir, "segment_features_test_data.tar.gz", + "segment_features_test_data"); // Read Exemplar DREAM3D File Filter - auto exemplarFilePath = fs::path(fmt::format("{}/6_6_ebsd_segment_features.dream3d", unit_test::k_TestFilesDir)); - DataStructure exemplarDataStructure = UnitTest::LoadDataStructure(exemplarFilePath); + auto exemplarFilePath = fs::path(fmt::format("{}/segment_features_test_data/segment_features_test_data.dream3d", unit_test::k_TestFilesDir)); + DataStructure dataStructure = UnitTest::LoadDataStructure(exemplarFilePath); - // Read the Small IN100 Data set - auto baseDataFilePath = fs::path(fmt::format("{}/Small_IN100.dream3d", unit_test::k_TestFilesDir)); - DataStructure dataStructure = UnitTest::LoadDataStructure(baseDataFilePath); + // EBSD Segment Features/Semgent Features (Misorientation) Filter + { + EBSDSegmentFeaturesFilter filter; + Arguments args; - // MultiThreshold Objects Filter (From SimplnxCore Plugins) - SmallIn100::ExecuteMultiThresholdObjects(dataStructure, *filterList); + // Create default Parameters for the filter. + args.insertOrAssign(EBSDSegmentFeaturesFilter::k_MisorientationTolerance_Key, std::make_any(5.0F)); + args.insertOrAssign(EBSDSegmentFeaturesFilter::k_NeighborScheme_Key, std::make_any(1)); - // Convert Orientations Filter (From OrientationAnalysis Plugin) - SmallIn100::ExecuteConvertOrientations(dataStructure, *filterList); + args.insertOrAssign(EBSDSegmentFeaturesFilter::k_UseMask_Key, std::make_any(false)); + args.insertOrAssign(EBSDSegmentFeaturesFilter::k_MaskArrayPath_Key, std::make_any(ebsd_segment_features_constants::k_MaskArrayPath)); - // Align Sections Misorientation Filter (From OrientationAnalysis Plugin) - SmallIn100::ExecuteAlignSectionsMisorientation(dataStructure, *filterList, fs::path(fmt::format("{}/AlignSectionsMisorientation_1.txt", unit_test::k_BinaryDir))); + args.insertOrAssign(EBSDSegmentFeaturesFilter::k_SelectedImageGeometryPath_Key, std::make_any(ebsd_segment_features_constants::k_InputGeometryPath)); + args.insertOrAssign(EBSDSegmentFeaturesFilter::k_QuatsArrayPath_Key, std::make_any(ebsd_segment_features_constants::k_QuatsArrayPath)); + args.insertOrAssign(EBSDSegmentFeaturesFilter::k_CellPhasesArrayPath_Key, std::make_any(ebsd_segment_features_constants::k_PhasesArrayPath)); + args.insertOrAssign(EBSDSegmentFeaturesFilter::k_CrystalStructuresArrayPath_Key, std::make_any(ebsd_segment_features_constants::k_CrystalStructuresArrayPath)); - // Identify Sample Filter - SmallIn100::ExecuteIdentifySample(dataStructure, *filterList); + args.insertOrAssign(EBSDSegmentFeaturesFilter::k_FeatureIdsArrayName_Key, std::make_any(k_FeatureIds)); + args.insertOrAssign(EBSDSegmentFeaturesFilter::k_CellFeatureAttributeMatrixName_Key, std::make_any(k_Grain_Data)); + args.insertOrAssign(EBSDSegmentFeaturesFilter::k_ActiveArrayName_Key, std::make_any(k_ActiveName)); + args.insertOrAssign(EBSDSegmentFeaturesFilter::k_RandomizeFeatureIds_Key, std::make_any(false)); - // Align Sections Feature Centroid Filter - SmallIn100::ExecuteAlignSectionsFeatureCentroid(dataStructure, *filterList, fs::path(fmt::format("{}/AlignSectionsFeatureCentroid_1.txt", unit_test::k_BinaryDir))); + // Preflight the filter and check result + auto preflightResult = filter.preflight(dataStructure, args); + SIMPLNX_RESULT_REQUIRE_VALID(preflightResult.outputActions); - // Bad Data Neighbor Orientation Check Filter - SmallIn100::ExecuteBadDataNeighborOrientationCheck(dataStructure, *filterList); + // Execute the filter and check the result + auto executeResult = filter.execute(dataStructure, args); + SIMPLNX_RESULT_REQUIRE_VALID(executeResult.result); + } - // Neighbor Orientation Correlation Filter - SmallIn100::ExecuteNeighborOrientationCorrelation(dataStructure, *filterList); + { + UInt8Array& actives = dataStructure.getDataRefAs(ebsd_segment_features_constants::k_ActivesArrayPath); + size_t numFeatures = actives.getNumberOfTuples(); + REQUIRE(numFeatures == 77); + } + + // Loop and compare each array from the 'Exemplar Data / CellData' to the 'Data Container / CellData' group + { + const auto& generatedDataArray = dataStructure.getDataRefAs(ebsd_segment_features_constants::k_FeatureIdsArrayPath); + const auto& exemplarDataArray = dataStructure.getDataRefAs(ebsd_segment_features_constants::k_FeatureIdsAllPath); + + UnitTest::CompareDataArrays(generatedDataArray, exemplarDataArray); + } + + UnitTest::CheckArraysInheritTupleDims(dataStructure, SmallIn100::k_TupleCheckIgnoredPaths); +} + +TEST_CASE("OrientationAnalysis::EBSDSegmentFeatures:MaskFace", "[OrientationAnalysis][EBSDSegmentFeatures]") +{ + UnitTest::LoadPlugins(); + + const nx::core::UnitTest::TestFileSentinel testDataSentinel(nx::core::unit_test::k_CMakeExecutable, nx::core::unit_test::k_TestFilesDir, "segment_features_test_data.tar.gz", + "segment_features_test_data"); + // Read Exemplar DREAM3D File Filter + auto exemplarFilePath = fs::path(fmt::format("{}/segment_features_test_data/segment_features_test_data.dream3d", unit_test::k_TestFilesDir)); + DataStructure dataStructure = UnitTest::LoadDataStructure(exemplarFilePath); // EBSD Segment Features/Semgent Features (Misorientation) Filter { @@ -63,12 +173,16 @@ TEST_CASE("OrientationAnalysis::EBSDSegmentFeatures: Valid Execution", "[Orienta // Create default Parameters for the filter. args.insertOrAssign(EBSDSegmentFeaturesFilter::k_MisorientationTolerance_Key, std::make_any(5.0F)); + args.insertOrAssign(EBSDSegmentFeaturesFilter::k_NeighborScheme_Key, std::make_any(0)); + args.insertOrAssign(EBSDSegmentFeaturesFilter::k_UseMask_Key, std::make_any(true)); - args.insertOrAssign(EBSDSegmentFeaturesFilter::k_SelectedImageGeometryPath_Key, std::make_any(k_DataContainerPath)); - args.insertOrAssign(EBSDSegmentFeaturesFilter::k_QuatsArrayPath_Key, std::make_any(k_QuatsArrayPath)); - args.insertOrAssign(EBSDSegmentFeaturesFilter::k_CellPhasesArrayPath_Key, std::make_any(k_PhasesArrayPath)); - args.insertOrAssign(EBSDSegmentFeaturesFilter::k_MaskArrayPath_Key, std::make_any(k_MaskArrayPath)); - args.insertOrAssign(EBSDSegmentFeaturesFilter::k_CrystalStructuresArrayPath_Key, std::make_any(k_CrystalStructuresArrayPath)); + args.insertOrAssign(EBSDSegmentFeaturesFilter::k_MaskArrayPath_Key, std::make_any(ebsd_segment_features_constants::k_MaskArrayPath)); + + args.insertOrAssign(EBSDSegmentFeaturesFilter::k_SelectedImageGeometryPath_Key, std::make_any(ebsd_segment_features_constants::k_InputGeometryPath)); + args.insertOrAssign(EBSDSegmentFeaturesFilter::k_QuatsArrayPath_Key, std::make_any(ebsd_segment_features_constants::k_QuatsArrayPath)); + args.insertOrAssign(EBSDSegmentFeaturesFilter::k_CellPhasesArrayPath_Key, std::make_any(ebsd_segment_features_constants::k_PhasesArrayPath)); + args.insertOrAssign(EBSDSegmentFeaturesFilter::k_CrystalStructuresArrayPath_Key, std::make_any(ebsd_segment_features_constants::k_CrystalStructuresArrayPath)); + args.insertOrAssign(EBSDSegmentFeaturesFilter::k_FeatureIdsArrayName_Key, std::make_any(k_FeatureIds)); args.insertOrAssign(EBSDSegmentFeaturesFilter::k_CellFeatureAttributeMatrixName_Key, std::make_any(k_Grain_Data)); args.insertOrAssign(EBSDSegmentFeaturesFilter::k_ActiveArrayName_Key, std::make_any(k_ActiveName)); @@ -84,15 +198,73 @@ TEST_CASE("OrientationAnalysis::EBSDSegmentFeatures: Valid Execution", "[Orienta } { - DataPath activeArrayDataPath = k_DataContainerPath.createChildPath(k_Grain_Data).createChildPath(k_ActiveName); - UInt8Array& actives = dataStructure.getDataRefAs(activeArrayDataPath); + UInt8Array& actives = dataStructure.getDataRefAs(ebsd_segment_features_constants::k_ActivesArrayPath); size_t numFeatures = actives.getNumberOfTuples(); - REQUIRE(numFeatures == 5417); + REQUIRE(numFeatures == 36); + } + + // Loop and compare each array from the 'Exemplar Data / CellData' to the 'Data Container / CellData' group + { + const auto& generatedDataArray = dataStructure.getDataRefAs(ebsd_segment_features_constants::k_FeatureIdsArrayPath); + const auto& exemplarDataArray = dataStructure.getDataRefAs(ebsd_segment_features_constants::k_FeatureIdsMaskFacePath); + + UnitTest::CompareDataArrays(generatedDataArray, exemplarDataArray); } + + UnitTest::CheckArraysInheritTupleDims(dataStructure, SmallIn100::k_TupleCheckIgnoredPaths); +} + +TEST_CASE("OrientationAnalysis::EBSDSegmentFeatures:MaskAll", "[OrientationAnalysis][EBSDSegmentFeatures]") +{ + UnitTest::LoadPlugins(); + + const nx::core::UnitTest::TestFileSentinel testDataSentinel(nx::core::unit_test::k_CMakeExecutable, nx::core::unit_test::k_TestFilesDir, "segment_features_test_data.tar.gz", + "segment_features_test_data"); + // Read Exemplar DREAM3D File Filter + auto exemplarFilePath = fs::path(fmt::format("{}/segment_features_test_data/segment_features_test_data.dream3d", unit_test::k_TestFilesDir)); + DataStructure dataStructure = UnitTest::LoadDataStructure(exemplarFilePath); + + // EBSD Segment Features/Semgent Features (Misorientation) Filter + { + EBSDSegmentFeaturesFilter filter; + Arguments args; + + // Create default Parameters for the filter. + args.insertOrAssign(EBSDSegmentFeaturesFilter::k_MisorientationTolerance_Key, std::make_any(5.0F)); + args.insertOrAssign(EBSDSegmentFeaturesFilter::k_NeighborScheme_Key, std::make_any(1)); + + args.insertOrAssign(EBSDSegmentFeaturesFilter::k_UseMask_Key, std::make_any(true)); + args.insertOrAssign(EBSDSegmentFeaturesFilter::k_MaskArrayPath_Key, std::make_any(ebsd_segment_features_constants::k_MaskArrayPath)); + + args.insertOrAssign(EBSDSegmentFeaturesFilter::k_SelectedImageGeometryPath_Key, std::make_any(ebsd_segment_features_constants::k_InputGeometryPath)); + args.insertOrAssign(EBSDSegmentFeaturesFilter::k_QuatsArrayPath_Key, std::make_any(ebsd_segment_features_constants::k_QuatsArrayPath)); + args.insertOrAssign(EBSDSegmentFeaturesFilter::k_CellPhasesArrayPath_Key, std::make_any(ebsd_segment_features_constants::k_PhasesArrayPath)); + args.insertOrAssign(EBSDSegmentFeaturesFilter::k_CrystalStructuresArrayPath_Key, std::make_any(ebsd_segment_features_constants::k_CrystalStructuresArrayPath)); + + args.insertOrAssign(EBSDSegmentFeaturesFilter::k_FeatureIdsArrayName_Key, std::make_any(k_FeatureIds)); + args.insertOrAssign(EBSDSegmentFeaturesFilter::k_CellFeatureAttributeMatrixName_Key, std::make_any(k_Grain_Data)); + args.insertOrAssign(EBSDSegmentFeaturesFilter::k_ActiveArrayName_Key, std::make_any(k_ActiveName)); + args.insertOrAssign(EBSDSegmentFeaturesFilter::k_RandomizeFeatureIds_Key, std::make_any(false)); + + // Preflight the filter and check result + auto preflightResult = filter.preflight(dataStructure, args); + SIMPLNX_RESULT_REQUIRE_VALID(preflightResult.outputActions); + + // Execute the filter and check the result + auto executeResult = filter.execute(dataStructure, args); + SIMPLNX_RESULT_REQUIRE_VALID(executeResult.result); + } + + { + UInt8Array& actives = dataStructure.getDataRefAs(ebsd_segment_features_constants::k_ActivesArrayPath); + size_t numFeatures = actives.getNumberOfTuples(); + REQUIRE(numFeatures == 32); + } + // Loop and compare each array from the 'Exemplar Data / CellData' to the 'Data Container / CellData' group { - const auto& generatedDataArray = dataStructure.getDataRefAs(k_FeatureIdsArrayPath); - const auto& exemplarDataArray = exemplarDataStructure.getDataRefAs(DataPath({"Small IN100", SmallIn100::k_SmallIN100ScanData, k_FeatureIds})); + const auto& generatedDataArray = dataStructure.getDataRefAs(ebsd_segment_features_constants::k_FeatureIdsArrayPath); + const auto& exemplarDataArray = dataStructure.getDataRefAs(ebsd_segment_features_constants::k_FeatureIdsMaskAllPath); UnitTest::CompareDataArrays(generatedDataArray, exemplarDataArray); } diff --git a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/RandomizeFeatureIdsFilter.cpp b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/RandomizeFeatureIdsFilter.cpp index 524453a2a4..af9bf791f8 100644 --- a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/RandomizeFeatureIdsFilter.cpp +++ b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/RandomizeFeatureIdsFilter.cpp @@ -40,7 +40,7 @@ Uuid RandomizeFeatureIdsFilter::uuid() const //------------------------------------------------------------------------------ std::string RandomizeFeatureIdsFilter::humanName() const { - return "Randomize Feature IDs"; + return "Randomize Feature Ids"; } //------------------------------------------------------------------------------ diff --git a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/ScalarSegmentFeaturesFilter.cpp b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/ScalarSegmentFeaturesFilter.cpp index 1dc307153c..b17ec03375 100644 --- a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/ScalarSegmentFeaturesFilter.cpp +++ b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/ScalarSegmentFeaturesFilter.cpp @@ -64,7 +64,7 @@ Parameters ScalarSegmentFeaturesFilter::parameters() const params.insertSeparator(Parameters::Separator{"Input Parameter(s)"}); params.insert(std::make_unique>(k_ScalarToleranceKey, "Scalar Tolerance", "Tolerance for segmenting input Cell Data", 1)); - params.insert(std::make_unique(k_RandomizeFeatures_Key, "Randomize Feature IDs", "Specifies if feature IDs should be randomized during calculations", false)); + params.insert(std::make_unique(k_RandomizeFeatures_Key, "Randomize Feature Ids", "Specifies if feature IDs should be randomized during calculations", false)); params.insert(std::make_unique(k_NeighborScheme_Key, "Neighbor Scheme", "How many neighbors to use", segment_features::k_6NeighborIndex, segment_features::k_OperationChoices)); diff --git a/src/Plugins/SimplnxCore/test/CMakeLists.txt b/src/Plugins/SimplnxCore/test/CMakeLists.txt index d1646a2c6e..a559b474e7 100644 --- a/src/Plugins/SimplnxCore/test/CMakeLists.txt +++ b/src/Plugins/SimplnxCore/test/CMakeLists.txt @@ -131,7 +131,7 @@ set(${PLUGIN_NAME}UnitTest_SRCS ReverseTriangleWindingTest.cpp RobustAutomaticThresholdTest.cpp RotateSampleRefFrameTest.cpp - ScalarSegmentFeaturesFilterTest.cpp + ScalarSegmentFeaturesTest.cpp SetImageGeomOriginScalingFilterTest.cpp SharedFeatureFaceTest.cpp SilhouetteTest.cpp diff --git a/src/Plugins/SimplnxCore/test/ScalarSegmentFeaturesFilterTest.cpp b/src/Plugins/SimplnxCore/test/ScalarSegmentFeaturesTest.cpp similarity index 84% rename from src/Plugins/SimplnxCore/test/ScalarSegmentFeaturesFilterTest.cpp rename to src/Plugins/SimplnxCore/test/ScalarSegmentFeaturesTest.cpp index 9d5bad612d..be4aba86b3 100644 --- a/src/Plugins/SimplnxCore/test/ScalarSegmentFeaturesFilterTest.cpp +++ b/src/Plugins/SimplnxCore/test/ScalarSegmentFeaturesTest.cpp @@ -31,10 +31,8 @@ const std::string k_ExemplaryCombinationFaceOnlyFeatureIdsName = "Exemplary Comb const std::string k_ExemplaryCombinationAllConnectedFeatureIdsName = "Exemplary Combination FeatureIds - All Connected"; } // namespace -TEST_CASE("SimplnxCore::ScalarSegmentFeatures", "[Reconstruction][ScalarSegmentFeatures]") +TEST_CASE("SimplnxCore::ScalarSegmentFeatures", "[SimplnxCore][ScalarSegmentFeatures]") { - UnitTest::LoadPlugins(); - const nx::core::UnitTest::TestFileSentinel testDataSentinel(nx::core::unit_test::k_CMakeExecutable, nx::core::unit_test::k_TestFilesDir, "6_5_test_data_1_v2.tar.gz", "6_5_test_data_1_v2"); // Read the Small IN100 Data set @@ -82,7 +80,7 @@ TEST_CASE("SimplnxCore::ScalarSegmentFeatures", "[Reconstruction][ScalarSegmentF UInt8Array& actives = dataStructure.getDataRefAs(activeArrayDataPath); size_t numFeatures = actives.getNumberOfTuples(); - REQUIRE(numFeatures == 848); + REQUIRE(numFeatures == 847); } { @@ -100,8 +98,23 @@ TEST_CASE("SimplnxCore::ScalarSegmentFeatures", "[Reconstruction][ScalarSegmentF TEST_CASE("SimplnxCore::ScalarSegmentFeatures: Neighbor Scheme", "[Reconstruction][ScalarSegmentFeatures]") { - UnitTest::LoadPlugins(); - + /** + * We are going to use Catch2's GENERATE macro to create variations of parameter values. + * EVERYTHING after the GENERATE macro will be run for each of the generated sets of values + */ + auto [sectionName, inputDataArrayName, exemplaryFeatureIdsArrayName, neighborSchemeIndex] = + GENERATE(std::make_tuple("Shared Edges - Face Only", k_SharedEdgesInputArrayName, k_ExemplarySharedEdgesFaceOnlyFeatureIdsName, 0), + std::make_tuple("Shared Edges - All Connected", k_SharedEdgesInputArrayName, k_ExemplarySharedEdgesAllConnectedFeatureIdsName, 1), + std::make_tuple("Shared Points - Face Only", k_SharedPointsInputArrayName, k_ExemplarySharedPointsFaceOnlyFeatureIdsName, 0), + std::make_tuple("Shared Points - All Connected", k_SharedPointsInputArrayName, k_ExemplarySharedPointsAllConnectedFeatureIdsName, 1), + std::make_tuple("Nothing Shared - Face Only", k_NothingSharedInputArrayName, k_ExemplaryNothingSharedFaceOnlyFeatureIdsName, 0), + std::make_tuple("Nothing Shared - All Connected", k_NothingSharedInputArrayName, k_ExemplaryNothingSharedAllConnectedFeatureIdsName, 1), + std::make_tuple("Combination - Face Only", k_CombinationInputArrayName, k_ExemplaryCombinationFaceOnlyFeatureIdsName, 0), + std::make_tuple("Combination - All Connected", k_CombinationInputArrayName, k_ExemplaryCombinationAllConnectedFeatureIdsName, 1)); + + /** + * @note EVERYTHING from here to the end of the test will be run for **each** tuple set above + */ const nx::core::UnitTest::TestFileSentinel testDataSentinel(nx::core::unit_test::k_CMakeExecutable, nx::core::unit_test::k_TestFilesDir, "segment_features_neighbor_scheme_test.tar.gz", "segment_features_neighbor_scheme_test"); auto baseDataFilePath = fs::path(fmt::format("{}/segment_features_neighbor_scheme_test/segment_features_neighbor_scheme_test.dream3d", nx::core::unit_test::k_TestFilesDir)); @@ -136,16 +149,6 @@ TEST_CASE("SimplnxCore::ScalarSegmentFeatures: Neighbor Scheme", "[Reconstructio // Are we going to randomize the featureIds when completed. args.insertOrAssign(ScalarSegmentFeaturesFilter::k_RandomizeFeatures_Key, std::make_any(false)); - auto [sectionName, inputDataArrayName, exemplaryFeatureIdsArrayName, neighborSchemeIndex] = - GENERATE(std::make_tuple("Shared Edges - Face Only", k_SharedEdgesInputArrayName, k_ExemplarySharedEdgesFaceOnlyFeatureIdsName, 0), - std::make_tuple("Shared Edges - All Connected", k_SharedEdgesInputArrayName, k_ExemplarySharedEdgesAllConnectedFeatureIdsName, 1), - std::make_tuple("Shared Points - Face Only", k_SharedPointsInputArrayName, k_ExemplarySharedPointsFaceOnlyFeatureIdsName, 0), - std::make_tuple("Shared Points - All Connected", k_SharedPointsInputArrayName, k_ExemplarySharedPointsAllConnectedFeatureIdsName, 1), - std::make_tuple("Nothing Shared - Face Only", k_NothingSharedInputArrayName, k_ExemplaryNothingSharedFaceOnlyFeatureIdsName, 0), - std::make_tuple("Nothing Shared - All Connected", k_NothingSharedInputArrayName, k_ExemplaryNothingSharedAllConnectedFeatureIdsName, 1), - std::make_tuple("Combination - Face Only", k_CombinationInputArrayName, k_ExemplaryCombinationFaceOnlyFeatureIdsName, 0), - std::make_tuple("Combination - All Connected", k_CombinationInputArrayName, k_ExemplaryCombinationAllConnectedFeatureIdsName, 1)); - SECTION(sectionName) { DataPath inputDataArrayPath = ebsdScanDataPath.createChildPath(inputDataArrayName); diff --git a/src/simplnx/Utilities/SegmentFeatures.cpp b/src/simplnx/Utilities/SegmentFeatures.cpp index bb8248c49c..aa28c918fb 100644 --- a/src/simplnx/Utilities/SegmentFeatures.cpp +++ b/src/simplnx/Utilities/SegmentFeatures.cpp @@ -148,7 +148,7 @@ Result<> SegmentFeatures::execute(IGridGeometry* gridGeom) // Initialize a sequence of execution modifiers int32 gnum = 1; int64 nextSeed = 0; - int64 seed = getSeed(gnum, nextSeed); + int64 seed = 0; // Always use the very first value of the array that we are using to segment usize size = 0; // Initialize containers @@ -205,18 +205,18 @@ Result<> SegmentFeatures::execute(IGridGeometry* gridGeom) totalVoxelsSegmented += size; } + // Send a progress message + throttledMessenger.sendThrottledMessage([&]() { return fmt::format("{:.2f}% - Features Found: {}", 100.0f * static_cast(totalVoxelsSegmented) / static_cast(totalVoxels), gnum); }); + // Increment or set values for the next iteration voxelsList.assign(size + 1, -1); gnum++; - - throttledMessenger.sendThrottledMessage([&]() { return fmt::format("{:.2f}% - Features Found: {}", 100.0f * static_cast(totalVoxelsSegmented) / static_cast(totalVoxels), gnum); }); - + // Get the next seed value + seed = getSeed(gnum, nextSeed); // If seed ends up being -1, then we will exit the loop. nextSeed = seed + 1; - seed = getSeed(gnum, nextSeed); } - m_MessageHelper.sendMessage(fmt::format("Total Features Found: {}", gnum)); - - m_FoundFeatures = gnum; + m_FoundFeatures = gnum - 1; // Decrement the gnum because it will end up 1 larger than it should have been. + m_MessageHelper.sendMessage(fmt::format("Total Features Found: {}", m_FoundFeatures)); return {}; }