Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
#include "RequireMinNumNeighbors.hpp"

#include "simplnx/DataStructure/DataArray.hpp"

Check failure on line 3 in src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/RequireMinNumNeighbors.cpp

View workflow job for this annotation

GitHub Actions / clang_format_pr

code should be clang-formatted [-Wclang-format-violations]
#include "simplnx/DataStructure/Geometry/ImageGeom.hpp"
#include "simplnx/Utilities/DataArrayUtilities.hpp"
#include "simplnx/Utilities/DataStoreUtilities.hpp"
#include "simplnx/Utilities/DataGroupUtilities.hpp"
#include "simplnx/Utilities/FilterUtilities.hpp"
#include "simplnx/Utilities/NeighborUtilities.hpp"
Expand All @@ -12,7 +13,7 @@
namespace
{
Result<> CopyTupleFromArray(DataStructure& dataStructure, const DataPath& dataArrayPath, const std::vector<usize>& badFeatureIdIndexes, const AbstractDataStore<int32_t>& featureIds,
const std::vector<int32>& neighbors, const IFilter::MessageHandler& mesgHandler)
const AbstractDataStore<int32>& neighbors, const IFilter::MessageHandler& mesgHandler)
{
auto* voxelArray = dataStructure.getDataAs<IDataArray>(dataArrayPath);
auto arraySize = voxelArray->getSize();
Expand Down Expand Up @@ -55,32 +56,8 @@
RequireMinNumNeighbors::~RequireMinNumNeighbors() noexcept = default;

// -----------------------------------------------------------------------------
Result<> RequireMinNumNeighbors::operator()()
Result<> RequireMinNumNeighbors::CheckForAvailablePhase()
{
// If running on a single phase, validate that the user has not entered a phase number
// that is not in the system ; the filter would not crash otherwise, but the user should
// be notified of unanticipated behavior ; this cannot be done in the dataCheck since
// we don't have access to the data yet
auto& featureIds = m_DataStructure.getDataAs<Int32Array>(m_InputValues->FeatureIdsPath)->getDataStoreRef();
auto& numNeighbors = m_DataStructure.getDataAs<Int32Array>(m_InputValues->NumNeighborsPath)->getDataStoreRef();

auto& imageGeom = m_DataStructure.getDataRefAs<ImageGeom>(m_InputValues->ImageGeomPath);
usize totalPoints = imageGeom.getNumberOfCells();
usize totalFeatures = numNeighbors.getNumberOfTuples();

// The Cell Attribute Matrix is the parent of the "Feature Ids" array. Always.
DataPath cellDataAttrMatrixPath = m_InputValues->FeatureIdsPath.getParent();
std::optional<std::vector<DataPath>> result = nx::core::GetAllChildDataPaths(m_DataStructure, cellDataAttrMatrixPath, DataObject::Type::DataArray, m_InputValues->IgnoredVoxelArrayPaths);
if(!result.has_value())
{
return MakeErrorResult(-5556, fmt::format("Error fetching all Data Arrays from Attribute Matrix '{}'", cellDataAttrMatrixPath.toString()));
}
std::vector<DataPath> cellDataArrayPaths = result.value();

// Run the algorithm.
// This was checked up in the execute function (which is called before this function),
// so if we got this far then all should be good with the return. We might get
// an empty vector<> but that is OK.
if(m_InputValues->ApplyToSinglePhase)
{
auto& featurePhases = m_DataStructure.getDataAs<Int32Array>(m_InputValues->FeaturePhasesPath)->getDataStoreRef();
Expand All @@ -104,8 +81,12 @@
}
}

return {};
}

