Skip to content

Commit

Permalink
Add ReshapeDataArrayFilter with unit test and documentation.
Browse files Browse the repository at this point in the history
Signed-off-by: Joey Kleingers <[email protected]>
  • Loading branch information
joeykleingers committed Oct 3, 2024
1 parent 03db1b0 commit fee1460
Show file tree
Hide file tree
Showing 9 changed files with 937 additions and 6 deletions.
2 changes: 2 additions & 0 deletions src/Plugins/SimplnxCore/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ set(FilterList
ReplaceElementAttributesWithNeighborValuesFilter
ResampleImageGeomFilter
ResampleRectGridToImageGeomFilter
ReshapeDataArrayFilter
ReverseTriangleWindingFilter
RobustAutomaticThresholdFilter
RotateSampleRefFrameFilter
Expand Down Expand Up @@ -209,6 +210,7 @@ set(AlgorithmList
ReplaceElementAttributesWithNeighborValues
ResampleImageGeom
ResampleRectGridToImageGeom
ReshapeDataArray
ScalarSegmentFeatures
SharedFeatureFace
Silhouette
Expand Down
23 changes: 23 additions & 0 deletions src/Plugins/SimplnxCore/docs/ReshapeDataArrayFilter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Reshape Data Array

## Group (Subgroup)

Core (Generation)

## Description

This **Filter** is used to modify the tuple shape of Data Arrays, Neighbor Lists, and String Arrays within a data structure. It validates the new tuple dimensions to ensure they are positive and differ from the current shape, preventing unnecessary or invalid reshapes.

**NOTE:** If the input array is a Neighbor List or String Array, the filter will throw a warning if the new tuple dimensions are multi-dimensional. This is because these array types do not support multi-dimensional tuple dimensions and the filter will default to reshaping the data to an equivalent 1-dimensional number of tuples.

% Auto generated parameter table will be inserted here

## Example Pipelines

## License & Copyright

Please see the description file distributed with this **Plugin**

## DREAM3D-NX Help

If you need help, need to file a bug report or want to request a new feature, please head over to the [DREAM3DNX-Issues](https://github.com/BlueQuartzSoftware/DREAM3DNX-Issues/discussions) GitHub site where the community of DREAM3D-NX users can help answer your questions.
Original file line number Diff line number Diff line change
Expand Up @@ -111,12 +111,6 @@ class SIMPLNXCORE_EXPORT ConcatenateDataArrays
InputArraysUnsupported = -2306
};

// Warning Codes
enum class WarningCodes : int32
{
MultipleTupleDimsNotSupported = -100
};

Result<> operator()();

const std::atomic_bool& getCancel();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#include "ReshapeDataArray.hpp"

using namespace nx::core;

// -----------------------------------------------------------------------------
ReshapeDataArray::ReshapeDataArray(DataStructure& dataStructure, const IFilter::MessageHandler& mesgHandler, const std::atomic_bool& shouldCancel, ReshapeDataArrayInputValues* inputValues)
: m_DataStructure(dataStructure)
, m_InputValues(inputValues)
, m_ShouldCancel(shouldCancel)
, m_MessageHandler(mesgHandler)
{
}

// -----------------------------------------------------------------------------
ReshapeDataArray::~ReshapeDataArray() noexcept = default;

// -----------------------------------------------------------------------------
const std::atomic_bool& ReshapeDataArray::getCancel()
{
return m_ShouldCancel;
}

// -----------------------------------------------------------------------------
Result<> ReshapeDataArray::operator()()
{
auto outputArrayPath = m_InputValues->InputArrayPath.getParent().createChildPath(fmt::format(".{}", m_InputValues->InputArrayPath.getTargetName()));
auto& outputArray = m_DataStructure.getDataRefAs<IArray>(outputArrayPath);

std::string arrayTypeName = outputArray.getTypeName();
switch(outputArray.getArrayType())
{
case IArray::ArrayType::DataArray: {
return ReshapeArray(m_DataStructure, m_InputValues->InputArrayPath, outputArrayPath, m_MessageHandler);
}
case IArray::ArrayType::StringArray: {
return ReshapeArrayImpl<StringArray>(m_DataStructure, m_InputValues->InputArrayPath, outputArrayPath, m_MessageHandler);
}
case IArray::ArrayType::NeighborListArray: {
return ReshapeNeighborList(m_DataStructure, m_InputValues->InputArrayPath, outputArrayPath, m_MessageHandler);
}
case IArray::ArrayType::Any: {
return MakeErrorResult(to_underlying(ReshapeDataArray::ErrorCodes::InputArrayEqualsAny),
"Every array in the input arrays list has array type 'Any'. This SHOULD NOT be possible, so please contact the developers.");
}
default: {
return MakeErrorResult(to_underlying(ReshapeDataArray::ErrorCodes::InputArrayUnsupported),
"Every array in the input arrays list has array type '{}'. This is an array type that is currently not supported by this filter, so please contact the developers.");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
#pragma once

#include "SimplnxCore/SimplnxCore_export.hpp"

#include "simplnx/DataStructure/DataArray.hpp"
#include "simplnx/DataStructure/StringArray.hpp"
#include "simplnx/Filter/IFilter.hpp"
#include "simplnx/Parameters/DynamicTableParameter.hpp"
#include "simplnx/Utilities/DataArrayUtilities.hpp"
#include "simplnx/Utilities/FilterUtilities.hpp"

namespace nx::core
{
template <typename T>
struct is_allowed_array_type : std::false_type
{
};

template <typename T>
struct is_allowed_array_type<DataArray<T>> : std::true_type
{
};

template <>
struct is_allowed_array_type<StringArray> : std::true_type
{
};

template <typename ArrayType>
typename std::enable_if<is_allowed_array_type<ArrayType>::value, Result<>>::type ReshapeArrayImpl(DataStructure& dataStructure, const DataPath& inputArrayPath, const DataPath& outputArrayPath,
const IFilter::MessageHandler& messageHandler)
{
auto& inputDataArray = dataStructure.getDataRefAs<ArrayType>(inputArrayPath);
auto& outputDataArray = dataStructure.getDataRefAs<ArrayType>(outputArrayPath);
messageHandler({IFilter::Message::Type::Info, fmt::format("Reshaping data array '{}' from [{}] to [{}]...", inputArrayPath.toString(), fmt::join(inputDataArray.getTupleShape(), ","),
fmt::join(outputDataArray.getTupleShape(), ","))});
usize tuplesToCopy = std::min(inputDataArray.getNumberOfTuples(), outputDataArray.getNumberOfTuples());
auto result = CopyFromArray::CopyData(inputDataArray, outputDataArray, 0, 0, tuplesToCopy);
if(result.invalid())
{
return result;
}

return {};
}

template <typename T>
Result<> ReshapeNeighborListImpl(DataStructure& dataStructure, const DataPath& inputArrayPath, const DataPath& outputArrayPath, const IFilter::MessageHandler& messageHandler)
{
const auto& inputNeighborList = dataStructure.getDataRefAs<NeighborList<T>>(inputArrayPath);
auto& outputNeighborList = dataStructure.getDataRefAs<NeighborList<T>>(outputArrayPath);

messageHandler({IFilter::Message::Type::Info, fmt::format("Reshaping neighbor list '{}' from [{}] to [{}]...", inputArrayPath.toString(), fmt::join(inputNeighborList.getTupleShape(), ","),
fmt::join(outputNeighborList.getTupleShape(), ","))});
for(int32 listIdx = 0; listIdx < outputNeighborList.getNumberOfTuples(); ++listIdx)
{
if(listIdx < inputNeighborList.getNumberOfTuples())
{
outputNeighborList.setList(listIdx, inputNeighborList.getList(listIdx));
}
else
{
typename NeighborList<T>::SharedVectorType inputList(new std::vector<T>({}));
outputNeighborList.setList(listIdx, inputList);
}
}

return {};
}

struct SIMPLNXCORE_EXPORT ReshapeDataArrayInputValues
{
DataPath InputArrayPath;
DynamicTableParameter::ValueType TupleDims;
};

/**
* @class
*/
class SIMPLNXCORE_EXPORT ReshapeDataArray
{
public:
ReshapeDataArray(DataStructure& dataStructure, const IFilter::MessageHandler& mesgHandler, const std::atomic_bool& shouldCancel, ReshapeDataArrayInputValues* inputValues);
~ReshapeDataArray() noexcept;

ReshapeDataArray(const ReshapeDataArray&) = delete;
ReshapeDataArray(ReshapeDataArray&&) noexcept = delete;
ReshapeDataArray& operator=(const ReshapeDataArray&) = delete;
ReshapeDataArray& operator=(ReshapeDataArray&&) noexcept = delete;

// Error Codes
enum class ErrorCodes : int32
{
NonPositiveTupleDimValue = -3501,
InputArrayEqualsAny = -3502,
InputArrayUnsupported = -3503,
TupleShapesEqual = -3504
};

enum class WarningCodes : int32
{
NeighborListMultipleTupleDims = -100,
StringArrayMultipleTupleDims = -101
};

Result<> operator()();

const std::atomic_bool& getCancel();

private:
DataStructure& m_DataStructure;
const ReshapeDataArrayInputValues* m_InputValues = nullptr;
const std::atomic_bool& m_ShouldCancel;
const IFilter::MessageHandler& m_MessageHandler;

struct ReshapeDataArrayTemplateImpl
{
template <typename T>
void operator()(DataStructure& dataStructure, const DataPath& inputArrayPath, const DataPath& outputArrayPath, const IFilter::MessageHandler& messageHandler, Result<>& result)
{
result = ReshapeArrayImpl<DataArray<T>>(dataStructure, inputArrayPath, outputArrayPath, messageHandler);
}
};

struct ReshapeNeighborListTemplateImpl
{
template <typename T>
void operator()(DataStructure& dataStructure, const DataPath& inputArrayPath, const DataPath& outputArrayPath, const IFilter::MessageHandler& messageHandler, Result<>& result)
{
result = ReshapeNeighborListImpl<T>(dataStructure, inputArrayPath, outputArrayPath, messageHandler);
}
};

static Result<> ReshapeArray(DataStructure& dataStructure, const DataPath& inputArrayPath, const DataPath& outputArrayPath, const IFilter::MessageHandler& messageHandler)
{
const auto& outputDataArray = dataStructure.getDataRefAs<IDataArray>(outputArrayPath);
Result<> result;
ExecuteDataFunction(ReshapeDataArrayTemplateImpl{}, outputDataArray.getDataType(), dataStructure, inputArrayPath, outputArrayPath, messageHandler, result);
return result;
}

static Result<> ReshapeNeighborList(DataStructure& dataStructure, const DataPath& inputArrayPath, const DataPath& outputArrayPath, const IFilter::MessageHandler& messageHandler)
{
const auto& outputNeighborList = dataStructure.getDataRefAs<INeighborList>(outputArrayPath);
Result<> result;
ExecuteNeighborFunction(ReshapeNeighborListTemplateImpl{}, outputNeighborList.getDataType(), dataStructure, inputArrayPath, outputArrayPath, messageHandler, result);
return result;
}
};

} // namespace nx::core
Loading

0 comments on commit fee1460

Please sign in to comment.