-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
FILTER: Concatenate Data Arrays (#1072)
* Add Concatenate Data Arrays filter with unit test and documentation. Signed-off-by: Joey Kleingers <[email protected]>
- Loading branch information
1 parent
af4f5c1
commit e6148a2
Showing
9 changed files
with
978 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
27 changes: 27 additions & 0 deletions
27
src/Plugins/SimplnxCore/docs/ConcatenateDataArraysFilter.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
# 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 will always output an array with tuple dimensions that are 1-dimensional. | ||
|
||
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. | ||
|
||
**NOTE:** If you are wanting to instead combine data arrays into a multi-component array, please see the [Combine Attribute Arrays](CombineAttributeArraysFilter.md) filter. | ||
|
||
% 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. |
51 changes: 51 additions & 0 deletions
51
src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ConcatenateDataArrays.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
#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); | ||
std::string arrayTypeName = outputDataArray.getTypeName(); | ||
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(to_underlying(ConcatenateDataArrays::ErrorCodes::InputArraysEqualAny), | ||
"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(ConcatenateDataArrays::ErrorCodes::InputArraysUnsupported), | ||
"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."); | ||
} | ||
} | ||
} |
169 changes: 169 additions & 0 deletions
169
src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ConcatenateDataArrays.hpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,169 @@ | ||
#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; | ||
|
||
// Error Codes | ||
enum class ErrorCodes : int32 | ||
{ | ||
EmptyInputArrays = -2300, | ||
OneInputArray = -2301, | ||
NonPositiveTupleDimValue = -2302, | ||
TypeNameMismatch = -2303, | ||
ComponentShapeMismatch = -2304, | ||
InputArraysEqualAny = -2305, | ||
InputArraysUnsupported = -2306 | ||
}; | ||
|
||
// Warning Codes | ||
enum class WarningCodes : int32 | ||
{ | ||
MultipleTupleDimsNotSupported = -100 | ||
}; | ||
|
||
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 |
Oops, something went wrong.