Skip to content

Commit

Permalink
Add Concatenate Data Arrays filter 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 Sep 16, 2024
1 parent 17241eb commit 417700b
Show file tree
Hide file tree
Showing 8 changed files with 1,065 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/Plugins/SimplnxCore/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ set(FilterList
ComputeVectorColorsFilter
ComputeVertexToTriangleDistancesFilter
ComputeVolumeFractionsFilter
ConcatenateDataArraysFilter
ConditionalSetValueFilter
ConvertColorToGrayScaleFilter
ConvertDataFilter
Expand Down Expand Up @@ -167,6 +168,7 @@ set(AlgorithmList
ComputeTriangleGeomCentroids
ComputeVectorColors
ComputeVertexToTriangleDistances
ConcatenateDataArrays
ConvertColorToGrayScale
ConvertData
CreatePythonSkeleton
Expand Down
23 changes: 23 additions & 0 deletions src/Plugins/SimplnxCore/docs/ConcatenateDataArraysFilter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Concatenate Data Arrays

## Group (Subgroup)

Core (Generation)

## Description

This **Filter** concatenates multiple input arrays by taking a list of input arrays and appending their data sequentially into a single output array. The concatenation process involves combining the arrays such that the order of the input arrays directly affects the structure of the output. For example, if the first input array contains 5 tuples and the second contains 7 tuples, the resulting output array will have 12 tuples, with the tuples from the second array appended directly after those from the first array.

This filter is designed to handle arrays of matching array types and component dimensions. If the arrays have different array types or component dimensions, the filter will raise an error.

% 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
@@ -0,0 +1,44 @@
#include "ConcatenateDataArrays.hpp"

#include "simplnx/DataStructure/IArray.hpp"

using namespace nx::core;

// -----------------------------------------------------------------------------
ConcatenateDataArrays::ConcatenateDataArrays(DataStructure& dataStructure, const IFilter::MessageHandler& msgHandler, const std::atomic_bool& shouldCancel,
ConcatenateDataArraysInputValues* inputValues)
: m_DataStructure(dataStructure)
, m_InputValues(inputValues)
, m_ShouldCancel(shouldCancel)
, m_MessageHandler(msgHandler)
{
}

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

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

// -----------------------------------------------------------------------------
Result<> ConcatenateDataArrays::operator()()
{
const auto& outputDataArray = m_DataStructure.getDataRefAs<IArray>(m_InputValues->OutputArrayPath);
switch(outputDataArray.getArrayType())
{
case IArray::ArrayType::DataArray: {
return ConcatenateArrays(m_DataStructure, m_InputValues->InputArrayPaths, m_InputValues->OutputArrayPath, m_MessageHandler, m_ShouldCancel);
}
case IArray::ArrayType::StringArray: {
return ConcatenateArraysImpl<StringArray>(m_DataStructure, m_InputValues->InputArrayPaths, m_InputValues->OutputArrayPath, m_MessageHandler, m_ShouldCancel);
}
case IArray::ArrayType::NeighborListArray: {
return ConcatenateNeighborLists(m_DataStructure, m_InputValues->InputArrayPaths, m_InputValues->OutputArrayPath, m_MessageHandler, m_ShouldCancel);
}
case IArray::ArrayType::Any:
return MakeErrorResult(-3001, "The input arrays list has array type 'Any'. Only array types 'DataArray', 'StringArray', and NeighborList' are allowed.");
}
}

Check failure on line 44 in src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ConcatenateDataArrays.cpp

View workflow job for this annotation

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

control reaches end of non-void function [-Werror=return-type]

Check failure on line 44 in src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ConcatenateDataArrays.cpp

View workflow job for this annotation

GitHub Actions / build (windows-2022, v142)

'nx::core::ConcatenateDataArrays::operator()': not all control paths return a value [D:\a\simplnx\simplnx\build\Plugins\SimplnxCore\SimplnxCore.vcxproj]

Check failure on line 44 in src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ConcatenateDataArrays.cpp

View workflow job for this annotation

GitHub Actions / build (windows-2022, v143)

'nx::core::ConcatenateDataArrays::operator()': not all control paths return a value [D:\a\simplnx\simplnx\build\Plugins\SimplnxCore\SimplnxCore.vcxproj]
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/DataStructure.hpp"
#include "simplnx/DataStructure/NeighborList.hpp"
#include "simplnx/DataStructure/StringArray.hpp"
#include "simplnx/Filter/IFilter.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 ConcatenateArraysImpl(DataStructure& dataStructure, const std::vector<DataPath>& inputArrayPaths,
const DataPath& outputArrayPath, const IFilter::MessageHandler& messageHandler,
const std::atomic_bool& shouldCancel)
{
auto& outputDataArray = dataStructure.getDataRefAs<ArrayType>(outputArrayPath);
usize destTupleOffset = 0;
for(const auto& inputArrayPath : inputArrayPaths)
{
if(shouldCancel)
{
return {};
}

messageHandler({IFilter::Message::Type::Info, fmt::format("Concatenating array '{}'...", inputArrayPath.toString())});
const auto& inputDataArray = dataStructure.getDataRefAs<ArrayType>(inputArrayPath);
auto result = CopyFromArray::CopyData(inputDataArray, outputDataArray, destTupleOffset, 0, inputDataArray.getNumberOfTuples());
if(result.invalid())
{
return result;
}
destTupleOffset += inputDataArray.getNumberOfTuples();
}

return {};
}

template <typename T>
Result<> ConcatenateNeighborListsImpl(DataStructure& dataStructure, const std::vector<DataPath>& inputArrayPaths, const DataPath& outputArrayPath, const IFilter::MessageHandler& messageHandler,
const std::atomic_bool& shouldCancel)
{
auto& outputNeighborList = dataStructure.getDataRefAs<NeighborList<T>>(outputArrayPath);
int32 currentOutputTuple = 0;
for(const auto& inputNeighborListPath : inputArrayPaths)
{
if(shouldCancel)
{
return {};
}

messageHandler({IFilter::Message::Type::Info, fmt::format("Concatenating neighbor list '{}'...", inputNeighborListPath.toString())});
const auto& inputNeighborList = dataStructure.getDataRefAs<NeighborList<T>>(inputNeighborListPath);
for(int32 listIdx = 0; listIdx < inputNeighborList.getNumberOfLists(); ++listIdx)
{
outputNeighborList.setList(currentOutputTuple, inputNeighborList.getList(listIdx));
currentOutputTuple++;
}
}

return {};
}

struct SIMPLNXCORE_EXPORT ConcatenateDataArraysInputValues
{
std::vector<DataPath> InputArrayPaths;
DataPath OutputArrayPath;
};

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

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

Result<> operator()();

const std::atomic_bool& getCancel();

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

struct ConcatenateDataArraysTemplateImpl
{
template <typename T>
void operator()(DataStructure& dataStructure, const std::vector<DataPath>& inputArrayPaths, const DataPath& outputArrayPath, const IFilter::MessageHandler& messageHandler,
const std::atomic_bool& shouldCancel, Result<>& result)
{
result = ConcatenateArraysImpl<DataArray<T>>(dataStructure, inputArrayPaths, outputArrayPath, messageHandler, shouldCancel);
}
};

struct ConcatenateNeighborListsTemplateImpl
{
template <typename T>
void operator()(DataStructure& dataStructure, const std::vector<DataPath>& inputArrayPaths, const DataPath& outputArrayPath, const IFilter::MessageHandler& messageHandler,
const std::atomic_bool& shouldCancel, Result<>& result)
{
result = ConcatenateNeighborListsImpl<T>(dataStructure, inputArrayPaths, outputArrayPath, messageHandler, shouldCancel);
}
};

static Result<> ConcatenateArrays(DataStructure& dataStructure, const std::vector<DataPath>& inputArrayPaths, const DataPath& outputArrayPath, const IFilter::MessageHandler& messageHandler,
const std::atomic_bool& shouldCancel)
{
const auto& outputDataArray = dataStructure.getDataRefAs<IDataArray>(outputArrayPath);
Result<> result;
ExecuteDataFunction(ConcatenateDataArraysTemplateImpl{}, outputDataArray.getDataType(), dataStructure, inputArrayPaths, outputArrayPath, messageHandler, shouldCancel, result);
return result;
}

static Result<> ConcatenateNeighborLists(DataStructure& dataStructure, const std::vector<DataPath>& inputArrayPaths, const DataPath& outputArrayPath, const IFilter::MessageHandler& messageHandler,
const std::atomic_bool& shouldCancel)
{
const auto& outputNeighborList = dataStructure.getDataRefAs<INeighborList>(outputArrayPath);
Result<> result;
ExecuteNeighborFunction(ConcatenateNeighborListsTemplateImpl{}, outputNeighborList.getDataType(), dataStructure, inputArrayPaths, outputArrayPath, messageHandler, shouldCancel, result);
return result;
}
};

} // namespace nx::core
Loading

0 comments on commit 417700b

Please sign in to comment.