From b1d6f47e685d9a6de6221b3e197a8759b4588735 Mon Sep 17 00:00:00 2001 From: Jessica Marquis Date: Thu, 15 Oct 2026 09:57:56 -0400 Subject: [PATCH 01/28] BUG: Correct anisotropic surface-area weights Use the perpendicular-axis face areas in the Direct and Scanline paths. Add analytical 3D and single-slice tests for ratios and optional sphericity. Preserve input data and existing archive controls. Document the numerical correction for unequal X and Y spacing. Signed-off-by: Jessica Marquis --- .../docs/ComputeSurfaceAreaToVolumeFilter.md | 8 + .../ComputeSurfaceAreaToVolumeDirect.cpp | 4 +- .../ComputeSurfaceAreaToVolumeScanline.cpp | 8 +- .../test/ComputeSurfaceAreaToVolumeTest.cpp | 25 +++ .../ComputeSurfaceAreaToVolumeTestUtils.hpp | 170 ++++++++++++++++++ 5 files changed, 209 insertions(+), 6 deletions(-) create mode 100644 src/Plugins/SimplnxCore/test/ComputeSurfaceAreaToVolumeTestUtils.hpp diff --git a/src/Plugins/SimplnxCore/docs/ComputeSurfaceAreaToVolumeFilter.md b/src/Plugins/SimplnxCore/docs/ComputeSurfaceAreaToVolumeFilter.md index efe9c63b12..5a1a25a18c 100644 --- a/src/Plugins/SimplnxCore/docs/ComputeSurfaceAreaToVolumeFilter.md +++ b/src/Plugins/SimplnxCore/docs/ComputeSurfaceAreaToVolumeFilter.md @@ -27,6 +27,14 @@ This **Filter** determines whether a **Feature** touches an outer *Surface* of t - Next, the surface area for each face that is in contact with a different **Feature** is totalled as long as that neighboring *featureId* is > 0. - This number is divided by the volume of each **Feature**, calculated by taking the number of **Cells** of each **Feature** and multiplying by the volume of a **Cell**. +For cell spacing `(dx, dy, dz)`, the area of a face uses the two spacing components perpendicular to its normal: + +- X-normal face: `dy * dz`. +- Y-normal face: `dx * dz`. +- Z-normal face: `dx * dy`. + +Corrected X/Y face weights can change surface-area-to-volume and sphericity values for images whose X and Y spacings differ. Isotropic results are unchanged. + ### WARNING - Aliasing The surface area will be the surface area of the **Cells** in contact with the neighboring **Feature** and will be influenced by the *aliasing* of the structure — the jagged, stair-stepped approximation of a smooth surface that results from representing it on a discrete voxel grid. As a result, the surface area to volume will likely be over-estimated with respect to the *real* **Feature**. diff --git a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeDirect.cpp b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeDirect.cpp index 0802643fd8..eb096e44e3 100644 --- a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeDirect.cpp +++ b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeDirect.cpp @@ -120,11 +120,11 @@ Result<> ComputeSurfaceAreaToVolumeDirect::operator()() } if(neighborOffsetIndex == 1 || neighborOffsetIndex == 4) { - onSurface = onSurface + spacing[1] * spacing[2]; + onSurface = onSurface + spacing[0] * spacing[2]; } if(neighborOffsetIndex == 2 || neighborOffsetIndex == 3) { - onSurface = onSurface + spacing[2] * spacing[0]; + onSurface = onSurface + spacing[1] * spacing[2]; } } } diff --git a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeScanline.cpp b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeScanline.cpp index e982b8daa2..eec275347c 100644 --- a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeScanline.cpp +++ b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeScanline.cpp @@ -118,7 +118,7 @@ Result<> ComputeSurfaceAreaToVolumeScanline::operator()() { if(curSlice[inSlice - static_cast(xPoints)] != currentFeatureId) { - onSurface += yzFaceArea; + onSurface += zxFaceArea; } } @@ -126,7 +126,7 @@ Result<> ComputeSurfaceAreaToVolumeScanline::operator()() { if(curSlice[inSlice + static_cast(xPoints)] != currentFeatureId) { - onSurface += yzFaceArea; + onSurface += zxFaceArea; } } @@ -134,7 +134,7 @@ Result<> ComputeSurfaceAreaToVolumeScanline::operator()() { if(curSlice[inSlice - 1] != currentFeatureId) { - onSurface += zxFaceArea; + onSurface += yzFaceArea; } } @@ -142,7 +142,7 @@ Result<> ComputeSurfaceAreaToVolumeScanline::operator()() { if(curSlice[inSlice + 1] != currentFeatureId) { - onSurface += zxFaceArea; + onSurface += yzFaceArea; } } diff --git a/src/Plugins/SimplnxCore/test/ComputeSurfaceAreaToVolumeTest.cpp b/src/Plugins/SimplnxCore/test/ComputeSurfaceAreaToVolumeTest.cpp index 8e54ad89f7..9fc06cc02b 100644 --- a/src/Plugins/SimplnxCore/test/ComputeSurfaceAreaToVolumeTest.cpp +++ b/src/Plugins/SimplnxCore/test/ComputeSurfaceAreaToVolumeTest.cpp @@ -1,6 +1,8 @@ #include "SimplnxCore/Filters/ComputeSurfaceAreaToVolumeFilter.hpp" #include "SimplnxCore/SimplnxCore_test_dirs.hpp" +#include "ComputeSurfaceAreaToVolumeTestUtils.hpp" + #include "simplnx/DataStructure/AttributeMatrix.hpp" #include "simplnx/DataStructure/DataArray.hpp" #include "simplnx/DataStructure/Geometry/ImageGeom.hpp" @@ -86,6 +88,29 @@ void BuildOctantWithNumCells(DataStructure& ds) } } // namespace +TEST_CASE("SimplnxCore::ComputeSurfaceAreaToVolumeFilter: analytical interior pair", "[SimplnxCore][ComputeSurfaceAreaToVolumeFilter]") +{ + UnitTest::LoadPlugins(); + const auto scenario = GENERATE(from_range(UnitTest::SelectAlgorithmTestScenariosForInMemoryStores())); + const auto pairAxis = GENERATE(usize{0}, usize{1}, usize{2}); + const auto spacing = GENERATE(FloatVec3{2.0f, 3.0f, 5.0f}, FloatVec3{1.0f, 1.0f, 1.0f}); + const auto calculateSphericity = GENERATE(false, true); + CAPTURE(scenario); + UnitTest::AlgorithmTestScope scope(scenario); + SurfaceAreaToVolumeTest::CheckInteriorPairSurfaceMetrics(scope, pairAxis, spacing, calculateSphericity); +} + +TEST_CASE("SimplnxCore::ComputeSurfaceAreaToVolumeFilter: analytical single-slice pair", "[SimplnxCore][ComputeSurfaceAreaToVolumeFilter]") +{ + UnitTest::LoadPlugins(); + const auto scenario = GENERATE(from_range(UnitTest::SelectAlgorithmTestScenariosForInMemoryStores())); + const auto pairAxis = GENERATE(usize{0}, usize{1}); + const auto calculateSphericity = GENERATE(false, true); + CAPTURE(scenario); + UnitTest::AlgorithmTestScope scope(scenario); + SurfaceAreaToVolumeTest::CheckInteriorPairSurfaceMetrics(scope, pairAxis, FloatVec3{2.0f, 3.0f, 5.0f}, calculateSphericity, SizeVec3{5, 5, 1}); +} + TEST_CASE("SimplnxCore::ComputeSurfaceAreaToVolume", "[SimplnxCore][ComputeSurfaceAreaToVolume]") { UnitTest::LoadPlugins(); diff --git a/src/Plugins/SimplnxCore/test/ComputeSurfaceAreaToVolumeTestUtils.hpp b/src/Plugins/SimplnxCore/test/ComputeSurfaceAreaToVolumeTestUtils.hpp new file mode 100644 index 0000000000..d7d9619c17 --- /dev/null +++ b/src/Plugins/SimplnxCore/test/ComputeSurfaceAreaToVolumeTestUtils.hpp @@ -0,0 +1,170 @@ +#pragma once + +#include "SimplnxCore/Filters/ComputeSurfaceAreaToVolumeFilter.hpp" + +#include "simplnx/DataStructure/AttributeMatrix.hpp" +#include "simplnx/DataStructure/DataArray.hpp" +#include "simplnx/DataStructure/Geometry/ImageGeom.hpp" +#include "simplnx/UnitTest/UnitTestCommon.hpp" +#include "simplnx/Utilities/DataStoreUtilities.hpp" + +#include + +#include +#include +#include + +namespace SurfaceAreaToVolumeTest +{ +// A wrong X/Y face weight changes the physical area of this interior box. +template +void CheckInteriorPairSurfaceMetrics(ScopeT& scope, nx::core::usize pairAxis, const nx::core::FloatVec3& spacing, bool calculateSphericity, const nx::core::SizeVec3& dimensions = {5, 5, 5}) +{ + using namespace nx::core; + DataStructure dataStructure; + const DataPath geomPath({"ImageGeom"}); + const DataPath cellPath = geomPath.createChildPath("CellData"); + const DataPath featurePath = geomPath.createChildPath("CellFeatureData"); + const DataPath idsPath = cellPath.createChildPath("FeatureIds"); + const DataPath countsPath = featurePath.createChildPath("NumCells"); + const DataPath ratioPath = featurePath.createChildPath("SurfaceAreaVolumeRatio"); + const DataPath sphericityPath = featurePath.createChildPath("Sphericity"); + const ShapeType cellShape = {dimensions[2], dimensions[1], dimensions[0]}; + const ShapeType featureShape = {3}; + const ShapeType componentShape = {1}; + const FloatVec3 origin = {-1.0f, 4.0f, 7.0f}; + const bool singleSlice = dimensions[2] == 1; + REQUIRE(pairAxis < (singleSlice ? 2 : 3)); + REQUIRE(dimensions == (singleSlice ? SizeVec3{5, 5, 1} : SizeVec3{5, 5, 5})); + constexpr usize pairFeature = 2; + constexpr int32 enclosingFeature = 1; + const usize cellCount = dimensions[0] * dimensions[1] * dimensions[2]; + + auto* geom = ImageGeom::Create(dataStructure, "ImageGeom"); + REQUIRE(geom != nullptr); + geom->setDimensions(dimensions); + geom->setSpacing(spacing); + geom->setOrigin(origin); + auto* cellAM = AttributeMatrix::Create(dataStructure, "CellData", cellShape, geom->getId()); + REQUIRE(cellAM != nullptr); + geom->setCellData(*cellAM); + auto* featureAM = AttributeMatrix::Create(dataStructure, "CellFeatureData", featureShape, geom->getId()); + REQUIRE(featureAM != nullptr); + + auto idsStore = DataStoreUtilities::CreateDataStore(dataStructure, idsPath, cellShape, componentShape); + auto countsStore = DataStoreUtilities::CreateDataStore(dataStructure, countsPath, featureShape, componentShape); + REQUIRE(idsStore != nullptr); + REQUIRE(countsStore != nullptr); + REQUIRE(Int32Array::Create(dataStructure, "FeatureIds", idsStore, cellAM->getId()) != nullptr); + REQUIRE(Int32Array::Create(dataStructure, "NumCells", countsStore, featureAM->getId()) != nullptr); + std::vector labels(cellCount, enclosingFeature); + std::array first = {2, 2, singleSlice ? usize{0} : usize{2}}; + auto second = first; + second[pairAxis]++; + labels[(first[2] * dimensions[1] + first[1]) * dimensions[0] + first[0]] = static_cast(pairFeature); + labels[(second[2] * dimensions[1] + second[1]) * dimensions[0] + second[0]] = static_cast(pairFeature); + const std::array counts = singleSlice ? std::array{0, 23, 2} : std::array{0, 123, 2}; + auto idsWrite = idsStore->copyFromBuffer(0, nonstd::span(labels.data(), labels.size())); + SIMPLNX_RESULT_REQUIRE_VALID(idsWrite); + auto countsWrite = countsStore->copyFromBuffer(0, nonstd::span(counts.data(), counts.size())); + SIMPLNX_RESULT_REQUIRE_VALID(countsWrite); + + REQUIRE_NOTHROW(dataStructure.getDataRefAs(idsPath)); + REQUIRE_NOTHROW(dataStructure.getDataRefAs(countsPath)); + const auto& ids = dataStructure.getDataRefAs(idsPath); + const auto& numCells = dataStructure.getDataRefAs(countsPath); + scope.requireExpectedStore(ids); + scope.requireExpectedStore(numCells); + const auto idsFormat = ids.getDataFormat(); + const auto countsFormat = numCells.getDataFormat(); + + ComputeSurfaceAreaToVolumeFilter filter; + Arguments args; + args.insertOrAssign(ComputeSurfaceAreaToVolumeFilter::k_SelectedImageGeometryPath_Key, std::make_any(geomPath)); + args.insertOrAssign(ComputeSurfaceAreaToVolumeFilter::k_CellFeatureIdsArrayPath_Key, std::make_any(idsPath)); + args.insertOrAssign(ComputeSurfaceAreaToVolumeFilter::k_NumCellsArrayPath_Key, std::make_any(countsPath)); + args.insertOrAssign(ComputeSurfaceAreaToVolumeFilter::k_CalculateSphericity_Key, std::make_any(calculateSphericity)); + args.insertOrAssign(ComputeSurfaceAreaToVolumeFilter::k_SurfaceAreaVolumeRatioArrayName_Key, std::make_any("SurfaceAreaVolumeRatio")); + args.insertOrAssign(ComputeSurfaceAreaToVolumeFilter::k_SphericityArrayName_Key, std::make_any("Sphericity")); + auto preflight = filter.preflight(dataStructure, args); + SIMPLNX_RESULT_REQUIRE_VALID(preflight.outputActions); + auto result = scope.executeFilter(filter, dataStructure, args); + SIMPLNX_RESULT_REQUIRE_VALID(result.result); + + // Independent rectangular-box oracle: the pair doubles one physical side. + std::array sides = {spacing[0], spacing[1], spacing[2]}; + sides[pairAxis] *= 2.0; + // Exterior Z faces are excluded for a single slice, as in the production boundary policy. + const double area = 2.0 * ((singleSlice ? 0.0 : sides[0] * sides[1]) + sides[0] * sides[2] + sides[1] * sides[2]); + const double voxelVolume = static_cast(spacing[0]) * spacing[1] * spacing[2]; + std::array volumes = {0.0, 0.0, 0.0}; + volumes[pairFeature] = sides[0] * sides[1] * sides[2]; + volumes[enclosingFeature] = (singleSlice ? 23.0 : 123.0) * voxelVolume; + CAPTURE(pairAxis, spacing[0], spacing[1], spacing[2], calculateSphericity, singleSlice, area); + + REQUIRE_NOTHROW(dataStructure.getDataRefAs(ratioPath)); + const auto& ratios = dataStructure.getDataRefAs(ratioPath); + scope.requireExpectedStore(ratios); + CHECK(ratios.getTupleShape() == featureShape); + CHECK(ratios.getComponentShape() == componentShape); + std::array ratioValues; + auto ratiosRead = ratios.getDataStoreRef().copyIntoBuffer(0, nonstd::span(ratioValues.data(), ratioValues.size())); + SIMPLNX_RESULT_REQUIRE_VALID(ratiosRead); + CHECK(ratioValues[0] == 0.0f); + for(usize feature = 1; feature < 3; feature++) + { + CAPTURE(feature); + CHECK(ratioValues[feature] == Approx(area / volumes[feature]).epsilon(1.0e-6)); + } + if(calculateSphericity) + { + REQUIRE_NOTHROW(dataStructure.getDataRefAs(sphericityPath)); + const auto& sphericity = dataStructure.getDataRefAs(sphericityPath); + scope.requireExpectedStore(sphericity); + CHECK(sphericity.getTupleShape() == featureShape); + CHECK(sphericity.getComponentShape() == componentShape); + std::array values; + auto sphericityRead = sphericity.getDataStoreRef().copyIntoBuffer(0, nonstd::span(values.data(), values.size())); + SIMPLNX_RESULT_REQUIRE_VALID(sphericityRead); + CHECK(values[0] == 0.0f); + for(usize feature = 1; feature < 3; feature++) + { + CAPTURE(feature); + const double expected = std::cbrt(std::acos(-1.0)) * std::pow(6.0 * volumes[feature], 2.0 / 3.0) / area; + // This tolerance accommodates the existing truncated exponents, intentionally preserved by this correction. + CHECK(values[feature] == Approx(expected).epsilon(1.0e-4)); + } + } + else + { + CHECK(dataStructure.getDataAs(sphericityPath) == nullptr); + } + + std::vector actualLabels(cellCount); + std::array actualCounts; + auto idsRead = ids.getDataStoreRef().copyIntoBuffer(0, nonstd::span(actualLabels.data(), actualLabels.size())); + SIMPLNX_RESULT_REQUIRE_VALID(idsRead); + auto countsRead = numCells.getDataStoreRef().copyIntoBuffer(0, nonstd::span(actualCounts.data(), actualCounts.size())); + SIMPLNX_RESULT_REQUIRE_VALID(countsRead); + CHECK(actualLabels == labels); + CHECK(actualCounts == counts); + CHECK(ids.getTupleShape() == cellShape); + CHECK(ids.getComponentShape() == componentShape); + CHECK(numCells.getTupleShape() == featureShape); + CHECK(numCells.getComponentShape() == componentShape); + CHECK(ids.getDataFormat() == idsFormat); + CHECK(numCells.getDataFormat() == countsFormat); + CHECK(&ids.getDataStoreRef() == idsStore.get()); + CHECK(&numCells.getDataStoreRef() == countsStore.get()); + scope.requireExpectedStore(ids); + scope.requireExpectedStore(numCells); + REQUIRE_NOTHROW(dataStructure.getDataRefAs(geomPath)); + const auto& finalGeom = dataStructure.getDataRefAs(geomPath); + CHECK(finalGeom.getDimensions() == dimensions); + CHECK(finalGeom.getSpacing() == spacing); + CHECK(finalGeom.getOrigin() == origin); + CHECK(cellAM->getShape() == cellShape); + CHECK(featureAM->getShape() == featureShape); + UnitTest::CheckArraysInheritTupleDims(dataStructure); +} +} // namespace SurfaceAreaToVolumeTest From 971aa89a37928a26e99a4d48635c093976e076ef Mon Sep 17 00:00:00 2001 From: Jessica Marquis Date: Thu, 15 Oct 2026 11:55:18 -0400 Subject: [PATCH 02/28] BUG: Reject mismatched surface-metric geometry and label sizes Require one Feature Id tuple per selected image cell before creating output actions. Allow separately stored labels when the counts agree. Signed-off-by: Jessica Marquis --- .../ComputeSurfaceAreaToVolumeFilter.cpp | 11 +++ .../test/ComputeSurfaceAreaToVolumeTest.cpp | 70 +++++++++++++++++++ 2 files changed, 81 insertions(+) diff --git a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/ComputeSurfaceAreaToVolumeFilter.cpp b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/ComputeSurfaceAreaToVolumeFilter.cpp index 6da89db6e4..513bd71dc2 100644 --- a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/ComputeSurfaceAreaToVolumeFilter.cpp +++ b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/ComputeSurfaceAreaToVolumeFilter.cpp @@ -5,6 +5,7 @@ #include "simplnx/DataStructure/AttributeMatrix.hpp" #include "simplnx/DataStructure/DataArray.hpp" #include "simplnx/DataStructure/DataPath.hpp" +#include "simplnx/DataStructure/Geometry/ImageGeom.hpp" #include "simplnx/Filter/Actions/CreateArrayAction.hpp" #include "simplnx/Parameters/ArraySelectionParameter.hpp" #include "simplnx/Parameters/BoolParameter.hpp" @@ -95,6 +96,16 @@ IFilter::PreflightResult ComputeSurfaceAreaToVolumeFilter::preflightImpl(const D auto pFeatureIdsArrayPathValue = filterArgs.value(k_CellFeatureIdsArrayPath_Key); auto pNumCellsArrayPathValue = filterArgs.value(k_NumCellsArrayPath_Key); auto pCalculateSphericityValue = filterArgs.value(k_CalculateSphericity_Key); + auto pImageGeometryPathValue = filterArgs.value(k_SelectedImageGeometryPath_Key); + + const auto& imageGeom = dataStructure.getDataRefAs(pImageGeometryPathValue); + const auto& featureIds = dataStructure.getDataRefAs(pFeatureIdsArrayPathValue); + if(featureIds.getNumberOfTuples() != imageGeom.getNumberOfCells()) + { + return MakePreflightErrorResult( + -12803, fmt::format("The Feature Ids array '{}' has {} tuples, but the selected Image Geometry '{}' has {} cells. Select a Feature Ids array with one tuple per geometry cell.", + pFeatureIdsArrayPathValue.toString(), featureIds.getNumberOfTuples(), pImageGeometryPathValue.toString(), imageGeom.getNumberOfCells())); + } PreflightResult preflightResult; diff --git a/src/Plugins/SimplnxCore/test/ComputeSurfaceAreaToVolumeTest.cpp b/src/Plugins/SimplnxCore/test/ComputeSurfaceAreaToVolumeTest.cpp index 9fc06cc02b..5cadbb9424 100644 --- a/src/Plugins/SimplnxCore/test/ComputeSurfaceAreaToVolumeTest.cpp +++ b/src/Plugins/SimplnxCore/test/ComputeSurfaceAreaToVolumeTest.cpp @@ -88,6 +88,76 @@ void BuildOctantWithNumCells(DataStructure& ds) } } // namespace +TEST_CASE("SimplnxCore::ComputeSurfaceAreaToVolumeFilter: geometry and FeatureIds tuple cardinality", "[SimplnxCore][ComputeSurfaceAreaToVolumeFilter]") +{ + UnitTest::LoadPlugins(); + const auto labelDimensions = GENERATE(SizeVec3{2, 2, 2}, SizeVec3{6, 5, 4}, SizeVec3{6, 5, 2}); + const auto calculateSphericity = GENERATE(false, true); + const ShapeType labelShape = {labelDimensions[2], labelDimensions[1], labelDimensions[0]}; + const usize labelCount = labelDimensions[0] * labelDimensions[1] * labelDimensions[2]; + CAPTURE(labelCount, calculateSphericity); + + DataStructure dataStructure; + const DataPath geomPath({"SelectedGeometry"}); + const DataPath labelGeomPath({"LabelGeometry"}); + const DataPath idsPath = labelGeomPath.createChildPath("CellData").createChildPath("FeatureIds"); + const DataPath countsPath = geomPath.createChildPath("CellFeatureData").createChildPath("NumCells"); + const DataPath ratioPath = countsPath.replaceName("SurfaceAreaVolumeRatio"); + const DataPath sphericityPath = countsPath.replaceName("Sphericity"); + + auto* geom = ImageGeom::Create(dataStructure, geomPath.getTargetName()); + REQUIRE(geom != nullptr); + geom->setDimensions({4, 3, 5}); + auto* cellAM = AttributeMatrix::Create(dataStructure, "CellData", {5, 3, 4}, geom->getId()); + REQUIRE(cellAM != nullptr); + geom->setCellData(*cellAM); + auto* featureAM = AttributeMatrix::Create(dataStructure, "CellFeatureData", {2}, geom->getId()); + REQUIRE(featureAM != nullptr); + + auto* labelGeom = ImageGeom::Create(dataStructure, labelGeomPath.getTargetName()); + REQUIRE(labelGeom != nullptr); + labelGeom->setDimensions(labelDimensions); + auto* labelAM = AttributeMatrix::Create(dataStructure, "CellData", labelShape, labelGeom->getId()); + REQUIRE(labelAM != nullptr); + labelGeom->setCellData(*labelAM); + + auto idsStore = DataStoreUtilities::CreateDataStore(dataStructure, idsPath, labelShape, {1}); + auto countsStore = DataStoreUtilities::CreateDataStore(dataStructure, countsPath, {2}, {1}); + REQUIRE(idsStore != nullptr); + REQUIRE(countsStore != nullptr); + REQUIRE(Int32Array::Create(dataStructure, "FeatureIds", idsStore, labelAM->getId()) != nullptr); + REQUIRE(Int32Array::Create(dataStructure, "NumCells", countsStore, featureAM->getId()) != nullptr); + + ComputeSurfaceAreaToVolumeFilter filter; + Arguments args = filter.getDefaultArguments(); + args.insertOrAssign(ComputeSurfaceAreaToVolumeFilter::k_SelectedImageGeometryPath_Key, std::make_any(geomPath)); + args.insertOrAssign(ComputeSurfaceAreaToVolumeFilter::k_CellFeatureIdsArrayPath_Key, std::make_any(idsPath)); + args.insertOrAssign(ComputeSurfaceAreaToVolumeFilter::k_NumCellsArrayPath_Key, std::make_any(countsPath)); + args.insertOrAssign(ComputeSurfaceAreaToVolumeFilter::k_CalculateSphericity_Key, std::make_any(calculateSphericity)); + + auto preflight = filter.preflight(dataStructure, args); + if(labelCount == 60) + { + SIMPLNX_RESULT_REQUIRE_VALID(preflight.outputActions); + CHECK(preflight.outputActions.value().actions.size() == (calculateSphericity ? 2 : 1)); + } + else + { + // An invalid output-actions result exposes no actions that could allocate outputs for the unsafe input. + SIMPLNX_RESULT_REQUIRE_INVALID(preflight.outputActions); + REQUIRE(preflight.outputActions.errors().size() == 1); + const auto& error = preflight.outputActions.errors().front(); + CHECK(error.code == -12803); + CHECK(error.message.find(idsPath.toString()) != std::string::npos); + CHECK(error.message.find(geomPath.toString()) != std::string::npos); + CHECK(error.message.find(fmt::format("{} tuples", labelCount)) != std::string::npos); + CHECK(error.message.find("60 cells") != std::string::npos); + } + CHECK(dataStructure.getDataAs(ratioPath) == nullptr); + CHECK(dataStructure.getDataAs(sphericityPath) == nullptr); + UnitTest::CheckArraysInheritTupleDims(dataStructure); +} + TEST_CASE("SimplnxCore::ComputeSurfaceAreaToVolumeFilter: analytical interior pair", "[SimplnxCore][ComputeSurfaceAreaToVolumeFilter]") { UnitTest::LoadPlugins(); From 945f1a3fbe40f245b52cac93d1f759b5031279f7 Mon Sep 17 00:00:00 2001 From: Jessica Marquis Date: Thu, 15 Oct 2026 12:00:51 -0400 Subject: [PATCH 03/28] BUG: Improve surface-area accumulation precision Use double precision for face areas, area sums, and volume arithmetic. Keep float32 output arrays and the existing interface-selection rules. Add connected-feature regressions with decimal and isotropic spacing. Signed-off-by: Jessica Marquis --- .../ComputeSurfaceAreaToVolumeDirect.cpp | 25 +-- .../ComputeSurfaceAreaToVolumeScanline.cpp | 22 +-- .../test/ComputeSurfaceAreaToVolumeTest.cpp | 11 ++ .../ComputeSurfaceAreaToVolumeTestUtils.hpp | 158 ++++++++++++++++++ 4 files changed, 194 insertions(+), 22 deletions(-) diff --git a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeDirect.cpp b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeDirect.cpp index eb096e44e3..4525b03465 100644 --- a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeDirect.cpp +++ b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeDirect.cpp @@ -47,11 +47,14 @@ Result<> ComputeSurfaceAreaToVolumeDirect::operator()() auto yPoints = static_cast(dims[1]); auto zPoints = static_cast(dims[2]); - float32 voxelVol = spacing[0] * spacing[1] * spacing[2]; + const float64 voxelVol = static_cast(spacing[0]) * spacing[1] * spacing[2]; + const float64 xyFaceArea = static_cast(spacing[0]) * spacing[1]; + const float64 yzFaceArea = static_cast(spacing[1]) * spacing[2]; + const float64 zxFaceArea = static_cast(spacing[2]) * spacing[0]; // Multiple cells contribute to one feature, so accumulation stays local until // the cell scan is complete. - std::vector featureSurfaceArea(static_cast(numFeatures), 0.0f); + std::vector featureSurfaceArea(static_cast(numFeatures), 0.0); // Flat offsets avoid repeated coordinate-to-index conversion for in-memory // six-neighbor reads. @@ -75,7 +78,7 @@ Result<> ComputeSurfaceAreaToVolumeDirect::operator()() int64 yStride = yIdx * xPoints; for(int64 xIdx = 0; xIdx < xPoints; xIdx++) { - float32 onSurface = 0.0f; + float64 onSurface = 0.0; int32 currentFeatureId = featureIdsStoreRef[zStride + yStride + xIdx]; // Feature 0 is the background tuple. if(currentFeatureId < 1) @@ -116,15 +119,15 @@ Result<> ComputeSurfaceAreaToVolumeDirect::operator()() { if(neighborOffsetIndex == 0 || neighborOffsetIndex == 5) { - onSurface = onSurface + spacing[0] * spacing[1]; + onSurface = onSurface + xyFaceArea; } if(neighborOffsetIndex == 1 || neighborOffsetIndex == 4) { - onSurface = onSurface + spacing[0] * spacing[2]; + onSurface = onSurface + zxFaceArea; } if(neighborOffsetIndex == 2 || neighborOffsetIndex == 3) { - onSurface = onSurface + spacing[1] * spacing[2]; + onSurface = onSurface + yzFaceArea; } } } @@ -134,11 +137,11 @@ Result<> ComputeSurfaceAreaToVolumeDirect::operator()() } } - const float32 thirdRootPi = std::pow(nx::core::Constants::k_PiF, 0.333333f); + const float64 thirdRootPi = std::pow(nx::core::Constants::k_PiD, 0.333333f); for(usize i = 1; i < numFeatures; i++) { - float32 featureVolume = voxelVol * numCells[i]; - surfaceAreaVolumeRatio[i] = featureSurfaceArea[i] / featureVolume; + const float64 featureVolume = voxelVol * numCells[i]; + surfaceAreaVolumeRatio[i] = static_cast(featureSurfaceArea[i] / featureVolume); } if(m_InputValues->CalculateSphericity) @@ -149,8 +152,8 @@ Result<> ComputeSurfaceAreaToVolumeDirect::operator()() // Sphericity is one for a sphere and decreases as the surface becomes less compact. for(usize i = 1; i < static_cast(numFeatures); i++) { - float32 featureVolume = voxelVol * numCells[i]; - sphericity[i] = (thirdRootPi * std::pow((6.0f * featureVolume), 0.66666f)) / featureSurfaceArea[i]; + const float64 featureVolume = voxelVol * numCells[i]; + sphericity[i] = static_cast((thirdRootPi * std::pow((6.0 * featureVolume), 0.66666f)) / featureSurfaceArea[i]); } } diff --git a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeScanline.cpp b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeScanline.cpp index eec275347c..4e3debaeb2 100644 --- a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeScanline.cpp +++ b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeScanline.cpp @@ -46,15 +46,15 @@ Result<> ComputeSurfaceAreaToVolumeScanline::operator()() auto yPoints = static_cast(dims[1]); auto zPoints = static_cast(dims[2]); - float32 voxelVol = spacing[0] * spacing[1] * spacing[2]; + const float64 voxelVol = static_cast(spacing[0]) * spacing[1] * spacing[2]; // Multiple cells contribute to one feature, so accumulation stays local until // the cell scan is complete. - std::vector featureSurfaceArea(static_cast(numFeatures), 0.0f); + std::vector featureSurfaceArea(static_cast(numFeatures), 0.0); - const float32 xyFaceArea = spacing[0] * spacing[1]; - const float32 yzFaceArea = spacing[1] * spacing[2]; - const float32 zxFaceArea = spacing[2] * spacing[0]; + const float64 xyFaceArea = static_cast(spacing[0]) * spacing[1]; + const float64 yzFaceArea = static_cast(spacing[1]) * spacing[2]; + const float64 zxFaceArea = static_cast(spacing[2]) * spacing[0]; const usize sliceSize = static_cast(yPoints) * static_cast(xPoints); @@ -95,7 +95,7 @@ Result<> ComputeSurfaceAreaToVolumeScanline::operator()() continue; } - float32 onSurface = 0.0f; + float64 onSurface = 0.0; // Z neighbors use adjacent buffers. X and Y neighbors use the current buffer. if(z > 0) @@ -174,11 +174,11 @@ Result<> ComputeSurfaceAreaToVolumeScanline::operator()() std::vector localSurfaceAreaVolumeRatio(numFeaturesUSize, 0.0f); - const float32 thirdRootPi = std::pow(nx::core::Constants::k_PiF, 0.333333f); + const float64 thirdRootPi = std::pow(nx::core::Constants::k_PiD, 0.333333f); for(usize i = 1; i < numFeaturesUSize; i++) { - float32 featureVolume = voxelVol * localNumCells[i]; - localSurfaceAreaVolumeRatio[i] = featureSurfaceArea[i] / featureVolume; + const float64 featureVolume = voxelVol * localNumCells[i]; + localSurfaceAreaVolumeRatio[i] = static_cast(featureSurfaceArea[i] / featureVolume); } ioResult = surfaceAreaVolumeRatio.copyFromBuffer(0, nonstd::span(localSurfaceAreaVolumeRatio.data(), numFeaturesUSize)); if(ioResult.invalid()) @@ -195,8 +195,8 @@ Result<> ComputeSurfaceAreaToVolumeScanline::operator()() std::vector localSphericity(numFeaturesUSize, 0.0f); for(usize i = 1; i < numFeaturesUSize; i++) { - float32 featureVolume = voxelVol * localNumCells[i]; - localSphericity[i] = (thirdRootPi * std::pow((6.0f * featureVolume), 0.66666f)) / featureSurfaceArea[i]; + const float64 featureVolume = voxelVol * localNumCells[i]; + localSphericity[i] = static_cast((thirdRootPi * std::pow((6.0 * featureVolume), 0.66666f)) / featureSurfaceArea[i]); } ioResult = sphericity.copyFromBuffer(0, nonstd::span(localSphericity.data(), numFeaturesUSize)); if(ioResult.invalid()) diff --git a/src/Plugins/SimplnxCore/test/ComputeSurfaceAreaToVolumeTest.cpp b/src/Plugins/SimplnxCore/test/ComputeSurfaceAreaToVolumeTest.cpp index 5cadbb9424..563c5a6993 100644 --- a/src/Plugins/SimplnxCore/test/ComputeSurfaceAreaToVolumeTest.cpp +++ b/src/Plugins/SimplnxCore/test/ComputeSurfaceAreaToVolumeTest.cpp @@ -181,6 +181,17 @@ TEST_CASE("SimplnxCore::ComputeSurfaceAreaToVolumeFilter: analytical single-slic SurfaceAreaToVolumeTest::CheckInteriorPairSurfaceMetrics(scope, pairAxis, FloatVec3{2.0f, 3.0f, 5.0f}, calculateSphericity, SizeVec3{5, 5, 1}); } +TEST_CASE("SimplnxCore::ComputeSurfaceAreaToVolumeFilter: decimal connected comb", "[SimplnxCore][ComputeSurfaceAreaToVolumeFilter]") +{ + UnitTest::LoadPlugins(); + const auto scenario = GENERATE(from_range(UnitTest::SelectAlgorithmTestScenariosForInMemoryStores())); + const auto spacing = GENERATE(FloatVec3{0.13f, 0.27f, 1.1f}, FloatVec3{0.13f, 0.13f, 0.13f}); + const auto calculateSphericity = GENERATE(false, true); + CAPTURE(scenario); + UnitTest::AlgorithmTestScope scope(scenario); + SurfaceAreaToVolumeTest::CheckConnectedCombSurfaceMetrics(scope, spacing, calculateSphericity); +} + TEST_CASE("SimplnxCore::ComputeSurfaceAreaToVolume", "[SimplnxCore][ComputeSurfaceAreaToVolume]") { UnitTest::LoadPlugins(); diff --git a/src/Plugins/SimplnxCore/test/ComputeSurfaceAreaToVolumeTestUtils.hpp b/src/Plugins/SimplnxCore/test/ComputeSurfaceAreaToVolumeTestUtils.hpp index d7d9619c17..e3ca250e38 100644 --- a/src/Plugins/SimplnxCore/test/ComputeSurfaceAreaToVolumeTestUtils.hpp +++ b/src/Plugins/SimplnxCore/test/ComputeSurfaceAreaToVolumeTestUtils.hpp @@ -10,6 +10,7 @@ #include +#include #include #include #include @@ -167,4 +168,161 @@ void CheckInteriorPairSurfaceMetrics(ScopeT& scope, nx::core::usize pairAxis, co CHECK(featureAM->getShape() == featureShape); UnitTest::CheckArraysInheritTupleDims(dataStructure); } +// A connected plate with long, separated teeth exposes repeated decimal-area accumulation. +template +void CheckConnectedCombSurfaceMetrics(ScopeT& scope, const nx::core::FloatVec3& spacing, bool calculateSphericity) +{ + using namespace nx::core; + DataStructure dataStructure; + const SizeVec3 dimensions = {137, 113, 37}; + const ShapeType cellShape = {dimensions[2], dimensions[1], dimensions[0]}; + const ShapeType featureShape = {2}; + const ShapeType componentShape = {1}; + const DataPath geomPath({"ImageGeom"}); + const DataPath cellPath = geomPath.createChildPath("CellData"); + const DataPath featurePath = geomPath.createChildPath("CellFeatureData"); + const DataPath idsPath = cellPath.createChildPath("FeatureIds"); + const DataPath countsPath = featurePath.createChildPath("NumCells"); + const DataPath ratioPath = featurePath.createChildPath("SurfaceAreaVolumeRatio"); + const DataPath sphericityPath = featurePath.createChildPath("Sphericity"); + const FloatVec3 origin = {-1.0f, 4.0f, 7.0f}; + const usize cellCount = dimensions[0] * dimensions[1] * dimensions[2]; + + // The x=1 backing plate is 111 by 35. Each odd (y,z) location extends a tooth + // another 134 cells along X. All teeth connect through the plate and the entire + // comb has a one-cell background border, so no exterior-domain faces enter the oracle. + constexpr int32 plateY = 111; + constexpr int32 plateZ = 35; + constexpr int32 toothLength = 134; + constexpr int32 teethY = 56; + constexpr int32 teethZ = 18; + constexpr int32 combCellCount = plateY * plateZ + toothLength * teethY * teethZ; + constexpr std::array normalFaceCounts = {2 * plateY * plateZ, 2 * plateZ + 2 * toothLength * teethY * teethZ, 2 * plateY + 2 * toothLength * teethY * teethZ}; + STATIC_REQUIRE(combCellCount == 138957); + STATIC_REQUIRE(normalFaceCounts[0] == 7770); + STATIC_REQUIRE(normalFaceCounts[1] == 270214); + STATIC_REQUIRE(normalFaceCounts[2] == 270366); + const std::array counts = {static_cast(cellCount) - combCellCount, combCellCount}; + std::vector labels(cellCount, 0); + for(usize z = 1; z <= plateZ; z++) + { + for(usize y = 1; y <= plateY; y++) + { + for(usize x = 1; x <= toothLength + 1; x++) + { + if(x == 1 || (y % 2 == 1 && z % 2 == 1)) + { + labels[(z * dimensions[1] + y) * dimensions[0] + x] = 1; + } + } + } + } + REQUIRE(std::count(labels.begin(), labels.end(), int32{1}) == combCellCount); + + auto* geom = ImageGeom::Create(dataStructure, "ImageGeom"); + REQUIRE(geom != nullptr); + geom->setDimensions(dimensions); + geom->setSpacing(spacing); + geom->setOrigin(origin); + auto* cellAM = AttributeMatrix::Create(dataStructure, "CellData", cellShape, geom->getId()); + REQUIRE(cellAM != nullptr); + geom->setCellData(*cellAM); + auto* featureAM = AttributeMatrix::Create(dataStructure, "CellFeatureData", featureShape, geom->getId()); + REQUIRE(featureAM != nullptr); + auto idsStore = DataStoreUtilities::CreateDataStore(dataStructure, idsPath, cellShape, componentShape); + auto countsStore = DataStoreUtilities::CreateDataStore(dataStructure, countsPath, featureShape, componentShape); + REQUIRE(idsStore != nullptr); + REQUIRE(countsStore != nullptr); + REQUIRE(Int32Array::Create(dataStructure, "FeatureIds", idsStore, cellAM->getId()) != nullptr); + REQUIRE(Int32Array::Create(dataStructure, "NumCells", countsStore, featureAM->getId()) != nullptr); + auto idsWrite = idsStore->copyFromBuffer(0, nonstd::span(labels.data(), labels.size())); + SIMPLNX_RESULT_REQUIRE_VALID(idsWrite); + auto countsWrite = countsStore->copyFromBuffer(0, nonstd::span(counts.data(), counts.size())); + SIMPLNX_RESULT_REQUIRE_VALID(countsWrite); + + REQUIRE_NOTHROW(dataStructure.getDataRefAs(idsPath)); + REQUIRE_NOTHROW(dataStructure.getDataRefAs(countsPath)); + const auto& ids = dataStructure.getDataRefAs(idsPath); + const auto& numCells = dataStructure.getDataRefAs(countsPath); + scope.requireExpectedStore(ids); + scope.requireExpectedStore(numCells); + const auto idsFormat = ids.getDataFormat(); + const auto countsFormat = numCells.getDataFormat(); + + ComputeSurfaceAreaToVolumeFilter filter; + Arguments args; + args.insertOrAssign(ComputeSurfaceAreaToVolumeFilter::k_SelectedImageGeometryPath_Key, std::make_any(geomPath)); + args.insertOrAssign(ComputeSurfaceAreaToVolumeFilter::k_CellFeatureIdsArrayPath_Key, std::make_any(idsPath)); + args.insertOrAssign(ComputeSurfaceAreaToVolumeFilter::k_NumCellsArrayPath_Key, std::make_any(countsPath)); + args.insertOrAssign(ComputeSurfaceAreaToVolumeFilter::k_CalculateSphericity_Key, std::make_any(calculateSphericity)); + args.insertOrAssign(ComputeSurfaceAreaToVolumeFilter::k_SurfaceAreaVolumeRatioArrayName_Key, std::make_any("SurfaceAreaVolumeRatio")); + args.insertOrAssign(ComputeSurfaceAreaToVolumeFilter::k_SphericityArrayName_Key, std::make_any("Sphericity")); + auto preflight = filter.preflight(dataStructure, args); + SIMPLNX_RESULT_REQUIRE_VALID(preflight.outputActions); + auto result = scope.executeFilter(filter, dataStructure, args); + SIMPLNX_RESULT_REQUIRE_VALID(result.result); + + // Count entire plate and tooth faces analytically; do not repeat the production neighbor scan. + const std::array physicalSpacing = {spacing[0], spacing[1], spacing[2]}; + const double area = + normalFaceCounts[0] * physicalSpacing[1] * physicalSpacing[2] + normalFaceCounts[1] * physicalSpacing[0] * physicalSpacing[2] + normalFaceCounts[2] * physicalSpacing[0] * physicalSpacing[1]; + const double volume = combCellCount * physicalSpacing[0] * physicalSpacing[1] * physicalSpacing[2]; + CAPTURE(spacing[0], spacing[1], spacing[2], calculateSphericity, area, volume); + REQUIRE_NOTHROW(dataStructure.getDataRefAs(ratioPath)); + const auto& ratios = dataStructure.getDataRefAs(ratioPath); + scope.requireExpectedStore(ratios); + CHECK(ratios.getTupleShape() == featureShape); + CHECK(ratios.getComponentShape() == componentShape); + std::array ratioValues; + auto ratiosRead = ratios.getDataStoreRef().copyIntoBuffer(0, nonstd::span(ratioValues.data(), ratioValues.size())); + SIMPLNX_RESULT_REQUIRE_VALID(ratiosRead); + CHECK(ratioValues[0] == 0.0f); + CHECK(ratioValues[1] == Approx(area / volume).epsilon(1.0e-6)); + if(calculateSphericity) + { + REQUIRE_NOTHROW(dataStructure.getDataRefAs(sphericityPath)); + const auto& sphericity = dataStructure.getDataRefAs(sphericityPath); + scope.requireExpectedStore(sphericity); + CHECK(sphericity.getTupleShape() == featureShape); + CHECK(sphericity.getComponentShape() == componentShape); + std::array values; + auto sphericityRead = sphericity.getDataStoreRef().copyIntoBuffer(0, nonstd::span(values.data(), values.size())); + SIMPLNX_RESULT_REQUIRE_VALID(sphericityRead); + CHECK(values[0] == 0.0f); + const double expected = std::cbrt(std::acos(-1.0)) * std::pow(6.0 * volume, 2.0 / 3.0) / area; + // Allow the existing truncated sphericity exponents until their separate correction. + CHECK(values[1] == Approx(expected).epsilon(1.0e-4)); + } + else + { + CHECK(dataStructure.getDataAs(sphericityPath) == nullptr); + } + + std::vector actualLabels(cellCount); + std::array actualCounts; + auto idsRead = ids.getDataStoreRef().copyIntoBuffer(0, nonstd::span(actualLabels.data(), actualLabels.size())); + SIMPLNX_RESULT_REQUIRE_VALID(idsRead); + auto countsRead = numCells.getDataStoreRef().copyIntoBuffer(0, nonstd::span(actualCounts.data(), actualCounts.size())); + SIMPLNX_RESULT_REQUIRE_VALID(countsRead); + CHECK(actualLabels == labels); + CHECK(actualCounts == counts); + CHECK(ids.getTupleShape() == cellShape); + CHECK(ids.getComponentShape() == componentShape); + CHECK(numCells.getTupleShape() == featureShape); + CHECK(numCells.getComponentShape() == componentShape); + CHECK(ids.getDataFormat() == idsFormat); + CHECK(numCells.getDataFormat() == countsFormat); + CHECK(&ids.getDataStoreRef() == idsStore.get()); + CHECK(&numCells.getDataStoreRef() == countsStore.get()); + scope.requireExpectedStore(ids); + scope.requireExpectedStore(numCells); + REQUIRE_NOTHROW(dataStructure.getDataRefAs(geomPath)); + const auto& finalGeom = dataStructure.getDataRefAs(geomPath); + CHECK(finalGeom.getDimensions() == dimensions); + CHECK(finalGeom.getSpacing() == spacing); + CHECK(finalGeom.getOrigin() == origin); + CHECK(cellAM->getShape() == cellShape); + CHECK(featureAM->getShape() == featureShape); + UnitTest::CheckArraysInheritTupleDims(dataStructure); +} } // namespace SurfaceAreaToVolumeTest From df83795b51354626bb91afd690cb8e3d08c29349 Mon Sep 17 00:00:00 2001 From: Jessica Marquis Date: Thu, 15 Oct 2026 12:05:16 -0400 Subject: [PATCH 04/28] BUG: Correct sphericity exponents Use double precision with a cube root of pi and a two-thirds exponent. Check uniform scaling and preserve zero and negative volume behavior. Signed-off-by: Jessica Marquis --- .../ComputeSurfaceAreaToVolumeDirect.cpp | 4 +- .../ComputeSurfaceAreaToVolumeScanline.cpp | 4 +- .../test/ComputeSurfaceAreaToVolumeTest.cpp | 19 ++++++ .../ComputeSurfaceAreaToVolumeTestUtils.hpp | 68 +++++++++++++++---- 4 files changed, 78 insertions(+), 17 deletions(-) diff --git a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeDirect.cpp b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeDirect.cpp index 4525b03465..02b20b2bf6 100644 --- a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeDirect.cpp +++ b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeDirect.cpp @@ -137,7 +137,7 @@ Result<> ComputeSurfaceAreaToVolumeDirect::operator()() } } - const float64 thirdRootPi = std::pow(nx::core::Constants::k_PiD, 0.333333f); + const float64 thirdRootPi = std::cbrt(nx::core::Constants::k_PiD); for(usize i = 1; i < numFeatures; i++) { const float64 featureVolume = voxelVol * numCells[i]; @@ -153,7 +153,7 @@ Result<> ComputeSurfaceAreaToVolumeDirect::operator()() for(usize i = 1; i < static_cast(numFeatures); i++) { const float64 featureVolume = voxelVol * numCells[i]; - sphericity[i] = static_cast((thirdRootPi * std::pow((6.0 * featureVolume), 0.66666f)) / featureSurfaceArea[i]); + sphericity[i] = static_cast((thirdRootPi * std::pow((6.0 * featureVolume), 2.0 / 3.0)) / featureSurfaceArea[i]); } } diff --git a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeScanline.cpp b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeScanline.cpp index 4e3debaeb2..d1457ae369 100644 --- a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeScanline.cpp +++ b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeScanline.cpp @@ -174,7 +174,7 @@ Result<> ComputeSurfaceAreaToVolumeScanline::operator()() std::vector localSurfaceAreaVolumeRatio(numFeaturesUSize, 0.0f); - const float64 thirdRootPi = std::pow(nx::core::Constants::k_PiD, 0.333333f); + const float64 thirdRootPi = std::cbrt(nx::core::Constants::k_PiD); for(usize i = 1; i < numFeaturesUSize; i++) { const float64 featureVolume = voxelVol * localNumCells[i]; @@ -196,7 +196,7 @@ Result<> ComputeSurfaceAreaToVolumeScanline::operator()() for(usize i = 1; i < numFeaturesUSize; i++) { const float64 featureVolume = voxelVol * localNumCells[i]; - localSphericity[i] = static_cast((thirdRootPi * std::pow((6.0 * featureVolume), 0.66666f)) / featureSurfaceArea[i]); + localSphericity[i] = static_cast((thirdRootPi * std::pow((6.0 * featureVolume), 2.0 / 3.0)) / featureSurfaceArea[i]); } ioResult = sphericity.copyFromBuffer(0, nonstd::span(localSphericity.data(), numFeaturesUSize)); if(ioResult.invalid()) diff --git a/src/Plugins/SimplnxCore/test/ComputeSurfaceAreaToVolumeTest.cpp b/src/Plugins/SimplnxCore/test/ComputeSurfaceAreaToVolumeTest.cpp index 563c5a6993..b798657f45 100644 --- a/src/Plugins/SimplnxCore/test/ComputeSurfaceAreaToVolumeTest.cpp +++ b/src/Plugins/SimplnxCore/test/ComputeSurfaceAreaToVolumeTest.cpp @@ -192,6 +192,25 @@ TEST_CASE("SimplnxCore::ComputeSurfaceAreaToVolumeFilter: decimal connected comb SurfaceAreaToVolumeTest::CheckConnectedCombSurfaceMetrics(scope, spacing, calculateSphericity); } +TEST_CASE("SimplnxCore::ComputeSurfaceAreaToVolumeFilter: scale-invariant sphericity", "[SimplnxCore][ComputeSurfaceAreaToVolumeFilter]") +{ + UnitTest::LoadPlugins(); + const auto scenario = GENERATE(from_range(UnitTest::SelectAlgorithmTestScenariosForInMemoryStores())); + CAPTURE(scenario); + UnitTest::AlgorithmTestScope scope(scenario); + SurfaceAreaToVolumeTest::CheckScaleInvariantSphericity(scope); +} + +TEST_CASE("SimplnxCore::ComputeSurfaceAreaToVolumeFilter: nonpositive supplied pair counts", "[SimplnxCore][ComputeSurfaceAreaToVolumeFilter]") +{ + UnitTest::LoadPlugins(); + const auto scenario = GENERATE(from_range(UnitTest::SelectAlgorithmTestScenariosForInMemoryStores())); + const auto suppliedPairCount = GENERATE(int32{0}, int32{-2}); + CAPTURE(scenario, suppliedPairCount); + UnitTest::AlgorithmTestScope scope(scenario); + SurfaceAreaToVolumeTest::CheckInteriorPairSurfaceMetrics(scope, 0, FloatVec3{2.0f, 3.0f, 5.0f}, true, SizeVec3{5, 5, 5}, suppliedPairCount); +} + TEST_CASE("SimplnxCore::ComputeSurfaceAreaToVolume", "[SimplnxCore][ComputeSurfaceAreaToVolume]") { UnitTest::LoadPlugins(); diff --git a/src/Plugins/SimplnxCore/test/ComputeSurfaceAreaToVolumeTestUtils.hpp b/src/Plugins/SimplnxCore/test/ComputeSurfaceAreaToVolumeTestUtils.hpp index e3ca250e38..740856fd68 100644 --- a/src/Plugins/SimplnxCore/test/ComputeSurfaceAreaToVolumeTestUtils.hpp +++ b/src/Plugins/SimplnxCore/test/ComputeSurfaceAreaToVolumeTestUtils.hpp @@ -19,7 +19,8 @@ namespace SurfaceAreaToVolumeTest { // A wrong X/Y face weight changes the physical area of this interior box. template -void CheckInteriorPairSurfaceMetrics(ScopeT& scope, nx::core::usize pairAxis, const nx::core::FloatVec3& spacing, bool calculateSphericity, const nx::core::SizeVec3& dimensions = {5, 5, 5}) +std::array CheckInteriorPairSurfaceMetrics(ScopeT& scope, nx::core::usize pairAxis, const nx::core::FloatVec3& spacing, bool calculateSphericity, + const nx::core::SizeVec3& dimensions = {5, 5, 5}, nx::core::int32 suppliedPairCount = 2) { using namespace nx::core; DataStructure dataStructure; @@ -64,7 +65,7 @@ void CheckInteriorPairSurfaceMetrics(ScopeT& scope, nx::core::usize pairAxis, co second[pairAxis]++; labels[(first[2] * dimensions[1] + first[1]) * dimensions[0] + first[0]] = static_cast(pairFeature); labels[(second[2] * dimensions[1] + second[1]) * dimensions[0] + second[0]] = static_cast(pairFeature); - const std::array counts = singleSlice ? std::array{0, 23, 2} : std::array{0, 123, 2}; + const std::array counts = {0, singleSlice ? 23 : 123, suppliedPairCount}; auto idsWrite = idsStore->copyFromBuffer(0, nonstd::span(labels.data(), labels.size())); SIMPLNX_RESULT_REQUIRE_VALID(idsWrite); auto countsWrite = countsStore->copyFromBuffer(0, nonstd::span(counts.data(), counts.size())); @@ -99,9 +100,10 @@ void CheckInteriorPairSurfaceMetrics(ScopeT& scope, nx::core::usize pairAxis, co const double area = 2.0 * ((singleSlice ? 0.0 : sides[0] * sides[1]) + sides[0] * sides[2] + sides[1] * sides[2]); const double voxelVolume = static_cast(spacing[0]) * spacing[1] * spacing[2]; std::array volumes = {0.0, 0.0, 0.0}; - volumes[pairFeature] = sides[0] * sides[1] * sides[2]; + volumes[pairFeature] = suppliedPairCount * voxelVolume; volumes[enclosingFeature] = (singleSlice ? 23.0 : 123.0) * voxelVolume; - CAPTURE(pairAxis, spacing[0], spacing[1], spacing[2], calculateSphericity, singleSlice, area); + CAPTURE(pairAxis, spacing[0], spacing[1], spacing[2], calculateSphericity, singleSlice, suppliedPairCount, area); + REQUIRE(area > 0.0); REQUIRE_NOTHROW(dataStructure.getDataRefAs(ratioPath)); const auto& ratios = dataStructure.getDataRefAs(ratioPath); @@ -115,8 +117,17 @@ void CheckInteriorPairSurfaceMetrics(ScopeT& scope, nx::core::usize pairAxis, co for(usize feature = 1; feature < 3; feature++) { CAPTURE(feature); - CHECK(ratioValues[feature] == Approx(area / volumes[feature]).epsilon(1.0e-6)); + if(volumes[feature] == 0.0) + { + CHECK(std::isinf(ratioValues[feature])); + CHECK(ratioValues[feature] > 0.0f); + } + else + { + CHECK(ratioValues[feature] == Approx(area / volumes[feature]).epsilon(1.0e-6)); + } } + std::array sphericityValues = {}; if(calculateSphericity) { REQUIRE_NOTHROW(dataStructure.getDataRefAs(sphericityPath)); @@ -124,16 +135,28 @@ void CheckInteriorPairSurfaceMetrics(ScopeT& scope, nx::core::usize pairAxis, co scope.requireExpectedStore(sphericity); CHECK(sphericity.getTupleShape() == featureShape); CHECK(sphericity.getComponentShape() == componentShape); - std::array values; - auto sphericityRead = sphericity.getDataStoreRef().copyIntoBuffer(0, nonstd::span(values.data(), values.size())); + auto sphericityRead = sphericity.getDataStoreRef().copyIntoBuffer(0, nonstd::span(sphericityValues.data(), sphericityValues.size())); SIMPLNX_RESULT_REQUIRE_VALID(sphericityRead); - CHECK(values[0] == 0.0f); + CHECK(sphericityValues[0] == 0.0f); for(usize feature = 1; feature < 3; feature++) { CAPTURE(feature); - const double expected = std::cbrt(std::acos(-1.0)) * std::pow(6.0 * volumes[feature], 2.0 / 3.0) / area; - // This tolerance accommodates the existing truncated exponents, intentionally preserved by this correction. - CHECK(values[feature] == Approx(expected).epsilon(1.0e-4)); + if(volumes[feature] < 0.0) + { + CHECK(std::isnan(sphericityValues[feature])); + } + else if(volumes[feature] == 0.0) + { + CHECK(sphericityValues[feature] == 0.0f); + } + else + { + // Derive the equal-volume sphere's area from its radius independently of the implementation formula. + const double pi = std::acos(-1.0); + const double sphereRadius = std::cbrt(3.0 * volumes[feature] / (4.0 * pi)); + const double expected = 4.0 * pi * sphereRadius * sphereRadius / area; + CHECK(sphericityValues[feature] == Approx(expected).epsilon(1.0e-6)); + } } } else @@ -167,6 +190,26 @@ void CheckInteriorPairSurfaceMetrics(ScopeT& scope, nx::core::usize pairAxis, co CHECK(cellAM->getShape() == cellShape); CHECK(featureAM->getShape() == featureShape); UnitTest::CheckArraysInheritTupleDims(dataStructure); + return sphericityValues; +} + +template +void CheckScaleInvariantSphericity(ScopeT& scope) +{ + using namespace nx::core; + const auto reference = CheckInteriorPairSurfaceMetrics(scope, 0, FloatVec3{2.0f, 3.0f, 5.0f}, true); + for(const int exponent : {-20, 20}) + { + CAPTURE(exponent); + const FloatVec3 spacing = {std::ldexp(2.0f, exponent), std::ldexp(3.0f, exponent), std::ldexp(5.0f, exponent)}; + // The pair helper independently checks each scale against the equal-volume sphere oracle. + const auto scaled = CheckInteriorPairSurfaceMetrics(scope, 0, spacing, true); + for(usize feature = 1; feature < reference.size(); feature++) + { + CAPTURE(feature); + CHECK(scaled[feature] == Approx(reference[feature]).epsilon(1.0e-6)); + } + } } // A connected plate with long, separated teeth exposes repeated decimal-area accumulation. template @@ -290,8 +333,7 @@ void CheckConnectedCombSurfaceMetrics(ScopeT& scope, const nx::core::FloatVec3& SIMPLNX_RESULT_REQUIRE_VALID(sphericityRead); CHECK(values[0] == 0.0f); const double expected = std::cbrt(std::acos(-1.0)) * std::pow(6.0 * volume, 2.0 / 3.0) / area; - // Allow the existing truncated sphericity exponents until their separate correction. - CHECK(values[1] == Approx(expected).epsilon(1.0e-4)); + CHECK(values[1] == Approx(expected).epsilon(1.0e-6)); } else { From 697414c1ba8f4b414809c1ef539e0386b576e302 Mon Sep 17 00:00:00 2001 From: Jessica Marquis Date: Thu, 15 Oct 2026 12:11:35 -0400 Subject: [PATCH 05/28] DOC: Correct surface-metric interface and volume rules Describe zero-label interfaces, omitted exterior faces, supplied volumes, and optional sphericity. Explain the numerical compatibility changes. Signed-off-by: Jessica Marquis --- .../docs/ComputeSurfaceAreaToVolumeFilter.md | 44 ++++++++++++++----- .../ComputeSurfaceAreaToVolumeScanline.hpp | 6 +-- 2 files changed, 35 insertions(+), 15 deletions(-) diff --git a/src/Plugins/SimplnxCore/docs/ComputeSurfaceAreaToVolumeFilter.md b/src/Plugins/SimplnxCore/docs/ComputeSurfaceAreaToVolumeFilter.md index 5a1a25a18c..367c82fa9e 100644 --- a/src/Plugins/SimplnxCore/docs/ComputeSurfaceAreaToVolumeFilter.md +++ b/src/Plugins/SimplnxCore/docs/ComputeSurfaceAreaToVolumeFilter.md @@ -12,20 +12,18 @@ This filter also optionally calculates the [Sphericity](https://en.wikipedia.org ![Equation for Sphericity used in the filter](Images/Sphericity_Equation.png) -This **Filter** determines whether a **Feature** touches an outer *Surface* of the sample volume. A **Feature** is considered touching the *Surface* of the sample if either of the following conditions are met: - -+ Any cell location is xmin, xmax, ymin, ymax, zmin or zmax -+ Any cell has **Feature ID = 0** as a neighbor. +Use [Compute Surface Features](ComputeSurfaceFeaturesFilter.md) when you need a separate flag that identifies features touching the sample surface. ### Required Input Sources - **Cell Feature Ids** -- the per-**Cell** **Feature** label array, typically produced by [Segment Features (Scalar)](ScalarSegmentFeaturesFilter.md) or another segmentation filter. +- **Number of Cells** -- the per-feature cell counts, typically produced by [Compute Feature Sizes](ComputeFeatureSizesFilter.md). + +The label array must have one tuple per cell in the selected geometry. The array can be stored separately from that geometry. Its tuple count, cell ordering, and feature labels must describe the selected image. Each Feature Id must index a tuple in the selected feature data. -## Algorithm Details +## Algorithm -- First, all the boundary **Cells** are found for each **Feature** (see also [Compute Boundary Cells (Image)](ComputeBoundaryCellsFilter.md)). -- Next, the surface area for each face that is in contact with a different **Feature** is totalled as long as that neighboring *featureId* is > 0. -- This number is divided by the volume of each **Feature**, calculated by taking the number of **Cells** of each **Feature** and multiplying by the volume of a **Cell**. +For each cell with a positive Feature Id, the filter examines its six face-sharing neighbors within the image. A face contributes area to the current feature when the neighbor has a different Feature Id, including Feature Id 0. An interface between two positive features contributes to each feature's area. Faces outside the image are omitted. Feature Id 0 is the background; its output tuple remains zero. For cell spacing `(dx, dy, dz)`, the area of a face uses the two spacing components perpendicular to its normal: @@ -33,19 +31,41 @@ For cell spacing `(dx, dy, dz)`, the area of a face uses the two spacing compone - Y-normal face: `dx * dz`. - Z-normal face: `dx * dy`. -Corrected X/Y face weights can change surface-area-to-volume and sphericity values for images whose X and Y spacings differ. Isotropic results are unchanged. +The filter calculates each feature's volume as `V = Number of Cells * dx * dy * dz`. It uses the supplied cell count without recounting the labels or checking that the count matches them. The surface-area-to-volume ratio is `S / V`, where `S` is the accumulated face area. Area has units of length squared, and volume has units of length cubed. + +When *Calculate Sphericity* is enabled, the filter also calculates `Psi = pi^(1/3) * (6 * V)^(2/3) / S`. Psi is dimensionless. For a complete closed surface and consistent positive volume, a sphere has sphericity 1. Both output arrays use 32-bit floating-point values; face areas, accumulated areas, and metric calculations use 64-bit floating-point values. + +### Algorithm selection + +The filter automatically uses *Direct* when Cell Feature Ids are stored in memory and *Scanline* when they use out-of-core storage. Both methods use the same face-counting and volume rules. + +### Direct + +Direct reads neighboring labels from the array and accumulates one surface area per feature. Its additional working memory scales as `O(F)`, where `F` is the number of feature tuples, including background. + +### Scanline + +Scanline reads labels in sequential slices and keeps three adjacent XY slices in memory. It reads the feature counts and writes the metrics in bulk. Its additional working memory scales as `O(X * Y + F)`, where `X` and `Y` are image dimensions in cells. This avoids buffering the full label volume, but the feature arrays can still be large when the feature count approaches the cell count. These memory estimates exclude the input/output stores and their caches. + +### Compatibility with earlier results + +Corrected X/Y face weights can change results when X and Y spacings differ. That weight correction alone leaves isotropic face products unchanged. The improved numerical precision and sphericity calculation can also change isotropic results. ### WARNING - Aliasing The surface area will be the surface area of the **Cells** in contact with the neighboring **Feature** and will be influenced by the *aliasing* of the structure — the jagged, stair-stepped approximation of a smooth surface that results from representing it on a discrete voxel grid. As a result, the surface area to volume will likely be over-estimated with respect to the *real* **Feature**. -### WARNING - Skewed Results for features touching the surface +### WARNING - Incomplete surfaces and nonfinite results + +Image-exterior faces are omitted, so a feature touching the image boundary can have an incomplete measured surface. This can reduce its surface-area-to-volume ratio and increase its sphericity, even above 1. In-image faces against Feature Id 0 are included. -Because the filter does not include any surface that is touching/connected to a "FeatureId = 0", those features that are in contact with the edge of the virtual volume or in contact with internal features that are labeled as "FeatureId = 0" will have their values skewed. +The filter does not reject zero or negative supplied cell counts or replace nonfinite results. For positive area and zero volume, the ratio is infinite and sphericity is zero. For positive volume and zero measured area, the ratio is zero and sphericity is infinite. Zero area with zero volume produces NaN (not a number). A negative volume can produce a negative ratio and NaN sphericity. Interpret these values as limitations of the supplied volume or measured surface. ### Warning - 2D Image Geometry Results -Because even a single slice has *volume* according to DREAM3D-NX, results will still be computed. These results should **NOT** be interpreted as "Boundary Length to Area" values. +For a single XY slice, each cell still has thickness `dz`, and the filter uses three-dimensional cell volumes. Both Z-normal faces lie outside the image and are omitted. The counted side-face area equals the counted in-plane boundary length times `dz`. + +When the supplied counts match the labels, thickness cancels in the ratio. The result then equals counted in-plane boundary length divided by feature area, with units of inverse length. Image-exterior edges remain omitted, so this need not be the feature's full perimeter-to-area ratio. Optional sphericity still uses the three-dimensional formula and depends on the slice thickness; it is not a two-dimensional circularity measure. % Auto generated parameter table will be inserted here diff --git a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeScanline.hpp b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeScanline.hpp index 94bacfc293..ce03769d4a 100644 --- a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeScanline.hpp +++ b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeScanline.hpp @@ -46,10 +46,10 @@ class SIMPLNXCORE_EXPORT ComputeSurfaceAreaToVolumeScanline /** * @brief Calculates surface metrics with bulk I/O. - * @return Error from Feature Id validation, or success after cancellation. + * @return Error from Feature Id validation or bulk I/O; success on completion or cancellation. * - * Cancellation during the cell scan leaves metric outputs unchanged. Current - * bulk-I/O Result values are not inspected. + * Cancellation during the cell scan leaves metric outputs unchanged. A bulk-I/O + * error stops processing. An output write error can leave partial metric outputs. */ Result<> operator()(); From c7f1a50d5ade586cc5f29051c01f8b22b798d18e Mon Sep 17 00:00:00 2001 From: Jessica Marquis Date: Thu, 15 Oct 2026 12:35:25 -0400 Subject: [PATCH 06/28] BUG: Reject unsupported Feature Id array kinds in preflight Return a preflight error for StringArray and NeighborList inputs before reading Feature Id tuple metadata. Add tests for both input slots. Signed-off-by: Jessica Marquis --- .../ComputeSurfaceAreaToVolumeFilter.cpp | 10 +- .../test/ComputeSurfaceAreaToVolumeTest.cpp | 91 +++++++++++++++++++ 2 files changed, 98 insertions(+), 3 deletions(-) diff --git a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/ComputeSurfaceAreaToVolumeFilter.cpp b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/ComputeSurfaceAreaToVolumeFilter.cpp index 513bd71dc2..1256fe2a44 100644 --- a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/ComputeSurfaceAreaToVolumeFilter.cpp +++ b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/ComputeSurfaceAreaToVolumeFilter.cpp @@ -99,12 +99,16 @@ IFilter::PreflightResult ComputeSurfaceAreaToVolumeFilter::preflightImpl(const D auto pImageGeometryPathValue = filterArgs.value(k_SelectedImageGeometryPath_Key); const auto& imageGeom = dataStructure.getDataRefAs(pImageGeometryPathValue); - const auto& featureIds = dataStructure.getDataRefAs(pFeatureIdsArrayPathValue); - if(featureIds.getNumberOfTuples() != imageGeom.getNumberOfCells()) + const auto* featureIds = dataStructure.getDataAs(pFeatureIdsArrayPathValue); + if(featureIds == nullptr) + { + return MakePreflightErrorResult(-12804, fmt::format("The selected Feature Ids object '{}' is not an int32 DataArray. Select a scalar int32 DataArray.", pFeatureIdsArrayPathValue.toString())); + } + if(featureIds->getNumberOfTuples() != imageGeom.getNumberOfCells()) { return MakePreflightErrorResult( -12803, fmt::format("The Feature Ids array '{}' has {} tuples, but the selected Image Geometry '{}' has {} cells. Select a Feature Ids array with one tuple per geometry cell.", - pFeatureIdsArrayPathValue.toString(), featureIds.getNumberOfTuples(), pImageGeometryPathValue.toString(), imageGeom.getNumberOfCells())); + pFeatureIdsArrayPathValue.toString(), featureIds->getNumberOfTuples(), pImageGeometryPathValue.toString(), imageGeom.getNumberOfCells())); } PreflightResult preflightResult; diff --git a/src/Plugins/SimplnxCore/test/ComputeSurfaceAreaToVolumeTest.cpp b/src/Plugins/SimplnxCore/test/ComputeSurfaceAreaToVolumeTest.cpp index b798657f45..e00b97e5e2 100644 --- a/src/Plugins/SimplnxCore/test/ComputeSurfaceAreaToVolumeTest.cpp +++ b/src/Plugins/SimplnxCore/test/ComputeSurfaceAreaToVolumeTest.cpp @@ -6,6 +6,8 @@ #include "simplnx/DataStructure/AttributeMatrix.hpp" #include "simplnx/DataStructure/DataArray.hpp" #include "simplnx/DataStructure/Geometry/ImageGeom.hpp" +#include "simplnx/DataStructure/NeighborList.hpp" +#include "simplnx/DataStructure/StringArray.hpp" #include "simplnx/Parameters/ArrayCreationParameter.hpp" #include "simplnx/Parameters/BoolParameter.hpp" #include "simplnx/UnitTest/UnitTestCommon.hpp" @@ -158,6 +160,95 @@ TEST_CASE("SimplnxCore::ComputeSurfaceAreaToVolumeFilter: geometry and FeatureId UnitTest::CheckArraysInheritTupleDims(dataStructure); } +TEST_CASE("SimplnxCore::ComputeSurfaceAreaToVolumeFilter: rejects non-DataArray selections", "[SimplnxCore][ComputeSurfaceAreaToVolumeFilter]") +{ + UnitTest::LoadPlugins(); + const bool replaceFeatureIds = GENERATE(true, false); + const bool useStringArray = GENERATE(true, false); + CAPTURE(replaceFeatureIds, useStringArray); + + DataStructure dataStructure; + const DataPath geomPath({"ImageGeom"}); + const DataPath cellPath = geomPath.createChildPath("CellData"); + const DataPath featurePath = geomPath.createChildPath("CellFeatureData"); + const DataPath idsPath = cellPath.createChildPath("FeatureIds"); + const DataPath countsPath = featurePath.createChildPath("NumCells"); + const DataPath ratioPath = featurePath.createChildPath("SurfaceAreaVolumeRatio"); + const DataPath sphericityPath = featurePath.createChildPath("Sphericity"); + const ShapeType cellShape = {2, 2, 2}; + const ShapeType featureShape = {2}; + const std::vector labels(8, 1); + const std::vector counts = {0, 8}; + + auto* geom = ImageGeom::Create(dataStructure, geomPath.getTargetName()); + REQUIRE(geom != nullptr); + geom->setDimensions({2, 2, 2}); + auto* cellAM = AttributeMatrix::Create(dataStructure, cellPath.getTargetName(), cellShape, geom->getId()); + REQUIRE(cellAM != nullptr); + geom->setCellData(*cellAM); + auto* featureAM = AttributeMatrix::Create(dataStructure, featurePath.getTargetName(), featureShape, geom->getId()); + REQUIRE(featureAM != nullptr); + auto idsStore = DataStoreUtilities::CreateDataStore(dataStructure, idsPath, cellShape, {1}); + auto countsStore = DataStoreUtilities::CreateDataStore(dataStructure, countsPath, featureShape, {1}); + REQUIRE(idsStore != nullptr); + REQUIRE(countsStore != nullptr); + REQUIRE(Int32Array::Create(dataStructure, idsPath.getTargetName(), idsStore, cellAM->getId()) != nullptr); + REQUIRE(Int32Array::Create(dataStructure, countsPath.getTargetName(), countsStore, featureAM->getId()) != nullptr); + const auto idsWrite = idsStore->copyFromBuffer(0, nonstd::span(labels.data(), labels.size())); + SIMPLNX_RESULT_REQUIRE_VALID(idsWrite); + const auto countsWrite = countsStore->copyFromBuffer(0, nonstd::span(counts.data(), counts.size())); + SIMPLNX_RESULT_REQUIRE_VALID(countsWrite); + + const auto* parent = replaceFeatureIds ? cellAM : featureAM; + const DataPath parentPath = replaceFeatureIds ? cellPath : featurePath; + const auto& values = replaceFeatureIds ? labels : counts; + const std::string malformedName = useStringArray ? "StringSelection" : "NeighborListSelection"; + const DataPath malformedPath = parentPath.createChildPath(malformedName); + REQUIRE(values.size() == parent->getNumberOfTuples()); + if(useStringArray) + { + std::vector strings; + strings.reserve(values.size()); + for(const int32 value : values) + { + strings.push_back(std::to_string(value)); + } + REQUIRE(StringArray::CreateWithValues(dataStructure, malformedName, parent->getShape(), std::move(strings), parent->getId()) != nullptr); + } + else + { + auto* lists = NeighborList::Create(dataStructure, malformedName, parent->getShape(), parent->getId()); + REQUIRE(lists != nullptr); + for(usize index = 0; index < values.size(); ++index) + { + lists->setList(static_cast(index), std::vector{values[index]}); + } + CHECK(lists->getComponentShape() == ShapeType{1}); + } + + ComputeSurfaceAreaToVolumeFilter filter; + Arguments args = filter.getDefaultArguments(); + args.insertOrAssign(ComputeSurfaceAreaToVolumeFilter::k_SelectedImageGeometryPath_Key, std::make_any(geomPath)); + args.insertOrAssign(ComputeSurfaceAreaToVolumeFilter::k_CellFeatureIdsArrayPath_Key, std::make_any(replaceFeatureIds ? malformedPath : idsPath)); + args.insertOrAssign(ComputeSurfaceAreaToVolumeFilter::k_NumCellsArrayPath_Key, std::make_any(replaceFeatureIds ? countsPath : malformedPath)); + args.insertOrAssign(ComputeSurfaceAreaToVolumeFilter::k_CalculateSphericity_Key, std::make_any(true)); + + IFilter::PreflightResult preflight; + REQUIRE_NOTHROW(preflight = filter.preflight(dataStructure, args)); + SIMPLNX_RESULT_REQUIRE_INVALID(preflight.outputActions); + REQUIRE(preflight.outputActions.errors().size() == 1); + const auto& error = preflight.outputActions.errors().front(); + CHECK(error.code == (replaceFeatureIds ? -12804 : -12801)); + CHECK(error.message.find(malformedPath.toString()) != std::string::npos); + if(replaceFeatureIds) + { + CHECK(error.message.find("scalar int32 DataArray") != std::string::npos); + } + CHECK(dataStructure.getData(ratioPath) == nullptr); + CHECK(dataStructure.getData(sphericityPath) == nullptr); + UnitTest::CheckArraysInheritTupleDims(dataStructure); +} + TEST_CASE("SimplnxCore::ComputeSurfaceAreaToVolumeFilter: analytical interior pair", "[SimplnxCore][ComputeSurfaceAreaToVolumeFilter]") { UnitTest::LoadPlugins(); From 15394280fe9b0131602dffa6dbc77ed1023f7364 Mon Sep 17 00:00:00 2001 From: Jessica Marquis Date: Thu, 15 Oct 2026 15:27:00 -0400 Subject: [PATCH 07/28] REV: Share cell tuple-count validation Use one count-only geometry check with caller-owned error codes and actionable paths. Cover image and rectilinear geometry counts without adding shape or ownership requirements. Signed-off-by: Jessica Marquis --- .../ComputeSurfaceAreaToVolumeFilter.cpp | 8 +-- src/simplnx/Utilities/DataArrayUtilities.cpp | 12 +++++ src/simplnx/Utilities/DataArrayUtilities.hpp | 15 ++++++ test/DataArrayTest.cpp | 49 +++++++++++++++++++ 4 files changed, 80 insertions(+), 4 deletions(-) diff --git a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/ComputeSurfaceAreaToVolumeFilter.cpp b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/ComputeSurfaceAreaToVolumeFilter.cpp index 1256fe2a44..6f9e34edee 100644 --- a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/ComputeSurfaceAreaToVolumeFilter.cpp +++ b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/ComputeSurfaceAreaToVolumeFilter.cpp @@ -10,6 +10,7 @@ #include "simplnx/Parameters/ArraySelectionParameter.hpp" #include "simplnx/Parameters/BoolParameter.hpp" #include "simplnx/Parameters/DataObjectNameParameter.hpp" +#include "simplnx/Utilities/DataArrayUtilities.hpp" #include "simplnx/Utilities/SIMPLConversion.hpp" @@ -104,11 +105,10 @@ IFilter::PreflightResult ComputeSurfaceAreaToVolumeFilter::preflightImpl(const D { return MakePreflightErrorResult(-12804, fmt::format("The selected Feature Ids object '{}' is not an int32 DataArray. Select a scalar int32 DataArray.", pFeatureIdsArrayPathValue.toString())); } - if(featureIds->getNumberOfTuples() != imageGeom.getNumberOfCells()) + auto tupleCountResult = ValidateCellTupleCount(imageGeom, pImageGeometryPathValue, featureIds->getNumberOfTuples(), pFeatureIdsArrayPathValue, -12803); + if(tupleCountResult.invalid()) { - return MakePreflightErrorResult( - -12803, fmt::format("The Feature Ids array '{}' has {} tuples, but the selected Image Geometry '{}' has {} cells. Select a Feature Ids array with one tuple per geometry cell.", - pFeatureIdsArrayPathValue.toString(), featureIds->getNumberOfTuples(), pImageGeometryPathValue.toString(), imageGeom.getNumberOfCells())); + return {ConvertResultTo(std::move(tupleCountResult), {})}; } PreflightResult preflightResult; diff --git a/src/simplnx/Utilities/DataArrayUtilities.cpp b/src/simplnx/Utilities/DataArrayUtilities.cpp index e78a403b85..f62b82eafb 100644 --- a/src/simplnx/Utilities/DataArrayUtilities.cpp +++ b/src/simplnx/Utilities/DataArrayUtilities.cpp @@ -3,6 +3,7 @@ #include "simplnx/Common/Types.hpp" #include "simplnx/Common/TypesUtility.hpp" #include "simplnx/Core/Application.hpp" +#include "simplnx/DataStructure/Geometry/IGridGeometry.hpp" #include "simplnx/Filter/Actions/CreateArrayAction.hpp" #include "simplnx/Filter/Actions/CreateNeighborListAction.hpp" #include "simplnx/Filter/Actions/CreateStringArrayAction.hpp" @@ -141,6 +142,17 @@ struct CreateDefaultValueNeighborListFunctor namespace nx::core { +Result<> ValidateCellTupleCount(const IGridGeometry& geometry, const DataPath& geometryPath, usize tupleCount, const DataPath& dataPath, int32 errorCode) +{ + const usize cellCount = geometry.getNumberOfCells(); + if(tupleCount != cellCount) + { + return MakeErrorResult(errorCode, fmt::format("The selected data '{}' has {} tuples, but the selected grid geometry '{}' has {} cells. Select data with one tuple per geometry cell.", + dataPath.toString(), tupleCount, geometryPath.toString(), cellCount)); + } + return {}; +} + bool IsChildOfAttributeMatrix(const DataStructure& dataStructure, const DataPath& arrayPath, const AttributeMatrix& attributeMatrix) { if(arrayPath.getLength() < 2) diff --git a/src/simplnx/Utilities/DataArrayUtilities.hpp b/src/simplnx/Utilities/DataArrayUtilities.hpp index 4ed4a436c3..5004bb1469 100644 --- a/src/simplnx/Utilities/DataArrayUtilities.hpp +++ b/src/simplnx/Utilities/DataArrayUtilities.hpp @@ -48,6 +48,21 @@ */ namespace nx::core { +class IGridGeometry; + +/** + * @brief Checks that data has one tuple per geometry cell. + * @param geometry Supplies the cell count. + * @param geometryPath Identifies the geometry in an error message. + * @param tupleCount Number of tuples in the selected data. + * @param dataPath Identifies the selected data in an error message. + * @param errorCode Error code to return if the counts differ. + * @return Empty valid result if the counts match; otherwise, an error with both paths and counts. + * + * This check compares counts only. It does not read array values or require matching tuple shapes or a common parent. + */ +SIMPLNX_EXPORT Result<> ValidateCellTupleCount(const IGridGeometry& geometry, const DataPath& geometryPath, usize tupleCount, const DataPath& dataPath, int32 errorCode); + /** * @brief Tests whether a path's parent identifies the specified Attribute Matrix. * @param dataStructure Resolves path identifiers. diff --git a/test/DataArrayTest.cpp b/test/DataArrayTest.cpp index 908ead1b8f..437fc3233a 100644 --- a/test/DataArrayTest.cpp +++ b/test/DataArrayTest.cpp @@ -11,6 +11,8 @@ #include "simplnx/DataStructure/EmptyDataStore.hpp" #include "simplnx/DataStructure/EmptyListStore.hpp" #include "simplnx/DataStructure/EmptyStringStore.hpp" +#include "simplnx/DataStructure/Geometry/ImageGeom.hpp" +#include "simplnx/DataStructure/Geometry/RectGridGeom.hpp" #include "simplnx/DataStructure/IO/Generic/DataIOCollection.hpp" #include "simplnx/DataStructure/IO/Generic/IDataIOManager.hpp" #include "simplnx/DataStructure/IO/Generic/IDataStoreFormatResolver.hpp" @@ -40,6 +42,53 @@ using namespace nx::core; +TEST_CASE("DataArrayUtilities::ValidateCellTupleCount", "[simplnx][DataArrayUtilities]") +{ + const bool useRectGrid = GENERATE(false, true); + const bool emptyGeometry = GENERATE(false, true); + const usize tupleCount = GENERATE(usize{0}, usize{1}, usize{59}, usize{60}, usize{61}); + const int32 errorCode = GENERATE(-1234, -5678); + const usize cellCount = emptyGeometry ? 0 : 60; + CAPTURE(useRectGrid, emptyGeometry, tupleCount, errorCode); + + DataStructure dataStructure; + auto* parent = DataGroup::Create(dataStructure, "Geometry Group"); + REQUIRE(parent != nullptr); + const DataPath geometryPath({"Geometry Group", "Selected Geometry"}); + const DataPath dataPath({"Other Geometry", "Cell Data", "Values"}); + IGridGeometry* geometry = nullptr; + if(useRectGrid) + { + geometry = RectGridGeom::Create(dataStructure, geometryPath.getTargetName(), parent->getId()); + } + else + { + geometry = ImageGeom::Create(dataStructure, geometryPath.getTargetName(), parent->getId()); + } + REQUIRE(geometry != nullptr); + geometry->setDimensions({emptyGeometry ? usize{0} : usize{4}, 3, 5}); + + auto result = ValidateCellTupleCount(*geometry, geometryPath, tupleCount, dataPath, errorCode); + if(tupleCount == cellCount) + { + REQUIRE(result.valid()); + } + else + { + REQUIRE(result.invalid()); + REQUIRE(result.errors().size() == 1); + const auto& error = result.errors().front(); + CHECK(error.code == errorCode); + CHECK(error.message.find(geometryPath.toString()) != std::string::npos); + CHECK(error.message.find(dataPath.toString()) != std::string::npos); + CHECK(error.message.find(fmt::format("{} tuples", tupleCount)) != std::string::npos); + CHECK(error.message.find(fmt::format("{} cells", cellCount)) != std::string::npos); + CHECK(error.message.find("Select data with one tuple per geometry cell.") != std::string::npos); + } + CHECK(result.warnings().empty()); + UnitTest::CheckArraysInheritTupleDims(dataStructure); +} + TEST_CASE("DataArrayUtilities::IsChildOfAttributeMatrix", "[simplnx][DataArrayUtilities]") { DataStructure dataStructure; From 29da66a0de2ac5e1a63fb68e332a986ff6224b8d Mon Sep 17 00:00:00 2001 From: Jessica Marquis Date: Thu, 15 Oct 2026 15:33:10 -0400 Subject: [PATCH 08/28] BUG: Clarify surface metric preflight errors Report the selected array kind and corrective action. Order the two new error codes and retain the existing codes. Signed-off-by: Jessica Marquis --- .../Filters/ComputeSurfaceAreaToVolumeFilter.cpp | 6 ++++-- .../SimplnxCore/test/ComputeSurfaceAreaToVolumeTest.cpp | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/ComputeSurfaceAreaToVolumeFilter.cpp b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/ComputeSurfaceAreaToVolumeFilter.cpp index 6f9e34edee..78fc26b3d7 100644 --- a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/ComputeSurfaceAreaToVolumeFilter.cpp +++ b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/ComputeSurfaceAreaToVolumeFilter.cpp @@ -103,9 +103,11 @@ IFilter::PreflightResult ComputeSurfaceAreaToVolumeFilter::preflightImpl(const D const auto* featureIds = dataStructure.getDataAs(pFeatureIdsArrayPathValue); if(featureIds == nullptr) { - return MakePreflightErrorResult(-12804, fmt::format("The selected Feature Ids object '{}' is not an int32 DataArray. Select a scalar int32 DataArray.", pFeatureIdsArrayPathValue.toString())); + const auto& selectedObject = dataStructure.getDataRefAs(pFeatureIdsArrayPathValue); + return MakePreflightErrorResult(-12803, fmt::format("The selected Feature Ids object '{}' has type '{}', but a scalar int32 DataArray is required. Select a scalar int32 DataArray.", + pFeatureIdsArrayPathValue.toString(), selectedObject.getTypeName())); } - auto tupleCountResult = ValidateCellTupleCount(imageGeom, pImageGeometryPathValue, featureIds->getNumberOfTuples(), pFeatureIdsArrayPathValue, -12803); + auto tupleCountResult = ValidateCellTupleCount(imageGeom, pImageGeometryPathValue, featureIds->getNumberOfTuples(), pFeatureIdsArrayPathValue, -12804); if(tupleCountResult.invalid()) { return {ConvertResultTo(std::move(tupleCountResult), {})}; diff --git a/src/Plugins/SimplnxCore/test/ComputeSurfaceAreaToVolumeTest.cpp b/src/Plugins/SimplnxCore/test/ComputeSurfaceAreaToVolumeTest.cpp index e00b97e5e2..f2d74c4785 100644 --- a/src/Plugins/SimplnxCore/test/ComputeSurfaceAreaToVolumeTest.cpp +++ b/src/Plugins/SimplnxCore/test/ComputeSurfaceAreaToVolumeTest.cpp @@ -149,7 +149,7 @@ TEST_CASE("SimplnxCore::ComputeSurfaceAreaToVolumeFilter: geometry and FeatureId SIMPLNX_RESULT_REQUIRE_INVALID(preflight.outputActions); REQUIRE(preflight.outputActions.errors().size() == 1); const auto& error = preflight.outputActions.errors().front(); - CHECK(error.code == -12803); + CHECK(error.code == -12804); CHECK(error.message.find(idsPath.toString()) != std::string::npos); CHECK(error.message.find(geomPath.toString()) != std::string::npos); CHECK(error.message.find(fmt::format("{} tuples", labelCount)) != std::string::npos); @@ -238,11 +238,13 @@ TEST_CASE("SimplnxCore::ComputeSurfaceAreaToVolumeFilter: rejects non-DataArray SIMPLNX_RESULT_REQUIRE_INVALID(preflight.outputActions); REQUIRE(preflight.outputActions.errors().size() == 1); const auto& error = preflight.outputActions.errors().front(); - CHECK(error.code == (replaceFeatureIds ? -12804 : -12801)); + CHECK(error.code == (replaceFeatureIds ? -12803 : -12801)); CHECK(error.message.find(malformedPath.toString()) != std::string::npos); if(replaceFeatureIds) { + CHECK(error.message.find(useStringArray ? "StringArray" : "NeighborList") != std::string::npos); CHECK(error.message.find("scalar int32 DataArray") != std::string::npos); + CHECK(error.message.find("Select a scalar int32 DataArray") != std::string::npos); } CHECK(dataStructure.getData(ratioPath) == nullptr); CHECK(dataStructure.getData(sphericityPath) == nullptr); From 14f3e786a8e01fecb2da1462d2c670e743596451 Mon Sep 17 00:00:00 2001 From: Jessica Marquis Date: Thu, 15 Oct 2026 15:35:53 -0400 Subject: [PATCH 09/28] REV: Clean up surface metric algorithm dependencies and reads Include standard-library dependencies explicitly. Reuse the current feature label and keep accumulation and loop syntax consistent. Signed-off-by: Jessica Marquis --- .../ComputeSurfaceAreaToVolumeDirect.cpp | 17 +++++++++-------- .../ComputeSurfaceAreaToVolumeScanline.cpp | 3 +++ 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeDirect.cpp b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeDirect.cpp index 02b20b2bf6..49498c8ea7 100644 --- a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeDirect.cpp +++ b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeDirect.cpp @@ -1,7 +1,9 @@ -#include - #include "ComputeSurfaceAreaToVolumeDirect.hpp" +#include +#include +#include + #include "ComputeSurfaceAreaToVolume.hpp" #include "simplnx/Common/Constants.hpp" @@ -119,26 +121,25 @@ Result<> ComputeSurfaceAreaToVolumeDirect::operator()() { if(neighborOffsetIndex == 0 || neighborOffsetIndex == 5) { - onSurface = onSurface + xyFaceArea; + onSurface += xyFaceArea; } if(neighborOffsetIndex == 1 || neighborOffsetIndex == 4) { - onSurface = onSurface + zxFaceArea; + onSurface += zxFaceArea; } if(neighborOffsetIndex == 2 || neighborOffsetIndex == 3) { - onSurface = onSurface + yzFaceArea; + onSurface += yzFaceArea; } } } - int32 featureId = featureIdsStoreRef[zStride + yStride + xIdx]; - featureSurfaceArea[featureId] = featureSurfaceArea[featureId] + onSurface; + featureSurfaceArea[currentFeatureId] += onSurface; } } } const float64 thirdRootPi = std::cbrt(nx::core::Constants::k_PiD); - for(usize i = 1; i < numFeatures; i++) + for(usize i = 1; i < static_cast(numFeatures); i++) { const float64 featureVolume = voxelVol * numCells[i]; surfaceAreaVolumeRatio[i] = static_cast(featureSurfaceArea[i] / featureVolume); diff --git a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeScanline.cpp b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeScanline.cpp index d1457ae369..7ca673ef44 100644 --- a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeScanline.cpp +++ b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeScanline.cpp @@ -1,5 +1,8 @@ #include "ComputeSurfaceAreaToVolumeScanline.hpp" +#include +#include + #include "ComputeSurfaceAreaToVolume.hpp" #include "simplnx/Common/Constants.hpp" From a855ee38d7cee3ce96c53932416b0e682b388ea3 Mon Sep 17 00:00:00 2001 From: Jessica Marquis Date: Thu, 15 Oct 2026 16:02:07 -0400 Subject: [PATCH 10/28] PERF: Release the ratio buffer before computing sphericity End the Scanline ratio buffer lifetime before the optional sphericity allocation. Preserve bulk-write errors and reduce live feature-buffer payload from 20 to 16 bytes per feature when sphericity is enabled. Signed-off-by: Jessica Marquis --- .../ComputeSurfaceAreaToVolumeScanline.cpp | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeScanline.cpp b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeScanline.cpp index 7ca673ef44..7df0e8fa21 100644 --- a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeScanline.cpp +++ b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeScanline.cpp @@ -175,18 +175,18 @@ Result<> ComputeSurfaceAreaToVolumeScanline::operator()() return ioResult; } - std::vector localSurfaceAreaVolumeRatio(numFeaturesUSize, 0.0f); - - const float64 thirdRootPi = std::cbrt(nx::core::Constants::k_PiD); - for(usize i = 1; i < numFeaturesUSize; i++) - { - const float64 featureVolume = voxelVol * localNumCells[i]; - localSurfaceAreaVolumeRatio[i] = static_cast(featureSurfaceArea[i] / featureVolume); - } - ioResult = surfaceAreaVolumeRatio.copyFromBuffer(0, nonstd::span(localSurfaceAreaVolumeRatio.data(), numFeaturesUSize)); - if(ioResult.invalid()) { - return ioResult; + std::vector localSurfaceAreaVolumeRatio(numFeaturesUSize, 0.0f); + for(usize i = 1; i < numFeaturesUSize; i++) + { + const float64 featureVolume = voxelVol * localNumCells[i]; + localSurfaceAreaVolumeRatio[i] = static_cast(featureSurfaceArea[i] / featureVolume); + } + ioResult = surfaceAreaVolumeRatio.copyFromBuffer(0, nonstd::span(localSurfaceAreaVolumeRatio.data(), numFeaturesUSize)); + if(ioResult.invalid()) + { + return ioResult; + } } if(m_InputValues->CalculateSphericity) @@ -194,6 +194,7 @@ Result<> ComputeSurfaceAreaToVolumeScanline::operator()() m_MessageHandler.sendMessage(IFilter::Message::Type::Info, fmt::format("Computing Sphericity")); auto& sphericity = m_DataStructure.getDataAs(m_InputValues->SphericityArrayName)->getDataStoreRef(); + const float64 thirdRootPi = std::cbrt(nx::core::Constants::k_PiD); // Sphericity is one for a sphere and decreases as the surface becomes less compact. std::vector localSphericity(numFeaturesUSize, 0.0f); for(usize i = 1; i < numFeaturesUSize; i++) From d7d7f12b424a42f21d7a0f154090aa06ca4b9f7c Mon Sep 17 00:00:00 2001 From: Jessica Marquis Date: Thu, 15 Oct 2026 16:02:07 -0400 Subject: [PATCH 11/28] DOC: Explain voxel surface metrics with verified Small IN100 figures Clarify voxelized sphericity and the X/Y spacing conditions. Add a six-face schematic and a computed before-and-after comparison using an explicitly labeled anisotropic copy of Small IN100. Signed-off-by: Jessica Marquis --- .../docs/ComputeSurfaceAreaToVolumeFilter.md | 14 ++++- ...faceAreaToVolume_SmallIN100_Sphericity.png | Bin 0 -> 207763 bytes ...faceAreaToVolume_SmallIN100_Sphericity.svg | 34 +++++++++++ ...puteSurfaceAreaToVolume_VoxelFaceAreas.png | Bin 0 -> 160195 bytes ...puteSurfaceAreaToVolume_VoxelFaceAreas.svg | 53 ++++++++++++++++++ 5 files changed, 99 insertions(+), 2 deletions(-) create mode 100644 src/Plugins/SimplnxCore/docs/Images/ComputeSurfaceAreaToVolume_SmallIN100_Sphericity.png create mode 100644 src/Plugins/SimplnxCore/docs/Images/ComputeSurfaceAreaToVolume_SmallIN100_Sphericity.svg create mode 100644 src/Plugins/SimplnxCore/docs/Images/ComputeSurfaceAreaToVolume_VoxelFaceAreas.png create mode 100644 src/Plugins/SimplnxCore/docs/Images/ComputeSurfaceAreaToVolume_VoxelFaceAreas.svg diff --git a/src/Plugins/SimplnxCore/docs/ComputeSurfaceAreaToVolumeFilter.md b/src/Plugins/SimplnxCore/docs/ComputeSurfaceAreaToVolumeFilter.md index 367c82fa9e..4205e1fa38 100644 --- a/src/Plugins/SimplnxCore/docs/ComputeSurfaceAreaToVolumeFilter.md +++ b/src/Plugins/SimplnxCore/docs/ComputeSurfaceAreaToVolumeFilter.md @@ -31,9 +31,11 @@ For cell spacing `(dx, dy, dz)`, the area of a face uses the two spacing compone - Y-normal face: `dx * dz`. - Z-normal face: `dx * dy`. +![Fig. 1: Generated schematic showing all six voxel faces and the two spacing components used for each face area.](Images/ComputeSurfaceAreaToVolume_VoxelFaceAreas.png) + The filter calculates each feature's volume as `V = Number of Cells * dx * dy * dz`. It uses the supplied cell count without recounting the labels or checking that the count matches them. The surface-area-to-volume ratio is `S / V`, where `S` is the accumulated face area. Area has units of length squared, and volume has units of length cubed. -When *Calculate Sphericity* is enabled, the filter also calculates `Psi = pi^(1/3) * (6 * V)^(2/3) / S`. Psi is dimensionless. For a complete closed surface and consistent positive volume, a sphere has sphericity 1. Both output arrays use 32-bit floating-point values; face areas, accumulated areas, and metric calculations use 64-bit floating-point values. +When *Calculate Sphericity* is enabled, the filter also calculates `Psi = pi^(1/3) * (6 * V)^(2/3) / S`. Psi is dimensionless. A mathematical sphere with a complete closed surface and consistent positive volume has sphericity 1. For a voxelized sphere with a complete counted surface and consistent positive volume, the stair-stepped surface has more area than an equal-volume smooth sphere, so its sphericity is below 1. Both output arrays use 32-bit floating-point values; face areas, accumulated areas, and metric calculations use 64-bit floating-point values. ### Algorithm selection @@ -49,7 +51,15 @@ Scanline reads labels in sequential slices and keeps three adjacent XY slices in ### Compatibility with earlier results -Corrected X/Y face weights can change results when X and Y spacings differ. That weight correction alone leaves isotropic face products unchanged. The improved numerical precision and sphericity calculation can also change isotropic results. +Corrected X/Y face weights can change results when `dx` differs from `dy`. The face-weight correction does not change the measured area when `dx = dy`, including when `dz` differs. Changes to numerical precision and the sphericity exponents can still change results, including isotropic results. + +### Small IN100 comparison + +The generated views below use segmented Small IN100 feature labels in a separate demonstration copy. The original spacing is `(0.25, 0.25, 0.25)` micrometers. The demonstration changes the spacing to `(0.25, 0.50, 0.25)` micrometers so that X-normal and Y-normal faces have different areas. The original dataset is unchanged, and the labels are reused without resampling. Both calculations use identical labels, cell counts derived from those labels, and demonstration spacing. + +The earlier Direct implementation and the current filter each calculate sphericity over the complete three-dimensional volume. The views display those three-dimensional feature values on the same central XY slice, at zero-based Z index 58. Both views use the same color scale and physical aspect ratio. The comparison includes corrections to numerical precision and sphericity exponents as well as the X/Y face weights. Features cut by the image boundary can have incomplete counted surfaces, as described below. + +![Fig. 2: Generated before-and-after views of full-volume Small IN100 feature sphericity on a central XY slice. Spacing was altered from 0.25/0.25/0.25 to 0.25/0.50/0.25 micrometers for demonstration; both panels share one color scale and physical aspect ratio.](Images/ComputeSurfaceAreaToVolume_SmallIN100_Sphericity.png) ### WARNING - Aliasing diff --git a/src/Plugins/SimplnxCore/docs/Images/ComputeSurfaceAreaToVolume_SmallIN100_Sphericity.png b/src/Plugins/SimplnxCore/docs/Images/ComputeSurfaceAreaToVolume_SmallIN100_Sphericity.png new file mode 100644 index 0000000000000000000000000000000000000000..112a18a47a1d64cb34484247318a5f2ad4d95b01 GIT binary patch literal 207763 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

q?MB+^`6eYGl(^OtVQTZ*f6Vq&qv1Z2@Gh& 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≷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

QS$-EdW=&Bmj4r)tAsusEnbm*WB8 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 + + + + +Small IN100 demonstration: Sphericity +Generated views • full 3D calculation; central XY slice shows each feature’s 3D metric + +Altered spacing for demonstration: dx = 0.25, dy = 0.50, dz = 0.25 µm. +Original spacing: 0.25, 0.25, 0.25 µm. Original file and labels are unchanged. +Before +Historical Direct • 5aaa879debf9 + + +X extent 47.25 µm; Y extent 100.50 µm +After +Current filter • corrected face weights + + +X extent 47.25 µm; Y extent 100.50 µm +Shared scale +dimensionless + +0 +0.8982 + +Background +No scale clipping +Y increases upward +Z index 58 of 0–116 +Whole volume: 2,317 populated positive features; mean |change| 0.028309; max |change| 0.19037 dimensionless. +Both views use identical labels, counts, spacing, physical aspect and full-range color limits. +Comparison includes precision/exponent changes. Out-of-image faces are excluded; edge features may have incomplete surfaces. + \ No newline at end of file diff --git a/src/Plugins/SimplnxCore/docs/Images/ComputeSurfaceAreaToVolume_VoxelFaceAreas.png b/src/Plugins/SimplnxCore/docs/Images/ComputeSurfaceAreaToVolume_VoxelFaceAreas.png new file mode 100644 index 0000000000000000000000000000000000000000..b2d3848b4d2a9d6eafa4ebee583ee9f814959e81 GIT binary patch literal 160195 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 literal 0 HcmV?d00001 diff --git a/src/Plugins/SimplnxCore/docs/Images/ComputeSurfaceAreaToVolume_VoxelFaceAreas.svg b/src/Plugins/SimplnxCore/docs/Images/ComputeSurfaceAreaToVolume_VoxelFaceAreas.svg new file mode 100644 index 0000000000..f318cf6fd3 --- /dev/null +++ b/src/Plugins/SimplnxCore/docs/Images/ComputeSurfaceAreaToVolume_VoxelFaceAreas.svg @@ -0,0 +1,53 @@ + + + + + +Voxel face areas: the face normal determines the two side lengths +Generated schematic • opposite views expose all six faces • lengths are illustrative +View toward the +X, +Y and +Z faces +Opposite view: −X, −Y and −Z faces + ++X + ++Y + ++Z +dx +dy +dz + +−X + +−Y + +−Z +dx +dy +dz + +Face normal +Face area +Demonstration spacing (µm) +Area (µm²) + + +−X and +X +dy × dz +0.50 × 0.25 +0.125 + + +−Y and +Y +dx × dz +0.25 × 0.25 +0.0625 + + +−Z and +Z +dx × dy +0.25 × 0.50 +0.125 +Count a face when its in-bounds neighbor has a different Feature Id. Out-of-image faces are excluded. +Anisotropic Small IN100 demonstration: dx = 0.25, dy = 0.50, dz = 0.25 µm. Original data spacing remains unchanged. + \ No newline at end of file From 891e236a23c5c845024a830d6d917872ce4b1fd7 Mon Sep 17 00:00:00 2001 From: Jessica Marquis Date: Thu, 15 Oct 2026 16:34:23 -0400 Subject: [PATCH 12/28] DOC: Use Viridis and enlarge the surface metric comparison Preserve the physical slice aspect while increasing panel width and moving the shared legend below the views. Use the catalog Viridis colors with a common zero-to-one sphericity scale. Signed-off-by: Jessica Marquis --- .../docs/ComputeSurfaceAreaToVolumeFilter.md | 4 +- ...faceAreaToVolume_SmallIN100_Sphericity.png | Bin 207763 -> 235708 bytes ...faceAreaToVolume_SmallIN100_Sphericity.svg | 60 ++++++++++-------- 3 files changed, 34 insertions(+), 30 deletions(-) diff --git a/src/Plugins/SimplnxCore/docs/ComputeSurfaceAreaToVolumeFilter.md b/src/Plugins/SimplnxCore/docs/ComputeSurfaceAreaToVolumeFilter.md index 4205e1fa38..7500ce6171 100644 --- a/src/Plugins/SimplnxCore/docs/ComputeSurfaceAreaToVolumeFilter.md +++ b/src/Plugins/SimplnxCore/docs/ComputeSurfaceAreaToVolumeFilter.md @@ -57,9 +57,9 @@ Corrected X/Y face weights can change results when `dx` differs from `dy`. The f The generated views below use segmented Small IN100 feature labels in a separate demonstration copy. The original spacing is `(0.25, 0.25, 0.25)` micrometers. The demonstration changes the spacing to `(0.25, 0.50, 0.25)` micrometers so that X-normal and Y-normal faces have different areas. The original dataset is unchanged, and the labels are reused without resampling. Both calculations use identical labels, cell counts derived from those labels, and demonstration spacing. -The earlier Direct implementation and the current filter each calculate sphericity over the complete three-dimensional volume. The views display those three-dimensional feature values on the same central XY slice, at zero-based Z index 58. Both views use the same color scale and physical aspect ratio. The comparison includes corrections to numerical precision and sphericity exponents as well as the X/Y face weights. Features cut by the image boundary can have incomplete counted surfaces, as described below. +The earlier Direct implementation and the current filter each calculate sphericity over the complete three-dimensional volume. The views display those three-dimensional feature values on the same central XY slice, at zero-based Z index 58. Both views use the same dimensionless 0–1 Viridis color scale and physical aspect ratio. The comparison includes corrections to numerical precision and sphericity exponents as well as the X/Y face weights. Features cut by the image boundary can have incomplete counted surfaces, as described below. -![Fig. 2: Generated before-and-after views of full-volume Small IN100 feature sphericity on a central XY slice. Spacing was altered from 0.25/0.25/0.25 to 0.25/0.50/0.25 micrometers for demonstration; both panels share one color scale and physical aspect ratio.](Images/ComputeSurfaceAreaToVolume_SmallIN100_Sphericity.png) +![Fig. 2: Generated before-and-after views of full-volume Small IN100 feature sphericity on a central XY slice. Spacing was altered from 0.25/0.25/0.25 to 0.25/0.50/0.25 micrometers for demonstration; both panels share the 0–1 Viridis color scale and physical aspect ratio.](Images/ComputeSurfaceAreaToVolume_SmallIN100_Sphericity.png) ### WARNING - Aliasing diff --git a/src/Plugins/SimplnxCore/docs/Images/ComputeSurfaceAreaToVolume_SmallIN100_Sphericity.png b/src/Plugins/SimplnxCore/docs/Images/ComputeSurfaceAreaToVolume_SmallIN100_Sphericity.png index 112a18a47a1d64cb34484247318a5f2ad4d95b01..6ac15e3d402a8bf03a393f4686d6fddd84ef6585 100644 GIT binary patch literal 235708 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

%a)7?Ht#YlV4Q zAn?FoMTf_^V_JG#2}jMtpT4BL`dn_gnHJyqAh_aAT{L|Lo+kBfUWiLX(%0AbyJOqy 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

``C7CM&O@wY}aeu{T(!WF+a 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

X+t<{p5EZd!9>$a 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

BY_kuU)#Grj=UPI3nu2tvgWy0x> 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
T&wgCE|K%<;K9DC5;uu0 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 literal 207763 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

q?MB+^`6eYGl(^OtVQTZ*f6Vq&qv1Z2@Gh& zcV^Sz7gN3GM142da1oZ7jbY#EhzQo>L<7(YRYA1CI#KYbPu zP{n1gKG?}4F-n>RN@(F@uehd<8;`jZVuRI{%0+C_QMObc6YlVgt)_a+*RRD5Xn@~F z0l5;L@5~NDk5`!0*y5zw#iyz;FlJ?Eef|MD5Vrx9<-ld5X+u~h&5LAqLllr%__g`j zsPB7swKh+Rg?`i)N*G}W+Twz=ZH&76?m`tRHdAU`kC2I>KXBNQ4?R`xaSuMnX=s6S z8l_yZ@AvHVWeFoH8`HgfAXD{qp?hE7S)e#-+ty^XkW_+-hYB+cA(eH01fjq)CZ@L`;-Mrzt>2t_`(zxlR{aYAf_+Oy{#lD>Ps^E#?ueVprO(>tx zjMf{pnGjzWl~!rQmPCDu!W)SfP8qdWlRX&V%e@k6nB!Exl9qucHu``8(k-3R8lvs* zzaj!gE#wv8Duy~ePCoc@Z``W|mQ&t`xo0}JNr}k!uR!LphF`i8+K40XnQ3)XzNev{ z+9?&ZJoS}MD_zzgHUaF}t6W5Z!7otUS|I6NlaxP*5@=qlo~Im4#hCO|U5REX+aT!B zdtP4o5)cjRD5xm);DmxZE;$A@NYFP`3!oQi*FRsCqkx2Hw_`a`?NUprZVc>vO%4Ro zS+s}9bu0l0p#1T`MW1a@5107(q_)$c<L zzKX#1+gF@0hCNls6X@&Fxw;lX8>pYebBq#551<{nhbI{lA{u=-9B^`Rgq*-E9z|wXJV- zcjt>N+=HPeI-aZHbJ^;l9kva7>b}M%#2uLm<*;R;y#k;fDcbF`8DO#ZxuhIs&%o|2 zT@BGkURb^qU?A7*G8gu8YI8=6w)gvcA%DOIIedr49%@@M@{uK1=GC%VZk%W?E6hkq z9-7&STN=SlIB0Oy!?nZJ+o~=CyF-P22{Mmn{9}#m=q1IXL%{Hx%OHgaGhFDwqPR*g zn=MA)j(_M~o}tJn3Noo;to@MV zQ_lZi#&}weu2MSEzD$>SSeOIpHjS9d zK46kXob;L4wZyh2YK$6Mu2}DdFMjqQJ%4E>khK|hciv7n{B@Y#wj?BUXhn?XK~P7r zkOLU7;L7D8G;->}+LR68-BC5Ii$?0gF;ZVi?b{lz5>+Cbm92Ld*BKHdmXA{g~c zqmPp1BS|Ti-J!N0$I?&6iH6$7@0>Ztjk?1FyaJinG{uO9#s~Sg7})Cq<_DGfIBY(I z#pVr)JW6$6)Rk3o?(>v_$5?4@W?cWAKAZ4pR4gG!&x z{g0DQ8UjXu0axt8G`;M`2glA+wy-+?*$y#L+xVSr{Vz{;8LFa)Quw*&Y%Al(K6S|M zW<;6W&3}++4N!7Q;fZdpkPwAC4(o8hS0En_bh~^OC)R>{#Z``^3Pp#=z&Rtf6XyBH zs1Bp2Z`n{Kt1=-!mX8pIXWvpK`X;*1_uGWjG-s|{EDc!nRHm(?d;hcnz-)Ez_7r)s zW{YZA;HO5cF;m;pekxF^a@lWj|CK*R@*m5C4|G@v4UB+LtzI;Vq~mHBX$m*o+t9)e z%3r6ajV3F~bHjwbn8)&}6ug2B(w$^Up(Fur9FeOZz+Fk6UsKbqa{YOfq5T_Px%8J#~bxe|&yuAW`fgpX7RsMR~v(9}VHy_{ox5uEWL2Mq{$3!p~Zo z*{8nAF&q7~4rPRu%hNkF;Nh&sRb^%j$h_BFcoYNA!%c^;Jj%YiT)7C_8n9jtb{;4- zC-9D@7*ZEVjIzJmH(@(}vz#HLGD^o?Xt=H;rdllQObt@CS8?uR;y*uoA*IQCCVB%Y z%I+ZRx}9*noccCNiKAAke0NsjZH+$m{0h3@$oE?5XmX-iQQ|tvACH{R6Ygjcyy%E} zyu`urr3&!HMfo!>1H0^AT5}iycYP%;dh)#m+K4ySKNFS$eqM{dZehRB&_;EGAM0p1 zE#dX{J@v3ihe%r7yhBUO8bV{{Nylc7j{dj_o9?%bk@%tUd_ikJjF~E$t0N{wCETpyP`DSCIbvmlpvLl#dQ8_V`ViKhQ2W z{s2pd{qv|tdtZU7l9Joy(d=N9?(MgC(N|2*WpoU0E~@u_QS6|Q^)&_G`>j}9A^eN! zlNON{5k){w_3U<1zZoUI=gj5i@|&Hjm(^zG2f3i@pv?Q~14+7Q=Y!8*)fz{44@3Jo zsksZ37)>ESrg7>e_Zzog*7+AeAbrIlyqNNBx%~5`<&As_{ezYoqQ05r?x3y-#vhwE z)s!s{5dT1#L(3T1#k7#L0t90tnyWe4O)nFi71~`Cpqi_aPu~}8p5-P_kkGMP$5xa4 z=VG`&-9L-r{2V+SW#8T6UM{EjEqcfv7xf8jwXRQWh!$DTYyc!AAyc5n{S&YH&qvRt zBLvPYvU}knXTaXHpM@g@{nE7dyn-w!#X2{Ku9J@%4^lbtrg5z;rejg!NzeX`RVkwg0?7|6D}) z>%Vfqz$>G_L-+rkUPH(7R~|7(`0985?ca&YoxiOA*XRF>9{um@{2%}GmgHZC%i!Qj z?(eMIzcV5pNc~F&07Ar--(Xk&zP4AP-@E=7as3_4{qL+fa>~De?@fZ=X~O?l*yWGb zFCY8`r%+z`P2TqJYr8`DIsE@Wy8n54|M#O?{26W|siiErBu$5_kkHEcMDq`#ap$*Z zxrdppGNoA(2fAj+hc&pTb2orqo(aAb-tgr9p-q=3c!NyJ{J(%fxb$Yz)Ko=FE32VCZy%# z))mc?cKqbYTBJIsGBz4%;)H?+LCp4hX}gtgg|yf0?-?5+MO>}+S5i5Y|B*5xybFFl zJM1nETr@U5o^NnK_1n0*ZyZ&c*13&uJN#5PTR3PKl=*WiCOGXl>t2R-i$~&gjElq+ z&St6gM~RIIzQo2Tw<>EZ=*4D%Lr++^KyJ&*SAMr3p3Zb!)?whVElX8;19E6ty7^G! ztgY=Iv~OQ=l7?1(W>or4>%vaih53V%qaG+~3=3wiiZUYXJGFKzzL6O%HnM;{ddgY_ z#DsOuV|kV4+QSFIOzl2B`D;*K*pt8%=B;@dULC33a{Ypi)0gr_Re_2b4<~V|nuD}w zh?CQ5GR|(~%bgaJZ5-f5nj}IFK07nWR9TnH9PS&zl7=1jrf%WhG<^lG)vS8Y19Y6is8pG!u z=br;U^1(HmoKBl;uqhS__Di@ z>*_q%csW%!UvIXzl#dZtjO7eNOmm#sncT677!(ZFwe8Hpb1*Bpmp zzR%j;)xCJz9XBKn(7iQQd8&?o#NWhi@zXWuIpYNiG#cla9m2n4uPQIjP8sXUx@Sz> zf&=uacJbqFu+P2DRei=008%5T3b)?Qt=}djr^@mQlMk!zHYfZK4#)ufmm_#>MNqWk zmrc1Djj*#50Vs!KyGD)8$=ldd4}<;98Q51WZ@q78hmR+UWDGzBT3!A2=%_280VD6n z^&i;)8_GOCx}ia(NVpyjhqE+J>{Jf2KevqPd+?0oE2s>D5f4|vTRpcKe^==387$brSOoxdTfy8!$qJS5`fWa4VAM(W> z>hj|DT-1Lq;FwcYSG2K;jIhmUv5s2V^usSLvoG>xt{>oMnYYhU&ux5vy_^z>^-`~-(n|SXnTwTKYH71I`e=UDgUR8gjTzuGr`y6@3pCxRu_h?SZ!KHa)iFdJm zn*z8a4xpyupgz;Y!uK7952G#V*nx_Tv>zbb1jLcUCS7b@FKrN^|IT>-Z!o{83l%63 zfRFi#ll!HZXg+FKUUoK8O8zSBOG8V;rrba1-EWojuULi}!wrorey#+PX7c1#dVKT^ zLUiI@TM0xOo`K&nx>I0r*;bGf`q!Lj@NsHMPTvX#>%Ccdi|->&zH(Ls16zB6 zrooo-zy%-W{*=WPZ&`*Z!oQ30w*VqJ**Kbv2MOV zbk9$uYHrUgOV?jS;hDjae?S?uSfy?;5+^xzOdU{vxxxIQzH!@lrJ=}$;XH6J$JnSh zXuR}}?RnxxI5va(2|d#z=^h@<6^%cQw8##UmjVG4{w$!)z-67Wy6PMnbhw-AFF5xU z@dL1zw%Ie^7cS{6DL23-eg9_*EeCoK{-8D+UA z{0r73@a`kXkxL$Af(KHxm+E+r_t&hJzO}>5kI!S5a0Ng#<|?kaIZvBxG8%FSB%-0~ zmjna0$@9aQ)>np0a!CNlHpv4W-%ZmBVq!M;%MaG@3e?lTDBdcl;VBV3fImvvI2=z$ zlzWmZ9?0V>5o3M_e3I$(5sf3f&RuxvW5O^Sgt)jcU5Q);u#L=I-M$VNE^pdc>z-aT z)rcF7tgVTgiY9k{9A|LM(QS^@Qr|Sr!09Xoef$QcC@noTSSmopG#_RP^RD?lWntT= z7pgp@$#thmbDxTFkv16lzu0@vs3y0zT@*w>1w^qRAVoz$5s=WOL_`IZ=0ZR^N|)Yi z5(EX2E=_7E0xG>rjfm1AV1Ur0QbG?9Af)eywU+O<_xG-MjPLw8W1KT~erN~}dCHu3 znfHBN*Zl6i^{$BU6=KAa_}vWGxb!(=&aI6-_TjD$GJ_N_GM(Z-*oy)fAMLxbAdM`w zx9(YGJP2_~+&1m`nsh~@2D&)m%KK4*OU^8SZSD$@-N8o1&$O(RGb%Ndt(KOjU0uy@ zlyub?X%W7B{R7yi4A~dAN}r9lKs0+duRPx9R|PQTUN*N8 zCC=|GQPaQf@0%w=D0wcjq}d{;WxJ0)9Dn%n@fXYq+kxxAlVfa{jO8t}m?}J))**ol zf5fGUIKYdc(r1D@Ef95_8Q{r*gm>D~WFvv-`a#tnAnr3)Vhb=T)kIq#Aj_~8%&LNB zpypzpmu<+gMyA>;H>;v3#d#S)m+fMcb2j<}k zqvu%t&*~6GLRFn-)GJ#)Z`5>usSxP$C-1rS0>$ySN9LE#j~ItYIjc07>5dU_-+Lq( ziq;tY)XF}bRyPXOu)9jZ=lwvD?gi%qVSfa*Ne{Vq{T%(5Z;co8>}f@hF2$!IMIWBd zpV_7ASLP>q283Xj@$KI3^f;U%KRlC`#b!?p)OmmpPiY%^ytYG-RjZXS_7h%c1@@Vb zfAaH#l-@m{tN*ephdrzob^6Foc=DL-i4`M+sX_W_SMP6ccR-irIRyX?ldq(q&;Z=3 zlVt~2*MCu@PHzP>8La@SdoYLic;vzpceQ%6&v&>cKg>L@_f*H#;Sq zfc5^8BW0xPU~jdXFuQ1w)3Snn;-Ai4QnJ@rcwV|p^8lPue%BjUjQTwM4?;tI4FGV?Rlh}O zYdS8B+ufl8;9Q@djLW~V0LN#=S95gc#u0D>11Eu*u6@kI2*Fk`Hc@UcM4C2uc?-iP zA2A~3)K!SnZgdDdmBg#uWVwnvp`bZ%j86isGd&}VetmfcUz|?ysSv5B1Y2h_9Yp-6 zc)5SfT%Wgh{I)ViYD?E@`+4TmuS4{np9#MHp24(RNE%4MHrfm8%UDyd-W%!_x{!1e zWGzP+u9Fl~K0x7r&U2mU_?ZtBlL_m}XPd2G)t9gi1ZlZ*+MW^GBWTu*?dF6%3vw)F z?LHPXuA$%XaiT9~I8Oam3B!7Ob(jU4rkf9NN~PV;W1RA)*PYg1%#_Ectlv~uUdQY! zb9Z&Ui=3djFDq|6C!>p-Beyo*3RrPFa6Po{wK7>6TnE~4xU1d8k=;P=?z9e_dY^k- zEA@UifOMog2iJ3=eB#K5_?ymmMc0-N7SRiNhlU1vyF6H3Pwv2Z}o5M1WU9Y<# zcr4k3;liqSg*mtjqRTm{%oFK6JGoq6(0@&bT)lU@umAXrBfymKH;SK1C-K;5wtv=z zJ_wmmM6a0BA+d%EoiavZ{*$LeeA}_^$X?1cDh zo%LQicdK^(<$xRAg_e?d@414jhIeCU{vnIApGF@W1jgvbwJ);OU3`wR6?zo$DM9_| zz*O^e+bTu;Q(<5OAp1gS3Dm@w--kMG1Q9;$ZhVr1$2Pk@nPNFQkaw)b2{Vd0rkKH_ zP3Auqw$hYWt#~7X`I5q?KtsAKb?mgYdxwzpVy9BMYT!NUbUeVIq-0oR9>5iktS)Y} zIe!R1DORaHvN|ny@6{b`7l@lfTX00>zCkf;M)nmR`d73w$n*H zBb|xO#|akAcEZ}0Nr2C+bdlkWC|0@g>APBs-&}TXSS@ zn4&yavzonO1KJ9MyP5UzzbsiQRR9<>GUn32g-O9|QHz4nc&EF$rCj%JV4E-_t@)NU zTkl+p2H1WXwtL2k$8x8)0Q;ollpI(*sUbbK{_zD+zxI8pF{ZhdhUfBHj=ICGNpTOc zx@4QRLc5hA)l$e^>U`%{@62gxYJWqM)h-9uWclN)Pg-d zJUUAg{S}QgMkp6A=M1uQ-LM~seyYtAzT(o#N4M<0{h_fhCXm;Rx8w#rLqk^dwJ%TK zci<=yg?O0fEtR)1c8j4b%T5;cpr;{X^r_Y6LosXo>#*A;)3Fchv& zUHkxvRliWiRXh3&`dO>1fE7V|t>oHqsO3I(_JjHtfgSPi7l;fC!~!mj=gf}25obOX z_laE)!g!%8M zIAwI>*?ms9`3J{#Y336~t&OeDR}g2!{N|Kw&Q#sEoL^2e8aO2FWFmc9`<_5WXE{lW zajukI^v-1P+;^QTJ@!};CFB{``+RQV_2DIDqGQ+40(bm7d1WMhjQ1M|+e&v*xMsVVD$?n;64Q86Q9^S;sr9HD_%OXr$Y{A8veT z5;h;q8``cchN$4jQ&U01Y0gm$` zIGvHQ&GZXt)GzMA2hw^aW1;M$bFWQm&#tJJx`S&?mhRlpG6m`TZ) z=Q91RZ}y;>QF}HDE3f2jvLfew+j~(^M$3`Xck^VXdN2~n*pxHnJE&mqbiVI)K`Od- zlmprVeM2M0cXL!t}>0T6s9f1=C_+%gc@T6@z`5O%nn^ zeLvpp@dSsKri29&I>MeoJ&>U5j)rzQ>$M=Qcg*BBMNDNr?5bINRt-gwt47B@D`=f| z1s$F5Nw#i3>+pxuoPRRpYna}Rw7fTBpzx(9h_Z2`N}=>w6Y z5e42h;XUae+0Xe+L+wuiw4st)OU$W+_b%l}^)xGt&Agg|7OeYsi4gUE$=^(yvP@gPLpT94+K)Kt-0PBLpHNAA z^HXBS!me@?Yr|iWt}()yhf~rx%@PIWN6Y^2$|?V??!LHhPn5}!kQap0(mtB)4 zSO8cxYnl^dt1O@{{qr;D%{u3VAtqYwy6Fv!tU)B^wDrS`<%FZTfJGaHn8M$whH&r* zQ?xnrwuMX?;SPf49LoSk12f#)YI_1KkuVtr;Dh!$Q?j8GY4aUU>*0mhq302z$A)O+iX9fjIoLt%=?B8cK#H5p+hSN)%~KV~jfR+_c_p_u#=n1Qyj zg(G8AX=A49!++0;iP-Kur;=`}7O#G5BEj5x_j^yeiJ6P8 zBjC-vIPzR4<@&7(;bT7QGtIvoRnQ{FVVq|H{M!qS%MPVid|TBDkbYkh2h%|3m#1Ie zCp^BX;u=%ZlH8nXiEh^dSL{Y;a2?aYaL<@Uw~ zLe&6u<(ZXP!riGf6XBBNP#)pxu&;a87VQlQ?HVN~cPoucmMJ#(SsMKsPM&tROV~7) zi)_nW1E-CFH5U)Do$!5@P??)5cmkg(&G#`edsLRCe>%7H(0XdmP~-6Z`>vuAd>XU% zC3Q821jnR$KC9;xeU2N9T1AyO)VjLqd!P?lL51oaYlPAeS5?ZaZhe>rW?7NsrfR-> zq31DNSq4w`>9uX+HbR5?Q=pI!Vsdg)ziWJ4RFfqY2(PGPF5K&2wzkIVJB;DC#k%2k z3D;4YC2y{!MzjH@Aoz(uHsDdE5R&Ds(AMc4wk)0tI$RT)BX4-pS)$dy?2nu;5ej;r z-Y6!nDEO@R^ktdUL+>T$bTQ|h2Bg}bpe?~OZE`Z1vgS;|$ZzdKwu^@mA7mc`a8A%? zm#lhZ%K7g~RW~c;>&PU(7fjBy(8k%z7;GPuE zMUBf(x8-LLkCt))fJFOIM}4o@Mhy8HqB+ySu9h{6$S8Tu=($=93Uic}WfPH5>+*E0)Yj^| z&=Xie_q%jIsB6wC_+IOl|5)R_RJ&tx)b(&cVzEm5ALCiB`R~Ra`;r9Pt<*rF5tlQm zhopOASobzP0bn{CpRkKuYgnZT!j%&ZkU=P{yLl-e0X|OqQ8V9Xan9*ZnZh*#yLD=IyQdaNH(;PX@cFkckpu*D3am$Ga z{a!CPIe!3j*|t#4ICjhE%0i~%^f;eG=1EL;IdA=%z`E_3Bd%TWNJ^2=J#m>gf|WUB zM^&xz&(20dYR0Ro#+*UoL-;`&qny?|>B2W4Xi>U;5FX$%oHa*+IBQKuH&|=0z0I@} z0|wY-w0dzKxT34e05r(y`BOFz07qm;t>U_Vc4V~99N)mK!&;*LWl%4tDAX~BYETs8 z306i}q+dBRl8Xd5Ztvtc@$%@rK0vZ5;56{O}*fUw}4nO2! zuDcd~yW9Fy)1FA*aVK`Hs@}?+3c=#nbhZYUOj+(s>31p5r|zdD0x6K<-w=%d)}g(w z_`CHC%56B)WO|h6qf*wGOG-99bex?l=(@>>&=cS1XI>1D)&uHX!Ft>AQ z+X8tm%m57kE25eB&Wyw5?g?gJ+iQTPLA8;kss3$7^H~rUyBAaYkxITh*L0OYe`yn9Bp8mwp6<;r~Ld-`LWL*3RBp( z(01pBQR=Nz#TSgjlge z0)`?h_!w+&7YwSgP+;dG=_s@8*0=+9tOq2Ib{#z=9iH>k^{3`04|UwB5ngD-aq%6C z%RFj`Rlhr|GG!cf#UJJ~VVgE{XMy7u-YP@=Vp_2Lq>!3}Awc1f>hTcszsO2tIz zfJo39V0lUt02O!bzuMZE{e$2RfCiuS?hNUKzp#Lt9(YdQ??P2hq&9Q=3yAcdf|Qe^ z+K&OP8yUZUu4J;G|5psMHhu;(i+%ry9@u7}>?5xWDGT)hrgd-sk3+3`#jHW`uDCvP zX$F>~X3~_sb*!<0NTxRX0f|9GBO?7SMRp4y&aCX#;-0&bvq zJ$>{Va})S%w7g83?WkeH=tN#E4vGr=1M`Z{&UvZ+L&>WrqOKbT8SABMhf^Eh8JaMI zyXE#o+3-A9z3TIQF-eSH=09%O8eCU9zIogz{Px99ML(QoJ#B!p6*tVK-Z`PtIa9{T zF2QmjF|SsB!O;Rt$8XTh#9Ft7l1cNEgIoPl@O{@^>?2a%EqVhS9YOYEGj?-C`M`UOd`7XtvodDP1F72dO?9HX77fHi<0TwU{cNcr@&2A7-Rqe4}7d(TO$ zX*z?ltqZO_F~{@zCC=_|0Q!$#q*m~e8-k`~D!2&sFB_~omP^X=ZYUt?iHN7aJCC`< z%V7Z2-gq)Wrm?L+{J0lBo7u1^PLK!cRv+wDV>OyJuRcpyn!&59L=djI%TLz!6%FuT zP5gzZfI`YEV*dCuNTm1F7+!e|geSi;6F_h32PA!<5qNm-N0Kd3b@BtX&Cow)uFV6Y zF7%1kckFlW&~@MBsSHpYi)?{5bv(~Mqi&e~)sRqHl304rP%dB^ap>$Zv55{Sv(GK@ zcYx~=`t-|wb{*)Nby-h2~&k9S! zl@OU*OHbUqc5?w{8Ajo-auD*4w_q77MMGV3RfBnM$72$sm)&gpxoV0f%GOFOcac@0 zj?3eV#e-kG<3K_|E)InxhDL%M9)Ioz+ZQH}xkqV&&lQJ8K*gOv<27rJGmm^+t7-?I z9lQO4o$ZFms5#m%1@aAMWv6mF`O#-loV&@UmUvWBiTEz2zUgt-BB3>`;A5bGX?wG; zE@@>&-@rq+9aUsV0vHhto$1Vg^iuM!dZF;w&MyyR$!Vk4sI7ww8<%4X&&gjg_y(v1 z7&d|B&#aB%ggMwiX-;Mtm!flQM&&q}OYF=mt*QOs1##zJtYss~t-{2dL+wvH7XN^$ z>;fIacCVDME2fqrPC@!nY|N!pWR_Y$r`=}d5Btg21YjPN>ygWof-r(f$3~(8Gs9Ux z;V;}DFPQ{?VdiA5QNM-0(#M;7O($;^-WedaG*hgk;7)e ztCyqJOlN=-1nV_HmzIgu;sMGP3NnU&_DMWS4I2LU&Lmq#d?uFdWy?1NDg2H~+ ziC}Rx@2qKK1+mP~Lv5lK9;e`b{5x$D@=O^Rk;W?)71XwBF7v>cL||*4ibp*_*;-+C zYH!c3jaRx2sAb&V;~J3K$XJ2sr8~$P1IxxrmuEpzfiAprH^6?9K*?0gzKsuteIt@1 z+u+Kf^IB@%BN}R|YmaiZ+wE1w>IteYK+ zl0PkmhJM8CTJZY=Ny_P)C^bI#ia0ZJXUIbQ@|p8BtQep+6m~HvG&?n0*!fQGp~O=- z(_i&cM$;Ob`uf*ShU%101Kb{E(PQQIa)`Y~9#{_#AwZH;0)(U({H>ZdJ zUZ~xmWP&v(UzL=&e)+h?-GpS&x$JYoaX1yQ+9PL6@BG1L#ZljfT@H3o5+Ej4q|`H5 zb^nx@{>oxRv`C}cxqcw11GUKRJg6b&16U4urF*^HmARVHWK3}2WJWQdfG7PCa{_1o zW(lAe>$Lx|sy8rmgOwKnI`0VXcbov~go~Co2KbV}s`8&C3r}~GSfGl{i@OoI63;^* zRFQ`=0?Lgh^7Z#PQqrrp3S9xgTmLh+>pvp|v-FyA-`ku@9XC7(H;`^V=}%lXw8j1B z6_}UGFm|&Bh-kreczG1)BEU~c*cvDYisesxHu_{?D|Pu;6sYLEQybdXa0+Ocn)|E8 z6aXoBh?-o{2<90mcvwLfXa5pbwu#V?~Z4*8nm1Rq?$SB^)^h4y5-FXs#B}66@nf-c3 z(rb_ZSb%^1H+GVjJ!xi-sJe0CW7(LFd?CY_hE|!pHW^yXa`Zv0v$~k`F>A5QEwjc# z4=ae`WFVXHAUFN6?&vjOyXaWgSU9~N0aRj6zG(-u?JPg>5i^Knc08kx>TqPMG)elY zZo>B6$c9WU`J7oT?sx_YkivDkTt4I`>0p(eel2kViHl^dPVhN*s<2EL=}Xu{8t!VY z4QCzdP_dH^bum%_ zHWHv_cTL|u9e}f)&XOSmWZ&mQeh+?#1&AM~ZaF^JX1-&_V|$QN?^n89mCgkCiPSQp z(_q1_P-~b2kPs$psY8|t;pL*Ht*YZ3T+d9~Hx@J781m%?1aH9ap$tokMkk(r4}0sT z%&qHl_iQU#5Mb%nXdk1=J-*Ap6Tf425Y&5a<~Cj-n(=ZrA%~|O5!s#bgN;185U9rD z5$DN0pwEniRXfdo_otR#2b?+R6cNCz6iOS`Qj#~&YtW$#pfqV)tyBt>K{B)>pH75r z(x|$oAKsLT$b>OtY;@aH`_hHJYah=(U?PoFy|$n$+Hz?Ph69Y1HMJkheXY(*95n^u ztGbGFH-UTa)omoqrtelC?+%JBR>5>pE8Whl$;W-C%rmk zeM2wkMAlhbXT>5L!N!}>aXqR+Qe2NV%2=Ih;h@)I=cI>1t_A@5X#xqN2C?GSWzdHw zMzQzW2mPF9oWJD_M#W7qqd}wx&mHV;ZyH?p@9&&EwGl9*R;v0l?#enob^Q`2o0E=9 zlxX&x5mhAO&EhLJ+4bf@6Ugx!ZYa>5>uhiS_|EWs@r)-0D3RIK zxjB!KWEAym{PVDzfaq$-~M>Mt9 z2lQt$=dF*K!3FKE8CccHsWeHGtM3g_yJNAc=x1&K5{t>d7=v%l<^hYx!((3x~BEvjfgr;`X*iL%7!lDN8GR?n~o7 z+D#G54J`AYbVcHvCx%%B%GfpE$K37zHOx5!2q2z82W~j{Ql+83R@=+4sNYzCw+@u$ zAYfa*g8zVUx0Cr7PCWFgtZKk0lU^ZMGT5rurA$7$O4v}Yo3b4#jO|Yre%**4O*C}st<8n%H?36@>~be-$wp1zk5W@+ z3SR?&xz7Y5sV8`P_ugf`BfTkLmV*mm*JH7tM%<7THQa0a5A1{ISAUy=9cO6!P|=~^@Wngt(c$Z83cj-YXF3bCIDMyAG>E9G@ocyhE9a<>IbQ={v1k{gv`}K zIGpH_L8z>}+Mjl~E^9y}u?bULGCM6$cCM!G!+cDPl5-dCbxzAWO9xB%6*2{NK!tdo z*ZUc04&Tl!T6ex`2f!CW`pyEWCPtUdduNURdC72HpZRyGaEg^V7R3(ZS z*1_5gO9P$dYC_6g!Q=r3mZ%NFa*OE7a|Mg|N1b;|lDcN$BD7~tJDn1Eo1~1zrMgpoC~S=KKZqX#aQg0^zwsf`CfU&d z^X1f^knA3*Q9&1;gk;A91GGSW(HG`TG@O zt*V#L_JZ{QhRS=82cVqmI0i@GMndMYmxfQC`lY0W7EiCKA6UQgHw)&ozJoQnMZn=u z2%x;f0TYjD@-meLigWqlt9r?8@&6&+&AtC$92D!yx&twIfC$qJ>zn1C6j}|R^)4Uj z>}hp)TxPM?2#`iP5*Q2p(7Vf2rr3qw2sEHj)62U^Gg97;|_aE;@alANj>&S)w^B;}_ zDH@^w^Rt6P9Nz=lCWrpp!3RHT9LT%>_iq7y!F!-~e)HddF{BT0W)J_{c`v+(IG7Lr zenA&xM*#V&=l}kTygXnxgQNd`rAPknE&SKh{lBB|UlZj2R})D#pw?p|cz72~)7jCp z`UE0@X$0eZI&@2Jm=>!7?_ zU;Z?&yeAcNt;PAlG>Ud5b*l{)qj{LGW&T*T_qdZg;1XtKBsX z>|3X#$d!I`^${4-l8{Xu<9nX-5v1Ry+x~e35KZqc0bLo8m*?86? zGdSSoZ)f7Gfs?ct-Dy~-H|>}W7sF{~3;vi2$d6v9ae{qov+RCjyqX$!E6C5wXU-K7 zOPgZG{P=osPmcN@|MrF*7C;%96DFK~Ixbt0r&Ssnv|}ap=_-^Cmuk8}S{0pgAn!ZT+Wr&HU2M>N(kU%v1cIE8j>H8JNw_)Td2MKyT z4NON=>~%c+(xaI^61~E$lF-j zVRbM!VW+kdF;Z~2>o22*LLNeP62b^h|XkC;ch|C$9q%T-vS3|Hml zLW;1P!~L!TIMp)}CXMnL&5n)1Z;`ps-}Dai^#cV}^s)@Q;o`roi>agnvtP51Q%YYebf<1|Z#mn{X7EyGD>h*H3z*U=zxCLh^VFa| zWY0K!L=+C?RVDW-5*n)M6RR*vrX!&(N4uaC4EcGVFllDsph+iiBTmxG;tnS0$o;>D zMs{uVpwiB6wLj@UN3hdBa*s2FRslnR@OeY3oN6=m>c4=wpP%WDXjt&K9SrcDPEKVx zig3~TE_4CkVTYc{AS!c*P>Ytn_7Eaf!GA~OM=ufnbc~c079_9bt{or>rS|f<@#%-Z z0I4}XQ6IzFWsNsFzyQ4{6VW%(r~XO_#Nz+@-*LQ8L8}GiSKW6m4~8S+WwxH3w$lyR zTc~QMO*YxY2j8?|c?nkC%@^;;yT*>fN_shIxsm}>Gen#u|8UvquBm9+`&QD%jiArK zY4T8uA{Nv-L1iT2o4P$)%9j4s;d{9L=r&5385hnP6Lx!hW@=;N*Dm4A4 z$@)8)tT{1IDCW|J_f^(>?bCY`?$bWa;#FJ2UD*6GWrE_Rm#zL&Gn~hRp?_PuW914` z4{@4K^}}=^J1a^`BYLgJgO&Yo&ZKf}4pQ?@IR<L z-oL(l?253y$sP63QE3p`okmdTklTr*+JU6-o7(_U<;J)`^mtq>lTgDA5z zKjJhHA;AH2AQ$rODl`C1wRFJjnF$@*T;gN0lI(xxZqEvaoIDNfj*a}RnO;Eqs$ffx~3-vCBtA{%JEC&D*ntn*Ijd*nw zg=GO3j4JK%@Lc`vfH@>39yi^fHLqjJKebaWGLmBmJ=>>^paozKE(B?AZp%R+*iCy= zMyf?kjn;n(i8wpWSqFH0B?rAfJz_TZU%`SSma{OBs-pb%{UK~(3Z?U z6hnE&mez{Ku|!29h}3-<1kCo)CQc_Mv=+H^?iM+(2r>0%40wI)uPivC6;OsJ*Kvk% z#z{7BjP1*yXSVx(tfaQM&J?);mhX?=q=bCUjPesW)iLOEHn0UXM_#ycgpGzS4BciY~~e$D-KUXWJz+R5)#r$qTkw|JyY`TGhA{)#IH zlQR6CdkoxioKo(>bpfTW0CcBOod^q0NFPE0*FyOD1L~;!=L20o^83+j^9qY-!>9He zQM<@k0P6rJ<*SK_*Q%;~Mw@cge~Dvg4>!qzaAj_4 zF-(b0rLxA?`l|drP%nB>h6=Nm<3L9U;Z8;gT`+h7u?GzLW!#lUL6G;KbE@vr?5!tbg=CdTbIBBpVl5x3IGr zH<~xAelMV|>d`QtRu$Zl6v}`iXyM)J;KE54ly6~FH zWf?(8h-A}t#MCe3G_hHecNXcK5D+lm$8lL+x7CUbx`9W6MLT}4y*NNr;&K`GlV@^Zzsp4 zmzEwiJ}4L0aEZ#QDs_7dZ}?|7_E}*mP%6jx-6ObEmx(v+YN`4*sT*1QMIo;XN|Q`X z3{7@(@Qc_}TZbQiyu3PZ(2H*&s^W+hmh>!6EAlcwv#{js_7=u9#KkZA6Fo0dG!myQ zue7y~Ld6rmNm*u6^yp+k%kABA>Q0&{X9#_Gd5w}Jnv-Lhy9uKXTWQnQECe&iiqlV- z7{;$K9%ZmzA7BwaJBpykyDxJn3V+_*Lo`4AP*If>db?$NrLl*;1#f7JclmO%3%a>f zgtU?uI@y4M(0$sSN^qBjfIY3RpRZ}=RNJ2GN+Y!(0+0)Qa6A~uFg$wJrBgYyz6w%$ z+{39ez08NpH1$-}vdtPY6qtn>LR*D^KQ3*(!x%+hgzaNQ=u`xm+LKA!ZbeO*Qb=e- zdTreKd30`{>uS}${C4mFG$fERJ7y%dTFr`4> zC5vm<+6N3{O_n4#|fJ6|8_1ts=b#s1o) zlN1o?ltl%^1RjUSv(Z6;J71HMYQT`dYQat~3J<(kFDGYj8$nw|Z0tK{1yIs^=Jc|s zhq1J^6l2i_4F2={DyGfZYn#aJPdUfHV9gGin!$hO6t!wzi0k2u2dhzQFqBn`l(c(-*^&8d~wMdn%y2tEyHZ``HQ>@)jeeodw`PuOOFZUtCqBXgp;P4!tq7y6h%E@awNjQNv7)kj! z!)K2JhqK(c;?Nd^-^o(IwguMgRu$`RTn#lVkpV_+8;fi7nxhcH1)Dv$-RXPoNr?UC z5)nGasukw7K|w00?Ui7fASCIdmpY7~I0;-v%N&!j6eRb%Gj9L09AE3cF@5tPYvWw% z6fV8IW7-qBXcD5#71O;%o#*CMYGYV?1=z>h7g)$@vnY((7B4}0+XYt}RsLk*x$aO5 zqy6X*_1kI17p)sz2sK<^*(AFMBj@91X>CsTVOoq)@zCu)J~mFs?jWayvJz?NQY)Oi zTrsUeed~@1#MmCG9!gih68gHpR6XzbsWeWAKj`){0YM$=DvsacoZa(JYB1l6N73P! zj>9%h)vxN_EBtZvq|bu?7MQw>(W7s~!icmU9JQypm=3mbZbmp49^yh!Mk|UCCB*5q z^NBBi?p1+_{oY9m)Lm8u=-&Ab3LQ+G>Jyd9p-#jJiZU>iBwly^a^mQBq;e!=uaWzs z+H^X&fv=xFGz!mYTh55)1{p8ttWey)oJ7#a2-=ozmKIlq5-l!!sSN~#-PT~!GN(6I z=#f{IBXRHz;b9K!_4JS}KFq}FUl?TQ?ZvspQGCuZ1`)vh=!*#@zD(mDr1)rJ6wD$P zIR>ZVLfoqbE!_qIIY9&}^s7dE)>{?GHgS0@Z9?^;@i*9h6H*UK7{F!GsH4FAL!}r^ zMEz*w9@LHak#102?A{Gq$ZS}jB2c>GVfNdd4G8z3Y5S7qP(@)@xBc%s#Fni-%;fm! z1$UCePnjnX8)YUruq_uHGLhHc%vvUgy$57%pU8lz`vej4xK^U>GoxuvPLvOpS zC*sJ&3JCcP7)-#kq2_kr^fg?udcrmK1%DxgI8n7HMW_7kVFoc#_sNB$2`Dl;MpP1wz3yUN3=O_8M+3OD#oP<)1TI=*9DdYEH|VWt`XXEEB)I;2mb+>JIBR z|ADRskqPN}3wpr%k3(F6<}iwa;3TR`);?Vct_-m!1vg_DqbO#Zi+wcDCbh#1v1Tp| zH`7DEx}8@e4edB@7~gz~Sd$gn`i`_*rjpIo>BTtO=8jF+c zI0Jv{rlfrKsJLxAsQGSxTOz!~+l#^#GJgN;(`{w46>WtnZSB>YJ8wc_cYd^3cYZ)Q zum~muZ2lC~L*OJDFu^@=I%n)+T%h%NK-;qV|DZ(PXnlZ|XPC}y+Zf+Q6Ry35FJ0+EDrCGe~8>OrhmMyHj@_vy^X8V+8PAkMR?!d=> zzwdF$=rRkw_N zC%EW(L4_}&TT*hl@vz(?KXR{XkQTBY7EJOpYO|zmoPsxhAUGdlsBGA1A+#?O#|;%i zJgqo=2W@0T2QwYKHZTqR5H&Syo05XXo{Fl|L>{BSF8oUSm ze8tXV0V~Y$$iBnEwB22}G!hMRW+bYudpDy(Z;$bNnRN$xod@CV_trB9&Z_DWTi>F+ zO=`L~UK5)N-A*NSrP`#~?4!~$`603A;mZgKJ$S}oe;*6b!VjMHZq>e--+WfV-IXo$ z#=#itiwJpkU=h+({KU6cW^M=vQl}$9t!CnB9r><@m2c$!K^)tWKin9UN0x@|ZN%?b zUe4(nlVn+-1KaJ*RHRP@?ohLMzJT$gW+L=uJt?Z%4D$>2x<=$Yoy<-5=;^X`h-AkF z^Cv9LvhI|V1t#}vDq!UDW%xqs`7#x5VvULd7)n_N(n?Y|AAP3x(2p*)-Gv@l0CkW5 z1H}cCeafguf^#-_frGD0HpPsWg6Ai=vM)hWhQ3(lx)_X|%Uq^WcwLU7M@ z*j||=kUPsFMFFGbj<+yVN^O+uFTF&7!M67Z0-xq>P{p+^QP6?!m^%Y_r1o*)IGcE@E~g z4Q~aPto4P>p0AnsRxU4;$o!QFPWgUWl^_ZWCSGpMyz?%wH5o2v*1G7qH*@z=ytE); zkaL}S<}m|_@3J7o8xfUh7ez3q)j;6z6 z-&z_T*?*nbOz{`TmP~voRi0WnFNf`^$=lv2O`WI>re%7g4qrAsdV`SNwYcXWJzup8 zu~hbNq2eksX6@Y`-n>}jfI+{dw!CgOL|2Y*7gvDKL(e* zGh3(K-jUCFvr7^`Sy7*D6Eo#u=8Mt6g8M(GXBM|vsN4wXYNz%adR&O*)rRLiD#Oq+ zH{?5X6GjT}VV~cY8*uAqdR6tjJ?}{#}v~ zj3(JmD{oWlK_+M4^d@Ig2n0dmJ@=azTi1S8c&<=S=OIueRJu;tHW}jT5OdqR|B3}g0??P z#R&{LU{SHe_yK9{>q1s!Q9ZThWlvl6WvZa6V(W?sTf@=Td1tJ%OC7_=p1J_C^xBL0 zw>uKw7s!kFZHSqPtrNEvp0eUzUGPw5YAaqSi(80cW;{iUtMk*-q@0!x<@Ct&WT zjUW*iVa(sMYIC2Fp)yDbJV<=K(-%vBTAV^=^c}?oiCGPjXch$;=Fv(y)DY?6b zqta9Gn4>49-tdTf-%}HHPpHQt)|GG|#;AUIVwPV~UtkbT8E+{5B<_4#zpqln(Hg8g z3^)gtc2pb*7$$0ai-_q@hWrdSnXr(=;*Xj+pu6oBbhi6>*0%jLvfNk6ZKm>8aMdl+ zrFikx^Xn4qGMc^%z4Vrz98BbnubO{49qw!3dJ(Yo`#@;;9&{*$#zimp&C&C;#N_U z@lW6xxA06gynJSL^CFutG3(m(ffdP^1$j0IV}##@GP20NC6G)4hS0oClDc*#p*s_K zG^qa>H^x3bn1yyN&hB~9%rjZ_lxv-K=$GcMwM*yL=g;yHN$$aryxg*li{FgkQ~tYO zcRuFXa1z>{&!V|aLi(`2{)t*1B2S`C)^E+LV#w`9B}Vpkd6I&emN_ZR@C~=~>nT_I zTrOq&FZSL8s;O;l8x2iF6a=<_B2^R%N>h3jR0ISRX(CM&lqxMq3t$1+h=72AlqgE? zU20IN(gdUvP$`ibsUd{Goht#`-sgPhe0SV`{Ns+jGlo05k~Qai%kw_(GiMUTHd|~- z{%&bv<%Hn<;x--DGnQ-t`L`vFD~N9$+}Lg7KvLnVgH^wa}Slp|t#CK?YJ;jFt)@vFfho7#M2y%G6*z%=vr|Rgg+F6GC zSt2|Z`Q^W+e+tAGMMIV-!QlC9dp0uqv!Vcrq!qBB5$Sm ziaccXIk#mSD(09ytK+lHp@wXYbI6&X`>=i~FL=Uv7_U#yuBcHPjhsmoruQxKz&QHa zfr6U};cMvWviB(_NKfX9n?>fqRhaaddfmZm2NW>V&CiB|?hEH{`$)w1bG1Bc%ABn) zDwiD%UeC@v{|eW6&j?-ja)vOAqQ%E8dJf=9wO>VI4sj!c-1~=7&AoUjOO(Ehn84TE z!#wTsR&?i@xn52;^v$|-vW2SN2!1|Q!_sy&pJht4q_@HT$;8MkjV$bA77%ZI<73gw zju(%!gsMJ~Ya~qn0ZDoOV}kIpqrUFEL04NujA37|zUin^lJ=w_02V$(-PV?%SSyM% zo(aG1Q)LBb=$-Oa@g(@oCiW%z)|~t*?7WuW5Sqc}bVhx+ZBQOLL#b7MTbSVQi3F5B zUs8C$qVL5EEbESfeD%|a+50+9$PQ}evVkEuGW<+GP4_Hir=G%y0=ig8E0tq%_CW zauz+gdMb<_!C<*=PLE@q3#s9_V?6DZ56tw-S;D8D?Qw zLx$zNe6WKeHNGk`>dTdB`}*()9B!958_2k=)eajMWf_)Y^|+gCu}BG*1)_5jf}$-95=OAeRlU9!zXmMar%d3~Jp<1uWZ4Vocr zo+}+j$U?uTvl`Ju=Xnl$ci^rTO;KfRS8WderdoB5L+w0wk&U!br6ICD{*-T35KaH> z^=Zvr1@nZMkSP?lNV|Gmr8P^UO(LQLA6<9(%yAQa{&(6v3SsRt~$j^0*@{94j++VnDSW zO%I22)Vb#qKTmfZv{Sscyq*SVsiAOFy%p1~y?c8L#%>Hzx89DW@n0T#g079K1Y?z` zel?jvfv!Kp(DH^+7yLyA`f;Aoj9${r7p3CY)8$94btwXuttRynQsTGi^_#SuRvn5) z?z(c_@c=zDUGMda{KU}OBCp}TnQJVthAxY~T7LcTF_XfXN;hZM&P>7lA+G_sPQ?4W z2H98N*N;yY>alh?(P&T}EkLo&oF1Bv6!VsOx_Erh)oouRr4=sP(&jUq7PPkFW>0Fv z`v`b=QAy!VDrWa)Ja*!^t;cE#Iw{e!=yF29eWmeR4k_*E7uQV`6L@QqWm@65bBVTP}MdCe?@I){Wt(AKgF9 zO5;B-c0=AoSCOw|cjI*2KsSGC!hmiu+mS*!B>Io>C1=x>=bo`)_C+!-*P{Z@%$E-h z<>yD9id`J4{nj$96=Eb&(M~K$CssCQ4&o#`IAT7t(eU^0JyjmE-1vYAczfZlx_j%q z^Kp*Q*TjS%rI0l*!;oi{rw+rGNVQCoBJefAQ=#|ujssN2*%8RfgVhzj0F&bS=OGxF`h9`p16TjZ>#t~xZt})XVP8b}Y^qW%H0B3)}Z{6{P5lqKNX3MZIfRg21 zpMzc%r$YFTyDwEUKGsr@=Z*AQYcp|o)uLpkAl^_SNjRT&)xY)K(9wB_1b-Dk{YkNgLeZiK2 z)syu46L}L|V)2|DWy1od3i=NO0ey{1)_*hRQ;vE!4E8=Je5^hn+Nk`Bcr}yd+F#%4 zAC(U)PW8zb?tGuun%E~hlX$I|)A$fi`+KZfev}1)BsL9 zkmIX@3$Dv<_M*$jHFD&+E5qAMZ6*Hr&}!{nGO2#2%7OMB?>7E^VYp@R83j)nTv5Th z3Qo51Mn`M6Q1ye4=I?RK6^~)$R=x#J)LZ#qc@=-Itb{5i66w7R7n-r{t~_O_Kb|Ym zb~SBy7yT&4z-6$1Ky}cGAQx-748U1b!LBRCE@yD#!%L%Vh3g2TGm3mR5;MmyGqbDu z@|H+9?i`%K!|k49#Sa?`N#tlMoG3vWEEb%2MsGxC^9sfCu)$7Y-a(Ngvms9{RX(3^ zy~?WlrKK_MMG;@L$y|_`4C0IUyET#yoB79h;;h*m< z)Awu+|13>^Xm9Ro817d39J@{4Ui( z{cofA*=09GcAu{bhot-XM~8PX;|Y9UuHvx}A)hFWmw;2-M=t~->Hto!a>diVWw7m5 zP8A>ucBzTwm0$Jp75gjuE%j#8q&eOi9^w(f4&R@(bA!Qp6{IjmaQIE)^paUEq&hsn zyo6xbp#tM9N?2-~>7BQnOC0ET?P3mHnGM6*mC?KrUGRYq4P@`n7TwisD3P85vt{`Tya;up3Y zV~?=L#M|fXo7x2mZdY~N16E_s@<*dZEc#*+dLnlQzx?)*JF2I^8yR#6o`II*ZSxt> zn%Spbeou|d?d}e|RGEx)afrg_z#Blb?57tTm$T|~v{0aA4mav~#xhXW`1}CG9|k-d^B$f9Ggvzt0fy+yKqvS;aCmz_6lA*>D4XqYcc+d@`ZJ zju|J)6ZZUkvHMJUqGdUtySI=M>&{Cxq9u7Z*@i5Y1%oJ=jf|HHxbs6p&pa2`cv975 z(d4aUbuhXe5IQA`Wv-V6as%Kg?`wxQg7m5dptcNUF5Knmn|JGfmxEpX&}Gsk>JSid zCLb18`$@KY*}ZLJ{3&mreW3$W3OX+lzyoH~ss&@`D%1y1!3b2xKf}&ETQeDVtF#dS z0xU=PF@H<9bPAZ6PoaLB6|TtLc`&mXA%$yQUi8M~&dhw%1H`+P3O_iAu+ITa`H2iSBdI|4P2`9Ej*(cSfPndiyfABu3TvGP+6JM2bna`qrQR3{m zHv@vQ-9P&-?;^ODFwS_a*9OU0HkWsqmCNT1_^QD9ntK{G;|ltXc?T>a5SrV0W!~Es z&4wC9kK!sEOa>p{x9U)yu~RLxQJ@>aVDpzFd~BSQREAMU(5~?_09XtaN}OgoO(YA` zeQWeeUIy+bEQ=pB%%ONLPpbR^0D^H4biiuU#mPR4zy5(6X0N1O^XWTbt~liMO4Q<_Nt>#p)eYH^Z>q`*Y;|>&(|1 z7IKa8S7y477L+W5pkZE&iHz5scLUKj+ASKi>Ivt4P2`-QZykM~-xqHN2YJ>yRqne; z+z*3Ihcs_1<-FS3B=u@ZDsbA+~= zgk&Y?|I0_rD5ty^tV*oraiwx+-%@xxsJ5BZBIUi++p^^54|$ZAs|?!<6by?g-LJyP z4d?6x@O zqYGBMzvREe)Yf~YY^$K&s7dtsHY@NUz4Ey)LT-y!#<*)ZbG>}oV936(f?<2Y0vz@)T zR^H6n9k;aAXHCy<2s>uzR35RYb@$W^(Y)L{l%{vh5Z=}xBD3DB)0uH@UaY9i9LLIG zC~HlS3(_dHQ(n&`_S!2ZR;nGN_fS}Cx9CI?=0kkoBNhOi?(;d-s;$dbMvu6Uu4A=4 zh1$-g6Rs9(%5QvGbe?x*YjlncY3#bh$nE2`TEz0lEjPs&~@CkSm{9yJPqNGHkkr-DX8G#g03i1jTG-;VN6A|JG zJGQgn!p(&8{ZoUKHx4{>>PkuWVT374xrbMxt>qW=TO${?-5O7-pm^py9!E9a?Ni{e zY*qChZ_{eAaMlOD*T!KW57_uL(@gOKP<)O{MYTxX9?zZD%mrn{7)KQUBVIyzL2O1} zkN{k@&PShpSi+zS5XPA=j}Bv*N-Dm;=s}(~%qQ;j%Bn){HG%nk!<; z%jXxyUngOmZE9t!WLuk^@zOE(+yH#f99xj<2yz?rw6#F<6C=#tg7%Q@K;hJ3Jo^1J zO?d$n3T^SU2-!R~!yphdwXo6|A~lqDV{C5pb=x`z%fuKwpr(&g@5_ROx96&xyRD(y zd)qj!=4m7n{BCL&=+QEfpqUQ`v*?yBF+6a~p`;W5^7X94Q(W%*@g6geCGm2apZLqY zM%l+Ps#>Ef1INzE86VpX&mU;Y!duK7WWnK_|J=aE|m>@!@&VMr0yoyki zf69EglGlwn^r7ss;AIzX=j@{mZN;YqmSfr&&YuwM7VG*V~J7 zdh&hyPE@?gpHhCyJyWR$!g;VRv2xh)XppT`f|NL@oL7_DPrwT!H#9@d!0{f#XjS1P z&$#~Tnu?Lg2LoQs`c%m6x-o%p^o6=cS&bL27lf<2R&?m+*N9{V$Q7N=2tAjohwZ3j$v zr<7ZBT*tPd@+D|Pw~XlRMjKc`5zli5HzyQ$k=)FSTXTgTk;4r|p ztnv;8x{J-Nmm#7wWVC-8kaq;C!W~(fOCUN4TDe`mX_eXMF0)|Oy}K+w_MF?n^N7wC&KR&UkYc4OMm`PH%VU!-~&CL(7LE4TT&&l*stD4*B!Txz-jT zE3dZ*giNJ#RK33SxMioDjH#vOg%4JShL~uaOw_6PWvQufcd5@$-~o-r^TY03Wnzw| ziitDf)0f(bQu7AP5jWkOzGkDrCU2Mzp)5q~MP>tvyTHbguA$lJ0F~Jqbfky<=~bFg zbA^(W=#nC9oQ3nL({4(ZaEfE5$AV7w_214J4W9K1xtgWmdB(H6H$uXnrS5aT`)MUF*@Sd|KNx zogZ3X(zWLgyu0%r9Sl zHsm00vX^GUy&Ku8jUpFT_)%8g13o7Xm>wWL6F&cVSkIdtrr76x0Migd?_4G8;Q!DW z<5MLP+f0wk?x>Yoz~374%(*hO*y8RG*q28fS{Q#hdsU*wxOe{bKwpJt#v?=bPH8bE z#M8wdlO~Hs!5D;zWkRFHvsQJXW@Jf$&UJ+U%tbTtDDO2r0FpZj+TD#+^Yi&Y&n_EZF3*o)Z!|-0x%`-^aVnJ6!C}>Oj#QDnueV zC0VXSqx-IvY#@?K$~vMZqB391=rV%SZ{N>UDTjsDAgc)PI*oF6iiA>E-}!zDYdU3` zdcHv4WQJHictyPYoQuQA4p;_s01o=Ey6U~1ln-?7;i@~4?GV&^Hn!7p#|(P(v^NqI zJZ|rMd}p9szT#t+427A@)+w)Eebj1KjsS9H@B;aK4Hc6ev3+1zq7vN{OHG7u*&hl2Z>Am9gJJ2y;4p8e{~{kb6Nk}^K2Yc z`*v=f1pv3wmicj_&Lf!f|LCbZSNv)T_Ssr%>+WSr=4Yx5h&z@o4KI# zk-!QIOg~$}ZOaN$+l)7@VEOk}fR02yKS9atzyDq~*|s|iXu;I0*RHI3sYq=jk7I_Q z>4pwWYO_($DL+=yCoj{#j|xoP3~}6BK5;)4c^qLB^Ym06!m zzEW>tiJ-CG>?IS|U@yqsQ*{#P`^^35K#$lO7Jpz0Y8&f5fF5gH|2bl_qkGSIX|pBV zuKJpi7J4aN3k|6yo?G(uz3)q{joNJK#%Pah_Jq{@q>gSf?!#45kIQZfnnBQdkv=~M zn$(Mk&`X6sbqFhkC@^elE$yaA%I9_z>e|XMa7ylGq{*tN&Hn$8m9b6Bw(K8-FoO zZW-utp$E*@BgV8v(^5cATZc4%u!2X*q^^`+V~qA1v{;HjUFy@*Jm$1?u+(^b*YtIG z2h}N(U4Uh(B_XBSHLvSr#(-8rNip zHth&3$xaeKPOwJ57h(pgh2k|&IWt;18P#4TN?3O|WH$uYmLVW3>uy<@jV{6hT6GxL z?Vw#Hz0t&yYStv+-cv%)*lZ?1lTUv5=2?^FkBf*fMX7C+%+MnvtBHYg__D=XiQbRI z$W8yttSFgTWtJ`8Og-~N8W|XQPbcP-#@9Q3>+QQ`x8x{6TH@92L3#uB2 zbJf3K!6X;Oe|nS8T{4ZaT`DSG@Mi5gs^Fs=a;tpUDnnwU{!$R4SWEu4<;0bxk=6dV z+e*7!KQ%O#>aGsIn~A{hNi`&EA|OO+q$7N5y6aUHuPuli;k4ZydYIc~cj(IasN0ZB z-(t}|NJ~nX>Q18OFP1+`$s8MUe!}dYuL}P8J>UD_M$oBvAg%R-9!Dk&y1kK^9$9@U>B{hbaQHLc)A&#w{*M_ww*u zl>fSgD`S{a*JFQo6+tuEMHXWc*S<9U?P7APsev8m7Y55B|7NK`_*wey^tl_HYKqsU zEckiy@X-+r;@edt7^SzX8kkW6tqSjMkN&%>KwtCN)WUl4iH*A$D_&nzHmd1s zdT&;9bh0?56{kmFXW)`4&s{ye!@Fp@z6(Hzvl~ilLh&7<`y5ujD0g|v@gvut(fUan z=%IA^TO>F=CY|$oeVt7_eNn2l)^H9V+&_tR(;0Br$aogR*43`V=8@sOGe9%W$iSQT zK@|uu>kQ&*Y58!9%X4#usc^72I%y2!`X} z9>crdGBC6GuuVgOt4~47OYkpA_n6=Sv2yQGe^&ybvB-}I28r#eizrq)Nb1xDC=NXm zU4+R`C=Iq0L1;qchgtv!^aLn?8^Hl%>RVH9cGrH2D!iCJhb`3Tm;Dd!*21@keA)5!(JOhVK45#LY%12Q!iD+wfcL1^{79cW2l6esMjhsSOnyR=Wix#5 z8`-|DJv;FUWI6fyHbrhA;=cdkwsTuge@x5eo6@EODW8V`Ir~Pp2>47HmC&q>-5$lS zo{s<~!j*SrWZKMn+iSZH=wLjj%mly}UPm&}WjdofSeUg(WVT7LWdgW0Js*h(p42mm zUDy}jV+}Kt!}OpBPgn>P>4G0Q6tQ2*^JD@hR%>nbc3u4VU`V>K<+e(?i>g_C#^Ukg zAFUt1K|J7HovaQEKbF>!a}lW3#wYFbD72$oubM&jgkbI=^oJ$%9Oj#6Sic#3B-}X1F{1=ez}?N6A%DL3m(&Jkju^(6%!@%*t?z3-(bSx zQ^|c>d%E32d4d+E9Sg=+gO(3r21DIt z${kaCJ3zuixVyQ~4nJB7x)=1&s(o)nvZ45>0Wt|+T@8?*%z((g0=c(^Ca|Yq zQ0=U0)KF>JlMwBJX``NjZ5$;CO9DI0 z?}PCkm%5juQvmS*X;p*I5Xz?(4EqcLWOQ~!0(1n8dlYJ<)Q*vpE}%&>FM|k zBKkMuC_-!~Do+R)RpBS2hGkF6l8u_zmXq|36sbw?wpj?0!yCAgf}*Rf11kopeOn8 zk*i;t%U31EYm$&H*}C6YSVcj$yqc~?yR#0QbXVoJ@g64#UC3A*NtNTdxVn_}Bjg=h zb4WS&F8yW73BgQdf!5>3J)Cltmm?Y2A5~KG!&yULF9j}iI<2jSwD}zn(7%*qIs)x4 z-h|4WXdO-R<%tgvku-xc6k?OWL)uW1W=4r@-g`_LLO^8(N@fCz{=RR`ml0rJ;S=OV zzpm!zxoF9o;<6h81c-0i!m1e{tjwLQlLX6_g;4Sg^oJDWi=B1?0Dd-;28>UFa~bGr zuM)V!;$uKkV7^OYb@(EePY`=O4BfW@g6u>W9)LAwgJi4y0QH|P!n)hoK}-OY3!Hxe z6$oB(bbw+3#w6{jlEw^Ns)(!$wa;tUPg16}NbPWV9#T1Y&BEs`bCT(BS!B<6#aRp> z-RzjPE7ISzJ;BhQ%y)uw)<-#|*_9&^RNm9BQ!JPi-Brhri1Of$97j@V1B-UuJ3^^5 z=}&92|3ajRFI3hKb3TG%iM`Vvy0@S(g`zRoZ>@%GzSjsWt(UyC?SEMsploCBfYAYK zsC?-Uc?9{ZN1%(8%t^|-!MGzNHQ>gh?^WyPi@Av3JRw8Q3cxjCkBmskB632Qj7t%W zKV7U|-8%wV0O|q$fXc%(IlQT%uGRiW0PynUX&8I~ATU4*+*^?h{5!MMP`BilSDSIB zOd1~tU@#uoc@?G0&-5nhMf@Sc2ElJxg*fJvbWRtnT5{8Cj`t5jxG)3ZLZsdVD5L3% zvEvpwMo3A8td0y;Wx6*d};dTs2ce1Mc`Ttt05fK$iRGdm<6QxVy<%d>e}8 zk2a6~Gn+%P1{`v2V|cOT9w`gTzuWvCurtXa|C7z#0s+VV*<1hdJ4vqm*;}9{{Nj)w z-bw;pOu=Pn-L)BuiA{;m*iN$RK&5g>`p)$9CD*Rc;e<;`@9304a6f~BTNzNEZZyaa zA-VbY9lFx{!^*~oFtkQV7>sTJUzzLIn$o1nvX?2iB((q*f9<5wTYcAnv9$8f4*o&eB_AO1M&-Ek#I6---Q$k36SvbAN>G{pVEv35`RBE zh%-ikTnIkM({4unZT98V{Qmk#{JJ`z zVv=>*QJm6MPmU6=MEwLF(ocPBP957RnpvjS)|Qb8AbPPIs0L5dryeH^^&Dl=Sg9cj z*^+KlBJYT}lEhulzQvZ^fNE#Cm0}TOw!Aykpagmb^L3S|``)Hq<5Y)8*z-eMujYpY zEJ%$>bTI(I++{kCI0w>SGI48Lw#<7>BH7yEWWqsihH{~fP%U5&XkWM)Wq!B5bS4jv z$aMZa>gsQ#P6!MbzDWjECL})5KyLz^=%*z5#lAm)gADUvW(X?q*}b(nD4L*h`@QM^ z;mYdQq@mK}c-p%mIR(2kM@T^Gxrw||;goc;zJk_Py6~N|NOb82Xfb5ld&n*3>Y`UZ z^}QjvVg~drtL&5S%M-v?b#MMWnH`>GiA3~#)x>gmGC zN@Ur<*>4)SMkc((r33He=0Zgw4S2`n_R?67GNVzKz^sq?x31-Nc={s8q(!PtNJ0Yn z{*eJl<8-)Z2B^w^mqLfRNlg5gwg~C~9o{l#LHGi*?f{Vw9V!BfiJLFUDI`Id+{#;M(=EfNBHYv@4|!hj4yqNTYc6$Ct`t~OyN_m)uG zdJ)mH9RfRGGhlog2G~a_R6qG|hq?WKIM5djHKfg;j!g4>X63NYyNDR!O$~s0XBUKDkR&<_aAc${&7E$qKfeg8PF7f;4^Q&H3`afSUIVg1$87zp7=q% z6IA5p>`8xctng{2hlhzP+xe$i;?22HUFdl8oj(#tcLH#h8mChn`%){jE2jE5d&Wu> zDus#$d~p3`b4!Xfw#JSaF`4Wp>>Ur#A{Cv;X>kv31=}OSt@tIIdQ)`j6Z60fth>Fw zu64@8ENcO0*G6fN$+vH%UA_z^LyYQ;-bCm-Kx6DU_f=~$5Da^&s%+k99+i=wK6jks z&))R$r4Jx|(2g_XD=itD`O{KLe`ab|5;siIuI_d9W+7rXInLtIs~O24NCG)TRzWp2 zYy`Qb!32={WNQBA99a29X(Z@^bFTsKGJ{kBQT`sfOv)*G4Os3l;HF!OiZa>j(WVq| zP-dQslHNnE?f%gJeq?P)FW7nMPy*ZndIk~>)@uW3a3oXc9Y?2k3^w35FO%U;s17R6 z{f|{$-vN&QQ%Zm;o~tW8$^(T#lu#;qy}SpMkIIim`h)o9$5Zn%2`2853{+*c+hC7; z5Jk|OL72(!+)B>19l0FPV0$|$J5#tlZs`DR((+&t^3B7()z)xK)Cr2fv3JZC^k*NP z;(>N-X4KL1EBLW=vubkz*D>R^>{qN0_URcyH4>)X5k1~xFPxYK(K5BkRf4HOS#}ks zG_o5$-b3s)z9zuNwKECAz>ASV~Xq)F`;Xm0ow;7FY}_BKP0 z88foc_xZ|Bu21vFf8FNYwb=kw7{c z^k9vKJ&zD+$szxZB(FhF$Mt=6NeLRwx<&NJS{5}w)HEHjc(xT?TmKBA3px<49rHp+ zcvj2fO>e4nvsW42YU%vKg`Ob=f(@tz3N z*SiGOtwP9Ya#`r+oSs3#T0)l|@BJ5~oq;K!KE*=Bn${F_>dN$I3zxdMPu)vZKDI;k zs^{XO+7yJ4V8rJtB~g&m)U3PePXYzx1EhdRxxKhq`C^d@mfG^+2LawpFJPDI-8;R% z^WV)J0b41VS0=pf0-Sty{CiusnOgwqe0kYdH>n5+YBIYsN6;9MkZz~={PkF5@y!bu%w#Ejj zW(}oU+7ZA(fPdk-+$b#GI}O`xD0?NDVZT(7Rgo@_`OT%ga;@W;_v%~iKSDI5s(8nt z#pBCBZg|BdQ<4jLRxYCo_70&pjB*6u`Z-p*lxATiKKZ8%vQO6-QQzsQmt;z{&>z?H zwL*^y_6})U!V-FONPp_2C24l74D7O40 zJbpL(Y4G9D2eo8z3d)q%FWNRU1$?02FM_Nh0f5xYaFJI6RJ>&?TOjhXNmO9f?3)Qm z%0*If1i_R-qWa&%h}=z)vg_B^lk-;_Ng}7;T}8%UG6GvfZ|36GJ(_bAy-BhRSVx+Q zVq#XvFm6q4QpTAz5U#VCfuY*@@^D<5F^MNu$%_;`FYGLHJY=QXl3xHW4@CjlJNkQvwZ3+RkEdO4D8l&6OzoOS zOJy6@&~A_FVZ(ByrzT^SUYA>WypR5pPySpt~1OO0qE{?vmV7ay~o-u>z6*u zAPo(?KR+Z&CW8$Mzwa%Ve-)6m$eFSACk5=^uA02Vu(clq<;)}V&BWZY9JIwr(uzeF zH+L~e?t#n=P*m9eI|bj&yZ;w1+vlwK1sFd-&lnj0$}LwaI_0zww6}E<3HdU#riHiX zb(YP&DTuWee<=KM@`QADqP_dt+WRTuu=}-_zxyDGCNNhz%mqD2S5b!Yyebdf>!W!>@+eFtTvx4VVkq4Rm*BZbly4)r2uAKm<9{uk zBJXXDEmcfOuAO&botBDqUb~}l<8IZqe8fS%@B$dKii%|tVH=AgB@aa?OclltV}{ZB zQZq4KWbe*_o_)VyfMO1FH-ypg@fCD<-=q8G zS^cRDjNw7++e(ZV@)>JW)cIN_QG{%=sFEp_Auwa(zc3?M$iu@sr}W9DayiVpNcM<| z${UhZ1b?>*3>f#}+gt?AcgG2+-o8scrOziS6vXm>(DKacAEkN++i&r;%ePrg_^l^i z5czbk^9Z_Uig0;lJLi1-HQVt$R`+gy2sd>1stJ$L=^4ApD&@<7*KC~SGPP`JY`U^( za#yV%CVyZLhrw$C;%FvPzb&)d_(<9JU@JRbDlN%x0r=qPfEKz$-gB9i16?d z;Ve@MQVMPc`fjF}Fp~2#zcE)DAx(yf*W z^jMajZ7O;Og;EjX_#yBU4;b5i>PjwG8Fj`u+>ISXqAAw3-8W@qEFAv`7oz04@K9jH z#pk*^>)@wa!9maL)B}f=dX9{b>|1mVfpR$R`-K0E0e#7<1crMg2mmL{@WHL$P=$%9 zee}4-Ryu527U0!&5~dv0;L!L5puqeOIhbGh6@&nm9H8e>Qn{{Y-fu?vJxzddl~hzt zy3=>A?)e4Dn8NmwlkGkE`w7=T9!0FQW;^OAcx?wDw~k31g%S@G(tSW5OWjNtpb92L<| z&~gb{M^!#}t4(_TDXwIU8|@eDxml{m!o(DY2P4^_s-8GQa31}{@XRySvd^;)oE&UN_2=2017@V z6`22Cy=d`Y0e3eO(}kh8g`3dgORfaKj%Qf~p!Mqh``2$ehV*(8JpX^68x;JDFlP0A ztMsu%?|!X`s-e5di4CDI40NV<$>yX~I11YV)Tgrr>yL_-ay7mc?lo}6@VRo8PJVfP zLF2aFZ%-avl1tFk?vX1MZ#s1)y9+8f*&umOGxCVocv>m3Ja%nYR0_w2uV{RRl0en0 zp!E3DXbl2iV~KGBjr6EYqYdV?0EgoC&O5{vsJ_n2LxFAnKLmE-7RXy(cf9+5Um`r4 zR=l>JEw=ozw6~%iUgo65->?5c@YYwH*%Dnk3@XL{c#ci^N(=8__{l%7RF4!99Japttf@I;N>x# zpxo`M=Z%HQO;&eJ79?ZbWy(8~D;#++8jCe@BSZ^rv}|IRt$onJX%S+IDm#}h|FKtSMFe5@$^F!^kPvp6jC{rI0#J0fzxLa92r92rzoPvi z#!%IS#7thQtEkzp?|ndtMLN$L)?YZOl;a-PToI4X7QhF3)*&HkQ`2i0MRQs*=7DFM z)INz1)%OjDBtLoFt(wh)c;tTqA)n|;wC4X-2!R;q;PZzxo~@Sg?_aWsX&Q^WeEOV8 zTve+(@)c2DfmAINvU_@Rk<9^wy#xq*579km{C7g|t=RvEvzXApFkK1@3K>~{?oqrh z1JC{NBYo&_aXjU{TrINc_Z|LGXctXUWlBt?-3QMYDsOv@K(~((LD0+FRa|Miu@9Ad zFE*y6U?BWFf>~i__=Klvvx0;2)J-LD`^j-83#)jl?VqnhKt{TK+k72G58$eyKT7Xk z=<{ERBB+3GRwExaH<8QN>~F=i*Nl&kZ^ygesw0V5lFMnC!>{bf>|Wr{L8XqU-U{!+A z8K<&tu!1nM+HTPfiOSN==+r#}Q#`=Xm{ck+JI6GN1HTkK1WZ4VdpLR%@E#MrpsdHN? zV$XQ1DZ852@k$Ksy>*v|rz?MIQU2;QbMSR@2@S_r5anwz##UAF2X_(Io7byqGS#mr zT6x5pirILk2|;EbKltN@CGo^LSZk&dH!l{MI+fs;(i=jqQ;S zCQsPzBnCu)szx?a2(+{+L$pv2{5RcR1F8x?&QWCfPJHPdQX%Y4hpg-Rmw=5I_UNkk z6?TBHcN=nCOn+s-jEa*RKGEEsQA4i{8wnQHWAY^r2grlA$>l| zwg$MaH|0Xj$U*TtfxGxn9o|2+VbHpNl@8ug@{7v(8GZ1E~+&?tYczHB%Uqu{1&Ni#L^{TiLYSBMz=JE1bpjVn8Q5Q`G%gFi_-hqhOsS6ra zy*wHa8Z3>jmhh(9Jii({w(oe4HJ?HmHtz@>Pu?xh%8?N8n-OQuQ96#!jdfu3Q zU(7eeXvCi&;Ff1@lzDj6D?JJx( zMh|5z```@V2~t+?o@#iPS$lu6Ig(`{HD}R&M}za0{l%!Pivgxb+D8ph{xqt0Dxq@I zHa)4yozs20&$4~Ud3lA7JFXQJ`~(fdgw!`ph8~|PFk^n-w2l`W zT#G|IGW8T|98U4dQ;N2<7)YIJTw16Fg`|N1HMRbK0c~Gud?$+#QDja9-{cb)D-jwh zfT7v7HpYnM#y#Q8xq!^EAAB9NJZD-0Pe0<|^SlbjIN~6*Fk-r<$tmk0J7e)wFZ;sa z+4T}x#|dZh@V-kp>2`F6o-lp#AvWu}M&7mg`Ggms5S*zsA&@-#*{5XKwVM^b>PGFZ+4d z?PZdKYegQP()8=(&T9JI_gXVu`=&4*g2yU&G$7LcyhFKDFBAPrGtQbDN4)bbO`pZ5 zmC_B(aSeP#3h8TUE=8Tz5i&<&3b8901MVpdI&(DjakJiHvm@EYs22#A4V`Si`=9Qv)US;{C^=L?j53|k7+j~t$(g?k z)}W(~`I=YZb>lLzXM<2cU3i<4e{|~c0cOABXe&aUcifub8Vak4S;^p*yZMqXvGHFQ zgRbke%yVf|T+Xtk37M|W3a-ZMt=VF;klfL)l2}O-jQsRw<_FwH&)4}S2D7Ao!rWOR zswDuX>=mQS^_*5frz}UpZt&W@+~&IO_Pc*6+W=7~*|bnkw;iP3`KYcgpOVg0fzLMKt(sWY@395wj^u?;dTy-v5=Ax^Ot~9(@KZAmR(T7|Ad*|JM!#b$lmqzboCC4NJsDms zH~9`9L>%>B>(lhDNh{8dt5$iUBlV@^)_U0~Y+G1E#F9;(pNiLA1JFdxyTM({ks7FB zp?=To=W{Hwuj4`UDi@P4d+{Dy!D2O@y!__D?$3B2U9N~CW*V=r?sW{>^;VQ);4J;K zs|q&%mIZ3xZahNYD73({@WH{9la~33UyT-*`-u^vMr;YcW9%*?c(5lj?sBe;=}Qmn zJ5dgSnu{uvbgba3^(LDfuHR+A$%)q@Zaw-KNEL|Pn9i%g@ClVNZM^;%MHN_b!|LOy z(9qEvice74K7_7?$?&!wt2O5@DfZjb8Ea6$iY_kyO2fuT;UBvEmE zL8#<9H8Z2af=3-8T4&YqEP#}?jmc7pdO1I#6zv9e30XoNAy8n&nIiB(Q-;`j%trL0 zC_BrAwRH;%eHI5otk3$H?)vKkvqX0aI(Ir2Dc8>s=-u)`%#ZL1=`;BZ`)sr;Kb|$x zoV_#sprljy{_{u(94W6#(l8^lhCZ##6`*pA+++~@A8Hu?9i{qLI~!qKEr$)C-Vt3Z z$ZsCg&cWUPh zdYM>5Xs1HC((pe)ouyzcz_pKmYR$1OoMNYasS54^#L{?TnJez0|&z*MuFCT8|GdH2_baTI*1 z=1Ety#a@BV@S;BZSm`DPhS4}_MkSR=TkD{Mps~x#4EHKmE$qR~v8cRi&76sM*K%FB z-GBLY%`UtqXwBOXacF)p-+@P5I0;0NKTc-sP~2sr2?VP`$Gf}Up5!n(Cl_;dL!8=m zSAUHw_yvSg!szZcU(rrj z5#zcuxrYFcnOzvFbU>YOKfk+lW|+9xbE_o0UKW2tA`TXq(UU#UdwS@E5M77+_|@*5 zmPR@@m2h+7BxH_S1Ju(C->%~rAS-+%YrXJj5E6@+)`J3QR`4o+rA%S@YCPb z02uSAmXn8{Y~%XuU~M|Q-lS{IHAC8?;!M_XzK-1L+DAtrnlP_KC0+s5wJ9Owg$nQ5 z{tJ_>@#T~KOB|rxdR!B}fTyH;!?l6gkbCwTt&VNZGllc5UtfRlf~hD!Sr5H2+B70> zk6TwBsnT=b8|qA?vc5T*-_I%cYJKVR@IkWx4jx_s(TX`lpmbMvq~fmmQm-|9R3O1) zv`?bGa%X@SdJc!)sA*cpz$fyPwh1w0lvUDp0enxqW}!bbFpTSssIj9dZ%AXBf5OXA zJgfPMPC}7y>4psA_VCEEx^Dwgh^|-i&f@D;BDdv1lYRGZ=I8vKGC|(y0h^7#>?OR} z#)7Bie`2m!Y?xbNJy^eolAn*;M}D?yV~wDo6_@;N)$`!8y2B_v|EsSr4lP9~taaXE z6m{BY6i~b_?fALt)b&hK*{EOfm*A=|E>-$? z@nCQV82F#+XQ|_*u?6SWaS0cHQ9@oz!G`8F4lH8sX5O28b{qA#N$T4cw!Aej4%8kz*jy}m1aqkxKHzvok256}0 zCTh~)OMs&_Jfue~$Fg-nEQ7!<)p%M{OSN_n%47C|Yq5i3)<7W|)Rm~zm5G-?s@zX) z+t3u%fQdQc?uA6Sdi3MYe5x@jVC@$;Q)6ncEYIe?_5|gC_0moUeZegx>@%yXs?&}K zvaCKtEg$Lj1M)tE5z~Hw$2(2SzI+wo5&id#;O~3L>xWXdHH6~{jHlAxwU}lURAOdI z_7t@DMoSNMB<~A}zkDDnXyJN!g-Tu6I4j}uHmS5XjmQH+osQErM+l1nRSRsgc-hf0 zkUy%`mq!GI zvf8^kZIqe$6gvO?jPFu2H-=Bp^_R_xoGY0AU>> zz}|<_2xh}VExU11EP|fnzN2_?FsnD%ZDn%jhPHchq22g>XJPzz>zRI13&>9k$b8oq0-?^?g#g_1`5G5ydDo`?KVIk6h<+2l_| zE44O@AckFI3f*p#qdY%Z{%I!R|E&W9j0Rqm?5lk4w#80SvpJ-vwPDwUp4=^ptl?)7 z2;ub*bZjHMlXbSJ3`ojZ!PcwT?LCwBN?(zFuA$0K)ZWDiP%lDvH8c|s{K761k}`eH zIBpb?rd@F^s>Oy|=tc3qYRN&4^kU^h&*GVatRP6(@H~*Zb5T)5lxDqtw`&7O^{$pm z$2opaAm~;PbUQD&F)JnTVZdom@;lku+z6hUB}J4DUwM9Fz-#Fj_KAw;Hon_cBte90 z2LN*7XH76~@&7=6!X5t`8#96b`2!zu2R$C7mHhw;ic%N|bWO@&B|bXK8(?VhDWmG) zEgQ4CVl@Vcru)8vdZ^5>#XAHydG&$f(KEK|5=}p?^2ovL4{d`Nma47qJPQ`@ruV-R#HG_Q3ECyb? zZ~{mewUU&j2Uipi^ARD9Wm401E(aY}Djttj=|02@^UpnQd=d^l@om(Ss~S6t*Vy03 z91wnOeV3lqkPP26!%E@38^%`tVbCEV27^C45$#F5UvC`0__dvmbm6ds91&2tuythTsU{h4SA z4Z$m}@_O4Y)HvdLVfV%`djRmZcd<0ji`Ku8DoHYWCeG{R<{`JCO2Y{e^Y02#0ikx0 zSq=gp`c)q~g!iG19rxdL(5ZN^|E_*nmw|nDI13F$d9pRg^odLUc1Z{Embu#%-&nt0c@f+*Gkc?Y+zUe%7{pkd+Tx$~$qCF7Qc~0w2SdcT7RhhLUYAn8UpRR}&Z4c|;^T`a za--A3LIY5E6|Ce1KM6558q8kdsMS64yP=XFy?0ha^e^Tuo$j>ICO6ghq0Z7mLuD%d zrfK>0#wKf((6;!BpqukkYQ}AgUkX-Q7pTLBy1KrsP{?Qhn4I|c^!P~BKSWz4p4PEj zv$3NtP0sB5XOHlnq|fQ4@MxOWO8m4D6AE_vTAD_~*UKcdNd)$)S%^kl2{%l5Rc+@z`qA&V6?71Ix6CGwMV@@VE> z&Oy3d!>&6W&5~VrIwy7yl~@c7WO?W00ntxQoo6b#ol;m|GVr%K-;d56$b1tH0nt0~ zaTQG?M`b$RI~(!-!9eZq&Maq(`*ur9CzBIx>6!cwY3CIcRK5?W@XXmS+IYF}N%qm? z>3zo&qMRI6J{KfZX_S-{QgCHgN{-HOXp0n_c`7hoJ(H>M>_HzsyOAH7akj5 z@N5@Z9=A8HOb}ckUg}*wb|fy!abgP%itW&fLq{{GPEm<5kBxQ5@Ry!uv(BU_I~|+P zHe7lScs<)Ya_uUd+V4~(*NfzkNCX3yuA1DHf1G{n*|yv6D?arBt6PD1Cc}qxsq~HvTf^BkNkWJR* zcG|4#?{`yfCKi|yzjW)h4=;`F-1dW?HDriWYAh7P>;r7VHPL(u-Qxa8j@A|`hl8qt)N!KYrsjTmQF1d%rG={R z_lSOX3sei%VdD7N){CQmVK*4$DDHmAwITS4|EZ%IP+mur`-kNZ-Oe8kJRe@y$-=@> zx}ab?$=rD`QJ&~Zt`pOe=YrYP*5P)#z$uzsGx!zu6j8C8vqu}bH z`KoW5bZLcwgZ<~XUr0uj*Jc6AQ|We>(3gFBJKP^kEbTDXXue=}txm$&O@gUMi?O%d zaHxH>J=J6B+<{h#QidF%c7FdUK1rveo+{>XpowO${`j1I_%|nGb+#wPI~G6bURz2< zMtW99*Pvlc#pAG=bgZWAoBU%g4V;fzH-+BpS*U?m!&y)aoeH_2*0#3H65TJs?L#vMqA!v= zN1$a&Wy5r_6r@rLEjaTp#A$M_PQ!_7KIy9!QLUm;R;ll+YZ`M zXgew14>l|fI$<|LC|znqo>XSEW4z!asZ?EOj#U@Kf}@YTcKZrD2QLHs!NQPuLN{EQ zerzb5PIqy!uq~^rK-6x|>&E7t=u;;|tw*9=UaP)r7;d+{w%L>YC3W2=apQ2?p$rSA zS^BPO4od%!W_h%MYF;Ap9a>`U5mjRiDcr+;3riXk${!0PjHD$L9^DvTx;1Uq z+pyhE?ZHJB6EgYff644@qZV1sM%Rik;MTtlHl?L?4+?=;>Qbux6$cW_E7Yi1KAvD&5DmP3AwL0j}J+3)55W7-Jwb}Oy`{88_j z9y@ysTC3U4iVg-Nb>5?+vm*zN!;RLNjIt~Hy_(c24lei(q=kehAm#XQGmiu75&y44 z-!i(gV;s&mErbEg)7+gRYj`h%haik$|V(bw+1^(LU(3Qe;EqP=EEnj9aDS<&vJmRX>V z*z9gUGm->})}xQ+GI~CaFRhl`)Brj%>HTg+B-hq8McU9^+vfJkLs_hwz~69GWM+8g zii&QBtm`|Pg6k(?KBalNi{Ij7`3)M^W8-rlUpTfek3Rd0BmP<5QR5YXg&lO&vvU;x zpnWbkKWbJZ}JrGua;@{z;q+0mO37z0xp3Snwfv)Wt2l zwS#s-m+NCry>t3q0VkKOEEyv&D~0%b`hUzlojrquPEn&}u+E|A_mE{H;q;Y|bLi6Z z?c+9uuI{MY!HJH#g~H?C)Elq%x-Z$41x|0?g*NXcAv1?m91@6Z^&GoIN9woVe7UEa zm%>@=8-=VYt`)pHwMd18pDq#4%az6Z`R@A%EClAf`abPo-Fg>s|1A{fT5Uagh6VJD zRVSYcHaeYx;G8U?p^*~hpm*xC9_P)QTZe)hTJm+GmmJA+&z_$cCZ>`V(Fo2JE!s8y zY@CZ}e71Z>99AZ*9Fx*~Wh30vFU!-~oDPi`O?|xykB3RuQM4TjoXrfri!@mjn`ybWZd;UO$O4|*lWxMx^8OJ*u4qLd; zv*-{lOBYm^B*^7-zkX0FT67y;S+<=FZN%(szL^bebus%?z4<6~@hKV6dPKLSmlp|m zh-&=nIX@@LASa+BDreNEzCAY*UA&70LJA*Z@* z!}0+c7EEfnTaUr9WPjG&S4Y`8Z z%1^n{T4lSKPgtI%mR5W13Cu(?E;XksHSxsD*X&`ehk98iyj(}3z`J=c)idfonCIY) zUBkk`GrIFjokvp1-YL`W-`1FFu|JE&5Z%2q=#a%eB8P+OyLVcxJc7#k%3Xr}9dfa& zgay8G{MUhpo_RN zV&>)Cx$DSfj)Y6qCDd&){C+cEU0Z&V`8sqF^9_KsODmz;Lmpl365|%G)+HFmM?qf0@(pd6O+XI)Ve0ljUe2}qw^#VV zx32OM_)-d4CuOJh$Hx4>)&!CxqW!N5B5II(u%+}&>UuQ{-ee^3e(f>aaP#TwCcR`w z^bQ3B&_!wwn&s;;CH~Au^2}|COQzE((MJjiq5J4HXSb{){ZSMO26_|HR}SwN zyM4t+buig8${lfoo8{E=^$2O|dkVCief^zx=xMqlw|Ybe)_m@|`le=zz#VKFPTXV9 z9NKh`mpy2-=YTOv`d>G}|9QrEgXsP%W3&G#&yCB-*4iH%)`e|+h z)RTv425$P?Iwtm2GRyXHgH$g#K3~@i{ib80&Q@I_3%11iE7h}cAt}Oh{$YsxkFDDO z9gADv4%9R4zE%a4_F$5LowX<7LpmH@0HSw2mHN#N2TJU)k9lNO~B}3%=4D z0gDinGX%D}`F-~we>e>XUX zA8+F&-EAf!e645-I<*2(VM;1ZtUl8(qCD;d{>6AMar)&gn>~pyq-%=G5N|8fb=!ui zY#?P90HT6qShrodf-k&Kf@-cREHGHpZ?|D=3%9*g;vgu&^;ds`dS9fv-!ELzp6fx$ z?Yn$me72;ORH`3t9xaMrxT&eACQ)dBT+={SiY-$~jrr>*-KHGhn_M(J;d?dOtrSF@ z{jTrLF)0(DQH7Gfxradg&@{3(RG4z916TKhd%=>mUkAl;%O(G?{2I3&@WHPmBmYZq zQFjYP^a~VuQbrPckku*-4jM9^jM60w5QJ9i8TqWOxeQ%uu#7BF&C>J`XKM_$i`!a4 zwh0!Idxw~Y8*_!X>qJ#kZw$p~TM1J&56jc2B$)+jm;+U?=KAO|v z%8$t!U^KrfDv3s&0^-zO-ZA;C%3;nf1NrjXL2@Eu49$hsbJ#l<5$EApSG&UEeR&1? zv9WHFlSnE}Ait`qtaH)23X!lJ*GQ?UW^{qs&Ep~xn`V{wQC~mtz)pN?PDX)sLtt5^ zQ{-2J(sa+!^bajFB6G99QU;%=U}+#&HVLnW`_#2pO+qDXeU5UPc)QuVxZu zsmJ;5TZtr#hFhIukciE=Ix5hN(^a@*F?kuNJ|g7!8EGdC&SGMBe^|E2ZKgl^-C$kF zDo^Y-v2Cbn6dL#p|HFQ0G2=aMqd{8w&OBw}S$necWcI*<`OPQo0}3@)sJ?b(RSu% z;pjNSaQ?KBKLAXFfei!m(Ldr;FG6>1dc> z&B8Fxq?Xb`wWiWp`?O?7gY@KAT*9i2QBf($1^vlwj(zQ|*7|b8L$pfPT$(z@Qq3W4 zN9zR=vaNlSoR%1m}<(l_m_BwG`WMxk(p zlpOx3bC6Oz7EN7Ie>L_+W~yyBOGC<_Z%S}8tt!V8BNdJ`^K*sT)^frtb7!Yar^u&X zCcho{w)0Md(gUA?vg+;0C8ENQX%}W)=B-b<&7YrhnkpTCeDg-D$dp&SeWRP~^y7uy z%_%D$4Jiw!ZBwGz+v1>uq$M@f&DRJZ({&U`m6t)3DX@xxmoD=C`}+ib=ytC&vPzp>OtwQd|!{fy2!bJ09dTub6Q52P76j;3^ciU6aJ}b^c5S-yJ_bR_D-T^$Lv{)h7!z6Qh1s{4FszJIcTohz91 zt?b#JLXUa7>9)BAQ9NX4t?jpRR%A^AX3gn)FTIn@xZ$kb)@vmico~Wb`~_R<$S3p; zZzp{b<n03P1P@E!l{j=50W^8`hU4uqW`OKPuwr@00 z+`c-d_Jpp6A)j#4!*bx#?xogE%saUnm47-r6x{nB1KlnyPWNr67dd1kn~ayAtZhg zFOF)%W==mQIDR#16!AYi=PDic>v8`-JH!8xuSbazj+zQaS~1pYX(ygRbzg@}m!J|d z-6&*lhW?DSFLxh82~s-cpzO@o-|Mz}F$&84Nkk_Vpc50$TZ@|ipp$;TBJU^r1;Bs0 znpvsDjz_ZZe}+x?Toc2hz!unNaJ6P5c=`h4VPUP0`M4wXTp9x4p@|b zQ0D)=Ky|hO7jiOS(e~gRQd00~Z6e~&0HB}x@Ub;=2A22Fa@8AaXey4+Fw%L%3_>rn zxTl&Y#pb4tKxj3o5k1Y$~k38S%Krt6!4G1P2EoWkwj&ct# zGZ0p`G(0xSTC638OA>D0YfhgNLu3*GQxq@OnU52YCk0l+b|332yE2o=c1g)cV-Tpi z7j%y4nA{PD8PF&g>+HXB$wMx%`sQPxk2{sTU%B)mN!hpFEfm)g%3dciTe!~<%4({% zvfYxp@K2cPJO46V{818rwEaJ-2hSk>Jze?(`A9ImEf*CEq9 zjplFNbsd(13?iYTmTH{Y(9AwH2HB0r5W>5SFl=IVGSVpPNtA*JJ*FQavBH2Okpj2a z*EU9dYG+T`Hqms~bu-bhTVRa)s9zCqkK77C9}Zf+&_9ZnFg4xJZWxhvYc;`MG)K6N z#K0ZWHFhwX>rI_#&jrq~ZJ25s5S;mzH4~TDQNm7co`LJP&chcUjO_oiwD?^O1>Mm9 zRR?8mqPT?=Gy-6t3GZRgj#5D!|A7RHs?0VOMHX#57{x|^*}8R~{Q3H)kCf8ZeW{GMFR20a?l z0JmlY_@f{yYa&}I^>aVT&N2+-kR*BwsIOiHWJr|a`TDDdCG76fw1rXr-zU~Dh7m`$ z$Apt1GtGfxlma(|$EFnD$6^p#>ZXX*z>B+lbK>sD1?nHQ22AQA$-cI5{m%B|bhrIXU@sR!)w= zt6`V|f9ShkC_!XtQfa5BWJ6n)N#iY&-OoFhVU0lYvu9@=7spDbmz?Lm1RLMDaeQ#N zy{)aGKib*6E5||JetPIx;VH(R=5*@UC_>zEBal-QPI*BcKTLCvRcu?mXCq>ba0qI zgvVvmUt-9kmHdSw#%+Qcw`f25YG#P#!lIx-=1yfv*&W3MphC7-kvfdOa_&=`(E;xGYY8 z`}$xL`+_b>-VWEjlBd$OdH;5+h_di44}?F%gqOHbG9Sk<8rHlRTkp+;jF_@T| z4PF@#^z!&vYzPwOlS9AW_mJzE(SNzFc{q3Q7-M~4f8AJ5Nyca5@kFrtwk|h0j(7$R zTZYkv#ffUG&XRVELbI-szRGZ;Ll_0C8$CY!6c&Mj`+KvKIDE(zwL~No?nx8wXjOQA z+;KkhVKqnR=l5R2?G@iBC5zJ#Ny{x8GPakI1nNOKrHJc=Q1V=WE%=plk$XdM^^80$ z0+2+2b^9;CO7Mhk3%EO@VK06x*W=nun@M_-6rCeaPlaKrEPW|u(>Pj)pgyBoBqhpe z{+suxS2T(foHAnOteTopm%?k=YuD~c9Cn!-%76)aUVeUq{Pfw1Yu-LS2Rf(gWI2+$ z7W?=Iz~y_)U)l_-FJw#k(OOStRfTew6gV#GiFtTmEZj_$>GT&Q<(@GC`1K_8jN1(G zJDxrO_@|}^#|IO^K@-k1&N?j(s1}|pTv-~;C=gv9C+>Adz-q^d?=CkdD*3q!v=!XR z&U_!Q;ONh%t9Wi|$dD)+al)={Ik%}vW$FzHM@u4x+07jwt9@p!QB_+nKb=)6p=A{Q zQ_PninTWkZdv3IFrC`a%m11gYY9P39F+NPdO8=BYU|57CgQ(ZF6$NuesVLL!$< zuzi>0_mEAia08p(;yFAd+#fPr+Jj@S&_4TcxCDP3vbP=W%!(e060|mMf=R&!rRi^| zUgw7oA5PCmeZpkZI?Z0D5tX~2FIf_(C}Py5?a;d*cr`N8;7K&5@Kr~_o*Icgm zhs#NJf52DdzZG)8Lhp)+cGP_*z?kQqeRKWMIV++IWh7{Jri_dyspYlEd*q&yL+xo7p1o=8k)SI7XED2f<}A(r z-rh!@!J>WXQXLeky~0qaI)=s+iMP1E8$UrV!I_wBbX+-*6w^x$0}_WNzWl0z@Aq*m|ke!HPVoz)YIAg@uS(pJF41_ z)*ThNe!}(fso+Kxi z&*l+-@Q;4AmCoUeSx0VdqmBfa&k-?(1{N99(S7*ahTVJYsu7azpy5+88~U>WELRTo zA?&I$cWqK~=xtxe53+x;3wLU6_c`qA- z%{P5dW04;)Lrl-k&OU91=F>Hv8~-xB@P*2wAx-O5vO=`TleYGDN{$=`QIawi6=hY` zcDh1?>L_nf(eaD}qB=<&&6eZ6GBjN$mL}_``=xn|n$oFH%vEp57dF~GCm$K34&$(znx!fGd>u;b`Ji$5Qe&+_-RlB?bFKx0aepG@Gb#VW_;x&ErJU%x&YB_T^0 zJAxHwuG&OO!6R*0v7JY{hMrs{5Z$ASLOF~1qfj1un-q_!U7d)ghi_szxRDYYtFKSk4z+M9q*HwP@}*BG*Jduka6%-UW)#(J7>9*G=D*B0L>y}YWw0Kgoa24neG$i%Sb#`h^WU##*0}$WK32)5a z9K&3kzN=%Ag$Qo&YsFv4j~e<-C^8QC3kvm)WRN9kKTy@;^r1J`6$;qdyP&x3uhv}4p4+V@li%uD_T6E7!ca2v zEipPF%in{Cp}LHVrmUGcetVAYrZeYyRMEGjBeqa88~WD-?MH47?hEB&7=RP%?%xZw zTUl8-B)m!6X)Zo5iQR{sTmQo`{wgEC8iU%nlYI+n`8S?fff*-0dsfSHY;kmDIlaEF zj_Y!}qR8C4xgNTeubDYHexe5}3`z&JotLZ)+Oy570+^&CAQE)4ePr-U*DiE=BLaDC zL|dEsgcc*0DLC@np!Ui@{#;*p)$7-<-OZv!oktwT-tX2Itxu5WW~XG7m)5zp?@n(= zo>fnKIslsKkxI&Okx<4GBC__e6axMgVl0}JVxDUY@&l(6FEkd763c(;geAr>TKPf17e)g z8txq-LE){}Ce#`E-+nnI_;uoYw}ipBy7*HUWSm5i?3H}axqv3fEy7qjhPn#7GF_Rq zqZfT4J_*N?i$6|Hjd&XAv4>t*~>edpD0bMQ>G+qUuQe`yE9w_cN}pG@glLXLFBSY95J?pTD8qsdhdl zpG-eHs*uK0H<13?fz&<^-93eyQL`Wil-LJ&_%bZbG8(fPBd)D4=8t?(hoU4IyEC)1 z1)I~g6*Z1-n%qlEYjae)VCcHFb!gvhxsF0-(ZOqb8O2Mj>W(t3$n9k6D6QLPW@e_} zUR!&%I?jjfJwtjx^A^KPOS6rCJ3Go_H)8py&$p&1<%qTg2yI1NC6-+T=dq*|C=_aJ z?a}c5?zIE?4RB|a%Mvr$+M&BTzW?fNC{&Z5HhXTjA{k=O!F!P(F__ILdaa*_{U2WO zJqd+0<$D=Q?!k6(&+Mm{+~@=3=4zw7)zowY-BkD@UQv4Lns`e4^fBKI`7ulik3{B* z7~!JK7#3Y8X<7H~&629b+VN9k1>S1sk>l}tg5xX46FSGxtP;B0HbNZ3A<2<_IE-T# zp_fKJaPD`MgC*&>=R#n|&}#<~1@b|mrUUU$e?hcJw}{jkOCP(R8YF=i3JS$|%qi>B zZBdMW&301w{Z+)`#~nKMW}f&U`c`QqU;`O*W;nwdHlSQ?Tv?jkiFk|)Au*bGSf2<% z59C6xoqirlVm?cW20c&e5u!amKkpujlzwzDo|RF9ho$!IkM#hAD3lA4_ePc7t!SFC zWePB3l_zg~o}XlU0#i;F`et?~>NOpr`zyDfP|8UYk6HMa?lRjOdq23nX4fuL3g)|- zb#JnB54h_|y{M-kz`O}6b2=CT!kK((vuIq@b%?oz(9^Uwi2Sr&9;w;oqJx;YmILgj zUK-+0)ndLMK8XlYG8&)(tnW=5@j(*vNw|Nry_>-^kPiZjxO*k1Vzl2*hREdoRx~_6 zV#-4-t~jhujl3j&#$!kTgny?(Tm@-`V_+83`)cT2 z>0>|s1%84DIIs(o5(r9P!A;uC$dSWw$6`fM?;fmTpAlAOp;)9gkg>yPWG{EExv_`1 zepAjIwb|uO7{&-Tp}I(JnySvTvOX!CjG=OYOFMmp?GpXN2{UYR!VNWde`))G+@ec- zkLn}$duBdY6XRE0J+nQ?Zn1SZH#Qsc3)awImIA9z2{Jp%z!>^P{*@7{Xj`Q1Hlqj9 zzK(klAliWkB4aGE48!w&6e2n#KH|g#DYr z*R(aP0;Y&JZ!Gb_b?QO{?r~*W`(-e1+r7<*bV{uQ2qjS-+^fQGL{nnLb*lkx5K)n> z!3|1m@tHALkB<|$&c|&aSuA|umzGgyw!xJU5IavPw<_W%aNMehDdj-vwHBvm4G;yHb46psh1N9Q)A2dfs4_EnQ2}Sm&77u5LDD|Nj%H^y)Nc(iS8TmHt?;#s$5mL3+g-bCvJ*6tcnf)IlyE9_q59Q_ zkO~>*h_}=*Gq9e=#3k8(kbL>R=(Zsdg;N=s6ERh2ah|vKCe-341RwP;@B%`tKBgfk$TRq$`+PW4gT}P_!+dt!xzkw5gnq2KWzC1@OdkmhAnLm&TquhT(S1>L z%*58d3hk)*2xNwO{TT_rGW=4^^>r(+kyFH@+mQ$iryzwLzw3i2O)CM)w#YwYCwu>> z?Z7E!?$(gtu_Gw4Zk&ey!fV(T&}8x?5rQSi2h8?dQ8F%A02pMqxPV+@*)e#i-*Ed7 zwZ%0|SD}QO`Cju$1dC8?w20Y_035_}h~pg|=O|~HIRz8KL=EWxQaYZ3yRAaFBl)V% z5C})bC_hCk9v3Xw`EZfuBLz+`DAeVcVHVt-+pQ)I|JmhNF%oAl9e|PI+U~1qFb*RR z?ZnybTf}a?NO6%YM-m_Q#rFIV7#l?Q>uArusAri}&*{uqi>5!MT1-S(NSI!$IXyme zu-*!jbG*eLqQFGe?F`!!2GdbCfo0h#XN0hk`RR?tyD?{; zlTxrR?Wj9f>a?oD^VMp*;vUC5fGjFh_ojk| z1AXie45Qkq+$qTtbP;&Um)&Qa^1OcqK5z!-{EFWUHE5FHK>B36#XQ%1Y>cGip3 zKJ#^35b#2@0;R=CiibMMb8gd{04+$@YzfJGXjfx3&Kyn?q#%{acO(c<;F8}qc8CSI zGZ3~pZAR`qf+Ylz>wkKAB*hqe1MrK>6WXbn4|-+CTvCDn^5sJg!`*Fs2iasW+!emp zcRv{DaV$t=)D^fgtoIrWkRBx?iBXnnm#$h<2l=Y$s$YE@Evexj!q$ex%B$tB7+0~8 zJS!_IHst4(WZ+FCbWqGweD2mfbUo{&ZnT{0t$hxz6Ott!pvlS8q5PPr3`t4QQnSLZn zKQAlh=3eks42d52$o$`UUC$i)0M@oREa}+1^Esm&!J2)w{U$+nrgvc&^@es#(jjr1 z?_s(^?!jwzQ;wfD`t*_keTVxz;9wzwwbd+-sZ z%arfX;%dDR@_XR=0`?lzgex018hXXHe{JY`1c;$8ngR=t;5o|W_~phQX{BSHDAS1Az9ig@Fon&`k6yVE=7 zbQ4n;7?nD#gaUnTkuPpSZQF`SNB@FQk*+I|7?P8&dN3l{7&7d#5GhKG1ad&4ZB0>I z(8P|hAcWP#ihck<2IRTB3CSKWAZbR8g~LxgE+qh9c()TtAU#lM49IvUlQTR(k;c@qi1;~FoXC-BAu-U?Zs6-r2a2n|8j z;|NrW50n;R{vsu=ToD@nCzf-s9IiHD6#tf z3DaK}FMCRzh{UdNWiEQf5;)&oZT6=kfvF0&Qh|K~91op&b3qicr>963fD7L9Z*caG zLY-wFWq@5B?D-RGXWt zbMNrjLH+a0cVjMngvp? z$$G_8{uiF>%6!s3j+I=dmv$iqDP)Ne(c`PBvjed>7e*Dra{yzQ4VHi4U7hPI?LwQtH@Q(I*8{NprFO%Dgjk_a1PTLoO(w3OkmsKc?hd&XF+#+iQ&Wgx-Lj!$)YNMYy_d>MwtAq^h*E^wH=9G@=Av zy?Ui!Z~t>qVrS#Z}meB_8#SXkJH z>a47+z1myP)Iro(b7Fkq1IYwrX^4XZ5r8Hb#M90YaJuFph=aLX?qpWi(C~SEOs|}( z{_&?%=Dmeu#WYpWTJ(8+b$QW_=}2kie6`2|o4oIZ7uUb#iZP_`+$-Mer6{`8kOzWM z!H9<)l+-1ACf-Kdu@E6()pz6N`?5fmNUQ!T0dNuCHo8e_w3&<->zl;xeKVlVM}uQUh9!BeD~O? z7`aOC?Mw0)@|W=^+uIEtK;DwNj~|7*d1Y#2^7CO=;j;ec#1!KKC-bHCpdoZhQhFPu zx#Z@6e#x)jCH%>{;|dF%-%QulF;ts4}V!KoTw5aqKNU$ zT2&zq>eh;Pv19n6!31I6Q}HY#)Zk8ot0*V$?=Q{mdg9=@*T5M^#>O%zE~phcy~?}X z)!Hhs+>&Wj|Dm8GPV8U@*lqmSbh`zOz^7t(EknB#(9V4=x=DU=`76r{Y6Qea7Sbot z-lo+D0`&NF!+W{t-V;$AQB9L;*9w}EKFun#oleA*HgK1h+)&FiU@sb;*+4e>6X;eY zk3tpVt76D3j7T8nGM4r}pUvVu4ET8@PC)0j{bogGh6@i&L z>c4#HL`O_po)#gLJ-79Ma=kY_|D>MLw#%lbAM!=4yYkS)0b7^ns-43Qu%}(jyJx8p zAn-_-fre2~my)>vo<4IpkWn0%-zLZM@%_(z*!s_=(m#WEkqO!1_ARZ@2#;m*7vv-_Yi-4G%>0CHf2lIQhS``z`xKk_I zb7^5F(M(%g+afCPi`er3Q*!P<9sG51D?O7CRu-B+rUB=(T^e!H1A;HUF09dKEXeNG8M|h=Mm>M+K^Ql?A;8gxGidD!rM#om|vH_Z_-} zX8vTXMIUF6!PtOzJBwbx6}0F0__c|aFBQSu=A-d*n`0h9EhxQ~&#f7r%O`w5#HH33 z93d6Nh2W)WT+W8_cu9X&Nr^jFGd3^J4tuP-4*)%sUV0H+q6+ESsxv&YEb^jfxc44{ zQX~R0`e+-)8&Gm2Ob~^YIKf<$ zcU|!d>%qEd=fQ7{}$3 zL3+NgAM999=2A9DhWEB>o9}wCv&0;jhoiwAWXdY)5yMZIqMnb$Q*{GZSdeLIyth0= zu6;i8?uj<0{B7IcAN)EPw>qNll1ofcH+km#dA)NgDt!*{Tz!2DbStw`{VmUQdfGel ztV-r8w3k0GPNh3r4-5`QdhO;2b1okgg@!W^M%;YJ%YojnqHb@AA02=7Xlq7ECI>SC zRvE*X7jcK}3xi+9v`jBAGU^nttM|sqOa4nLDk@301xGJfb)@-E!(*DbuZkI}F+Pr7_RVC0A%UxIwNzKGktz)ai4VGC#O zH-uQU;ZJvRU+Kw3FhY7xmi5j4!Zt=Oz1G^1IG|3Ond`0cdT+-(ACN4}N;26$c3-Yb zsWQnmf|TNNj*RZSaAnZbUvZ)grww!?E?r-Z^q0vAFpRA?=*h>#%;zia?d3P`kZvzX zN-C2^l@063kdUJvmC>K~Cxbl4z_kT9nHxKq(MH%=$lNRK56rM)OYa?!jfjnn^{%9>yTZ`UoD&?+ z+nd35F}G$n=JU7uM15A$nY=(Nj%&s6f5;&?Bg75jtc=pn_OBLhjM0OP2!9{??rVtg za*QLCl9uai37_cVJc5kWbT{+1ZpbPWY;AL_hTC}iVLB>Gi;2r!nh1vKtf44z6!0x7 z!qhKcU6>vogI%~nuefg}-?QzquI{@bC0}0FtG(iq;J@3gM53VGigx9(Eam)|Z&x2- zkJ12|5Q5kguGfLf*Adi!QidaQ2`R8#jzd2lfEX!7FI;guz=!*Te&F3%|ED{RO#M%7 zH3~+#P|y^r|LvDhDC}xs%Uk4*zr>FVz+YU>Nw%>R7uV4oh!(cj4|?mbcL>HJ6R(+~ z;%@^3u@u+-hv z$#GCDc(MaypjX=3DR@q~>6NKZX%JMA0(zbhVMFg0M~&SuvnOH%3Q_It&ez-3)zu?Z zwd~%j6*%P8*VKI4CuH-X^_k8cWY&*K>O-Uu|I_%R2w9v$0IvjB0bVA4rRc^RQ?sYS zqS-#~QRBf+$VX-mNa&W2CunsAS`0z~Y8@xq0P&CNL0Lft5Ha{m@0}S;ux(t9Lq+&aM^CzQZqbN(o`QO2qsqd>jTJ~A>Dl&w zy}>0+r~4+XK9p^pep+~n-03fCyAeQQvJa0q$e%#iUh0CB;Y|S{z`ipwpLkP*um=4N!mCFcCZ%9IPR?$()vb8lWcqhR&@}wl=kqo{g zUZvAb0cW0%d@xf?vMD2hvbyfGlSpZU*69lYG3j1x&p=9Knixibt&<(G~cs|NtR_KFNLJ)k+V?=8T6>GFKO3F zWdE8(5bgyvME66OYdtP3GG26u0F3w-iL|cKXt*vTYMn%ekn9urte41oHT<~f-_)@E zAJp(ac2O_jYDNqz(3Uba{1f5!#US)O?^vhy&lwol=c=8JK?fWGg00Cwj}`!u!ni3i zFVdDT>#z9uHn)yXQpOwyQl)E}Pp+;@1Idy(V&3dG3#C6wJg@Hr+yoc|p=CKZm0jY| zUQi;o^Z~GJseT#`A#B!9m}2!+OAI?(KZZt8@3`hh$Eq83(BqgB0qW2`JVez4!G!as zSdQaAi3zw)3ou?_=uBX@1h~#T(oKW*0CZ~cOeezFg1saDf?aK6V$rxx?KE(K_=bUF z(GT5%Gv42fG~}Sw_`8c9D?)=GuYezmYx{zW?cTR$P+)LktkCa7=+*!FMafw(SL}RU zld`Xq#iJd!6aq`d-gXX?^r)a`X2`U;;_l`H9t}WGojiO*6Etz46x@E)=K{^bf*QwixJPmc_9jXt^I_QI|6* zD(#hh{LJCGXJ)!5tnaE_`+n-IOqI|R0ba5sLysL=87VpqO5>rsQ_GaDm$JYNMvrB6 zh2brvBLg%iDE2QrUL!3p#~*S-SX0#NW#Hgf{pF{?oCsXbA@THQkU%W>r`*<~lN1CA zeAf~|sJ{n^jTc=HiPw-I@$O$h;(y_yUQpmcB!1$Z-El?^*i0Vc`GbyD)ghkQY+_EL zTZP)+mZ|R;mk@y<GNnZCjOX&@VYm(CB~2pu8HyVG2RiRmPmLh-LWszWVKQIy8WhTXwV#5- zCww~aBjp7p(!&(knjft)bqG2^i>&1b#;lzS`H6D~GO&-e3*&zx;S8B@LAtiM%wp}F z$WPp`RNOJZ(DkX|CFpjuk?1l@mA4p!9{)HCBz6b1Cp zKDV%IpWEqDb4D&-p~lQ2i$9x)B9ALnGMF{%mJlpw`Q^pA}$lELc0qr>D_*Kw{ zK!KOtc@15}tPY(wT1$384w$dUtiiZ(vj9J3(#D8{1o!O6E^8ToZaOj;1rc7zsc{z! zbwZc(B(67vBdQQj*ydTw*|>;VfM5E28$55_Iac#A+$0@Oar)oCK@#R$KN4mc{EgP^ z+PM}(a9HS3JiGb`>%KwaeA3T2Z{&ra?TCX`8~%d}X|;O_jsNxy;)*+ex}sS??0sEN z-o3gWa$|$H0nc#i9A6M<0k=}QK}DaRkesK;Zf(YN@}#VLX^^#nd1Cy~)!2r(?Xlu=N4Qv}9?W~ix&)qwat?$pk^*)_u8lOQE_;*!fp6PI=kJ*bDRwixA zYUs-i7(JlQD49L<|8e&w;83sc|G3jpQOR1#zC{ZuLY8c)h$xaIrYs>_QI;^u5+Z9z zw#t@->{;hz$rh6&%V3gavJM7gjG6gA?-}Gc=kxns-|PBa-|zMNUvpij&ig$*@Aq>* z_x-x>`*q*XGvk~Wv{_u-0}``Ao?BU%>QI+fZE@n+-@SfxNhO5om)?F|ohC>&Xu$SX zLK3o#XKzo?qz)Mzi|o2JI(R_Zp>A?{J(cNO?O6h;%3v!ixWKhpH6d%e3Ha^^IRi99}bB8bUsu&8E#|;~mI13R2%( z5*XXp*nQ`^QhEY0rH0NZ5jIlu0#!JjrMN#h-Fwc?1FE zExI@Fb|buK&KO9HpTyg4Tpi0`sI$PcA+L8%{ZJE|iF6}N{Ld~XA}tWxa{iQBSgj~G z^RmqLqS0@v2eVr5bSMYeG_gj3IBaOvGuLrswi*mtNwq)Fw_uxv?Mp0>#VRjPlLBaj1wQ#-7hLBU z__rDsD{udy3Q+WR8ED6vMg3!0*DdNFcmA>97tg=0d$CJOLrSG6%u+{C4oi!Sw?*v3 z+_3h%+caNM`SZEi+quNV=2(I6B@!YxL)bueqLf~c)rA*-@&>Tk7rV|t5e(gXH|SlT zMIFqS@!J)t104A$4rg3-Iz{bTQ9a$KDZorzGG{1$ROjN;Tw}!|OGR;i&UDn zfOr4J3Q}=tgURX~Q)5wbUuu-^zSnGd$L1ua#K>{}`P5@};e4W$Zpn37AN(|N9Dt!U4v9__bDXgE<~qQqnzE``!+QR{ne7@-+D;9^F(Q-UMUpE-PCH-&5-jO%@7 ztV{WE@fVhfWdwjL@Zo<)h0V6V$G&l#o%G7Gg-{_1^k_KA%kd`-V|NKiwtZ|{Tmeo< z#QF+{;7N{zw?d+sPfU@rLH15e$_u$NIxV~1Ms%zUoNgFj_6O=TmF|DdxBO^9-L@qO z&BhDv1k590u>!{s0oG~(K~0N>DxyW$wy!tTJn1#Ig2)W&nltux7ITLWc>7KscW~jU9H3R73 zY8o|)Iy8*%jNX)$6^+nyg9f3$SYrQL_lfCZnwN7)1L7kyi|1gsOx6EXQ$H6$_wW}0 zihubw-Ak}@31Y87ufB=ydqEnc)0kC_xpGZEdNA9|4&Boyk`$cCRqr0SeDtl$6HaZ5 z;Xc*2kWiW!7|yrH>$;F_Bixax&lNEF$@eS7^pX|iJc&td6aB^syN4Itrpe>ir^b&r z7&WqS7tCuqQ5-PM3)Anm1n-L?Mh;DJS4!X1iU#$>bK(4oa^=KCJ2}s!hVT^k2d#dA z;h*vMQi)eCwYW7Bn>-UpN}jPUCWNEqPE5~nZ#tj+F;*>$=fI=s*RQ z;C{5o?Cve`H;M045IzM04*Ui4r(0u_+PDocI^C{ngx*<);cY7!Q%o6qYO7ksaLq{r z)oMsze#;yoN4w{IqVI&f|GD8~9MA?JVzmL?!L<~D$G*-KWmrM7g zBG+z3rwc@qbhZ5b+(HZNAmdyBv0~40^NDa`qMY&ysjo?XdF+l$@7)$+GqECaD7ve0 zcKX!4&mNc|k0GK5HhSymtPYR8lFT3uvHVfTddjUL@pOZ3LW+;_gReLO{d;dY!gL~p zEfb8$3ju{*ra3O7>J{=Cr&QzsKn@=-o0W|6?<+!lyW6@_Q8_&%uPw$v4~pin7s$$P z__RLeSMXkpIm%FYUn3^Q+uhbK0)Hrbz^7j^nWA zyWYxLf=yd#n`EnXtMbSag;dXm>&x{%C$)oZ?!_4H$Y=Rj7a??yinX{blGk2g#5m%r zesL4w2QKgFk^p9eXu3TS;eD)wfh$XbTS&jrPCtBsG!~M`Yz+tAIiDK@myEK|9=Ej* z#I$c9_o9C*Crw44-|&68l~K*{I%0|YPFI?*zb4050fE*(gpAVkO(=yPt+Bi+7aoXr zCX9bBN$PSO?bE$>$g-j;@GCcS-&a5J>_}U!r%qQKW%ICii#09TM23sM794YMjmOQj z4~6=O@y~pD5TTSJhm*ug5Iyfm48_oGm-7xUM5v)_x#*kk3jKq=c5w9hzN z_Ao~(185)gw~}&ZWW$oJtD`x~TGno7Vq?kNXl=9! zZK5P?TNp2~94JXda9@Snfa0l_;|~aR4~YNqFfGN;3%=d0=;?6Mo~_MH@QlMP^f8*- zFCiDN_!yv%D}cv>o(}K^?#Y>jwEA%%A$1_o$v!YM(po@+Sg{Eo#{4G?(SC-hYjD zsYX0&RP6Z_b`zx3k3w0;1jeDFvJ5eIfIHlC+8o5)7Y#1GWQpX;!-<9?WxM?m5Gk} zTSUCIxbxm;dG~LZOy6sME9VIsM?jNHEKB5wh}4$xhM8Fk< zfQLS2&=Qu_G9?I#1ll(Gr1c5XrU`t~E>Np4v~Kgk#3YC^vI?Zh2pUFQEz56H5|vVy z9Tu&yck!8ggc&Mt_io7oKXa+cR-h5clS%yKGc`Rw!rQ0hHQ(srvn+(Eq8z=akmsi7 ze)N#Bj;N-{nJ3kc6m?(CGYuRkvSTPlWcIt;0<eXWhBU1Jm<{}B@VRmw@uFf4QF;7({ zXGJu<5EH7sQS5}d$sXy#w7?)Pp+pdnBv$mr--W^Qx^0rNQ`|c2dvg1JH7#-3PO}J} ziQPJD5Yc@x0bbqzEU)J=4WYFeWw);5GuUql5V|fNYPO`2mC#bz%ljBfKvANOvfMP3 zZLrln^~w2+cB^-(Q7!?vBtNv^cJ~}A2=ngXMNsz5(pTdttdgOCTmPIknXHmBbDh|E)CFFBRp~AvJWW7w zPGjy=bYt0Pk>n*oO%X(hUiEcZGD)QDd#4>e4?w(AbU&rwouCZSToQtKYgK@7z?Izv zG_`<)THjLFd1W7yKyUk)r&aQWpeZKP%jeLbyy4dKOmI=d!$B4xY@KTZVXKlg70V(a zL6~8T=k~XFG65RkA=KLqdZGdSX-i!Rbr_tQwd`Fj91G~EsSiK&@yV~Vk2|c%u$@~k zo_h|&7nZTwHi)lQjvrd)xaXGo3OX~iZc4>=dRc=W7-Qh*AG30jrQPCjlwoDfdHVY4V8h9(Pue zKId8}Vk4c?JsGEv8-L*7us8a}Vmhma=;_$K@v;^6*LhBQS9eaH>y^uBTe)?;;Gjmt zb7e$LJfZVE&UiSn$vS4}!BDMy8-#FM89iDn(`9sV@jFK=8$F_@&hTiNZmVThQ$GlT z6u!9FC+yae^7~M^3W|$-vgr0ML&@HwEFuEBYk2Xig}TAISBOe~0pWpdq|jC?T5Lu& zwJ&jCuQEhaf`SZ0twYj_;O_0A2QkI6&j}1_)-I=NjlVPFs0u6y0Zmr zz^=ebIw~}D!0m7s+{ypxu<~&CKBHXzxN{(`7*-OA>i|D~83ZDI+lB}ZkzvJ@(tEA` zU0$<>F|2y}v)U2vE5pHsw{c;NDKLL7!fuWCktt_F{|IUUev|6emgi`MECZClK!xp} zI<$hoZx`TApfP*?kj{W`)PAI`AJ*DRm^S${`I@j)vElq8lLC~&jvNyeKK=k%=3IrU z6zy={=e*0?&rK(xruJNTqB<+9x+T4QF6`Xdj@UOdPk3rU_M#*F_=GmcdHskF#EBpR zVfs!D4{GYw;JZ8!9W~)ZP|bG3#Ww|0j0X&=^M=0)ph+Jjv+w-D(g{K!kgP%5z^Jug z2UaNbTLqQ1=7?3V{rCCNv#Z)hAJ%jSu>L+k5|MMOF^Whu7GN#iffPKJ{DpYiv~zGpVdQM~3mN$?T?fp^To??IeI%@BkAsI`qrLrp zsit|*MU3TKNCaHrUxf$tK$Qb3+OmDSAIT{C@T=%;-?|@375n*}lswvaqQzylP$N4q zE&IJ9eeqS9r?56VnD(6W)bWiKbUqM-H0FwBZI(ADJ5?17<+Ckv-hxNaz`9FT%~=c6YBN`p0CiTb-@4 z%SVWr071R|3t@y)urUGr(c1ZnPv;X?ypg{73wtYSf!DHy0vqN z^fk?wPEDSgsutn@%f}58Ww{_Jsh^Ul>DAN(6&%^nA_7^PjE|}B`9GVgqM7|k+5q}X8La5D%Uh7 zm;#LVI9RM|%m<2RoYTK#B5U)d$(0_|;2c0vk^0oNg`h15D9?!eF3*4vYh4;NnSezu zxw&e8n+H{mSZ_Um?Blh>+23{m-J$EIvaJ6$sG2WS7?P%zS2ife+B?zR;D$)^e;bs3 z0~dDwyc+ zbUn!fEY4{yK`D(4(0G%Tc}30sxwxGk^V!2{L99)nDzlWFe$FvtgrA|Gz zg!{LI!JbesG)=a@B}_#)!0h#^uPzv*hmez6-5pM?ebIBjmH_>Fzdw+KpFlkJzYTix z;cp4E+Xt1f{01*t|KSlx!hmi3$DnIR46L$^o8O7ZU6TsI^5j%xb0%c z7kP!`-Z($9PIwvnu$#0GI_8Uk>xU!HmhOjL;pxybrSm$d`M@A$;ZoC?#bk>)^Q5ET_gkc8l)tt@|o0cM4iwk4!!&3+DKpVgXLB zJyzhiXS0cTX!GUnREEp@v1cwI3CFm$S|2?b_(B)+jGs>h{?luQ(A9=OTs0^2s)nRz zm%hkv>W7_MVq1U71FNt`ORwqZYBuEEfFE>VTqConf4&yhY((FY-g{XAwA`C~a!`Od z3d<$A%>Eb@#^l(-6tG@O$o-x($6g9=dk#A3g1$nm2v9k;|3c-c2T!aio$9@-SM%Fe zc-=0DG)#QgSW4(mXe;(w z^B9$MD_WZ+GC~F%Btz>3pyk>@yStnQoXrSb``WBSVl#_1uiIDLCVw(1%h#P+qMHNB z;%f-gAVsAAyLN9@L~WKV!stb#Yg7=w7XGKVTg`GZ6~t*sfkZyBc#wrVc+wI=iYUDZ zUyU;s;Z3jq?0V8%LmDUmU{PrhBJc<6(8M0@RlnzWl~GsTd*{faPrr{I&0OSf&)H5cHEC*_niZi!s zE355b>y(V>P0s2x)GIqyoCitDI)0)glV zIKNX^41dQyg%qzc`x*xiJ;o^;tG4DO9nFU z7^)emrSbS`X%4&w+o8yhbP3~80V)=`W;UQ{d+kF#17X+Sk!G*ZZ=?aa>4Rs6PO?78 zB&RBKa=3TdAqly~bmPC6)y%azMKK6mbL$0XkMI`~imgMG<@qBW?|+;viR50SB<6S9 zp6nhjaviu6mQwW#DkAYHyNXVUQZOM#CwCtC9*@w97JBIQI4|4mgvB!;)wb(4Zn{Z! zGN>ktgc3O&cO+A>XJYuM*Tf{bti22r1mr#Q`{O}^+2VlLjo{PhW05x}CZE2Aik66L zofs+B8Yaa7a==UybER&#*4%SI@bRFph-{Syy}mx!SGRB;;Yrmu>bCc|UG%LB-5PUN z0ZPi-!o4I-eEO_Kc6(H3I(@M}LX5%IN+>c2#aH6d0k|(P{5?gwQc$^ zO3&*(8T~)HBGGtBZRMbqA7^8`S!@Sut^79j%jTXQq>MX;ZqhYZnoVsZte>iuTUE{ON3cPHo zwcR5;BN`*>9bRUY-Rdb)|1hD7G+I38KHlmfhl~BrsixX1sILWntRX@7!iOxxZQO1# zK(Z)z{i>QDV!x!(tC*%Ha_Fh1$>Yh)sphAEcgj~AX0>gLz*x$MigetHi^txOvMh_T zY&rW@KoEnhLWUaZaR zyj?Pj#!;3gkq)BRnP*rxUI0baXU<19>@~`DJ6a5L0nG3)&g!%XJzm-A9{$3~TWZ(T zWXWG{z@0ujb6t>(?TEOw3zy8qj>gr)9pydYj?Qo8rjA7g2XPim`OX#Ff|@BJGPpFO zwRJf$Vg+s+@$g_MEc=BMfz6>wFihWHu@GMr7zMg)ak>HLKECQ6UglN|x-7f6jY}ns z!3}g#f0OFrX}Croq`EbDTqxSkzGA+y^|kZNGO5x4_D~#35C8fdQm>_b)D!xkz#-_U zbH_DuZp%0Ei{O9>xpo7HKTVGQ&ftc7*jI`7wHJ$0Km3(Tkhn+dXFugLlB-lekaASY zpFzlZh>{SK&|1JuiLbEt6%YheeK$CcR9jVqTTbJh=G=Ubv>p~4%Vc?Ihq09UHQwRk z4vf)BKoo8}toeEQfz@|!xM^{FrQ^(qlz`CVpwKy}yomv)6Bb}^ zYRMp3S3@DPAsTHmQhv>4H`oCW0=Ep_E)b=*E*9vVmmNMy)4zYrj_%{mer)@6L@SbbdCyy%( zmJMGZ>0pKiNXIh=Z$v|F9JWt6@<^T~#&99ncp7byS5fm)u=Kb^#ng|R$;IdLV}jp_%zz$8Th^? z4+77&r!dbVQ}SdX!g%Ce-&HyC^_KK~7xwUWIdWZ6uXd9&u#SmuFc=#jYtfF-ED6xsM8lRTRpXE{kY{veZ0$0W(x?0W65R5!66Jdu*J_YjW7r@ z1+L&TVXfZPAbc`kG_Jmt;E~hF;b_SiCYRYJ^OV)m(m2vOM3bl@}vqQAWZk#BGzc@&?`{)*>FR=83iEo zl}He-^yk$F;OL`_10AjeOJVcV;`G5f;4H8gl06tU{<#aF&j&;OjYXH+3n~v=ef=*M zT4j1%=i0TKSJB}GF9^Jjx0p7nR57p#N$Gg^kOkxh6Lgd0h_--7H3oeH@g^k?yil$LR-N1BW;A1qzo;=g~wHmy!=Sh z+kBFM_FO!Im29|lrK+A_-~MFQ0nev!OSu7b8-)rugK)R-gL9R~)T2}}u~XPo{4}@x z>9no#+vJbR>p7EeNo2Jh)(rY4n6ult8VQ;*+DxbK#pY2y+DmHNf3SKcQsDIoB3lQZ zD>P`bIt~*fNzHQtS$R1FMYWSgC6O+o+JTMuW0(X(51{)zf(X00a>E3-=g1=kk9jJT zl!+tOXCofIc?u&%9gs?2u_-kSe!>~~8Bk4+Zh-^WK4#4vJUJZgvRf=Fs*x z&@5HKVK4L-7E{p1opwR3cPE+boaJw6*|W>z={_}ePTkOx=y!dVb${UD!<>4FRVQwu zraX7QusRTh(i~C)WiZ?WJmFWh%#CChte(i9tcR18J!4&kVgA0Lt;3~eQRwQ4Bqh0< z9#8OO;?KuEQv6$cSSZpW zW^WKk0`{ZN)rF+ZM>bc(!Vq4L+PyCL>F}r8{7sEWL|EvkgeF6kw_n>nnBj%)l%lZt zd8QXGVIYa+q3#r*ndYw|W9ToS>3{VMNpSuYs41*{sQWbp%AwLs9|Ho^H_8+fXT*1= z329%wUe<0gyv;VY@v$Zg=$-m}!PNt6-*~r=k4u&~$^9W(^lX|C)}uJPp{xg$vOu!x z2_t_LEJS{MHJFG^Ve)v&Q!y#rh0%%89>%$Qo8||x2x81_P7bz^KjZI!=eXdFV2j(+ zALabsBtqj1AR^XFD>N)?l(~01*oY@*56-7uPb;AG0+ed#zQ(`v{!^f>Tj5`}e#{q)#Mciwhq#gad@U&@h*?H>9$L-f=gPWK`x+s7Z=9Bq-Hfpw)3!FXnOQz z!;hcSsj|^C9<;LOM{GNEUMCjpBY9<+;JYjGkQqfesVcKSjzdUwIQmKIDGv-dS7ABo z%+a!s;UL&}9AzlB?5(9d)b;oX-mB@_fp~#7hz`eI-u@h9x}!-iqW^rgQQfCDsyj{T z>1M#;GZ&k?mH$m}!mGQhy#J;oAW8upwo6I*+nJLIkoJc{aJE91 zJ>w-`%~rX<^0~0SH#)6=ic36n*?C4005!t_9Nu(R29&eZgJFmcux;1*Q^-t&lk8zF z`nyn(eV}O`9Vk$6hf-YhPFeoOncqKt4i0;U_R3DQ_3?#gh!5(59apeI2@OUenSd4V za`NY?qR#^z$|-gpigPVnx#l;cKtsn=>L)RRQNc&S6IplS5|T5mWP2; z8^}vSt+oFGg+DKsH!UvuP8V;5q^SF$jh%lzz6O{u{X3BHMK!^Fs%{yyL}1(_LH&B( zpy%5JFeJrG_E%DP-pj(xcK+VA^$=9QN;xB6yd5?9p0Q%%*7l(x549zhzp`!uoffrV z?dbUgdH`WDF5xzm?tIL$pJY0atvgSQ^7@o#HVmq=q<2aKm_wa{>7&CBi=mA~KbUCT z-~`y>yGBd;S5qrTprQQ+dr27Brn?qK&DT>iZ@PysX#p{Gn%nyF{-PCiz^cpMoS<&p zqQSH}j9SJ5G$iN@gATa*AAD2?eTSvK#_=AnX~%=$@a8u6+md2RR@$0U;KWFt@wsQv zjvIFW?jJ_6JmohHM=L~vu7lkRd(OwoE$ofCAaQ!D82^6SZum^lL2s~w;B;2d*!1BC zmMa^QM=;}xPkCi&LFNXXUPqpR%AX2f-cXl=U=z!qWvtj;jU@+?qQV5^AeHikT-%f9Z{$wD{>tLXU>OKA8;DxI+(Q@gRdMFi7v*PKT@~sv{_g}6^Z}%fvq)IK8OQ;vA?Cm9k zb@#eZvtuNk@7f})iUJ3T-&3AX+ZdDashuVB`;QNoiKm1N_V6UP4;nMc!205Ic;sjA zp5rD?X`rwZdDZyB=C=#AW$=eah{~#EPmjTthD$zz=XAZl&RZ;u451}Fi7a7W&bII7 z#<>x>l_yqiS)m70V=C}`9COw1rS_g?7@4G(&0qT7Am#dPq62vzqhh4Iyre!7)4%-) zcPYZq15+FBOnA<(Lb4snspWT_FB!COpQ##(N##$nBbE$y{qP&IK8!L`x#&&7^SC3N zCvcKd?%{``W7srLpjyNbzdRE3(9<^ki7>Z)99l)oM9fTC&*xaTnJ-h{`4V()XTP9l zEzaRj3MeP3U(;Xj8>JLW{xH^Hx4bx6IzYz5ybTHX z`zG0x={)kFbqs>i?$Svi?eoD$HwTKfjV@O!yPtrO?!srVl2>5zLX~r$hR~$yky1u} zRA#bw*0M5rfjK#A1?xjTv*1H%MZA0KMXpcM8OTGqVI@h|a#3^FP^F0D$4v=M<4-$F zeMnRIYt>U_Ax1|ixDad=X^yQNrYaS%n&745klFlkksc^l zQ`)_cBAf20_11{h)KUz+3#Z`3s&Vv`EVi$!9q)!G*EVAj%csZw3})f<#|u`nX{3gu zz_C%8PF1AurcOp^@`w@s3SyTQi@G1e^Y;A(cD(VK?N1X4^UezmaLQ7AuJR{ASH?W0 zOT?%{gE4$HDnv5!yCHc2OLC1Z!r;dlS zni;-gA1cjwarStEYo#H{&06yM7=griybk7tZ|J;g`C!x$rTP<=Yz*`6d{|L~z4r1fDK=@lW{l}Fk6XM(Ev zyHu=O!+_gcCw}E=y>bP3_A*v>>eu9+GhAivR+V!<2Cpyp1j1@vA87;~--{p==hkz# zZV8?_yl)U4NZGe->Obk%yLr{uB}OV`aj1b0N?i-CrtT4h?@x7(P7#>J-g0v#HQ)Ex z&fGs;#_YuO?K@9WPzjS*Mupi2o@VpFT*>*$Zb3EUQgYqBb1gW8n91_4eNV2%BI{@D zr$;G2lVTj^KNH5WaSnO>zsA`Y2T}H%aGVKcMJ!wH3K{FOWV@ivvx{_FPo|u~Y2V@y z%<-L4VghW@J3wzKP*Qs~&WF;GUdojB7mL~5SH=RY=0QfT{O`zDi=A*rXri$dHZNS< zJ3eSema^1Q+$s6-mPA%~tf9pA9&ldGz}Jyz21c6pO1%Cj*S!82E=?gd<^u@2GE!rIclR6kf*5$H#HT z>I8WvQ00mb3I1U`{rp}9Mv?L2og&GmD%VLT1M%!YzFfi)Zya!AsIr_m+{CnYxD*-y zU3w=u*O-EwyE^dkbg7A_z4OZw_&tT*2ZXBRPQt>>k~uPjm+jeoZoSrfMHl29?NSES zFS)?C{t8vy^3qbj{01BFGgL>avBC-Yof|X$Hw5b#2DSJ28(B08MJ%--h+0;i%Y)-> zUJuHaNBC;Q3Tsg+xSA5DD(|5E$sTu27SK68McK>E+XoG|yH1|EPO2lh`7E_qJ|f(mlxvRpPYxmYJN5^m~`sR1%7!wu+s#V_n3XqkhfQU zp(%YFPy9Z}d?Zta@QzDD=>^PYc@dz6`iI#K{ePBM=1j;PQCvW9foTL%OZONM*j`VND^rwo&nFVaoKZV#qlajxx5PTN| zH*_3o06?V6zZzQ1;sw1v!;jCOA6c{?lH_$B8+Xcv-A*N={6RM%$q06T z-lDBl@`?|ipcw-!V^}M%dUj$QUxrOe_4W>aO8GwA^61+NDLgs*6JOR=HfGG;Sa?dn zdr|OfTqGpo>Vq?pEF}MnTmPE^xP7-~QO>7-q10iY=7|SZk4=dKIpm6E&Y?`C!&`V1 zdBE@71r;@lr2wl?(9Fp3+j+?su~X>K%V_dsK(;nT-0RSjnRHQg1`s}xvzDi7DP)5L z$(&0r!2jI7e%Hdh+6_Q}27%P89@#tb%w`UGuS| ze|vVG607>NnMFh&SQKxY%)JVga?a(02xgVcnH}6{N>6$6pTRTfXKGO7c|z+2^yqf5 zM^R>8QzGJd^(o>)oFO4F#ju((U*25z?X$iJt}T$?@XuHTsS75%a;l~|<}1N)HDaS@ zo3&s7j%UkD2H=XKw8nh3Hr?_4$m;7qGr~@uwYEFrvsBA3%_O2e!=g+er}Z9D@s~7a z^*4IX01Fe=U}^nUed3%%1Osf_@Pr;*#l(ASuvqDG`c!8rv&xk!fFW6A9E+^K-V%Cw zWkT-_-h!AAn2okx`nr1|Z-qrUcaW6rlOFn`mfbqr39(RIih`q0BYF+IQ7l#`*lQln zpKEv-eh5dSvf7-XekrX@@7K`yY2V&Ht9K{=A)TheF z$)9(k-U`+(@F8}oWvjmKiL+e#u@paED(^A<^J}(1k>^&wPDv-q6#>@Qe&7VaTCwQ_ ziOMH`MZ@P?;t=o@m`7?u9;GfXoD&&z*xdZ4UT~1eE5`vXNH85|ib*J8YeD?AVPT&BWRmk_I z3XI?kDrUkH2oEd2mM$&|@kMchn<0AoI|g>bJ7FeWy#|>@)(*JGt?3``#30M%edtM9 zK)sG%l=z>)(7D{5cp?aW&@-sVk}mqBQ{*dH1n5KgZ^b!j*y*b6G{>59J&*Er*YPdE z0`xlvrx0E%6;@7^PJZ%5lJlO0M;a_I^p_ zWgE@2Y5E&^F*x}Q&MjC`rt9Kyoj!68M!gOctG-_Jlvue&CTHixk}8B#`Hc_`O9i44 zKmU^f{F~Vq1qcZE|KT&+&u`?Yql;hgw%VgAYcxQ7gAauTzi>%5Bthm(J})slwK5*)a`f_Ws; z?87yZ^2%s#_ z2}k_5P_KwrdG68z){zBl)FoCFWx&sG*^7_1wQE0Odbi-7sudA)poSFPu6 zL-HIJu21rKjL%{ZROU2YURYj@Aey0UYNFJeWTlkcKQmrn^zoN$1Ot5GLfRaJKv0gqFYr40*xJSYY@oHwH?ysSP`0U^*Z9Q|8=iPnB!WRS)5!?_;dX5)d}W68xv$K~ zm^8NtLbE%7aJZew;_J8Uv`<-{+?1X-^za;RXQz=W&>AyCk`(uXa)oQ^@?w%#)>9To zCBl%uB#G6mOrUPB-VRu~NM+6GC4JEaw5XSHG|Sa{Lv;=N4pU}^Fo*@xN;sC{34Yv~ z|HMkZC-5(LT=TSF3}UGwMV!RxL-K*o<`{j_JRb4JI|b>~N63MtP!{~G5A(x^we8-| zZ3%A8bP_|jV!8%h3jahvuA+32Dh?=xcSSgbC?ojzV3RgfKQWXQA69ZG&|ymY>cIzX zd2~sv{~?R|5?yxO@%tsK1(d(!p4ketPYg;@bxC6-2Z?wCj}Jv6J{Uk2 zbGB#)v--;2s+JT3VK?k4kPdc8yD2W`dy?eCNUpD!arPXrG;w;xK|?)9U3mLqOWb?s z^n36gQ%U8V_=}Th*`Hv()3vXC?d#oFM`)#BQBa1#7 z(08VJaoYYM9ac0G+o$G%1!9c_(%7}^nv8UsA}i*nBQ*s_HvjmC` zagHUYq(lqE8Rhau-%G};xJ~mC&~f?5+?#<7`%I3yUOx7#1!rG5_D!b+Sde~@{J%#V z%)(HHNT+Fdek0#PyZUc@%m4oOZ$)egHcFre>@f&DKg*p^0DGx`Fcz;z({Q!D>p|Id zP6cJd{>SVc+7qL5nZJ0;tG_tsTllHf2j4yc{!F`Zc+5L zDK5US#s8a;&*Mp}?175*g%UVU>*q2$Bp>-E$JN~{f5g0Do8O1mZB0PWi_t!QC;$H< zVZg9u010n7;yrOz)CC3j=b{nb(^lhSZ9a78e-v=U z5Pp^tzov!((FO@3Hv)n{4sK#p^wD4EAyPyCD3w!E|-1q|Ov)Yq*BlPrRr>x=>5VCmBC z!=Hk2%DV;q0Jp$FWB$Rnt)#_3-69UuIm`nYvUI6wTg4M zr9dI$9P28p`Nu_B7l7Q(AVmJ}EEPKtyY~O+A_Y9vRdy_UXAulMosFkN?aZr=&cJO} z-4H4}0L_M>+Uw8gwWID2s&%y}DrkE5lgW&rJOj@~_5T#g>Muzwi>})U&8zBEb5^w4 zzO4Jw=~$H8{py+eFmCe(HWOsum>mQe-&;Jyu)hQra+IA5Cq}$8rZFqMSS}ead4HWhwyvoSjE8jA36Cv|`*i3c$iRvc zBWgC-4Sh~SdGWtv79JhjUOq1)p zJ0ZFYVvd`h>|oP30amZj15{tSXPQqkt_G6zw*vR|IGAR-i4nIsE+Ie=nci2OSR2$^ z9?ZP$CO{Lnq8#gK%Ytr9r&t%#I1_$mD`S?!LS#a`M7H#O6-1aZNf~(?gpxUov_e8g z_bXp8VOB-=HS7T3uh9|4val&QPEfo3G=Jyx0E>Cf0la;CJ^c zbyn^quf!%Oq${|Pc`H^{BqE3p45CnRqZeql;}NNgLB;#Rea!kHM0dgvh~5sRsx{C% zH9`WoSO?Vkvt{l6`dxW2uMb7cHB!ag!cr4NP)46b)qYEj8{Vjoj|FjaSNU$ z)0i&DiFidVi4csryKJEKJ@+erZUj|H29Zi%jmaO-lvp&~w?b-kj1y?eQ|5x*G2-tiVK+RtQiU0gpiLgg8H+9$D2jp3X z);tS~<_GXBwUfYeZ@PXGvE@kZZ~qJVmWDOoA{cQ89JTIu2l&&?*8$=@{*5@6jSo_z z!(C7i=9G+m`&_^%vd!sqLuS-9u{ez+dxz+qrKbD%G*F9s|ELXVP{F$ARHwL3j5gR7 z%bXM2fd;^1lH1ji{$9d*TBKM!dA)v4^W{>ORguAxE+$uw*G%l=KME>qGbIb3lhR^4 z3B^5lG;)6?+QE+X*gcm|P79NF>Bp~HV?W6Bb%@P-GtQq zsQ7qq%~aM*X!G^In~>jQxU2%2McmJ*xWlDT;)1@(-FYOGnr7EB3`}g zT=xrfC3_+4uQO936I2~r+k=NohzUD0{JQo^K~ax$|D*hXjFz8eoXM?&`+1W)X~Bou zX%+7HrGhUI^=g;r!+!e2H3Zu23UIs1rS-eHnz_!NxF(6|(nVlySm5uUo|CK_QFy&ktLVNaZ1Y$oJd6>g=f&aTi#`=Ig*B zp8U3mO%q#pRhzH>-Bk^L89OV+e-859)g@yIoUi); zvf7uc?4dxZXwQBb%Q9d?QK*l0JIfqe;uSl2IZbTJdQqKu{iRtjYGHRn^cu#a(BD`W z*AAsyc~#^KyV@N|dUHpcBxbw}||1P7=gRa@( z=IejA!x@@!tE?IKnjLPw{&zbZtc`};`6O`Xi^Uh1%!AH?^7?sm$i0l218oZ?#_;OB zLx)h&%_Q>DX)~z&63qJi0jD))z@$25nJw^U9FMU?}l=r;O<#Jqg98w24ez{ z$prDL05=ce9Q+5=t@U`7G<(9UK~?9WHFXB*7u9sOLzu5IxkL*Q>X?B6($%juP~`hT zeniN1Wiw>1J&P*U;H5`?;4z%5JklXo7RYq#)|Vg3&HNzC`P(b7s@#EUzo%E{#dLnx z-S_okGvx&Mat|D}lAT-+zB?)U{_+74~ zMy*@uwhjL7>wrZ57gYA%wYhJI)`tfKcIP(*3N69kR&%}8U^RV&9Q=A&9SX32i}uLz z2+k=XjW;=Qdff|iL-Pgqg`*`(0Z%1rw^x!Qzw4;-X9uKAFq?kw#Wd}}ccu8|l>)2% z8cJorZ*vsv6F$Ra4EYJ0BT_-`&f7oDne2sHMplvK$}NH8U(WCpe_9YELacAD1^0Ag z$*{t(182*Fm=|G5NX!0}=cISWmoK6~d~~b8RYjK-a>}?p_Z`RY8E@N?<$z2-cfsfz z@jX!NzP&`aKsJ;Qf1%P3ba$z;=v?jZVx_#MVSq?||F8940MH70AS;>H3aYU}4PIC@ z=lL!&tgHrBZ&w8`1gFMBkTmHcqAnw8ZCM+ydQk1?f8hJYGRqjXuNc>+foqKX*K_) z35t^ba$1V^l<2ZO*glqbI+-#xb$|P(0@J<7zt)War1B*@N!$S(!r*blJfQK=i!$0`(B}B#1!X@}>Q{hjTGEG;3mrWB`SXI{`erh}dFos_BJ5^nmSGz7Z-1&d$ z`_jK2X^_sE)X{^L<0!a-JsnHzY;cq6$uN)xoI5O93Ex{EC}C7L(&WNFF#aIlFW~Z@ z!OJAnWln$Kri(;@&yD{kN$aTASZP^vw{#CV(%`Fz zJ}bO_webbjKOjI@^Mao@*`1zOd^O3W(pWa$k66@u1%H{Zk-(0Ck~=aYAvzv7b#-2nAT< z*%x&?&xj*k1_5T3Tra%w>Q}L%b>@4L#m<(!M4hDD9PKv82k`w4=0UxnspEcSH=a>1 zH%`TAgNl!@skjd-Ewz3C+l#FEZIP=@X2DCZXo)4s?vgG$>_Lbnz9yXXJEk@EIe!M8-=g<6ffN z{~vpA9uH;T_5qI+MO0c;vQ(n7hA4Zah>%2xk!*#OHQNly(uT-Z*&`ydXPqo1WDR4T zsgPxu$vVs!-rqUa>b|b$e(v{u?&o=*&*Pu2>pagn&pD6fdmP92IDWsmzMbDRH=tqT z$!JDh&Vp9E(Q=>oHv9{AdotK=L~y#p6}tV-sZzqtZA$kXU8}TF%fbh2-#}i4$LWpU zBA^23rvl9%TKEn6R|;*|@6f+`W^JfgJ^F9EUeAXG7`a19Q+1WkO%G6aVIkqOL&A>^ zztkx5>B4CWuybq^wRKTl)5+s@wQu6{^!KruR3GM^w2msChg0L&AH~kb{HQ6?=9R82 z7vPamag|VBWNZ4pRw1115?_)1ZTMimt5H$J{?sY^kAikU>XP~+_IdL0vsGNRQZIq9 zua?X$K}!8$>D^BOr0_$W*9xRmezhTl&VCLb;KfmwXMj}1w`D2V0(NAeIpMSJWW!=0 zhxMsK$#n{Raj^3KOqsWQIUhs=f?fmch%#jvys~KG1b^@~S&mgi)g#H?IR*wD= zbXLy%5_DFME?%GAOnV>5yeX_7?LT6QBF)q{0}@XK0Xlz~)?g8Wk^YG4Q=P8c^9azi z7TK(@`+`AROss7_E9udJy`vv`KR{7gMyMgswrD}Ts@*Gdt_>$DEd9JfR8l&X#&fbE z!-byZ;CA>KgKq;53+*XD?!nl+Z0B&B-s;H253=z5&iPExStq}c*?9G|jncxE@pp<3 zZoksx-0fJDmf%lf$BUlWo%4tIPtQ^7MkvFCacxM6Sx$^rkAi8YHR}4Ga=o@t1c~Wj zboXFiZ(p8l#Y|iXNPQm z<0othoCbqdnZ0ygm1s`yctUU%NmK^ngZg(Wh;@B?RPKE$a)R%@9kq_9EX~_)uAerF z6f$)|d^e&paxnQqExE;F^L|-Jv}z!OUbNg|KC@iSt|Y8}YjEWkGysWg@!fm6L7@Er z)1&gU!z*P3mCji#BknFE+X2Mt(f>EspXTs7ojqk=0NHx!F38p&Smvb3UFV!u2sm~+ zq2x|6iV10#G0;CYhI0Ucfg8lqjtsPg@oN1=b@}_!&eKcse_yGKql#pzByx!F6w2ZvWWC1D6c#1&hfPTHV)HL<^UhZtzpBl1_tW ze&o%}bT%OKtEKiIr&bDG1ud#6|AyhzMH^IP{~g0u&#cA#)uaEO>lZQnhJl=9R5c)r z^RM7+i@*5aNc&xq0k6{Q4%^c(^v~^JliP7XT`=}x*^Vk+uk_V!1Gv#bN|aM zodNV?UW?!!kd~+Ei8^32V%wZqIqDS`+5)$_qR)bWSxLYvR= z|3R9StS&-FzeCMU-JDNFXKkDfvUwU2S09 zD-NVKD%K#c`O&4X$$f$Iz{|JN_4|Q?jNasQMj7FQqKA)xi8e5A7y=(L248$@%#tnr zhs>=t6ccBEp~@CpVbqZLJLOE}H2)pyNm28vY!h|Xzv*%6*l7whCNh*4Rnm3qxq2PH z!7J9Y>+Xl{R5slM#@2vyxEXQCVS$`8@IxF2{dK@vI+0m`7m^@V!GwRvUd_`T8Zyj4 ze;w(H>VF`a&_W2!&W^;_)lM+w1H?D0CCwF%^{KIR$>jyjcJ_Ff=E{U~D8VrULFUf< z?4!LSx<#t4ud6o3w}N?Dbp)Uyo+bcF9t;<(nMYgZ8~;X#Q1{Stt`ff;AP-;Pe<_sw zhw2AyLRjBfsB8m*0rZDOp(2`<)Cojih#~E(@COFpmuF)^5bp+LOsk`-UJGHx+=qPa zN^f<$naPr}9__zTJAr4x>UkHYSQ>i^bO2wcC$HLj60TqH<@3>k$-|`a6K-Nfy49wf#QayT zk2obe0Cx$zsaW`M=Di6%O>=w3zy!QhCYHuCOXZ)yXR3S0P|18_pDU|N0T=ZKg9aZ~ z_9KAWT;c$ez|sj&Yk|19g5-emxN1BiZ+3E&J1;@-<|h-ylUGi(*@80N5+`x@j$I~llWvAf39ZaIgnKagjcVWdV!NT#sg zdPc_vx6jc2$~COcrTi&Ss7=`MOXmJJ4n_|-*vKzQ*xv*ZS||&cUdjS47754aEy}@%tq%E~Whs zWKlPzPli-ZgJiT2L6Gl+dM!SJf%a#Lik`OQ;oJMNWLnKOHdzDejI~q;DHsEq47DEu zSizh9+IjgKSya#gs^*_hTiVyAE&n0bP*VXa)}$EyXB;kcw{lL=yAuu``@h({dB{%c z39HN-9qBQ{^_v_Hw2}3Y>U3)Pz@%pjW;=gC-K`+U?a~fK5hzTFHRvRoxy|;m8WM(V z4?G|tA$NegIlE`#%%1TlBZO+lxU zwE1r8K-5xm_n!z7eoUab`>$jxD}=@hNd4K|{rBiCi=KsYMQdMSY0zw*_$JQ6p0Lx9 z-iApfn`^EC(k&p5{rq?E!<%4sZi2nE^sTj9#%E&j&2nGFE-03Ol_{ClLe5)HJ7fVL zlG4wXLlXkPN=pO+)gt7ywaJ?PW8p6}d=01aQ4KF`T#613B22~Ude8XxNisbfGF6s~LIZTZ$>^1|l^i0IEx)15$ ztubBg`xO~3fItI=Fa@Lo3JH}6dRPt5GP}R%QYL<2xB;fDy3Fn`9sTQg4;r~pzoI#K z_}BLCUzHmF-(L^bv6$c_Xv#=ULuNRlNqim%|03{F3f|d(MNfwlCk@3J%dRGFD9%*9 za>abZF&aX#Cd`WUSYKuYDo@Xb>SP5~T=A`7*Os*O=SzBWLTMBl?g0e<6lt~MGZv=3 z4?6w)Ha(yEvdpHIwIvQMorARX(Bq6vE+|amZIB`F_CK7mCyW6-rRM{pIqc!>uy&_u z{CnG;%xbeP%(bmeH-Lxf=1U|h#>-PL-T#pgSvanFMzW$8C$b@A+o2*1p4p5PZ z9)+maHP3TOu?;sc-&?}=(9jlyBqrTSJrfWn6FUp9fyoaU?-K{CfhWljyq`Zb6l##G z%{=IbXv3{$K(tv{;@65dS?&EX|0ntkk2!O*<*sC8!+I!%qjCjIC#*)J7xqHOnN@R5AOsW`sCXv}eF!?g4H{hy;s0asWG==9roXJ}0((c1Tk;;v<#eKw(I zR7≷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

QS$-EdW=&Bmj4r)tAsusEnbm*WB8 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 + - - - + + Small IN100 demonstration: Sphericity Generated views • full 3D calculation; central XY slice shows each feature’s 3D metric - + Altered spacing for demonstration: dx = 0.25, dy = 0.50, dz = 0.25 µm. Original spacing: 0.25, 0.25, 0.25 µm. Original file and labels are unchanged. -Before -Historical Direct • 5aaa879debf9 - - -X extent 47.25 µm; Y extent 100.50 µm -After -Current filter • corrected face weights - - -X extent 47.25 µm; Y extent 100.50 µm -Shared scale -dimensionless - -0 -0.8982 - -Background -No scale clipping -Y increases upward -Z index 58 of 0–116 -Whole volume: 2,317 populated positive features; mean |change| 0.028309; max |change| 0.19037 dimensionless. -Both views use identical labels, counts, spacing, physical aspect and full-range color limits. -Comparison includes precision/exponent changes. Out-of-image faces are excluded; edge features may have incomplete surfaces. +Before +Historical Direct • 5aaa879debf9 + + +X extent 47.25 µm; Y extent 100.50 µm +After +Current filter • corrected face weights + + +X extent 47.25 µm; Y extent 100.50 µm +Shared sphericity scale • dimensionless • Viridis + + +0 + +0.25 + +0.5 + +0.75 + +1 + +Background • Feature Id 0 +No scale clipping • Y increases upward • Z index 58 of 0–116 +Whole volume: 2,317 populated positive features; mean |change| 0.028309; max |change| 0.19037 dimensionless. +Both views use identical labels, counts, spacing, physical aspect and full-range color limits. +Comparison includes precision/exponent changes. Out-of-image faces are excluded; edge features may have incomplete surfaces. \ No newline at end of file From f659a4247fdaf5c7f516f915cd6cb1efc6160cec Mon Sep 17 00:00:00 2001 From: Jessica Marquis Date: Mon, 19 Oct 2026 11:53:08 -0400 Subject: [PATCH 13/28] DOC: Explain temporary surface-metric type checks Track the shared parameter validation follow-up in issue #1833. Keep the local guards while that compatibility change is developed. Signed-off-by: Jessica Marquis --- .../SimplnxCore/Filters/ComputeSurfaceAreaToVolumeFilter.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/ComputeSurfaceAreaToVolumeFilter.cpp b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/ComputeSurfaceAreaToVolumeFilter.cpp index 78fc26b3d7..bed8c1bd68 100644 --- a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/ComputeSurfaceAreaToVolumeFilter.cpp +++ b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/ComputeSurfaceAreaToVolumeFilter.cpp @@ -100,6 +100,9 @@ IFilter::PreflightResult ComputeSurfaceAreaToVolumeFilter::preflightImpl(const D auto pImageGeometryPathValue = filterArgs.value(k_SelectedImageGeometryPath_Key); const auto& imageGeom = dataStructure.getDataRefAs(pImageGeometryPathValue); + // ArraySelectionParameter also accepts StringArray and NeighborList for numeric selections. + // Keep the local type checks until the parameter validates supported array kinds. + // TODO(#1833): Revisit these guards after the shared fix preserves generic array support. const auto* featureIds = dataStructure.getDataAs(pFeatureIdsArrayPathValue); if(featureIds == nullptr) { From 7f923ff9193a1d388a02689f23308d0a8f3f605d Mon Sep 17 00:00:00 2001 From: Jessica Marquis Date: Mon, 19 Oct 2026 11:56:51 -0400 Subject: [PATCH 14/28] DOC: Put the sphericity figure caption in visible text Signed-off-by: Jessica Marquis --- .../SimplnxCore/docs/ComputeSurfaceAreaToVolumeFilter.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Plugins/SimplnxCore/docs/ComputeSurfaceAreaToVolumeFilter.md b/src/Plugins/SimplnxCore/docs/ComputeSurfaceAreaToVolumeFilter.md index 7500ce6171..4e1124cfd0 100644 --- a/src/Plugins/SimplnxCore/docs/ComputeSurfaceAreaToVolumeFilter.md +++ b/src/Plugins/SimplnxCore/docs/ComputeSurfaceAreaToVolumeFilter.md @@ -59,7 +59,9 @@ The generated views below use segmented Small IN100 feature labels in a separate The earlier Direct implementation and the current filter each calculate sphericity over the complete three-dimensional volume. The views display those three-dimensional feature values on the same central XY slice, at zero-based Z index 58. Both views use the same dimensionless 0–1 Viridis color scale and physical aspect ratio. The comparison includes corrections to numerical precision and sphericity exponents as well as the X/Y face weights. Features cut by the image boundary can have incomplete counted surfaces, as described below. -![Fig. 2: Generated before-and-after views of full-volume Small IN100 feature sphericity on a central XY slice. Spacing was altered from 0.25/0.25/0.25 to 0.25/0.50/0.25 micrometers for demonstration; both panels share the 0–1 Viridis color scale and physical aspect ratio.](Images/ComputeSurfaceAreaToVolume_SmallIN100_Sphericity.png) +![Small IN100 sphericity before and after the correction](Images/ComputeSurfaceAreaToVolume_SmallIN100_Sphericity.png) + +Fig. 2: Generated before-and-after views of full-volume Small IN100 feature sphericity on a central XY slice. Spacing was altered from 0.25/0.25/0.25 to 0.25/0.50/0.25 micrometers for demonstration; both panels share the 0–1 Viridis color scale and physical aspect ratio. ### WARNING - Aliasing From 2d3a195c197b6099f291f93bc529014205958c20 Mon Sep 17 00:00:00 2001 From: Jessica Marquis Date: Mon, 19 Oct 2026 11:56:52 -0400 Subject: [PATCH 15/28] DOC: Clarify nonfinite surface-metric results Signed-off-by: Jessica Marquis --- .../SimplnxCore/docs/ComputeSurfaceAreaToVolumeFilter.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Plugins/SimplnxCore/docs/ComputeSurfaceAreaToVolumeFilter.md b/src/Plugins/SimplnxCore/docs/ComputeSurfaceAreaToVolumeFilter.md index 4e1124cfd0..3bdfd9c86c 100644 --- a/src/Plugins/SimplnxCore/docs/ComputeSurfaceAreaToVolumeFilter.md +++ b/src/Plugins/SimplnxCore/docs/ComputeSurfaceAreaToVolumeFilter.md @@ -71,7 +71,9 @@ The surface area will be the surface area of the **Cells** in contact with the n Image-exterior faces are omitted, so a feature touching the image boundary can have an incomplete measured surface. This can reduce its surface-area-to-volume ratio and increase its sphericity, even above 1. In-image faces against Feature Id 0 are included. -The filter does not reject zero or negative supplied cell counts or replace nonfinite results. For positive area and zero volume, the ratio is infinite and sphericity is zero. For positive volume and zero measured area, the ratio is zero and sphericity is infinite. Zero area with zero volume produces NaN (not a number). A negative volume can produce a negative ratio and NaN sphericity. Interpret these values as limitations of the supplied volume or measured surface. +The filter does not reject zero or negative supplied cell counts or replace nonfinite results. For positive area and zero volume, the ratio is infinite and sphericity is zero. For positive volume and zero measured area, the ratio is zero and sphericity is infinite. Zero area with zero volume produces NaN (not a number). A negative volume can produce a negative ratio and NaN sphericity. + +Zero or negative supplied counts do not give a positive feature volume. Check **Number of Cells** against the feature labels before interpreting either metric. A zero measured area does not support a finite sphericity value, but it can result from omitted image-exterior faces even when the labels and counts are correct. ### Warning - 2D Image Geometry Results From ff3005237136c01d75a353f0c8190d6bd325a1c8 Mon Sep 17 00:00:00 2001 From: Jessica Marquis Date: Mon, 19 Oct 2026 11:56:52 -0400 Subject: [PATCH 16/28] DOC: Explain responsibility for image label ordering Signed-off-by: Jessica Marquis --- .../SimplnxCore/docs/ComputeSurfaceAreaToVolumeFilter.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Plugins/SimplnxCore/docs/ComputeSurfaceAreaToVolumeFilter.md b/src/Plugins/SimplnxCore/docs/ComputeSurfaceAreaToVolumeFilter.md index 3bdfd9c86c..6bff94084e 100644 --- a/src/Plugins/SimplnxCore/docs/ComputeSurfaceAreaToVolumeFilter.md +++ b/src/Plugins/SimplnxCore/docs/ComputeSurfaceAreaToVolumeFilter.md @@ -19,7 +19,7 @@ Use [Compute Surface Features](ComputeSurfaceFeaturesFilter.md) when you need a - **Cell Feature Ids** -- the per-**Cell** **Feature** label array, typically produced by [Segment Features (Scalar)](ScalarSegmentFeaturesFilter.md) or another segmentation filter. - **Number of Cells** -- the per-feature cell counts, typically produced by [Compute Feature Sizes](ComputeFeatureSizesFilter.md). -The label array must have one tuple per cell in the selected geometry. The array can be stored separately from that geometry. Its tuple count, cell ordering, and feature labels must describe the selected image. Each Feature Id must index a tuple in the selected feature data. +The label array must have one tuple per cell in the selected geometry. The array can be stored separately from that geometry. Its tuple count, cell ordering, and feature labels must describe the selected image. You are responsible for checking that the cell ordering and feature labels match the selected image. The tuple-count check cannot verify this correspondence. Each Feature Id must index a tuple in the selected feature data; the filter checks these index bounds. ## Algorithm From 6c7ebbbf6a48ac72723727cee0269e072d57bb89 Mon Sep 17 00:00:00 2001 From: Jessica Marquis Date: Mon, 19 Oct 2026 12:32:37 -0400 Subject: [PATCH 17/28] REV: Limit pi-root calculation to sphericity Signed-off-by: Jessica Marquis --- .../Filters/Algorithms/ComputeSurfaceAreaToVolumeDirect.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeDirect.cpp b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeDirect.cpp index 49498c8ea7..6da4a105fa 100644 --- a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeDirect.cpp +++ b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeDirect.cpp @@ -138,7 +138,6 @@ Result<> ComputeSurfaceAreaToVolumeDirect::operator()() } } - const float64 thirdRootPi = std::cbrt(nx::core::Constants::k_PiD); for(usize i = 1; i < static_cast(numFeatures); i++) { const float64 featureVolume = voxelVol * numCells[i]; @@ -149,6 +148,8 @@ Result<> ComputeSurfaceAreaToVolumeDirect::operator()() { m_MessageHandler.sendMessage(IFilter::Message::Type::Info, fmt::format("Computing Sphericity")); + const float64 thirdRootPi = std::cbrt(nx::core::Constants::k_PiD); + auto& sphericity = m_DataStructure.getDataAs(m_InputValues->SphericityArrayName)->getDataStoreRef(); // Sphericity is one for a sphere and decreases as the surface becomes less compact. for(usize i = 1; i < static_cast(numFeatures); i++) From 3b710ca117e1f5c9f63fcbb1478714b897b119e6 Mon Sep 17 00:00:00 2001 From: Jessica Marquis Date: Mon, 19 Oct 2026 12:32:37 -0400 Subject: [PATCH 18/28] REV: Keep surface-metric feature counts in usize Signed-off-by: Jessica Marquis --- .../ComputeSurfaceAreaToVolumeDirect.cpp | 8 +++---- .../ComputeSurfaceAreaToVolumeScanline.cpp | 21 +++++++++---------- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeDirect.cpp b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeDirect.cpp index 6da4a105fa..265c86178b 100644 --- a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeDirect.cpp +++ b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeDirect.cpp @@ -41,7 +41,7 @@ Result<> ComputeSurfaceAreaToVolumeDirect::operator()() { return validateNumFeatResult; } - auto numFeatures = static_cast(numCells.getNumberOfTuples()); + const usize numFeatures = numCells.getNumberOfTuples(); SizeVec3 dims = imageGeom.getDimensions(); FloatVec3 spacing = imageGeom.getSpacing(); @@ -56,7 +56,7 @@ Result<> ComputeSurfaceAreaToVolumeDirect::operator()() // Multiple cells contribute to one feature, so accumulation stays local until // the cell scan is complete. - std::vector featureSurfaceArea(static_cast(numFeatures), 0.0); + std::vector featureSurfaceArea(numFeatures, 0.0); // Flat offsets avoid repeated coordinate-to-index conversion for in-memory // six-neighbor reads. @@ -138,7 +138,7 @@ Result<> ComputeSurfaceAreaToVolumeDirect::operator()() } } - for(usize i = 1; i < static_cast(numFeatures); i++) + for(usize i = 1; i < numFeatures; i++) { const float64 featureVolume = voxelVol * numCells[i]; surfaceAreaVolumeRatio[i] = static_cast(featureSurfaceArea[i] / featureVolume); @@ -152,7 +152,7 @@ Result<> ComputeSurfaceAreaToVolumeDirect::operator()() auto& sphericity = m_DataStructure.getDataAs(m_InputValues->SphericityArrayName)->getDataStoreRef(); // Sphericity is one for a sphere and decreases as the surface becomes less compact. - for(usize i = 1; i < static_cast(numFeatures); i++) + for(usize i = 1; i < numFeatures; i++) { const float64 featureVolume = voxelVol * numCells[i]; sphericity[i] = static_cast((thirdRootPi * std::pow((6.0 * featureVolume), 2.0 / 3.0)) / featureSurfaceArea[i]); diff --git a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeScanline.cpp b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeScanline.cpp index 7df0e8fa21..2c1ca5e7ad 100644 --- a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeScanline.cpp +++ b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeScanline.cpp @@ -41,7 +41,7 @@ Result<> ComputeSurfaceAreaToVolumeScanline::operator()() { return validateNumFeatResult; } - auto numFeatures = static_cast(numCells.getNumberOfTuples()); + const usize numFeatures = numCells.getNumberOfTuples(); SizeVec3 dims = imageGeom.getDimensions(); FloatVec3 spacing = imageGeom.getSpacing(); @@ -53,7 +53,7 @@ Result<> ComputeSurfaceAreaToVolumeScanline::operator()() // Multiple cells contribute to one feature, so accumulation stays local until // the cell scan is complete. - std::vector featureSurfaceArea(static_cast(numFeatures), 0.0); + std::vector featureSurfaceArea(numFeatures, 0.0); const float64 xyFaceArea = static_cast(spacing[0]) * spacing[1]; const float64 yzFaceArea = static_cast(spacing[1]) * spacing[2]; @@ -167,22 +167,21 @@ Result<> ComputeSurfaceAreaToVolumeScanline::operator()() } // Feature-level caches avoid per-value OOC access during metric calculation. - const usize numFeaturesUSize = static_cast(numFeatures); - std::vector localNumCells(numFeaturesUSize); - ioResult = numCells.copyIntoBuffer(0, nonstd::span(localNumCells.data(), numFeaturesUSize)); + std::vector localNumCells(numFeatures); + ioResult = numCells.copyIntoBuffer(0, nonstd::span(localNumCells.data(), numFeatures)); if(ioResult.invalid()) { return ioResult; } { - std::vector localSurfaceAreaVolumeRatio(numFeaturesUSize, 0.0f); - for(usize i = 1; i < numFeaturesUSize; i++) + std::vector localSurfaceAreaVolumeRatio(numFeatures, 0.0f); + for(usize i = 1; i < numFeatures; i++) { const float64 featureVolume = voxelVol * localNumCells[i]; localSurfaceAreaVolumeRatio[i] = static_cast(featureSurfaceArea[i] / featureVolume); } - ioResult = surfaceAreaVolumeRatio.copyFromBuffer(0, nonstd::span(localSurfaceAreaVolumeRatio.data(), numFeaturesUSize)); + ioResult = surfaceAreaVolumeRatio.copyFromBuffer(0, nonstd::span(localSurfaceAreaVolumeRatio.data(), numFeatures)); if(ioResult.invalid()) { return ioResult; @@ -196,13 +195,13 @@ Result<> ComputeSurfaceAreaToVolumeScanline::operator()() auto& sphericity = m_DataStructure.getDataAs(m_InputValues->SphericityArrayName)->getDataStoreRef(); const float64 thirdRootPi = std::cbrt(nx::core::Constants::k_PiD); // Sphericity is one for a sphere and decreases as the surface becomes less compact. - std::vector localSphericity(numFeaturesUSize, 0.0f); - for(usize i = 1; i < numFeaturesUSize; i++) + std::vector localSphericity(numFeatures, 0.0f); + for(usize i = 1; i < numFeatures; i++) { const float64 featureVolume = voxelVol * localNumCells[i]; localSphericity[i] = static_cast((thirdRootPi * std::pow((6.0 * featureVolume), 2.0 / 3.0)) / featureSurfaceArea[i]); } - ioResult = sphericity.copyFromBuffer(0, nonstd::span(localSphericity.data(), numFeaturesUSize)); + ioResult = sphericity.copyFromBuffer(0, nonstd::span(localSphericity.data(), numFeatures)); if(ioResult.invalid()) { return ioResult; From 80960e797bdbbce7ea099c6865ff2e99faf8275b Mon Sep 17 00:00:00 2001 From: Jessica Marquis Date: Mon, 19 Oct 2026 12:32:37 -0400 Subject: [PATCH 19/28] REV: Use a const FeatureIds store in Scanline Signed-off-by: Jessica Marquis --- .../Filters/Algorithms/ComputeSurfaceAreaToVolumeScanline.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeScanline.cpp b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeScanline.cpp index 2c1ca5e7ad..53242f3d6c 100644 --- a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeScanline.cpp +++ b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeScanline.cpp @@ -30,7 +30,7 @@ ComputeSurfaceAreaToVolumeScanline::~ComputeSurfaceAreaToVolumeScanline() noexce Result<> ComputeSurfaceAreaToVolumeScanline::operator()() { auto featureIdsArrayPtr = m_DataStructure.getDataAs(m_InputValues->FeatureIdsArrayPath); - auto& featureIdsStore = featureIdsArrayPtr->getDataStoreRef(); + const auto& featureIdsStore = featureIdsArrayPtr->getDataStoreRef(); const auto& numCells = m_DataStructure.getDataAs(m_InputValues->NumCellsArrayPath)->getDataStoreRef(); auto& surfaceAreaVolumeRatio = m_DataStructure.getDataAs(m_InputValues->SurfaceAreaVolumeRatioArrayName)->getDataStoreRef(); From 3c77f6f1d471fc78a5693714657ad153a7cd5ab0 Mon Sep 17 00:00:00 2001 From: Jessica Marquis Date: Mon, 19 Oct 2026 12:32:38 -0400 Subject: [PATCH 20/28] TEST: Make the surface-metric fixture mode explicit Signed-off-by: Jessica Marquis --- .../SimplnxCore/test/ComputeSurfaceAreaToVolumeTest.cpp | 4 ++-- .../test/ComputeSurfaceAreaToVolumeTestUtils.hpp | 7 +++---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/Plugins/SimplnxCore/test/ComputeSurfaceAreaToVolumeTest.cpp b/src/Plugins/SimplnxCore/test/ComputeSurfaceAreaToVolumeTest.cpp index f2d74c4785..82800b21e1 100644 --- a/src/Plugins/SimplnxCore/test/ComputeSurfaceAreaToVolumeTest.cpp +++ b/src/Plugins/SimplnxCore/test/ComputeSurfaceAreaToVolumeTest.cpp @@ -271,7 +271,7 @@ TEST_CASE("SimplnxCore::ComputeSurfaceAreaToVolumeFilter: analytical single-slic const auto calculateSphericity = GENERATE(false, true); CAPTURE(scenario); UnitTest::AlgorithmTestScope scope(scenario); - SurfaceAreaToVolumeTest::CheckInteriorPairSurfaceMetrics(scope, pairAxis, FloatVec3{2.0f, 3.0f, 5.0f}, calculateSphericity, SizeVec3{5, 5, 1}); + SurfaceAreaToVolumeTest::CheckInteriorPairSurfaceMetrics(scope, pairAxis, FloatVec3{2.0f, 3.0f, 5.0f}, calculateSphericity, true); } TEST_CASE("SimplnxCore::ComputeSurfaceAreaToVolumeFilter: decimal connected comb", "[SimplnxCore][ComputeSurfaceAreaToVolumeFilter]") @@ -301,7 +301,7 @@ TEST_CASE("SimplnxCore::ComputeSurfaceAreaToVolumeFilter: nonpositive supplied p const auto suppliedPairCount = GENERATE(int32{0}, int32{-2}); CAPTURE(scenario, suppliedPairCount); UnitTest::AlgorithmTestScope scope(scenario); - SurfaceAreaToVolumeTest::CheckInteriorPairSurfaceMetrics(scope, 0, FloatVec3{2.0f, 3.0f, 5.0f}, true, SizeVec3{5, 5, 5}, suppliedPairCount); + SurfaceAreaToVolumeTest::CheckInteriorPairSurfaceMetrics(scope, 0, FloatVec3{2.0f, 3.0f, 5.0f}, true, false, suppliedPairCount); } TEST_CASE("SimplnxCore::ComputeSurfaceAreaToVolume", "[SimplnxCore][ComputeSurfaceAreaToVolume]") diff --git a/src/Plugins/SimplnxCore/test/ComputeSurfaceAreaToVolumeTestUtils.hpp b/src/Plugins/SimplnxCore/test/ComputeSurfaceAreaToVolumeTestUtils.hpp index 740856fd68..faa3584114 100644 --- a/src/Plugins/SimplnxCore/test/ComputeSurfaceAreaToVolumeTestUtils.hpp +++ b/src/Plugins/SimplnxCore/test/ComputeSurfaceAreaToVolumeTestUtils.hpp @@ -19,10 +19,11 @@ namespace SurfaceAreaToVolumeTest { // A wrong X/Y face weight changes the physical area of this interior box. template -std::array CheckInteriorPairSurfaceMetrics(ScopeT& scope, nx::core::usize pairAxis, const nx::core::FloatVec3& spacing, bool calculateSphericity, - const nx::core::SizeVec3& dimensions = {5, 5, 5}, nx::core::int32 suppliedPairCount = 2) +std::array CheckInteriorPairSurfaceMetrics(ScopeT& scope, nx::core::usize pairAxis, const nx::core::FloatVec3& spacing, bool calculateSphericity, bool singleSlice = false, + nx::core::int32 suppliedPairCount = 2) { using namespace nx::core; + const SizeVec3 dimensions = singleSlice ? SizeVec3{5, 5, 1} : SizeVec3{5, 5, 5}; DataStructure dataStructure; const DataPath geomPath({"ImageGeom"}); const DataPath cellPath = geomPath.createChildPath("CellData"); @@ -35,9 +36,7 @@ std::array CheckInteriorPairSurfaceMetrics(ScopeT& scope, const ShapeType featureShape = {3}; const ShapeType componentShape = {1}; const FloatVec3 origin = {-1.0f, 4.0f, 7.0f}; - const bool singleSlice = dimensions[2] == 1; REQUIRE(pairAxis < (singleSlice ? 2 : 3)); - REQUIRE(dimensions == (singleSlice ? SizeVec3{5, 5, 1} : SizeVec3{5, 5, 5})); constexpr usize pairFeature = 2; constexpr int32 enclosingFeature = 1; const usize cellCount = dimensions[0] * dimensions[1] * dimensions[2]; From 6538fff0574b83db75c32936e3a6597219878687 Mon Sep 17 00:00:00 2001 From: Jessica Marquis Date: Mon, 19 Oct 2026 12:32:38 -0400 Subject: [PATCH 21/28] DOC: Explain the legacy sphericity exemplar tolerance Signed-off-by: Jessica Marquis --- src/Plugins/SimplnxCore/test/ComputeSurfaceAreaToVolumeTest.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Plugins/SimplnxCore/test/ComputeSurfaceAreaToVolumeTest.cpp b/src/Plugins/SimplnxCore/test/ComputeSurfaceAreaToVolumeTest.cpp index 82800b21e1..67830892ee 100644 --- a/src/Plugins/SimplnxCore/test/ComputeSurfaceAreaToVolumeTest.cpp +++ b/src/Plugins/SimplnxCore/test/ComputeSurfaceAreaToVolumeTest.cpp @@ -353,6 +353,7 @@ TEST_CASE("SimplnxCore::ComputeSurfaceAreaToVolume", "[SimplnxCore][ComputeSurfa calculatedPath = DataPath({k_DataContainer, k_CellFeatureData, k_SphericityArrayNameNX}); REQUIRE_NOTHROW(dataStructure.getDataRefAs(exemplarPath)); REQUIRE_NOTHROW(dataStructure.getDataRefAs(calculatedPath)); + // The archived exemplar predates the sphericity exponent correction. Its absolute tolerance can hide small output differences; analytical cases establish the corrected exponent behavior. CompareDataArrays(dataStructure.getDataRefAs(exemplarPath), dataStructure.getDataRefAs(calculatedPath)); } From 87c4f9c0b96edb26686ec1057776ae2b86494a33 Mon Sep 17 00:00:00 2001 From: Jessica Marquis Date: Mon, 19 Oct 2026 14:12:35 -0400 Subject: [PATCH 22/28] REV: Bound surface metric transfer buffers Release label slices before metric processing. Reuse bounded count and result buffers while retaining Float64 accumulation and Float32 outputs. Test batch boundaries, analytical values, and later I/O failures. Signed-off-by: Jessica Marquis --- .../docs/ComputeSurfaceAreaToVolumeFilter.md | 6 +- .../ComputeSurfaceAreaToVolumeScanline.cpp | 208 +++++++++-------- .../ComputeSurfaceAreaToVolumeScanline.hpp | 15 +- .../test/ComputeSurfaceAreaToVolumeTest.cpp | 212 ++++++++++++++++++ .../ComputeSurfaceAreaToVolumeTestUtils.hpp | 161 +++++++++++++ 5 files changed, 503 insertions(+), 99 deletions(-) diff --git a/src/Plugins/SimplnxCore/docs/ComputeSurfaceAreaToVolumeFilter.md b/src/Plugins/SimplnxCore/docs/ComputeSurfaceAreaToVolumeFilter.md index 6bff94084e..36ff9b9418 100644 --- a/src/Plugins/SimplnxCore/docs/ComputeSurfaceAreaToVolumeFilter.md +++ b/src/Plugins/SimplnxCore/docs/ComputeSurfaceAreaToVolumeFilter.md @@ -47,7 +47,11 @@ Direct reads neighboring labels from the array and accumulates one surface area ### Scanline -Scanline reads labels in sequential slices and keeps three adjacent XY slices in memory. It reads the feature counts and writes the metrics in bulk. Its additional working memory scales as `O(X * Y + F)`, where `X` and `Y` are image dimensions in cells. This avoids buffering the full label volume, but the feature arrays can still be large when the feature count approaches the cell count. These memory estimates exclude the input/output stores and their caches. +Scanline reads labels in sequential slices and keeps three adjacent XY slices in memory. It releases these slices before reading feature counts and writing metrics in bounded batches. Each batch has at most `min(65536, max(1, floor(F / 2)))` tuples, where `F` includes background. The count and result buffers together use at most 512 KiB. This is an implementation memory budget, not a limit on the number of features. + +The 64-bit area accumulator still uses eight bytes per feature tuple. Additional working memory scales as `O(X * Y + F)`, where `X` and `Y` are image dimensions in cells. Scanline avoids buffering the full label volume, but the area accumulator can still be large when the feature count approaches the cell count. These memory estimates exclude the input/output stores, their caches, and allocator overhead. + +A bulk read or write error stops execution. If a feature-count read or metric write fails after earlier batches completed, those earlier outputs remain written. Output updates are not transactional. ### Compatibility with earlier results diff --git a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeScanline.cpp b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeScanline.cpp index 53242f3d6c..56c696a1af 100644 --- a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeScanline.cpp +++ b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeScanline.cpp @@ -1,11 +1,14 @@ #include "ComputeSurfaceAreaToVolumeScanline.hpp" +#include #include #include #include "ComputeSurfaceAreaToVolume.hpp" #include "simplnx/Common/Constants.hpp" +#include "simplnx/Common/Types.hpp" +#include "simplnx/DataStructure/AbstractDataStore.hpp" #include "simplnx/DataStructure/DataArray.hpp" #include "simplnx/DataStructure/DataGroup.hpp" #include "simplnx/DataStructure/Geometry/ImageGeom.hpp" @@ -42,6 +45,10 @@ Result<> ComputeSurfaceAreaToVolumeScanline::operator()() return validateNumFeatResult; } const usize numFeatures = numCells.getNumberOfTuples(); + if(numFeatures == 0) + { + return {}; + } SizeVec3 dims = imageGeom.getDimensions(); FloatVec3 spacing = imageGeom.getSpacing(); @@ -61,151 +68,166 @@ Result<> ComputeSurfaceAreaToVolumeScanline::operator()() const usize sliceSize = static_cast(yPoints) * static_cast(xPoints); - // The rolling window turns Z-neighbor reads into sequential slice I/O. - std::vector prevSlice(sliceSize, 0); - std::vector curSlice(sliceSize, 0); - std::vector nextSlice(sliceSize, 0); - - // A bulk-I/O error stops the scan before later slices or output arrays change. - Result<> ioResult = featureIdsStore.copyIntoBuffer(0, nonstd::span(curSlice.data(), sliceSize)); - if(ioResult.invalid()) - { - return ioResult; - } - if(zPoints > 1) { - ioResult = featureIdsStore.copyIntoBuffer(sliceSize, nonstd::span(nextSlice.data(), sliceSize)); + // The rolling window turns Z-neighbor reads into sequential slice I/O. + std::vector prevSlice(sliceSize, 0); + std::vector curSlice(sliceSize, 0); + std::vector nextSlice(sliceSize, 0); + + // A bulk-I/O error stops the scan before later slices or output arrays change. + Result<> ioResult = featureIdsStore.copyIntoBuffer(0, nonstd::span(curSlice.data(), sliceSize)); if(ioResult.invalid()) { return ioResult; } - } - - for(int64 z = 0; z < zPoints; z++) - { - if(m_ShouldCancel) + if(zPoints > 1) { - return {}; + ioResult = featureIdsStore.copyIntoBuffer(sliceSize, nonstd::span(nextSlice.data(), sliceSize)); + if(ioResult.invalid()) + { + return ioResult; + } } - for(int64 y = 0; y < yPoints; y++) + + for(int64 z = 0; z < zPoints; z++) { - for(int64 x = 0; x < xPoints; x++) + if(m_ShouldCancel) + { + return {}; + } + for(int64 y = 0; y < yPoints; y++) { - const usize inSlice = static_cast(y) * static_cast(xPoints) + static_cast(x); - int32 currentFeatureId = curSlice[inSlice]; - if(currentFeatureId < 1) + for(int64 x = 0; x < xPoints; x++) { - continue; - } + const usize inSlice = static_cast(y) * static_cast(xPoints) + static_cast(x); + int32 currentFeatureId = curSlice[inSlice]; + if(currentFeatureId < 1) + { + continue; + } - float64 onSurface = 0.0; + float64 onSurface = 0.0; - // Z neighbors use adjacent buffers. X and Y neighbors use the current buffer. - if(z > 0) - { - if(prevSlice[inSlice] != currentFeatureId) + // Z neighbors use adjacent buffers. X and Y neighbors use the current buffer. + if(z > 0) { - onSurface += xyFaceArea; + if(prevSlice[inSlice] != currentFeatureId) + { + onSurface += xyFaceArea; + } } - } - if(z < zPoints - 1) - { - if(nextSlice[inSlice] != currentFeatureId) + if(z < zPoints - 1) { - onSurface += xyFaceArea; + if(nextSlice[inSlice] != currentFeatureId) + { + onSurface += xyFaceArea; + } } - } - if(y > 0) - { - if(curSlice[inSlice - static_cast(xPoints)] != currentFeatureId) + if(y > 0) { - onSurface += zxFaceArea; + if(curSlice[inSlice - static_cast(xPoints)] != currentFeatureId) + { + onSurface += zxFaceArea; + } } - } - if(y < yPoints - 1) - { - if(curSlice[inSlice + static_cast(xPoints)] != currentFeatureId) + if(y < yPoints - 1) { - onSurface += zxFaceArea; + if(curSlice[inSlice + static_cast(xPoints)] != currentFeatureId) + { + onSurface += zxFaceArea; + } } - } - if(x > 0) - { - if(curSlice[inSlice - 1] != currentFeatureId) + if(x > 0) { - onSurface += yzFaceArea; + if(curSlice[inSlice - 1] != currentFeatureId) + { + onSurface += yzFaceArea; + } } - } - if(x < xPoints - 1) - { - if(curSlice[inSlice + 1] != currentFeatureId) + if(x < xPoints - 1) { - onSurface += yzFaceArea; + if(curSlice[inSlice + 1] != currentFeatureId) + { + onSurface += yzFaceArea; + } } - } - featureSurfaceArea[currentFeatureId] += onSurface; + featureSurfaceArea[currentFeatureId] += onSurface; + } } - } - // Vector swaps rotate the window without copying a slice. - std::swap(prevSlice, curSlice); - std::swap(curSlice, nextSlice); - if(z + 2 < zPoints) - { - ioResult = featureIdsStore.copyIntoBuffer(static_cast(z + 2) * sliceSize, nonstd::span(nextSlice.data(), sliceSize)); - if(ioResult.invalid()) + // Vector swaps rotate the window without copying a slice. + std::swap(prevSlice, curSlice); + std::swap(curSlice, nextSlice); + if(z + 2 < zPoints) { - return ioResult; + ioResult = featureIdsStore.copyIntoBuffer(static_cast(z + 2) * sliceSize, nonstd::span(nextSlice.data(), sliceSize)); + if(ioResult.invalid()) + { + return ioResult; + } } } } - // Feature-level caches avoid per-value OOC access during metric calculation. - std::vector localNumCells(numFeatures); - ioResult = numCells.copyIntoBuffer(0, nonstd::span(localNumCells.data(), numFeatures)); - if(ioResult.invalid()) + // The slice buffers are released before these batches are allocated. The cap + // gives paired count/result buffers a 512 KiB budget, not a feature-count limit. + // For F >= 2, B <= F/2 also limits their combined payload to 4*F bytes. + constexpr usize k_MaxBatchTuples = 65536; + const usize batchCapacity = std::min(k_MaxBatchTuples, std::max(usize{1}, numFeatures / 2)); + std::vector localNumCells(batchCapacity); + std::vector localMetrics(batchCapacity); + + AbstractDataStore* sphericityPtr = nullptr; + if(m_InputValues->CalculateSphericity) { - return ioResult; + m_MessageHandler.sendMessage(IFilter::Message::Type::Info, fmt::format("Computing Sphericity")); + sphericityPtr = &m_DataStructure.getDataAs(m_InputValues->SphericityArrayName)->getDataStoreRef(); } - + const float64 thirdRootPi = m_InputValues->CalculateSphericity ? std::cbrt(nx::core::Constants::k_PiD) : 0.0; + for(usize offset = 0; offset < numFeatures;) { - std::vector localSurfaceAreaVolumeRatio(numFeatures, 0.0f); - for(usize i = 1; i < numFeatures; i++) - { - const float64 featureVolume = voxelVol * localNumCells[i]; - localSurfaceAreaVolumeRatio[i] = static_cast(featureSurfaceArea[i] / featureVolume); - } - ioResult = surfaceAreaVolumeRatio.copyFromBuffer(0, nonstd::span(localSurfaceAreaVolumeRatio.data(), numFeatures)); + const usize batchSize = std::min(batchCapacity, numFeatures - offset); + auto ioResult = numCells.copyIntoBuffer(offset, nonstd::span(localNumCells.data(), batchSize)); if(ioResult.invalid()) { return ioResult; } - } - if(m_InputValues->CalculateSphericity) - { - m_MessageHandler.sendMessage(IFilter::Message::Type::Info, fmt::format("Computing Sphericity")); - - auto& sphericity = m_DataStructure.getDataAs(m_InputValues->SphericityArrayName)->getDataStoreRef(); - const float64 thirdRootPi = std::cbrt(nx::core::Constants::k_PiD); - // Sphericity is one for a sphere and decreases as the surface becomes less compact. - std::vector localSphericity(numFeatures, 0.0f); - for(usize i = 1; i < numFeatures; i++) + // Background stays zero. Every other tuple uses the supplied cell count. + const usize firstFeature = offset == 0 ? 1 : 0; + localMetrics[0] = 0.0f; + for(usize i = firstFeature; i < batchSize; i++) { const float64 featureVolume = voxelVol * localNumCells[i]; - localSphericity[i] = static_cast((thirdRootPi * std::pow((6.0 * featureVolume), 2.0 / 3.0)) / featureSurfaceArea[i]); + localMetrics[i] = static_cast(featureSurfaceArea[offset + i] / featureVolume); } - ioResult = sphericity.copyFromBuffer(0, nonstd::span(localSphericity.data(), numFeatures)); + ioResult = surfaceAreaVolumeRatio.copyFromBuffer(offset, nonstd::span(localMetrics.data(), batchSize)); if(ioResult.invalid()) { return ioResult; } + + if(sphericityPtr != nullptr) + { + // Reuse the ratio buffer after its write; no second output buffer is needed. + for(usize i = firstFeature; i < batchSize; i++) + { + const float64 featureVolume = voxelVol * localNumCells[i]; + localMetrics[i] = static_cast((thirdRootPi * std::pow((6.0 * featureVolume), 2.0 / 3.0)) / featureSurfaceArea[offset + i]); + } + ioResult = sphericityPtr->copyFromBuffer(offset, nonstd::span(localMetrics.data(), batchSize)); + if(ioResult.invalid()) + { + return ioResult; + } + } + offset += batchSize; } return {}; diff --git a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeScanline.hpp b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeScanline.hpp index ce03769d4a..003def673e 100644 --- a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeScanline.hpp +++ b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeScanline.hpp @@ -13,9 +13,13 @@ struct ComputeSurfaceAreaToVolumeInputValues; * @class ComputeSurfaceAreaToVolumeScanline * @brief Computes surface metrics with a three-slice Feature Id window. * - * The window converts disk-backed neighbor reads to sequential slice I/O. Memory - * is three cell-scale slices plus feature-scale caches. Feature caches can be - * large when the feature count approaches the cell count. + * The window converts disk-backed neighbor reads to sequential slice I/O. The + * three label slices are released before count and metric batches are allocated. + * Let F be the number of feature tuples and S the number of cells per XY slice. + * For F > 0, these buffers require 8*F + max(12*S, 8*B) bytes. + * The batch capacity is B = min(65536, max(1, floor(F/2))). + * The 8*F-byte area accumulator can still be large. This estimate excludes + * stores, caches, allocator overhead, and the separate Feature Id validation. * * @see ComputeSurfaceAreaToVolumeDirect for the in-core variant. * @see ComputeSurfaceAreaToVolume for the dispatcher. @@ -48,8 +52,9 @@ class SIMPLNXCORE_EXPORT ComputeSurfaceAreaToVolumeScanline * @brief Calculates surface metrics with bulk I/O. * @return Error from Feature Id validation or bulk I/O; success on completion or cancellation. * - * Cancellation during the cell scan leaves metric outputs unchanged. A bulk-I/O - * error stops processing. An output write error can leave partial metric outputs. + * At each slice start, cancellation stops processing before metric writes. + * A bulk-I/O error stops processing. A later count read or metric write error + * can leave earlier batches written. Output updates are not transactional. */ Result<> operator()(); diff --git a/src/Plugins/SimplnxCore/test/ComputeSurfaceAreaToVolumeTest.cpp b/src/Plugins/SimplnxCore/test/ComputeSurfaceAreaToVolumeTest.cpp index 67830892ee..275d16e742 100644 --- a/src/Plugins/SimplnxCore/test/ComputeSurfaceAreaToVolumeTest.cpp +++ b/src/Plugins/SimplnxCore/test/ComputeSurfaceAreaToVolumeTest.cpp @@ -1,13 +1,21 @@ +#include "SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolume.hpp" +#include "SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeScanline.hpp" #include "SimplnxCore/Filters/ComputeSurfaceAreaToVolumeFilter.hpp" #include "SimplnxCore/SimplnxCore_test_dirs.hpp" #include "ComputeSurfaceAreaToVolumeTestUtils.hpp" +#include "simplnx/Common/Result.hpp" +#include "simplnx/Common/Types.hpp" #include "simplnx/DataStructure/AttributeMatrix.hpp" #include "simplnx/DataStructure/DataArray.hpp" +#include "simplnx/DataStructure/DataPath.hpp" +#include "simplnx/DataStructure/DataStore.hpp" +#include "simplnx/DataStructure/DataStructure.hpp" #include "simplnx/DataStructure/Geometry/ImageGeom.hpp" #include "simplnx/DataStructure/NeighborList.hpp" #include "simplnx/DataStructure/StringArray.hpp" +#include "simplnx/Filter/IFilter.hpp" #include "simplnx/Parameters/ArrayCreationParameter.hpp" #include "simplnx/Parameters/BoolParameter.hpp" #include "simplnx/UnitTest/UnitTestCommon.hpp" @@ -15,8 +23,16 @@ #include "simplnx/Utilities/DataStoreUtilities.hpp" #include +#include +#include +#include +#include +#include #include +#include +#include +#include namespace fs = std::filesystem; @@ -36,6 +52,46 @@ constexpr usize k_TotalVoxels = k_Dim * k_Dim * k_Dim; constexpr int32 k_NumOctantFeatures = 8; const std::string k_GeomName = "ImageGeom"; +// Resident test stores observe Scanline transfers without adding a production fault hook. +template +class SurfaceMetricTransferStore : public DataStore +{ +public: + SurfaceMetricTransferStore(usize numTuples, T initialValue, usize failRead = 0, usize failWrite = 0) + : DataStore(numTuples, initialValue) + , m_FailRead(failRead) + , m_FailWrite(failWrite) + { + } + + Result<> copyIntoBuffer(usize offset, nonstd::span buffer) const override + { + Reads.push_back({offset, buffer.size()}); + if(Reads.size() == m_FailRead) + { + return MakeErrorResult(-94801, "Injected surface metric input read failure"); + } + return DataStore::copyIntoBuffer(offset, buffer); + } + + Result<> copyFromBuffer(usize offset, nonstd::span buffer) override + { + Writes.push_back({offset, buffer.size()}); + if(Writes.size() == m_FailWrite) + { + return MakeErrorResult(-94802, "Injected surface metric output write failure"); + } + return DataStore::copyFromBuffer(offset, buffer); + } + + mutable std::vector> Reads; + std::vector> Writes; + +private: + usize m_FailRead = 0; + usize m_FailWrite = 0; +}; + void BuildOctantWithNumCells(DataStructure& ds) { const ShapeType cellTupleShape = {k_Dim, k_Dim, k_Dim}; @@ -90,6 +146,162 @@ void BuildOctantWithNumCells(DataStructure& ds) } } // namespace +TEST_CASE("SimplnxCore::ComputeSurfaceAreaToVolumeFilter: sparse feature table batch boundaries", "[SimplnxCore][ComputeSurfaceAreaToVolumeFilter]") +{ + UnitTest::LoadPlugins(); + const auto scenario = GENERATE(from_range(UnitTest::SelectAlgorithmTestScenariosForInMemoryStores())); + const auto numFeatures = GENERATE(usize{1}, usize{2}, usize{3}, usize{7}, usize{131071}, usize{131072}, usize{131073}); + const bool calculateSphericity = GENERATE(false, true); + CAPTURE(scenario, numFeatures, calculateSphericity); + UnitTest::AlgorithmTestScope scope(scenario); + SurfaceAreaToVolumeTest::CheckSparseFeatureSurfaceMetrics(scope, numFeatures, calculateSphericity); +} + +TEST_CASE("SimplnxCore::ComputeSurfaceAreaToVolumeScanline: bounded metric transfers", "[SimplnxCore][ComputeSurfaceAreaToVolumeFilter]") +{ + UnitTest::LoadPlugins(); + // This targets Scanline directly: the test contract is its bulk-transfer bound, not dispatch. + const auto featureAndBatchCounts = GENERATE(std::pair{0, 1}, std::pair{1, 1}, std::pair{2, 1}, std::pair{3, 1}, std::pair{7, 3}, + std::pair{131071, 65535}, std::pair{131072, 65536}, std::pair{131073, 65536}); + const auto [numFeatures, batchCapacity] = featureAndBatchCounts; + const bool calculateSphericity = GENERATE(false, true); + CAPTURE(numFeatures, batchCapacity, calculateSphericity); + DataStructure dataStructure; + const auto occupiedFeatures = SurfaceAreaToVolumeTest::BuildSparseFeatureSurfaceData(dataStructure, numFeatures); + const DataPath featurePath({"ImageGeom", "CellFeatureData"}); + const DataPath countsPath = featurePath.createChildPath("NumCells"); + REQUIRE_NOTHROW(dataStructure.getDataRefAs(featurePath)); + const auto featureId = dataStructure.getDataRefAs(featurePath).getId(); + auto countsStore = std::make_shared>(numFeatures, 0); + for(const usize feature : occupiedFeatures) + { + countsStore->setValue(feature, 1); + } + REQUIRE_NOTHROW(dataStructure.getDataRefAs(countsPath)); + const auto replacement = dataStructure.getDataRefAs(countsPath).setDataStore(countsStore); + SIMPLNX_RESULT_REQUIRE_VALID(replacement); + auto ratioStore = std::make_shared>(numFeatures, -47.0f); + REQUIRE(Float32Array::Create(dataStructure, "SurfaceAreaVolumeRatio", ratioStore, featureId) != nullptr); + auto sphericityStore = std::make_shared>(numFeatures, -47.0f); + if(calculateSphericity) + { + REQUIRE(Float32Array::Create(dataStructure, "Sphericity", sphericityStore, featureId) != nullptr); + } + const ComputeSurfaceAreaToVolumeInputValues inputValues = {.FeatureIdsArrayPath = DataPath({"ImageGeom", "CellData", "FeatureIds"}), + .NumCellsArrayPath = countsPath, + .SurfaceAreaVolumeRatioArrayName = featurePath.createChildPath("SurfaceAreaVolumeRatio"), + .CalculateSphericity = calculateSphericity, + .SphericityArrayName = featurePath.createChildPath("Sphericity"), + .InputImageGeometry = DataPath({"ImageGeom"})}; + const std::atomic_bool shouldCancel = false; + const IFilter::MessageHandler messageHandler; + const auto result = ComputeSurfaceAreaToVolumeScanline(dataStructure, messageHandler, shouldCancel, &inputValues)(); + SIMPLNX_RESULT_REQUIRE_VALID(result); + + std::vector> expectedTransfers; + for(usize offset = 0; offset < numFeatures; offset += batchCapacity) + { + expectedTransfers.push_back({offset, std::min(batchCapacity, numFeatures - offset)}); + } + CHECK(countsStore->Reads == expectedTransfers); + CHECK(ratioStore->Writes == expectedTransfers); + if(calculateSphericity) + { + CHECK(sphericityStore->Writes == expectedTransfers); + } + else + { + CHECK(sphericityStore->Writes.empty()); + } + if(numFeatures > 0) + { + CHECK(ratioStore->getValue(0) == 0.0f); + if(calculateSphericity) + { + CHECK(sphericityStore->getValue(0) == 0.0f); + } + } + UnitTest::CheckArraysInheritTupleDims(dataStructure); +} + +TEST_CASE("SimplnxCore::ComputeSurfaceAreaToVolumeScanline: later metric I/O failures preserve prior batches", "[SimplnxCore][ComputeSurfaceAreaToVolumeFilter]") +{ + UnitTest::LoadPlugins(); + // Exercise each failed operation on the second batch, after the first batch was written. + const int failure = GENERATE(0, 1, 2); // NumCells read, ratio write, sphericity write. + CAPTURE(failure); + constexpr usize k_NumFeatures = 7; + constexpr float32 k_Unwritten = -47.0f; + DataStructure dataStructure; + const auto occupiedFeatures = SurfaceAreaToVolumeTest::BuildSparseFeatureSurfaceData(dataStructure, k_NumFeatures); + const DataPath featurePath({"ImageGeom", "CellFeatureData"}); + const DataPath countsPath = featurePath.createChildPath("NumCells"); + REQUIRE_NOTHROW(dataStructure.getDataRefAs(featurePath)); + const auto featureId = dataStructure.getDataRefAs(featurePath).getId(); + auto countsStore = std::make_shared>(k_NumFeatures, 0, failure == 0 ? 2 : 0); + for(const usize feature : occupiedFeatures) + { + countsStore->setValue(feature, 1); + } + REQUIRE_NOTHROW(dataStructure.getDataRefAs(countsPath)); + const auto replacement = dataStructure.getDataRefAs(countsPath).setDataStore(countsStore); + SIMPLNX_RESULT_REQUIRE_VALID(replacement); + auto ratioStore = std::make_shared>(k_NumFeatures, k_Unwritten, 0, failure == 1 ? 2 : 0); + auto sphericityStore = std::make_shared>(k_NumFeatures, k_Unwritten, 0, failure == 2 ? 2 : 0); + REQUIRE(Float32Array::Create(dataStructure, "SurfaceAreaVolumeRatio", ratioStore, featureId) != nullptr); + REQUIRE(Float32Array::Create(dataStructure, "Sphericity", sphericityStore, featureId) != nullptr); + const ComputeSurfaceAreaToVolumeInputValues inputValues = {.FeatureIdsArrayPath = DataPath({"ImageGeom", "CellData", "FeatureIds"}), + .NumCellsArrayPath = countsPath, + .SurfaceAreaVolumeRatioArrayName = featurePath.createChildPath("SurfaceAreaVolumeRatio"), + .CalculateSphericity = true, + .SphericityArrayName = featurePath.createChildPath("Sphericity"), + .InputImageGeometry = DataPath({"ImageGeom"})}; + const std::atomic_bool shouldCancel = false; + const IFilter::MessageHandler messageHandler; + const auto result = ComputeSurfaceAreaToVolumeScanline(dataStructure, messageHandler, shouldCancel, &inputValues)(); + SIMPLNX_RESULT_REQUIRE_INVALID(result); + REQUIRE(result.errors().size() == 1); + CHECK(result.errors().front().code == (failure == 0 ? -94801 : -94802)); + CHECK(countsStore->Reads.size() == 2); + CHECK(ratioStore->Writes.size() == (failure == 0 ? 1 : 2)); + CHECK(sphericityStore->Writes.size() == (failure == 2 ? 2 : 1)); + + const double pi = std::acos(-1.0); + const double sphereRadius = std::cbrt(3.0 * 30.0 / (4.0 * pi)); + const double expectedSphericity = 4.0 * pi * sphereRadius * sphereRadius / 62.0; + CHECK(ratioStore->getValue(0) == 0.0f); + CHECK(sphericityStore->getValue(0) == 0.0f); + for(usize feature = 1; feature < k_NumFeatures; ++feature) + { + CAPTURE(feature); + const bool occupied = std::binary_search(occupiedFeatures.begin(), occupiedFeatures.end(), feature); + if(feature < (failure == 2 ? 6 : 3)) + { + if(occupied) + { + CHECK(ratioStore->getValue(feature) == Approx(62.0 / 30.0).epsilon(1.0e-6)); + } + else + { + CHECK(std::isnan(ratioStore->getValue(feature))); + } + } + else + { + CHECK(ratioStore->getValue(feature) == k_Unwritten); + } + if(feature < 3) + { + CHECK(sphericityStore->getValue(feature) == Approx(expectedSphericity).epsilon(1.0e-6)); + } + else + { + CHECK(sphericityStore->getValue(feature) == k_Unwritten); + } + } + UnitTest::CheckArraysInheritTupleDims(dataStructure); +} + TEST_CASE("SimplnxCore::ComputeSurfaceAreaToVolumeFilter: geometry and FeatureIds tuple cardinality", "[SimplnxCore][ComputeSurfaceAreaToVolumeFilter]") { UnitTest::LoadPlugins(); diff --git a/src/Plugins/SimplnxCore/test/ComputeSurfaceAreaToVolumeTestUtils.hpp b/src/Plugins/SimplnxCore/test/ComputeSurfaceAreaToVolumeTestUtils.hpp index faa3584114..a7c8ce2c1b 100644 --- a/src/Plugins/SimplnxCore/test/ComputeSurfaceAreaToVolumeTestUtils.hpp +++ b/src/Plugins/SimplnxCore/test/ComputeSurfaceAreaToVolumeTestUtils.hpp @@ -2,21 +2,182 @@ #include "SimplnxCore/Filters/ComputeSurfaceAreaToVolumeFilter.hpp" +#include "simplnx/Common/Result.hpp" +#include "simplnx/Common/Types.hpp" #include "simplnx/DataStructure/AttributeMatrix.hpp" #include "simplnx/DataStructure/DataArray.hpp" +#include "simplnx/DataStructure/DataPath.hpp" +#include "simplnx/DataStructure/DataStructure.hpp" #include "simplnx/DataStructure/Geometry/ImageGeom.hpp" +#include "simplnx/Filter/Arguments.hpp" #include "simplnx/UnitTest/UnitTestCommon.hpp" #include "simplnx/Utilities/DataStoreUtilities.hpp" #include +#include #include +#include #include #include +#include #include namespace SurfaceAreaToVolumeTest { +/** + * @brief Builds isolated cells that exercise large feature tables in a small image. + * @param dataStructure Receives the geometry, labels, and supplied cell counts. + * @param numFeatures Number of feature tuples, including background. Zero creates empty inputs. + * @return Sorted feature identifiers for the isolated one-cell boxes. + */ +inline std::vector BuildSparseFeatureSurfaceData(nx::core::DataStructure& dataStructure, nx::core::usize numFeatures) +{ + using namespace nx::core; + const DataPath geomPath({"ImageGeom"}); + const DataPath cellPath = geomPath.createChildPath("CellData"); + const DataPath featurePath = geomPath.createChildPath("CellFeatureData"); + const DataPath idsPath = cellPath.createChildPath("FeatureIds"); + const DataPath countsPath = featurePath.createChildPath("NumCells"); + const ShapeType cellShape = numFeatures == 0 ? ShapeType{0, 0, 0} : ShapeType{3, 3, 19}; + const ShapeType featureShape = {numFeatures}; + auto* geomPtr = ImageGeom::Create(dataStructure, geomPath.getTargetName()); + REQUIRE(geomPtr != nullptr); + geomPtr->setDimensions({cellShape[2], cellShape[1], cellShape[0]}); + geomPtr->setSpacing({2.0f, 3.0f, 5.0f}); + auto* cellAMPtr = AttributeMatrix::Create(dataStructure, cellPath.getTargetName(), cellShape, geomPtr->getId()); + REQUIRE(cellAMPtr != nullptr); + geomPtr->setCellData(*cellAMPtr); + auto* featureAMPtr = AttributeMatrix::Create(dataStructure, featurePath.getTargetName(), featureShape, geomPtr->getId()); + REQUIRE(featureAMPtr != nullptr); + + auto idsStore = DataStoreUtilities::CreateDataStore(dataStructure, idsPath, cellShape, {1}); + auto countsStore = DataStoreUtilities::CreateDataStore(dataStructure, countsPath, featureShape, {1}); + REQUIRE(idsStore != nullptr); + REQUIRE(countsStore != nullptr); + REQUIRE(Int32Array::Create(dataStructure, idsPath.getTargetName(), idsStore, cellAMPtr->getId()) != nullptr); + REQUIRE(Int32Array::Create(dataStructure, countsPath.getTargetName(), countsStore, featureAMPtr->getId()) != nullptr); + if(numFeatures == 0) + { + return {}; + } + + // Probe both sides of the half-table and fixed-cap boundaries, plus the last tuple. + std::vector occupiedFeatures = {1, numFeatures / 2, numFeatures / 2 + 1, numFeatures - 1, 65535, 65536, 65537}; + if(numFeatures > 3) + { + occupiedFeatures.push_back(numFeatures / 2 - 1); + } + std::erase_if(occupiedFeatures, [numFeatures](usize feature) { return feature == 0 || feature >= numFeatures; }); + std::sort(occupiedFeatures.begin(), occupiedFeatures.end()); + occupiedFeatures.erase(std::unique(occupiedFeatures.begin(), occupiedFeatures.end()), occupiedFeatures.end()); + REQUIRE(occupiedFeatures.size() <= 8); + std::vector labels(19 * 3 * 3, 0); + std::vector counts(numFeatures, 0); + for(usize index = 0; index < occupiedFeatures.size(); ++index) + { + // Background separates every one-cell box from its neighbors and the image exterior. + labels[(1 * 3 + 1) * 19 + 1 + 2 * index] = static_cast(occupiedFeatures[index]); + counts[occupiedFeatures[index]] = 1; + } + counts[0] = static_cast(labels.size() - occupiedFeatures.size()); + const auto idsWrite = idsStore->copyFromBuffer(0, nonstd::span(labels.data(), labels.size())); + SIMPLNX_RESULT_REQUIRE_VALID(idsWrite); + const auto countsWrite = countsStore->copyFromBuffer(0, nonstd::span(counts.data(), counts.size())); + SIMPLNX_RESULT_REQUIRE_VALID(countsWrite); + return occupiedFeatures; +} + +/** + * @brief Checks all sparse-table metrics against box and equal-volume sphere geometry. + * @tparam ScopeT Verifies the selected algorithm and actual array storage. + * @param scope Active algorithm and storage scenario. + * @param numFeatures Number of feature tuples, including background. Must be positive. + * @param calculateSphericity Enables the optional sphere-area ratio check. + */ +template +void CheckSparseFeatureSurfaceMetrics(ScopeT& scope, nx::core::usize numFeatures, bool calculateSphericity) +{ + using namespace nx::core; + REQUIRE(numFeatures > 0); + DataStructure dataStructure; + const auto occupiedFeatures = BuildSparseFeatureSurfaceData(dataStructure, numFeatures); + const DataPath geomPath({"ImageGeom"}); + const DataPath idsPath({"ImageGeom", "CellData", "FeatureIds"}); + const DataPath featurePath({"ImageGeom", "CellFeatureData"}); + const DataPath countsPath = featurePath.createChildPath("NumCells"); + const DataPath ratioPath = featurePath.createChildPath("SurfaceAreaVolumeRatio"); + const DataPath sphericityPath = featurePath.createChildPath("Sphericity"); + REQUIRE_NOTHROW(dataStructure.getDataRefAs(idsPath)); + REQUIRE_NOTHROW(dataStructure.getDataRefAs(countsPath)); + scope.requireExpectedStore(dataStructure.getDataRefAs(idsPath)); + scope.requireExpectedStore(dataStructure.getDataRefAs(countsPath)); + + ComputeSurfaceAreaToVolumeFilter filter; + Arguments args = filter.getDefaultArguments(); + args.insertOrAssign(ComputeSurfaceAreaToVolumeFilter::k_SelectedImageGeometryPath_Key, std::make_any(geomPath)); + args.insertOrAssign(ComputeSurfaceAreaToVolumeFilter::k_CellFeatureIdsArrayPath_Key, std::make_any(idsPath)); + args.insertOrAssign(ComputeSurfaceAreaToVolumeFilter::k_NumCellsArrayPath_Key, std::make_any(countsPath)); + args.insertOrAssign(ComputeSurfaceAreaToVolumeFilter::k_CalculateSphericity_Key, std::make_any(calculateSphericity)); + const auto result = scope.executeFilter(filter, dataStructure, args); + SIMPLNX_RESULT_REQUIRE_VALID(result.result); + + REQUIRE_NOTHROW(dataStructure.getDataRefAs(ratioPath)); + const auto& ratios = dataStructure.getDataRefAs(ratioPath); + scope.requireExpectedStore(ratios); + CHECK(ratios.getTupleShape() == ShapeType{numFeatures}); + CHECK(ratios.getComponentShape() == ShapeType{1}); + std::vector values(numFeatures); + const auto ratioRead = ratios.getDataStoreRef().copyIntoBuffer(0, nonstd::span(values.data(), values.size())); + SIMPLNX_RESULT_REQUIRE_VALID(ratioRead); + CHECK(values[0] == 0.0f); + // An isolated 2-by-3-by-5 box has area 62 and volume 30. + for(usize feature = 1; feature < numFeatures; ++feature) + { + CAPTURE(feature); + if(std::binary_search(occupiedFeatures.begin(), occupiedFeatures.end(), feature)) + { + REQUIRE(values[feature] == Approx(62.0 / 30.0).epsilon(1.0e-6)); + } + else + { + REQUIRE(std::isnan(values[feature])); + } + } + if(calculateSphericity) + { + REQUIRE_NOTHROW(dataStructure.getDataRefAs(sphericityPath)); + const auto& sphericity = dataStructure.getDataRefAs(sphericityPath); + scope.requireExpectedStore(sphericity); + CHECK(sphericity.getTupleShape() == ShapeType{numFeatures}); + CHECK(sphericity.getComponentShape() == ShapeType{1}); + const auto sphericityRead = sphericity.getDataStoreRef().copyIntoBuffer(0, nonstd::span(values.data(), values.size())); + SIMPLNX_RESULT_REQUIRE_VALID(sphericityRead); + CHECK(values[0] == 0.0f); + // Independently calculate the equal-volume sphere from its radius. + const double pi = std::acos(-1.0); + const double radius = std::cbrt(3.0 * 30.0 / (4.0 * pi)); + const double expected = 4.0 * pi * radius * radius / 62.0; + for(usize feature = 1; feature < numFeatures; ++feature) + { + CAPTURE(feature); + if(std::binary_search(occupiedFeatures.begin(), occupiedFeatures.end(), feature)) + { + REQUIRE(values[feature] == Approx(expected).epsilon(1.0e-6)); + } + else + { + REQUIRE(std::isnan(values[feature])); + } + } + } + else + { + CHECK(dataStructure.getData(sphericityPath) == nullptr); + } + UnitTest::CheckArraysInheritTupleDims(dataStructure); +} + // A wrong X/Y face weight changes the physical area of this interior box. template std::array CheckInteriorPairSurfaceMetrics(ScopeT& scope, nx::core::usize pairAxis, const nx::core::FloatVec3& spacing, bool calculateSphericity, bool singleSlice = false, From 7f2c0f3044e95507958a5c95aa0da20ac3be30c1 Mon Sep 17 00:00:00 2001 From: Jessica Marquis Date: Mon, 19 Oct 2026 14:30:47 -0400 Subject: [PATCH 23/28] REV: Apply surface metric coding standards Declare direct dependencies and use the configured naming conventions. Preserve invalid-result details and make test buffer access explicit. Keep the analytical expectations and scientific calculations unchanged. Signed-off-by: Jessica Marquis --- .../ComputeSurfaceAreaToVolumeDirect.cpp | 1 + .../ComputeSurfaceAreaToVolumeScanline.cpp | 42 +-- .../ComputeSurfaceAreaToVolumeFilter.cpp | 15 +- .../test/ComputeSurfaceAreaToVolumeTest.cpp | 245 ++++++++++-------- .../ComputeSurfaceAreaToVolumeTestUtils.hpp | 205 +++++++-------- src/simplnx/Utilities/DataArrayUtilities.cpp | 2 + src/simplnx/Utilities/DataArrayUtilities.hpp | 2 + test/DataArrayTest.cpp | 21 +- 8 files changed, 295 insertions(+), 238 deletions(-) diff --git a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeDirect.cpp b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeDirect.cpp index 265c86178b..91aedaf4f9 100644 --- a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeDirect.cpp +++ b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeDirect.cpp @@ -7,6 +7,7 @@ #include "ComputeSurfaceAreaToVolume.hpp" #include "simplnx/Common/Constants.hpp" +#include "simplnx/Common/Types.hpp" #include "simplnx/DataStructure/DataArray.hpp" #include "simplnx/DataStructure/DataGroup.hpp" #include "simplnx/DataStructure/Geometry/ImageGeom.hpp" diff --git a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeScanline.cpp b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeScanline.cpp index 56c696a1af..e0cc80ae7c 100644 --- a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeScanline.cpp +++ b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolumeScanline.cpp @@ -89,18 +89,18 @@ Result<> ComputeSurfaceAreaToVolumeScanline::operator()() } } - for(int64 z = 0; z < zPoints; z++) + for(int64 zIndex = 0; zIndex < zPoints; zIndex++) { if(m_ShouldCancel) { return {}; } - for(int64 y = 0; y < yPoints; y++) + for(int64 yIndex = 0; yIndex < yPoints; yIndex++) { - for(int64 x = 0; x < xPoints; x++) + for(int64 xIndex = 0; xIndex < xPoints; xIndex++) { - const usize inSlice = static_cast(y) * static_cast(xPoints) + static_cast(x); - int32 currentFeatureId = curSlice[inSlice]; + const usize inSlice = (static_cast(yIndex) * static_cast(xPoints)) + static_cast(xIndex); + const int32 currentFeatureId = curSlice[inSlice]; if(currentFeatureId < 1) { continue; @@ -109,7 +109,7 @@ Result<> ComputeSurfaceAreaToVolumeScanline::operator()() float64 onSurface = 0.0; // Z neighbors use adjacent buffers. X and Y neighbors use the current buffer. - if(z > 0) + if(zIndex > 0) { if(prevSlice[inSlice] != currentFeatureId) { @@ -117,7 +117,7 @@ Result<> ComputeSurfaceAreaToVolumeScanline::operator()() } } - if(z < zPoints - 1) + if(zIndex < zPoints - 1) { if(nextSlice[inSlice] != currentFeatureId) { @@ -125,7 +125,7 @@ Result<> ComputeSurfaceAreaToVolumeScanline::operator()() } } - if(y > 0) + if(yIndex > 0) { if(curSlice[inSlice - static_cast(xPoints)] != currentFeatureId) { @@ -133,7 +133,7 @@ Result<> ComputeSurfaceAreaToVolumeScanline::operator()() } } - if(y < yPoints - 1) + if(yIndex < yPoints - 1) { if(curSlice[inSlice + static_cast(xPoints)] != currentFeatureId) { @@ -141,7 +141,7 @@ Result<> ComputeSurfaceAreaToVolumeScanline::operator()() } } - if(x > 0) + if(xIndex > 0) { if(curSlice[inSlice - 1] != currentFeatureId) { @@ -149,7 +149,7 @@ Result<> ComputeSurfaceAreaToVolumeScanline::operator()() } } - if(x < xPoints - 1) + if(xIndex < xPoints - 1) { if(curSlice[inSlice + 1] != currentFeatureId) { @@ -164,9 +164,9 @@ Result<> ComputeSurfaceAreaToVolumeScanline::operator()() // Vector swaps rotate the window without copying a slice. std::swap(prevSlice, curSlice); std::swap(curSlice, nextSlice); - if(z + 2 < zPoints) + if(zIndex + 2 < zPoints) { - ioResult = featureIdsStore.copyIntoBuffer(static_cast(z + 2) * sliceSize, nonstd::span(nextSlice.data(), sliceSize)); + ioResult = featureIdsStore.copyIntoBuffer(static_cast(zIndex + 2) * sliceSize, nonstd::span(nextSlice.data(), sliceSize)); if(ioResult.invalid()) { return ioResult; @@ -178,8 +178,8 @@ Result<> ComputeSurfaceAreaToVolumeScanline::operator()() // The slice buffers are released before these batches are allocated. The cap // gives paired count/result buffers a 512 KiB budget, not a feature-count limit. // For F >= 2, B <= F/2 also limits their combined payload to 4*F bytes. - constexpr usize k_MaxBatchTuples = 65536; - const usize batchCapacity = std::min(k_MaxBatchTuples, std::max(usize{1}, numFeatures / 2)); + constexpr usize maxBatchTuples = 65536; + const usize batchCapacity = std::min(maxBatchTuples, std::max(usize{1}, numFeatures / 2)); std::vector localNumCells(batchCapacity); std::vector localMetrics(batchCapacity); @@ -202,10 +202,10 @@ Result<> ComputeSurfaceAreaToVolumeScanline::operator()() // Background stays zero. Every other tuple uses the supplied cell count. const usize firstFeature = offset == 0 ? 1 : 0; localMetrics[0] = 0.0f; - for(usize i = firstFeature; i < batchSize; i++) + for(usize batchIndex = firstFeature; batchIndex < batchSize; batchIndex++) { - const float64 featureVolume = voxelVol * localNumCells[i]; - localMetrics[i] = static_cast(featureSurfaceArea[offset + i] / featureVolume); + const float64 featureVolume = voxelVol * localNumCells[batchIndex]; + localMetrics[batchIndex] = static_cast(featureSurfaceArea[offset + batchIndex] / featureVolume); } ioResult = surfaceAreaVolumeRatio.copyFromBuffer(offset, nonstd::span(localMetrics.data(), batchSize)); if(ioResult.invalid()) @@ -216,10 +216,10 @@ Result<> ComputeSurfaceAreaToVolumeScanline::operator()() if(sphericityPtr != nullptr) { // Reuse the ratio buffer after its write; no second output buffer is needed. - for(usize i = firstFeature; i < batchSize; i++) + for(usize batchIndex = firstFeature; batchIndex < batchSize; batchIndex++) { - const float64 featureVolume = voxelVol * localNumCells[i]; - localMetrics[i] = static_cast((thirdRootPi * std::pow((6.0 * featureVolume), 2.0 / 3.0)) / featureSurfaceArea[offset + i]); + const float64 featureVolume = voxelVol * localNumCells[batchIndex]; + localMetrics[batchIndex] = static_cast((thirdRootPi * std::pow((6.0 * featureVolume), 2.0 / 3.0)) / featureSurfaceArea[offset + batchIndex]); } ioResult = sphericityPtr->copyFromBuffer(offset, nonstd::span(localMetrics.data(), batchSize)); if(ioResult.invalid()) diff --git a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/ComputeSurfaceAreaToVolumeFilter.cpp b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/ComputeSurfaceAreaToVolumeFilter.cpp index bed8c1bd68..e3c4d65dc1 100644 --- a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/ComputeSurfaceAreaToVolumeFilter.cpp +++ b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/ComputeSurfaceAreaToVolumeFilter.cpp @@ -2,11 +2,14 @@ #include "SimplnxCore/Filters/Algorithms/ComputeSurfaceAreaToVolume.hpp" +#include "simplnx/Common/Result.hpp" #include "simplnx/DataStructure/AttributeMatrix.hpp" #include "simplnx/DataStructure/DataArray.hpp" +#include "simplnx/DataStructure/DataObject.hpp" #include "simplnx/DataStructure/DataPath.hpp" #include "simplnx/DataStructure/Geometry/ImageGeom.hpp" #include "simplnx/Filter/Actions/CreateArrayAction.hpp" +#include "simplnx/Filter/Output.hpp" #include "simplnx/Parameters/ArraySelectionParameter.hpp" #include "simplnx/Parameters/BoolParameter.hpp" #include "simplnx/Parameters/DataObjectNameParameter.hpp" @@ -16,6 +19,10 @@ #include "simplnx/Parameters/GeometrySelectionParameter.hpp" +#include + +#include + using namespace nx::core; namespace nx::core @@ -103,17 +110,17 @@ IFilter::PreflightResult ComputeSurfaceAreaToVolumeFilter::preflightImpl(const D // ArraySelectionParameter also accepts StringArray and NeighborList for numeric selections. // Keep the local type checks until the parameter validates supported array kinds. // TODO(#1833): Revisit these guards after the shared fix preserves generic array support. - const auto* featureIds = dataStructure.getDataAs(pFeatureIdsArrayPathValue); - if(featureIds == nullptr) + const auto* featureIdsPtr = dataStructure.getDataAs(pFeatureIdsArrayPathValue); + if(featureIdsPtr == nullptr) { const auto& selectedObject = dataStructure.getDataRefAs(pFeatureIdsArrayPathValue); return MakePreflightErrorResult(-12803, fmt::format("The selected Feature Ids object '{}' has type '{}', but a scalar int32 DataArray is required. Select a scalar int32 DataArray.", pFeatureIdsArrayPathValue.toString(), selectedObject.getTypeName())); } - auto tupleCountResult = ValidateCellTupleCount(imageGeom, pImageGeometryPathValue, featureIds->getNumberOfTuples(), pFeatureIdsArrayPathValue, -12804); + auto tupleCountResult = ValidateCellTupleCount(imageGeom, pImageGeometryPathValue, featureIdsPtr->getNumberOfTuples(), pFeatureIdsArrayPathValue, -12804); if(tupleCountResult.invalid()) { - return {ConvertResultTo(std::move(tupleCountResult), {})}; + return {.outputActions = ConvertInvalidResult(std::move(tupleCountResult))}; } PreflightResult preflightResult; diff --git a/src/Plugins/SimplnxCore/test/ComputeSurfaceAreaToVolumeTest.cpp b/src/Plugins/SimplnxCore/test/ComputeSurfaceAreaToVolumeTest.cpp index 275d16e742..9710f541b8 100644 --- a/src/Plugins/SimplnxCore/test/ComputeSurfaceAreaToVolumeTest.cpp +++ b/src/Plugins/SimplnxCore/test/ComputeSurfaceAreaToVolumeTest.cpp @@ -5,6 +5,8 @@ #include "ComputeSurfaceAreaToVolumeTestUtils.hpp" +#include "simplnx/Common/Aliases.hpp" +#include "simplnx/Common/Array.hpp" #include "simplnx/Common/Result.hpp" #include "simplnx/Common/Types.hpp" #include "simplnx/DataStructure/AttributeMatrix.hpp" @@ -13,24 +15,30 @@ #include "simplnx/DataStructure/DataStore.hpp" #include "simplnx/DataStructure/DataStructure.hpp" #include "simplnx/DataStructure/Geometry/ImageGeom.hpp" +#include "simplnx/DataStructure/IDataArray.hpp" #include "simplnx/DataStructure/NeighborList.hpp" #include "simplnx/DataStructure/StringArray.hpp" +#include "simplnx/Filter/Arguments.hpp" #include "simplnx/Filter/IFilter.hpp" #include "simplnx/Parameters/ArrayCreationParameter.hpp" #include "simplnx/Parameters/BoolParameter.hpp" +#include "simplnx/UnitTest/AlgorithmTestScope.hpp" #include "simplnx/UnitTest/UnitTestCommon.hpp" #include "simplnx/Utilities/AlgorithmDispatch.hpp" #include "simplnx/Utilities/DataStoreUtilities.hpp" #include +#include #include #include +#include #include #include #include #include #include +#include #include #include @@ -57,17 +65,43 @@ template class SurfaceMetricTransferStore : public DataStore { public: - SurfaceMetricTransferStore(usize numTuples, T initialValue, usize failRead = 0, usize failWrite = 0) + SurfaceMetricTransferStore(usize numTuples, T initialValue) : DataStore(numTuples, initialValue) - , m_FailRead(failRead) - , m_FailWrite(failWrite) { } + /** + * @brief Selects the read that returns an injected error before copying data. + * @param readNumber One-based call number; zero disables the injected error. + */ + void failReadOn(usize readNumber) + { + m_FailRead = readNumber; + } + + /** + * @brief Selects the write that returns an injected error before copying data. + * @param writeNumber One-based call number; zero disables the injected error. + */ + void failWriteOn(usize writeNumber) + { + m_FailWrite = writeNumber; + } + + const std::vector>& getReads() const + { + return m_Reads; + } + + const std::vector>& getWrites() const + { + return m_Writes; + } + Result<> copyIntoBuffer(usize offset, nonstd::span buffer) const override { - Reads.push_back({offset, buffer.size()}); - if(Reads.size() == m_FailRead) + m_Reads.push_back({offset, buffer.size()}); + if(m_Reads.size() == m_FailRead) { return MakeErrorResult(-94801, "Injected surface metric input read failure"); } @@ -76,18 +110,17 @@ class SurfaceMetricTransferStore : public DataStore Result<> copyFromBuffer(usize offset, nonstd::span buffer) override { - Writes.push_back({offset, buffer.size()}); - if(Writes.size() == m_FailWrite) + m_Writes.push_back({offset, buffer.size()}); + if(m_Writes.size() == m_FailWrite) { return MakeErrorResult(-94802, "Injected surface metric output write failure"); } return DataStore::copyFromBuffer(offset, buffer); } - mutable std::vector> Reads; - std::vector> Writes; - private: + mutable std::vector> m_Reads; + std::vector> m_Writes; usize m_FailRead = 0; usize m_FailWrite = 0; }; @@ -154,7 +187,7 @@ TEST_CASE("SimplnxCore::ComputeSurfaceAreaToVolumeFilter: sparse feature table b const bool calculateSphericity = GENERATE(false, true); CAPTURE(scenario, numFeatures, calculateSphericity); UnitTest::AlgorithmTestScope scope(scenario); - SurfaceAreaToVolumeTest::CheckSparseFeatureSurfaceMetrics(scope, numFeatures, calculateSphericity); + surface_area_to_volume_test::CheckSparseFeatureSurfaceMetrics(scope, numFeatures, calculateSphericity); } TEST_CASE("SimplnxCore::ComputeSurfaceAreaToVolumeScanline: bounded metric transfers", "[SimplnxCore][ComputeSurfaceAreaToVolumeFilter]") @@ -167,25 +200,25 @@ TEST_CASE("SimplnxCore::ComputeSurfaceAreaToVolumeScanline: bounded metric trans const bool calculateSphericity = GENERATE(false, true); CAPTURE(numFeatures, batchCapacity, calculateSphericity); DataStructure dataStructure; - const auto occupiedFeatures = SurfaceAreaToVolumeTest::BuildSparseFeatureSurfaceData(dataStructure, numFeatures); + const auto occupiedFeatures = surface_area_to_volume_test::BuildSparseFeatureSurfaceData(dataStructure, numFeatures); const DataPath featurePath({"ImageGeom", "CellFeatureData"}); const DataPath countsPath = featurePath.createChildPath("NumCells"); REQUIRE_NOTHROW(dataStructure.getDataRefAs(featurePath)); const auto featureId = dataStructure.getDataRefAs(featurePath).getId(); - auto countsStore = std::make_shared>(numFeatures, 0); + auto countsStorePtr = std::make_shared>(numFeatures, 0); for(const usize feature : occupiedFeatures) { - countsStore->setValue(feature, 1); + countsStorePtr->setValue(feature, 1); } REQUIRE_NOTHROW(dataStructure.getDataRefAs(countsPath)); - const auto replacement = dataStructure.getDataRefAs(countsPath).setDataStore(countsStore); + const auto replacement = dataStructure.getDataRefAs(countsPath).setDataStore(countsStorePtr); SIMPLNX_RESULT_REQUIRE_VALID(replacement); - auto ratioStore = std::make_shared>(numFeatures, -47.0f); - REQUIRE(Float32Array::Create(dataStructure, "SurfaceAreaVolumeRatio", ratioStore, featureId) != nullptr); - auto sphericityStore = std::make_shared>(numFeatures, -47.0f); + auto ratioStorePtr = std::make_shared>(numFeatures, -47.0f); + REQUIRE(Float32Array::Create(dataStructure, "SurfaceAreaVolumeRatio", ratioStorePtr, featureId) != nullptr); + auto sphericityStorePtr = std::make_shared>(numFeatures, -47.0f); if(calculateSphericity) { - REQUIRE(Float32Array::Create(dataStructure, "Sphericity", sphericityStore, featureId) != nullptr); + REQUIRE(Float32Array::Create(dataStructure, "Sphericity", sphericityStorePtr, featureId) != nullptr); } const ComputeSurfaceAreaToVolumeInputValues inputValues = {.FeatureIdsArrayPath = DataPath({"ImageGeom", "CellData", "FeatureIds"}), .NumCellsArrayPath = countsPath, @@ -203,22 +236,22 @@ TEST_CASE("SimplnxCore::ComputeSurfaceAreaToVolumeScanline: bounded metric trans { expectedTransfers.push_back({offset, std::min(batchCapacity, numFeatures - offset)}); } - CHECK(countsStore->Reads == expectedTransfers); - CHECK(ratioStore->Writes == expectedTransfers); + CHECK(countsStorePtr->getReads() == expectedTransfers); + CHECK(ratioStorePtr->getWrites() == expectedTransfers); if(calculateSphericity) { - CHECK(sphericityStore->Writes == expectedTransfers); + CHECK(sphericityStorePtr->getWrites() == expectedTransfers); } else { - CHECK(sphericityStore->Writes.empty()); + CHECK(sphericityStorePtr->getWrites().empty()); } if(numFeatures > 0) { - CHECK(ratioStore->getValue(0) == 0.0f); + CHECK(ratioStorePtr->getValue(0) == 0.0f); if(calculateSphericity) { - CHECK(sphericityStore->getValue(0) == 0.0f); + CHECK(sphericityStorePtr->getValue(0) == 0.0f); } } UnitTest::CheckArraysInheritTupleDims(dataStructure); @@ -230,26 +263,29 @@ TEST_CASE("SimplnxCore::ComputeSurfaceAreaToVolumeScanline: later metric I/O fai // Exercise each failed operation on the second batch, after the first batch was written. const int failure = GENERATE(0, 1, 2); // NumCells read, ratio write, sphericity write. CAPTURE(failure); - constexpr usize k_NumFeatures = 7; - constexpr float32 k_Unwritten = -47.0f; + constexpr usize numFeatures = 7; + constexpr float32 unwritten = -47.0f; DataStructure dataStructure; - const auto occupiedFeatures = SurfaceAreaToVolumeTest::BuildSparseFeatureSurfaceData(dataStructure, k_NumFeatures); + const auto occupiedFeatures = surface_area_to_volume_test::BuildSparseFeatureSurfaceData(dataStructure, numFeatures); const DataPath featurePath({"ImageGeom", "CellFeatureData"}); const DataPath countsPath = featurePath.createChildPath("NumCells"); REQUIRE_NOTHROW(dataStructure.getDataRefAs(featurePath)); const auto featureId = dataStructure.getDataRefAs(featurePath).getId(); - auto countsStore = std::make_shared>(k_NumFeatures, 0, failure == 0 ? 2 : 0); + auto countsStorePtr = std::make_shared>(numFeatures, 0); + countsStorePtr->failReadOn(failure == 0 ? 2 : 0); for(const usize feature : occupiedFeatures) { - countsStore->setValue(feature, 1); + countsStorePtr->setValue(feature, 1); } REQUIRE_NOTHROW(dataStructure.getDataRefAs(countsPath)); - const auto replacement = dataStructure.getDataRefAs(countsPath).setDataStore(countsStore); + const auto replacement = dataStructure.getDataRefAs(countsPath).setDataStore(countsStorePtr); SIMPLNX_RESULT_REQUIRE_VALID(replacement); - auto ratioStore = std::make_shared>(k_NumFeatures, k_Unwritten, 0, failure == 1 ? 2 : 0); - auto sphericityStore = std::make_shared>(k_NumFeatures, k_Unwritten, 0, failure == 2 ? 2 : 0); - REQUIRE(Float32Array::Create(dataStructure, "SurfaceAreaVolumeRatio", ratioStore, featureId) != nullptr); - REQUIRE(Float32Array::Create(dataStructure, "Sphericity", sphericityStore, featureId) != nullptr); + auto ratioStorePtr = std::make_shared>(numFeatures, unwritten); + ratioStorePtr->failWriteOn(failure == 1 ? 2 : 0); + auto sphericityStorePtr = std::make_shared>(numFeatures, unwritten); + sphericityStorePtr->failWriteOn(failure == 2 ? 2 : 0); + REQUIRE(Float32Array::Create(dataStructure, "SurfaceAreaVolumeRatio", ratioStorePtr, featureId) != nullptr); + REQUIRE(Float32Array::Create(dataStructure, "Sphericity", sphericityStorePtr, featureId) != nullptr); const ComputeSurfaceAreaToVolumeInputValues inputValues = {.FeatureIdsArrayPath = DataPath({"ImageGeom", "CellData", "FeatureIds"}), .NumCellsArrayPath = countsPath, .SurfaceAreaVolumeRatioArrayName = featurePath.createChildPath("SurfaceAreaVolumeRatio"), @@ -262,41 +298,41 @@ TEST_CASE("SimplnxCore::ComputeSurfaceAreaToVolumeScanline: later metric I/O fai SIMPLNX_RESULT_REQUIRE_INVALID(result); REQUIRE(result.errors().size() == 1); CHECK(result.errors().front().code == (failure == 0 ? -94801 : -94802)); - CHECK(countsStore->Reads.size() == 2); - CHECK(ratioStore->Writes.size() == (failure == 0 ? 1 : 2)); - CHECK(sphericityStore->Writes.size() == (failure == 2 ? 2 : 1)); - - const double pi = std::acos(-1.0); - const double sphereRadius = std::cbrt(3.0 * 30.0 / (4.0 * pi)); - const double expectedSphericity = 4.0 * pi * sphereRadius * sphereRadius / 62.0; - CHECK(ratioStore->getValue(0) == 0.0f); - CHECK(sphericityStore->getValue(0) == 0.0f); - for(usize feature = 1; feature < k_NumFeatures; ++feature) + CHECK(countsStorePtr->getReads().size() == 2); + CHECK(ratioStorePtr->getWrites().size() == (failure == 0 ? 1 : 2)); + CHECK(sphericityStorePtr->getWrites().size() == (failure == 2 ? 2 : 1)); + + const double piValue = std::acos(-1.0); + const double sphereRadius = std::cbrt(3.0 * 30.0 / (4.0 * piValue)); + const double expectedSphericity = 4.0 * piValue * sphereRadius * sphereRadius / 62.0; + CHECK(ratioStorePtr->getValue(0) == 0.0f); + CHECK(sphericityStorePtr->getValue(0) == 0.0f); + for(usize feature = 1; feature < numFeatures; ++feature) { CAPTURE(feature); - const bool occupied = std::binary_search(occupiedFeatures.begin(), occupiedFeatures.end(), feature); + const bool occupied = std::ranges::binary_search(occupiedFeatures, feature); if(feature < (failure == 2 ? 6 : 3)) { if(occupied) { - CHECK(ratioStore->getValue(feature) == Approx(62.0 / 30.0).epsilon(1.0e-6)); + CHECK(ratioStorePtr->getValue(feature) == Approx(62.0 / 30.0).epsilon(1.0e-6)); } else { - CHECK(std::isnan(ratioStore->getValue(feature))); + CHECK(std::isnan(ratioStorePtr->getValue(feature))); } } else { - CHECK(ratioStore->getValue(feature) == k_Unwritten); + CHECK(ratioStorePtr->getValue(feature) == unwritten); } if(feature < 3) { - CHECK(sphericityStore->getValue(feature) == Approx(expectedSphericity).epsilon(1.0e-6)); + CHECK(sphericityStorePtr->getValue(feature) == Approx(expectedSphericity).epsilon(1.0e-6)); } else { - CHECK(sphericityStore->getValue(feature) == k_Unwritten); + CHECK(sphericityStorePtr->getValue(feature) == unwritten); } } UnitTest::CheckArraysInheritTupleDims(dataStructure); @@ -319,30 +355,30 @@ TEST_CASE("SimplnxCore::ComputeSurfaceAreaToVolumeFilter: geometry and FeatureId const DataPath ratioPath = countsPath.replaceName("SurfaceAreaVolumeRatio"); const DataPath sphericityPath = countsPath.replaceName("Sphericity"); - auto* geom = ImageGeom::Create(dataStructure, geomPath.getTargetName()); - REQUIRE(geom != nullptr); - geom->setDimensions({4, 3, 5}); - auto* cellAM = AttributeMatrix::Create(dataStructure, "CellData", {5, 3, 4}, geom->getId()); - REQUIRE(cellAM != nullptr); - geom->setCellData(*cellAM); - auto* featureAM = AttributeMatrix::Create(dataStructure, "CellFeatureData", {2}, geom->getId()); - REQUIRE(featureAM != nullptr); - - auto* labelGeom = ImageGeom::Create(dataStructure, labelGeomPath.getTargetName()); - REQUIRE(labelGeom != nullptr); - labelGeom->setDimensions(labelDimensions); - auto* labelAM = AttributeMatrix::Create(dataStructure, "CellData", labelShape, labelGeom->getId()); - REQUIRE(labelAM != nullptr); - labelGeom->setCellData(*labelAM); - - auto idsStore = DataStoreUtilities::CreateDataStore(dataStructure, idsPath, labelShape, {1}); - auto countsStore = DataStoreUtilities::CreateDataStore(dataStructure, countsPath, {2}, {1}); - REQUIRE(idsStore != nullptr); - REQUIRE(countsStore != nullptr); - REQUIRE(Int32Array::Create(dataStructure, "FeatureIds", idsStore, labelAM->getId()) != nullptr); - REQUIRE(Int32Array::Create(dataStructure, "NumCells", countsStore, featureAM->getId()) != nullptr); - - ComputeSurfaceAreaToVolumeFilter filter; + auto* imageGeomPtr = ImageGeom::Create(dataStructure, geomPath.getTargetName()); + REQUIRE(imageGeomPtr != nullptr); + imageGeomPtr->setDimensions({4, 3, 5}); + auto* cellAttributeMatrixPtr = AttributeMatrix::Create(dataStructure, "CellData", {5, 3, 4}, imageGeomPtr->getId()); + REQUIRE(cellAttributeMatrixPtr != nullptr); + imageGeomPtr->setCellData(*cellAttributeMatrixPtr); + auto* featureAttributeMatrixPtr = AttributeMatrix::Create(dataStructure, "CellFeatureData", {2}, imageGeomPtr->getId()); + REQUIRE(featureAttributeMatrixPtr != nullptr); + + auto* labelGeomPtr = ImageGeom::Create(dataStructure, labelGeomPath.getTargetName()); + REQUIRE(labelGeomPtr != nullptr); + labelGeomPtr->setDimensions(labelDimensions); + auto* labelAttributeMatrixPtr = AttributeMatrix::Create(dataStructure, "CellData", labelShape, labelGeomPtr->getId()); + REQUIRE(labelAttributeMatrixPtr != nullptr); + labelGeomPtr->setCellData(*labelAttributeMatrixPtr); + + auto idsStorePtr = DataStoreUtilities::CreateDataStore(dataStructure, idsPath, labelShape, {1}); + auto countsStorePtr = DataStoreUtilities::CreateDataStore(dataStructure, countsPath, {2}, {1}); + REQUIRE(idsStorePtr != nullptr); + REQUIRE(countsStorePtr != nullptr); + REQUIRE(Int32Array::Create(dataStructure, "FeatureIds", idsStorePtr, labelAttributeMatrixPtr->getId()) != nullptr); + REQUIRE(Int32Array::Create(dataStructure, "NumCells", countsStorePtr, featureAttributeMatrixPtr->getId()) != nullptr); + + const ComputeSurfaceAreaToVolumeFilter filter; Arguments args = filter.getDefaultArguments(); args.insertOrAssign(ComputeSurfaceAreaToVolumeFilter::k_SelectedImageGeometryPath_Key, std::make_any(geomPath)); args.insertOrAssign(ComputeSurfaceAreaToVolumeFilter::k_CellFeatureIdsArrayPath_Key, std::make_any(idsPath)); @@ -392,31 +428,31 @@ TEST_CASE("SimplnxCore::ComputeSurfaceAreaToVolumeFilter: rejects non-DataArray const std::vector labels(8, 1); const std::vector counts = {0, 8}; - auto* geom = ImageGeom::Create(dataStructure, geomPath.getTargetName()); - REQUIRE(geom != nullptr); - geom->setDimensions({2, 2, 2}); - auto* cellAM = AttributeMatrix::Create(dataStructure, cellPath.getTargetName(), cellShape, geom->getId()); - REQUIRE(cellAM != nullptr); - geom->setCellData(*cellAM); - auto* featureAM = AttributeMatrix::Create(dataStructure, featurePath.getTargetName(), featureShape, geom->getId()); - REQUIRE(featureAM != nullptr); - auto idsStore = DataStoreUtilities::CreateDataStore(dataStructure, idsPath, cellShape, {1}); - auto countsStore = DataStoreUtilities::CreateDataStore(dataStructure, countsPath, featureShape, {1}); - REQUIRE(idsStore != nullptr); - REQUIRE(countsStore != nullptr); - REQUIRE(Int32Array::Create(dataStructure, idsPath.getTargetName(), idsStore, cellAM->getId()) != nullptr); - REQUIRE(Int32Array::Create(dataStructure, countsPath.getTargetName(), countsStore, featureAM->getId()) != nullptr); - const auto idsWrite = idsStore->copyFromBuffer(0, nonstd::span(labels.data(), labels.size())); + auto* imageGeomPtr = ImageGeom::Create(dataStructure, geomPath.getTargetName()); + REQUIRE(imageGeomPtr != nullptr); + imageGeomPtr->setDimensions({2, 2, 2}); + auto* cellAttributeMatrixPtr = AttributeMatrix::Create(dataStructure, cellPath.getTargetName(), cellShape, imageGeomPtr->getId()); + REQUIRE(cellAttributeMatrixPtr != nullptr); + imageGeomPtr->setCellData(*cellAttributeMatrixPtr); + auto* featureAttributeMatrixPtr = AttributeMatrix::Create(dataStructure, featurePath.getTargetName(), featureShape, imageGeomPtr->getId()); + REQUIRE(featureAttributeMatrixPtr != nullptr); + auto idsStorePtr = DataStoreUtilities::CreateDataStore(dataStructure, idsPath, cellShape, {1}); + auto countsStorePtr = DataStoreUtilities::CreateDataStore(dataStructure, countsPath, featureShape, {1}); + REQUIRE(idsStorePtr != nullptr); + REQUIRE(countsStorePtr != nullptr); + REQUIRE(Int32Array::Create(dataStructure, idsPath.getTargetName(), idsStorePtr, cellAttributeMatrixPtr->getId()) != nullptr); + REQUIRE(Int32Array::Create(dataStructure, countsPath.getTargetName(), countsStorePtr, featureAttributeMatrixPtr->getId()) != nullptr); + const auto idsWrite = idsStorePtr->copyFromBuffer(0, nonstd::span(labels.data(), labels.size())); SIMPLNX_RESULT_REQUIRE_VALID(idsWrite); - const auto countsWrite = countsStore->copyFromBuffer(0, nonstd::span(counts.data(), counts.size())); + const auto countsWrite = countsStorePtr->copyFromBuffer(0, nonstd::span(counts.data(), counts.size())); SIMPLNX_RESULT_REQUIRE_VALID(countsWrite); - const auto* parent = replaceFeatureIds ? cellAM : featureAM; + const auto* parentPtr = replaceFeatureIds ? cellAttributeMatrixPtr : featureAttributeMatrixPtr; const DataPath parentPath = replaceFeatureIds ? cellPath : featurePath; const auto& values = replaceFeatureIds ? labels : counts; const std::string malformedName = useStringArray ? "StringSelection" : "NeighborListSelection"; const DataPath malformedPath = parentPath.createChildPath(malformedName); - REQUIRE(values.size() == parent->getNumberOfTuples()); + REQUIRE(values.size() == parentPtr->getNumberOfTuples()); if(useStringArray) { std::vector strings; @@ -425,20 +461,21 @@ TEST_CASE("SimplnxCore::ComputeSurfaceAreaToVolumeFilter: rejects non-DataArray { strings.push_back(std::to_string(value)); } - REQUIRE(StringArray::CreateWithValues(dataStructure, malformedName, parent->getShape(), std::move(strings), parent->getId()) != nullptr); + auto* stringsPtr = StringArray::CreateWithValues(dataStructure, malformedName, parentPtr->getShape(), std::move(strings), parentPtr->getId()); + REQUIRE(stringsPtr != nullptr); } else { - auto* lists = NeighborList::Create(dataStructure, malformedName, parent->getShape(), parent->getId()); - REQUIRE(lists != nullptr); + auto* listsPtr = NeighborList::Create(dataStructure, malformedName, parentPtr->getShape(), parentPtr->getId()); + REQUIRE(listsPtr != nullptr); for(usize index = 0; index < values.size(); ++index) { - lists->setList(static_cast(index), std::vector{values[index]}); + listsPtr->setList(static_cast(index), std::vector{values[index]}); } - CHECK(lists->getComponentShape() == ShapeType{1}); + CHECK(listsPtr->getComponentShape() == ShapeType{1}); } - ComputeSurfaceAreaToVolumeFilter filter; + const ComputeSurfaceAreaToVolumeFilter filter; Arguments args = filter.getDefaultArguments(); args.insertOrAssign(ComputeSurfaceAreaToVolumeFilter::k_SelectedImageGeometryPath_Key, std::make_any(geomPath)); args.insertOrAssign(ComputeSurfaceAreaToVolumeFilter::k_CellFeatureIdsArrayPath_Key, std::make_any(replaceFeatureIds ? malformedPath : idsPath)); @@ -472,7 +509,7 @@ TEST_CASE("SimplnxCore::ComputeSurfaceAreaToVolumeFilter: analytical interior pa const auto calculateSphericity = GENERATE(false, true); CAPTURE(scenario); UnitTest::AlgorithmTestScope scope(scenario); - SurfaceAreaToVolumeTest::CheckInteriorPairSurfaceMetrics(scope, pairAxis, spacing, calculateSphericity); + surface_area_to_volume_test::CheckInteriorPairSurfaceMetrics(scope, pairAxis, spacing, calculateSphericity); } TEST_CASE("SimplnxCore::ComputeSurfaceAreaToVolumeFilter: analytical single-slice pair", "[SimplnxCore][ComputeSurfaceAreaToVolumeFilter]") @@ -483,7 +520,7 @@ TEST_CASE("SimplnxCore::ComputeSurfaceAreaToVolumeFilter: analytical single-slic const auto calculateSphericity = GENERATE(false, true); CAPTURE(scenario); UnitTest::AlgorithmTestScope scope(scenario); - SurfaceAreaToVolumeTest::CheckInteriorPairSurfaceMetrics(scope, pairAxis, FloatVec3{2.0f, 3.0f, 5.0f}, calculateSphericity, true); + surface_area_to_volume_test::CheckInteriorPairSurfaceMetrics(scope, pairAxis, FloatVec3{2.0f, 3.0f, 5.0f}, calculateSphericity, true); } TEST_CASE("SimplnxCore::ComputeSurfaceAreaToVolumeFilter: decimal connected comb", "[SimplnxCore][ComputeSurfaceAreaToVolumeFilter]") @@ -494,7 +531,7 @@ TEST_CASE("SimplnxCore::ComputeSurfaceAreaToVolumeFilter: decimal connected comb const auto calculateSphericity = GENERATE(false, true); CAPTURE(scenario); UnitTest::AlgorithmTestScope scope(scenario); - SurfaceAreaToVolumeTest::CheckConnectedCombSurfaceMetrics(scope, spacing, calculateSphericity); + surface_area_to_volume_test::CheckConnectedCombSurfaceMetrics(scope, spacing, calculateSphericity); } TEST_CASE("SimplnxCore::ComputeSurfaceAreaToVolumeFilter: scale-invariant sphericity", "[SimplnxCore][ComputeSurfaceAreaToVolumeFilter]") @@ -503,7 +540,7 @@ TEST_CASE("SimplnxCore::ComputeSurfaceAreaToVolumeFilter: scale-invariant spheri const auto scenario = GENERATE(from_range(UnitTest::SelectAlgorithmTestScenariosForInMemoryStores())); CAPTURE(scenario); UnitTest::AlgorithmTestScope scope(scenario); - SurfaceAreaToVolumeTest::CheckScaleInvariantSphericity(scope); + surface_area_to_volume_test::CheckScaleInvariantSphericity(scope); } TEST_CASE("SimplnxCore::ComputeSurfaceAreaToVolumeFilter: nonpositive supplied pair counts", "[SimplnxCore][ComputeSurfaceAreaToVolumeFilter]") @@ -513,7 +550,7 @@ TEST_CASE("SimplnxCore::ComputeSurfaceAreaToVolumeFilter: nonpositive supplied p const auto suppliedPairCount = GENERATE(int32{0}, int32{-2}); CAPTURE(scenario, suppliedPairCount); UnitTest::AlgorithmTestScope scope(scenario); - SurfaceAreaToVolumeTest::CheckInteriorPairSurfaceMetrics(scope, 0, FloatVec3{2.0f, 3.0f, 5.0f}, true, false, suppliedPairCount); + surface_area_to_volume_test::CheckInteriorPairSurfaceMetrics(scope, 0, FloatVec3{2.0f, 3.0f, 5.0f}, true, false, suppliedPairCount); } TEST_CASE("SimplnxCore::ComputeSurfaceAreaToVolume", "[SimplnxCore][ComputeSurfaceAreaToVolume]") diff --git a/src/Plugins/SimplnxCore/test/ComputeSurfaceAreaToVolumeTestUtils.hpp b/src/Plugins/SimplnxCore/test/ComputeSurfaceAreaToVolumeTestUtils.hpp index a7c8ce2c1b..f21f90ccf2 100644 --- a/src/Plugins/SimplnxCore/test/ComputeSurfaceAreaToVolumeTestUtils.hpp +++ b/src/Plugins/SimplnxCore/test/ComputeSurfaceAreaToVolumeTestUtils.hpp @@ -2,6 +2,8 @@ #include "SimplnxCore/Filters/ComputeSurfaceAreaToVolumeFilter.hpp" +#include "simplnx/Common/Aliases.hpp" +#include "simplnx/Common/Array.hpp" #include "simplnx/Common/Result.hpp" #include "simplnx/Common/Types.hpp" #include "simplnx/DataStructure/AttributeMatrix.hpp" @@ -9,6 +11,7 @@ #include "simplnx/DataStructure/DataPath.hpp" #include "simplnx/DataStructure/DataStructure.hpp" #include "simplnx/DataStructure/Geometry/ImageGeom.hpp" +#include "simplnx/DataStructure/IDataArray.hpp" #include "simplnx/Filter/Arguments.hpp" #include "simplnx/UnitTest/UnitTestCommon.hpp" #include "simplnx/Utilities/DataStoreUtilities.hpp" @@ -23,7 +26,7 @@ #include #include -namespace SurfaceAreaToVolumeTest +namespace surface_area_to_volume_test { /** * @brief Builds isolated cells that exercise large feature tables in a small image. @@ -51,39 +54,39 @@ inline std::vector BuildSparseFeatureSurfaceData(nx::core::Data auto* featureAMPtr = AttributeMatrix::Create(dataStructure, featurePath.getTargetName(), featureShape, geomPtr->getId()); REQUIRE(featureAMPtr != nullptr); - auto idsStore = DataStoreUtilities::CreateDataStore(dataStructure, idsPath, cellShape, {1}); - auto countsStore = DataStoreUtilities::CreateDataStore(dataStructure, countsPath, featureShape, {1}); - REQUIRE(idsStore != nullptr); - REQUIRE(countsStore != nullptr); - REQUIRE(Int32Array::Create(dataStructure, idsPath.getTargetName(), idsStore, cellAMPtr->getId()) != nullptr); - REQUIRE(Int32Array::Create(dataStructure, countsPath.getTargetName(), countsStore, featureAMPtr->getId()) != nullptr); + auto idsStorePtr = DataStoreUtilities::CreateDataStore(dataStructure, idsPath, cellShape, {1}); + auto countsStorePtr = DataStoreUtilities::CreateDataStore(dataStructure, countsPath, featureShape, {1}); + REQUIRE(idsStorePtr != nullptr); + REQUIRE(countsStorePtr != nullptr); + REQUIRE(Int32Array::Create(dataStructure, idsPath.getTargetName(), idsStorePtr, cellAMPtr->getId()) != nullptr); + REQUIRE(Int32Array::Create(dataStructure, countsPath.getTargetName(), countsStorePtr, featureAMPtr->getId()) != nullptr); if(numFeatures == 0) { return {}; } // Probe both sides of the half-table and fixed-cap boundaries, plus the last tuple. - std::vector occupiedFeatures = {1, numFeatures / 2, numFeatures / 2 + 1, numFeatures - 1, 65535, 65536, 65537}; + std::vector occupiedFeatures = {1, numFeatures / 2, (numFeatures / 2) + 1, numFeatures - 1, 65535, 65536, 65537}; if(numFeatures > 3) { - occupiedFeatures.push_back(numFeatures / 2 - 1); + occupiedFeatures.push_back((numFeatures / 2) - 1); } std::erase_if(occupiedFeatures, [numFeatures](usize feature) { return feature == 0 || feature >= numFeatures; }); - std::sort(occupiedFeatures.begin(), occupiedFeatures.end()); - occupiedFeatures.erase(std::unique(occupiedFeatures.begin(), occupiedFeatures.end()), occupiedFeatures.end()); + std::ranges::sort(occupiedFeatures); + occupiedFeatures.erase(std::ranges::unique(occupiedFeatures).begin(), occupiedFeatures.end()); REQUIRE(occupiedFeatures.size() <= 8); - std::vector labels(19 * 3 * 3, 0); + std::vector labels(usize{19} * 3 * 3, 0); std::vector counts(numFeatures, 0); for(usize index = 0; index < occupiedFeatures.size(); ++index) { // Background separates every one-cell box from its neighbors and the image exterior. - labels[(1 * 3 + 1) * 19 + 1 + 2 * index] = static_cast(occupiedFeatures[index]); + labels[(((1 * 3) + 1) * 19) + 1 + (2 * index)] = static_cast(occupiedFeatures[index]); counts[occupiedFeatures[index]] = 1; } counts[0] = static_cast(labels.size() - occupiedFeatures.size()); - const auto idsWrite = idsStore->copyFromBuffer(0, nonstd::span(labels.data(), labels.size())); + const auto idsWrite = idsStorePtr->copyFromBuffer(0, nonstd::span(labels.data(), labels.size())); SIMPLNX_RESULT_REQUIRE_VALID(idsWrite); - const auto countsWrite = countsStore->copyFromBuffer(0, nonstd::span(counts.data(), counts.size())); + const auto countsWrite = countsStorePtr->copyFromBuffer(0, nonstd::span(counts.data(), counts.size())); SIMPLNX_RESULT_REQUIRE_VALID(countsWrite); return occupiedFeatures; } @@ -113,7 +116,7 @@ void CheckSparseFeatureSurfaceMetrics(ScopeT& scope, nx::core::usize numFeatures scope.requireExpectedStore(dataStructure.getDataRefAs(idsPath)); scope.requireExpectedStore(dataStructure.getDataRefAs(countsPath)); - ComputeSurfaceAreaToVolumeFilter filter; + const ComputeSurfaceAreaToVolumeFilter filter; Arguments args = filter.getDefaultArguments(); args.insertOrAssign(ComputeSurfaceAreaToVolumeFilter::k_SelectedImageGeometryPath_Key, std::make_any(geomPath)); args.insertOrAssign(ComputeSurfaceAreaToVolumeFilter::k_CellFeatureIdsArrayPath_Key, std::make_any(idsPath)); @@ -135,7 +138,7 @@ void CheckSparseFeatureSurfaceMetrics(ScopeT& scope, nx::core::usize numFeatures for(usize feature = 1; feature < numFeatures; ++feature) { CAPTURE(feature); - if(std::binary_search(occupiedFeatures.begin(), occupiedFeatures.end(), feature)) + if(std::ranges::binary_search(occupiedFeatures, feature)) { REQUIRE(values[feature] == Approx(62.0 / 30.0).epsilon(1.0e-6)); } @@ -155,13 +158,13 @@ void CheckSparseFeatureSurfaceMetrics(ScopeT& scope, nx::core::usize numFeatures SIMPLNX_RESULT_REQUIRE_VALID(sphericityRead); CHECK(values[0] == 0.0f); // Independently calculate the equal-volume sphere from its radius. - const double pi = std::acos(-1.0); - const double radius = std::cbrt(3.0 * 30.0 / (4.0 * pi)); - const double expected = 4.0 * pi * radius * radius / 62.0; + const double piValue = std::acos(-1.0); + const double radius = std::cbrt(3.0 * 30.0 / (4.0 * piValue)); + const double expected = 4.0 * piValue * radius * radius / 62.0; for(usize feature = 1; feature < numFeatures; ++feature) { CAPTURE(feature); - if(std::binary_search(occupiedFeatures.begin(), occupiedFeatures.end(), feature)) + if(std::ranges::binary_search(occupiedFeatures, feature)) { REQUIRE(values[feature] == Approx(expected).epsilon(1.0e-6)); } @@ -202,33 +205,33 @@ std::array CheckInteriorPairSurfaceMetrics(ScopeT& scope, constexpr int32 enclosingFeature = 1; const usize cellCount = dimensions[0] * dimensions[1] * dimensions[2]; - auto* geom = ImageGeom::Create(dataStructure, "ImageGeom"); - REQUIRE(geom != nullptr); - geom->setDimensions(dimensions); - geom->setSpacing(spacing); - geom->setOrigin(origin); - auto* cellAM = AttributeMatrix::Create(dataStructure, "CellData", cellShape, geom->getId()); - REQUIRE(cellAM != nullptr); - geom->setCellData(*cellAM); - auto* featureAM = AttributeMatrix::Create(dataStructure, "CellFeatureData", featureShape, geom->getId()); - REQUIRE(featureAM != nullptr); + auto* imageGeomPtr = ImageGeom::Create(dataStructure, "ImageGeom"); + REQUIRE(imageGeomPtr != nullptr); + imageGeomPtr->setDimensions(dimensions); + imageGeomPtr->setSpacing(spacing); + imageGeomPtr->setOrigin(origin); + auto* cellAttributeMatrixPtr = AttributeMatrix::Create(dataStructure, "CellData", cellShape, imageGeomPtr->getId()); + REQUIRE(cellAttributeMatrixPtr != nullptr); + imageGeomPtr->setCellData(*cellAttributeMatrixPtr); + auto* featureAttributeMatrixPtr = AttributeMatrix::Create(dataStructure, "CellFeatureData", featureShape, imageGeomPtr->getId()); + REQUIRE(featureAttributeMatrixPtr != nullptr); - auto idsStore = DataStoreUtilities::CreateDataStore(dataStructure, idsPath, cellShape, componentShape); - auto countsStore = DataStoreUtilities::CreateDataStore(dataStructure, countsPath, featureShape, componentShape); - REQUIRE(idsStore != nullptr); - REQUIRE(countsStore != nullptr); - REQUIRE(Int32Array::Create(dataStructure, "FeatureIds", idsStore, cellAM->getId()) != nullptr); - REQUIRE(Int32Array::Create(dataStructure, "NumCells", countsStore, featureAM->getId()) != nullptr); + auto idsStorePtr = DataStoreUtilities::CreateDataStore(dataStructure, idsPath, cellShape, componentShape); + auto countsStorePtr = DataStoreUtilities::CreateDataStore(dataStructure, countsPath, featureShape, componentShape); + REQUIRE(idsStorePtr != nullptr); + REQUIRE(countsStorePtr != nullptr); + REQUIRE(Int32Array::Create(dataStructure, "FeatureIds", idsStorePtr, cellAttributeMatrixPtr->getId()) != nullptr); + REQUIRE(Int32Array::Create(dataStructure, "NumCells", countsStorePtr, featureAttributeMatrixPtr->getId()) != nullptr); std::vector labels(cellCount, enclosingFeature); - std::array first = {2, 2, singleSlice ? usize{0} : usize{2}}; + const std::array first = {2, 2, singleSlice ? usize{0} : usize{2}}; auto second = first; - second[pairAxis]++; - labels[(first[2] * dimensions[1] + first[1]) * dimensions[0] + first[0]] = static_cast(pairFeature); - labels[(second[2] * dimensions[1] + second[1]) * dimensions[0] + second[0]] = static_cast(pairFeature); + second.at(pairAxis)++; + labels[(((first[2] * dimensions[1]) + first[1]) * dimensions[0]) + first[0]] = static_cast(pairFeature); + labels[(((second[2] * dimensions[1]) + second[1]) * dimensions[0]) + second[0]] = static_cast(pairFeature); const std::array counts = {0, singleSlice ? 23 : 123, suppliedPairCount}; - auto idsWrite = idsStore->copyFromBuffer(0, nonstd::span(labels.data(), labels.size())); + auto idsWrite = idsStorePtr->copyFromBuffer(0, nonstd::span(labels.data(), labels.size())); SIMPLNX_RESULT_REQUIRE_VALID(idsWrite); - auto countsWrite = countsStore->copyFromBuffer(0, nonstd::span(counts.data(), counts.size())); + auto countsWrite = countsStorePtr->copyFromBuffer(0, nonstd::span(counts.data(), counts.size())); SIMPLNX_RESULT_REQUIRE_VALID(countsWrite); REQUIRE_NOTHROW(dataStructure.getDataRefAs(idsPath)); @@ -240,7 +243,7 @@ std::array CheckInteriorPairSurfaceMetrics(ScopeT& scope, const auto idsFormat = ids.getDataFormat(); const auto countsFormat = numCells.getDataFormat(); - ComputeSurfaceAreaToVolumeFilter filter; + const ComputeSurfaceAreaToVolumeFilter filter; Arguments args; args.insertOrAssign(ComputeSurfaceAreaToVolumeFilter::k_SelectedImageGeometryPath_Key, std::make_any(geomPath)); args.insertOrAssign(ComputeSurfaceAreaToVolumeFilter::k_CellFeatureIdsArrayPath_Key, std::make_any(idsPath)); @@ -255,9 +258,9 @@ std::array CheckInteriorPairSurfaceMetrics(ScopeT& scope, // Independent rectangular-box oracle: the pair doubles one physical side. std::array sides = {spacing[0], spacing[1], spacing[2]}; - sides[pairAxis] *= 2.0; + sides.at(pairAxis) *= 2.0; // Exterior Z faces are excluded for a single slice, as in the production boundary policy. - const double area = 2.0 * ((singleSlice ? 0.0 : sides[0] * sides[1]) + sides[0] * sides[2] + sides[1] * sides[2]); + const double area = 2.0 * ((singleSlice ? 0.0 : sides[0] * sides[1]) + (sides[0] * sides[2]) + (sides[1] * sides[2])); const double voxelVolume = static_cast(spacing[0]) * spacing[1] * spacing[2]; std::array volumes = {0.0, 0.0, 0.0}; volumes[pairFeature] = suppliedPairCount * voxelVolume; @@ -270,21 +273,21 @@ std::array CheckInteriorPairSurfaceMetrics(ScopeT& scope, scope.requireExpectedStore(ratios); CHECK(ratios.getTupleShape() == featureShape); CHECK(ratios.getComponentShape() == componentShape); - std::array ratioValues; + std::array ratioValues = {}; auto ratiosRead = ratios.getDataStoreRef().copyIntoBuffer(0, nonstd::span(ratioValues.data(), ratioValues.size())); SIMPLNX_RESULT_REQUIRE_VALID(ratiosRead); CHECK(ratioValues[0] == 0.0f); for(usize feature = 1; feature < 3; feature++) { CAPTURE(feature); - if(volumes[feature] == 0.0) + if(volumes.at(feature) == 0.0) { - CHECK(std::isinf(ratioValues[feature])); - CHECK(ratioValues[feature] > 0.0f); + CHECK(std::isinf(ratioValues.at(feature))); + CHECK(ratioValues.at(feature) > 0.0f); } else { - CHECK(ratioValues[feature] == Approx(area / volumes[feature]).epsilon(1.0e-6)); + CHECK(ratioValues.at(feature) == Approx(area / volumes.at(feature)).epsilon(1.0e-6)); } } std::array sphericityValues = {}; @@ -301,21 +304,21 @@ std::array CheckInteriorPairSurfaceMetrics(ScopeT& scope, for(usize feature = 1; feature < 3; feature++) { CAPTURE(feature); - if(volumes[feature] < 0.0) + if(volumes.at(feature) < 0.0) { - CHECK(std::isnan(sphericityValues[feature])); + CHECK(std::isnan(sphericityValues.at(feature))); } - else if(volumes[feature] == 0.0) + else if(volumes.at(feature) == 0.0) { - CHECK(sphericityValues[feature] == 0.0f); + CHECK(sphericityValues.at(feature) == 0.0f); } else { // Derive the equal-volume sphere's area from its radius independently of the implementation formula. - const double pi = std::acos(-1.0); - const double sphereRadius = std::cbrt(3.0 * volumes[feature] / (4.0 * pi)); - const double expected = 4.0 * pi * sphereRadius * sphereRadius / area; - CHECK(sphericityValues[feature] == Approx(expected).epsilon(1.0e-6)); + const double piValue = std::acos(-1.0); + const double sphereRadius = std::cbrt(3.0 * volumes.at(feature) / (4.0 * piValue)); + const double expected = 4.0 * piValue * sphereRadius * sphereRadius / area; + CHECK(sphericityValues.at(feature) == Approx(expected).epsilon(1.0e-6)); } } } @@ -325,7 +328,7 @@ std::array CheckInteriorPairSurfaceMetrics(ScopeT& scope, } std::vector actualLabels(cellCount); - std::array actualCounts; + std::array actualCounts = {}; auto idsRead = ids.getDataStoreRef().copyIntoBuffer(0, nonstd::span(actualLabels.data(), actualLabels.size())); SIMPLNX_RESULT_REQUIRE_VALID(idsRead); auto countsRead = numCells.getDataStoreRef().copyIntoBuffer(0, nonstd::span(actualCounts.data(), actualCounts.size())); @@ -338,8 +341,8 @@ std::array CheckInteriorPairSurfaceMetrics(ScopeT& scope, CHECK(numCells.getComponentShape() == componentShape); CHECK(ids.getDataFormat() == idsFormat); CHECK(numCells.getDataFormat() == countsFormat); - CHECK(&ids.getDataStoreRef() == idsStore.get()); - CHECK(&numCells.getDataStoreRef() == countsStore.get()); + CHECK(&ids.getDataStoreRef() == idsStorePtr.get()); + CHECK(&numCells.getDataStoreRef() == countsStorePtr.get()); scope.requireExpectedStore(ids); scope.requireExpectedStore(numCells); REQUIRE_NOTHROW(dataStructure.getDataRefAs(geomPath)); @@ -347,8 +350,8 @@ std::array CheckInteriorPairSurfaceMetrics(ScopeT& scope, CHECK(finalGeom.getDimensions() == dimensions); CHECK(finalGeom.getSpacing() == spacing); CHECK(finalGeom.getOrigin() == origin); - CHECK(cellAM->getShape() == cellShape); - CHECK(featureAM->getShape() == featureShape); + CHECK(cellAttributeMatrixPtr->getShape() == cellShape); + CHECK(featureAttributeMatrixPtr->getShape() == featureShape); UnitTest::CheckArraysInheritTupleDims(dataStructure); return sphericityValues; } @@ -367,7 +370,7 @@ void CheckScaleInvariantSphericity(ScopeT& scope) for(usize feature = 1; feature < reference.size(); feature++) { CAPTURE(feature); - CHECK(scaled[feature] == Approx(reference[feature]).epsilon(1.0e-6)); + CHECK(scaled.at(feature) == Approx(reference.at(feature)).epsilon(1.0e-6)); } } } @@ -399,48 +402,48 @@ void CheckConnectedCombSurfaceMetrics(ScopeT& scope, const nx::core::FloatVec3& constexpr int32 toothLength = 134; constexpr int32 teethY = 56; constexpr int32 teethZ = 18; - constexpr int32 combCellCount = plateY * plateZ + toothLength * teethY * teethZ; - constexpr std::array normalFaceCounts = {2 * plateY * plateZ, 2 * plateZ + 2 * toothLength * teethY * teethZ, 2 * plateY + 2 * toothLength * teethY * teethZ}; + constexpr int32 combCellCount = (plateY * plateZ) + (toothLength * teethY * teethZ); + constexpr std::array normalFaceCounts = {2 * plateY * plateZ, (2 * plateZ) + (2 * toothLength * teethY * teethZ), (2 * plateY) + (2 * toothLength * teethY * teethZ)}; STATIC_REQUIRE(combCellCount == 138957); STATIC_REQUIRE(normalFaceCounts[0] == 7770); STATIC_REQUIRE(normalFaceCounts[1] == 270214); STATIC_REQUIRE(normalFaceCounts[2] == 270366); const std::array counts = {static_cast(cellCount) - combCellCount, combCellCount}; std::vector labels(cellCount, 0); - for(usize z = 1; z <= plateZ; z++) + for(usize zIndex = 1; zIndex <= plateZ; zIndex++) { - for(usize y = 1; y <= plateY; y++) + for(usize yIndex = 1; yIndex <= plateY; yIndex++) { - for(usize x = 1; x <= toothLength + 1; x++) + for(usize xIndex = 1; xIndex <= toothLength + 1; xIndex++) { - if(x == 1 || (y % 2 == 1 && z % 2 == 1)) + if(xIndex == 1 || (yIndex % 2 == 1 && zIndex % 2 == 1)) { - labels[(z * dimensions[1] + y) * dimensions[0] + x] = 1; + labels[(((zIndex * dimensions[1]) + yIndex) * dimensions[0]) + xIndex] = 1; } } } } REQUIRE(std::count(labels.begin(), labels.end(), int32{1}) == combCellCount); - auto* geom = ImageGeom::Create(dataStructure, "ImageGeom"); - REQUIRE(geom != nullptr); - geom->setDimensions(dimensions); - geom->setSpacing(spacing); - geom->setOrigin(origin); - auto* cellAM = AttributeMatrix::Create(dataStructure, "CellData", cellShape, geom->getId()); - REQUIRE(cellAM != nullptr); - geom->setCellData(*cellAM); - auto* featureAM = AttributeMatrix::Create(dataStructure, "CellFeatureData", featureShape, geom->getId()); - REQUIRE(featureAM != nullptr); - auto idsStore = DataStoreUtilities::CreateDataStore(dataStructure, idsPath, cellShape, componentShape); - auto countsStore = DataStoreUtilities::CreateDataStore(dataStructure, countsPath, featureShape, componentShape); - REQUIRE(idsStore != nullptr); - REQUIRE(countsStore != nullptr); - REQUIRE(Int32Array::Create(dataStructure, "FeatureIds", idsStore, cellAM->getId()) != nullptr); - REQUIRE(Int32Array::Create(dataStructure, "NumCells", countsStore, featureAM->getId()) != nullptr); - auto idsWrite = idsStore->copyFromBuffer(0, nonstd::span(labels.data(), labels.size())); + auto* imageGeomPtr = ImageGeom::Create(dataStructure, "ImageGeom"); + REQUIRE(imageGeomPtr != nullptr); + imageGeomPtr->setDimensions(dimensions); + imageGeomPtr->setSpacing(spacing); + imageGeomPtr->setOrigin(origin); + auto* cellAttributeMatrixPtr = AttributeMatrix::Create(dataStructure, "CellData", cellShape, imageGeomPtr->getId()); + REQUIRE(cellAttributeMatrixPtr != nullptr); + imageGeomPtr->setCellData(*cellAttributeMatrixPtr); + auto* featureAttributeMatrixPtr = AttributeMatrix::Create(dataStructure, "CellFeatureData", featureShape, imageGeomPtr->getId()); + REQUIRE(featureAttributeMatrixPtr != nullptr); + auto idsStorePtr = DataStoreUtilities::CreateDataStore(dataStructure, idsPath, cellShape, componentShape); + auto countsStorePtr = DataStoreUtilities::CreateDataStore(dataStructure, countsPath, featureShape, componentShape); + REQUIRE(idsStorePtr != nullptr); + REQUIRE(countsStorePtr != nullptr); + REQUIRE(Int32Array::Create(dataStructure, "FeatureIds", idsStorePtr, cellAttributeMatrixPtr->getId()) != nullptr); + REQUIRE(Int32Array::Create(dataStructure, "NumCells", countsStorePtr, featureAttributeMatrixPtr->getId()) != nullptr); + auto idsWrite = idsStorePtr->copyFromBuffer(0, nonstd::span(labels.data(), labels.size())); SIMPLNX_RESULT_REQUIRE_VALID(idsWrite); - auto countsWrite = countsStore->copyFromBuffer(0, nonstd::span(counts.data(), counts.size())); + auto countsWrite = countsStorePtr->copyFromBuffer(0, nonstd::span(counts.data(), counts.size())); SIMPLNX_RESULT_REQUIRE_VALID(countsWrite); REQUIRE_NOTHROW(dataStructure.getDataRefAs(idsPath)); @@ -452,7 +455,7 @@ void CheckConnectedCombSurfaceMetrics(ScopeT& scope, const nx::core::FloatVec3& const auto idsFormat = ids.getDataFormat(); const auto countsFormat = numCells.getDataFormat(); - ComputeSurfaceAreaToVolumeFilter filter; + const ComputeSurfaceAreaToVolumeFilter filter; Arguments args; args.insertOrAssign(ComputeSurfaceAreaToVolumeFilter::k_SelectedImageGeometryPath_Key, std::make_any(geomPath)); args.insertOrAssign(ComputeSurfaceAreaToVolumeFilter::k_CellFeatureIdsArrayPath_Key, std::make_any(idsPath)); @@ -467,8 +470,8 @@ void CheckConnectedCombSurfaceMetrics(ScopeT& scope, const nx::core::FloatVec3& // Count entire plate and tooth faces analytically; do not repeat the production neighbor scan. const std::array physicalSpacing = {spacing[0], spacing[1], spacing[2]}; - const double area = - normalFaceCounts[0] * physicalSpacing[1] * physicalSpacing[2] + normalFaceCounts[1] * physicalSpacing[0] * physicalSpacing[2] + normalFaceCounts[2] * physicalSpacing[0] * physicalSpacing[1]; + const double area = (normalFaceCounts[0] * physicalSpacing[1] * physicalSpacing[2]) + (normalFaceCounts[1] * physicalSpacing[0] * physicalSpacing[2]) + + (normalFaceCounts[2] * physicalSpacing[0] * physicalSpacing[1]); const double volume = combCellCount * physicalSpacing[0] * physicalSpacing[1] * physicalSpacing[2]; CAPTURE(spacing[0], spacing[1], spacing[2], calculateSphericity, area, volume); REQUIRE_NOTHROW(dataStructure.getDataRefAs(ratioPath)); @@ -476,7 +479,7 @@ void CheckConnectedCombSurfaceMetrics(ScopeT& scope, const nx::core::FloatVec3& scope.requireExpectedStore(ratios); CHECK(ratios.getTupleShape() == featureShape); CHECK(ratios.getComponentShape() == componentShape); - std::array ratioValues; + std::array ratioValues = {}; auto ratiosRead = ratios.getDataStoreRef().copyIntoBuffer(0, nonstd::span(ratioValues.data(), ratioValues.size())); SIMPLNX_RESULT_REQUIRE_VALID(ratiosRead); CHECK(ratioValues[0] == 0.0f); @@ -488,7 +491,7 @@ void CheckConnectedCombSurfaceMetrics(ScopeT& scope, const nx::core::FloatVec3& scope.requireExpectedStore(sphericity); CHECK(sphericity.getTupleShape() == featureShape); CHECK(sphericity.getComponentShape() == componentShape); - std::array values; + std::array values = {}; auto sphericityRead = sphericity.getDataStoreRef().copyIntoBuffer(0, nonstd::span(values.data(), values.size())); SIMPLNX_RESULT_REQUIRE_VALID(sphericityRead); CHECK(values[0] == 0.0f); @@ -501,7 +504,7 @@ void CheckConnectedCombSurfaceMetrics(ScopeT& scope, const nx::core::FloatVec3& } std::vector actualLabels(cellCount); - std::array actualCounts; + std::array actualCounts = {}; auto idsRead = ids.getDataStoreRef().copyIntoBuffer(0, nonstd::span(actualLabels.data(), actualLabels.size())); SIMPLNX_RESULT_REQUIRE_VALID(idsRead); auto countsRead = numCells.getDataStoreRef().copyIntoBuffer(0, nonstd::span(actualCounts.data(), actualCounts.size())); @@ -514,8 +517,8 @@ void CheckConnectedCombSurfaceMetrics(ScopeT& scope, const nx::core::FloatVec3& CHECK(numCells.getComponentShape() == componentShape); CHECK(ids.getDataFormat() == idsFormat); CHECK(numCells.getDataFormat() == countsFormat); - CHECK(&ids.getDataStoreRef() == idsStore.get()); - CHECK(&numCells.getDataStoreRef() == countsStore.get()); + CHECK(&ids.getDataStoreRef() == idsStorePtr.get()); + CHECK(&numCells.getDataStoreRef() == countsStorePtr.get()); scope.requireExpectedStore(ids); scope.requireExpectedStore(numCells); REQUIRE_NOTHROW(dataStructure.getDataRefAs(geomPath)); @@ -523,8 +526,8 @@ void CheckConnectedCombSurfaceMetrics(ScopeT& scope, const nx::core::FloatVec3& CHECK(finalGeom.getDimensions() == dimensions); CHECK(finalGeom.getSpacing() == spacing); CHECK(finalGeom.getOrigin() == origin); - CHECK(cellAM->getShape() == cellShape); - CHECK(featureAM->getShape() == featureShape); + CHECK(cellAttributeMatrixPtr->getShape() == cellShape); + CHECK(featureAttributeMatrixPtr->getShape() == featureShape); UnitTest::CheckArraysInheritTupleDims(dataStructure); } -} // namespace SurfaceAreaToVolumeTest +} // namespace surface_area_to_volume_test diff --git a/src/simplnx/Utilities/DataArrayUtilities.cpp b/src/simplnx/Utilities/DataArrayUtilities.cpp index f62b82eafb..30f1445b24 100644 --- a/src/simplnx/Utilities/DataArrayUtilities.cpp +++ b/src/simplnx/Utilities/DataArrayUtilities.cpp @@ -1,5 +1,6 @@ #include "DataArrayUtilities.hpp" +#include "simplnx/Common/Result.hpp" #include "simplnx/Common/Types.hpp" #include "simplnx/Common/TypesUtility.hpp" #include "simplnx/Core/Application.hpp" @@ -14,6 +15,7 @@ #include "simplnx/Utilities/StringInterpretationUtilities.hpp" #include "simplnx/Utilities/TemplateHelpers.hpp" +#include #include using namespace nx::core; diff --git a/src/simplnx/Utilities/DataArrayUtilities.hpp b/src/simplnx/Utilities/DataArrayUtilities.hpp index 5004bb1469..487dad7759 100644 --- a/src/simplnx/Utilities/DataArrayUtilities.hpp +++ b/src/simplnx/Utilities/DataArrayUtilities.hpp @@ -6,9 +6,11 @@ #include "simplnx/Common/Bit.hpp" #include "simplnx/Common/Result.hpp" #include "simplnx/Common/ScratchBuffer.hpp" +#include "simplnx/Common/Types.hpp" #include "simplnx/DataStructure/AbstractListStore.hpp" #include "simplnx/DataStructure/AttributeMatrix.hpp" #include "simplnx/DataStructure/DataArray.hpp" +#include "simplnx/DataStructure/DataPath.hpp" #include "simplnx/DataStructure/NeighborList.hpp" #include "simplnx/DataStructure/StringArray.hpp" #include "simplnx/Filter/IFilter.hpp" diff --git a/test/DataArrayTest.cpp b/test/DataArrayTest.cpp index 437fc3233a..1ac964fdda 100644 --- a/test/DataArrayTest.cpp +++ b/test/DataArrayTest.cpp @@ -1,16 +1,19 @@ #include "simplnx/DataStructure/DataArray.hpp" #include "simplnx/Common/Array.hpp" #include "simplnx/Common/ScopeGuard.hpp" +#include "simplnx/Common/Types.hpp" #include "simplnx/Common/TypesUtility.hpp" #include "simplnx/Core/Application.hpp" #include "simplnx/Core/Preferences.hpp" #include "simplnx/DataStructure/AttributeMatrix.hpp" #include "simplnx/DataStructure/DataGroup.hpp" +#include "simplnx/DataStructure/DataPath.hpp" #include "simplnx/DataStructure/DataStore.hpp" #include "simplnx/DataStructure/DataStructure.hpp" #include "simplnx/DataStructure/EmptyDataStore.hpp" #include "simplnx/DataStructure/EmptyListStore.hpp" #include "simplnx/DataStructure/EmptyStringStore.hpp" +#include "simplnx/DataStructure/Geometry/IGridGeometry.hpp" #include "simplnx/DataStructure/Geometry/ImageGeom.hpp" #include "simplnx/DataStructure/Geometry/RectGridGeom.hpp" #include "simplnx/DataStructure/IO/Generic/DataIOCollection.hpp" @@ -29,6 +32,7 @@ #include "DataStructObserver.hpp" #include +#include #include #include @@ -37,6 +41,7 @@ #include #include #include +#include #include #include @@ -52,23 +57,23 @@ TEST_CASE("DataArrayUtilities::ValidateCellTupleCount", "[simplnx][DataArrayUtil CAPTURE(useRectGrid, emptyGeometry, tupleCount, errorCode); DataStructure dataStructure; - auto* parent = DataGroup::Create(dataStructure, "Geometry Group"); - REQUIRE(parent != nullptr); + auto* parentPtr = DataGroup::Create(dataStructure, "Geometry Group"); + REQUIRE(parentPtr != nullptr); const DataPath geometryPath({"Geometry Group", "Selected Geometry"}); const DataPath dataPath({"Other Geometry", "Cell Data", "Values"}); - IGridGeometry* geometry = nullptr; + IGridGeometry* gridGeomPtr = nullptr; if(useRectGrid) { - geometry = RectGridGeom::Create(dataStructure, geometryPath.getTargetName(), parent->getId()); + gridGeomPtr = RectGridGeom::Create(dataStructure, geometryPath.getTargetName(), parentPtr->getId()); } else { - geometry = ImageGeom::Create(dataStructure, geometryPath.getTargetName(), parent->getId()); + gridGeomPtr = ImageGeom::Create(dataStructure, geometryPath.getTargetName(), parentPtr->getId()); } - REQUIRE(geometry != nullptr); - geometry->setDimensions({emptyGeometry ? usize{0} : usize{4}, 3, 5}); + REQUIRE(gridGeomPtr != nullptr); + gridGeomPtr->setDimensions({emptyGeometry ? usize{0} : usize{4}, 3, 5}); - auto result = ValidateCellTupleCount(*geometry, geometryPath, tupleCount, dataPath, errorCode); + auto result = ValidateCellTupleCount(*gridGeomPtr, geometryPath, tupleCount, dataPath, errorCode); if(tupleCount == cellCount) { REQUIRE(result.valid()); From 232e70811a061c783546a5ef960bfdfa92296c18 Mon Sep 17 00:00:00 2001 From: Jessica Marquis Date: Thu, 15 Oct 2026 16:55:47 -0400 Subject: [PATCH 24/28] REV: Reuse cell tuple validation in three filters Use the shared count-only check in RequireMinNumNeighbors, WriteOnScaleTableFile, and PartitionGeometry. Preserve error codes and validation order while reporting the actual selected paths. Cover linked selections, separate data storage, unequal counts, and equal counts with different tuple shapes. Signed-off-by: Jessica Marquis --- .../Filters/PartitionGeometryFilter.cpp | 44 +++-- .../Filters/PartitionGeometryFilter.hpp | 60 ++++++- .../Filters/RequireMinNumNeighborsFilter.cpp | 15 +- .../Filters/WriteOnScaleTableFileFilter.cpp | 12 +- .../test/PartitionGeometryTest.cpp | 166 ++++++++++++++++++ .../test/RequireMinNumNeighborsTest.cpp | 53 ++++-- .../test/WriteOnScaleTableFileTest.cpp | 61 ++++++- 7 files changed, 361 insertions(+), 50 deletions(-) diff --git a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/PartitionGeometryFilter.cpp b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/PartitionGeometryFilter.cpp index d5d338ba27..2a9615a95a 100644 --- a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/PartitionGeometryFilter.cpp +++ b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/PartitionGeometryFilter.cpp @@ -16,8 +16,17 @@ #include "simplnx/Parameters/GeometrySelectionParameter.hpp" #include "simplnx/Parameters/NumberParameter.hpp" #include "simplnx/Parameters/VectorParameter.hpp" +#include "simplnx/Utilities/DataArrayUtilities.hpp" #include "simplnx/Utilities/GeometryUtilities.hpp" +#include +#include +#include +#include +#include +#include +#include + using namespace nx::core; namespace @@ -370,10 +379,10 @@ IFilter::PreflightResult PartitionGeometryFilter::preflightImpl(const DataStruct } case IGeometry::Type::RectGrid: { const auto& geometry = dataStructure.getDataRefAs({pInputGeometryToPartitionValue}); - if(attrMatrix.getNumberOfTuples() != geometry.getNumberOfCells()) + auto cellTupleResult = ValidateCellTupleCount(geometry, pInputGeometryToPartitionValue, attrMatrix.getNumberOfTuples(), pInputGeomCellAMPathValue, -3010); + if(cellTupleResult.invalid()) { - return {MakeErrorResult(-3010, fmt::format("{}: The attribute matrix '{}' does not have the same tuple count ({}) as geometry \"{}\"'s cell count ({}).", humanName(), - attrMatrix.getName(), attrMatrix.getNumberOfTuples(), geometry.getName(), geometry.getNumberOfCells()))}; + return {ConvertResultTo(std::move(cellTupleResult), {})}; } psInfo = GeneratePartitioningSchemeInfo(geometry, dataStructure, filterArgs); inputGeometryInformation = "Rectilinear grid geometry space unknown during preflight."; @@ -555,15 +564,16 @@ Result<> PartitionGeometryFilter::dataCheckPartitioningMode(const DataStructure& auto pInputGeomCellAMPathValue = filterArgs.value(k_InputGeometryCellAttributeMatrixPath_Key); const auto& attrMatrix = dataStructure.getDataRefAs({pInputGeomCellAMPathValue}); + const auto geometryToPartitionPath = filterArgs.value(k_InputGeometryToPartition_Key); switch(partitioningMode) { case PartitioningMode::Basic: - return dataCheckBasicMode(numOfPartitionsPerAxis, geometryToPartition, attrMatrix); + return dataCheckBasicMode(numOfPartitionsPerAxis, geometryToPartition, attrMatrix, geometryToPartitionPath, pInputGeomCellAMPathValue); case PartitioningMode::Advanced: - return dataCheckAdvancedMode(numOfPartitionsPerAxis, pCellLengthValue, geometryToPartition, attrMatrix); + return dataCheckAdvancedMode(numOfPartitionsPerAxis, pCellLengthValue, geometryToPartition, attrMatrix, geometryToPartitionPath, pInputGeomCellAMPathValue); case PartitioningMode::BoundingBox: - return dataCheckBoundingBoxMode(numOfPartitionsPerAxis, pMinGridCoordValue, pMaxGridCoordValue, geometryToPartition, attrMatrix); + return dataCheckBoundingBoxMode(numOfPartitionsPerAxis, pMinGridCoordValue, pMaxGridCoordValue, geometryToPartition, attrMatrix, geometryToPartitionPath, pInputGeomCellAMPathValue); case PartitioningMode::ExistingPartitionGrid: return DataCheckExistingGeometryMode(); } @@ -573,7 +583,8 @@ Result<> PartitionGeometryFilter::dataCheckPartitioningMode(const DataStructure& // ----------------------------------------------------------------------------- template -Result<> PartitionGeometryFilter::dataCheckBasicMode(const SizeVec3& numOfPartitionsPerAxis, const GeomType& geometryToPartition, const AttributeMatrix& attrMatrix) const +Result<> PartitionGeometryFilter::dataCheckBasicMode(const SizeVec3& numOfPartitionsPerAxis, const GeomType& geometryToPartition, const AttributeMatrix& attrMatrix, + const DataPath& geometryToPartitionPath, const DataPath& attrMatrixPath) const { Result<> result = DataCheckNumberOfPartitions(numOfPartitionsPerAxis); if(result.invalid()) @@ -581,7 +592,7 @@ Result<> PartitionGeometryFilter::dataCheckBasicMode(const SizeVec3& numOfPartit return result; } - result = dataCheckPartitioningScheme(geometryToPartition, attrMatrix); + result = dataCheckPartitioningScheme(geometryToPartition, attrMatrix, geometryToPartitionPath, attrMatrixPath); if(result.invalid()) { return result; @@ -593,7 +604,7 @@ Result<> PartitionGeometryFilter::dataCheckBasicMode(const SizeVec3& numOfPartit // ----------------------------------------------------------------------------- template Result<> PartitionGeometryFilter::dataCheckAdvancedMode(const SizeVec3& numOfPartitionsPerAxis, const FloatVec3& lengthPerPartition, const GeomType& geometryToPartition, - const AttributeMatrix& attrMatrix) const + const AttributeMatrix& attrMatrix, const DataPath& geometryToPartitionPath, const DataPath& attrMatrixPath) const { Result<> result = DataCheckNumberOfPartitions(numOfPartitionsPerAxis); if(result.invalid()) @@ -614,7 +625,7 @@ Result<> PartitionGeometryFilter::dataCheckAdvancedMode(const SizeVec3& numOfPar return MakeErrorResult(-3005, fmt::format("{}: Length Per Partition - The Z value ({}) cannot be negative.", humanName(), lengthPerPartition.getZ())); } - result = dataCheckPartitioningScheme(geometryToPartition, attrMatrix); + result = dataCheckPartitioningScheme(geometryToPartition, attrMatrix, geometryToPartitionPath, attrMatrixPath); if(result.invalid()) { return result; @@ -626,7 +637,7 @@ Result<> PartitionGeometryFilter::dataCheckAdvancedMode(const SizeVec3& numOfPar // ----------------------------------------------------------------------------- template Result<> PartitionGeometryFilter::dataCheckBoundingBoxMode(const SizeVec3& numOfPartitionsPerAxis, const FloatVec3& llCoord, const FloatVec3& urCoord, const GeomType& geometryToPartition, - const AttributeMatrix& attrMatrix) const + const AttributeMatrix& attrMatrix, const DataPath& geometryToPartitionPath, const DataPath& attrMatrixPath) const { Result<> result = DataCheckNumberOfPartitions(numOfPartitionsPerAxis); if(result.invalid()) @@ -649,7 +660,7 @@ Result<> PartitionGeometryFilter::dataCheckBoundingBoxMode(const SizeVec3& numOf return MakeErrorResult(-3008, fmt::format("{}: Lower Left Coordinate - Z value ({}) is larger than the upper right coordinate Z value ({}).", humanName(), llCoord.getZ(), urCoord.getZ())); } - result = dataCheckPartitioningScheme(geometryToPartition, attrMatrix); + result = dataCheckPartitioningScheme(geometryToPartition, attrMatrix, geometryToPartitionPath, attrMatrixPath); if(result.invalid()) { return result; @@ -667,15 +678,12 @@ Result<> PartitionGeometryFilter::DataCheckExistingGeometryMode() // ----------------------------------------------------------------------------- template -Result<> PartitionGeometryFilter::dataCheckPartitioningScheme(const GeomType& geometryToPartition, const AttributeMatrix& attrMatrix) const +Result<> PartitionGeometryFilter::dataCheckPartitioningScheme(const GeomType& geometryToPartition, const AttributeMatrix& attrMatrix, const DataPath& geometryToPartitionPath, + const DataPath& attrMatrixPath) const { if constexpr(std::is_same_v || std::is_same_v) { - if(attrMatrix.getNumberOfTuples() != geometryToPartition.getNumberOfCells()) - { - return MakeErrorResult(-3009, fmt::format("{}: The attribute matrix '{}' does not have the same tuple count ({}) as geometry \"{}\"'s cell count ({}).", humanName(), attrMatrix.getName(), - attrMatrix.getNumberOfTuples(), geometryToPartition.getName(), geometryToPartition.getNumberOfCells())); - } + return ValidateCellTupleCount(geometryToPartition, geometryToPartitionPath, attrMatrix.getNumberOfTuples(), attrMatrixPath, -3009); } else { diff --git a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/PartitionGeometryFilter.hpp b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/PartitionGeometryFilter.hpp index 51ecf2c695..129c8fcd13 100644 --- a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/PartitionGeometryFilter.hpp +++ b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/PartitionGeometryFilter.hpp @@ -11,6 +11,10 @@ #include "simplnx/Filter/FilterTraits.hpp" #include "simplnx/Filter/IFilter.hpp" +#include +#include +#include + namespace nx::core { /** @@ -153,20 +157,66 @@ class SIMPLNXCORE_EXPORT PartitionGeometryFilter : public IFilter template Result<> dataCheckPartitioningMode(const DataStructure& dataStructure, const Arguments& filterArgs, const GeomType& geometryToPartition) const; + /** + * @brief Checks partition counts before the geometry data count. + * @tparam GeomType Image, rectilinear, or node geometry type. + * @param numOfPartitionsPerAxis Partition count on each axis; each count must exceed zero. + * @param geometryToPartition Geometry that supplies the cell or vertex count. + * @param attrMatrix Selected matrix whose tuple count must match the geometry data count. + * @param geometryToPartitionPath Actual selected geometry path for grid diagnostics, including linked selections. + * @param attrMatrixPath Actual selected matrix path for grid diagnostics, including linked selections. + * @return First partition-count or geometry-data error, or a valid empty result. + */ template - Result<> dataCheckBasicMode(const SizeVec3& numOfPartitionsPerAxis, const GeomType& geometryToPartition, const AttributeMatrix& attrMatrix) const; + Result<> dataCheckBasicMode(const SizeVec3& numOfPartitionsPerAxis, const GeomType& geometryToPartition, const AttributeMatrix& attrMatrix, const DataPath& geometryToPartitionPath, + const DataPath& attrMatrixPath) const; + /** + * @brief Checks partition counts and lengths before the geometry data count. + * @tparam GeomType Image, rectilinear, or node geometry type. + * @param numOfPartitionsPerAxis Partition count on each axis; each count must exceed zero. + * @param lengthPerPartition Partition length on each axis; negative values are invalid. + * @param geometryToPartition Geometry that supplies the cell or vertex count. + * @param attrMatrix Selected matrix whose tuple count must match the geometry data count. + * @param geometryToPartitionPath Actual selected geometry path for grid diagnostics, including linked selections. + * @param attrMatrixPath Actual selected matrix path for grid diagnostics, including linked selections. + * @return First partition-count, length, or geometry-data error, or a valid empty result. + */ template - Result<> dataCheckAdvancedMode(const SizeVec3& numOfPartitionsPerAxis, const FloatVec3& lengthPerPartition, const GeomType& geometryToPartition, const AttributeMatrix& attrMatrix) const; + Result<> dataCheckAdvancedMode(const SizeVec3& numOfPartitionsPerAxis, const FloatVec3& lengthPerPartition, const GeomType& geometryToPartition, const AttributeMatrix& attrMatrix, + const DataPath& geometryToPartitionPath, const DataPath& attrMatrixPath) const; + /** + * @brief Checks partition counts and bounds before the geometry data count. + * @tparam GeomType Image, rectilinear, or node geometry type. + * @param numOfPartitionsPerAxis Partition count on each axis; each count must exceed zero. + * @param llCoord Lower corner; each coordinate must not exceed the corresponding upper corner coordinate. + * @param urCoord Upper corner of the partition grid. + * @param geometryToPartition Geometry that supplies the cell or vertex count. + * @param attrMatrix Selected matrix whose tuple count must match the geometry data count. + * @param geometryToPartitionPath Actual selected geometry path for grid diagnostics, including linked selections. + * @param attrMatrixPath Actual selected matrix path for grid diagnostics, including linked selections. + * @return First partition-count, bounds, or geometry-data error, or a valid empty result. + */ template - Result<> dataCheckBoundingBoxMode(const SizeVec3& numOfPartitionsPerAxis, const FloatVec3& llCoord, const FloatVec3& urCoord, const GeomType& geometryToPartition, - const AttributeMatrix& attrMatrix) const; + Result<> dataCheckBoundingBoxMode(const SizeVec3& numOfPartitionsPerAxis, const FloatVec3& llCoord, const FloatVec3& urCoord, const GeomType& geometryToPartition, const AttributeMatrix& attrMatrix, + const DataPath& geometryToPartitionPath, const DataPath& attrMatrixPath) const; static Result<> DataCheckExistingGeometryMode(); + /** + * @brief Checks the selected matrix tuple count against geometry cells or vertices. + * @tparam GeomType Image, rectilinear, or node geometry type. + * @param geometryToPartition Geometry that supplies the cell or vertex count. + * @param attrMatrix Selected matrix whose tuple count must match the geometry data count. + * @param geometryToPartitionPath Actual selected geometry path for grid diagnostics, including linked selections. + * @param attrMatrixPath Actual selected matrix path for grid diagnostics, including linked selections. + * @return Count-mismatch error, or a valid empty result when counts match. + * + * Grid validation compares counts only; tuple shapes and ownership need not match. + */ template - Result<> dataCheckPartitioningScheme(const GeomType& geometryToPartition, const AttributeMatrix& attrMatrix) const; + Result<> dataCheckPartitioningScheme(const GeomType& geometryToPartition, const AttributeMatrix& attrMatrix, const DataPath& geometryToPartitionPath, const DataPath& attrMatrixPath) const; /** * @brief Helper method that data checks the Number Of Partitions Per Axis variable. diff --git a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/RequireMinNumNeighborsFilter.cpp b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/RequireMinNumNeighborsFilter.cpp index e61996a2ca..cce321a6b3 100644 --- a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/RequireMinNumNeighborsFilter.cpp +++ b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/RequireMinNumNeighborsFilter.cpp @@ -11,9 +11,17 @@ #include "simplnx/Parameters/GeometrySelectionParameter.hpp" #include "simplnx/Parameters/MultiArraySelectionParameter.hpp" #include "simplnx/Parameters/NumberParameter.hpp" +#include "simplnx/Utilities/DataArrayUtilities.hpp" #include "simplnx/Utilities/FilterUtilities.hpp" #include "simplnx/Utilities/SIMPLConversion.hpp" +#include +#include +#include +#include +#include +#include + namespace nx::core { namespace @@ -110,11 +118,10 @@ IFilter::PreflightResult RequireMinNumNeighborsFilter::preflightImpl(const DataS auto& featureIds = dataStructure.getDataRefAs(featureIdsPath); auto& imageGeom = dataStructure.getDataRefAs(imageGeomPath); - if(featureIds.getNumberOfTuples() != imageGeom.getNumberOfCells()) + auto cellTupleResult = ValidateCellTupleCount(imageGeom, imageGeomPath, featureIds.getNumberOfTuples(), featureIdsPath, k_FeatureIdsTupleCountMismatch); + if(cellTupleResult.invalid()) { - return MakePreflightErrorResult(k_FeatureIdsTupleCountMismatch, - fmt::format("FeatureIds array '{}' contains {} tuples, but Image Geometry '{}' contains {} cells. Select a FeatureIds array that matches the Image Geometry.", - featureIdsPath.toString(), featureIds.getNumberOfTuples(), imageGeomPath.toString(), imageGeom.getNumberOfCells())); + return {ConvertResultTo(std::move(cellTupleResult), {})}; } dataArrayPaths.push_back(numNeighborsPath); diff --git a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/WriteOnScaleTableFileFilter.cpp b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/WriteOnScaleTableFileFilter.cpp index 7e44bc6c7d..deac7d30c1 100644 --- a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/WriteOnScaleTableFileFilter.cpp +++ b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/WriteOnScaleTableFileFilter.cpp @@ -12,10 +12,16 @@ #include "simplnx/Parameters/GeometrySelectionParameter.hpp" #include "simplnx/Parameters/StringParameter.hpp" #include "simplnx/Parameters/VectorParameter.hpp" +#include "simplnx/Utilities/DataArrayUtilities.hpp" #include "simplnx/Utilities/SIMPLConversion.hpp" #include "simplnx/Utilities/StringUtilities.hpp" +#include #include +#include +#include +#include +#include namespace fs = std::filesystem; using namespace nx::core; @@ -98,10 +104,10 @@ IFilter::PreflightResult WriteOnScaleTableFileFilter::preflightImpl(const DataSt const auto& geometry = dataStructure.getDataRefAs(geometryPath); const auto featureIdsPath = filterArgs.value(k_FeatureIdsArrayPath_Key); const auto& featureIds = dataStructure.getDataRefAs(featureIdsPath); - if(featureIds.getNumberOfTuples() != geometry.getNumberOfCells()) + auto cellTupleResult = ValidateCellTupleCount(geometry, geometryPath, featureIds.getNumberOfTuples(), featureIdsPath, -12024); + if(cellTupleResult.invalid()) { - return MakePreflightErrorResult(-12024, fmt::format("The array '{}' has {} tuples, but the grid geometry '{}' has {} cells.", featureIdsPath.toString(), featureIds.getNumberOfTuples(), - geometryPath.toString(), geometry.getNumberOfCells())); + return {ConvertResultTo(std::move(cellTupleResult), {})}; } const auto phaseNamesPath = filterArgs.value(k_PhaseNamesArrayPath_Key); diff --git a/src/Plugins/SimplnxCore/test/PartitionGeometryTest.cpp b/src/Plugins/SimplnxCore/test/PartitionGeometryTest.cpp index 062a39e119..be3896d80c 100644 --- a/src/Plugins/SimplnxCore/test/PartitionGeometryTest.cpp +++ b/src/Plugins/SimplnxCore/test/PartitionGeometryTest.cpp @@ -7,11 +7,18 @@ #include #include +#include #include #include +#include +#include +#include +#include +#include #include "simplnx/DataStructure/AttributeMatrix.hpp" #include "simplnx/DataStructure/DataArray.hpp" +#include "simplnx/DataStructure/DataGroup.hpp" #include "simplnx/DataStructure/Geometry/ImageGeom.hpp" #include "simplnx/DataStructure/Geometry/RectGridGeom.hpp" #include "simplnx/Parameters/ArrayCreationParameter.hpp" @@ -213,6 +220,85 @@ using FileSentinelType = nx::core::UnitTest::TestFileSentinel; using SharedFileSentinelType = std::shared_ptr; // One shared sentinel keeps the extracted geometry fixtures available across each parameterized loop. SharedFileSentinelType s_FileSentinel; + +const DataPath k_SelectedTupleGeometryPath({"Selected", "Geometries", "Geometry"}); +const DataPath k_SelectedTupleMatrixPath({"Selected", "Arrays", "CellData"}); + +/** + * @brief Creates an eight-cell grid and separately stored selected cell data. + * @param dataStructure Receives the fixture and linked selected paths. + * @param rectilinear Chooses a rectilinear grid instead of an image geometry. + * @param tupleCount Number of tuples in the selected AttributeMatrix. + */ +void CreateCellTupleValidationInput(DataStructure& dataStructure, bool rectilinear, usize tupleCount) +{ + auto* storedGeometryGroup = DataGroup::Create(dataStructure, "StoredGeometry"); + REQUIRE(storedGeometryGroup != nullptr); + IGridGeometry* geometry = nullptr; + if(rectilinear) + { + auto* rectGrid = RectGridGeom::Create(dataStructure, "Geometry", storedGeometryGroup->getId()); + REQUIRE(rectGrid != nullptr); + rectGrid->setDimensions({2, 2, 2}); + auto* xBounds = UnitTest::CreateTestDataArray(dataStructure, "XBounds", {3}, {1}, rectGrid->getId()); + auto* yBounds = UnitTest::CreateTestDataArray(dataStructure, "YBounds", {3}, {1}, rectGrid->getId()); + auto* zBounds = UnitTest::CreateTestDataArray(dataStructure, "ZBounds", {3}, {1}, rectGrid->getId()); + REQUIRE(xBounds != nullptr); + REQUIRE(yBounds != nullptr); + REQUIRE(zBounds != nullptr); + for(usize index = 0; index < 3; index++) + { + (*xBounds)[index] = static_cast(index); + (*yBounds)[index] = static_cast(index); + (*zBounds)[index] = static_cast(index); + } + rectGrid->setXBoundsId(xBounds->getId()); + rectGrid->setYBoundsId(yBounds->getId()); + rectGrid->setZBoundsId(zBounds->getId()); + geometry = rectGrid; + } + else + { + auto* image = ImageGeom::Create(dataStructure, "Geometry", storedGeometryGroup->getId()); + REQUIRE(image != nullptr); + image->setDimensions({2, 2, 2}); + image->setSpacing({1.0F, 1.0F, 1.0F}); + image->setOrigin({0.0F, 0.0F, 0.0F}); + geometry = image; + } + auto* geometryCellData = AttributeMatrix::Create(dataStructure, "GeometryCellData", {2, 2, 2}, geometry->getId()); + REQUIRE(geometryCellData != nullptr); + geometry->setCellData(*geometryCellData); + auto* storedDataGroup = DataGroup::Create(dataStructure, "StoredData"); + REQUIRE(storedDataGroup != nullptr); + // {4, 2} has eight tuples, with neither shape nor ownership matching the grid. + const ShapeType tupleShape = tupleCount == 8 ? ShapeType{4, 2} : ShapeType{tupleCount}; + auto* selectedMatrix = AttributeMatrix::Create(dataStructure, "CellData", tupleShape, storedDataGroup->getId()); + REQUIRE(selectedMatrix != nullptr); + auto* selected = DataGroup::Create(dataStructure, "Selected"); + REQUIRE(selected != nullptr); + auto* selectedGeometries = DataGroup::Create(dataStructure, "Geometries", selected->getId()); + auto* selectedArrays = DataGroup::Create(dataStructure, "Arrays", selected->getId()); + REQUIRE(selectedGeometries != nullptr); + REQUIRE(selectedArrays != nullptr); + REQUIRE(dataStructure.setAdditionalParent(geometry->getId(), selectedGeometries->getId())); + REQUIRE(dataStructure.setAdditionalParent(selectedMatrix->getId(), selectedArrays->getId())); +} + +/** + * @brief Configures one of the three modes that creates a partition grid. + * @param mode Basic, advanced, or bounding-box mode index. + * @return Arguments using the linked selected geometry and matrix paths. + */ +Arguments CreateCellTupleValidationArguments(ChoicesParameter::ValueType mode) +{ + Arguments args = createBasicPartitionGeometryArguments(k_SelectedTupleGeometryPath, k_SelectedTupleMatrixPath, "PartitionIds", {2, 2, 2}, {}); + args.insertOrAssign(PartitionGeometryFilter::k_PartitioningMode_Key, mode); + args.insertOrAssign(PartitionGeometryFilter::k_CellLength_Key, std::vector{1.0F, 1.0F, 1.0F}); + args.insertOrAssign(PartitionGeometryFilter::k_MinGridCoord_Key, std::vector{0.0F, 0.0F, 0.0F}); + args.insertOrAssign(PartitionGeometryFilter::k_MaxGridCoord_Key, std::vector{2.0F, 2.0F, 2.0F}); + return args; +} } // namespace TEST_CASE("SimplnxCore::PartitionGeometryFilter: Basic RectGrid bounds", "[Plugins][PartitionGeometryFilter]") @@ -286,6 +372,86 @@ TEST_CASE("SimplnxCore::PartitionGeometryFilter: Basic RectGrid bounds", "[Plugi UnitTest::CheckArraysInheritTupleDims(dataStructure); } +TEST_CASE("SimplnxCore::PartitionGeometryFilter: Selected cell tuple counts", "[Plugins][PartitionGeometryFilter]") +{ + UnitTest::LoadPlugins(); + const bool rectilinear = GENERATE(false, true); + const auto mode = GENERATE(ChoicesParameter::ValueType{0}, ChoicesParameter::ValueType{1}, ChoicesParameter::ValueType{2}); + const usize tupleCount = GENERATE(usize{7}, usize{8}, usize{9}); + CAPTURE(rectilinear, mode, tupleCount); + DataStructure dataStructure; + CreateCellTupleValidationInput(dataStructure, rectilinear, tupleCount); + const PartitionGeometryFilter filter; + const auto preflightResult = filter.preflight(dataStructure, CreateCellTupleValidationArguments(mode)); + if(tupleCount == 8) + { + SIMPLNX_RESULT_REQUIRE_VALID(preflightResult.outputActions); + } + else + { + SIMPLNX_RESULT_REQUIRE_INVALID(preflightResult.outputActions); + REQUIRE(preflightResult.outputActions.errors().size() == 1); + const auto& error = preflightResult.outputActions.errors()[0]; + CHECK(error.code == (rectilinear ? -3010 : -3009)); + CHECK(error.message.find(k_SelectedTupleGeometryPath.toString()) != std::string::npos); + CHECK(error.message.find(k_SelectedTupleMatrixPath.toString()) != std::string::npos); + CHECK(error.message.find(fmt::format("has {} tuples", tupleCount)) != std::string::npos); + CHECK(error.message.find("has 8 cells") != std::string::npos); + CHECK(error.message.find("one tuple per geometry cell") != std::string::npos); + } + UnitTest::CheckArraysInheritTupleDims(dataStructure); +} + +TEST_CASE("SimplnxCore::PartitionGeometryFilter: Partition counts precede image tuple validation", "[Plugins][PartitionGeometryFilter]") +{ + UnitTest::LoadPlugins(); + const auto mode = GENERATE(ChoicesParameter::ValueType{0}, ChoicesParameter::ValueType{1}, ChoicesParameter::ValueType{2}); + const usize axis = GENERATE(usize{0}, usize{1}, usize{2}); + CAPTURE(mode, axis); + DataStructure dataStructure; + CreateCellTupleValidationInput(dataStructure, false, 7); + Arguments args = CreateCellTupleValidationArguments(mode); + std::vector partitionCounts = {2, 2, 2}; + partitionCounts[axis] = 0; + args.insertOrAssign(PartitionGeometryFilter::k_NumberOfCellsPerAxis_Key, partitionCounts); + // A partition-count error also precedes invalid advanced lengths/bounds. + args.insertOrAssign(PartitionGeometryFilter::k_CellLength_Key, std::vector{-1.0F, -1.0F, -1.0F}); + args.insertOrAssign(PartitionGeometryFilter::k_MinGridCoord_Key, std::vector{3.0F, 3.0F, 3.0F}); + const auto preflightResult = PartitionGeometryFilter().preflight(dataStructure, args); + SIMPLNX_RESULT_REQUIRE_INVALID(preflightResult.outputActions); + REQUIRE(preflightResult.outputActions.errors().size() == 1); + CHECK(preflightResult.outputActions.errors()[0].code == -3012 - static_cast(axis)); + UnitTest::CheckArraysInheritTupleDims(dataStructure); +} + +TEST_CASE("SimplnxCore::PartitionGeometryFilter: Mode errors precede image tuple validation", "[Plugins][PartitionGeometryFilter]") +{ + UnitTest::LoadPlugins(); + const auto mode = GENERATE(ChoicesParameter::ValueType{1}, ChoicesParameter::ValueType{2}); + const usize axis = GENERATE(usize{0}, usize{1}, usize{2}); + CAPTURE(mode, axis); + DataStructure dataStructure; + CreateCellTupleValidationInput(dataStructure, false, 7); + Arguments args = CreateCellTupleValidationArguments(mode); + std::vector invalidValues = {1.0F, 1.0F, 1.0F}; + if(mode == static_cast(PartitionGeometryFilter::PartitioningMode::Advanced)) + { + invalidValues[axis] = -1.0F; + args.insertOrAssign(PartitionGeometryFilter::k_CellLength_Key, invalidValues); + } + else + { + invalidValues[axis] = 3.0F; + args.insertOrAssign(PartitionGeometryFilter::k_MinGridCoord_Key, invalidValues); + } + const auto preflightResult = PartitionGeometryFilter().preflight(dataStructure, args); + SIMPLNX_RESULT_REQUIRE_INVALID(preflightResult.outputActions); + REQUIRE(preflightResult.outputActions.errors().size() == 1); + const int32 firstAxisError = mode == static_cast(PartitionGeometryFilter::PartitioningMode::Advanced) ? -3003 : -3006; + CHECK(preflightResult.outputActions.errors()[0].code == firstAxisError - static_cast(axis)); + UnitTest::CheckArraysInheritTupleDims(dataStructure); +} + TEST_CASE("SimplnxCore::PartitionGeometryFilter: Basic", "[Plugins][PartitionGeometryFilter]") { const auto scenario = GENERATE(from_range(UnitTest::SelectAlgorithmTestScenariosForInMemoryStores())); diff --git a/src/Plugins/SimplnxCore/test/RequireMinNumNeighborsTest.cpp b/src/Plugins/SimplnxCore/test/RequireMinNumNeighborsTest.cpp index a8b701a046..9ac0cbf239 100644 --- a/src/Plugins/SimplnxCore/test/RequireMinNumNeighborsTest.cpp +++ b/src/Plugins/SimplnxCore/test/RequireMinNumNeighborsTest.cpp @@ -6,6 +6,7 @@ #include "simplnx/Core/Application.hpp" #include "simplnx/DataStructure/AttributeMatrix.hpp" #include "simplnx/DataStructure/DataArray.hpp" +#include "simplnx/DataStructure/DataGroup.hpp" #include "simplnx/DataStructure/Geometry/ImageGeom.hpp" #include "simplnx/Parameters/MultiArraySelectionParameter.hpp" #include "simplnx/Pipeline/Pipeline.hpp" @@ -16,11 +17,14 @@ #include +#include #include #include #include #include +#include #include +#include #include namespace fs = std::filesystem; @@ -637,32 +641,59 @@ TEST_CASE("SimplnxCore::RequireMinNumNeighborsFilter: Preflight Error - tuple co REQUIRE(preflightResult.outputActions.errors()[0].code == -252); } -TEST_CASE("SimplnxCore::RequireMinNumNeighborsFilter: Preflight Error - FeatureIds tuple count mismatch (-55571)", "[SimplnxCore][RequireMinNumNeighborsFilter][preflight]") +TEST_CASE("SimplnxCore::RequireMinNumNeighborsFilter: Selected cell tuple counts", "[SimplnxCore][RequireMinNumNeighborsFilter][preflight]") { UnitTest::LoadPlugins(); + const usize tupleCount = GENERATE(usize{3}, usize{4}, usize{5}); + CAPTURE(tupleCount); DataStructure dataStructure; - auto* imageGeom = ImageGeom::Create(dataStructure, "ImageGeometry"); - imageGeom->setDimensions({5, 1, 1}); - auto* cellAM = AttributeMatrix::Create(dataStructure, "CellData", {1, 1, 4}, imageGeom->getId()); - imageGeom->setCellData(*cellAM); + auto* selectedGroup = DataGroup::Create(dataStructure, "Selected"); + REQUIRE(selectedGroup != nullptr); + auto* imageGeom = ImageGeom::Create(dataStructure, "ImageGeometry", selectedGroup->getId()); + REQUIRE(imageGeom != nullptr); + imageGeom->setDimensions({2, 2, 1}); + auto* storageGroup = DataGroup::Create(dataStructure, "Storage"); + REQUIRE(storageGroup != nullptr); + // Equal counts are valid even when the selected array is stored separately + // and its tuple shape differs from the geometry's {1, 2, 2} shape. + auto* cellAM = AttributeMatrix::Create(dataStructure, "CellData", {tupleCount}, storageGroup->getId()); + REQUIRE(cellAM != nullptr); auto* featureAM = AttributeMatrix::Create(dataStructure, "FeatureData", {4}, imageGeom->getId()); - UnitTest::CreateTestDataArray(dataStructure, "FeatureIds", {1, 1, 4}, {1}, cellAM->getId()); + REQUIRE(featureAM != nullptr); + UnitTest::CreateTestDataArray(dataStructure, "FeatureIds", {tupleCount}, {1}, cellAM->getId()); UnitTest::CreateTestDataArray(dataStructure, "NumNeighbors", {4}, {1}, featureAM->getId()); + const DataPath geometryPath({"Selected", "ImageGeometry"}); + const DataPath featureIdsPath({"Storage", "CellData", "FeatureIds"}); RequireMinNumNeighborsFilter filter; Arguments args; args.insertOrAssign(RequireMinNumNeighborsFilter::k_MinNumNeighbors_Key, std::make_any(0)); args.insertOrAssign(RequireMinNumNeighborsFilter::k_ApplyToSinglePhase_Key, std::make_any(false)); args.insertOrAssign(RequireMinNumNeighborsFilter::k_PhaseNumber_Key, std::make_any(0)); - args.insertOrAssign(RequireMinNumNeighborsFilter::k_SelectedImageGeometryPath_Key, std::make_any(DataPath({"ImageGeometry"}))); - args.insertOrAssign(RequireMinNumNeighborsFilter::k_FeatureIdsPath_Key, std::make_any(DataPath({"ImageGeometry", "CellData", "FeatureIds"}))); - args.insertOrAssign(RequireMinNumNeighborsFilter::k_NumNeighborsPath_Key, std::make_any(DataPath({"ImageGeometry", "FeatureData", "NumNeighbors"}))); + args.insertOrAssign(RequireMinNumNeighborsFilter::k_SelectedImageGeometryPath_Key, std::make_any(geometryPath)); + args.insertOrAssign(RequireMinNumNeighborsFilter::k_FeatureIdsPath_Key, std::make_any(featureIdsPath)); + args.insertOrAssign(RequireMinNumNeighborsFilter::k_NumNeighborsPath_Key, std::make_any(geometryPath.createChildPath("FeatureData").createChildPath("NumNeighbors"))); args.insertOrAssign(RequireMinNumNeighborsFilter::k_IgnoredVoxelArrays_Key, std::make_any>(std::vector{})); const auto preflightResult = filter.preflight(dataStructure, args); - SIMPLNX_RESULT_REQUIRE_INVALID(preflightResult.outputActions); - REQUIRE(preflightResult.outputActions.errors()[0].code == -55571); + if(tupleCount == 4) + { + SIMPLNX_RESULT_REQUIRE_VALID(preflightResult.outputActions); + } + else + { + SIMPLNX_RESULT_REQUIRE_INVALID(preflightResult.outputActions); + REQUIRE(preflightResult.outputActions.errors().size() == 1); + const auto& error = preflightResult.outputActions.errors()[0]; + CHECK(error.code == -55571); + CHECK(error.message.find(featureIdsPath.toString()) != std::string::npos); + CHECK(error.message.find(geometryPath.toString()) != std::string::npos); + CHECK(error.message.find(fmt::format("has {} tuples", tupleCount)) != std::string::npos); + CHECK(error.message.find("has 4 cells") != std::string::npos); + CHECK(error.message.find("one tuple per geometry cell") != std::string::npos); + } + UnitTest::CheckArraysInheritTupleDims(dataStructure); } TEST_CASE("SimplnxCore::RequireMinNumNeighborsFilter: Execute Error - feature ID out of range (-55567)", "[SimplnxCore][RequireMinNumNeighborsFilter][execute]") diff --git a/src/Plugins/SimplnxCore/test/WriteOnScaleTableFileTest.cpp b/src/Plugins/SimplnxCore/test/WriteOnScaleTableFileTest.cpp index 909ba867df..dd4c27c444 100644 --- a/src/Plugins/SimplnxCore/test/WriteOnScaleTableFileTest.cpp +++ b/src/Plugins/SimplnxCore/test/WriteOnScaleTableFileTest.cpp @@ -6,6 +6,7 @@ #include "simplnx/Core/Application.hpp" #include "simplnx/DataStructure/AttributeMatrix.hpp" #include "simplnx/DataStructure/DataArray.hpp" +#include "simplnx/DataStructure/DataGroup.hpp" #include "simplnx/DataStructure/Geometry/ImageGeom.hpp" #include "simplnx/DataStructure/Geometry/RectGridGeom.hpp" #include "simplnx/DataStructure/StringArray.hpp" @@ -24,16 +25,20 @@ #include #include +#include +#include #include #include #include #include #include +#include #include #include #include #include #include +#include #include namespace fs = std::filesystem; @@ -46,7 +51,6 @@ const DataPath k_CellDataPath = k_GeometryPath.createChildPath("Cell Data"); const DataPath k_FeatureIdsPath = k_CellDataPath.createChildPath("FeatureIds"); const DataPath k_EnsembleDataPath = k_GeometryPath.createChildPath("Cell Ensemble Data"); const DataPath k_PhaseNamesPath = k_EnsembleDataPath.createChildPath("PhaseNames"); -const DataPath k_WrongFeatureIdsPath({"Wrong FeatureIds"}); template DataStructure CreateImageDataStructure(const SizeVec3& dimensions, const std::vector& featureIds, const std::vector& phaseNames, const FloatVec3& spacing = {0.001F, 0.002F, 0.003F}, @@ -596,19 +600,58 @@ TEST_CASE("SimplnxCore::WriteOnScaleTableFileFilter: RectGrid Needs Reorder Fail UnitTest::CheckArraysInheritTupleDims(dataStructure); } -TEST_CASE("SimplnxCore::WriteOnScaleTableFileFilter: Tuple Count Mismatch", "[SimplnxCore][WriteOnScaleTableFileFilter]") +TEST_CASE("SimplnxCore::WriteOnScaleTableFileFilter: Selected cell tuple counts", "[SimplnxCore][WriteOnScaleTableFileFilter]") { UnitTest::LoadPlugins(); + const bool rectilinear = GENERATE(false, true); + const usize tupleCount = GENERATE(usize{3}, usize{4}, usize{5}); + CAPTURE(rectilinear, tupleCount); + + DataStructure dataStructure; + if(rectilinear) + { + const std::array, 3> bounds = {{{0.0F, 1.0F, 2.0F}, {0.0F, 1.0F, 2.0F}, {0.0F, 1.0F}}}; + dataStructure = CreateRectGridDataStructure({2, 2, 1}, bounds, {1, 2, 3, 1}, {"", "Phase1", "Phase2", "Phase3"}); + } + else + { + dataStructure = CreateImageDataStructure({2, 2, 1}, {1, 2, 3, 1}, {"", "Phase1", "Phase2", "Phase3"}); + } + auto* selectedGroup = DataGroup::Create(dataStructure, "Selected"); + REQUIRE(selectedGroup != nullptr); + REQUIRE_NOTHROW(dataStructure.getDataRefAs(k_GeometryPath)); + REQUIRE(dataStructure.setAdditionalParent(dataStructure.getDataRefAs(k_GeometryPath).getId(), selectedGroup->getId())); + const DataPath geometryPath({"Selected", "Geometry"}); + auto* storageGroup = DataGroup::Create(dataStructure, "Storage"); + REQUIRE(storageGroup != nullptr); + auto* selectedCellData = AttributeMatrix::Create(dataStructure, "Cell Data", {tupleCount}, storageGroup->getId()); + REQUIRE(selectedCellData != nullptr); + const DataPath featureIdsPath({"Storage", "Cell Data", "FeatureIds"}); + auto featureIdsStore = DataStoreUtilities::CreateDataStore(dataStructure, featureIdsPath, {tupleCount}, {1}); + REQUIRE(Int32Array::Create(dataStructure, "FeatureIds", featureIdsStore, selectedCellData->getId()) != nullptr); - DataStructure dataStructure = CreateImageDataStructure({2, 2, 1}, {1, 2, 3, 1}, {"", "Phase1", "Phase2", "Phase3"}); - auto wrongFeatureIdsStore = DataStoreUtilities::CreateDataStore(dataStructure, k_WrongFeatureIdsPath, {3}, {1}); - REQUIRE(Int32Array::Create(dataStructure, k_WrongFeatureIdsPath.getTargetName(), wrongFeatureIdsStore) != nullptr); const WriteOnScaleTableFileFilter filter; Arguments args = CreateArguments(fs::path(unit_test::k_BinaryTestOutputDir.view()), "Tuple_Mismatch"); - args.insertOrAssign(WriteOnScaleTableFileFilter::k_FeatureIdsArrayPath_Key, std::make_any(k_WrongFeatureIdsPath)); - auto preflightResult = filter.preflight(dataStructure, args); - REQUIRE(preflightResult.outputActions.invalid()); - + args.insertOrAssign(WriteOnScaleTableFileFilter::k_InputGeometryPath_Key, std::make_any(geometryPath)); + args.insertOrAssign(WriteOnScaleTableFileFilter::k_FeatureIdsArrayPath_Key, std::make_any(featureIdsPath)); + const auto preflightResult = filter.preflight(dataStructure, args); + if(tupleCount == 4) + { + // The separately stored flat tuple shape is a valid count-only match. + SIMPLNX_RESULT_REQUIRE_VALID(preflightResult.outputActions); + } + else + { + SIMPLNX_RESULT_REQUIRE_INVALID(preflightResult.outputActions); + REQUIRE(preflightResult.outputActions.errors().size() == 1); + const auto& error = preflightResult.outputActions.errors()[0]; + CHECK(error.code == -12024); + CHECK(error.message.find(featureIdsPath.toString()) != std::string::npos); + CHECK(error.message.find(geometryPath.toString()) != std::string::npos); + CHECK(error.message.find(fmt::format("has {} tuples", tupleCount)) != std::string::npos); + CHECK(error.message.find("has 4 cells") != std::string::npos); + CHECK(error.message.find("one tuple per geometry cell") != std::string::npos); + } UnitTest::CheckArraysInheritTupleDims(dataStructure); } From 697a0a3d2ee7ab747bc6fd25e4b60ac3c0defba1 Mon Sep 17 00:00:00 2001 From: Jessica Marquis Date: Mon, 19 Oct 2026 15:10:25 -0400 Subject: [PATCH 25/28] DOC: Define the shared tuple diagnostic prefix policy State that the selected geometry and data paths identify the inputs, so the shared count diagnostic does not add a filter-name prefix. Signed-off-by: Jessica Marquis --- src/simplnx/Utilities/DataArrayUtilities.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/simplnx/Utilities/DataArrayUtilities.hpp b/src/simplnx/Utilities/DataArrayUtilities.hpp index 487dad7759..8d2bca210b 100644 --- a/src/simplnx/Utilities/DataArrayUtilities.hpp +++ b/src/simplnx/Utilities/DataArrayUtilities.hpp @@ -62,6 +62,7 @@ class IGridGeometry; * @return Empty valid result if the counts match; otherwise, an error with both paths and counts. * * This check compares counts only. It does not read array values or require matching tuple shapes or a common parent. + * The error omits a filter-name prefix. The selected paths identify the geometry and data. */ SIMPLNX_EXPORT Result<> ValidateCellTupleCount(const IGridGeometry& geometry, const DataPath& geometryPath, usize tupleCount, const DataPath& dataPath, int32 errorCode); From a1f160eab9ecb0cc976047f7065e06047aa53074 Mon Sep 17 00:00:00 2001 From: Jessica Marquis Date: Mon, 19 Oct 2026 15:10:25 -0400 Subject: [PATCH 26/28] REV: Include the span type used by partition tests Replace the unused standard span header with the direct nonstd span dependency used by the test fixtures. Signed-off-by: Jessica Marquis --- src/Plugins/SimplnxCore/test/PartitionGeometryTest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Plugins/SimplnxCore/test/PartitionGeometryTest.cpp b/src/Plugins/SimplnxCore/test/PartitionGeometryTest.cpp index be3896d80c..d57f2a165e 100644 --- a/src/Plugins/SimplnxCore/test/PartitionGeometryTest.cpp +++ b/src/Plugins/SimplnxCore/test/PartitionGeometryTest.cpp @@ -4,6 +4,7 @@ */ #include +#include #include #include @@ -12,7 +13,6 @@ #include #include #include -#include #include #include From 5d8ef6bd30fc7277b3c507a910a995f8651873f9 Mon Sep 17 00:00:00 2001 From: Jessica Marquis Date: Mon, 19 Oct 2026 15:28:31 -0400 Subject: [PATCH 27/28] REV: Give vertex tuple mismatches a distinct diagnostic Reuse a local metadata check at both vertex-count validation sites. Report selected paths, actual and expected counts, and corrective action with error -3043. Preserve cell and partition-count error meanings. Test linked selections, all four modes, and independent eight-vertex counts, including separation from the Z partition-count error. Signed-off-by: Jessica Marquis --- .../Filters/PartitionGeometryFilter.cpp | 42 ++++-- .../Filters/PartitionGeometryFilter.hpp | 16 +- .../test/PartitionGeometryTest.cpp | 139 ++++++++++++++++++ 3 files changed, 177 insertions(+), 20 deletions(-) diff --git a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/PartitionGeometryFilter.cpp b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/PartitionGeometryFilter.cpp index 2a9615a95a..9ce8f758ed 100644 --- a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/PartitionGeometryFilter.cpp +++ b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/PartitionGeometryFilter.cpp @@ -1,7 +1,12 @@ #include "PartitionGeometryFilter.hpp" #include "simplnx/Common/Array.hpp" +#include "simplnx/Common/Result.hpp" +#include "simplnx/Common/Types.hpp" #include "simplnx/DataStructure/AttributeMatrix.hpp" +#include "simplnx/DataStructure/DataPath.hpp" +#include "simplnx/DataStructure/DataStructure.hpp" +#include "simplnx/DataStructure/Geometry/INodeGeometry0D.hpp" #include "simplnx/DataStructure/Geometry/RectGridGeom.hpp" #include "simplnx/DataStructure/Geometry/VertexGeom.hpp" #include "simplnx/Filter/Actions/CreateArrayAction.hpp" @@ -19,6 +24,8 @@ #include "simplnx/Utilities/DataArrayUtilities.hpp" #include "simplnx/Utilities/GeometryUtilities.hpp" +#include + #include #include #include @@ -44,6 +51,25 @@ const ChoicesParameter::ValueType k_AdvancedModeIndex = 1; const ChoicesParameter::ValueType k_BoundingBoxModeIndex = 2; const ChoicesParameter::ValueType k_ExistingSchemeModeIndex = 3; +/** + * @brief Checks the selected tuple count against vertex metadata without reading coordinate values. + * @param geometry Supplies the vertex count. + * @param geometryPath Selected geometry path, including linked selections. + * @param tupleCount Number of tuples in the selected data. + * @param dataPath Selected data path, including linked selections. + * @return Error -3043 if the counts differ; otherwise, a valid result. + */ +Result<> validateVertexTupleCount(const INodeGeometry0D& geometry, const DataPath& geometryPath, usize tupleCount, const DataPath& dataPath) +{ + const usize vertexCount = geometry.getVerticesRef().getNumberOfTuples(); + if(tupleCount != vertexCount) + { + return MakeErrorResult(-3043, fmt::format("The selected data '{}' has {} tuples, but the selected node geometry '{}' has {} vertices. Select data with one tuple per geometry vertex.", + dataPath.toString(), tupleCount, geometryPath.toString(), vertexCount)); + } + return {}; +} + /** * @brief Generates the display text that describes the input geometry, * shown as a preflight updated value in the user interface. @@ -506,12 +532,11 @@ Result PartitionGeometryFilter::generateNodeBased const DataPath& attrMatrixPath) const { const auto& geometry = dataStructure.getDataRefAs({geometryToPartitionPath}); - const IGeometry::SharedVertexList& vertexList = geometry.getVerticesRef(); const auto& attrMatrix = dataStructure.getDataRefAs(attrMatrixPath); - if(attrMatrix.getNumberOfTuples() != vertexList.getNumberOfTuples()) + auto vertexTupleResult = validateVertexTupleCount(geometry, geometryToPartitionPath, attrMatrix.getNumberOfTuples(), attrMatrixPath); + if(vertexTupleResult.invalid()) { - return {MakeErrorResult(-3014, fmt::format("{}: The attribute matrix '{}' does not have the same tuple count ({}) as geometry \"{}\"'s vertex count ({}).", - humanName(), attrMatrix.getName(), attrMatrix.getNumberOfTuples(), geometry.getName(), geometry.getNumberOfVertices()))}; + return {ConvertResultTo(std::move(vertexTupleResult), {})}; } Result<> dimensionalityResult = DataCheckDimensionality(geometry); if(dimensionalityResult.invalid()) @@ -687,15 +712,8 @@ Result<> PartitionGeometryFilter::dataCheckPartitioningScheme(const GeomType& ge } else { - const IGeometry::SharedVertexList& vertexList = geometryToPartition.getVertices(); - if(attrMatrix.getNumberOfTuples() != vertexList.getNumberOfTuples()) - { - return MakeErrorResult(-3010, fmt::format("{}: The attribute matrix '{}' does not have the same tuple count ({}) as geometry \"{}\"'s vertex count ({}).", humanName(), attrMatrix.getName(), - attrMatrix.getNumberOfTuples(), geometryToPartition.getName(), vertexList.getNumberOfTuples())); - } + return validateVertexTupleCount(geometryToPartition, geometryToPartitionPath, attrMatrix.getNumberOfTuples(), attrMatrixPath); } - - return {}; } // ----------------------------------------------------------------------------- diff --git a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/PartitionGeometryFilter.hpp b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/PartitionGeometryFilter.hpp index 129c8fcd13..ce2ef58154 100644 --- a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/PartitionGeometryFilter.hpp +++ b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/PartitionGeometryFilter.hpp @@ -163,8 +163,8 @@ class SIMPLNXCORE_EXPORT PartitionGeometryFilter : public IFilter * @param numOfPartitionsPerAxis Partition count on each axis; each count must exceed zero. * @param geometryToPartition Geometry that supplies the cell or vertex count. * @param attrMatrix Selected matrix whose tuple count must match the geometry data count. - * @param geometryToPartitionPath Actual selected geometry path for grid diagnostics, including linked selections. - * @param attrMatrixPath Actual selected matrix path for grid diagnostics, including linked selections. + * @param geometryToPartitionPath Actual selected geometry path for geometry diagnostics, including linked selections. + * @param attrMatrixPath Actual selected matrix path for geometry diagnostics, including linked selections. * @return First partition-count or geometry-data error, or a valid empty result. */ template @@ -178,8 +178,8 @@ class SIMPLNXCORE_EXPORT PartitionGeometryFilter : public IFilter * @param lengthPerPartition Partition length on each axis; negative values are invalid. * @param geometryToPartition Geometry that supplies the cell or vertex count. * @param attrMatrix Selected matrix whose tuple count must match the geometry data count. - * @param geometryToPartitionPath Actual selected geometry path for grid diagnostics, including linked selections. - * @param attrMatrixPath Actual selected matrix path for grid diagnostics, including linked selections. + * @param geometryToPartitionPath Actual selected geometry path for geometry diagnostics, including linked selections. + * @param attrMatrixPath Actual selected matrix path for geometry diagnostics, including linked selections. * @return First partition-count, length, or geometry-data error, or a valid empty result. */ template @@ -194,8 +194,8 @@ class SIMPLNXCORE_EXPORT PartitionGeometryFilter : public IFilter * @param urCoord Upper corner of the partition grid. * @param geometryToPartition Geometry that supplies the cell or vertex count. * @param attrMatrix Selected matrix whose tuple count must match the geometry data count. - * @param geometryToPartitionPath Actual selected geometry path for grid diagnostics, including linked selections. - * @param attrMatrixPath Actual selected matrix path for grid diagnostics, including linked selections. + * @param geometryToPartitionPath Actual selected geometry path for geometry diagnostics, including linked selections. + * @param attrMatrixPath Actual selected matrix path for geometry diagnostics, including linked selections. * @return First partition-count, bounds, or geometry-data error, or a valid empty result. */ template @@ -209,8 +209,8 @@ class SIMPLNXCORE_EXPORT PartitionGeometryFilter : public IFilter * @tparam GeomType Image, rectilinear, or node geometry type. * @param geometryToPartition Geometry that supplies the cell or vertex count. * @param attrMatrix Selected matrix whose tuple count must match the geometry data count. - * @param geometryToPartitionPath Actual selected geometry path for grid diagnostics, including linked selections. - * @param attrMatrixPath Actual selected matrix path for grid diagnostics, including linked selections. + * @param geometryToPartitionPath Actual selected geometry path for geometry diagnostics, including linked selections. + * @param attrMatrixPath Actual selected matrix path for geometry diagnostics, including linked selections. * @return Count-mismatch error, or a valid empty result when counts match. * * Grid validation compares counts only; tuple shapes and ownership need not match. diff --git a/src/Plugins/SimplnxCore/test/PartitionGeometryTest.cpp b/src/Plugins/SimplnxCore/test/PartitionGeometryTest.cpp index d57f2a165e..8c4ea2adc6 100644 --- a/src/Plugins/SimplnxCore/test/PartitionGeometryTest.cpp +++ b/src/Plugins/SimplnxCore/test/PartitionGeometryTest.cpp @@ -4,9 +4,11 @@ */ #include +#include #include #include +#include #include #include #include @@ -16,11 +18,20 @@ #include #include +#include "simplnx/Common/Aliases.hpp" +#include "simplnx/Common/Array.hpp" +#include "simplnx/Common/Result.hpp" +#include "simplnx/Common/Types.hpp" #include "simplnx/DataStructure/AttributeMatrix.hpp" #include "simplnx/DataStructure/DataArray.hpp" #include "simplnx/DataStructure/DataGroup.hpp" +#include "simplnx/DataStructure/DataPath.hpp" +#include "simplnx/DataStructure/DataStructure.hpp" #include "simplnx/DataStructure/Geometry/ImageGeom.hpp" #include "simplnx/DataStructure/Geometry/RectGridGeom.hpp" +#include "simplnx/DataStructure/Geometry/VertexGeom.hpp" +#include "simplnx/Filter/Arguments.hpp" +#include "simplnx/Filter/IFilter.hpp" #include "simplnx/Parameters/ArrayCreationParameter.hpp" #include "simplnx/Parameters/BoolParameter.hpp" #include "simplnx/Parameters/ChoicesParameter.hpp" @@ -223,6 +234,8 @@ SharedFileSentinelType s_FileSentinel; const DataPath k_SelectedTupleGeometryPath({"Selected", "Geometries", "Geometry"}); const DataPath k_SelectedTupleMatrixPath({"Selected", "Arrays", "CellData"}); +const DataPath k_SelectedVertexTupleMatrixPath({"Selected", "Arrays", "VertexData"}); +const DataPath k_ExistingTuplePartitionGridPath({"ExistingTuplePartitionGrid"}); /** * @brief Creates an eight-cell grid and separately stored selected cell data. @@ -299,6 +312,71 @@ Arguments CreateCellTupleValidationArguments(ChoicesParameter::ValueType mode) args.insertOrAssign(PartitionGeometryFilter::k_MaxGridCoord_Key, std::vector{2.0F, 2.0F, 2.0F}); return args; } + +/** + * @brief Creates eight cube corners and separately stored selected vertex data. + * @param dataStructure Receives the geometry, linked selections, and an existing partition grid. + * @param tupleCount Number of tuples in the selected AttributeMatrix. + */ +void createVertexTupleValidationInput(DataStructure& dataStructure, usize tupleCount) +{ + auto* storedGeometryGroupPtr = DataGroup::Create(dataStructure, "StoredGeometry"); + REQUIRE(storedGeometryGroupPtr != nullptr); + auto* geometryPtr = VertexGeom::Create(dataStructure, "Geometry", storedGeometryGroupPtr->getId()); + REQUIRE(geometryPtr != nullptr); + const DataPath coordinatesPath({"StoredGeometry", "Geometry", "Coordinates"}); + auto vertexStorePtr = DataStoreUtilities::CreateDataStore(dataStructure, coordinatesPath, {8}, {3}); + REQUIRE(vertexStorePtr != nullptr); + auto* coordinatesPtr = Float32Array::Create(dataStructure, coordinatesPath.getTargetName(), vertexStorePtr, geometryPtr->getId()); + REQUIRE(coordinatesPtr != nullptr); + constexpr std::array cubeCorners = {0.0F, 0.0F, 0.0F, 1.0F, 0.0F, 0.0F, 0.0F, 1.0F, 0.0F, 1.0F, 1.0F, 0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 0.0F, 1.0F, 0.0F, 1.0F, 1.0F, 1.0F, 1.0F, 1.0F}; + const auto writeResult = vertexStorePtr->copyFromBuffer(0, nonstd::span(cubeCorners.data(), cubeCorners.size())); + SIMPLNX_RESULT_REQUIRE_VALID(writeResult); + geometryPtr->setVertices(*coordinatesPtr); + auto* geometryVertexDataPtr = AttributeMatrix::Create(dataStructure, "GeometryVertexData", {8}, geometryPtr->getId()); + REQUIRE(geometryVertexDataPtr != nullptr); + geometryPtr->setVertexAttributeMatrix(*geometryVertexDataPtr); + + auto* storedDataGroupPtr = DataGroup::Create(dataStructure, "StoredData"); + REQUIRE(storedDataGroupPtr != nullptr); + // The selected matrix can have a different tuple shape and parent than the vertex list. + const ShapeType tupleShape = tupleCount == 8 ? ShapeType{4, 2} : ShapeType{tupleCount}; + auto* selectedMatrixPtr = AttributeMatrix::Create(dataStructure, "VertexData", tupleShape, storedDataGroupPtr->getId()); + REQUIRE(selectedMatrixPtr != nullptr); + auto* selectedPtr = DataGroup::Create(dataStructure, "Selected"); + REQUIRE(selectedPtr != nullptr); + auto* selectedGeometriesPtr = DataGroup::Create(dataStructure, "Geometries", selectedPtr->getId()); + auto* selectedArraysPtr = DataGroup::Create(dataStructure, "Arrays", selectedPtr->getId()); + REQUIRE(selectedGeometriesPtr != nullptr); + REQUIRE(selectedArraysPtr != nullptr); + REQUIRE(dataStructure.setAdditionalParent(geometryPtr->getId(), selectedGeometriesPtr->getId())); + REQUIRE(dataStructure.setAdditionalParent(selectedMatrixPtr->getId(), selectedArraysPtr->getId())); + REQUIRE(dataStructure.getDataAs(k_SelectedTupleGeometryPath) == geometryPtr); + REQUIRE(dataStructure.getDataAs(k_SelectedVertexTupleMatrixPath) == selectedMatrixPtr); + REQUIRE(geometryPtr->getNumberOfVertices() == 8); + REQUIRE(selectedMatrixPtr->getNumberOfTuples() == tupleCount); + + auto* existingGridPtr = ImageGeom::Create(dataStructure, k_ExistingTuplePartitionGridPath.getTargetName()); + REQUIRE(existingGridPtr != nullptr); + existingGridPtr->setDimensions({2, 2, 2}); + existingGridPtr->setOrigin({0.0F, 0.0F, 0.0F}); + existingGridPtr->setSpacing({1.0F, 1.0F, 1.0F}); +} + +/** + * @brief Configures valid partition settings for the selected vertex fixture. + * @param mode Basic, advanced, bounding-box, or existing-grid mode index. + * @return Arguments using the linked selected geometry and vertex matrix paths. + */ +Arguments createVertexTupleValidationArguments(ChoicesParameter::ValueType mode) +{ + Arguments args = CreateCellTupleValidationArguments(mode); + args.insertOrAssign(PartitionGeometryFilter::k_InputGeometryCellAttributeMatrixPath_Key, k_SelectedVertexTupleMatrixPath); + args.insertOrAssign(PartitionGeometryFilter::k_ExistingPartitionGridPath_Key, k_ExistingTuplePartitionGridPath); + args.insertOrAssign(PartitionGeometryFilter::k_PartitionGridGeometry_Key, DataPath({"CreatedTuplePartitionGrid"})); + args.insertOrAssign(PartitionGeometryFilter::k_FeatureAttrMatrixName_Key, std::string("PartitionData")); + return args; +} } // namespace TEST_CASE("SimplnxCore::PartitionGeometryFilter: Basic RectGrid bounds", "[Plugins][PartitionGeometryFilter]") @@ -424,6 +502,67 @@ TEST_CASE("SimplnxCore::PartitionGeometryFilter: Partition counts precede image UnitTest::CheckArraysInheritTupleDims(dataStructure); } +TEST_CASE("SimplnxCore::PartitionGeometryFilter: Selected vertex tuple counts", "[Plugins][PartitionGeometryFilter]") +{ + UnitTest::LoadPlugins(); + const auto mode = GENERATE(ChoicesParameter::ValueType{0}, ChoicesParameter::ValueType{1}, ChoicesParameter::ValueType{2}, ChoicesParameter::ValueType{3}); + const usize tupleCount = GENERATE(usize{7}, usize{8}, usize{9}); + CAPTURE(mode, tupleCount); + DataStructure dataStructure; + createVertexTupleValidationInput(dataStructure, tupleCount); + const auto initialSize = dataStructure.getSize(); + const PartitionGeometryFilter filter; + IFilter::PreflightResult preflightResult; + REQUIRE_NOTHROW(preflightResult = filter.preflight(dataStructure, createVertexTupleValidationArguments(mode))); + if(tupleCount == 8) + { + SIMPLNX_RESULT_REQUIRE_VALID(preflightResult.outputActions); + } + else + { + SIMPLNX_RESULT_REQUIRE_INVALID(preflightResult.outputActions); + REQUIRE(preflightResult.outputActions.errors().size() == 1); + const auto& error = preflightResult.outputActions.errors()[0]; + CHECK(error.code == -3043); + CHECK(error.code != -3014); + CHECK(error.message.find(k_SelectedTupleGeometryPath.toString()) != std::string::npos); + CHECK(error.message.find(k_SelectedVertexTupleMatrixPath.toString()) != std::string::npos); + CHECK(error.message.find(fmt::format("has {} tuples", tupleCount)) != std::string::npos); + CHECK(error.message.find("has 8 vertices") != std::string::npos); + CHECK(error.message.find("one tuple per geometry vertex") != std::string::npos); + CHECK(error.message.find(filter.humanName() + ":") == std::string::npos); + } + CHECK(dataStructure.getSize() == initialSize); + CHECK_FALSE(dataStructure.containsData(k_SelectedVertexTupleMatrixPath.createChildPath("PartitionIds"))); + CHECK_FALSE(dataStructure.containsData(k_SelectedVertexTupleMatrixPath.getParent().createChildPath("PartitionData"))); + CHECK_FALSE(dataStructure.containsData(DataPath({"CreatedTuplePartitionGrid"}))); + UnitTest::CheckArraysInheritTupleDims(dataStructure); +} + +TEST_CASE("SimplnxCore::PartitionGeometryFilter: Vertex tuple and partition Z count errors are distinct", "[Plugins][PartitionGeometryFilter]") +{ + UnitTest::LoadPlugins(); + DataStructure vertexDataStructure; + createVertexTupleValidationInput(vertexDataStructure, 7); + const auto vertexPreflight = PartitionGeometryFilter().preflight(vertexDataStructure, createVertexTupleValidationArguments(0)); + SIMPLNX_RESULT_REQUIRE_INVALID(vertexPreflight.outputActions); + REQUIRE(vertexPreflight.outputActions.errors().size() == 1); + CHECK(vertexPreflight.outputActions.errors()[0].code == -3043); + + DataStructure imageDataStructure; + CreateCellTupleValidationInput(imageDataStructure, false, 8); + Arguments imageArgs = CreateCellTupleValidationArguments(0); + imageArgs.insertOrAssign(PartitionGeometryFilter::k_NumberOfCellsPerAxis_Key, std::vector{2, 2, 0}); + const auto imagePreflight = PartitionGeometryFilter().preflight(imageDataStructure, imageArgs); + SIMPLNX_RESULT_REQUIRE_INVALID(imagePreflight.outputActions); + REQUIRE(imagePreflight.outputActions.errors().size() == 1); + CHECK(imagePreflight.outputActions.errors()[0].code == -3014); + CHECK(imagePreflight.outputActions.errors()[0].message.find("Z dimension (0)") != std::string::npos); + CHECK(vertexPreflight.outputActions.errors()[0].code != imagePreflight.outputActions.errors()[0].code); + UnitTest::CheckArraysInheritTupleDims(vertexDataStructure); + UnitTest::CheckArraysInheritTupleDims(imageDataStructure); +} + TEST_CASE("SimplnxCore::PartitionGeometryFilter: Mode errors precede image tuple validation", "[Plugins][PartitionGeometryFilter]") { UnitTest::LoadPlugins(); From dc54103a6ca47567a9cb522026efc433c2ef6fee Mon Sep 17 00:00:00 2001 From: Jessica Marquis Date: Mon, 19 Oct 2026 15:51:38 -0400 Subject: [PATCH 28/28] REV: Guard concrete array kinds in migrated filters Reject unsupported array kinds before typed access in PartitionGeometry, RequireMinNumNeighbors, and WriteOnScaleTableFile. Keep optional inputs, supported integer types, and existing validation order unchanged. Track the temporary guards with issue #1833. Test exact diagnostics, unchanged data, inactive inputs, and error precedence. Preserve each NeighborList fixture's AttributeMatrix shape. Correct configured include, naming, and initialization findings on the migrated lines. Signed-off-by: Jessica Marquis --- .../Filters/PartitionGeometryFilter.cpp | 18 +- .../Filters/RequireMinNumNeighborsFilter.cpp | 32 ++- .../Filters/WriteOnScaleTableFileFilter.cpp | 20 +- .../test/PartitionGeometryTest.cpp | 250 ++++++++++++++---- .../test/RequireMinNumNeighborsTest.cpp | 172 +++++++++++- .../test/WriteOnScaleTableFileTest.cpp | 112 +++++++- 6 files changed, 524 insertions(+), 80 deletions(-) diff --git a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/PartitionGeometryFilter.cpp b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/PartitionGeometryFilter.cpp index 9ce8f758ed..6dc8ebd154 100644 --- a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/PartitionGeometryFilter.cpp +++ b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/PartitionGeometryFilter.cpp @@ -4,6 +4,8 @@ #include "simplnx/Common/Result.hpp" #include "simplnx/Common/Types.hpp" #include "simplnx/DataStructure/AttributeMatrix.hpp" +#include "simplnx/DataStructure/DataArray.hpp" +#include "simplnx/DataStructure/DataObject.hpp" #include "simplnx/DataStructure/DataPath.hpp" #include "simplnx/DataStructure/DataStructure.hpp" #include "simplnx/DataStructure/Geometry/INodeGeometry0D.hpp" @@ -408,7 +410,7 @@ IFilter::PreflightResult PartitionGeometryFilter::preflightImpl(const DataStruct auto cellTupleResult = ValidateCellTupleCount(geometry, pInputGeometryToPartitionValue, attrMatrix.getNumberOfTuples(), pInputGeomCellAMPathValue, -3010); if(cellTupleResult.invalid()) { - return {ConvertResultTo(std::move(cellTupleResult), {})}; + return {.outputActions = ConvertResultTo(std::move(cellTupleResult), {})}; } psInfo = GeneratePartitioningSchemeInfo(geometry, dataStructure, filterArgs); inputGeometryInformation = "Rectilinear grid geometry space unknown during preflight."; @@ -524,6 +526,20 @@ IFilter::PreflightResult PartitionGeometryFilter::preflightImpl(const DataStruct return {MakeErrorResult(-3019, fmt::format("{}: The input geometry is {}, which is not vertex-based. Vertex mask cannot be used.", humanName(), iGeom.getTypeName()))}; } + if(pUseVertexMask) + { + const auto maskPath = filterArgs.value(k_VertexMaskPath_Key); + // ArraySelectionParameter also accepts StringArray and NeighborList for Boolean selections. + // Keep the local type check until the parameter validates supported array kinds. + // TODO(#1833): Revisit this guard after the shared fix preserves generic array support. + if(dataStructure.getDataAs(maskPath) == nullptr) + { + const auto& selectedObject = dataStructure.getDataRefAs(maskPath); + return MakePreflightErrorResult(-3044, fmt::format("The selected Vertex Mask object '{}' has type '{}', but a scalar Boolean DataArray is required. Select a scalar Boolean DataArray.", + maskPath.toString(), selectedObject.getTypeName())); + } + } + return {std::move(resultOutputActions), std::move(preflightUpdatedValues)}; } diff --git a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/RequireMinNumNeighborsFilter.cpp b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/RequireMinNumNeighborsFilter.cpp index cce321a6b3..837e8fbe80 100644 --- a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/RequireMinNumNeighborsFilter.cpp +++ b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/RequireMinNumNeighborsFilter.cpp @@ -2,7 +2,9 @@ #include "SimplnxCore/Filters/Algorithms/RequireMinNumNeighbors.hpp" +#include "simplnx/Common/Result.hpp" #include "simplnx/DataStructure/DataArray.hpp" +#include "simplnx/DataStructure/DataObject.hpp" #include "simplnx/DataStructure/Geometry/ImageGeom.hpp" #include "simplnx/Filter/Actions/DeleteDataAction.hpp" #include "simplnx/Parameters/ArraySelectionParameter.hpp" @@ -15,6 +17,8 @@ #include "simplnx/Utilities/FilterUtilities.hpp" #include "simplnx/Utilities/SIMPLConversion.hpp" +#include + #include #include #include @@ -116,12 +120,21 @@ IFilter::PreflightResult RequireMinNumNeighborsFilter::preflightImpl(const DataS std::vector dataArrayPaths; - auto& featureIds = dataStructure.getDataRefAs(featureIdsPath); + // ArraySelectionParameter also accepts StringArray and NeighborList for numeric selections. + // Keep the local type checks until the parameter validates supported array kinds. + // TODO(#1833): Revisit these guards after the shared fix preserves generic array support. + const auto* featureIdsPtr = dataStructure.getDataAs(featureIdsPath); + if(featureIdsPtr == nullptr) + { + const auto& selectedObject = dataStructure.getDataRefAs(featureIdsPath); + return MakePreflightErrorResult(-55574, fmt::format("The selected Feature Ids object '{}' has type '{}', but a scalar int32 DataArray is required. Select a scalar int32 DataArray.", + featureIdsPath.toString(), selectedObject.getTypeName())); + } auto& imageGeom = dataStructure.getDataRefAs(imageGeomPath); - auto cellTupleResult = ValidateCellTupleCount(imageGeom, imageGeomPath, featureIds.getNumberOfTuples(), featureIdsPath, k_FeatureIdsTupleCountMismatch); + auto cellTupleResult = ValidateCellTupleCount(imageGeom, imageGeomPath, featureIdsPtr->getNumberOfTuples(), featureIdsPath, k_FeatureIdsTupleCountMismatch); if(cellTupleResult.invalid()) { - return {ConvertResultTo(std::move(cellTupleResult), {})}; + return {.outputActions = ConvertResultTo(std::move(cellTupleResult), {})}; } dataArrayPaths.push_back(numNeighborsPath); @@ -137,6 +150,19 @@ IFilter::PreflightResult RequireMinNumNeighborsFilter::preflightImpl(const DataS return MakePreflightErrorResult(k_InconsistentTupleCount, fmt::format("The following DataArrays all must have equal number of tuples but this was not satisfied.\n{}", tupleValidityCheck.error())); } + if(dataStructure.getDataAs(numNeighborsPath) == nullptr) + { + const auto& selectedObject = dataStructure.getDataRefAs(numNeighborsPath); + return MakePreflightErrorResult(-55575, fmt::format("The selected Number of Neighbors object '{}' has type '{}', but a scalar int32 DataArray is required. Select a scalar int32 DataArray.", + numNeighborsPath.toString(), selectedObject.getTypeName())); + } + if(applyToSinglePhase && dataStructure.getDataAs(featurePhasesPath) == nullptr) + { + const auto& selectedObject = dataStructure.getDataRefAs(featurePhasesPath); + return MakePreflightErrorResult(-55576, fmt::format("The selected Feature Phases object '{}' has type '{}', but a scalar int32 DataArray is required. Select a scalar int32 DataArray.", + featurePhasesPath.toString(), selectedObject.getTypeName())); + } + // Report arrays that the filter modifies in place. // Cell Data arrays are modified. nx::core::AppendDataObjectModifications(dataStructure, resultOutputActions.value().modifiedActions, featureIdsPath.getParent(), {}); diff --git a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/WriteOnScaleTableFileFilter.cpp b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/WriteOnScaleTableFileFilter.cpp index deac7d30c1..fa4b4f2874 100644 --- a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/WriteOnScaleTableFileFilter.cpp +++ b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/WriteOnScaleTableFileFilter.cpp @@ -2,7 +2,10 @@ #include "SimplnxCore/Filters/Algorithms/WriteOnScaleTableFile.hpp" +#include "simplnx/Common/Result.hpp" +#include "simplnx/DataStructure/DataObject.hpp" #include "simplnx/DataStructure/Geometry/IGridGeometry.hpp" +#include "simplnx/DataStructure/IDataArray.hpp" #include "simplnx/DataStructure/StringArray.hpp" #include "simplnx/Parameters/ArraySelectionParameter.hpp" // This header declares DataContainerSelectionFilterParameterConverter. @@ -16,6 +19,8 @@ #include "simplnx/Utilities/SIMPLConversion.hpp" #include "simplnx/Utilities/StringUtilities.hpp" +#include + #include #include #include @@ -103,11 +108,20 @@ IFilter::PreflightResult WriteOnScaleTableFileFilter::preflightImpl(const DataSt const auto geometryPath = filterArgs.value(k_InputGeometryPath_Key); const auto& geometry = dataStructure.getDataRefAs(geometryPath); const auto featureIdsPath = filterArgs.value(k_FeatureIdsArrayPath_Key); - const auto& featureIds = dataStructure.getDataRefAs(featureIdsPath); - auto cellTupleResult = ValidateCellTupleCount(geometry, geometryPath, featureIds.getNumberOfTuples(), featureIdsPath, -12024); + // ArraySelectionParameter also accepts StringArray and NeighborList for numeric selections. + // Keep the local type check until the parameter validates supported array kinds. + // TODO(#1833): Revisit this guard after the shared fix preserves generic array support. + const auto* featureIdsPtr = dataStructure.getDataAs(featureIdsPath); + if(featureIdsPtr == nullptr) + { + const auto& selectedObject = dataStructure.getDataRefAs(featureIdsPath); + return MakePreflightErrorResult(-12042, fmt::format("The selected Feature Ids object '{}' has type '{}', but a scalar integer DataArray is required. Select a scalar integer DataArray.", + featureIdsPath.toString(), selectedObject.getTypeName())); + } + auto cellTupleResult = ValidateCellTupleCount(geometry, geometryPath, featureIdsPtr->getNumberOfTuples(), featureIdsPath, -12024); if(cellTupleResult.invalid()) { - return {ConvertResultTo(std::move(cellTupleResult), {})}; + return {.outputActions = ConvertResultTo(std::move(cellTupleResult), {})}; } const auto phaseNamesPath = filterArgs.value(k_PhaseNamesArrayPath_Key); diff --git a/src/Plugins/SimplnxCore/test/PartitionGeometryTest.cpp b/src/Plugins/SimplnxCore/test/PartitionGeometryTest.cpp index 8c4ea2adc6..090ab97ed2 100644 --- a/src/Plugins/SimplnxCore/test/PartitionGeometryTest.cpp +++ b/src/Plugins/SimplnxCore/test/PartitionGeometryTest.cpp @@ -27,9 +27,12 @@ #include "simplnx/DataStructure/DataGroup.hpp" #include "simplnx/DataStructure/DataPath.hpp" #include "simplnx/DataStructure/DataStructure.hpp" +#include "simplnx/DataStructure/Geometry/IGridGeometry.hpp" #include "simplnx/DataStructure/Geometry/ImageGeom.hpp" #include "simplnx/DataStructure/Geometry/RectGridGeom.hpp" #include "simplnx/DataStructure/Geometry/VertexGeom.hpp" +#include "simplnx/DataStructure/NeighborList.hpp" +#include "simplnx/DataStructure/StringArray.hpp" #include "simplnx/Filter/Arguments.hpp" #include "simplnx/Filter/IFilter.hpp" #include "simplnx/Parameters/ArrayCreationParameter.hpp" @@ -243,59 +246,59 @@ const DataPath k_ExistingTuplePartitionGridPath({"ExistingTuplePartitionGrid"}); * @param rectilinear Chooses a rectilinear grid instead of an image geometry. * @param tupleCount Number of tuples in the selected AttributeMatrix. */ -void CreateCellTupleValidationInput(DataStructure& dataStructure, bool rectilinear, usize tupleCount) +void createCellTupleValidationInput(DataStructure& dataStructure, bool rectilinear, usize tupleCount) { - auto* storedGeometryGroup = DataGroup::Create(dataStructure, "StoredGeometry"); - REQUIRE(storedGeometryGroup != nullptr); - IGridGeometry* geometry = nullptr; + auto* storedGeometryGroupPtr = DataGroup::Create(dataStructure, "StoredGeometry"); + REQUIRE(storedGeometryGroupPtr != nullptr); + IGridGeometry* geometryPtr = nullptr; if(rectilinear) { - auto* rectGrid = RectGridGeom::Create(dataStructure, "Geometry", storedGeometryGroup->getId()); - REQUIRE(rectGrid != nullptr); - rectGrid->setDimensions({2, 2, 2}); - auto* xBounds = UnitTest::CreateTestDataArray(dataStructure, "XBounds", {3}, {1}, rectGrid->getId()); - auto* yBounds = UnitTest::CreateTestDataArray(dataStructure, "YBounds", {3}, {1}, rectGrid->getId()); - auto* zBounds = UnitTest::CreateTestDataArray(dataStructure, "ZBounds", {3}, {1}, rectGrid->getId()); - REQUIRE(xBounds != nullptr); - REQUIRE(yBounds != nullptr); - REQUIRE(zBounds != nullptr); + auto* rectGridPtr = RectGridGeom::Create(dataStructure, "Geometry", storedGeometryGroupPtr->getId()); + REQUIRE(rectGridPtr != nullptr); + rectGridPtr->setDimensions({2, 2, 2}); + auto* xBoundsPtr = UnitTest::CreateTestDataArray(dataStructure, "XBounds", {3}, {1}, rectGridPtr->getId()); + auto* yBoundsPtr = UnitTest::CreateTestDataArray(dataStructure, "YBounds", {3}, {1}, rectGridPtr->getId()); + auto* zBoundsPtr = UnitTest::CreateTestDataArray(dataStructure, "ZBounds", {3}, {1}, rectGridPtr->getId()); + REQUIRE(xBoundsPtr != nullptr); + REQUIRE(yBoundsPtr != nullptr); + REQUIRE(zBoundsPtr != nullptr); for(usize index = 0; index < 3; index++) { - (*xBounds)[index] = static_cast(index); - (*yBounds)[index] = static_cast(index); - (*zBounds)[index] = static_cast(index); + (*xBoundsPtr)[index] = static_cast(index); + (*yBoundsPtr)[index] = static_cast(index); + (*zBoundsPtr)[index] = static_cast(index); } - rectGrid->setXBoundsId(xBounds->getId()); - rectGrid->setYBoundsId(yBounds->getId()); - rectGrid->setZBoundsId(zBounds->getId()); - geometry = rectGrid; + rectGridPtr->setXBoundsId(xBoundsPtr->getId()); + rectGridPtr->setYBoundsId(yBoundsPtr->getId()); + rectGridPtr->setZBoundsId(zBoundsPtr->getId()); + geometryPtr = rectGridPtr; } else { - auto* image = ImageGeom::Create(dataStructure, "Geometry", storedGeometryGroup->getId()); - REQUIRE(image != nullptr); - image->setDimensions({2, 2, 2}); - image->setSpacing({1.0F, 1.0F, 1.0F}); - image->setOrigin({0.0F, 0.0F, 0.0F}); - geometry = image; + auto* imagePtr = ImageGeom::Create(dataStructure, "Geometry", storedGeometryGroupPtr->getId()); + REQUIRE(imagePtr != nullptr); + imagePtr->setDimensions({2, 2, 2}); + imagePtr->setSpacing({1.0F, 1.0F, 1.0F}); + imagePtr->setOrigin({0.0F, 0.0F, 0.0F}); + geometryPtr = imagePtr; } - auto* geometryCellData = AttributeMatrix::Create(dataStructure, "GeometryCellData", {2, 2, 2}, geometry->getId()); - REQUIRE(geometryCellData != nullptr); - geometry->setCellData(*geometryCellData); - auto* storedDataGroup = DataGroup::Create(dataStructure, "StoredData"); - REQUIRE(storedDataGroup != nullptr); + auto* geometryCellDataPtr = AttributeMatrix::Create(dataStructure, "GeometryCellData", {2, 2, 2}, geometryPtr->getId()); + REQUIRE(geometryCellDataPtr != nullptr); + geometryPtr->setCellData(*geometryCellDataPtr); + auto* storedDataGroupPtr = DataGroup::Create(dataStructure, "StoredData"); + REQUIRE(storedDataGroupPtr != nullptr); // {4, 2} has eight tuples, with neither shape nor ownership matching the grid. const ShapeType tupleShape = tupleCount == 8 ? ShapeType{4, 2} : ShapeType{tupleCount}; - auto* selectedMatrix = AttributeMatrix::Create(dataStructure, "CellData", tupleShape, storedDataGroup->getId()); - REQUIRE(selectedMatrix != nullptr); - auto* selected = DataGroup::Create(dataStructure, "Selected"); - REQUIRE(selected != nullptr); - auto* selectedGeometries = DataGroup::Create(dataStructure, "Geometries", selected->getId()); - auto* selectedArrays = DataGroup::Create(dataStructure, "Arrays", selected->getId()); - REQUIRE(selectedGeometries != nullptr); - REQUIRE(selectedArrays != nullptr); - REQUIRE(dataStructure.setAdditionalParent(geometry->getId(), selectedGeometries->getId())); - REQUIRE(dataStructure.setAdditionalParent(selectedMatrix->getId(), selectedArrays->getId())); + auto* selectedMatrixPtr = AttributeMatrix::Create(dataStructure, "CellData", tupleShape, storedDataGroupPtr->getId()); + REQUIRE(selectedMatrixPtr != nullptr); + auto* selectedPtr = DataGroup::Create(dataStructure, "Selected"); + REQUIRE(selectedPtr != nullptr); + auto* selectedGeometriesPtr = DataGroup::Create(dataStructure, "Geometries", selectedPtr->getId()); + auto* selectedArraysPtr = DataGroup::Create(dataStructure, "Arrays", selectedPtr->getId()); + REQUIRE(selectedGeometriesPtr != nullptr); + REQUIRE(selectedArraysPtr != nullptr); + REQUIRE(dataStructure.setAdditionalParent(geometryPtr->getId(), selectedGeometriesPtr->getId())); + REQUIRE(dataStructure.setAdditionalParent(selectedMatrixPtr->getId(), selectedArraysPtr->getId())); } /** @@ -303,7 +306,7 @@ void CreateCellTupleValidationInput(DataStructure& dataStructure, bool rectiline * @param mode Basic, advanced, or bounding-box mode index. * @return Arguments using the linked selected geometry and matrix paths. */ -Arguments CreateCellTupleValidationArguments(ChoicesParameter::ValueType mode) +Arguments createCellTupleValidationArguments(ChoicesParameter::ValueType mode) { Arguments args = createBasicPartitionGeometryArguments(k_SelectedTupleGeometryPath, k_SelectedTupleMatrixPath, "PartitionIds", {2, 2, 2}, {}); args.insertOrAssign(PartitionGeometryFilter::k_PartitioningMode_Key, mode); @@ -370,7 +373,7 @@ void createVertexTupleValidationInput(DataStructure& dataStructure, usize tupleC */ Arguments createVertexTupleValidationArguments(ChoicesParameter::ValueType mode) { - Arguments args = CreateCellTupleValidationArguments(mode); + Arguments args = createCellTupleValidationArguments(mode); args.insertOrAssign(PartitionGeometryFilter::k_InputGeometryCellAttributeMatrixPath_Key, k_SelectedVertexTupleMatrixPath); args.insertOrAssign(PartitionGeometryFilter::k_ExistingPartitionGridPath_Key, k_ExistingTuplePartitionGridPath); args.insertOrAssign(PartitionGeometryFilter::k_PartitionGridGeometry_Key, DataPath({"CreatedTuplePartitionGrid"})); @@ -458,9 +461,9 @@ TEST_CASE("SimplnxCore::PartitionGeometryFilter: Selected cell tuple counts", "[ const usize tupleCount = GENERATE(usize{7}, usize{8}, usize{9}); CAPTURE(rectilinear, mode, tupleCount); DataStructure dataStructure; - CreateCellTupleValidationInput(dataStructure, rectilinear, tupleCount); + createCellTupleValidationInput(dataStructure, rectilinear, tupleCount); const PartitionGeometryFilter filter; - const auto preflightResult = filter.preflight(dataStructure, CreateCellTupleValidationArguments(mode)); + const auto preflightResult = filter.preflight(dataStructure, createCellTupleValidationArguments(mode)); if(tupleCount == 8) { SIMPLNX_RESULT_REQUIRE_VALID(preflightResult.outputActions); @@ -487,8 +490,8 @@ TEST_CASE("SimplnxCore::PartitionGeometryFilter: Partition counts precede image const usize axis = GENERATE(usize{0}, usize{1}, usize{2}); CAPTURE(mode, axis); DataStructure dataStructure; - CreateCellTupleValidationInput(dataStructure, false, 7); - Arguments args = CreateCellTupleValidationArguments(mode); + createCellTupleValidationInput(dataStructure, false, 7); + Arguments args = createCellTupleValidationArguments(mode); std::vector partitionCounts = {2, 2, 2}; partitionCounts[axis] = 0; args.insertOrAssign(PartitionGeometryFilter::k_NumberOfCellsPerAxis_Key, partitionCounts); @@ -539,6 +542,151 @@ TEST_CASE("SimplnxCore::PartitionGeometryFilter: Selected vertex tuple counts", UnitTest::CheckArraysInheritTupleDims(dataStructure); } +TEST_CASE("SimplnxCore::PartitionGeometryFilter: Rejects unsupported active vertex mask kinds", "[Plugins][PartitionGeometryFilter]") +{ + UnitTest::LoadPlugins(); + const auto mode = GENERATE(ChoicesParameter::ValueType{0}, ChoicesParameter::ValueType{1}, ChoicesParameter::ValueType{2}, ChoicesParameter::ValueType{3}); + const bool useStringArray = GENERATE(false, true); + CAPTURE(mode, useStringArray); + DataStructure dataStructure; + createVertexTupleValidationInput(dataStructure, 8); + REQUIRE_NOTHROW(dataStructure.getDataRefAs(k_SelectedVertexTupleMatrixPath)); + const auto& parent = dataStructure.getDataRefAs(k_SelectedVertexTupleMatrixPath); + const DataPath maskPath = k_SelectedVertexTupleMatrixPath.createChildPath("RejectedMask"); + if(useStringArray) + { + REQUIRE(StringArray::CreateWithValues(dataStructure, maskPath.getTargetName(), parent.getShape(), std::vector(8, "true"), parent.getId()) != nullptr); + } + else + { + auto* listsPtr = NeighborList::Create(dataStructure, maskPath.getTargetName(), parent.getShape(), parent.getId()); + REQUIRE(listsPtr != nullptr); + for(usize index = 0; index < parent.getNumberOfTuples(); index++) + { + listsPtr->setList(static_cast(index), std::vector{1}); + } + REQUIRE(listsPtr->getTupleShape() == parent.getShape()); + } + auto args = createVertexTupleValidationArguments(mode); + args.insertOrAssign(PartitionGeometryFilter::k_UseVertexMask_Key, true); + args.insertOrAssign(PartitionGeometryFilter::k_VertexMaskPath_Key, maskPath); + const auto initialPaths = dataStructure.getAllDataPaths(); + const auto initialNextId = dataStructure.getNextId(); + IFilter::PreflightResult preflightResult; + REQUIRE_NOTHROW(preflightResult = PartitionGeometryFilter().preflight(dataStructure, args)); + SIMPLNX_RESULT_REQUIRE_INVALID(preflightResult.outputActions); + REQUIRE(preflightResult.outputActions.errors().size() == 1); + const auto& error = preflightResult.outputActions.errors().front(); + CHECK(error.code == -3044); + CHECK(error.message.find(maskPath.toString()) != std::string::npos); + CHECK(error.message.find(useStringArray ? "StringArray" : "NeighborList") != std::string::npos); + CHECK(error.message.find("scalar Boolean DataArray") != std::string::npos); + CHECK(error.message.find("Select a scalar Boolean DataArray") != std::string::npos); + CHECK(dataStructure.getAllDataPaths() == initialPaths); + CHECK(dataStructure.getNextId() == initialNextId); + CHECK_FALSE(dataStructure.containsData(k_SelectedVertexTupleMatrixPath.createChildPath("PartitionIds"))); + CHECK_FALSE(dataStructure.containsData(k_SelectedVertexTupleMatrixPath.getParent().createChildPath("PartitionData"))); + CHECK_FALSE(dataStructure.containsData(DataPath({"CreatedTuplePartitionGrid"}))); + if(useStringArray) + { + REQUIRE_NOTHROW(dataStructure.getDataRefAs(maskPath)); + CHECK(dataStructure.getDataRefAs(maskPath)[0] == "true"); + } + else + { + REQUIRE_NOTHROW(dataStructure.getDataRefAs>(maskPath)); + CHECK(dataStructure.getDataRefAs>(maskPath).getList(0) == std::vector{1}); + } + UnitTest::CheckArraysInheritTupleDims(dataStructure); +} + +TEST_CASE("SimplnxCore::PartitionGeometryFilter: Inactive mask selections and active Boolean arrays pass preflight", "[Plugins][PartitionGeometryFilter]") +{ + UnitTest::LoadPlugins(); + const usize maskKind = GENERATE(usize{0}, usize{1}, usize{2}, usize{3}, usize{4}); + CAPTURE(maskKind); + DataStructure dataStructure; + createVertexTupleValidationInput(dataStructure, 8); + const DataPath maskPath({"OptionalMask"}); + if(maskKind == 0) + { + REQUIRE(StringArray::CreateWithValues(dataStructure, maskPath.getTargetName(), {1}, {"unused"}) != nullptr); + } + else if(maskKind == 1) + { + REQUIRE(NeighborList::Create(dataStructure, maskPath.getTargetName(), {1}) != nullptr); + } + else if(maskKind >= 3) + { + auto maskStorePtr = DataStoreUtilities::CreateDataStore(dataStructure, maskPath, {8}, {1}); + auto* maskPtr = BoolArray::Create(dataStructure, maskPath.getTargetName(), maskStorePtr); + REQUIRE(maskPtr != nullptr); + maskPtr->fill(true); + } + auto args = createVertexTupleValidationArguments(0); + args.insertOrAssign(PartitionGeometryFilter::k_UseVertexMask_Key, maskKind == 4); + args.insertOrAssign(PartitionGeometryFilter::k_VertexMaskPath_Key, maskPath); + const auto initialPaths = dataStructure.getAllDataPaths(); + IFilter::PreflightResult preflightResult; + REQUIRE_NOTHROW(preflightResult = PartitionGeometryFilter().preflight(dataStructure, args)); + SIMPLNX_RESULT_REQUIRE_VALID(preflightResult.outputActions); + CHECK(dataStructure.getAllDataPaths() == initialPaths); + CHECK_FALSE(dataStructure.containsData(k_SelectedVertexTupleMatrixPath.createChildPath("PartitionIds"))); + CHECK_FALSE(dataStructure.containsData(DataPath({"CreatedTuplePartitionGrid"}))); + UnitTest::CheckArraysInheritTupleDims(dataStructure); +} + +TEST_CASE("SimplnxCore::PartitionGeometryFilter: Geometry errors precede vertex mask kind errors", "[Plugins][PartitionGeometryFilter]") +{ + UnitTest::LoadPlugins(); + const usize geometryKind = GENERATE(usize{0}, usize{1}, usize{2}); + const bool tupleMismatch = GENERATE(false, true); + const bool useStringArray = GENERATE(false, true); + CAPTURE(geometryKind, tupleMismatch, useStringArray); + DataStructure dataStructure; + const usize tupleCount = tupleMismatch ? 7 : 8; + Arguments args; + if(geometryKind == 0) + { + createVertexTupleValidationInput(dataStructure, tupleCount); + args = createVertexTupleValidationArguments(0); + } + else + { + createCellTupleValidationInput(dataStructure, geometryKind == 2, tupleCount); + args = createCellTupleValidationArguments(0); + } + const DataPath maskPath({"RejectedMask"}); + if(useStringArray) + { + REQUIRE(StringArray::CreateWithValues(dataStructure, maskPath.getTargetName(), {8}, std::vector(8, "true")) != nullptr); + } + else + { + REQUIRE(NeighborList::Create(dataStructure, maskPath.getTargetName(), {8}) != nullptr); + } + args.insertOrAssign(PartitionGeometryFilter::k_UseVertexMask_Key, true); + args.insertOrAssign(PartitionGeometryFilter::k_VertexMaskPath_Key, maskPath); + const auto initialPaths = dataStructure.getAllDataPaths(); + IFilter::PreflightResult preflightResult; + REQUIRE_NOTHROW(preflightResult = PartitionGeometryFilter().preflight(dataStructure, args)); + SIMPLNX_RESULT_REQUIRE_INVALID(preflightResult.outputActions); + REQUIRE(preflightResult.outputActions.errors().size() == 1); + constexpr std::array tupleErrorCodes = {-3043, -3009, -3010}; + int32 expectedCode = -3019; + if(tupleMismatch) + { + expectedCode = tupleErrorCodes.at(geometryKind); + } + else if(geometryKind == 0) + { + expectedCode = -3044; + } + CHECK(preflightResult.outputActions.errors().front().code == expectedCode); + CHECK(dataStructure.getAllDataPaths() == initialPaths); + UnitTest::CheckArraysInheritTupleDims(dataStructure); +} + TEST_CASE("SimplnxCore::PartitionGeometryFilter: Vertex tuple and partition Z count errors are distinct", "[Plugins][PartitionGeometryFilter]") { UnitTest::LoadPlugins(); @@ -550,8 +698,8 @@ TEST_CASE("SimplnxCore::PartitionGeometryFilter: Vertex tuple and partition Z co CHECK(vertexPreflight.outputActions.errors()[0].code == -3043); DataStructure imageDataStructure; - CreateCellTupleValidationInput(imageDataStructure, false, 8); - Arguments imageArgs = CreateCellTupleValidationArguments(0); + createCellTupleValidationInput(imageDataStructure, false, 8); + Arguments imageArgs = createCellTupleValidationArguments(0); imageArgs.insertOrAssign(PartitionGeometryFilter::k_NumberOfCellsPerAxis_Key, std::vector{2, 2, 0}); const auto imagePreflight = PartitionGeometryFilter().preflight(imageDataStructure, imageArgs); SIMPLNX_RESULT_REQUIRE_INVALID(imagePreflight.outputActions); @@ -570,8 +718,8 @@ TEST_CASE("SimplnxCore::PartitionGeometryFilter: Mode errors precede image tuple const usize axis = GENERATE(usize{0}, usize{1}, usize{2}); CAPTURE(mode, axis); DataStructure dataStructure; - CreateCellTupleValidationInput(dataStructure, false, 7); - Arguments args = CreateCellTupleValidationArguments(mode); + createCellTupleValidationInput(dataStructure, false, 7); + Arguments args = createCellTupleValidationArguments(mode); std::vector invalidValues = {1.0F, 1.0F, 1.0F}; if(mode == static_cast(PartitionGeometryFilter::PartitioningMode::Advanced)) { diff --git a/src/Plugins/SimplnxCore/test/RequireMinNumNeighborsTest.cpp b/src/Plugins/SimplnxCore/test/RequireMinNumNeighborsTest.cpp index 9ac0cbf239..48e46994a4 100644 --- a/src/Plugins/SimplnxCore/test/RequireMinNumNeighborsTest.cpp +++ b/src/Plugins/SimplnxCore/test/RequireMinNumNeighborsTest.cpp @@ -3,11 +3,19 @@ #include "SimplnxCore/Filters/RequireMinNumNeighborsFilter.hpp" #include "SimplnxCore/SimplnxCore_test_dirs.hpp" +#include "simplnx/Common/StringLiteral.hpp" +#include "simplnx/Common/Types.hpp" #include "simplnx/Core/Application.hpp" #include "simplnx/DataStructure/AttributeMatrix.hpp" #include "simplnx/DataStructure/DataArray.hpp" #include "simplnx/DataStructure/DataGroup.hpp" +#include "simplnx/DataStructure/DataPath.hpp" +#include "simplnx/DataStructure/DataStructure.hpp" #include "simplnx/DataStructure/Geometry/ImageGeom.hpp" +#include "simplnx/DataStructure/NeighborList.hpp" +#include "simplnx/DataStructure/StringArray.hpp" +#include "simplnx/Filter/Arguments.hpp" +#include "simplnx/Filter/IFilter.hpp" #include "simplnx/Parameters/MultiArraySelectionParameter.hpp" #include "simplnx/Pipeline/Pipeline.hpp" #include "simplnx/Pipeline/PipelineFilter.hpp" @@ -16,6 +24,7 @@ #include "simplnx/Utilities/Parsing/HDF5/IO/FileIO.hpp" #include +#include #include #include @@ -281,6 +290,22 @@ void PopulateDataStructure(DataStructure& dataStructure) } } } // namespace DiscriminatingFixture + +/** + * @brief Selects the analytical fixture inputs for array-kind validation. + * @return Arguments with all three numeric inputs active. + */ +Arguments createArrayKindValidationArguments() +{ + Arguments args = RequireMinNumNeighborsFilter().getDefaultArguments(); + args.insertOrAssign(RequireMinNumNeighborsFilter::k_SelectedImageGeometryPath_Key, DataPath({"ImageGeometry"})); + args.insertOrAssign(RequireMinNumNeighborsFilter::k_FeatureIdsPath_Key, DataPath({"ImageGeometry", "CellData", "FeatureIds"})); + args.insertOrAssign(RequireMinNumNeighborsFilter::k_NumNeighborsPath_Key, DataPath({"ImageGeometry", "FeatureData", "NumNeighbors"})); + args.insertOrAssign(RequireMinNumNeighborsFilter::k_FeaturePhasesPath_Key, DataPath({"ImageGeometry", "FeatureData", "Phases"})); + args.insertOrAssign(RequireMinNumNeighborsFilter::k_ApplyToSinglePhase_Key, true); + args.insertOrAssign(RequireMinNumNeighborsFilter::k_PhaseNumber_Key, uint64{1}); + return args; +} } // namespace // The tests use two analytical oracles. @@ -648,21 +673,21 @@ TEST_CASE("SimplnxCore::RequireMinNumNeighborsFilter: Selected cell tuple counts CAPTURE(tupleCount); DataStructure dataStructure; - auto* selectedGroup = DataGroup::Create(dataStructure, "Selected"); - REQUIRE(selectedGroup != nullptr); - auto* imageGeom = ImageGeom::Create(dataStructure, "ImageGeometry", selectedGroup->getId()); - REQUIRE(imageGeom != nullptr); - imageGeom->setDimensions({2, 2, 1}); - auto* storageGroup = DataGroup::Create(dataStructure, "Storage"); - REQUIRE(storageGroup != nullptr); + auto* selectedGroupPtr = DataGroup::Create(dataStructure, "Selected"); + REQUIRE(selectedGroupPtr != nullptr); + auto* imageGeomPtr = ImageGeom::Create(dataStructure, "ImageGeometry", selectedGroupPtr->getId()); + REQUIRE(imageGeomPtr != nullptr); + imageGeomPtr->setDimensions({2, 2, 1}); + auto* storageGroupPtr = DataGroup::Create(dataStructure, "Storage"); + REQUIRE(storageGroupPtr != nullptr); // Equal counts are valid even when the selected array is stored separately // and its tuple shape differs from the geometry's {1, 2, 2} shape. - auto* cellAM = AttributeMatrix::Create(dataStructure, "CellData", {tupleCount}, storageGroup->getId()); - REQUIRE(cellAM != nullptr); - auto* featureAM = AttributeMatrix::Create(dataStructure, "FeatureData", {4}, imageGeom->getId()); - REQUIRE(featureAM != nullptr); - UnitTest::CreateTestDataArray(dataStructure, "FeatureIds", {tupleCount}, {1}, cellAM->getId()); - UnitTest::CreateTestDataArray(dataStructure, "NumNeighbors", {4}, {1}, featureAM->getId()); + auto* cellAMPtr = AttributeMatrix::Create(dataStructure, "CellData", {tupleCount}, storageGroupPtr->getId()); + REQUIRE(cellAMPtr != nullptr); + auto* featureAMPtr = AttributeMatrix::Create(dataStructure, "FeatureData", {4}, imageGeomPtr->getId()); + REQUIRE(featureAMPtr != nullptr); + UnitTest::CreateTestDataArray(dataStructure, "FeatureIds", {tupleCount}, {1}, cellAMPtr->getId()); + UnitTest::CreateTestDataArray(dataStructure, "NumNeighbors", {4}, {1}, featureAMPtr->getId()); const DataPath geometryPath({"Selected", "ImageGeometry"}); const DataPath featureIdsPath({"Storage", "CellData", "FeatureIds"}); @@ -696,6 +721,127 @@ TEST_CASE("SimplnxCore::RequireMinNumNeighborsFilter: Selected cell tuple counts UnitTest::CheckArraysInheritTupleDims(dataStructure); } +TEST_CASE("SimplnxCore::RequireMinNumNeighborsFilter: Rejects unsupported array kinds", "[SimplnxCore][RequireMinNumNeighborsFilter][preflight]") +{ + UnitTest::LoadPlugins(); + const usize inputIndex = GENERATE(usize{0}, usize{1}, usize{2}); + const bool useStringArray = GENERATE(false, true); + CAPTURE(inputIndex, useStringArray); + const std::array inputKeys = {RequireMinNumNeighborsFilter::k_FeatureIdsPath_Key, RequireMinNumNeighborsFilter::k_NumNeighborsPath_Key, + RequireMinNumNeighborsFilter::k_FeaturePhasesPath_Key}; + constexpr std::array expectedCodes = {-55574, -55575, -55576}; + DataStructure dataStructure; + DiscriminatingFixture::PopulateDataStructure(dataStructure); + Arguments args = createArrayKindValidationArguments(); + const auto parentPath = args.value(inputKeys.at(inputIndex)).getParent(); + REQUIRE_NOTHROW(dataStructure.getDataRefAs(parentPath)); + const auto& parent = dataStructure.getDataRefAs(parentPath); + const DataPath rejectedPath = parentPath.createChildPath("RejectedInput"); + if(useStringArray) + { + REQUIRE(StringArray::CreateWithValues(dataStructure, rejectedPath.getTargetName(), parent.getShape(), std::vector(parent.getNumberOfTuples(), "17"), parent.getId()) != nullptr); + } + else + { + auto* listsPtr = NeighborList::Create(dataStructure, rejectedPath.getTargetName(), parent.getShape(), parent.getId()); + REQUIRE(listsPtr != nullptr); + for(usize index = 0; index < parent.getNumberOfTuples(); index++) + { + listsPtr->setList(static_cast(index), std::vector{17}); + } + REQUIRE(listsPtr->getTupleShape() == parent.getShape()); + } + args.insertOrAssign(inputKeys.at(inputIndex), rejectedPath); + const auto initialPaths = dataStructure.getAllDataPaths(); + const auto initialNextId = dataStructure.getNextId(); + const RequireMinNumNeighborsFilter filter; + IFilter::PreflightResult preflightResult; + REQUIRE_NOTHROW(preflightResult = filter.preflight(dataStructure, args)); + SIMPLNX_RESULT_REQUIRE_INVALID(preflightResult.outputActions); + REQUIRE(preflightResult.outputActions.errors().size() == 1); + const auto& error = preflightResult.outputActions.errors().front(); + CHECK(error.code == expectedCodes.at(inputIndex)); + CHECK(error.message.find(rejectedPath.toString()) != std::string::npos); + CHECK(error.message.find(useStringArray ? "StringArray" : "NeighborList") != std::string::npos); + CHECK(error.message.find("scalar int32 DataArray") != std::string::npos); + CHECK(error.message.find("Select a scalar int32 DataArray") != std::string::npos); + CHECK(dataStructure.getAllDataPaths() == initialPaths); + CHECK(dataStructure.getNextId() == initialNextId); + if(useStringArray) + { + REQUIRE_NOTHROW(dataStructure.getDataRefAs(rejectedPath)); + CHECK(dataStructure.getDataRefAs(rejectedPath)[0] == "17"); + } + else + { + REQUIRE_NOTHROW(dataStructure.getDataRefAs>(rejectedPath)); + CHECK(dataStructure.getDataRefAs>(rejectedPath).getList(0) == std::vector{17}); + } + REQUIRE_NOTHROW(dataStructure.getDataRefAs(DataPath({"ImageGeometry", "CellData", "CopiedScalar"}))); + CHECK(dataStructure.getDataRefAs(DataPath({"ImageGeometry", "CellData", "CopiedScalar"}))[0] == 10000); + UnitTest::CheckArraysInheritTupleDims(dataStructure); +} + +TEST_CASE("SimplnxCore::RequireMinNumNeighborsFilter: Inactive phases skip array-kind validation", "[SimplnxCore][RequireMinNumNeighborsFilter][preflight]") +{ + UnitTest::LoadPlugins(); + const usize inactiveKind = GENERATE(usize{0}, usize{1}, usize{2}); + CAPTURE(inactiveKind); + DataStructure dataStructure; + DiscriminatingFixture::PopulateDataStructure(dataStructure); + const DataPath inactivePath({"InactivePhases"}); + if(inactiveKind == 0) + { + REQUIRE(StringArray::CreateWithValues(dataStructure, inactivePath.getTargetName(), {1}, {"unused"}) != nullptr); + } + else if(inactiveKind == 1) + { + REQUIRE(NeighborList::Create(dataStructure, inactivePath.getTargetName(), {1}) != nullptr); + } + Arguments args = createArrayKindValidationArguments(); + args.insertOrAssign(RequireMinNumNeighborsFilter::k_ApplyToSinglePhase_Key, false); + args.insertOrAssign(RequireMinNumNeighborsFilter::k_FeaturePhasesPath_Key, inactivePath); + const auto initialPaths = dataStructure.getAllDataPaths(); + IFilter::PreflightResult preflightResult; + REQUIRE_NOTHROW(preflightResult = RequireMinNumNeighborsFilter().preflight(dataStructure, args)); + SIMPLNX_RESULT_REQUIRE_VALID(preflightResult.outputActions); + CHECK(dataStructure.getAllDataPaths() == initialPaths); + UnitTest::CheckArraysInheritTupleDims(dataStructure); +} + +TEST_CASE("SimplnxCore::RequireMinNumNeighborsFilter: Tuple errors precede feature array-kind errors", "[SimplnxCore][RequireMinNumNeighborsFilter][preflight]") +{ + UnitTest::LoadPlugins(); + const bool replaceNeighbors = GENERATE(false, true); + const bool useStringArray = GENERATE(false, true); + const bool cellMismatch = GENERATE(false, true); + CAPTURE(replaceNeighbors, useStringArray, cellMismatch); + DataStructure dataStructure; + DiscriminatingFixture::PopulateDataStructure(dataStructure); + const DataPath rejectedPath({"RejectedFeatureInput"}); + if(useStringArray) + { + REQUIRE(StringArray::CreateWithValues(dataStructure, rejectedPath.getTargetName(), {5}, std::vector(5, "17")) != nullptr); + } + else + { + REQUIRE(NeighborList::Create(dataStructure, rejectedPath.getTargetName(), {5}) != nullptr); + } + if(cellMismatch) + { + REQUIRE_NOTHROW(dataStructure.getDataRefAs(DataPath({"ImageGeometry"}))); + dataStructure.getDataRefAs(DataPath({"ImageGeometry"})).setDimensions({7, 6, 6}); + } + Arguments args = createArrayKindValidationArguments(); + args.insertOrAssign(replaceNeighbors ? RequireMinNumNeighborsFilter::k_NumNeighborsPath_Key : RequireMinNumNeighborsFilter::k_FeaturePhasesPath_Key, rejectedPath); + IFilter::PreflightResult preflightResult; + REQUIRE_NOTHROW(preflightResult = RequireMinNumNeighborsFilter().preflight(dataStructure, args)); + SIMPLNX_RESULT_REQUIRE_INVALID(preflightResult.outputActions); + REQUIRE(preflightResult.outputActions.errors().size() == 1); + CHECK(preflightResult.outputActions.errors().front().code == (cellMismatch ? -55571 : -252)); + UnitTest::CheckArraysInheritTupleDims(dataStructure); +} + TEST_CASE("SimplnxCore::RequireMinNumNeighborsFilter: Execute Error - feature ID out of range (-55567)", "[SimplnxCore][RequireMinNumNeighborsFilter][execute]") { UnitTest::LoadPlugins(); diff --git a/src/Plugins/SimplnxCore/test/WriteOnScaleTableFileTest.cpp b/src/Plugins/SimplnxCore/test/WriteOnScaleTableFileTest.cpp index dd4c27c444..f599aaed93 100644 --- a/src/Plugins/SimplnxCore/test/WriteOnScaleTableFileTest.cpp +++ b/src/Plugins/SimplnxCore/test/WriteOnScaleTableFileTest.cpp @@ -3,13 +3,20 @@ #include "SimplnxCore/Filters/WriteOnScaleTableFileFilter.hpp" #include "SimplnxCore/SimplnxCore_test_dirs.hpp" +#include "simplnx/Common/Types.hpp" #include "simplnx/Core/Application.hpp" #include "simplnx/DataStructure/AttributeMatrix.hpp" #include "simplnx/DataStructure/DataArray.hpp" #include "simplnx/DataStructure/DataGroup.hpp" +#include "simplnx/DataStructure/DataPath.hpp" +#include "simplnx/DataStructure/DataStructure.hpp" +#include "simplnx/DataStructure/Geometry/IGridGeometry.hpp" #include "simplnx/DataStructure/Geometry/ImageGeom.hpp" #include "simplnx/DataStructure/Geometry/RectGridGeom.hpp" +#include "simplnx/DataStructure/NeighborList.hpp" #include "simplnx/DataStructure/StringArray.hpp" +#include "simplnx/Filter/Arguments.hpp" +#include "simplnx/Filter/IFilter.hpp" #include "simplnx/Parameters/ChoicesParameter.hpp" #include "simplnx/Parameters/DynamicTableParameter.hpp" #include "simplnx/Parameters/FileSystemPathParameter.hpp" @@ -21,6 +28,7 @@ #include "simplnx/Utilities/DataStoreUtilities.hpp" #include +#include #include @@ -617,18 +625,18 @@ TEST_CASE("SimplnxCore::WriteOnScaleTableFileFilter: Selected cell tuple counts" { dataStructure = CreateImageDataStructure({2, 2, 1}, {1, 2, 3, 1}, {"", "Phase1", "Phase2", "Phase3"}); } - auto* selectedGroup = DataGroup::Create(dataStructure, "Selected"); - REQUIRE(selectedGroup != nullptr); + auto* selectedGroupPtr = DataGroup::Create(dataStructure, "Selected"); + REQUIRE(selectedGroupPtr != nullptr); REQUIRE_NOTHROW(dataStructure.getDataRefAs(k_GeometryPath)); - REQUIRE(dataStructure.setAdditionalParent(dataStructure.getDataRefAs(k_GeometryPath).getId(), selectedGroup->getId())); + REQUIRE(dataStructure.setAdditionalParent(dataStructure.getDataRefAs(k_GeometryPath).getId(), selectedGroupPtr->getId())); const DataPath geometryPath({"Selected", "Geometry"}); - auto* storageGroup = DataGroup::Create(dataStructure, "Storage"); - REQUIRE(storageGroup != nullptr); - auto* selectedCellData = AttributeMatrix::Create(dataStructure, "Cell Data", {tupleCount}, storageGroup->getId()); - REQUIRE(selectedCellData != nullptr); + auto* storageGroupPtr = DataGroup::Create(dataStructure, "Storage"); + REQUIRE(storageGroupPtr != nullptr); + auto* selectedCellDataPtr = AttributeMatrix::Create(dataStructure, "Cell Data", {tupleCount}, storageGroupPtr->getId()); + REQUIRE(selectedCellDataPtr != nullptr); const DataPath featureIdsPath({"Storage", "Cell Data", "FeatureIds"}); - auto featureIdsStore = DataStoreUtilities::CreateDataStore(dataStructure, featureIdsPath, {tupleCount}, {1}); - REQUIRE(Int32Array::Create(dataStructure, "FeatureIds", featureIdsStore, selectedCellData->getId()) != nullptr); + auto featureIdsStorePtr = DataStoreUtilities::CreateDataStore(dataStructure, featureIdsPath, {tupleCount}, {1}); + REQUIRE(Int32Array::Create(dataStructure, "FeatureIds", featureIdsStorePtr, selectedCellDataPtr->getId()) != nullptr); const WriteOnScaleTableFileFilter filter; Arguments args = CreateArguments(fs::path(unit_test::k_BinaryTestOutputDir.view()), "Tuple_Mismatch"); @@ -655,6 +663,92 @@ TEST_CASE("SimplnxCore::WriteOnScaleTableFileFilter: Selected cell tuple counts" UnitTest::CheckArraysInheritTupleDims(dataStructure); } +TEMPLATE_TEST_CASE("SimplnxCore::WriteOnScaleTableFileFilter: All integer Feature Ids pass preflight", "[SimplnxCore][WriteOnScaleTableFileFilter]", int8, int16, int32, int64, uint8, uint16, uint32, + uint64) +{ + UnitTest::LoadPlugins(); + DataStructure dataStructure = CreateImageDataStructure({2, 2, 1}, {1, 2, 3, 1}, {"", "Phase1", "Phase2", "Phase3"}); + const auto initialPaths = dataStructure.getAllDataPaths(); + const auto args = CreateArguments(fs::path(unit_test::k_BinaryTestOutputDir.view()), "Integer_Preflight"); + IFilter::PreflightResult preflightResult; + REQUIRE_NOTHROW(preflightResult = WriteOnScaleTableFileFilter().preflight(dataStructure, args)); + SIMPLNX_RESULT_REQUIRE_VALID(preflightResult.outputActions); + CHECK(dataStructure.getAllDataPaths() == initialPaths); + REQUIRE_NOTHROW(dataStructure.getDataRefAs(k_PhaseNamesPath)); + CHECK(dataStructure.getDataRefAs(k_PhaseNamesPath)[1] == "Phase1"); + UnitTest::CheckArraysInheritTupleDims(dataStructure); +} + +TEST_CASE("SimplnxCore::WriteOnScaleTableFileFilter: Rejects unsupported array kinds after output path errors", "[SimplnxCore][WriteOnScaleTableFileFilter]") +{ + UnitTest::LoadPlugins(); + const bool useStringArray = GENERATE(false, true); + const bool outputPathIsFile = GENERATE(false, true); + const bool rectilinear = GENERATE(false, true); + CAPTURE(useStringArray, outputPathIsFile, rectilinear); + DataStructure dataStructure; + if(rectilinear) + { + const std::array, 3> bounds = {{{0.0F, 1.0F, 2.0F}, {0.0F, 1.0F, 2.0F}, {0.0F, 1.0F}}}; + dataStructure = CreateRectGridDataStructure({2, 2, 1}, bounds, {1, 2, 3, 1}, {"", "Phase1", "Phase2", "Phase3"}); + } + else + { + dataStructure = CreateImageDataStructure({2, 2, 1}, {1, 2, 3, 1}, {"", "Phase1", "Phase2", "Phase3"}); + } + const DataPath rejectedPath({"RejectedFeatureIds"}); + if(useStringArray) + { + REQUIRE(StringArray::CreateWithValues(dataStructure, rejectedPath.getTargetName(), {4}, {"1", "2", "3", "1"}) != nullptr); + } + else + { + auto* listsPtr = NeighborList::Create(dataStructure, rejectedPath.getTargetName(), {4}); + REQUIRE(listsPtr != nullptr); + listsPtr->setLists({{1}, {2}, {3}, {1}}); + } + const auto uniqueSuffix = std::chrono::high_resolution_clock::now().time_since_epoch().count(); + const fs::path outputPath = fs::path(unit_test::k_BinaryTestOutputDir.view()) / fmt::format("WriteOnScaleTableFile_ArrayKind_{}", uniqueSuffix); + REQUIRE_FALSE(fs::exists(outputPath)); + if(outputPathIsFile) + { + fs::create_directories(outputPath.parent_path()); + std::ofstream output(outputPath); + REQUIRE(output.is_open()); + output << "Existing regular file"; + } + auto args = CreateArguments(outputPath, "Rejected_Input"); + args.insertOrAssign(WriteOnScaleTableFileFilter::k_FeatureIdsArrayPath_Key, rejectedPath); + const auto initialPaths = dataStructure.getAllDataPaths(); + const auto initialNextId = dataStructure.getNextId(); + IFilter::PreflightResult preflightResult; + REQUIRE_NOTHROW(preflightResult = WriteOnScaleTableFileFilter().preflight(dataStructure, args)); + SIMPLNX_RESULT_REQUIRE_INVALID(preflightResult.outputActions); + REQUIRE(preflightResult.outputActions.errors().size() == 1); + const auto& error = preflightResult.outputActions.errors().front(); + CHECK(error.code == (outputPathIsFile ? -12023 : -12042)); + if(outputPathIsFile) + { + CHECK(ReadFile(outputPath) == "Existing regular file"); + fs::remove(outputPath); + } + else + { + CHECK(error.message.find(rejectedPath.toString()) != std::string::npos); + CHECK(error.message.find(useStringArray ? "StringArray" : "NeighborList") != std::string::npos); + CHECK(error.message.find("scalar integer DataArray") != std::string::npos); + CHECK(error.message.find("Select a scalar integer DataArray") != std::string::npos); + CHECK_FALSE(fs::exists(outputPath)); + } + CHECK(dataStructure.getAllDataPaths() == initialPaths); + CHECK(dataStructure.getNextId() == initialNextId); + REQUIRE_NOTHROW(dataStructure.getDataRefAs(k_FeatureIdsPath)); + CHECK(dataStructure.getDataRefAs(k_FeatureIdsPath)[0] == 1); + REQUIRE_NOTHROW(dataStructure.getDataRefAs(k_PhaseNamesPath)); + CHECK(dataStructure.getDataRefAs(k_PhaseNamesPath)[1] == "Phase1"); + UnitTest::CheckArraysInheritTupleDims(dataStructure); +} + TEST_CASE("SimplnxCore::WriteOnScaleTableFileFilter: Empty Phase Names Warns During Preflight", "[SimplnxCore][WriteOnScaleTableFileFilter]") { UnitTest::LoadPlugins();