Result<> RequireMinNumNeighbors::CheckNumNeighbors(Int32AbstractDataStore& numNeighbors, usize totalFeatures, std::vector<bool>& activeObjects)
{
bool valid = false;
std::vector<bool> activeObjects(totalFeatures, true);
if(m_InputValues->ApplyToSinglePhase)
{
auto& featurePhases = m_DataStructure.getDataAs<Int32Array>(m_InputValues->FeaturePhasesPath)->getDataStoreRef();
Expand Down Expand Up @@ -139,23 +120,13 @@
{
return MakeErrorResult(-55569, "The minimum number of neighbors is larger than the Feature with the most neighbors. All Features would be removed");
}
if(m_ShouldCancel)
{
return {};
}
auto numInactiveObjects = std::count(activeObjects.begin(), activeObjects.end(), false);
m_MessageHandler({nx::core::IFilter::Message::Type::Info, fmt::format("Removing {} features", numInactiveObjects)});

// Mark all features to be removed with a -1 value.
for(usize i = 0; i < totalPoints; i++)
{
int32 featureId = featureIds[i];
if(!activeObjects[featureId])
{
featureIds[i] = -1;
}
}
return {};
}

// -----------------------------------------------------------------------------
Result<> RequireMinNumNeighbors::FindFeatureCount(ImageGeom& imageGeom, std::vector<DataPath>& cellDataArrayPaths, Int32AbstractDataStore& featureIds, Int32AbstractDataStore& numNeighbors)
{
SizeVec3 udims = imageGeom.getDimensions();
std::array<int64, 3> dims = {
static_cast<int64>(udims[0]),
Expand All @@ -164,7 +135,10 @@
};

// Create a temp array to hold the neighbor values
std::vector<int32> neighbors(featureIds.getNumberOfTuples(), -1);
// This should be able to store out-of-core data sizes
auto neighborsPtr = DataStoreUtilities::CreateDataStore<int32>({featureIds.getNumberOfTuples()}, {1});

Check failure on line 139 in src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/RequireMinNumNeighbors.cpp

View workflow job for this annotation

GitHub Actions / build (windows-2022, v143)

'nx::core::DataStoreUtilities::CreateDataStore': no matching overloaded function found [D:\a\simplnx\simplnx\build\Plugins\SimplnxCore\SimplnxCore.vcxproj]

Check failure on line 139 in src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/RequireMinNumNeighbors.cpp

View workflow job for this annotation

GitHub Actions / build (ubuntu-22.04, clang++-14)

no matching function for call to 'CreateDataStore'

Check failure on line 139 in src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/RequireMinNumNeighbors.cpp

View workflow job for this annotation

GitHub Actions / build (ubuntu-22.04, g++-11)

too few arguments to function ‘std::shared_ptr<nx::core::AbstractDataStore<T> > nx::core::DataStoreUtilities::CreateDataStore(const ShapeType&, const ShapeType&, nx::core::IDataAction::Mode, std::string) [with T = int; nx::core::ShapeType = std::vector<long unsigned int>; std::string = std::__cxx11::basic_string<char>]’

Check failure on line 139 in src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/RequireMinNumNeighbors.cpp

View workflow job for this annotation

GitHub Actions / build (macos-15)

no matching function for call to 'CreateDataStore'

Check failure on line 139 in src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/RequireMinNumNeighbors.cpp

View workflow job for this annotation

GitHub Actions / build (macos-14)

no matching function for call to 'CreateDataStore'
AbstractDataStore<int32>& neighbors = *neighborsPtr.get();

Check failure on line 140 in src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/RequireMinNumNeighbors.cpp

View workflow job for this annotation

GitHub Actions / build (windows-2022, v143)

'neighbors': references must be initialized [D:\a\simplnx\simplnx\build\Plugins\SimplnxCore\SimplnxCore.vcxproj]

Check failure on line 140 in src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/RequireMinNumNeighbors.cpp

View workflow job for this annotation

GitHub Actions / build (windows-2022, v143)

'neighborsPtr': cannot be used before it is initialized [D:\a\simplnx\simplnx\build\Plugins\SimplnxCore\SimplnxCore.vcxproj]
neighbors.fill(-1);

int32 current = 0;
int32 most = 0;
Expand All @@ -181,6 +155,12 @@
int32 featureName = 0;
int32 feature = 0;
int32 neighbor = 0;

// Update featureCount for out-of-core data sizes
auto featureCountPtr = DataStoreUtilities::CreateDataStore<int32>({numFeatures + 1}, {1});

Check failure on line 160 in src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/RequireMinNumNeighbors.cpp

View workflow job for this annotation

GitHub Actions / build (windows-2022, v143)

'nx::core::DataStoreUtilities::CreateDataStore': no matching overloaded function found [D:\a\simplnx\simplnx\build\Plugins\SimplnxCore\SimplnxCore.vcxproj]

Check failure on line 160 in src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/RequireMinNumNeighbors.cpp

View workflow job for this annotation

GitHub Actions / build (ubuntu-22.04, clang++-14)

no matching function for call to 'CreateDataStore'

Check failure on line 160 in src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/RequireMinNumNeighbors.cpp

View workflow job for this annotation

GitHub Actions / build (ubuntu-22.04, g++-11)

too few arguments to function ‘std::shared_ptr<nx::core::AbstractDataStore<T> > nx::core::DataStoreUtilities::CreateDataStore(const ShapeType&, const ShapeType&, nx::core::IDataAction::Mode, std::string) [with T = int; nx::core::ShapeType = std::vector<long unsigned int>; std::string = std::__cxx11::basic_string<char>]’

Check failure on line 160 in src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/RequireMinNumNeighbors.cpp

View workflow job for this annotation

GitHub Actions / build (macos-15)

no matching function for call to 'CreateDataStore'

Check failure on line 160 in src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/RequireMinNumNeighbors.cpp

View workflow job for this annotation

GitHub Actions / build (macos-14)

no matching function for call to 'CreateDataStore'
AbstractDataStore<int32>& featureCount = *featureCountPtr.get();

Check failure on line 161 in src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/RequireMinNumNeighbors.cpp

View workflow job for this annotation

GitHub Actions / build (windows-2022, v143)

'featureCount': references must be initialized [D:\a\simplnx\simplnx\build\Plugins\SimplnxCore\SimplnxCore.vcxproj]

Check failure on line 161 in src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/RequireMinNumNeighbors.cpp

View workflow job for this annotation

GitHub Actions / build (windows-2022, v143)

'featureCountPtr': cannot be used before it is initialized [D:\a\simplnx\simplnx\build\Plugins\SimplnxCore\SimplnxCore.vcxproj]
featureCount.fill(0);

std::vector<int32> voteCount(numFeatures + 1, 0);
std::vector<usize> badFeatureIdIndexes;

Expand Down Expand Up @@ -218,11 +198,13 @@
}
neighborPoint = voxelIndex + neighborVoxelIndexOffsets[faceIndex];
{
feature = featureIds[neighborPoint];
voteCount[feature]++;
current = voteCount[feature];
//feature = featureIds[neighborPoint];

Check failure on line 203 in src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/RequireMinNumNeighbors.cpp

View workflow job for this annotation

GitHub Actions / clang_format_pr

code should be clang-formatted [-Wclang-format-violations]
if(feature >= 0)
{
voteCount[feature]++;
current = voteCount[feature];
featureCount[feature].inc();
current = featureCount[feature];
if(current > most)
{
most = current;
Expand All @@ -233,7 +215,7 @@
}

// Reset the voteCount array to all zeros
std::fill(voteCount.begin(), voteCount.end(), 0);
std::fill(voteCount.begin(), voteCount.end(), 0); //
}
else if(featureName >= numFeatures)
{
Expand Down Expand Up @@ -266,6 +248,70 @@
}
}

return {};
}

