diff --git a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/Algorithms/AlignSectionsMutualInformation.cpp b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/Algorithms/AlignSectionsMutualInformation.cpp index 5a97b3339e..e60490cde9 100644 --- a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/Algorithms/AlignSectionsMutualInformation.cpp +++ b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/Algorithms/AlignSectionsMutualInformation.cpp @@ -65,7 +65,7 @@ Result<> AlignSectionsMutualInformation::findShifts(std::vector& xShifts, { const auto& imageGeom = m_DataStructure.getDataRefAs(m_InputValues->ImageGeometryPath); const AttributeMatrix* cellData = imageGeom.getCellData(); - int64 totalPoints = static_cast(cellData->getNumTuples()); + auto totalPoints = static_cast(cellData->getNumTuples()); std::ofstream outFile; if(m_InputValues->WriteAlignmentShifts) @@ -86,6 +86,20 @@ Result<> AlignSectionsMutualInformation::findShifts(std::vector& xShifts, } } + if(m_InputValues->UseMask) + { + try + { + m_MaskCompare = InstantiateMaskCompare(m_DataStructure, m_InputValues->MaskArrayPath); + } catch(const std::out_of_range& exception) + { + // This really should NOT be happening as the path was verified during preflight BUT we may be calling this from + // somewhere else that is NOT going through the normal nx::core::IFilter API of Preflight and Execute + std::string message = fmt::format("Mask Array DataPath does not exist or is not of the correct type (Bool | UInt8) {}", m_InputValues->MaskArrayPath.toString()); + return MakeErrorResult(-53702, message); + } + } + SizeVec3 udims = imageGeom.getDimensions(); int64 dims[3] = { static_cast(udims[0]), @@ -246,10 +260,9 @@ void AlignSectionsMutualInformation::formFeaturesSections(std::vector& mi auto orientationOps = LaueOps::GetAllOrientationOps(); - Float32Array& quats = m_DataStructure.getDataRefAs(m_InputValues->QuatsArrayPath); - BoolArray* goodVoxelsPtr = m_DataStructure.getDataAs(m_InputValues->MaskArrayPath); - Int32Array& m_CellPhases = m_DataStructure.getDataRefAs(m_InputValues->CellPhasesArrayPath); - UInt32Array& m_CrystalStructures = m_DataStructure.getDataRefAs(m_InputValues->CrystalStructuresArrayPath); + auto& quats = m_DataStructure.getDataRefAs(m_InputValues->QuatsArrayPath); + auto& m_CellPhases = m_DataStructure.getDataRefAs(m_InputValues->CellPhasesArrayPath); + auto& m_CrystalStructures = m_DataStructure.getDataRefAs(m_InputValues->CrystalStructuresArrayPath); size_t initialVoxelsListSize = 1000; @@ -276,7 +289,7 @@ void AlignSectionsMutualInformation::formFeaturesSections(std::vector& mi for(int64 point = currentStartPoint; point < endPoint; point++) { - if((!m_InputValues->UseMask || (goodVoxelsPtr != nullptr && (*goodVoxelsPtr)[point])) && miFeatureIds[point] == 0 && m_CellPhases[point] > 0) + if((!m_InputValues->UseMask || (m_MaskCompare != nullptr && m_MaskCompare->isTrue(point))) && miFeatureIds[point] == 0 && m_CellPhases[point] > 0) { seed = point; currentStartPoint = point; diff --git a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/Algorithms/AlignSectionsMutualInformation.hpp b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/Algorithms/AlignSectionsMutualInformation.hpp index cd63c25f31..a53856cec2 100644 --- a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/Algorithms/AlignSectionsMutualInformation.hpp +++ b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/Algorithms/AlignSectionsMutualInformation.hpp @@ -9,10 +9,10 @@ #include "simplnx/Parameters/FileSystemPathParameter.hpp" #include "simplnx/Parameters/NumberParameter.hpp" #include "simplnx/Utilities/AlignSections.hpp" +#include "simplnx/Utilities/DataArrayUtilities.hpp" namespace nx::core { - struct ORIENTATIONANALYSIS_EXPORT AlignSectionsMutualInformationInputValues { bool WriteAlignmentShifts; @@ -56,6 +56,8 @@ class ORIENTATIONANALYSIS_EXPORT AlignSectionsMutualInformation : public AlignSe const std::atomic_bool& m_ShouldCancel; const IFilter::MessageHandler& m_MessageHandler; Result<> m_Result = {}; + + std::unique_ptr m_MaskCompare = nullptr; }; } // namespace nx::core diff --git a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/Algorithms/BadDataNeighborOrientationCheck.hpp b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/Algorithms/BadDataNeighborOrientationCheck.hpp index 1e2f80777a..5a65acab3d 100644 --- a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/Algorithms/BadDataNeighborOrientationCheck.hpp +++ b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/Algorithms/BadDataNeighborOrientationCheck.hpp @@ -6,20 +6,6 @@ #include "simplnx/DataStructure/DataStructure.hpp" #include "simplnx/Filter/IFilter.hpp" -/** -* This is example code to put in the Execute Method of the filter. - BadDataNeighborOrientationCheckInputValues inputValues; - - inputValues.MisorientationTolerance = filterArgs.value(k_MisorientationTolerance_Key); - inputValues.NumberOfNeighbors = filterArgs.value(k_NumberOfNeighbors_Key); - inputValues.QuatsArrayPath = filterArgs.value(k_QuatsArrayPath_Key); - inputValues.MaskArrayPath = filterArgs.value(k_MaskArrayPath_Key); - inputValues.CellPhasesArrayPath = filterArgs.value(k_CellPhasesArrayPath_Key); - inputValues.CrystalStructuresArrayPath = filterArgs.value(k_CrystalStructuresArrayPath_Key); - - return BadDataNeighborOrientationCheck(dataStructure, messageHandler, shouldCancel, &inputValues)(); -*/ - namespace nx::core { diff --git a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/Algorithms/WriteStatsGenOdfAngleFile.cpp b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/Algorithms/WriteStatsGenOdfAngleFile.cpp index b4d57d196a..68deccf175 100644 --- a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/Algorithms/WriteStatsGenOdfAngleFile.cpp +++ b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/Algorithms/WriteStatsGenOdfAngleFile.cpp @@ -47,10 +47,10 @@ Result<> WriteStatsGenOdfAngleFile::operator()() } const auto& cellPhases = m_DataStructure.getDataRefAs(m_InputValues->CellPhasesArrayPath); - BoolArray* maskPtr = nullptr; + std::unique_ptr maskPtr = nullptr; if(m_InputValues->UseMask) { - maskPtr = m_DataStructure.getDataAs(m_InputValues->MaskArrayPath); + maskPtr = InstantiateMaskCompare(m_DataStructure, m_InputValues->MaskArrayPath); } // Figure out how many unique phase values we have by looping over all the phase values @@ -100,14 +100,14 @@ Result<> WriteStatsGenOdfAngleFile::operator()() } // ----------------------------------------------------------------------------- -int WriteStatsGenOdfAngleFile::determineOutputLineCount(const Int32Array& cellPhases, const BoolArray* mask, usize totalPoints, int32 phase) const +int WriteStatsGenOdfAngleFile::determineOutputLineCount(const Int32Array& cellPhases, const std::unique_ptr& mask, usize totalPoints, int32 phase) const { int32 lineCount = 0; for(usize i = 0; i < totalPoints; i++) { if(cellPhases[i] == phase) { - if(!m_InputValues->UseMask || (m_InputValues->UseMask && (*mask)[i])) + if(!m_InputValues->UseMask || (m_InputValues->UseMask && mask->isTrue(i))) { lineCount++; } @@ -118,7 +118,7 @@ int WriteStatsGenOdfAngleFile::determineOutputLineCount(const Int32Array& cellPh } // ----------------------------------------------------------------------------- -Result<> WriteStatsGenOdfAngleFile::writeOutputFile(std::ofstream& out, const Int32Array& cellPhases, const BoolArray* mask, int32 lineCount, usize totalPoints, int32 phase) const +Result<> WriteStatsGenOdfAngleFile::writeOutputFile(std::ofstream& out, const Int32Array& cellPhases, const std::unique_ptr& mask, int32 lineCount, usize totalPoints, int32 phase) const { const auto& eulerAngles = m_DataStructure.getDataRefAs(m_InputValues->CellEulerAnglesArrayPath); @@ -147,7 +147,7 @@ Result<> WriteStatsGenOdfAngleFile::writeOutputFile(std::ofstream& out, const In if(cellPhases[i] == phase) { - if(!m_InputValues->UseMask || (m_InputValues->UseMask && (*mask)[i])) + if(!m_InputValues->UseMask || (m_InputValues->UseMask && mask->isTrue(i))) { writeLine = true; } diff --git a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/Algorithms/WriteStatsGenOdfAngleFile.hpp b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/Algorithms/WriteStatsGenOdfAngleFile.hpp index f007c4a258..4f27f03aa5 100644 --- a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/Algorithms/WriteStatsGenOdfAngleFile.hpp +++ b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/Algorithms/WriteStatsGenOdfAngleFile.hpp @@ -8,6 +8,8 @@ #include "simplnx/Filter/IFilter.hpp" #include "simplnx/Parameters/ChoicesParameter.hpp" #include "simplnx/Parameters/FileSystemPathParameter.hpp" +#include "simplnx/Utilities/DataArrayUtilities.hpp" + namespace nx::core { @@ -44,8 +46,8 @@ class ORIENTATIONANALYSIS_EXPORT WriteStatsGenOdfAngleFile const std::atomic_bool& getCancel(); - int determineOutputLineCount(const Int32Array& cellPhases, const BoolArray* mask, usize totalPoints, int32 phase) const; - Result<> writeOutputFile(std::ofstream& out, const Int32Array& cellPhases, const BoolArray* mask, int32 lineCount, usize totalPoints, int32 phase) const; + int determineOutputLineCount(const Int32Array& cellPhases, const std::unique_ptr& mask, usize totalPoints, int32 phase) const; + Result<> writeOutputFile(std::ofstream& out, const Int32Array& cellPhases, const std::unique_ptr& mask, int32 lineCount, usize totalPoints, int32 phase) const; private: DataStructure& m_DataStructure; diff --git a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/AlignSectionsMutualInformationFilter.cpp b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/AlignSectionsMutualInformationFilter.cpp index 027f4d1c01..fedd41ee33 100644 --- a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/AlignSectionsMutualInformationFilter.cpp +++ b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/AlignSectionsMutualInformationFilter.cpp @@ -66,7 +66,7 @@ Parameters AlignSectionsMutualInformationFilter::parameters() const params.insertLinkableParameter(std::make_unique(k_UseMask_Key, "Use Mask Array", "Whether to remove some Cells from consideration in the alignment process.", true)); params.insert(std::make_unique(k_MaskArrayPath_Key, "Cell Mask Array", "Specifies if the Cell is to be counted in the algorithm. Only required if Use Mask Array is checked.", DataPath{}, - ArraySelectionParameter::AllowedTypes{DataType::boolean}, ArraySelectionParameter::AllowedComponentShapes{{1}})); + ArraySelectionParameter::AllowedTypes{DataType::boolean, DataType::uint8}, ArraySelectionParameter::AllowedComponentShapes{{1}})); params.linkParameters(k_UseMask_Key, k_MaskArrayPath_Key, true); params.insertSeparator(Parameters::Separator{"Input Cell Data"}); @@ -102,10 +102,7 @@ IFilter::UniquePointer AlignSectionsMutualInformationFilter::clone() const IFilter::PreflightResult AlignSectionsMutualInformationFilter::preflightImpl(const DataStructure& dataStructure, const Arguments& filterArgs, const MessageHandler& messageHandler, const std::atomic_bool& shouldCancel) const { - auto pWriteAlignmentShiftsValue = filterArgs.value(k_WriteAlignmentShifts_Key); auto pAlignmentShiftFileNameValue = filterArgs.value(k_AlignmentShiftFileName_Key); - auto pMisorientationToleranceValue = filterArgs.value(k_MisorientationTolerance_Key); - auto pUseGoodVoxelsValue = filterArgs.value(k_UseMask_Key); auto imageGeometryPath = filterArgs.value(k_SelectedImageGeometryPath_Key); auto pQuatsArrayPathValue = filterArgs.value(k_QuatsArrayPath_Key); auto pCellPhasesArrayPathValue = filterArgs.value(k_CellPhasesArrayPath_Key); @@ -116,7 +113,7 @@ IFilter::PreflightResult AlignSectionsMutualInformationFilter::preflightImpl(con nx::core::Result resultOutputActions; std::vector preflightUpdatedValues; - const ImageGeom& imageGeom = dataStructure.getDataRefAs(imageGeometryPath); + const auto& imageGeom = dataStructure.getDataRefAs(imageGeometryPath); if(imageGeom.getCellData() == nullptr) { return {MakeErrorResult(-3540, fmt::format("Cannot find cell data Attribute Matrix in the selected Image geometry '{}'", imageGeometryPath.toString()))}; diff --git a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/BadDataNeighborOrientationCheckFilter.cpp b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/BadDataNeighborOrientationCheckFilter.cpp index d610ac8c71..1cf372ae88 100644 --- a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/BadDataNeighborOrientationCheckFilter.cpp +++ b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/BadDataNeighborOrientationCheckFilter.cpp @@ -71,7 +71,7 @@ Parameters BadDataNeighborOrientationCheckFilter::parameters() const params.insert(std::make_unique(k_QuatsArrayPath_Key, "Cell Quaternions", "Specifies the orientation of the Cell in quaternion representation", DataPath{}, ArraySelectionParameter::AllowedTypes{DataType::float32}, ArraySelectionParameter::AllowedComponentShapes{{4}})); params.insert(std::make_unique(k_MaskArrayPath_Key, "Cell Mask Array", "Used to define Cells as good or bad", DataPath{}, - ArraySelectionParameter::AllowedTypes{DataType::boolean}, ArraySelectionParameter::AllowedComponentShapes{{1}})); + ArraySelectionParameter::AllowedTypes{DataType::boolean, DataType::uint8}, ArraySelectionParameter::AllowedComponentShapes{{1}})); params.insert(std::make_unique(k_CellPhasesArrayPath_Key, "Cell Phases", "Specifies to which Ensemble each Cell belongs", DataPath({"Phases"}), ArraySelectionParameter::AllowedTypes{DataType::int32}, ArraySelectionParameter::AllowedComponentShapes{{1}})); @@ -119,15 +119,11 @@ IFilter::PreflightResult BadDataNeighborOrientationCheckFilter::preflightImpl(co { return {nonstd::make_unexpected(std::vector{Error{k_MissingInputArray, fmt::format("Could not find mask array at path '{}'", pGoodVoxelsArrayPathValue.toString())}})}; } - auto* goodVoxelsBoolPtr = dataStructure.getDataAs(pGoodVoxelsArrayPathValue); - if(nullptr == goodVoxelsBoolPtr) - { - return {nonstd::make_unexpected( - std::vector{Error{k_IncorrectInputArray, fmt::format("Mask array at path '{}' is not of the correct type. It must be Bool.", pGoodVoxelsArrayPathValue.toString())}})}; - } + + auto* goodVoxelsBoolPtr = dataStructure.getDataAs(pGoodVoxelsArrayPathValue); if(goodVoxelsBoolPtr->getNumberOfComponents() != 1) { - return {nonstd::make_unexpected(std::vector{Error{k_IncorrectInputArray, "Mask Input Array must be a 1 component Bool array"}})}; + return {nonstd::make_unexpected(std::vector{Error{k_IncorrectInputArray, "Mask Input Array must be a 1 component array"}})}; } dataArrayPaths.push_back(pGoodVoxelsArrayPathValue); diff --git a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/CAxisSegmentFeaturesFilter.cpp b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/CAxisSegmentFeaturesFilter.cpp index d5d7b93b02..db3d4602b8 100644 --- a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/CAxisSegmentFeaturesFilter.cpp +++ b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/CAxisSegmentFeaturesFilter.cpp @@ -66,7 +66,7 @@ Parameters CAxisSegmentFeaturesFilter::parameters() const params.insertLinkableParameter( std::make_unique(k_UseMask_Key, "Use Mask Array", "Specifies whether to use a boolean array to exclude some Cells from the Feature identification process", true)); params.insert(std::make_unique(k_MaskArrayPath_Key, "Cell Mask Array", "Specifies if the Cell is to be counted in the algorithm. Only required if Use Mask Array is checked", - DataPath{}, ArraySelectionParameter::AllowedTypes{DataType::boolean}, ArraySelectionParameter::AllowedComponentShapes{{1}})); + DataPath{}, ArraySelectionParameter::AllowedTypes{DataType::boolean, DataType::uint8}, ArraySelectionParameter::AllowedComponentShapes{{1}})); params.insertSeparator(Parameters::Separator{"Input Cell Data"}); params.insert(std::make_unique(k_FeatureIdsArrayName_Key, "Cell Feature Ids", "Specifies to which Feature each Cell belongs", "FeatureIds")); diff --git a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/WriteStatsGenOdfAngleFileFilter.cpp b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/WriteStatsGenOdfAngleFileFilter.cpp index 50d692d809..23038d414b 100644 --- a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/WriteStatsGenOdfAngleFileFilter.cpp +++ b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/WriteStatsGenOdfAngleFileFilter.cpp @@ -70,7 +70,7 @@ Parameters WriteStatsGenOdfAngleFileFilter::parameters() const params.insertLinkableParameter( std::make_unique(k_UseMask_Key, "Only Write Good Elements", "Whether to only write the Euler angles for those elements denoted as true in the supplied mask array", false)); params.insert(std::make_unique(k_MaskArrayPath_Key, "Mask Array", "Used to define Elements as good or bad. Only required if Only Write Good Elements is checked", DataPath{}, - ArraySelectionParameter::AllowedTypes{DataType::boolean}, ArraySelectionParameter::AllowedComponentShapes{{1}})); + ArraySelectionParameter::AllowedTypes{DataType::boolean, DataType::uint8}, ArraySelectionParameter::AllowedComponentShapes{{1}})); params.insertSeparator(Parameters::Separator{"Input Cell Data"}); params.insert(std::make_unique(k_CellEulerAnglesArrayPath_Key, "Euler Angles", "Three angles defining the orientation of the Element in Bunge convention (Z-X-Z)", diff --git a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeKMeans.cpp b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeKMeans.cpp index 85f3f6d986..009ba22ef9 100644 --- a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeKMeans.cpp +++ b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeKMeans.cpp @@ -1,6 +1,7 @@ #include "ComputeKMeans.hpp" #include "simplnx/DataStructure/DataArray.hpp" +#include "simplnx/Utilities/DataArrayUtilities.hpp" #include "simplnx/Utilities/FilterUtilities.hpp" #include "simplnx/Utilities/KUtilities.hpp" @@ -14,7 +15,7 @@ template class ComputeKMeansTemplate { public: - ComputeKMeansTemplate(ComputeKMeans* filter, const IDataArray& inputIDataArray, IDataArray& meansIDataArray, const BoolArray& maskDataArray, usize numClusters, Int32Array& fIds, + ComputeKMeansTemplate(ComputeKMeans* filter, const IDataArray& inputIDataArray, IDataArray& meansIDataArray, const std::unique_ptr& maskDataArray, usize numClusters, Int32Array& fIds, KUtilities::DistanceMetric distMetric, std::mt19937_64::result_type seed) : m_Filter(filter) , m_InputArray(dynamic_cast(inputIDataArray)) @@ -48,7 +49,7 @@ class ComputeKMeansTemplate while(clusterChoices < m_NumClusters) { usize index = std::floor(dist(gen) * static_cast(rangeMax)); - if(m_Mask[index]) + if(m_Mask->isTrue(index)) { clusterIdxs[clusterChoices] = index; clusterChoices++; @@ -103,7 +104,7 @@ class ComputeKMeansTemplate ComputeKMeans* m_Filter; const DataArrayT& m_InputArray; DataArrayT& m_Means; - const BoolArray& m_Mask; + const std::unique_ptr& m_Mask; usize m_NumClusters; Int32Array& m_FeatureIds; KUtilities::DistanceMetric m_DistMetric; @@ -125,7 +126,7 @@ class ComputeKMeansTemplate { return; } - if(m_Mask[i]) + if(m_Mask->isTrue(i)) { float64 minDist = std::numeric_limits::max(); for(int32 j = 0; j < m_NumClusters; j++) @@ -207,9 +208,22 @@ const std::atomic_bool& ComputeKMeans::getCancel() Result<> ComputeKMeans::operator()() { auto& clusteringArray = m_DataStructure.getDataRefAs(m_InputValues->ClusteringArrayPath); + + std::unique_ptr maskCompare; + try + { + maskCompare = InstantiateMaskCompare(m_DataStructure, m_InputValues->MaskArrayPath); + } catch(const std::out_of_range& exception) + { + // This really should NOT be happening as the path was verified during preflight BUT we may be calling this from + // somewhere else that is NOT going through the normal nx::core::IFilter API of Preflight and Execute + std::string message = fmt::format("Mask Array DataPath does not exist or is not of the correct type (Bool | UInt8) {}", m_InputValues->MaskArrayPath.toString()); + return MakeErrorResult(-54060, message); + } + RunTemplateClass(clusteringArray.getDataType(), this, clusteringArray, m_DataStructure.getDataRefAs(m_InputValues->MeansArrayPath), - m_DataStructure.getDataRefAs(m_InputValues->MaskArrayPath), m_InputValues->InitClusters, - m_DataStructure.getDataRefAs(m_InputValues->FeatureIdsArrayPath), m_InputValues->DistanceMetric, m_InputValues->Seed); + maskCompare, m_InputValues->InitClusters, m_DataStructure.getDataRefAs(m_InputValues->FeatureIdsArrayPath), + m_InputValues->DistanceMetric, m_InputValues->Seed); return {}; } diff --git a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeKMedoids.cpp b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeKMedoids.cpp index cfbf4ac380..fa48a52926 100644 --- a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeKMedoids.cpp +++ b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeKMedoids.cpp @@ -1,6 +1,7 @@ #include "ComputeKMedoids.hpp" #include "simplnx/DataStructure/DataArray.hpp" +#include "simplnx/Utilities/DataArrayUtilities.hpp" #include "simplnx/Utilities/FilterUtilities.hpp" #include "simplnx/Utilities/KUtilities.hpp" @@ -14,7 +15,7 @@ template class KMedoidsTemplate { public: - KMedoidsTemplate(ComputeKMedoids* filter, const IDataArray& inputIDataArray, IDataArray& medoidsIDataArray, const BoolArray& maskDataArray, usize numClusters, Int32Array& fIds, + KMedoidsTemplate(ComputeKMedoids* filter, const IDataArray& inputIDataArray, IDataArray& medoidsIDataArray, const std::unique_ptr& maskDataArray, usize numClusters, Int32Array& fIds, KUtilities::DistanceMetric distMetric, std::mt19937_64::result_type seed) : m_Filter(filter) , m_InputArray(dynamic_cast(inputIDataArray)) @@ -46,7 +47,7 @@ class KMedoidsTemplate while(clusterChoices < m_NumClusters) { usize index = dist(gen); - if(m_Mask[index]) + if(m_Mask->isTrue(index)) { clusterIdxs[clusterChoices] = index; clusterChoices++; @@ -91,7 +92,7 @@ class KMedoidsTemplate ComputeKMedoids* m_Filter; const DataArrayT& m_InputArray; DataArrayT& m_Medoids; - const BoolArray& m_Mask; + const std::unique_ptr& m_Mask; usize m_NumClusters; Int32Array& m_FeatureIds; KUtilities::DistanceMetric m_DistMetric; @@ -106,7 +107,7 @@ class KMedoidsTemplate { return; } - if(m_Mask[i]) + if(m_Mask->isTrue(i)) { float64 minDist = std::numeric_limits::max(); for(int32 j = 0; j < m_NumClusters; j++) @@ -139,7 +140,7 @@ class KMedoidsTemplate { return {}; } - if(m_Mask[j]) + if(m_Mask->isTrue(j)) { if(m_FeatureIds[j] == i + 1) { @@ -150,7 +151,7 @@ class KMedoidsTemplate { return {}; } - if(m_FeatureIds[k] == i + 1 && m_Mask[k]) + if(m_FeatureIds[k] == i + 1 && m_Mask->isTrue(k)) { cost += KUtilities::GetDistance(m_InputArray, (dims * k), m_InputArray, (dims * j), dims, m_DistMetric); } @@ -207,9 +208,20 @@ const std::atomic_bool& ComputeKMedoids::getCancel() Result<> ComputeKMedoids::operator()() { auto& clusteringArray = m_DataStructure.getDataRefAs(m_InputValues->ClusteringArrayPath); - RunTemplateClass(clusteringArray.getDataType(), this, clusteringArray, m_DataStructure.getDataRefAs(m_InputValues->MedoidsArrayPath), - m_DataStructure.getDataRefAs(m_InputValues->MaskArrayPath), m_InputValues->InitClusters, - m_DataStructure.getDataRefAs(m_InputValues->FeatureIdsArrayPath), m_InputValues->DistanceMetric, m_InputValues->Seed); + std::unique_ptr maskCompare; + try + { + maskCompare = InstantiateMaskCompare(m_DataStructure, m_InputValues->MaskArrayPath); + } catch(const std::out_of_range& exception) + { + // This really should NOT be happening as the path was verified during preflight BUT we may be calling this from + // somewhere else that is NOT going through the normal nx::core::IFilter API of Preflight and Execute + std::string message = fmt::format("Mask Array DataPath does not exist or is not of the correct type (Bool | UInt8) {}", m_InputValues->MaskArrayPath.toString()); + return MakeErrorResult(-54070, message); + } + RunTemplateClass(clusteringArray.getDataType(), this, clusteringArray, m_DataStructure.getDataRefAs(m_InputValues->MedoidsArrayPath), maskCompare, + m_InputValues->InitClusters, m_DataStructure.getDataRefAs(m_InputValues->FeatureIdsArrayPath), m_InputValues->DistanceMetric, + m_InputValues->Seed); return {}; } diff --git a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/PointSampleTriangleGeometry.cpp b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/PointSampleTriangleGeometry.cpp index 2fcfa14504..e2a92d05dc 100644 --- a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/PointSampleTriangleGeometry.cpp +++ b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/PointSampleTriangleGeometry.cpp @@ -97,16 +97,22 @@ Result<> PointSampleTriangleGeometry::operator()() // We get the pointer to the Array instead of a reference because it might not have been set because // the bool "use_mask" might have been false, but we do NOT want to try to get the array // 'on demand' in the loop. That is a BAD idea as is it really slow to do that. (10x slower). - DataObject* maskArrayDataObject = m_DataStructure.getData(m_Inputs->pMaskArrayPath); - BoolArray* maskArray = nullptr; - if(nullptr != maskArrayDataObject && m_Inputs->pUseMask) + std::unique_ptr maskArray = nullptr; + if(m_Inputs->pUseMask) { - maskArray = m_DataStructure.getDataAs(m_Inputs->pMaskArrayPath); - } - if(maskArray == nullptr && m_Inputs->pUseMask) - { - return MakeErrorResult(-502, "Use Mask is true but the MaskArray could not be extracted from the DataStructure. Please ensure the path is correct and that the selected DataArray is of type bool"); + std::unique_ptr maskCompare; + try + { + maskCompare = InstantiateMaskCompare(m_DataStructure, m_Inputs->pMaskArrayPath); + } catch(const std::out_of_range& exception) + { + // This really should NOT be happening as the path was verified during preflight BUT we may be calling this from + // somewhere else that is NOT going through the normal nx::core::IFilter API of Preflight and Execute + std::string message = fmt::format("Mask Array DataPath does not exist or is not of the correct type (Bool | UInt8) {}", m_Inputs->pMaskArrayPath.toString()); + return MakeErrorResult(-506, message); + } } + // Get a reference to the Vertex List IGeometry::SharedVertexList* vertices = vertex.getVertices(); @@ -126,7 +132,7 @@ Result<> PointSampleTriangleGeometry::operator()() int64_t randomTri = 0; - if(m_Inputs->pUseMask) + if(m_Inputs->pUseMask && maskArray != nullptr) { while(true) { @@ -135,7 +141,7 @@ Result<> PointSampleTriangleGeometry::operator()() { throw std::out_of_range(fmt::format("Generated Random Triangle Index '{}' was out of range. '0->{}'", randomTri, numTris)); } - if((*maskArray)[randomTri]) + if(maskArray->isTrue(randomTri)) { break; } diff --git a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/RemoveFlaggedTriangles.cpp b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/RemoveFlaggedTriangles.cpp index 4bc400709a..410bffc40b 100644 --- a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/RemoveFlaggedTriangles.cpp +++ b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/RemoveFlaggedTriangles.cpp @@ -3,6 +3,7 @@ #include "simplnx/DataStructure/DataArray.hpp" #include "simplnx/DataStructure/DataGroup.hpp" #include "simplnx/DataStructure/Geometry/TriangleGeom.hpp" +#include "simplnx/Utilities/DataArrayUtilities.hpp" #include "simplnx/Utilities/ParallelDataAlgorithm.hpp" using namespace nx::core; @@ -81,7 +82,17 @@ Result<> RemoveFlaggedTriangles::operator()() { // Remove Triangles from reduced according to removeTrianglesIndex const auto& originalTriangle = m_DataStructure.getDataRefAs(m_InputValues->TriangleGeometry); - const auto& mask = m_DataStructure.getDataRefAs(m_InputValues->MaskArrayPath); + std::unique_ptr maskCompare; + try + { + maskCompare = InstantiateMaskCompare(m_DataStructure, m_InputValues->MaskArrayPath); + } catch(const std::out_of_range& exception) + { + // This really should NOT be happening as the path was verified during preflight BUT we may be calling this from + // somewhere else that is NOT going through the normal nx::core::IFilter API of Preflight and Execute + std::string message = fmt::format("Mask Array DataPath does not exist or is not of the correct type (Bool | UInt8) {}", m_InputValues->MaskArrayPath.toString()); + return MakeErrorResult(-54070, message); + } auto& reducedTriangle = m_DataStructure.getDataRefAs(m_InputValues->ReducedTriangleGeometry); // Set up allocated masks @@ -92,7 +103,7 @@ Result<> RemoveFlaggedTriangles::operator()() // parse mask Triangles list and load a list of indices for triangles to keep for(usize index = 0; index < size; index++) { - if(!mask[index]) + if(!maskCompare->isTrue(index)) { newTrianglesIndexList.push_back(index); } diff --git a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ScalarSegmentFeatures.cpp b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ScalarSegmentFeatures.cpp index 53b64767e3..339d6b7778 100644 --- a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ScalarSegmentFeatures.cpp +++ b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ScalarSegmentFeatures.cpp @@ -3,8 +3,6 @@ #include "simplnx/DataStructure/DataStore.hpp" #include "simplnx/DataStructure/Geometry/IGridGeometry.hpp" #include "simplnx/Filter/Actions/CreateArrayAction.hpp" -#include "simplnx/Parameters/BoolParameter.hpp" -#include "simplnx/Utilities/DataArrayUtilities.hpp" using namespace nx::core; @@ -136,11 +134,18 @@ ScalarSegmentFeatures::~ScalarSegmentFeatures() noexcept = default; // ----------------------------------------------------------------------------- Result<> ScalarSegmentFeatures::operator()() { - nx::core::AbstractDataStore* goodVoxels = nullptr; if(m_InputValues->pUseGoodVoxels) { - m_GoodVoxelsArray = m_DataStructure.getDataAs(m_InputValues->pGoodVoxelsPath); - goodVoxels = m_GoodVoxelsArray->getDataStore(); + try + { + m_GoodVoxels = InstantiateMaskCompare(m_DataStructure, m_InputValues->pGoodVoxelsPath); + } catch(const std::out_of_range& exception) + { + // This really should NOT be happening as the path was verified during preflight BUT we may be calling this from + // somewhere else that is NOT going through the normal nx::core::IFilter API of Preflight and Execute + std::string message = fmt::format("Mask Array DataPath does not exist or is not of the correct type (Bool | UInt8) {}", m_InputValues->pGoodVoxelsPath.toString()); + return MakeErrorResult(-54110, message); + } } auto* gridGeom = m_DataStructure.getDataAs(m_InputValues->pGridGeomPath); @@ -238,23 +243,17 @@ Result<> ScalarSegmentFeatures::operator()() // ----------------------------------------------------------------------------- int64_t ScalarSegmentFeatures::getSeed(int32 gnum, int64 nextSeed) const { - nx::core::AbstractDataStore* goodVoxels = nullptr; - if(m_InputValues->pUseGoodVoxels) - { - goodVoxels = m_GoodVoxelsArray->getDataStore(); - } - nx::core::DataArray::store_type* featureIds = m_FeatureIdsArray->getDataStore(); usize totalPoints = featureIds->getNumberOfTuples(); int64 seed = -1; // start with the next voxel after the last seed - usize randpoint = static_cast(nextSeed); + auto randpoint = static_cast(nextSeed); while(seed == -1 && randpoint < totalPoints) { if(featureIds->getValue(randpoint) == 0) // If the GrainId of the voxel is ZERO then we can use this as a seed point { - if(!m_InputValues->pUseGoodVoxels || goodVoxels->getValue(randpoint)) + if(!m_InputValues->pUseGoodVoxels || m_GoodVoxels->isTrue(randpoint)) { seed = randpoint; } @@ -270,7 +269,7 @@ int64_t ScalarSegmentFeatures::getSeed(int32 gnum, int64 nextSeed) const } if(seed >= 0) { - UInt8Array& activeArray = m_DataStructure.getDataRefAs(m_InputValues->pActiveArrayPath); + auto& activeArray = m_DataStructure.getDataRefAs(m_InputValues->pActiveArrayPath); featureIds->setValue(static_cast(seed), gnum); std::vector tDims = {static_cast(gnum) + 1}; auto& cellFeaturesAM = m_DataStructure.getDataRefAs(m_InputValues->pCellFeaturesPath); @@ -282,16 +281,8 @@ int64_t ScalarSegmentFeatures::getSeed(int32 gnum, int64 nextSeed) const // ----------------------------------------------------------------------------- bool ScalarSegmentFeatures::determineGrouping(int64 referencepoint, int64 neighborpoint, int32 gnum) const { - auto featureIds = m_FeatureIdsArray->getDataStore(); - - const nx::core::AbstractDataStore* goodVoxels = nullptr; - if(m_InputValues->pUseGoodVoxels) - { - goodVoxels = m_GoodVoxelsArray->getDataStore(); - } - - if(featureIds->getValue(neighborpoint) == 0 && (!m_InputValues->pUseGoodVoxels || goodVoxels->getValue(neighborpoint))) + if(featureIds->getValue(neighborpoint) == 0 && (!m_InputValues->pUseGoodVoxels || m_GoodVoxels->isTrue(neighborpoint))) { CompareFunctor* func = m_CompareFunctor.get(); return (*func)((usize)(referencepoint), (usize)(neighborpoint), gnum); diff --git a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ScalarSegmentFeatures.hpp b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ScalarSegmentFeatures.hpp index 2239932aa5..b03f1895fc 100644 --- a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ScalarSegmentFeatures.hpp +++ b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ScalarSegmentFeatures.hpp @@ -7,6 +7,7 @@ #include "simplnx/DataStructure/DataStructure.hpp" #include "simplnx/DataStructure/IDataArray.hpp" #include "simplnx/Filter/IFilter.hpp" +#include "simplnx/Utilities/DataArrayUtilities.hpp" #include "simplnx/Utilities/SegmentFeatures.hpp" #include @@ -74,5 +75,6 @@ class SIMPLNXCORE_EXPORT ScalarSegmentFeatures : public SegmentFeatures FeatureIdsArrayType* m_FeatureIdsArray = nullptr; GoodVoxelsArrayType* m_GoodVoxelsArray = nullptr; std::shared_ptr m_CompareFunctor; + std::unique_ptr m_GoodVoxels = nullptr; }; } // namespace nx::core diff --git a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/Silhouette.cpp b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/Silhouette.cpp index 4b0b239cd0..58cc0b4497 100644 --- a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/Silhouette.cpp +++ b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/Silhouette.cpp @@ -1,6 +1,7 @@ #include "Silhouette.hpp" #include "simplnx/DataStructure/DataArray.hpp" +#include "simplnx/Utilities/DataArrayUtilities.hpp" #include "simplnx/Utilities/FilterUtilities.hpp" #include "simplnx/Utilities/KUtilities.hpp" @@ -25,7 +26,7 @@ class SilhouetteTemplate return Pointer(static_cast(nullptr)); } - SilhouetteTemplate(const IDataArray& inputIDataArray, Float64Array& outputDataArray, const BoolArray& maskDataArray, usize numClusters, const Int32Array& featureIds, + SilhouetteTemplate(const IDataArray& inputIDataArray, Float64Array& outputDataArray, const std::unique_ptr& maskDataArray, usize numClusters, const Int32Array& featureIds, KUtilities::DistanceMetric distMetric) : m_InputData(dynamic_cast(inputIDataArray)) , m_OutputData(outputDataArray) @@ -56,7 +57,7 @@ class SilhouetteTemplate for(usize i = 0; i < numTuples; i++) { - if(m_Mask[i]) + if(m_Mask->isTrue(i)) { numTuplesPerFeature[m_FeatureIds[i]]++; } @@ -64,11 +65,11 @@ class SilhouetteTemplate for(usize i = 0; i < numTuples; i++) { - if(m_Mask[i]) + if(m_Mask->isTrue(i)) { for(usize j = 0; j < numTuples; j++) { - if(m_Mask[j]) + if(m_Mask->isTrue(j)) { clusterDist[i][m_FeatureIds[j]] += KUtilities::GetDistance(m_InputData, (numCompDims * i), m_InputData, (numCompDims * j), numCompDims, m_DistMetric); } @@ -78,7 +79,7 @@ class SilhouetteTemplate for(usize i = 0; i < numTuples; i++) { - if(m_Mask[i]) + if(m_Mask->isTrue(i)) { for(usize j = 1; j < totalClusters; j++) { @@ -89,7 +90,7 @@ class SilhouetteTemplate for(usize i = 0; i < numTuples; i++) { - if(m_Mask[i]) + if(m_Mask->isTrue(i)) { int32 cluster = m_FeatureIds[i]; inClusterDist[i] = clusterDist[i][cluster]; @@ -112,7 +113,7 @@ class SilhouetteTemplate for(usize i = 0; i < numTuples; i++) { - if(m_Mask[i]) + if(m_Mask->isTrue(i)) { m_OutputData[i] = (outClusterMinDist[i] - inClusterDist[i]) / (std::max(outClusterMinDist[i], inClusterDist[i])); } @@ -124,7 +125,7 @@ class SilhouetteTemplate const DataArrayT& m_InputData; Float64Array& m_OutputData; const Int32Array& m_FeatureIds; - const BoolArray& m_Mask; + const std::unique_ptr& m_Mask; usize m_NumClusters; KUtilities::DistanceMetric m_DistMetric; }; @@ -167,7 +168,18 @@ Result<> Silhouette::operator()() } auto& clusteringArray = m_DataStructure.getDataRefAs(m_InputValues->ClusteringArrayPath); + std::unique_ptr maskCompare; + try + { + maskCompare = InstantiateMaskCompare(m_DataStructure, m_InputValues->MaskArrayPath); + } catch(const std::out_of_range& exception) + { + // This really should NOT be happening as the path was verified during preflight BUT we may be calling this from + // somewhere else that is NOT going through the normal nx::core::IFilter API of Preflight and Execute + std::string message = fmt::format("Mask Array DataPath does not exist or is not of the correct type (Bool | UInt8) {}", m_InputValues->MaskArrayPath.toString()); + return MakeErrorResult(-54080, message); + } RunTemplateClass(clusteringArray.getDataType(), clusteringArray, m_DataStructure.getDataRefAs(m_InputValues->SilhouetteArrayPath), - m_DataStructure.getDataRefAs(m_InputValues->MaskArrayPath), uniqueIds.size(), featureIds, m_InputValues->DistanceMetric); + maskCompare, uniqueIds.size(), featureIds, m_InputValues->DistanceMetric); return {}; } diff --git a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/ComputeKMeansFilter.cpp b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/ComputeKMeansFilter.cpp index 64d31fc922..cfc4eff4f4 100644 --- a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/ComputeKMeansFilter.cpp +++ b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/ComputeKMeansFilter.cpp @@ -80,8 +80,9 @@ Parameters ComputeKMeansFilter::parameters() const params.insertSeparator(Parameters::Separator{"Optional Data Mask"}); params.insertLinkableParameter(std::make_unique(k_UseMask_Key, "Use Mask Array", "Specifies whether or not to use a mask array", false)); - params.insert(std::make_unique(k_MaskArrayPath_Key, "Cell Mask Array", "DataPath to the boolean mask array. Values that are true will mark that cell/point as usable.", - DataPath{}, ArraySelectionParameter::AllowedTypes{DataType::boolean})); + params.insert(std::make_unique(k_MaskArrayPath_Key, "Cell Mask Array", + "DataPath to the boolean or uint8 mask array. Values that are true will mark that cell/point as usable.", DataPath{}, + ArraySelectionParameter::AllowedTypes{DataType::boolean, DataType::uint8})); params.insertSeparator(Parameters::Separator{"Input Data Objects"}); params.insert(std::make_unique(k_SelectedArrayPath_Key, "Attribute Array to Cluster", "The array to cluster from", DataPath{}, nx::core::GetAllNumericTypes())); diff --git a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/ComputeKMedoidsFilter.cpp b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/ComputeKMedoidsFilter.cpp index bff5c10c99..afe20e1798 100644 --- a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/ComputeKMedoidsFilter.cpp +++ b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/ComputeKMedoidsFilter.cpp @@ -73,8 +73,8 @@ Parameters ComputeKMedoidsFilter::parameters() const params.insertSeparator(Parameters::Separator{"Input Parameter(s)"}); params.insertLinkableParameter(std::make_unique(k_UseMask_Key, "Use Mask Array", "Specifies whether or not to use a mask array", false)); - params.insert(std::make_unique(k_MaskArrayPath_Key, "Mask Array", "DataPath to the boolean mask array. Values that are true will mark that cell/point as usable.", - DataPath{}, ArraySelectionParameter::AllowedTypes{DataType::boolean})); + params.insert(std::make_unique(k_MaskArrayPath_Key, "Mask Array", "DataPath to the boolean or uint8 mask array. Values that are true will mark that cell/point as usable.", + DataPath{}, ArraySelectionParameter::AllowedTypes{DataType::boolean, DataType::uint8})); params.insert(std::make_unique(k_InitClusters_Key, "Number of Clusters", "This will be the tuple size for Cluster Attribute Matrix and the values within", 0)); params.insert( std::make_unique(k_DistanceMetric_Key, "Distance Metric", "Distance Metric type to be used for calculations", to_underlying(KUtilities::DistanceMetric::Euclidean), diff --git a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/PointSampleTriangleGeometryFilter.cpp b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/PointSampleTriangleGeometryFilter.cpp index b48ead7f2c..f92bd16bbc 100644 --- a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/PointSampleTriangleGeometryFilter.cpp +++ b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/PointSampleTriangleGeometryFilter.cpp @@ -65,7 +65,7 @@ Parameters PointSampleTriangleGeometryFilter::parameters() const params.insertSeparator(Parameters::Separator{"Optional Data Mask"}); params.insertLinkableParameter(std::make_unique(k_UseMask_Key, "Use Mask Array", "Specifies whether or not to use a mask array", false)); params.insert(std::make_unique(k_MaskArrayPath_Key, "Mask Array", "DataPath to the boolean mask array. Values that are true will mark that cell/point as usable.", - DataPath{}, ArraySelectionParameter::AllowedTypes{DataType::boolean}, ArraySelectionParameter::AllowedComponentShapes{{1}})); + DataPath{}, ArraySelectionParameter::AllowedTypes{DataType::boolean, DataType::uint8}, ArraySelectionParameter::AllowedComponentShapes{{1}})); params.insertSeparator(Parameters::Separator{"Random Number Seed Parameters"}); params.insertLinkableParameter(std::make_unique(k_UseSeed_Key, "Use Seed for Random Generation", "When true the user will be able to put in a seed for random generation", false)); diff --git a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/RemoveFlaggedTrianglesFilter.cpp b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/RemoveFlaggedTrianglesFilter.cpp index ee2cd881f5..c9764a4d7a 100644 --- a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/RemoveFlaggedTrianglesFilter.cpp +++ b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/RemoveFlaggedTrianglesFilter.cpp @@ -55,7 +55,7 @@ Parameters RemoveFlaggedTrianglesFilter::parameters() const params.insert(std::make_unique(k_SelectedTriangleGeometryPath_Key, "Triangle|Quad Geometry", "The Triangle|Quad Geometry that will be processed.", DataPath(), GeometrySelectionParameter::AllowedTypes{IGeometry::Type::Triangle, IGeometry::Type::Quad})); params.insert(std::make_unique(k_MaskArrayPath_Key, "Mask", "The DataArrayPath to the mask array that marks each face as either true (remove) or false(keep).", DataPath{}, - ArraySelectionParameter::AllowedTypes{DataType::boolean}, ArraySelectionParameter::AllowedComponentShapes{{1}})); + ArraySelectionParameter::AllowedTypes{DataType::boolean, DataType::uint8}, ArraySelectionParameter::AllowedComponentShapes{{1}})); params.insertSeparator(Parameters::Separator{"Output Geometry"}); params.insert(std::make_unique(k_CreatedTriangleGeometryPath_Key, "Created Geometry", "The name of the created Triangle Geometry", DataPath({"ReducedGeometry"}))); diff --git a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/ScalarSegmentFeaturesFilter.cpp b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/ScalarSegmentFeaturesFilter.cpp index 18c8979b76..ba54a749d0 100644 --- a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/ScalarSegmentFeaturesFilter.cpp +++ b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/ScalarSegmentFeaturesFilter.cpp @@ -73,8 +73,8 @@ Parameters ScalarSegmentFeaturesFilter::parameters() const params.insertSeparator(Parameters::Separator{"Optional Data Mask"}); params.insertLinkableParameter(std::make_unique(k_UseMask_Key, "Use Mask Array", "Determines if a mask array is used for segmenting", false)); - params.insert(std::make_unique(k_MaskArrayPath_Key, "Cell Mask Array", "Path to the DataArray Mask", DataPath(), ArraySelectionParameter::AllowedTypes{DataType::boolean}, - ArraySelectionParameter::AllowedComponentShapes{{1}})); + params.insert(std::make_unique(k_MaskArrayPath_Key, "Cell Mask Array", "Path to the DataArray Mask", DataPath(), + ArraySelectionParameter::AllowedTypes{DataType::boolean, DataType::uint8}, ArraySelectionParameter::AllowedComponentShapes{{1}})); params.linkParameters(k_UseMask_Key, k_MaskArrayPath_Key, std::make_any(true)); params.insertSeparator(Parameters::Separator{"Input Cell Data"}); @@ -158,12 +158,6 @@ IFilter::PreflightResult ScalarSegmentFeaturesFilter::preflightImpl(const DataSt { return {nonstd::make_unexpected(std::vector{Error{k_MissingOrIncorrectGoodVoxelsArray, fmt::format("Mask array is not located at path: '{}'", goodVoxelsPath.toString())}})}; } - const GoodVoxelsArrayType* maskArrayPtr = dataStructure.getDataAs(goodVoxelsPath); - if(maskArrayPtr == nullptr) - { - return {nonstd::make_unexpected( - std::vector{Error{k_MissingOrIncorrectGoodVoxelsArray, fmt::format("Mask array at path '{}' is not of the correct type. It must be Bool.", goodVoxelsPath.toString())}})}; - } dataPaths.push_back(goodVoxelsPath); } @@ -204,9 +198,7 @@ Result<> ScalarSegmentFeaturesFilter::executeImpl(DataStructure& dataStructure, inputValues.pCellFeaturesPath = inputValues.pGridGeomPath.createChildPath(args.value(k_CellFeatureName_Key)); inputValues.pActiveArrayPath = inputValues.pCellFeaturesPath.createChildPath(args.value(k_ActiveArrayName_Key)); - nx::core::ScalarSegmentFeatures filterAlgorithm(dataStructure, &inputValues, shouldCancel, messageHandler); - Result<> result = filterAlgorithm(); - return result; + return ScalarSegmentFeatures(dataStructure, &inputValues, shouldCancel, messageHandler)(); } namespace diff --git a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/SilhouetteFilter.cpp b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/SilhouetteFilter.cpp index 3f65c316b8..dc6e054d73 100644 --- a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/SilhouetteFilter.cpp +++ b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/SilhouetteFilter.cpp @@ -69,8 +69,8 @@ Parameters SilhouetteFilter::parameters() const // Create the parameter descriptors that are needed for this filter params.insertSeparator(Parameters::Separator{"Optional Data Mask"}); params.insertLinkableParameter(std::make_unique(k_UseMask_Key, "Use Mask Array", "Specifies whether or not to use a mask array", false)); - params.insert(std::make_unique(k_MaskArrayPath_Key, "Mask Array", "DataPath to the boolean mask array. Values that are true will mark that cell/point as usable.", - DataPath{}, ArraySelectionParameter::AllowedTypes{DataType::boolean})); + params.insert(std::make_unique(k_MaskArrayPath_Key, "Mask Array", "DataPath to the boolean or uint8 mask array. Values that are true will mark that cell/point as usable.", + DataPath{}, ArraySelectionParameter::AllowedTypes{DataType::boolean, DataType::uint8})); params.insertSeparator(Parameters::Separator{"Input Cell Data"}); params.insert(std::make_unique(k_SelectedArrayPath_Key, "Attribute Array to Silhouette", "The DataPath to the input DataArray", DataPath{}, nx::core::GetAllNumericTypes())); diff --git a/src/simplnx/Utilities/DataArrayUtilities.cpp b/src/simplnx/Utilities/DataArrayUtilities.cpp index 645fc8f2fc..dfabfe6f33 100644 --- a/src/simplnx/Utilities/DataArrayUtilities.cpp +++ b/src/simplnx/Utilities/DataArrayUtilities.cpp @@ -285,10 +285,10 @@ std::unique_ptr InstantiateMaskCompare(IDataArray& maskArray) switch(maskArray.getDataType()) { case DataType::boolean: { - return std::make_unique(dynamic_cast(maskArray)); + return std::make_unique(dynamic_cast(maskArray).getDataStoreRef()); } case DataType::uint8: { - return std::make_unique(dynamic_cast(maskArray)); + return std::make_unique(dynamic_cast(maskArray).getDataStoreRef()); } default: throw std::runtime_error("InstantiateMaskCompare: The Mask Array being used is NOT of type bool or uint8."); diff --git a/src/simplnx/Utilities/DataArrayUtilities.hpp b/src/simplnx/Utilities/DataArrayUtilities.hpp index c2fa934823..d128c909b7 100644 --- a/src/simplnx/Utilities/DataArrayUtilities.hpp +++ b/src/simplnx/Utilities/DataArrayUtilities.hpp @@ -855,80 +855,81 @@ struct MaskCompare struct BoolMaskCompare : public MaskCompare { - BoolMaskCompare(BoolArray& array) - : m_Array(array) + BoolMaskCompare(AbstractDataStore& dataStore) + : m_DataStore(dataStore) { } ~BoolMaskCompare() noexcept override = default; - BoolArray& m_Array; + AbstractDataStore& m_DataStore; bool bothTrue(usize indexA, usize indexB) const override { - return m_Array.at(indexA) && m_Array.at(indexB); + return m_DataStore.at(indexA) && m_DataStore.at(indexB); } bool bothFalse(usize indexA, usize indexB) const override { - return !m_Array.at(indexA) && !m_Array.at(indexB); + return !m_DataStore.at(indexA) && !m_DataStore.at(indexB); } bool isTrue(usize index) const override { - return m_Array.at(index); + return m_DataStore.at(index); } void setValue(usize index, bool val) override { - m_Array[index] = val; + m_DataStore[index] = val; } usize getNumberOfTuples() const override { - return m_Array.getNumberOfTuples(); + return m_DataStore.getNumberOfTuples(); } usize getNumberOfComponents() const override { - return m_Array.getNumberOfComponents(); + return m_DataStore.getNumberOfComponents(); } usize countTrueValues() const override { - return std::count(m_Array.begin(), m_Array.end(), true); + return std::count(m_DataStore.begin(), m_DataStore.end(), true); } }; struct UInt8MaskCompare : public MaskCompare { - UInt8MaskCompare(UInt8Array& array) - : m_Array(array) + UInt8MaskCompare(AbstractDataStore& dataStore) + : m_DataStore(dataStore) { } ~UInt8MaskCompare() noexcept override = default; - UInt8Array& m_Array; + + AbstractDataStore& m_DataStore; bool bothTrue(usize indexA, usize indexB) const override { - return m_Array.at(indexA) != 0 && m_Array.at(indexB) != 0; + return m_DataStore.at(indexA) != 0 && m_DataStore.at(indexB) != 0; } bool bothFalse(usize indexA, usize indexB) const override { - return m_Array.at(indexA) == 0 && m_Array.at(indexB) == 0; + return m_DataStore.at(indexA) == 0 && m_DataStore.at(indexB) == 0; } bool isTrue(usize index) const override { - return m_Array.at(index) != 0; + return m_DataStore.at(index) != 0; } void setValue(usize index, bool val) override { - m_Array[index] = static_cast(val); + m_DataStore[index] = static_cast(val); } usize getNumberOfTuples() const override { - return m_Array.getNumberOfTuples(); + return m_DataStore.getNumberOfTuples(); } usize getNumberOfComponents() const override { - return m_Array.getNumberOfComponents(); + return m_DataStore.getNumberOfComponents(); } usize countTrueValues() const override { - const usize falseCount = std::count(m_Array.begin(), m_Array.end(), 0); + const usize falseCount = std::count(m_DataStore.begin(), m_DataStore.end(), 0); return getNumberOfTuples() - falseCount; } };