Skip to content

Commit 68f1eca

Browse files
committed
FILT: Port ComputeArrayNorm from simpl to simplnx.
1 parent 296afc2 commit 68f1eca

7 files changed

Lines changed: 441 additions & 0 deletions

File tree

CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ set(${PLUGIN_NAME}_SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR})
2727
# These are all the filters in the plugin. All filters should be kept in the
2828
# SimplnxReview/src/SimplnxReview/Filters/ directory.
2929
set(FilterList
30+
ComputeArrayNormFilter
31+
ComputeGroupingDensityFilter
3032
ComputeLocalAverageCAxisMisalignmentsFilter
3133
ComputeMicroTextureRegionsFilter
3234
ComputeSaltykovSizesFilter
@@ -43,6 +45,8 @@ set(ActionList
4345
# This should be integrated with the `create_simplnx_plugin` function call
4446
# ------------------------------------------------------------------------------
4547
set(AlgorithmList
48+
ComputeArrayNorm
49+
ComputeGroupingDensity
4650
ComputeLocalAverageCAxisMisalignments
4751
ComputeMicroTextureRegions
4852
ComputeSaltykovSizes

docs/ComputeArrayNormFilter.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Compute Array Norm
2+
3+
## Group (Subgroup)
4+
5+
SimplnxReview (Statistics)
6+
7+
## Description
8+
9+
This **Filter** computes the p<sup>th</sup> norm of an **Attribute Array**. Specifically, for each tuple of the array, the following is computed:
10+
11+
$$\left\| \mathbf{x} \right\| _p := \bigg( \sum_{i=1}^n \left| x_i \right| ^p \bigg) ^{1/p}$$
12+
13+
where $n$ is the number of components for the **Attribute Array**.
14+
15+
- When $p = 2$, this results in the *Euclidean norm*
16+
- When $p = 1$, this results in the *Manhattan norm* (also called the *taxicab norm*)
17+
18+
The p-space value may be any real number greater than or equal to zero. When $0 \leq p < 1$, the result may not strictly be a *norm* in the exact mathematical sense. Additionally, when $p = 0$, the result is simply the number of components for the **Attribute Array**.
19+
20+
**Note:** If the input array is a scalar array (1 component), the output array will contain the same values as the input array, but in 32-bit floating point precision.
21+
22+
% Auto generated parameter table will be inserted here
23+
24+
## Example Pipelines
25+
26+
## License & Copyright
27+
28+
Please see the description file distributed with this plugin.
29+
30+
## DREAM3D-NX Help
31+
32+
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.
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
#include "ComputeArrayNorm.hpp"
2+
3+
#include "simplnx/DataStructure/DataArray.hpp"
4+
#include "simplnx/Utilities/DataArrayUtilities.hpp"
5+
#include "simplnx/Utilities/FilterUtilities.hpp"
6+
7+
#include <cmath>
8+
9+
using namespace nx::core;
10+
11+
namespace
12+
{
13+
template <typename T>
14+
class ComputeNormImpl
15+
{
16+
public:
17+
ComputeNormImpl(const IDataArray& inputArray, Float32Array& normArray, float32 pSpace)
18+
: m_InputArray(dynamic_cast<const DataArray<T>&>(inputArray))
19+
, m_NormArray(normArray)
20+
, m_PSpace(pSpace)
21+
{
22+
}
23+
24+
void operator()() const
25+
{
26+
const auto& inputStore = m_InputArray.getDataStoreRef();
27+
auto& normStore = m_NormArray.getDataStoreRef();
28+
29+
usize numTuples = m_InputArray.getNumberOfTuples();
30+
usize numComponents = m_InputArray.getNumberOfComponents();
31+
32+
for(usize i = 0; i < numTuples; i++)
33+
{
34+
float32 normTmp = 0.0f;
35+
for(usize j = 0; j < numComponents; j++)
36+
{
37+
float32 value = static_cast<float32>(inputStore[numComponents * i + j]);
38+
normTmp += std::pow(std::abs(value), m_PSpace);
39+
}
40+
normStore[i] = std::pow(normTmp, 1.0f / m_PSpace);
41+
}
42+
}
43+
44+
private:
45+
const DataArray<T>& m_InputArray;
46+
Float32Array& m_NormArray;
47+
float32 m_PSpace;
48+
};
49+
50+
struct ComputeNormFunctor
51+
{
52+
template <typename T>
53+
void operator()(const IDataArray& inputArray, Float32Array& normArray, float32 pSpace)
54+
{
55+
ComputeNormImpl<T>(inputArray, normArray, pSpace)();
56+
}
57+
};
58+
} // namespace
59+
60+
// -----------------------------------------------------------------------------
61+
ComputeArrayNorm::ComputeArrayNorm(DataStructure& dataStructure, const IFilter::MessageHandler& mesgHandler, const std::atomic_bool& shouldCancel, ComputeArrayNormInputValues* inputValues)
62+
: m_DataStructure(dataStructure)
63+
, m_InputValues(inputValues)
64+
, m_ShouldCancel(shouldCancel)
65+
, m_MessageHandler(mesgHandler)
66+
{
67+
}
68+
69+
// -----------------------------------------------------------------------------
70+
ComputeArrayNorm::~ComputeArrayNorm() noexcept = default;
71+
72+
// -----------------------------------------------------------------------------
73+
const std::atomic_bool& ComputeArrayNorm::getCancel()
74+
{
75+
return m_ShouldCancel;
76+
}
77+
78+
// -----------------------------------------------------------------------------
79+
Result<> ComputeArrayNorm::operator()()
80+
{
81+
const auto& inputArray = m_DataStructure.getDataRefAs<IDataArray>(m_InputValues->SelectedArrayPath);
82+
auto& normArray = m_DataStructure.getDataRefAs<Float32Array>(m_InputValues->NormArrayPath);
83+
84+
ExecuteDataFunction(ComputeNormFunctor{}, inputArray.getDataType(), inputArray, normArray, m_InputValues->PSpace);
85+
86+
return {};
87+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#pragma once
2+
3+
#include "SimplnxReview/SimplnxReview_export.hpp"
4+
5+
#include "simplnx/DataStructure/DataPath.hpp"
6+
#include "simplnx/DataStructure/DataStructure.hpp"
7+
#include "simplnx/Filter/IFilter.hpp"
8+
9+
namespace nx::core
10+
{
11+
12+
struct SIMPLNXREVIEW_EXPORT ComputeArrayNormInputValues
13+
{
14+
float32 PSpace;
15+
DataPath SelectedArrayPath;
16+
DataPath NormArrayPath;
17+
};
18+
19+
/**
20+
* @class ComputeArrayNorm
21+
* @brief This algorithm computes the p-th norm of an Attribute Array.
22+
*/
23+
class SIMPLNXREVIEW_EXPORT ComputeArrayNorm
24+
{
25+
public:
26+
ComputeArrayNorm(DataStructure& dataStructure, const IFilter::MessageHandler& mesgHandler, const std::atomic_bool& shouldCancel, ComputeArrayNormInputValues* inputValues);
27+
~ComputeArrayNorm() noexcept;
28+
29+
ComputeArrayNorm(const ComputeArrayNorm&) = delete;
30+
ComputeArrayNorm(ComputeArrayNorm&&) noexcept = delete;
31+
ComputeArrayNorm& operator=(const ComputeArrayNorm&) = delete;
32+
ComputeArrayNorm& operator=(ComputeArrayNorm&&) noexcept = delete;
33+
34+
Result<> operator()();
35+
36+
const std::atomic_bool& getCancel();
37+
38+
private:
39+
DataStructure& m_DataStructure;
40+
const ComputeArrayNormInputValues* m_InputValues = nullptr;
41+
const std::atomic_bool& m_ShouldCancel;
42+
const IFilter::MessageHandler& m_MessageHandler;
43+
};
44+
45+
} // namespace nx::core
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
#include "ComputeArrayNormFilter.hpp"
2+
3+
#include "SimplnxReview/Filters/Algorithms/ComputeArrayNorm.hpp"
4+
5+
#include "simplnx/DataStructure/DataArray.hpp"
6+
#include "simplnx/DataStructure/DataPath.hpp"
7+
#include "simplnx/Filter/Actions/CreateArrayAction.hpp"
8+
#include "simplnx/Parameters/ArraySelectionParameter.hpp"
9+
#include "simplnx/Parameters/DataObjectNameParameter.hpp"
10+
#include "simplnx/Parameters/NumberParameter.hpp"
11+
#include "simplnx/Utilities/SIMPLConversion.hpp"
12+
13+
using namespace nx::core;
14+
15+
namespace nx::core
16+
{
17+
//------------------------------------------------------------------------------
18+
std::string ComputeArrayNormFilter::name() const
19+
{
20+
return FilterTraits<ComputeArrayNormFilter>::name.str();
21+
}
22+
23+
//------------------------------------------------------------------------------
24+
std::string ComputeArrayNormFilter::className() const
25+
{
26+
return FilterTraits<ComputeArrayNormFilter>::className;
27+
}
28+
29+
//------------------------------------------------------------------------------
30+
Uuid ComputeArrayNormFilter::uuid() const
31+
{
32+
return FilterTraits<ComputeArrayNormFilter>::uuid;
33+
}
34+
35+
//------------------------------------------------------------------------------
36+
std::string ComputeArrayNormFilter::humanName() const
37+
{
38+
return "Compute Array Norm";
39+
}
40+
41+
//------------------------------------------------------------------------------
42+
std::vector<std::string> ComputeArrayNormFilter::defaultTags() const
43+
{
44+
return {className(), "Statistics", "DREAM3DReview"};
45+
}
46+
47+
//------------------------------------------------------------------------------
48+
Parameters ComputeArrayNormFilter::parameters() const
49+
{
50+
Parameters params;
51+
52+
params.insertSeparator(Parameters::Separator{"Input Parameter"});
53+
params.insert(std::make_unique<Float32Parameter>(k_PSpace_Key, "p-Space Value", "p-Value used for computing the norm (2 = Euclidean, 1 = Manhattan)", 2.0f));
54+
55+
params.insertSeparator(Parameters::Separator{"Input Data"});
56+
params.insert(std::make_unique<ArraySelectionParameter>(k_SelectedArrayPath_Key, "Input Attribute Array", "The input array for computing the norm", DataPath{},
57+
ArraySelectionParameter::AllowedTypes{DataType::int8, DataType::uint8, DataType::int16, DataType::uint16, DataType::int32, DataType::uint32,
58+
DataType::int64, DataType::uint64, DataType::float32, DataType::float64},
59+
ArraySelectionParameter::AllowedComponentShapes{}));
60+
61+
params.insertSeparator(Parameters::Separator{"Output Data"});
62+
params.insert(std::make_unique<DataObjectNameParameter>(k_NormArrayName_Key, "Norm Array Name", "The name of the output norm array", "Norm"));
63+
64+
return params;
65+
}
66+
67+
//------------------------------------------------------------------------------
68+
IFilter::UniquePointer ComputeArrayNormFilter::clone() const
69+
{
70+
return std::make_unique<ComputeArrayNormFilter>();
71+
}
72+
73+
//------------------------------------------------------------------------------
74+
IFilter::VersionType ComputeArrayNormFilter::parametersVersion() const
75+
{
76+
return 1;
77+
}
78+
79+
//------------------------------------------------------------------------------
80+
IFilter::PreflightResult ComputeArrayNormFilter::preflightImpl(const DataStructure& dataStructure, const Arguments& filterArgs, const MessageHandler& messageHandler,
81+
const std::atomic_bool& shouldCancel, const ExecutionContext& executionContext) const
82+
{
83+
auto pSpaceValue = filterArgs.value<float32>(k_PSpace_Key);
84+
auto pSelectedArrayPathValue = filterArgs.value<DataPath>(k_SelectedArrayPath_Key);
85+
auto pNormArrayNameValue = filterArgs.value<std::string>(k_NormArrayName_Key);
86+
87+
PreflightResult preflightResult;
88+
nx::core::Result<OutputActions> resultOutputActions;
89+
std::vector<PreflightValue> preflightUpdatedValues;
90+
91+
if(pSpaceValue < 0.0f)
92+
{
93+
return {MakeErrorResult<OutputActions>(-11002, "p-space value must be greater than or equal to 0")};
94+
}
95+
96+
const auto* inputArray = dataStructure.getDataAs<IDataArray>(pSelectedArrayPathValue);
97+
if(inputArray == nullptr)
98+
{
99+
return {MakeErrorResult<OutputActions>(-11003, fmt::format("Cannot find the selected input array at path '{}'", pSelectedArrayPathValue.toString()))};
100+
}
101+
102+
DataPath normArrayPath = pSelectedArrayPathValue.replaceName(pNormArrayNameValue);
103+
104+
{
105+
auto createArrayAction = std::make_unique<CreateArrayAction>(DataType::float32, inputArray->getTupleShape(), std::vector<usize>{1}, normArrayPath);
106+
resultOutputActions.value().appendAction(std::move(createArrayAction));
107+
}
108+
109+
return {std::move(resultOutputActions), std::move(preflightUpdatedValues)};
110+
}
111+
112+
//------------------------------------------------------------------------------
113+
Result<> ComputeArrayNormFilter::executeImpl(DataStructure& dataStructure, const Arguments& filterArgs, const PipelineFilter* pipelineNode, const MessageHandler& messageHandler,
114+
const std::atomic_bool& shouldCancel, const ExecutionContext& executionContext) const
115+
{
116+
ComputeArrayNormInputValues inputValues;
117+
118+
inputValues.PSpace = filterArgs.value<float32>(k_PSpace_Key);
119+
inputValues.SelectedArrayPath = filterArgs.value<DataPath>(k_SelectedArrayPath_Key);
120+
inputValues.NormArrayPath = inputValues.SelectedArrayPath.replaceName(filterArgs.value<std::string>(k_NormArrayName_Key));
121+
122+
return ComputeArrayNorm(dataStructure, messageHandler, shouldCancel, &inputValues)();
123+
}
124+
125+
namespace
126+
{
127+
namespace SIMPL
128+
{
129+
constexpr StringLiteral k_SelectedArrayPathKey = "SelectedArrayPath";
130+
constexpr StringLiteral k_NormArrayPathKey = "NormArrayPath";
131+
constexpr StringLiteral k_PSpaceKey = "PSpace";
132+
} // namespace SIMPL
133+
} // namespace
134+
135+
Result<Arguments> ComputeArrayNormFilter::FromSIMPLJson(const nlohmann::json& json)
136+
{
137+
Arguments args = ComputeArrayNormFilter().getDefaultArguments();
138+
139+
std::vector<Result<>> results;
140+
141+
results.push_back(SIMPLConversion::ConvertParameter<SIMPLConversion::FloatFilterParameterConverter<float32>>(args, json, SIMPL::k_PSpaceKey, k_PSpace_Key));
142+
results.push_back(SIMPLConversion::ConvertParameter<SIMPLConversion::DataArraySelectionFilterParameterConverter>(args, json, SIMPL::k_SelectedArrayPathKey, k_SelectedArrayPath_Key));
143+
results.push_back(SIMPLConversion::ConvertParameter<SIMPLConversion::DataArrayCreationToDataObjectNameFilterParameterConverter>(args, json, SIMPL::k_NormArrayPathKey, k_NormArrayName_Key));
144+
145+
Result<> conversionResult = MergeResults(std::move(results));
146+
147+
return ConvertResultTo<Arguments>(std::move(conversionResult), std::move(args));
148+
}
149+
} // namespace nx::core

0 commit comments

Comments
 (0)