Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/Plugins/SimplnxCore/docs/ReadOnScaleTableFileFilter.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ IO (Input)

## Description

This filter reads an OnScale/PZFLEX table file and creates a **Rectilinear Grid Geometry**. The suggested file extension is `.flxtbl`, but the filter accepts any file extension. OnScale table files describe grid coordinates, material names, and the material index for each grid **Cell**.
This filter reads an OnScale/PZFLEX table file and creates a **Rectilinear Grid Geometry**. The file must have the `.flxtbl` extension. OnScale table files describe grid coordinates, material names, and the material index for each grid **Cell**.

The reader processes these sections:

Expand Down
2 changes: 1 addition & 1 deletion src/Plugins/SimplnxCore/docs/RegularizeZSpacingFilter.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ The input file is a simple text file with one floating point value per line (or
9.5
12.0

The values must be monotonically non-decreasing, and the final value (the total Z extent) must be greater than zero. The `.txt` extension is a file-dialog hint only; any readable text file is accepted.
The values must be monotonically non-decreasing, and the final value (the total Z extent) must be greater than zero. The file must have a `.txt`, `.dat`, or `.csv` extension.

### Output Geometry

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,8 @@ Parameters ReadOnScaleTableFileFilter::parameters() const
Parameters params;

params.insertSeparator(Parameters::Separator{"Input Parameter(s)"});
params.insert(std::make_unique<FileSystemPathParameter>(k_InputFile_Key, "Input File", "The OnScale table file to import. Any file extension is accepted.", fs::path(""),
FileSystemPathParameter::ExtensionsType{".flxtbl"}, FileSystemPathParameter::PathType::InputFile, true));
params.insert(std::make_unique<FileSystemPathParameter>(k_InputFile_Key, "Input File", "The OnScale table file to import. The file must have the .flxtbl extension.", fs::path(""),
FileSystemPathParameter::ExtensionsType{".flxtbl"}, FileSystemPathParameter::PathType::InputFile));
params.insert(std::make_unique<VectorFloat32Parameter>(k_Origin_Key, "Fallback Origin", "The origin for each axis that is absent from the file.", VectorFloat32Parameter::ValueType{0.0F, 0.0F, 0.0F},
VectorFloat32Parameter::NamesType{"X", "Y", "Z"}));
params.insert(std::make_unique<VectorFloat32Parameter>(k_Spacing_Key, "Fallback Spacing", "The spacing for each axis that is absent from the file.",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,12 +79,11 @@ Parameters RegularizeZSpacingFilter::parameters() const
Parameters params;

params.insertSeparator(Parameters::Separator{"Input Parameter(s)"});
// acceptAllExtensions = true: ".txt" is only a file-dialog hint. The legacy filter treated its
// "*.txt" string as a GUI filter and executed on any readable file, so converted pipelines may
// reference .dat/.csv/extensionless files and must not fail extension validation here.
// These extensions are the file types the Z-positions reader accepts. Keep acceptAllExtensions off
// so DREAM3D-NX only offers this filter for those extensions on file drop.
params.insert(std::make_unique<FileSystemPathParameter>(k_InputFile_Key, "Current Z Positions File",
"Path to a whitespace-delimited text file that contains the current Z position of each slice boundary (ZPoints + 1 float values).",
fs::path(""), FileSystemPathParameter::ExtensionsType{".txt"}, FileSystemPathParameter::PathType::InputFile, true));
fs::path(""), FileSystemPathParameter::ExtensionsType{".txt", ".dat", ".csv"}, FileSystemPathParameter::PathType::InputFile));
params.insert(std::make_unique<Float32Parameter>(k_NewZRes_Key, "New Z Spacing", "The new, regular spacing to use along the Z axis. Must be greater than 0.", 1.0F));

params.insertLinkableParameter(
Expand Down
24 changes: 17 additions & 7 deletions src/Plugins/SimplnxCore/test/ReadOnScaleTableFileTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -459,12 +459,12 @@ TEST_CASE("SimplnxCore::ReadOnScaleTableFileFilter: Invalid Preflight Input", "[
TEST_CASE("SimplnxCore::ReadOnScaleTableFileFilter: Additional Valid Inputs", "[SimplnxCore][ReadOnScaleTableFileFilter]")
{
UnitTest::LoadPlugins();
const std::string testName = GENERATE("CRLF Line Endings", "Empty Names", "Nonstandard Extension");
const std::string testName = GENERATE("CRLF Line Endings", "Empty Names");
CAPTURE(testName);

FixtureOptions options;
options.BoundsCounts = {4, 3, 2};
fs::path inputFile = fs::path(unit_test::k_BinaryTestOutputDir.view()) / "ReadOnScaleTableFile" / fmt::format("{}.flxtbl", testName);
const fs::path inputFile = fs::path(unit_test::k_BinaryTestOutputDir.view()) / "ReadOnScaleTableFile" / fmt::format("{}.flxtbl", testName);
if(testName == "CRLF Line Endings")
{
options.LineEnding = "\r\n";
Expand All @@ -473,15 +473,25 @@ TEST_CASE("SimplnxCore::ReadOnScaleTableFileFilter: Additional Valid Inputs", "[
{
options.Names.clear();
}
else
{
inputFile.replace_extension(".table");
}

const GeneratedFixture fixture = WriteFixture(inputFile, options);
RequireValidImport(inputFile, fixture, {3, 2, 1});
}

TEST_CASE("SimplnxCore::ReadOnScaleTableFileFilter: Unsupported Extension", "[SimplnxCore][ReadOnScaleTableFileFilter]")
{
UnitTest::LoadPlugins();
FixtureOptions options;
options.BoundsCounts = {4, 3, 2};
const fs::path inputFile = fs::path(unit_test::k_BinaryTestOutputDir.view()) / "ReadOnScaleTableFile" / "UnsupportedExtension.table";
WriteFixture(inputFile, options);

DataStructure dataStructure;
const ReadOnScaleTableFileFilter filter;
auto preflightResult = filter.preflight(dataStructure, CreateArguments(inputFile));
SIMPLNX_RESULT_REQUIRE_INVALID(preflightResult.outputActions);
REQUIRE(preflightResult.outputActions.errors().front().code == -3003);
}

TEST_CASE("SimplnxCore::ReadOnScaleTableFileFilter: Malformed File", "[SimplnxCore][ReadOnScaleTableFileFilter]")
{
UnitTest::LoadPlugins();
Expand Down
42 changes: 42 additions & 0 deletions src/Plugins/SimplnxCore/test/RegularizeZSpacingTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,48 @@ TEST_CASE("SimplnxCore::RegularizeZSpacingFilter: Valid Execution (New Geometry)
REQUIRE_NOTHROW(dataStructure.getDataRefAs<ImageGeom>(k_InputGeometryPath));
}

TEST_CASE("SimplnxCore::RegularizeZSpacingFilter: Supported Extensions", "[SimplnxCore][RegularizeZSpacingFilter]")
{
UnitTest::LoadPlugins();
const std::string extension = GENERATE(".dat", ".csv");
CAPTURE(extension);
DataStructure dataStructure = createTestDataStructure();
const fs::path zBoundsFile = writeZBoundsFile("RegularizeZSpacing_supported" + extension, {0.0F, 1.0F, 3.0F, 6.0F, 10.0F});

RegularizeZSpacingFilter filter;
Arguments args;
args.insertOrAssign(RegularizeZSpacingFilter::k_SelectedImageGeometryPath_Key, std::make_any<DataPath>(k_InputGeometryPath));
args.insertOrAssign(RegularizeZSpacingFilter::k_InputFile_Key, std::make_any<fs::path>(zBoundsFile));
args.insertOrAssign(RegularizeZSpacingFilter::k_NewZRes_Key, std::make_any<float32>(2.0F));
args.insertOrAssign(RegularizeZSpacingFilter::k_RemoveOriginalGeometry_Key, std::make_any<bool>(false));
args.insertOrAssign(RegularizeZSpacingFilter::k_CreatedImageGeometry_Key, std::make_any<DataPath>(k_OutputGeometryPath));

auto preflightResult = filter.preflight(dataStructure, args);
SIMPLNX_RESULT_REQUIRE_VALID(preflightResult.outputActions);
auto executeResult = filter.execute(dataStructure, args);
SIMPLNX_RESULT_REQUIRE_VALID(executeResult.result);
UnitTest::CheckArraysInheritTupleDims(dataStructure);
}

TEST_CASE("SimplnxCore::RegularizeZSpacingFilter: Unsupported Extension", "[SimplnxCore][RegularizeZSpacingFilter]")
{
UnitTest::LoadPlugins();
DataStructure dataStructure = createTestDataStructure();
const fs::path zBoundsFile = writeZBoundsFile("RegularizeZSpacing_unsupported.zpos", {0.0F, 1.0F, 3.0F, 6.0F, 10.0F});

RegularizeZSpacingFilter filter;
Arguments args;
args.insertOrAssign(RegularizeZSpacingFilter::k_SelectedImageGeometryPath_Key, std::make_any<DataPath>(k_InputGeometryPath));
args.insertOrAssign(RegularizeZSpacingFilter::k_InputFile_Key, std::make_any<fs::path>(zBoundsFile));
args.insertOrAssign(RegularizeZSpacingFilter::k_NewZRes_Key, std::make_any<float32>(2.0F));
args.insertOrAssign(RegularizeZSpacingFilter::k_RemoveOriginalGeometry_Key, std::make_any<bool>(false));
args.insertOrAssign(RegularizeZSpacingFilter::k_CreatedImageGeometry_Key, std::make_any<DataPath>(k_OutputGeometryPath));

auto preflightResult = filter.preflight(dataStructure, args);
SIMPLNX_RESULT_REQUIRE_INVALID(preflightResult.outputActions);
REQUIRE(preflightResult.outputActions.errors().front().code == -3003);
}

TEST_CASE("SimplnxCore::RegularizeZSpacingFilter: Valid Execution (Spacing Exceeds Extent)", "[SimplnxCore][RegularizeZSpacingFilter]")
{
DataStructure dataStructure = createTestDataStructure();
Expand Down
2 changes: 1 addition & 1 deletion src/Plugins/SimplnxCore/vv/RegularizeZSpacingFilter.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@

1. **Data copy**: legacy per-tuple `memcpy` via a rebuilt `newindicies` table → SIMPLNX bulk `AbstractDataStore::copyFrom` of one contiguous plane-slab per destination plane. Same bytes moved; more efficient and out-of-core friendly.
2. **Output mode**: legacy replaces the cell AttributeMatrix in place → SIMPLNX uses the modern new-geometry pattern (`CreateImageGeometryAction` + rename + deferred delete) with a "Perform In Place" toggle (default true). In-place mode is behaviorally equivalent to legacy.
3. **Preflight validation added**: positive `new_z_spacing`; input file has ≥ `ZPoints + 1` parseable values; values monotonically non-decreasing; positive total Z extent; only DataArray members in the cell AM. These reject bad input that legacy silently consumed (short files reused the last-read value; non-monotonic files produced a garbage mapping; zero extent produced a clamped 1-plane output) but do not alter valid-input output. The `.txt` extension is a dialog hint only (`acceptAllExtensions`), so converted legacy pipelines referencing `.dat`/`.csv`/extensionless files still validate.
3. **Preflight validation added**: positive `new_z_spacing`; input file has ≥ `ZPoints + 1` parseable values; values monotonically non-decreasing; positive total Z extent; only DataArray members in the cell AM. These reject bad input that legacy silently consumed (short files reused the last-read value; non-monotonic files produced a garbage mapping; zero extent produced a clamped 1-plane output) but do not alter valid-input output. The input file must have a `.txt`, `.dat`, or `.csv` extension. Converted legacy pipelines that reference other extensions now fail preflight with error `-3003`; files without an extension fail with error `-3002`. Rename these files and update the paths in the pipelines.
4. **Parallelization**: per-array parallel task runner (one task per cell array, distinct stores) vs legacy serial loop. No output effect.
5. **Cell-AM binding**: legacy took an explicit AttributeMatrix path; SIMPLNX takes the geometry and uses its assigned cell AttributeMatrix. `FromSIMPLJson` keeps only the DataContainer name from the legacy `CellAttributeMatrixPath` (the AM name is discarded). For the overwhelmingly common single-cell-AM case this is identity; corner-case consequences for converted pipelines are documented in the deviations file's scope note. Related accept/reject divergences: a geometry with no cell AM now errors (`-5560`, impossible to express in legacy), and a stale AM name that legacy rejected converts to the geometry's actual cell AM and proceeds.

Expand Down
Loading