Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ENH: AppendImageGeometry now has option to mirror across the chosen axis. #1052

Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ TEST_CASE("OrientationAnalysis::AlignSectionsMisorientation Small IN100 Pipeline
const nx::core::UnitTest::TestFileSentinel testDataSentinel(nx::core::unit_test::k_CMakeExecutable, nx::core::unit_test::k_TestFilesDir, "6_6_align_sections_misorientation.tar.gz",
"6_6_align_sections_misorientation.dream3d");

const nx::core::UnitTest::TestFileSentinel testDataSentinel1(nx::core::unit_test::k_CMakeExecutable, nx::core::unit_test::k_TestFilesDir, "Small_IN100_dream3d.tar.gz", "Small_IN100.dream3d");
const nx::core::UnitTest::TestFileSentinel testDataSentinel1(nx::core::unit_test::k_CMakeExecutable, nx::core::unit_test::k_TestFilesDir, "Small_IN100_dream3d_v2.tar.gz", "Small_IN100.dream3d");

const std::string kDataInputArchive2 = "align_sections.tar.gz";
const std::string kExpectedOutputTopLevel2 = "align_sections_misorientation.txt";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ TEST_CASE("OrientationAnalysis::BadDataNeighborOrientationCheckFilter: Small IN1
const nx::core::UnitTest::TestFileSentinel testDataSentinel(nx::core::unit_test::k_CMakeExecutable, nx::core::unit_test::k_TestFilesDir, "bad_data_neighbor_orientation_check.tar.gz",
"bad_data_neighbor_orientation_check.dream3d");

const nx::core::UnitTest::TestFileSentinel testDataSentinel1(nx::core::unit_test::k_CMakeExecutable, nx::core::unit_test::k_TestFilesDir, "Small_IN100_dream3d.tar.gz", "Small_IN100.dream3d");
const nx::core::UnitTest::TestFileSentinel testDataSentinel1(nx::core::unit_test::k_CMakeExecutable, nx::core::unit_test::k_TestFilesDir, "Small_IN100_dream3d_v2.tar.gz", "Small_IN100.dream3d");

Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true);
auto* filterList = Application::Instance()->getFilterList();
Expand Down
2 changes: 1 addition & 1 deletion src/Plugins/OrientationAnalysis/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ if(EXISTS "${DREAM3D_DATA_DIR}" AND SIMPLNX_DOWNLOAD_TEST_FILES)
download_test_data(DREAM3D_DATA_DIR ${DREAM3D_DATA_DIR} ARCHIVE_NAME neighbor_orientation_correlation.tar.gz SHA512 122367452174ade2f24dde7a4610bddc4f147a223722d9b30c1df9eaa2cd2bf25e1c7957aba83f3f9de79b4eadd79339b848f9530d1ebf44c69244ea5442cf85)
download_test_data(DREAM3D_DATA_DIR ${DREAM3D_DATA_DIR} ARCHIVE_NAME PoleFigure_Exemplars_v2.tar.gz SHA512 1c7169e01e66cff074bd58fc188ec69d26df10c4eb61feeb2b123cab945ea44c0419b5d76ab422fc6c585e0a4078bf796f785e7e6ccccc84cc1c518631afb589)
download_test_data(DREAM3D_DATA_DIR ${DREAM3D_DATA_DIR} ARCHIVE_NAME Small_IN100_Ang_Files.tar.gz SHA512 79e9f6948d4e8e06187e11216a67596fa786ffd2700e51f594ad014090383eb8bcc003e14de2e88082aa9ae512cc4fc9cee22c80066fc54f38c3ebc75267eb5b)
download_test_data(DREAM3D_DATA_DIR ${DREAM3D_DATA_DIR} ARCHIVE_NAME Small_IN100_dream3d.tar.gz SHA512 6dd8a3412532bdc7481f7781c7087b4477c6a1efbe6b214f997dad30c53c59714a751be522f084b98065fe75100c74df901bb8af2f512ef47344d8f7941575cf)
download_test_data(DREAM3D_DATA_DIR ${DREAM3D_DATA_DIR} ARCHIVE_NAME Small_IN100_dream3d_v2.tar.gz SHA512 d2c6d537e3085f944ef3ce6b79553b65ead81f7f25fc4810af642e1d3dc86c465727e2bfb886b77e6da41e987e502c4263a35164aa8c07453853659d10f3de24)
download_test_data(DREAM3D_DATA_DIR ${DREAM3D_DATA_DIR} ARCHIVE_NAME Small_IN100_h5ebsd.tar.gz SHA512 31e606285ea9e8235dcb5f608fd2b252a5ab1492abd975e5ec33a21d083aa9720fe16fb8f752742c140f40e963d692f1a46256b9d36e96b1b09796c1e4ea3db9)
download_test_data(DREAM3D_DATA_DIR ${DREAM3D_DATA_DIR} ARCHIVE_NAME so3_cubic_high_ipf_001.tar.gz SHA512 dfe4598cd4406e8b83f244302dc4fe0d4367527835c5ddd6567fe8d8ab3484d5b10ba24a8bb31db269256ec0b5272daa4340eedb5a8b397755541b32dd616b85)
download_test_data(DREAM3D_DATA_DIR ${DREAM3D_DATA_DIR} ARCHIVE_NAME write_stats_gen_odf_angle_file.tar.gz SHA512 be3f663aae1f78e5b789200421534ed9fe293187ec3514796ac8177128b34ded18bb9a98b8e838bb283f9818ac30dc4b19ec379bdd581b1a98eb36d967cdd319)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ TEST_CASE("OrientationAnalysis::EBSDSegmentFeatures: Valid Execution", "[Orienta
const nx::core::UnitTest::TestFileSentinel testDataSentinel(nx::core::unit_test::k_CMakeExecutable, nx::core::unit_test::k_TestFilesDir, "6_6_ebsd_segment_features.tar.gz",
"6_6_ebsd_segment_features.dream3d");

const nx::core::UnitTest::TestFileSentinel testDataSentinel1(nx::core::unit_test::k_CMakeExecutable, nx::core::unit_test::k_TestFilesDir, "Small_IN100_dream3d.tar.gz", "Small_IN100.dream3d");
const nx::core::UnitTest::TestFileSentinel testDataSentinel1(nx::core::unit_test::k_CMakeExecutable, nx::core::unit_test::k_TestFilesDir, "Small_IN100_dream3d_v2.tar.gz", "Small_IN100.dream3d");

Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true);
auto* filterList = Application::Instance()->getFilterList();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ TEST_CASE("OrientationAnalysis::NeighborOrientationCorrelationFilter: Small IN10
const nx::core::UnitTest::TestFileSentinel testDataSentinel(nx::core::unit_test::k_CMakeExecutable, nx::core::unit_test::k_TestFilesDir, "neighbor_orientation_correlation.tar.gz",
"neighbor_orientation_correlation.dream3d");

const nx::core::UnitTest::TestFileSentinel testDataSentinel1(nx::core::unit_test::k_CMakeExecutable, nx::core::unit_test::k_TestFilesDir, "Small_IN100_dream3d.tar.gz", "Small_IN100.dream3d");
const nx::core::UnitTest::TestFileSentinel testDataSentinel1(nx::core::unit_test::k_CMakeExecutable, nx::core::unit_test::k_TestFilesDir, "Small_IN100_dream3d_v2.tar.gz", "Small_IN100.dream3d");

Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true);
auto* filterList = Application::Instance()->getFilterList();
Expand Down
2 changes: 1 addition & 1 deletion src/Plugins/OrientationAnalysis/test/ReadH5EbsdTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const std::string k_MaterialName("MaterialName");

TEST_CASE("OrientationAnalysis::ReadH5Ebsd: Valid filter execution", "[OrientationAnalysis][ReadH5Ebsd]")
{
const nx::core::UnitTest::TestFileSentinel testDataSentinel1(nx::core::unit_test::k_CMakeExecutable, nx::core::unit_test::k_TestFilesDir, "Small_IN100_dream3d.tar.gz", "Small_IN100.dream3d");
const nx::core::UnitTest::TestFileSentinel testDataSentinel1(nx::core::unit_test::k_CMakeExecutable, nx::core::unit_test::k_TestFilesDir, "Small_IN100_dream3d_v2.tar.gz", "Small_IN100.dream3d");

const nx::core::UnitTest::TestFileSentinel testDataSentinel(nx::core::unit_test::k_CMakeExecutable, nx::core::unit_test::k_TestFilesDir, "Small_IN100_h5ebsd.tar.gz", "Small_IN100.h5ebsd");

Expand Down
53 changes: 44 additions & 9 deletions src/Plugins/SimplnxCore/docs/AppendImageGeometryFilter.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,52 @@ Sampling (Memory/Management)
This filter allows the user to append one or multiple image geometries to a given image geometry, in any direction (X,Y,Z). The input and
destination **ImageGeometry** objects must have the same dimensions in the directions that are NOT chosen. If the X direction is chosen, the geometries must match in Y & Z. If the Y direction is chosen, the geometries must match in X & Z. If the Z direction is chosen, the geometries must match in X & Y. Optional checks for equal **Resolution** values can also be performed.

For the X direction example, if the user has an already existing **Image Geometry** that is 100 voxels in the *Y* direction by 300 pixels in the
*Z* direction and composed of 10 *X* slices, then if the user appends another three data sets in the X direction that are the same dimensions in Y & Z but contain
20 *X* slices each, the resulting **Image Geometry** will have a total of 70 *X* slices.
This filter also has an option to mirror the resulting geometry in the chosen direction. If the X direction is chosen, it will mirror the positions of the YZ planes. If the Y direction is chosen, it will mirror the positions of the XZ planes. If the Z direction is chosen, it will mirror the positions of the XY planes.

For the Y direction example, if the user has an already existing **Image Geometry** that is 400 voxels in the *X* direction by 200 pixels in the
*Z* direction and composed of 50 *Y* slices, then if the user appends another two data sets in the Y direction that are the same dimensions in X & Z but contain
40 *Y* slices each, the resulting **Image Geometry** will have a total of 130 *Y* slices.
### X Direction Examples

For the Z direction example, if the user has an already existing **Image Geometry** that is 100 voxels in the *X* direction by 200 pixels in the
*Y* direction and composed of 5 *Z* slices, then if the user appends one other data set in the Z direction that is the same dimensions in X & Y but contains
10 *Z* slices, the resulting **Image Geometry** will have a total of 15 *Z* slices.
#### Example 1
If the user has an already existing **Image Geometry** that is 100 voxels in the *Y* direction by 300 pixels in the
*Z* direction and composed of 10 *X* slices, then if the user appends another three data sets in the X direction that are the same dimensions in Y & Z but contain 20 *X* slices each, the resulting **Image Geometry** will have a total of 70 *X* slices.

#### Example 2 (Visual Example)
Here's the SmallIN100 dataset example sliced into three pieces in the X direction:

![](Images/AppendImageGeometry/x_direction_pieces.png)

And here is what the geometry looks like after appending the three pieces together in the X direction. On the left is the regular result, on the right is the mirrored result:
| ![](Images/AppendImageGeometry/x_complete.png) | ![](Images/AppendImageGeometry/x_mirrored.png) |
|:----------------------:|:----------------------:|

### Y Direction Examples

#### Example 1
If the user has an already existing **Image Geometry** that is 400 voxels in the *X* direction by 200 pixels in the
*Z* direction and composed of 50 *Y* slices, then if the user appends another two data sets in the Y direction that are the same dimensions in X & Z but contain 40 *Y* slices each, the resulting **Image Geometry** will have a total of 130 *Y* slices.

#### Example 2 (Visual Example)
Here's the SmallIN100 dataset example sliced into three pieces in the Y direction:

![](Images/AppendImageGeometry/y_direction_pieces.png)

And here is what the geometry looks like after appending the three pieces together in the Y direction. On the left is the regular result, on the right is the mirrored result:
| ![](Images/AppendImageGeometry/y_complete.png) | ![](Images/AppendImageGeometry/y_mirrored.png) |
|:----------------------:|:----------------------:|

### Z Direction Examples

#### Example 1
If the user has an already existing **Image Geometry** that is 100 voxels in the *X* direction by 200 pixels in the
*Y* direction and composed of 5 *Z* slices, then if the user appends one other data set in the Z direction that is the same dimensions in X & Y but contains 10 *Z* slices, the resulting **Image Geometry** will have a total of 15 *Z* slices.

#### Example 2 (Visual Example)
Here's the SmallIN100 dataset example sliced into three pieces in the Z direction:

![](Images/AppendImageGeometry/z_direction_pieces.png)

And here is what the geometry looks like after appending the three pieces together in the Z direction. On the left is the regular result, on the right is the mirrored result:
| ![](Images/AppendImageGeometry/z_complete.png) | ![](Images/AppendImageGeometry/z_mirrored.png) |
|:----------------------:|:----------------------:|

% Auto generated parameter table will be inserted here

Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -115,14 +115,20 @@ Result<> AppendImageGeometry::operator()()
if(m_InputValues->SaveAsNewGeometry)
{
m_MessageHandler(fmt::format("Combining data into array {}", newCellDataPath.createChildPath(name).toString()));
CopyFromArray::RunParallelCombine(*newDataArray, taskRunner, inputDataArrays, inputTupleShapes, m_InputValues->Direction);
auto newGeometry = m_DataStructure.getDataRefAs<ImageGeom>(m_InputValues->NewGeometryPath);
auto newDestGeomDimsVec = newGeometry.getDimensions().toContainer<std::vector<usize>>();
std::reverse(newDestGeomDimsVec.begin(), newDestGeomDimsVec.end());
CopyFromArray::RunParallelCombine(*newDataArray, taskRunner, inputDataArrays, inputTupleShapes, newDestGeomDimsVec, m_InputValues->Direction, m_InputValues->MirrorGeometry);
}
else
{
m_MessageHandler(fmt::format("Appending data into array {}", newCellDataPath.createChildPath(name).toString()));
auto destGeomDimsVec = destGeomDims.toContainer<std::vector<usize>>();
std::reverse(destGeomDimsVec.begin(), destGeomDimsVec.end());
CopyFromArray::RunParallelAppend(*destDataArray, taskRunner, inputDataArrays, inputTupleShapes, destGeomDimsVec, m_InputValues->Direction);
auto originalDestGeomDimsVec = destGeomDims.toContainer<std::vector<usize>>();
std::reverse(originalDestGeomDimsVec.begin(), originalDestGeomDimsVec.end());
auto newDestGeomDimsVec = destGeometry.getDimensions().toContainer<std::vector<usize>>();
std::reverse(newDestGeomDimsVec.begin(), newDestGeomDimsVec.end());
CopyFromArray::RunParallelAppend(*destDataArray, taskRunner, inputDataArrays, inputTupleShapes, originalDestGeomDimsVec, newDestGeomDimsVec, m_InputValues->Direction,
m_InputValues->MirrorGeometry);
}
}
taskRunner.wait(); // This will spill over if the number of DataArrays to process does not divide evenly by the number of threads.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ struct SIMPLNXCORE_EXPORT AppendImageGeometryInputValues
DataPath DestinationGeometryPath;
DataPath NewGeometryPath;
bool CheckResolution;
bool MirrorGeometry;
bool SaveAsNewGeometry;
CopyFromArray::Direction Direction;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,15 @@ Parameters AppendImageGeometryFilter::parameters() const
params.insert(std::make_unique<GeometrySelectionParameter>(k_DestinationGeometry_Key, "Destination Image Geometry",
"The destination image geometry (cell data) that is the final location for the appended data.", DataPath{},
GeometrySelectionParameter::AllowedTypes{IGeometry::Type::Image}));
params.insert(std::make_unique<ChoicesParameter>(k_AppendDimension_Key, "Append Dimension", "The dimension that will be used to append the geometries.", to_underlying(CopyFromArray::Direction::Z),
params.insert(std::make_unique<ChoicesParameter>(k_Direction_Key, "Direction", "The direction that will be used to append the geometries.", to_underlying(CopyFromArray::Direction::Z),
std::vector<std::string>{"X", "Y", "Z"}));
params.insert(std::make_unique<BoolParameter>(k_MirrorGeometry_Key, "Mirror Geometry In Direction", "Mirrors the resulting geometry in the chosen direction.", false));
params.insert(std::make_unique<BoolParameter>(k_CheckResolution_Key, "Check Spacing", "Checks to make sure the spacing for the input geometry and destination geometry match", false));
params.insertLinkableParameter(std::make_unique<BoolParameter>(k_SaveAsNewGeometry_Key, "Save as new geometry",
"Save the combined data as a new geometry instead of appending the input data to the destination geometry", false));
params.insert(std::make_unique<DataGroupCreationParameter>(k_NewGeometry_Key, "New Image Geometry", "The path to the new geometry with the combined data from the input & destination geometry",
DataPath({"AppendedImageGeom"})));

params.linkParameters(k_SaveAsNewGeometry_Key, k_NewGeometry_Key, true);

return params;
Expand All @@ -86,7 +88,7 @@ IFilter::PreflightResult AppendImageGeometryFilter::preflightImpl(const DataStru
{
auto pInputGeometriesPathsValue = filterArgs.value<std::vector<DataPath>>(k_InputGeometries_Key);
auto pDestinationGeometryPathValue = filterArgs.value<DataPath>(k_DestinationGeometry_Key);
auto pAppendDimension = static_cast<CopyFromArray::Direction>(filterArgs.value<ChoicesParameter::ValueType>(k_AppendDimension_Key));
auto pDirection = static_cast<CopyFromArray::Direction>(filterArgs.value<ChoicesParameter::ValueType>(k_Direction_Key));
auto pCheckResolutionValue = filterArgs.value<bool>(k_CheckResolution_Key);
auto pSaveAsNewGeometry = filterArgs.value<bool>(k_SaveAsNewGeometry_Key);

Expand All @@ -100,15 +102,15 @@ IFilter::PreflightResult AppendImageGeometryFilter::preflightImpl(const DataStru
{
const auto& inputGeometry = dataStructure.getDataRefAs<ImageGeom>(pInputGeometryPathValue);
SizeVec3 inputGeomDims = inputGeometry.getDimensions();
if((pAppendDimension == CopyFromArray::Direction::Y || pAppendDimension == CopyFromArray::Direction::Z) && destGeomDims[0] != inputGeomDims[0])
if((pDirection == CopyFromArray::Direction::Y || pDirection == CopyFromArray::Direction::Z) && destGeomDims[0] != inputGeomDims[0])
{
return MakePreflightErrorResult(-8200, fmt::format("Input X Dim ({}) not equal to Destination X Dim ({})", inputGeomDims[0], destGeomDims[0]));
}
if((pAppendDimension == CopyFromArray::Direction::X || pAppendDimension == CopyFromArray::Direction::Z) && destGeomDims[1] != inputGeomDims[1])
if((pDirection == CopyFromArray::Direction::X || pDirection == CopyFromArray::Direction::Z) && destGeomDims[1] != inputGeomDims[1])
{
return MakePreflightErrorResult(-8201, fmt::format("Input Y Dim ({}) not equal to Destination Y Dim ({})", inputGeomDims[1], destGeomDims[1]));
}
if((pAppendDimension == CopyFromArray::Direction::X || pAppendDimension == CopyFromArray::Direction::Y) && destGeomDims[2] != inputGeomDims[2])
if((pDirection == CopyFromArray::Direction::X || pDirection == CopyFromArray::Direction::Y) && destGeomDims[2] != inputGeomDims[2])
{
return MakePreflightErrorResult(-8201, fmt::format("Input Z Dim ({}) not equal to Destination Z Dim ({})", inputGeomDims[2], destGeomDims[2]));
}
Expand Down Expand Up @@ -138,7 +140,7 @@ IFilter::PreflightResult AppendImageGeometryFilter::preflightImpl(const DataStru
return MakePreflightErrorResult(-8310, fmt::format("Input units ({}) not equal to Destination units ({})", IGeometry::LengthUnitToString(inputUnits), IGeometry::LengthUnitToString(destUnits)));
}

switch(pAppendDimension)
switch(pDirection)
{
case CopyFromArray::Direction::X:
newDims[0] += inputGeomDims[0];
Expand Down Expand Up @@ -307,8 +309,9 @@ Result<> AppendImageGeometryFilter::executeImpl(DataStructure& dataStructure, co

inputValues.InputGeometriesPaths = filterArgs.value<std::vector<DataPath>>(k_InputGeometries_Key);
inputValues.DestinationGeometryPath = filterArgs.value<DataPath>(k_DestinationGeometry_Key);
inputValues.Direction = static_cast<CopyFromArray::Direction>(filterArgs.value<ChoicesParameter::ValueType>(k_AppendDimension_Key));
inputValues.Direction = static_cast<CopyFromArray::Direction>(filterArgs.value<ChoicesParameter::ValueType>(k_Direction_Key));
inputValues.CheckResolution = filterArgs.value<bool>(k_CheckResolution_Key);
inputValues.MirrorGeometry = filterArgs.value<bool>(k_MirrorGeometry_Key);
inputValues.SaveAsNewGeometry = filterArgs.value<bool>(k_SaveAsNewGeometry_Key);
inputValues.NewGeometryPath = filterArgs.value<DataPath>(k_NewGeometry_Key);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ class SIMPLNXCORE_EXPORT AppendImageGeometryFilter : public IFilter
// Parameter Keys
static inline constexpr StringLiteral k_InputGeometries_Key = "input_image_geometries_paths";
static inline constexpr StringLiteral k_DestinationGeometry_Key = "destination_image_geometry_path";
static inline constexpr StringLiteral k_AppendDimension_Key = "append_dimension_index";
static inline constexpr StringLiteral k_Direction_Key = "direction_index";
static inline constexpr StringLiteral k_MirrorGeometry_Key = "mirror_geometry";
static inline constexpr StringLiteral k_CheckResolution_Key = "check_resolution";
static inline constexpr StringLiteral k_SaveAsNewGeometry_Key = "save_as_new_geometry";
static inline constexpr StringLiteral k_NewGeometry_Key = "output_image_geometry_path";
Expand Down
Loading
Loading