|
| 1 | +#include "MatrixCalculator.hpp" |
| 2 | + |
| 3 | +#include "simplnx/DataStructure/DataArray.hpp" |
| 4 | +#include "simplnx/DataStructure/Geometry/ImageGeom.hpp" |
| 5 | +#include "simplnx/Utilities/DataGroupUtilities.hpp" |
| 6 | +#include "simplnx/Utilities/FilterUtilities.hpp" |
| 7 | +#include "simplnx/Utilities/ImageRotationUtilities.hpp" |
| 8 | + |
| 9 | +#include <Eigen/Dense> |
| 10 | + |
| 11 | +using namespace nx::core; |
| 12 | + |
| 13 | +namespace |
| 14 | +{ |
| 15 | +template <typename T> |
| 16 | +Eigen::Matrix<T, 4, 4, Eigen::RowMajor> CreateEigenMatrix(const AbstractDataStore<T>& dataStore) |
| 17 | +{ |
| 18 | + Eigen::Matrix<T, 4, 4, Eigen::RowMajor> matrix; |
| 19 | + matrix.fill(0); |
| 20 | + matrix << dataStore[0], dataStore[1], dataStore[2], dataStore[3], dataStore[4], dataStore[5], dataStore[6], dataStore[7], dataStore[8], dataStore[9], dataStore[10], dataStore[11], dataStore[12], |
| 21 | + dataStore[13], dataStore[14], dataStore[15]; |
| 22 | + |
| 23 | + return matrix; |
| 24 | +} |
| 25 | + |
| 26 | +struct MatrixOperationFunctor |
| 27 | +{ |
| 28 | + template <typename ScalarType> |
| 29 | + Result<> operator()(const IDataArray& array1, const IDataArray& array2, IDataArray& outputArray, ChoicesParameter::ValueType opIdx) |
| 30 | + { |
| 31 | + using MatrixType = Eigen::Matrix<ScalarType, 4, 4, Eigen::RowMajor>; |
| 32 | + using StoreType = AbstractDataStore<ScalarType>; |
| 33 | + const auto& array1StoreRef = array1.getIDataStoreRefAs<StoreType>(); |
| 34 | + const auto& array2StoreRef = array2.getIDataStoreRefAs<StoreType>(); |
| 35 | + |
| 36 | + auto eigenMatrix1 = CreateEigenMatrix<ScalarType>(array1StoreRef); |
| 37 | + auto eigenMatrix2 = CreateEigenMatrix<ScalarType>(array2StoreRef); |
| 38 | + |
| 39 | + MatrixType output; |
| 40 | + |
| 41 | + if(opIdx == matrix_calculator::constants::k_MultiplicationIdx) |
| 42 | + { |
| 43 | + output = eigenMatrix1 * eigenMatrix2; |
| 44 | + } |
| 45 | + else if(opIdx == matrix_calculator::constants::k_AdditionIdx) |
| 46 | + { |
| 47 | + output = eigenMatrix1 + eigenMatrix2; |
| 48 | + } |
| 49 | + else if(opIdx == matrix_calculator::constants::k_SubtractionIdx) |
| 50 | + { |
| 51 | + output = eigenMatrix1 - eigenMatrix2; |
| 52 | + } |
| 53 | + |
| 54 | + auto& dataStore = outputArray.getIDataStoreRefAs<StoreType>(); |
| 55 | + |
| 56 | + dataStore[0] = output(0, 0); |
| 57 | + dataStore[1] = output(0, 1); |
| 58 | + dataStore[2] = output(0, 2); |
| 59 | + dataStore[3] = output(0, 3); |
| 60 | + dataStore[4] = output(1, 0); |
| 61 | + dataStore[5] = output(1, 1); |
| 62 | + dataStore[6] = output(1, 2); |
| 63 | + dataStore[7] = output(1, 3); |
| 64 | + dataStore[8] = output(2, 0); |
| 65 | + dataStore[9] = output(2, 1); |
| 66 | + dataStore[10] = output(2, 2); |
| 67 | + dataStore[11] = output(2, 3); |
| 68 | + dataStore[12] = output(3, 0); |
| 69 | + dataStore[13] = output(3, 1); |
| 70 | + dataStore[14] = output(3, 2); |
| 71 | + dataStore[15] = output(3, 3); |
| 72 | + |
| 73 | + return {}; |
| 74 | + } |
| 75 | +}; |
| 76 | + |
| 77 | +} // namespace |
| 78 | + |
| 79 | +// ----------------------------------------------------------------------------- |
| 80 | +MatrixCalculator::MatrixCalculator(DataStructure& dataStructure, const IFilter::MessageHandler& mesgHandler, const std::atomic_bool& shouldCancel, MatrixCalculatorInputValues* inputValues) |
| 81 | +: m_DataStructure(dataStructure) |
| 82 | +, m_InputValues(inputValues) |
| 83 | +, m_ShouldCancel(shouldCancel) |
| 84 | +, m_MessageHandler(mesgHandler) |
| 85 | +{ |
| 86 | +} |
| 87 | + |
| 88 | +// ----------------------------------------------------------------------------- |
| 89 | +MatrixCalculator::~MatrixCalculator() noexcept = default; |
| 90 | + |
| 91 | +// ----------------------------------------------------------------------------- |
| 92 | +const std::atomic_bool& MatrixCalculator::getCancel() |
| 93 | +{ |
| 94 | + return m_ShouldCancel; |
| 95 | +} |
| 96 | + |
| 97 | +// ----------------------------------------------------------------------------- |
| 98 | +Result<> MatrixCalculator::operator()() |
| 99 | +{ |
| 100 | + |
| 101 | + auto& outputArray = m_DataStructure.getDataRefAs<IDataArray>(m_InputValues->OutputPath); |
| 102 | + const auto& array1Ref = m_DataStructure.getDataRefAs<IDataArray>(m_InputValues->SelectedPaths[0]); |
| 103 | + const auto& array2Ref = m_DataStructure.getDataRefAs<IDataArray>(m_InputValues->SelectedPaths[1]); |
| 104 | + |
| 105 | + if(array1Ref.getDataType() != array2Ref.getDataType()) |
| 106 | + { |
| 107 | + return MakeErrorResult(-89750, "DataType mismatch"); |
| 108 | + } |
| 109 | + |
| 110 | + ExecuteDataFunction(MatrixOperationFunctor{}, array1Ref.getDataType(), array1Ref, array2Ref, outputArray, m_InputValues->Operation); |
| 111 | + |
| 112 | + for(usize selectedArrayIdx = 2; selectedArrayIdx < m_InputValues->SelectedPaths.size(); selectedArrayIdx++) |
| 113 | + { |
| 114 | + |
| 115 | + const auto& arrayRef = m_DataStructure.getDataRefAs<IDataArray>(m_InputValues->SelectedPaths[selectedArrayIdx]); |
| 116 | + |
| 117 | + ExecuteDataFunction(MatrixOperationFunctor{}, outputArray.getDataType(), outputArray, arrayRef, outputArray, m_InputValues->Operation); |
| 118 | + } |
| 119 | + |
| 120 | + return {}; |
| 121 | +} |
0 commit comments