// -----------------------------------------------------------------------------
Result<> RequireMinNumNeighbors::operator()()
{
// If running on a single phase, validate that the user has not entered a phase number
// that is not in the system ; the filter would not crash otherwise, but the user should
// be notified of unanticipated behavior ; this cannot be done in the dataCheck since
// we don't have access to the data yet
auto& featureIds = m_DataStructure.getDataAs<Int32Array>(m_InputValues->FeatureIdsPath)->getDataStoreRef();
auto& numNeighbors = m_DataStructure.getDataAs<Int32Array>(m_InputValues->NumNeighborsPath)->getDataStoreRef();

auto& imageGeom = m_DataStructure.getDataRefAs<ImageGeom>(m_InputValues->ImageGeomPath);
usize totalPoints = imageGeom.getNumberOfCells();
usize totalFeatures = numNeighbors.getNumberOfTuples();

// The Cell Attribute Matrix is the parent of the "Feature Ids" array. Always.
DataPath cellDataAttrMatrixPath = m_InputValues->FeatureIdsPath.getParent();
std::optional<std::vector<DataPath>> result = nx::core::GetAllChildDataPaths(m_DataStructure, cellDataAttrMatrixPath, DataObject::Type::DataArray, m_InputValues->IgnoredVoxelArrayPaths);
if(!result.has_value())
{
return MakeErrorResult(-5556, fmt::format("Error fetching all Data Arrays from Attribute Matrix '{}'", cellDataAttrMatrixPath.toString()));
}
std::vector<DataPath> cellDataArrayPaths = result.value();

// Run the algorithm.
// This was checked up in the execute function (which is called before this function),
// so if we got this far then all should be good with the return. We might get
// an empty vector<> but that is OK.
if (Result<> result2 = CheckForAvailablePhase(); result2.invalid())

Check failure on line 281 in src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/RequireMinNumNeighbors.cpp

View workflow job for this annotation

GitHub Actions / clang_format_pr

code should be clang-formatted [-Wclang-format-violations]
{
return result2;
}

std::vector<bool> activeObjects(totalFeatures, true);
if (Result<> result2 = CheckNumNeighbors(numNeighbors, totalFeatures, activeObjects); result2.invalid())

Check failure on line 287 in src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/RequireMinNumNeighbors.cpp

View workflow job for this annotation

GitHub Actions / clang_format_pr

code should be clang-formatted [-Wclang-format-violations]
{
return result2;
}

if(m_ShouldCancel)
{
return {};
}
auto numInactiveObjects = std::count(activeObjects.begin(), activeObjects.end(), false);
m_MessageHandler({nx::core::IFilter::Message::Type::Info, fmt::format("Removing {} features", numInactiveObjects)});

// Mark all features to be removed with a -1 value.
for(usize i = 0; i < totalPoints; i++)
{
int32 featureId = featureIds[i];
if(!activeObjects[featureId])
{
featureIds[i] = -1;
}
}

if (Result<> result2 = FindFeatureCount(imageGeom, cellDataArrayPaths, featureIds, numNeighbors); result2.invalid())

Check failure on line 309 in src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/RequireMinNumNeighbors.cpp

View workflow job for this annotation

GitHub Actions / clang_format_pr

code should be clang-formatted [-Wclang-format-violations]
{
return result2;
}

Check failure on line 312 in src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/RequireMinNumNeighbors.cpp

View workflow job for this annotation

GitHub Actions / clang_format_pr

code should be clang-formatted [-Wclang-format-violations]

// Remove inactive objects
int32 count = 0;
for(const auto& value : activeObjects)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

#include "SimplnxCore/SimplnxCore_export.hpp"

#include "simplnx/DataStructure/AbstractDataStore.hpp"
#include "simplnx/DataStructure/DataPath.hpp"
#include "simplnx/DataStructure/DataStructure.hpp"
#include "simplnx/DataStructure/Geometry/ImageGeom.hpp"
#include "simplnx/Filter/IFilter.hpp"
#include "simplnx/Parameters/MultiArraySelectionParameter.hpp"

Expand Down Expand Up @@ -38,6 +40,11 @@ class SIMPLNXCORE_EXPORT RequireMinNumNeighbors

Result<> operator()();

protected:
Result<> CheckForAvailablePhase();
Result<> CheckNumNeighbors(Int32AbstractDataStore& numNeighbors, usize totalFeatures, std::vector<bool>& activeObjects);
Result<> FindFeatureCount(ImageGeom& imageGeom, std::vector<DataPath>& cellDataArrayPaths, Int32AbstractDataStore& featureIds, Int32AbstractDataStore& numNeighbors);

private:
DataStructure& m_DataStructure;
const RequireMinNumNeighborsInputValues* m_InputValues = nullptr;
Expand Down
Loading