diff --git a/CLAUDE.md b/CLAUDE.md deleted file mode 100644 index 5f1d38f26b..0000000000 --- a/CLAUDE.md +++ /dev/null @@ -1,308 +0,0 @@ -# Project Guidelines for Claude - -## Project Overview - -[SIMPLNX Issue 1284](https://github.com/BlueQuartzSoftware/simplnx/issues/1284) -I would like to work on this issue more by converting Filters that have anything more than a trivial execute implementation to move that implementation to an "Algorithm" class like the bulk of the other filters. - -The Algorithm files are located in src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/not_used. - -Look at the other filters and understand how we create the Algorithm classes and follow that same style. - -Each Algorithm class that gets updated should be moved out of the "not_used" folder. - -If anything is ambiguous please ask. - -## Directory Structure -- `src/simplnx/` - Core library (Common, Core, DataStructure, Filter, Parameters, Pipeline, Plugin, Utilities) -- `src/Plugins/` - Plugin modules -- `src/nxrunner/` - CLI runner -- `test/` - Test files -- `cmake/` - CMake configuration -- Additional Plugin at "/Users/mjackson/Workspace1/DREAM3D_Plugins/SimplnxReview" -- Additional Plugin at "/Users/mjackson/Workspace1/DREAM3D_Plugins/FileStore" -- Additional Plugin at "/Users/mjackson/Workspace1/DREAM3D_Plugins/Synthetic" -- DREAM3DNX application located in "/Users/mjackson/Workspace1/DREAM3DNX" - -## Directories to Ignore -- `scripts/` - Build/utility scripts -- `conda/` - Conda packaging - -## Coding Standards - -### C++ Style (from .clang-format) -- C++20 standard -- Allman brace style (braces on new lines for classes, control statements, enums, functions, namespaces, structs, before else) -- 200 column limit -- 2-space indentation, no tabs -- Pointer alignment left (`int* ptr` not `int *ptr`) -- No space before parentheses -- Sort includes alphabetically -- No short functions on single line -- Always break template declarations -- Constructor initializers break before comma - -### Naming Conventions (from .clang-tidy) -- C++ header files: `.hpp` extension -- C++ source files: `.cpp` extension -- Namespaces: `lower_case` -- Classes: `CamelCase` -- Structs: `CamelCase` -- Class methods: `camelBack` -- Functions: `camelBack` -- Variables: `camelBack` -- Private members: `m_` prefix + `CamelCase` (e.g., `m_MemberVariable`) -- Global variables: `CamelCase` -- Global constants: `k_` prefix + `CamelCase` (e.g., `k_DefaultValue`) -- Local pointers: `camelBack` + `Ptr` suffix (e.g., `dataPtr`) -- Type aliases: `CamelCase` + `Type` suffix (e.g., `ValueType`) -- Macros: `UPPER_CASE` - -### Descriptive Variable Naming -Use suffixes to make variable types and purposes immediately clear: - -**Geometry variables use `Geom` suffix:** -- Correct: `const auto& imageGeom = dataStructure.getDataRefAs(path);` -- Incorrect: `const auto& image = dataStructure.getDataRefAs(path);` - -**DataStore references use `Ref` suffix:** -- Correct: `const auto& verticesRef = vertexGeom.getVertices()->getDataStoreRef();` -- Incorrect: `const auto& vertices = vertexGeom.getVertices()->getDataStoreRef();` - -Examples: -```cpp -// Geometry variables -auto& imageGeom = dataStructure.getDataRefAs(imagePath); -const auto& rectGridGeom = dataStructure.getDataRefAs(rectPath); -const auto& edgeGeom = dataStructure.getDataRefAs(edgePath); - -// DataStore references -const auto& xBoundsRef = rectGridGeom.getXBounds()->getDataStoreRef(); -const auto& yBoundsRef = rectGridGeom.getYBounds()->getDataStoreRef(); -const auto& verticesRef = edgeGeom.getVertices()->getDataStoreRef(); -``` - -These conventions improve code clarity and distinguish between geometry objects and their underlying data references. - -### File Organization -- When creating a C++ based simplnx filter inside a plugin, the complete filter will have a "NameFilter.hpp" and "NameFilter.cpp" file, an "Algorithm/Name.hpp" and "Algorithm/Name.cpp". -- Filter documentation files are created in Markdown and are in the "docs" subfolder inside the Plugins directory -- Unit tests should be created in the 'test' subfolder and use the 'catch2' unit testing framework. - -## Filter Implementation Guidelines - -### Parameter Validation -- Selection parameters (GeometrySelectionParameter, ArraySelectionParameter, DataGroupSelectionParameter, etc.) automatically validate that the selected object exists in the DataStructure. Do NOT add null checks for these in preflightImpl() or executeImpl(). -- Only add explicit existence checks for objects that are not validated by a selection parameter. - -### DataStructure Access -- Use `getDataRefAs()` to get a reference when you know the object exists (e.g., validated by a selection parameter). -- Use `getDataAs()` to get a pointer only when you need to check if an object exists or when the object may not be present. -- **IMPORTANT**: In unit tests, always wrap `getDataRefAs()` calls with `REQUIRE_NOTHROW()` to provide clear test failure messages if the object doesn't exist. - -Example - Correct: -```cpp -// Parameter already validated this exists, use reference -const auto& imageGeom = dataStructure.getDataRefAs(pInputImageGeometryPathValue); -SizeVec3 dims = imageGeom.getDimensions(); -``` - -Example - Incorrect: -```cpp -// Unnecessary null check - parameter already validated existence -const auto* imageGeomPtr = dataStructure.getDataAs(pInputImageGeometryPathValue); -if(imageGeomPtr == nullptr) -{ - return {MakeErrorResult(-1000, "Could not find geometry")}; -} -``` - -## Thread Safety - -### DataArray and DataStore Classes Are NOT Thread-Safe -- `DataArray`, `DataStore`, and `AbstractDataStore` classes are **NOT thread-safe** for concurrent read or write access. -- The subscript operator (`operator[]`) and other access methods may have internal state or go through virtual function calls that are not safe for concurrent access, even when accessing different indices. -- Some `DataStore` subclasses use out-of-core implementations where data may not be resident in memory. Getting raw pointers to the underlying data is dangerous and should be avoided. - -### Parallelization Guidelines -- When writing parallel algorithms using `ParallelDataAlgorithm`, be aware that passing `DataArray` or `DataStore` references to worker classes can cause random failures on different platforms. -- If parallel access to data arrays is required, consider: - 1. Disabling parallelization with `parallelAlgorithm.setParallelizationEnabled(false)` for correctness - 2. Using thread-local storage for intermediate results - 3. Structuring the algorithm to avoid concurrent access to the same DataArray -- Do NOT assume that writing to different indices of a DataArray from multiple threads is safe. - -Example - Potentially Unsafe: -```cpp -// This pattern can cause random failures even when threads write to different indices -class MyParallelWorker -{ - DataArray& m_OutputArray; // NOT thread-safe for concurrent access - void operator()(const Range& range) const - { - for(usize i = range.min(); i < range.max(); i++) - { - m_OutputArray[i] = computeValue(i); // May fail randomly - } - } -}; -``` - -## Build System -- vcpkg for dependency management -- CMake-based build system - -Example configuring the project -```bash -cd /Users/mjackson/Workspace2/simplnx && cmake --preset simplnx-Rel -``` - -- Build directory is located at "/Users/mjackson/Workspace2/DREAM3D-Build/simplnx-Rel" - -Example building the project -```bash -cd /Users/mjackson/Workspace2/DREAM3D-Build/simplnx-Rel && cmake --build . --target all -``` - -Ensuring all test data files are downloaded -```bash -cd /Users/mjackson/Workspace2/DREAM3D-Build/simplnx-Rel && cmake --build . --target Fetch_Remote_Data_Files -``` - -- Python anaconda environment 'dream3d' can be used if needed - -## Testing -- Unit tests use the Catch2 framework. -- Each `TEST_CASE` should include `UnitTest::CheckArraysInheritTupleDims(dataStructure);` near the end of the test to ensure all created data arrays have correct tuple dimensions inherited from their parent groups. -- Use the `ctest` to run unit tests - -### Running Unit Tests -- Always use `ctest` to run unit tests, NOT the test binary directly -- The `ctest` command handles test data extraction and cleanup automatically -- Use the `-R` flag to run specific tests by name pattern - -Example - Running a specific test: -```bash -cd /Users/mjackson/Workspace2/DREAM3D-Build/NX-Com-Qt69-Vtk95-Rel && ctest -R "SimplnxCore::FillBadData" --verbose -``` - -Example - Running all SimplnxCore tests: -```bash -cd /Users/mjackson/Workspace2/DREAM3D-Build/NX-Com-Qt69-Vtk95-Rel && ctest -R "SimplnxCore::" --verbose -``` - -### Printing debug statements in unit tests - -Example - Correct - -auto executeResult = filter.execute(dataStructure, args, nullptr, IFilter::MessageHandler{[](const IFilter::Message& message){ fmt::print("{}\n", message.message); }}); - -### Exemplar-Based Testing Pattern -- Many tests use "exemplar" datasets - pre-generated golden reference data stored in `.dream3d` files -- Exemplar datasets are generated by running pipeline files (`.d3dpipeline`) that configure and execute filters - -#### Workflow for Creating and Publishing Test Data: -1. **Generate test data locally**: Create pipeline file with filter configurations and `WriteDREAM3DFilter` to save results -2. **Execute pipeline**: Run the pipeline to generate exemplar `.dream3d` file and any input data files -3. **Package as tar.gz**: Compress test data (no `6_6_` prefix needed - that was only for legacy DREAM3D data) - ```bash - tar -zvcf test_name.tar.gz test_directory/ - ``` -4. **Compute SHA512 hash**: - ```bash - shasum -a 512 test_name.tar.gz - ``` -5. **Upload to GitHub**: Upload to the [DREAM3D data archive release](https://github.com/BlueQuartzSoftware/simplnx/releases/tag/Data_Archive) -6. **Update CMakeLists.txt**: Add `download_test_data()` call in `src/Plugins/[PluginName]/test/CMakeLists.txt`: - ```cmake - download_test_data(DREAM3D_DATA_DIR ${DREAM3D_DATA_DIR} - ARCHIVE_NAME test_name.tar.gz - SHA512 ) - ``` -7. **Test data auto-downloads**: When tests run, the sentinel mechanism automatically downloads and extracts the tar.gz to `unit_test::k_TestFilesDir` - -#### Test Data Archive Naming and Versioning: -- **Base naming**: Use descriptive names that match the test: `test_name.tar.gz` -- **Version suffixes**: When updating existing test data, append version numbers: `test_name_v2.tar.gz`, `test_name_v3.tar.gz` -- **When to version**: - - Original archive already exists in GitHub data archive - - Test requirements changed (new exemplars, different parameters, additional data files) - - Cannot overwrite original because other code may depend on it - - CMakeLists.txt may reference both old and new versions for different tests -- **Check before creating**: Browse the [Data_Archive release](https://github.com/BlueQuartzSoftware/simplnx/releases/tag/Data_Archive) to see if your test data name already exists -- **Legacy prefixes**: The `6_6_` and `6_5_` prefixes are for data from legacy DREAM3D/SIMPL versions - do NOT use for new DREAM3DNX test data - -#### Test Code Pattern: -```cpp -namespace -{ -const std::string k_TestDataDirName = "test_name"; -const fs::path k_TestDataDir = fs::path(unit_test::k_TestFilesDir.view()) / k_TestDataDirName; -const fs::path k_ExemplarFile = k_TestDataDir / "test_name.dream3d"; -const fs::path k_InputImageFile = k_TestDataDir / "input_file.tif"; -} -``` - -**Example**: If `import_image_stack_test.tar.gz` exists in the archive and you need to upload updated test data with new exemplars, create `import_image_stack_test_v2.tar.gz`. Update CMakeLists.txt to reference the new version, and optionally keep the old version if other tests depend on it. - -#### Comparing Test Results Against Exemplars: -- **Load exemplar DataStructure**: Use `UnitTest::LoadDataStructure(exemplarFilePath)` to load the .dream3d file -- **ALWAYS use `REQUIRE_NOTHROW()` before `getDataRefAs()`**: This applies to ALL `getDataRefAs` calls - both generated and exemplar data -- **Get generated data**: Use `getDataRefAs()` wrapped in `REQUIRE_NOTHROW()` since objects were just created by the filter -- **Get exemplar data**: Use `getDataRefAs()` wrapped in `REQUIRE_NOTHROW()` to verify the exemplar exists before accessing -- **Compare geometries**: Use `UnitTest::CompareImageGeometry(&exemplarGeom, &generatedGeom)` - takes two pointers -- **Compare arrays**: Use `UnitTest::CompareDataArrays(exemplarArray, generatedArray)` - type-specific template -- **Switch on data type** when comparing arrays to handle different types (uint8, uint16, uint32, float32, etc.) - -Example pattern: -```cpp -// Load exemplar -DataStructure exemplarDS = UnitTest::LoadDataStructure(k_ExemplarFile); - -// Get geometries - ALWAYS wrap getDataRefAs with REQUIRE_NOTHROW -REQUIRE_NOTHROW(dataStructure.getDataRefAs(generatedGeomPath)); -const auto& generatedGeom = dataStructure.getDataRefAs(generatedGeomPath); -REQUIRE_NOTHROW(exemplarDS.getDataRefAs(DataPath({exemplarGeomName}))); -const auto& exemplarGeom = exemplarDS.getDataRefAs(DataPath({exemplarGeomName})); - -// Compare geometries (dimensions, origin, spacing) - pass pointers -UnitTest::CompareImageGeometry(&exemplarGeom, &generatedGeom); - -// Get arrays - ALWAYS wrap getDataRefAs with REQUIRE_NOTHROW -REQUIRE_NOTHROW(dataStructure.getDataRefAs(generatedDataPath)); -const auto& generatedArray = dataStructure.getDataRefAs(generatedDataPath); -REQUIRE_NOTHROW(exemplarDS.getDataRefAs(exemplarDataPath)); -const auto& exemplarArray = exemplarDS.getDataRefAs(exemplarDataPath); - -// Compare arrays based on type -switch(generatedArray.getDataType()) -{ -case DataType::uint8: - UnitTest::CompareDataArrays(exemplarArray, generatedArray); - break; -case DataType::uint16: - UnitTest::CompareDataArrays(exemplarArray, generatedArray); - break; -// ... etc -} -``` - -**Important**: Use the standardized `UnitTest::` comparison methods directly in test code. - -### Test Organization -- Each test should call `UnitTest::LoadPlugins()` before executing filters -- Use `DYNAMIC_SECTION()` for parameterized tests that generate multiple test cases - -## Pipeline Files -- JSON format with `.d3dpipeline` extension -- Contains array of filter configurations with arguments -- Each filter has: - - `args`: Dictionary of parameter keys and values - - `comments`: Description of what the filter does - - `filter`: Name and UUID - - `isDisabled`: Boolean to skip filter execution -- Common pattern: Multiple filter configurations followed by WriteDREAM3DFilter to save all results to one `.dream3d` file -- Output geometry paths in pipeline must match exemplar names expected by tests - -## Additional Notes - diff --git a/docs/documentation_review_tracker.md b/docs/documentation_review_tracker.md new file mode 100644 index 0000000000..df9243fcf6 --- /dev/null +++ b/docs/documentation_review_tracker.md @@ -0,0 +1,1569 @@ +# DREAM3DNX Filter Documentation Review Tracker + +**Design Spec:** [docs/superpowers/specs/2026-04-12-documentation-review-design.md](superpowers/specs/2026-04-12-documentation-review-design.md) +**Style Guide:** [docs/style_palette_final.svg](style_palette_final.svg) +**Branch:** topic/documentation_update (will submit as single PR when complete) + +--- + +## Progress Summary + +| Batch | Category | Total Filters | Triaged | Rewritten | Status | +|-------|----------|---------------|---------|-----------|--------| +| 1 | Orientation / Crystallography Statistics | 17 | 17 | 17 | Complete | +| 2 | Alignment Filters | 5 | 5 | 5 | Complete | +| 3 | Segmentation / Feature Identification | 10 | 10 | 10 | Complete | +| 4 | Neighbor / Kernel Operations | 11 | 11 | 11 | Complete | +| 5 | Geometry Creation / Manipulation | 15 | 15 | 15 | Complete | +| 6 | Data Manipulation (Copy, Create, Delete, Rename) | 21 | 21 | 21 | Complete | +| 7 | I/O Filters (Read/Write) | 44 | 44 | 44 | Complete | +| 8 | Image Processing (ITK wrappers) | ~88 | 0 | 0 | Not Started | +| 9 | Remaining SimplnxCore filters | 73 | 73 | 73 | Complete | + +--- + +## Batch 1: Orientation / Crystallography Statistics + +**Plugin:** OrientationAnalysis +**Filters:** 17 (15 crystallography + 2 morphological) + +### Tier 1 — Critical + +| Filter | Plugin | Status | +|--------|--------|--------| +| ComputeAvgCAxes | OrientationAnalysis | Done | +| ComputeCAxisLocations | OrientationAnalysis | Done | +| ComputeGBCD | OrientationAnalysis | Done | +| ComputeSchmids | OrientationAnalysis | Done | + +- [x] **ComputeAvgCAxesFilter** (OrientationAnalysis) + - **Clarity:** Assumed deep quaternion/transform knowledge; no explanation of what C-axis is + - **Figures Needed:** Hexagonal unit cell with C-axis labeled + - **Real-World Viz:** IPF color map showing C-axis orientations + - **Concept Links:** C-axis, hexagonal materials, quaternions, reference frames + - **Changes Made:** Added "What is the C-Axis?" section with example materials, plain-language algorithm, hexagonal-only explanation. Added hexagonal unit cell figure. + +- [x] **ComputeCAxisLocationsFilter** (OrientationAnalysis) + - **Clarity:** Very sparse, just restated algorithm + - **Figures Needed:** Same hexagonal C-axis figure (shared with ComputeAvgCAxes) + - **Real-World Viz:** C-axis direction map colored by orientation + - **Concept Links:** C-axis, hexagonal materials, quaternions, reference frames + - **Changes Made:** Added "What is the C-Axis?" section, upper-hemisphere convention note, comparison with ComputeAvgCAxes to help users pick the right filter. Shared hexagonal unit cell figure. + +- [x] **ComputeGBCDFilter** (OrientationAnalysis) + - **Clarity:** 2-sentence stub; non-expert cannot understand what GBCD is + - **Figures Needed:** Conceptual diagram of 5D boundary space (deferred -- complex) + - **Real-World Viz:** GBCD pole figure output screenshot + - **Concept Links:** grain boundaries, misorientation, boundary normals, MRD units + - **Changes Made:** Added "What is the GBCD?" section explaining 5 parameters, MRD units, algorithm steps, resolution parameter. Added Rohrer citations [1][2]. Cross-reference to metric-based filter. + +- [x] **ComputeSchmidsFilter** (OrientationAnalysis) + - **Clarity:** Formula presented but no explanation of slip systems or physical meaning + - **Figures Needed:** Diagram showing tensile axis, slip plane, slip direction, and angles φ/λ + - **Real-World Viz:** Microstructure colored by Schmid factor + - **Concept Links:** slip systems, crystal plasticity, loading axis, CRSS + - **Changes Made:** Added "What is the Schmid Factor?" section with plain-language slip explanation, 0-0.5 range meaning, 4-step algorithm, CRSS limitation note. Added Schmid factor geometric diagram. + +### Tier 2 — Important + +| Filter | Plugin | Status | +|--------|--------|--------| +| ComputeAvgOrientations | OrientationAnalysis | Done | +| ComputeBoundaryStrengths | OrientationAnalysis | Done | +| ComputeFeatureNeighborCAxisMisalignments | OrientationAnalysis | Done | +| ComputeFeatureNeighborMisorientations | OrientationAnalysis | Done | +| ComputeFeatureReferenceCAxisMisorientations | OrientationAnalysis | Done | +| ComputeFeatureReferenceMisorientations | OrientationAnalysis | Done | +| ComputeSlipTransmissionMetrics | OrientationAnalysis | Done | +| ComputeTwinBoundaries | OrientationAnalysis | Done | +| ComputeShapes | OrientationAnalysis | Done | + +- [x] **ComputeAvgOrientationsFilter** (OrientationAnalysis) + - **Clarity:** Comprehensive but very math-heavy; 3 methods with dense statistical notation + - **Figures Needed:** Diagram showing orientations being averaged within a grain; vMF distribution concept + - **Real-World Viz:** IPF color map showing average orientation assignment + - **Concept Links:** quaternions, Fundamental Zone, symmetry operators, Euler angles, EM algorithm + - **Changes Made:** Added introductory paragraph explaining what average orientation means and why it matters for downstream filters. Existing method descriptions were already thorough; kept intact. + +- [x] **ComputeBoundaryStrengthsFilter** (OrientationAnalysis) + - **Clarity:** Relies on citations for metric definitions; readers need access to papers + - **Figures Needed:** Slip transmission across grain boundary concept diagram + - **Real-World Viz:** Feature boundary map colored by boundary strength metrics + - **Concept Links:** slip transmission, Luster-Morris parameter, fracture initiation, grain boundaries + - **Changes Made:** Clarified relationship to ComputeSlipTransmissionMetrics (same metrics, per-Face storage). Added cross-reference for detailed explanations. Explained M' value meaning. + +- [x] **ComputeFeatureNeighborCAxisMisalignmentsFilter** (OrientationAnalysis) + - **Clarity:** Good basic description but "misalignment" vs "misorientation" distinction unclear + - **Figures Needed:** Diagram showing C-axis misalignment angle between two grains + - **Real-World Viz:** Neighbor misalignment values on microstructure + - **Concept Links:** C-axis, misalignment angle, hexagonal crystals, neighbor relationships + - **Changes Made:** Distinguished C-axis misalignment from full misorientation. Explained flexible neighbor list concept. Cross-referenced ComputeAvgCAxes for hexagonal-only explanation. + +- [x] **ComputeFeatureNeighborMisorientationsFilter** (OrientationAnalysis) + - **Clarity:** Straightforward but minimal + - **Figures Needed:** Diagram showing misorientation angle concept between neighboring grains + - **Real-World Viz:** Microstructure with neighbor misorientations displayed + - **Concept Links:** misorientation, orientation angle, grain boundaries + - **Changes Made:** Added plain-language explanation of misorientation. Explained NaN constraint (different crystal structures not comparable). Clarified optional average output. + +- [x] **ComputeFeatureReferenceCAxisMisorientationsFilter** (OrientationAnalysis) + - **Clarity:** Clear what it does but doesn't explain why this metric matters + - **Figures Needed:** Diagram showing cell-to-average C-axis deviation concept + - **Real-World Viz:** Misalignment map within a feature showing spatial variation + - **Concept Links:** C-axis misalignment, hexagonal materials, orientation variation + - **Changes Made:** Reframed around intragranular orientation gradients. Explained what average/std dev outputs tell you (low = uniform, high = internal variation). Cross-referenced ComputeAvgCAxes. + +- [x] **ComputeFeatureReferenceMisorientationsFilter** (OrientationAnalysis) + - **Clarity:** Good. Two reference orientation options clearly explained with use cases + - **Figures Needed:** Legend for existing color scale images would help interpretation + - **Real-World Viz:** Already has 3 images showing IPF colors and two reference orientation results + - **Concept Links:** misorientation, plastic deformation, reference orientation, IPF colors + - **Changes Made:** Added purpose statement about detecting deformation. Rewrote reference orientation options with physical reasoning for when to use each. + +- [x] **ComputeSlipTransmissionMetricsFilter** (OrientationAnalysis) + - **Clarity:** Relies on citations; metrics not explained in the documentation itself + - **Figures Needed:** Slip transmission concept diagram (same as ComputeBoundaryStrengths) + - **Real-World Viz:** Feature pairs with transmission metrics visualized + - **Concept Links:** slip transmission, slip planes/directions, grain boundaries, Luster-Morris + - **Changes Made:** Added introductory explanation of slip transmission concept. Explained M' value meaning (1.0 = perfect alignment). Added cross-reference to ComputeBoundaryStrengths. + +- [x] **ComputeTwinBoundariesFilter** (OrientationAnalysis) + - **Clarity:** Good sigma-3 identification logic but "incoherence" concept needs definition + - **Figures Needed:** Sigma-3 twin relationship diagram; incoherence concept + - **Real-World Viz:** Microstructure with twin boundaries highlighted + - **Concept Links:** twin boundaries, sigma-3, misorientation axis, CSL, incoherence + - **Changes Made:** Added "What is a Twin Boundary?" section explaining Sigma-3 twins and their significance. Explained incoherence in plain terms (0 = perfect coherent twin). + +- [x] **ComputeShapesFilter** (OrientationAnalysis) + - **Clarity:** Good algorithmic steps but missing interpretation guidance + - **Figures Needed:** Best-fit ellipsoid concept; Omega3 sphericity measure + - **Real-World Viz:** Features colored by aspect ratio or Omega3 + - **Concept Links:** principal moments, ellipsoid fitting, eigenvalues, Omega3, aspect ratios + - **Changes Made:** Added "What This Filter Produces" section explaining each output. Defined Omega3 (1.0 = sphere). Cross-referenced triangle geometry version. + +### Tier 3 — Polish + +| Filter | Plugin | Status | +|--------|--------|--------| +| ComputeGBCDMetricBased | OrientationAnalysis | Done | +| ComputeGBPDMetricBased | OrientationAnalysis | Done | +| ComputeShapesTriangleGeom | OrientationAnalysis | Done | + +- [x] **ComputeGBCDMetricBasedFilter** (OrientationAnalysis) + - **Clarity:** Excellent technical documentation with clear metric-based vs bin-based distinction + - **Figures Needed:** Maybe one more diagram showing metric distances visually + - **Real-World Viz:** Already has 3 excellent figures (GBCD result, sampling points, error maps) + - **Concept Links:** GBCD, metrics, boundary space, MRD units + - **Changes Made:** Restructured dense metric explanation into numbered two-stage process. Added note about advantages over binning (avoids discretization artifacts). + +- [x] **ComputeGBPDMetricBasedFilter** (OrientationAnalysis) + - **Clarity:** Good. References GBCD Metric-Based filter effectively + - **Figures Needed:** Plane normal vs misorientation sampling differences + - **Real-World Viz:** Already has 1 good figure + - **Concept Links:** GBPD, grain boundary plane distribution, boundary normal + - **Changes Made:** Added opening explaining what GBPD is and how it differs from GBCD (2D plane normals vs full 5D). Added MRD interpretation (1.0 = random, >1.0 = preferred). + +- [x] **ComputeShapesTriangleGeomFilter** (OrientationAnalysis) + - **Clarity:** Very technical but thorough. Excellent caveats section and validation table + - **Figures Needed:** Tetrahedron construction from mesh; watertight vs non-watertight mesh + - **Real-World Viz:** Comparison of voxelized vs triangle geometry shape results + - **Concept Links:** triangle geometry, mesh watertightness, Euler characteristic, winding + - **Changes Made:** Consolidated caveats into "Differences from Image Geometry Version" section. Merged watertight warning and Euler characteristic into "Mesh Quality Requirements" section. Cross-referenced Image Geometry version for output descriptions. + +### Already Complete (Prior to Triage) + +| Filter | Plugin | Status | +|--------|--------|--------| +| ComputeKernelAvgMisorientations | OrientationAnalysis | Done | + +- [x] **ComputeKernelAvgMisorientationsFilter** (OrientationAnalysis) + - **Changes Made:** Full rewrite with kernel radius explanation, 6 figures (formula, 1D radius 1 & 2, 2D radius (1,1,0) & (1,2,0), quick reference table). Serves as template for rewrite style. + +--- + +## Batch 4: Neighbor / Kernel Operations + +**Plugin:** SimplnxCore + OrientationAnalysis +**Filters:** 11 (cell-level cleanup, morphology, neighbor-list utilities) + +### Tier 1 — Critical + +| Filter | Plugin | Status | +|--------|--------|--------| +| AddBadData | SimplnxCore | Done | + +- [x] **AddBadDataFilter** (SimplnxCore) + - **Clarity:** Single dense paragraph with one run-on sentence; the filter's purpose (introduce realism into synthetic structures) is buried. + - **Completeness:** No example imagery, no parameter guidance. Mentions "Manhattan distances" with no context. Requires the reader to know about the *Convert Attribute Data Type* filter as a prerequisite. Group is "Synthetic Building (Misc)" which is an outlier vs. the other Batch 4 cleanup filters but is correct given the filter's purpose. + - **Accessibility:** Volume-fraction semantics are easy to misread (the *0.2* applies only to the affected cells, not the whole volume — a subtle but important point). + - **Figures Needed:** Diagram showing the two noise modes (random voxels scattered through volume vs. boundary voxels along feature surfaces). Visual of how a 0.2 volume fraction translates to actual changed-cell counts. + - **Real-World Viz:** Before/after of a synthetic microstructure with random noise applied; same with boundary noise applied. + - **Concept Links:** Manhattan distance, feature boundary cells, synthetic microstructure realism + - **Changes Made:** Added "Why Use This Filter?" section motivating the experimental-realism use case (matched cleanup pipelines for apples-to-apples comparison). Added "Random vs. Boundary Noise" section explaining the two independent modes. Added "Volume Fraction Semantics" section clarifying the per-eligible-cell meaning. Added "What 'Bad' Means in Output" section. Added explicit two-step prerequisite recipe (Compute Euclidean Distance Map → Convert Data Type). Added Required Input Sources. + +### Tier 2 — Important + +| Filter | Plugin | Status | +|--------|--------|--------| +| FillBadData | SimplnxCore | Done | +| ErodeDilateBadData | SimplnxCore | Done | +| ErodeDilateMask | SimplnxCore | Done | +| ErodeDilateCoordinationNumber | SimplnxCore | Done | +| ReplaceElementAttributesWithNeighborValues | SimplnxCore | Done | +| NeighborOrientationCorrelation | OrientationAnalysis | Done | +| BadDataNeighborOrientationCheck | OrientationAnalysis | Done | + +- [x] **FillBadDataFilter** (SimplnxCore) + - **Changes Made:** Rewrote lead-in to distinguish "small noise (filled)" vs "large defects (preserved)". Restructured implementation-detail Phase 1-4 into a concise "How This Filter Works" 3-step summary. Added "Minimum Defect Size Units" section stating cells/integer voxel count with conversion formula and typical ranges (5-50 for noise, 500-5000 for preserving real pores). Promoted "Store Defects as New Phase" option to its own section. Trimmed performance discussion to a brief note. Added Required Input Sources. + +- [x] **ErodeDilateBadDataFilter** (SimplnxCore) + - **Changes Made:** Removed stray backtick. Restructured into Dilation/Erosion/When-to-Use/Iterations-and-Direction sections. Named the morphological *opening* (erode-then-dilate) and *closing* (dilate-then-erode) patterns explicitly. Stated iterations are in **cell-layers**. Documented the X/Y/Z directional toggle for anisotropic morphology. Added Required Input Sources. + +- [x] **ErodeDilateMaskFilter** (SimplnxCore) + - **Changes Made:** Defined "mask" inline as a boolean cell-level array with cross-link to Multi-Threshold Objects. Added "When to Use" with concrete examples (erode = discard unreliable boundary cells; dilate = recover over-thresholded valid cells). Stated iterations are in **cell-layers**. Documented X/Y/Z directional toggle motivation (anisotropic serial-section resolution). Added Required Input Sources. + +- [x] **ErodeDilateCoordinationNumberFilter** (SimplnxCore) + - **Changes Made:** Stated coordination-number range is **0 to 6** with worked examples (CN=0 inside, CN=6 isolated voxel, CN=4-5 thin protrusion). Cross-linked "isotropic coarsening" definition to RequireMinimumSizeFeatures. Promoted "Loop Until Gone" to its own section with single-pass-vs-full-smoothing guidance. Added "When to Use This Filter" section calling out salt-and-pepper cleanup. Added Required Input Sources. + +- [x] **ReplaceElementAttributesWithNeighborValuesFilter** (SimplnxCore) + - **Changes Made:** Added generic "How This Filter Works" section before EBSD vendor-specific examples. Promoted "Comparison Operator" to its own subsection with use-case guidance for higher-is-better (CI, IQ) vs lower-is-better (MAD, Error) scalars. Added "Loop Until Gone" subsection with caution about flood-fill behavior. Promoted the "too much replacement" warning to its own "Caution: Flood Fill Behavior" section. Reframed EBSD examples as "Example Use Cases". Added Required Input Sources. + +- [x] **NeighborOrientationCorrelationFilter** (OrientationAnalysis) + - **Changes Made:** Added lead-in distinguishing this filter from sister filter ReplaceElementAttributesWithNeighborValues. Restructured algorithm into 4 numbered steps. Promoted *Cleanup Level* to its own subsection with **1-6 range** stated explicitly and worked guidance for each value (6=conservative, 4-5=moderate, 2-3=aggressive, 1=flood-fill). Cross-linked sister filters and EBSD readers. Added Required Input Sources. + +- [x] **BadDataNeighborOrientationCheckFilter** (OrientationAnalysis) + - **Changes Made:** Verified the doc title matches humanName() ("Neighbor Orientation Comparison (Bad Data)"); kept as-is. Added lead-in distinguishing this filter (mask-only update) from NeighborOrientationCorrelation (full-attribute replacement) and recommending sequencing. Promoted *Required Number of Neighbors* to its own section with **1-6 range** stated explicitly. Added cross-references to Multi-Threshold Objects, EBSD readers, and the sister filter. Added Required Input Sources. + +### Tier 3 — Polish + +| Filter | Plugin | Status | +|--------|--------|--------| +| RequireMinNumNeighbors | SimplnxCore | Done | +| ComputeNeighborhoods | SimplnxCore | Done | +| ComputeNeighborListStatistics | SimplnxCore | Done | + +- [x] **RequireMinNumNeighborsFilter** (SimplnxCore) + - **Changes Made:** Rewrote lead with explicit motivation (isolated single-feature islands from segmentation). Cross-linked "isotropic coarsening" to the shared definition in RequireMinimumSizeFeatures. Stated threshold is in **count of contiguous neighbors**. Added inspection-recommendation (look at *Number of Neighbors* output before choosing). Added Required Input Sources. + +- [x] **ComputeNeighborhoodsFilter** (SimplnxCore) + - **Changes Made:** Added lead-in motivating the use case (clustering, second-nearest-neighbor analysis). Defined Equivalent Sphere Diameter inline with cross-link to Compute Feature Sizes. Stated *Multiplier* is **dimensionless**. Added typical-value guidance for the multiplier (1.0 immediate neighbors, 2.0-3.0 second-nearest, 5.0+ broader clustering). Added Required Input Sources. + +- [x] **ComputeNeighborListStatisticsFilter** (SimplnxCore) + - **Changes Made:** Added concrete motivating example (summarizing per-feature neighbor misorientations from ComputeFeatureNeighborMisorientations). Restructured statistics list with inline descriptions. Stated outputs inherit units from input. Added Required Input Sources listing the four common NeighborList producers across both plugins. + +--- + +## Batch 5: Geometry Creation / Manipulation + +**Plugin:** SimplnxCore +**Filters:** 15 (geometry creation, transformation, resampling, cropping/padding, mesh generation, partitioning) + +### Tier 1 — Critical + +None. No filter in this batch has a non-expert blocker. + +### Tier 2 — Important + +| Filter | Plugin | Status | +|--------|--------|--------| +| CreateGeometry | SimplnxCore | Done | +| ApplyTransformationToGeometry | SimplnxCore | Done | +| RotateSampleRefFrame | SimplnxCore | Done | +| ResampleImageGeom | SimplnxCore | Done | +| ResampleRectGridToImageGeom | SimplnxCore | Done | +| PadImageGeometry | SimplnxCore | Done | +| QuickSurfaceMesh | SimplnxCore | Done | +| InitializeImageGeomCellData | SimplnxCore | Done | + +- [x] **CreateGeometryFilter** (SimplnxCore) + - **Clarity:** Comprehensive but very long (~19KB); the 8-geometry-type taxonomy is buried in dense prose. + - **Completeness:** Excellent — covers all 8 geometry types with examples, including a complete worked example for importing from text files. Possibly too much for a single filter doc. + - **Accessibility:** Heavy DREAM3D-NX terminology assumed (Element, Attribute Matrix, shared vertex list). + - **Figures Needed:** Side-by-side infographic showing all 8 geometry types (Image, Rectilinear Grid, Vertex, Edge, Triangle, Quadrilateral, Tetrahedral, Hexahedral) with their defining elements illustrated. + - **Real-World Viz:** None additional needed; the text import workflow could use a quick diagram. + - **Units Clarity:** Spacing units ("microns per pixel" example) called out — good. + - **Concept Links:** Geometry types, Element type, shared vertex list, winding/right-hand rule, Attribute Matrix + - **Notes:** "DREAM3D Review (Geometry)" group is unusual — verify this is intended. Typo "dimenionality" appears multiple times. Each geometry-type section duplicates content from per-type filters. Consider promoting the geometry-type taxonomy into a shared concept page and trimming this doc to filter-specific guidance. + +- [x] **ApplyTransformationToGeometryFilter** (SimplnxCore) + - **Clarity:** Strong before/after image sequences explaining the successive-rotation artifact problem. Excellent caveat. + - **Completeness:** Has duplicate transformation-type listing (bullets at lines 96-103 and the same content as a table at lines 107-114). One needs to go. + - **Accessibility:** Node vs Image distinction is critical and well-explained; row-major matrix encoding explained. + - **Figures Needed:** Already has many. Could add a diagram explaining the four-element axis-angle representation. + - **Real-World Viz:** Already excellent. + - **Units Clarity:** Rotation angle units (degrees) explicit; translation in geometry's coordinate units; scale dimensionless. + - **Concept Links:** transformation matrix, axis-angle, row-major matrix order, interpolation modes + - **Notes:** Remove the duplicated transformation-type listing. Convert "[Combine Transformation Matrices](CombineTransformationMatricesFilter.md)" link to a proper MyST link (already is). Add Required Input Sources. The relative `./Filter.md` should be checked — current uses both `./` and bare forms. + +- [x] **RotateSampleRefFrameFilter** (SimplnxCore) + - **Clarity:** Verified-only-for-axis-aligned-90/180 warning is at the top — good. Distinction from ApplyTransformation (sample reference frame vs geometric rotation) is not made explicit. + - **Completeness:** Has rotation matrix equivalent shown. Note about origin shift after rotation is valuable. + - **Accessibility:** "Sample reference frame" jargon assumed; the term needs first-use definition. + - **Figures Needed:** Diagram showing sample frame rotation (the axes of the sample relabeled) vs geometric rotation (the data physically rotated). + - **Real-World Viz:** Already has EBSD rotation example. + - **Units Clarity:** Rotation angle in degrees; axis is dimensionless unit vector. + - **Concept Links:** sample reference frame, EBSD frame convention, axis-angle rotation + - **Notes:** Add explicit "When to Use vs ApplyTransformation" guidance. Make verified-axis-only banner more prominent. Cross-link to SetImageGeomOriginScaling for the origin reset workflow. Add Required Input Sources. + +- [x] **ResampleImageGeomFilter** (SimplnxCore) + - **Clarity:** Three resampling modes (Spacing, Scaling, Exact Dimensions) each with worked numerical examples. Clear. + - **Completeness:** "No interpolation, closest cell wins" behavior noted. Renumber Features + NeighborList removal warning present. + - **Accessibility:** Spacing/dimensions/scaling distinction depends on understanding Image Geometry. + - **Figures Needed:** Before/after voxel-grid diagram showing how a 2x spacing reduction halves the cell count. + - **Real-World Viz:** Cubic Small IN100 sliced at different resolutions side-by-side. + - **Units Clarity:** Spacing values are in **physical units** (same as input geometry's spacing); scaling is **percent**; exact dimensions are in **cells**. + - **Concept Links:** spacing vs scaling vs dimensions, closest-cell resampling, Feature renumbering + - **Notes:** Cross-link to ApplyTransformation is present but uses `./` path; convert to plain MyST form. Add explicit units callouts per mode. Add Required Input Sources. + +- [x] **ResampleRectGridToImageGeomFilter** (SimplnxCore) + - **Clarity:** Brief, just describes the "last one wins" rule. + - **Completeness:** Missing: when to use this, how to specify the target image geometry's spacing/dimensions, what happens when target is finer than source. + - **Accessibility:** Rectilinear Grid concept not introduced. + - **Figures Needed:** Side-by-side diagram of variable-spacing RectGrid → regular Image Geom with the "last one wins" cells highlighted. + - **Real-World Viz:** A real RectGrid resampled to a uniform Image Geom. + - **Units Clarity:** Target spacing in physical units. + - **Concept Links:** Rectilinear Grid vs Image Geometry, downsampling vs upsampling + - **Notes:** Add "When to Use" section. Explain why "last one wins" was chosen (interpolation is wrong for label data). Add Required Input Sources. + +- [x] **PadImageGeometryFilter** (SimplnxCore) + - **Clarity:** Very brief; the figures are helpful but the prose underdocuments the "default padding value" semantics. + - **Completeness:** Doesn't explain what the *Update Origin* option does or when to use it. + - **Accessibility:** "Default padding value" is undefined. + - **Figures Needed:** Already has before/after. Could add a 3-panel diagram showing Update Origin ON vs OFF. + - **Real-World Viz:** Before/after with both Update Origin settings. + - **Units Clarity:** Pad amounts are in **cells/voxels**. Default value is in whatever units the target array uses. + - **Concept Links:** padding, image extension, origin shift + - **Notes:** Expand "default padding value" to "Each padded cell is initialized to the user-specified Default Value, which is interpreted in the same units as each cell-level array being padded". Document *Update Origin* and *Update Spacing* options. Add Required Input Sources. + +- [x] **QuickSurfaceMeshFilter** (SimplnxCore) + - **Clarity:** Deprecation notice at top recommending "Surface Nets". Node Types table is excellent. Triangle-pair-per-cell-face algorithm explained. + - **Completeness:** Has good images for each Node Type. The Verify Triangle Winding reference is implicit; needs a link. + - **Accessibility:** "Stair stepped" surface mesh result not pictured directly. + - **Figures Needed:** Already has plenty. Could use a small diagram of how a single voxel face becomes 2 triangles. + - **Real-World Viz:** Already present. + - **Concept Links:** voxel-face-to-triangle conversion, Node Types, FaceLabels convention, mesh windings + - **Notes:** Improve deprecation banner — make clear when to use this vs Surface Nets. Convert "see Verify Triangle Winding documentation" to a MyST link. Add Required Input Sources (FeatureIds from a segment filter). + +- [x] **InitializeImageGeomCellDataFilter** (SimplnxCore) + - **Clarity:** Three modes (Manual, Random, Random With Range) are listed but the "subvolume" parameter is undefined. + - **Completeness:** Missing: how is the subvolume specified (min/max cell indices? physical bounds?). What data types support each random mode? What about boolean arrays? + - **Accessibility:** Reader has to guess the subvolume specification UI. + - **Figures Needed:** Diagram showing a subvolume highlighted within a larger volume; before/after. + - **Real-World Viz:** Before/after on a real cube showing the initialized subvolume. + - **Units Clarity:** Subvolume bounds in **cells/voxels** vs **physical units** — must be stated. + - **Concept Links:** subvolume, cell-level initialization, random number generation seed + - **Notes:** Document the subvolume specification mode and units. Note random-mode behavior for boolean, integer, and float types separately. Document the random seed parameter. Add Required Input Sources. + +### Tier 3 — Polish + +| Filter | Plugin | Status | +|--------|--------|--------| +| CreateImageGeometry | SimplnxCore | Done | +| CombineTransformationMatrices | SimplnxCore | Done | +| SetImageGeomOriginScaling | SimplnxCore | Done | +| CropImageGeometry | SimplnxCore | Done | +| AppendImageGeometry | SimplnxCore | Done | +| PartitionGeometry | SimplnxCore | Done | +| ComputeCoordinatesImageGeom | SimplnxCore | Done | + +- [x] **CreateImageGeometryFilter** (SimplnxCore) + - **Clarity:** Deprecation banner is right under the title but as a level-2 heading, making it look like its own section. Confusing. + - **Completeness:** Dimensions/Spacing/Origin definitions are good. + - **Accessibility:** Same dense terminology as CreateGeometry. + - **Figures Needed:** Dimensions/origin/spacing diagram (would also serve SetImageGeomOriginScaling and ResampleImageGeom). + - **Real-World Viz:** N/A — filter creates rather than transforms data. + - **Units Clarity:** Already states spacing example "microns per pixel". + - **Concept Links:** Image Geometry dimensions/origin/spacing + - **Notes:** Move deprecation notice into a clear callout. Fix "dimenionality" typo. Cross-link to CreateGeometry filter. Add Required Input Sources note (none — geometry is created from user parameters). + +- [x] **CombineTransformationMatricesFilter** (SimplnxCore) + - **Clarity:** Brief and adequate. Output format documented. + - **Completeness:** Missing motivating context for why you'd combine matrices (the answer is in ApplyTransformation — referenced indirectly there). + - **Accessibility:** Assumes user knows row-major 4x4 convention. + - **Figures Needed:** Optional — a diagram showing two 4x4 matrices multiplying into a single 4x4 result. + - **Real-World Viz:** N/A. + - **Units Clarity:** N/A (matrix is dimensionless apart from translation components). + - **Concept Links:** matrix composition, transformation order, row-major matrix order + - **Notes:** Add a short "Why Use This Filter" pointing to ApplyTransformationToGeometry's caveat about successive image-geometry transformations. Note that matrices are applied left-to-right in the order listed. Add Required Input Sources. + +- [x] **SetImageGeomOriginScalingFilter** (SimplnxCore) + - **Clarity:** Title says "Set Origin & Spacing" but body only describes the origin parameters. Spacing is implicit. + - **Completeness:** "Put Input Origin at the Center of Geometry" option mentioned but not explained in detail. + - **Accessibility:** OK for the limited content provided. + - **Figures Needed:** Diagram showing origin-at-corner vs origin-at-center. + - **Real-World Viz:** N/A. + - **Units Clarity:** Origin coordinates and spacing are in physical units. + - **Concept Links:** Image Geometry origin, spacing + - **Notes:** Document both Origin and Spacing parameter sets. Document the linkable parameters (only-change-origin, only-change-spacing options). Expand the "Put Origin at Center" explanation. Add Required Input Sources. + +- [x] **CropImageGeometryFilter** (SimplnxCore) + - **Clarity:** Three worked examples with images. Inclusive-bounds note is critical and called out. + - **Completeness:** Voxels-vs-physical-coordinates mode is implicit; the "Use Physical Bounds" parameter should be stated explicitly. + - **Accessibility:** Voxel index 0-based convention is implied via examples. + - **Figures Needed:** Already adequate. + - **Real-World Viz:** Already present. + - **Units Clarity:** Bounds are in **cells (0-based, inclusive)** OR **physical units (depending on parameter)** — explicit per-mode. + - **Concept Links:** ROI cropping, inclusive bounds, voxel indexing + - **Notes:** Add explicit "Bounds Mode" subsection naming the parameter that toggles voxels vs physical. State units per mode. Update NeighborList warning to use the standard pattern shared with RequireMinimumSizeFeatures. + +- [x] **AppendImageGeometryFilter** (SimplnxCore) + - **Clarity:** Exhaustive examples for X/Y/Z directions with figures. + - **Completeness:** "Resolution" terminology used in one place — should be "Spacing" per the modern simplnx convention. + - **Accessibility:** Good. + - **Figures Needed:** Already comprehensive. + - **Real-World Viz:** Already present. + - **Units Clarity:** Append happens in cell-count units along the chosen direction; the *Check Spacing* option checks physical-unit match. + - **Concept Links:** geometry concatenation, mirroring, spacing check + - **Notes:** Replace remaining "Resolution" with "Spacing" for consistency. Cross-link to CreateImageGeometry for the geometry-definition concepts. Add Required Input Sources. + +- [x] **PartitionGeometryFilter** (SimplnxCore) + - **Clarity:** Four modes with excellent visual examples and walk-throughs. + - **Completeness:** "Reconstruction (Reconstruction)" group/subgroup is a stutter — verify. + - **Accessibility:** Long doc but well-organized with figures. + - **Figures Needed:** Already excellent. + - **Real-World Viz:** Already present. + - **Units Clarity:** Cell Length is in physical units; Number of Cells Per Axis is in **integer cell counts**; Origin in physical units; Min/Max in physical units. + - **Concept Links:** spatial partitioning, partition grid, out-of-bounds handling, vertex mask + - **Notes:** Verify group "Reconstruction (Reconstruction)". Add a short lead-in explaining why partition (spatial analysis, sub-volume statistics, parallel processing prep). Add Required Input Sources. + +- [x] **ComputeCoordinatesImageGeomFilter** (SimplnxCore) + - **Clarity:** "Implicit vs explicit" framing is jargon; the example output is clear. + - **Completeness:** Three output modes documented with raster scheme. + - **Accessibility:** Reader benefits from concrete example, which is provided. + - **Figures Needed:** Optional — a small voxel-grid diagram with one cell highlighted showing its (i,j,k) index and (x,y,z) physical position. + - **Real-World Viz:** N/A — output is numerical. + - **Units Clarity:** Physical coordinates in geometry's physical units; indices are **integer cell indices (0-based)**. + - **Concept Links:** cell indexing scheme, physical coordinates, ijk vs xyz, raster order + - **Notes:** Rewrite "implicit/explicit" framing in plain language ("makes the per-cell coordinates available as a regular cell-level array"). Add a "When to Use" — typically for CSV/text export workflows. Add Required Input Sources (Image Geometry). + +--- + +## Batch 6: Data Manipulation + +**Plugin:** SimplnxCore +**Filters:** 21 (create / copy / delete / rename / move / combine / split / convert / initialize / calculate) + +### Tier 1 — Critical + +None. No filter in this batch is incomprehensible to a non-expert. + +### Tier 2 — Important + +| Filter | Plugin | Status | +|--------|--------|--------| +| CreateAttributeMatrix | SimplnxCore | Done | +| CreateDataGroup | SimplnxCore | Done | +| DeleteData | SimplnxCore | Done | +| RenameDataObject | SimplnxCore | Done | +| MoveData | SimplnxCore | Done | +| CopyFeatureArrayToElementArray | SimplnxCore | Done | +| CreateFeatureArrayFromElementArray | SimplnxCore | Done | +| ConditionalSetValue | SimplnxCore | Done | +| ConvertColorToGrayScale | SimplnxCore | Done | +| ReshapeDataArray | SimplnxCore | Done | + +- [ ] **CreateAttributeMatrixFilter** (SimplnxCore) + - **Clarity:** Extremely brief (only ~20 lines). Lone example does not explain what an Attribute Matrix conceptually represents. + - **Completeness:** Missing the *why* (tuple-dimensions discipline for arrays in the same matrix), the *when* (typical use cases — creating a Feature Attribute Matrix, an Ensemble Attribute Matrix), and the relationship to DataGroup. + - **Accessibility:** Assumes the user already knows what an Attribute Matrix is. + - **Figures Needed:** Optional — a hierarchy diagram showing Image Geometry → Cell Attribute Matrix → arrays would also serve CreateGeometry/CreateDataGroup. + - **Concept Links:** Attribute Matrix, tuple dimensions, DataGroup vs Attribute Matrix + - **Notes:** Add "What is an Attribute Matrix?" subsection. Cross-link to CreateDataGroup with explicit when-to-use-which guidance. Note tuple-dimension consistency requirement. + +- [ ] **CreateDataGroupFilter** (SimplnxCore) + - **Clarity:** Only 1 paragraph; says "unlike AttributeMatrix, DataGroups are capable of holding any DataObject of any size" but doesn't explain when to choose one over the other. + - **Completeness:** Missing typical use case (organizing related arrays of different sizes, creating an output structure for a future filter). + - **Concept Links:** DataGroup, AttributeMatrix + - **Notes:** Expand. Cross-reference CreateAttributeMatrix and explain the choice: DataGroup for heterogeneous content, Attribute Matrix when all child arrays must share tuple dimensions. + +- [ ] **DeleteDataFilter** (SimplnxCore) + - **Clarity:** Two use cases (memory and name collisions) clearly explained. + - **Completeness:** Missing: cascade behavior (does deleting a Geometry also delete its Attribute Matrices? Does deleting an Attribute Matrix delete its child arrays?), what happens to downstream filters that reference the deleted object. + - **Concept Links:** cascade delete, object lifetimes + - **Notes:** Document the cascade behavior. Add explicit warning: subsequent filters that selected the deleted object will fail preflight. + +- [ ] **RenameDataObjectFilter** (SimplnxCore) + - **Clarity:** Single sentence. + - **Completeness:** Missing: what happens to filter parameters downstream that reference the old name (they won't auto-update — preflight will fail). What name collisions are allowed/disallowed. + - **Notes:** Expand to one paragraph. Warn about downstream filter parameter references not updating automatically. + +- [ ] **MoveDataFilter** (SimplnxCore) + - **Clarity:** Brief but covers the tuple-count requirement. + - **Completeness:** Missing: examples (moving a computed array into a Feature Attribute Matrix; moving an array between DataGroups). What happens to arrays that are children of the moved object. + - **Concept Links:** parent-child hierarchy, tuple validation + - **Notes:** Add concrete examples. Explain that tuple-dimension *shape* doesn't need to match — only the *number of tuples*. + +- [ ] **CopyFeatureArrayToElementArrayFilter** (SimplnxCore) + - **Clarity:** "Xmdf visualization files write only the Element attributes" is jargon and almost the entire rationale. + - **Completeness:** Missing: general "when to use" (broadcasting a per-Feature scalar to every cell of that feature for visualization), parameter description. + - **Notes:** Lead with the general purpose (broadcast Feature-level value back to all cells of the Feature). Explain the Xmdf-export reason as one specific use case rather than the only one. Add Required Input Sources. + +- [ ] **CreateFeatureArrayFromElementArrayFilter** (SimplnxCore) + - **Clarity:** "the value of the *last element copied*" is buried as the central footgun. + - **Completeness:** Missing: warning that this filter is destructive when used on per-cell scalars that vary within a feature (since most cells get discarded). When to use vs. ComputeArrayStatistics (which computes per-feature means). + - **Notes:** Promote the "last element copied" caveat to a Warning section. Cross-reference ComputeArrayStatistics for averaging behavior. Add Required Input Sources. + +- [ ] **ConditionalSetValueFilter** (SimplnxCore) + - **Clarity:** Two modes (conditional mask vs value-replacement) buried in one dense sentence. + - **Completeness:** Mode parameter (*Use Conditional Mask*) is the central control but not promoted. + - **Notes:** Split the two modes into their own subsections. Document *Use Conditional Mask* explicitly. Add Required Input Sources. + +- [ ] **ConvertColorToGrayScaleFilter** (SimplnxCore) + - **Clarity:** Four conversion algorithms documented with formulas. + - **Completeness:** Missing: when to use (preprocessing color images for downstream grayscale-only filters), expected input format (uint8 RGB/RGBA), output type. + - **Notes:** Add "When to Use" lead-in. State input/output array types and component shapes. Add Required Input Sources (ITK image reader). + +- [ ] **ReshapeDataArrayFilter** (SimplnxCore) + - **Clarity:** Critical footgun warning ("DOES NOT MOVE ANY VALUES IN MEMORY") is buried at line 11. + - **Completeness:** Stride-mismatch example is good but the warning needs more prominence given that misuse silently produces wrong results. + - **Concept Links:** strides, row-major / C-order storage, tuple dimensions + - **Notes:** Promote the "no memory rearrangement" warning into a top-level Warning section. Add a "When NOT to Use" callout. Add Required Input Sources. + +### Tier 3 — Polish + +| Filter | Plugin | Status | +|--------|--------|--------| +| CreateDataArray | SimplnxCore | Done | +| CreateDataArrayAdvanced | SimplnxCore | Done | +| CopyDataObject | SimplnxCore | Done | +| CombineAttributeArrays | SimplnxCore | Done | +| ConcatenateDataArrays | SimplnxCore | Done | +| SplitDataArrayByComponent | SimplnxCore | Done | +| SplitDataArrayByTuple | SimplnxCore | Done | +| ExtractComponentAsArray | SimplnxCore | Done | +| ConvertData | SimplnxCore | Done | +| ArrayCalculator | SimplnxCore | Done | +| InitializeData | SimplnxCore | Done | + +- [ ] **CreateDataArrayFilter** (SimplnxCore) + - **Notes:** Already has good data-type ranges table and semicolon-notation example. Minor polish: state that Number of Components must be ≥ 1; explicitly note that this filter creates a *single component dimension* (use CreateDataArrayAdvanced for multi-dimension components). Add Required Input Sources (none). + +- [ ] **CreateDataArrayAdvancedFilter** (SimplnxCore) + - **Notes:** Documents 4 initialization modes (Fill, Incremental, Random, Random With Range) and Step Operation. Mostly good. Polish: state component-dimension product must be ≥ 1; clarify that multi-dimensional components (e.g., 3x3 tensor) are supported here. Cross-link CreateDataArray as the simpler version. + +- [ ] **CopyDataObjectFilter** (SimplnxCore) + - **Notes:** Clear; "deep copy" semantics for BaseGroup containers documented. Polish: cross-link Copy to New Parent option more explicitly; add Required Input Sources (none). + +- [ ] **CombineAttributeArraysFilter** (SimplnxCore) + - **Notes:** Already has worked examples and figures. Polish: cross-link "Concatenate Data Arrays" already present; mention the use case of building a Vertex coordinates array from three separate x/y/z arrays. Add Required Input Sources. + +- [ ] **ConcatenateDataArraysFilter** (SimplnxCore) + - **Notes:** Brief but clear. Cross-link to Combine Attribute Arrays is present. Polish: state that the result is always 1-D (already does); add example. + +- [ ] **SplitDataArrayByComponentFilter** (SimplnxCore) + - **Notes:** Clear worked example. Polish: minor copy-edit ("unput" → "input"); state the "specifying a subset of components" mode more cleanly; cross-link Combine Attribute Arrays as the inverse operation (already does). + +- [ ] **SplitDataArrayByTupleFilter** (SimplnxCore) + - **Notes:** Clear worked example. Polish: cross-link Split Data Array (By Component) present. Polish: state units on tuple counts (integer counts). + +- [ ] **ExtractComponentAsArrayFilter** (SimplnxCore) + - **Notes:** Title in cpp is "Extract/Remove Components" — verify match. Brief but covers the 3 operation modes. Polish: add a worked example showing the 3 modes; add Required Input Sources. + +- [ ] **ConvertDataFilter** (SimplnxCore) + - **Notes:** Already very thorough with up/down casting and signed/unsigned warnings. Polish: cross-link to Reshape Data Array for the related-but-different "interpret data differently" use case. Add Required Input Sources. + +- [ ] **ArrayCalculatorFilter** (SimplnxCore) + - **Notes:** Already extremely thorough — operator tables, multi-component handling, explicit array name escaping, multiple worked examples. Polish: minor only. Cross-link to Convert Angles to Degrees or Radians (already mentioned). Add Required Input Sources. + +- [ ] **InitializeDataFilter** (SimplnxCore) + - **Notes:** Content is good but the prose is rambly. Polish: restructure each initialization mode into its own subsection with a brief intro and bullet list of nuances rather than nested bullet trees. Move boolean entry rules to a single dedicated subsection. + +--- + +## Batches 8-9: Not Yet Triaged + +The following batches have been identified in the design spec but have not yet been triaged. Each batch will be triaged at the start of its work cycle. (Batch 7 was triaged 2026-06-10; see the Batch 7 section below.) + +## Batch 2: Alignment Filters + +**Plugin:** OrientationAnalysis + SimplnxCore +**Filters:** 5 + +### Tier 2 — Important + +| Filter | Plugin | Status | +|--------|--------|--------| +| AlignSectionsMutualInformation | OrientationAnalysis | Done | +| AlignSectionsMisorientation | OrientationAnalysis | Done | +| AlignSectionsList | SimplnxCore | Done | + +- [x] **AlignSectionsMutualInformationFilter** (OrientationAnalysis) + - **Clarity:** Functional but domain-heavy; mutual information concept not explained for non-experts + - **Figures Needed:** Diagram showing 7x7 grid search with high/low MI regions + - **Real-World Viz:** Pipeline screenshot showing input/output shift arrays + - **Concept Links:** mutual information, feature segmentation, 7x7 grid search, local minima + - **Changes Made:** Added "What is Mutual Information?" section. Added "When to Use This Method" guidance. Restructured algorithm into clear numbered steps with named subsections. Explained misorientation tolerance parameter. Cross-referenced other alignment methods. + +- [x] **AlignSectionsMisorientationFilter** (OrientationAnalysis) + - **Clarity:** Clear algorithm steps but non-experts need misorientation definition; background subtraction underdocumented + - **Figures Needed:** Diagram of 7x7 grid search with before/after alignment; background subtraction concept + - **Real-World Viz:** Example output shifts for a real dataset + - **Concept Links:** misorientation angle, cell-to-cell pairing, 7x7 grid search, local minima, background shift removal + - **Changes Made:** Added "When to Use This Method" guidance with cross-references to alternatives. Restructured algorithm with clear step descriptions. Separated local minima warning, masking, and linear background subtraction into named subsections. + +- [x] **AlignSectionsListFilter** (SimplnxCore) + - **Clarity:** Core concept clear but overwhelmed by backwards compatibility cruft and file format specs + - **Figures Needed:** Flowchart showing relative vs cumulative shift interpretation + - **Real-World Viz:** Typical usage showing output from another alignment filter feeding into this one + - **Concept Links:** relative shifts, cumulative shifts, slice ordering, CSV import + - **Changes Made:** Rewrote lead paragraph to explain the three use cases. Clarified relative vs cumulative with concise definitions. Consolidated file import instructions into a single streamlined section. Moved legacy format details into a brief "Note on Legacy Files" section. + +### Tier 3 — Polish + +| Filter | Plugin | Status | +|--------|--------|--------| +| AlignSectionsFeatureCentroid | SimplnxCore | Done | + +- [x] **AlignSectionsFeatureCentroidFilter** (SimplnxCore) + - **Clarity:** Clear and accessible; centroid-based alignment is straightforward + - **Figures Needed:** Diagram showing centroid calculation on adjacent slices before/after alignment + - **Real-World Viz:** Before/after visualization of aligned sections + - **Concept Links:** centroid, cell resolution, reference slice, background shift removal + - **Changes Made:** Restructured into clear subsections (When to Use, How It Works, Reference Slice, Linear Background Subtraction). Added comparison note about local minima advantage over other methods. + +### Tier 4 — Adequate + +| Filter | Plugin | Status | +|--------|--------|--------| +| AlignGeometries | SimplnxCore | No Changes Needed | + +- [x] **AlignGeometriesFilter** (SimplnxCore) + - **Notes:** 32 lines. Two simple alignment methods (Origin and Centroid) clearly explained. No domain jargon. Adequate as-is. + +--- + +## Batch 3: Segmentation / Feature Identification + +**Plugin:** SimplnxCore + OrientationAnalysis +**Filters:** 10 (3 core segmentation + 7 feature identification/post-processing) + +### Tier 1 — Critical + +| Filter | Plugin | Status | +|--------|--------|--------| +| MergeTwins | OrientationAnalysis | Done | + +- [x] **MergeTwinsFilter** (OrientationAnalysis) + - **Clarity:** Very sparse (~27 lines). Cubic-High restriction stated in caps but no context on why twins are merged; Sigma-3 and `<111>` axis terminology used with no definitions. + - **Completeness:** Only one paragraph of description; no output array description; no guidance on typical tolerance values; no before/after imagery. + - **Accessibility:** Assumes reader knows what a twin is, what Sigma-3 notation means, and how to interpret `<111>` direction notation. + - **Figures Needed:** Sigma-3 twin relationship diagram; visual explanation of axis tolerance vs. angle tolerance. + - **Real-World Viz:** Before/after microstructure showing twin variants merged into the parent grain. + - **Concept Links:** twin boundaries, Sigma-3, FCC, `<111>` axis, misorientation + - **Changes Made:** Added "What is a Twin?" section explaining Sigma-3, FCC annealing twins, and CSL notation. Added "Why Merge Twins?" section giving the downstream-analysis motivation (grain counting, size distributions, neighbor stats). Restructured algorithm into numbered steps on the Feature level. Added "Parameter Guidance" with explicit degree units and typical tolerance ranges. Added "Required Input Sources" section listing each upstream filter that must run first. Added "Limitations" clarifying Cubic-High/m3m restriction, FCC-only practical applicability, and Sigma-3-only detection. + +### Tier 2 — Important + +| Filter | Plugin | Status | +|--------|--------|--------| +| ScalarSegmentFeatures | SimplnxCore | Done | +| CAxisSegmentFeatures | OrientationAnalysis | Done | +| EBSDSegmentFeatures | OrientationAnalysis | Done | +| RequireMinimumSizeFeatures | SimplnxCore | Done | +| ComputeFeatureNeighbors | SimplnxCore | Done | + +- [x] **ScalarSegmentFeaturesFilter** (SimplnxCore) + - **Clarity:** Burn algorithm steps clear, but term "burn algorithm" undefined; no introduction to what segmentation accomplishes conceptually. + - **Completeness:** Neighbor scheme well documented with 4 paired figure sets. No guidance on tolerance values (tolerance is in whatever units the scalar array uses). + - **Accessibility:** "Cells" and "Features" used without first-use definition; bold emphasis is stylistic rather than explanatory. + - **Figures Needed:** Neighbor-scheme figures already excellent; could add a simple "what is segmentation" before/after conceptual diagram. + - **Real-World Viz:** Before/after FeatureIds map from a scalar-based segmentation (e.g., image-quality thresholding). + - **Units Clarity:** Tolerance has no explicit units — depends entirely on input array data type; this must be stated. + - **Concept Links:** Feature IDs, burn algorithm, segmentation, Cell vs Feature data + - **Changes Made:** Added lead-in describing the FeatureIds output and cross-referencing the two orientation-based segment filters. Added "What is Feature Segmentation?" conceptual section. Rewrote algorithm into a burn-algorithm step list. Added "Tolerance and Units" section with concrete examples for integer phase maps, 0-1 image quality, and 0-255 grayscale. Added "Mask Array" and "Periodic Option" sections. Added Required Input Sources with cross-plugin links. + +- [x] **CAxisSegmentFeaturesFilter** (OrientationAnalysis) + - **Clarity:** Brief C-axis definition provided, but assumes hexagonal-system knowledge; no guidance on when to use this vs EBSDSegmentFeatures. + - **Completeness:** Shares structure and neighbor scheme figures with other segment filters. Missing: explicit hexagonal-only warning, phase handling, when-to-use guidance. + - **Accessibility:** `<001>`, hexagonal system, C-axis all used without plain-language expansion. + - **Figures Needed:** Reuse hexagonal C-axis figure from ComputeAvgCAxes (Batch 1); add a "C-axis misalignment between two neighboring cells" diagram. + - **Real-World Viz:** Before/after segmentation on hexagonal (e.g., Ti) EBSD data. + - **Units Clarity:** Tolerance is in **degrees** — must be stated explicitly in the parameter description. + - **Concept Links:** C-axis, hexagonal materials, burn algorithm, reference frames + - **Changes Made:** Added explicit hexagonal-only warning at the top with cross-references to alternative segment filters. Added "When to Use This Filter" explaining why C-axis alignment is the right criterion for hexagonal materials and when to use misorientation-based segmentation instead. Rewrote algorithm steps; added "Tolerance and Units" with degree units and typical values (1-3 / 5 / 10+). Added Required Input Sources linking ComputeAvgCAxes for C-axis concept. + +- [x] **EBSDSegmentFeaturesFilter** (OrientationAnalysis) + - **Clarity:** Generic term "misorientation" used without definition; core burn algorithm clear but domain context missing. + - **Completeness:** No guidance on typical tolerance values (5° is the common industry default for grain segmentation); no mention of how multiple phases are handled. + - **Accessibility:** Assumes EBSD workflow and misorientation knowledge. + - **Figures Needed:** Misorientation angle diagram (shared with Batch 1 misorientation concept work); before/after segmentation example. + - **Real-World Viz:** EBSD IPF map → segmented grains visualization — this is one of the highest-value workflow visualizations in DREAM3DNX. + - **Units Clarity:** Tolerance is in **degrees** — must be stated explicitly. + - **Concept Links:** misorientation, EBSD workflow, burn algorithm, reference frames, grain segmentation + - **Changes Made:** Added "What is Misorientation-Based Segmentation?" section explaining grains and misorientation for non-experts. Rewrote algorithm into numbered burn steps including symmetry handling. Added "Typical Tolerance Values" section with 5° industry default, 2-3° for subgrains, 10-15° high-angle cutoff. Added "Phase Handling" explaining different-phase and phase-0 behavior. Added "Mask Array" and "Periodic Option" sections. Added Required Input Sources. + +- [x] **RequireMinimumSizeFeaturesFilter** (SimplnxCore) + - **Clarity:** Core action (remove features below size threshold) clear, but "isotropically coarsened" is unexplained jargon. + - **Completeness:** Has good warnings (feature data invalidation, NeighborList removal); no guidance on typical minimum-size values. + - **Accessibility:** "Ensemble" bolded but not defined; "isotropically coarsened" needs a plain-language explanation. + - **Figures Needed:** Before/after showing small features removed and gaps filled; diagram of isotropic coarsening (neighbors growing outward uniformly). + - **Real-World Viz:** Before/after microstructure with minimum-size filter applied. + - **Units Clarity:** Minimum size is in **cells** (integer voxel count) — must be stated explicitly. + - **Concept Links:** feature cleanup, isotropic coarsening, Ensemble, NeighborList invalidation + - **Changes Made:** Added lead-in explaining typical use (discarding spurious single-cell grains after segmentation). Added "What is Isotropic Coarsening?" section with plain-language explanation. Added "Minimum Size Units" section stating units are **cells** (integer voxel count), with a formula for converting physical volume to cell count. Rewrote the "Single Phase" option more clearly. Kept existing warnings. Added Required Input Sources. + +- [x] **ComputeFeatureNeighborsFilter** (SimplnxCore) + - **Clarity:** Algorithm steps clear, but the multiple output arrays are described inline in running prose and hard to scan. + - **Completeness:** Mentions several outputs (neighbor count, shared surface area, boundary-cell count, surface-feature flag) but all buried in a single paragraph. + - **Accessibility:** Face-sharing neighbor concept not illustrated; implicit assumption that user knows what a NeighborList is. + - **Figures Needed:** Diagram showing feature-to-feature shared boundary with shared surface area highlighted. + - **Real-World Viz:** Grain map colored by number of neighbors; or shared-surface-area visualization. + - **Units Clarity:** Shared surface area is in **cell-face units** (dimensionless count of shared faces, not physical area) — should be stated. + - **Concept Links:** contiguous neighbors, Feature IDs, shared surface area, NeighborList + - **Changes Made:** Rewrote lead-in describing why downstream filters depend on this (misorientation stats, GBCD, twin merging, boundary strengths). Separated algorithm steps from output descriptions. Added "What This Filter Produces" section with bulleted list of the three main outputs plus two optional outputs; explained each output's downstream use. Explicitly stated shared surface area units are **cell-face count**, not physical area. Added Required Input Sources. + +### Tier 3 — Polish + +| Filter | Plugin | Status | +|--------|--------|--------| +| IdentifySample | SimplnxCore | Done | +| ComputeSurfaceFeatures | SimplnxCore | Done | +| ComputeBiasedFeatures | SimplnxCore | Done | +| RemoveFlaggedFeatures | SimplnxCore | Done | + +- [x] **IdentifySampleFilter** (SimplnxCore) + - **Clarity:** Clear purpose (remove overscan border), steps well explained, slice-by-slice option well documented. + - **Completeness:** Good example images showing when to use vs when not to use the filter. + - **Accessibility:** FIB-SEM mentioned but not critical to understanding; typo: "thresheld" should be "thresholded". + - **Figures Needed:** Already adequate; could add a before/after showing cleanup effect on a real overscanned dataset. + - **Real-World Viz:** Already has good/bad-dataset examples. + - **Concept Links:** thresholding, sample identification, contiguous regions + - **Changes Made:** Fixed typo "thresheld" → "thresholded". Rewrote intro prose for readability (shorter sentences, active voice). Added explicit link to Multi-Threshold Objects as the typical mask source. Added Required Input Sources. Title preserved as it matches the filter's humanName(). + +- [x] **ComputeSurfaceFeaturesFilter** (SimplnxCore) + - **Clarity:** Purpose clear; algorithm clear; two WARNING sections are helpful and well-placed. + - **Completeness:** Broken/truncated sentence on line 9: "the Cells that sit at either ." — should be completed or deleted. Intro paragraph and the "This Filter determines..." paragraph are partially redundant. + - **Accessibility:** Feature ID=0 convention referenced in a warning but could use an inline first-use definition. + - **Figures Needed:** Already has good example output images. + - **Real-World Viz:** Already present. + - **Concept Links:** Feature ID=0, surface features, bounding box + - **Changes Made:** Deleted broken truncated sentence. Consolidated the two redundant intro paragraphs into one. Added inline definition of Feature ID = 0 (the "unassigned / outside sample" convention) with cross-link to IdentifySample. Added cross-link to ComputeBiasedFeatures as the more rigorous approach to boundary bias. Added Required Input Sources. + +- [x] **ComputeBiasedFeaturesFilter** (SimplnxCore) + - **Clarity:** Algorithm and rationale well explained; before/after example figure is strong. + - **Completeness:** Good — explains why larger features are more likely to be biased and why bounding-box logic works. + - **Accessibility:** Most terms defined inline; credit to Dave Rowenhorst retained. + - **Figures Needed:** Already adequate. + - **Real-World Viz:** Already present. + - **Concept Links:** stereology, feature centroids, bounding-box bias, unbiased statistics + - **Changes Made:** Added "Why Bias Matters for Statistics" section explaining the size-dependent sampling bias — why excluding only surface-touching features still leaves bias, and why centroid-based bounding-box logic fixes it. Cross-linked ComputeSurfaceFeatures. Added Required Input Sources. + +- [x] **RemoveFlaggedFeaturesFilter** (SimplnxCore) + - **Clarity:** Three operations (Remove / Extract / Extract then Remove) well documented. + - **Completeness:** NeighborList warning present; no Example Pipeline link populated. + - **Accessibility:** "isotropically coarsened" is jargon (same issue as RequireMinimumSizeFeatures). + - **Figures Needed:** Before/after showing each of the three operation modes; at least a side-by-side of Remove vs Extract. + - **Real-World Viz:** Microstructure showing extraction vs removal outcomes. + - **Concept Links:** feature cleanup, isotropic coarsening, feature extraction + - **Changes Made:** Rewrote description to position this filter as the general-purpose flag-based removal tool and cross-reference RequireMinimumSizeFeatures for size-based use. Linked "isotropic coarsening" to the definition in RequireMinimumSizeFeatures rather than repeating. Cleaned up operation list phrasing. Converted NeighborList warning to sub-heading. Added Required Input Sources listing typical flag-producing filters (ComputeBiasedFeatures, ComputeSurfaceFeatures). + +--- + +## Batch 7: I/O Filters (Read/Write) + +**Plugin:** SimplnxCore + OrientationAnalysis +**Filters:** 44 (24 readers + 20 writers) + +> **Scope note:** The design spec estimated ~15 I/O filters. The actual count is **44** once the full set of EBSD/HDF5 readers (Ang, Ctf, Channel5, H5Ebsd, H5Esprit, H5Oim, H5Oina, EnsembleInfo, GrainMapper3D) and the format-specific exporters (Abaqus, LAMMPS, SPParks, LosAlamos FFT, VTK, Avizo, INL, GBCD, StatsGen ODF, etc.) are included. Rewrites will be committed at each tier boundary, and the large Tier 2 group may be split into sub-commits by sub-theme (core data I/O, image/volume readers, simulation exporters, VTK/Avizo, EBSD readers, OrientationAnalysis writers). + +### Tier 1 — Critical + +| Filter | Plugin | Status | +|--------|--------|--------| +| ReadH5OinaData | OrientationAnalysis | Done | +| WriteGBCDGMTFile | OrientationAnalysis | Done | + +- [x] **ReadH5OinaDataFilter** (OrientationAnalysis) + - **Clarity:** Reads a single Oxford Aztec `.h5oina` file; vendor clearly identified. FORMAT VERSION 2.0 limitation and the Read HDF5 Dataset workaround are useful. + - **Completeness:** STRUCTURAL DEFECT (fixed) — the doc had hand-written `## Parameters` and `## Created Objects` tables and was missing the auto-table marker entirely. + - **Accessibility:** Same undefined EBSD jargon (Euler angles, crystal structures, reference frames) as the other EBSD readers. + - **Figures Needed:** Has Figure 1 (Hexagonal alignment) + a UI overview; a sample/crystal reference-frame diagram would help. + - **Real-World Viz:** IPF map of imported Aztec data. + - **Units Clarity:** `.h5oina` angles stated as radians (good); Z Spacing units (microns) now live in the parameter help text (the auto-table). + - **Concept Links:** Euler angles (Bunge Z-X-Z), crystal structures/Ensemble, lattice constants, sample/crystal reference frame, hexagonal symmetry, H5OINA v2.0 format + - **Changes Made:** DELETED the hand-written `## Parameters` and `## Created Objects` tables and INSERTED the `% Auto generated parameter table` marker (so the real parameter table now injects). Added a "What This Filter Produces" prose paragraph explaining the imported EBSD data in plain language (orientation as Euler angles, per-pixel phase, pattern-quality metrics, per-phase Ensemble data) instead of a stale type table. Fixed the phi2 +30° bullet that wrongly referenced "(.ctf) files" → "`.h5oina` files". Reworded the historical reference-frame note from ".ctf file" to "Oxford data". Converted the two `{ref}` rotation links and the bold-only "Threshold Objects" to MyST links; fixed the Read HDF5 Dataset link to the cross-plugin `../SimplnxCore/` form. Added a "Downstream Processing" note cross-linking Convert Orientation Representation. Fixed typo "agment" → "augment". Normalized footer to "## DREAM3D-NX Help". + +- [x] **WriteGBCDGMTFileFilter** (OrientationAnalysis) + - **Clarity:** Was one sentence; never explained what a GBCD pole figure is, what the `.dat` contains, or why an engineer would want one. + - **Completeness:** No parameter explanation beyond "phase index"; the Misorientation Axis-Angle parameter was undocumented. No Required Input Sources. + - **Accessibility:** "GBCD", "GMT", "pole figure", "phase index" all undefined. GMT URL (`gmt.soest.hawaii.edu`) was stale. + - **Figures Needed:** Data-flow diagram: GBCD data (from Compute GBCD) → this filter → `.dat` → GMT → rendered pole figure (shows the external toolchain). + - **Real-World Viz:** Already has a rendered GMT pole figure image (caption now explains MRD contours). + - **Units Clarity:** Phase index now stated as 1-based dimensionless index; misorientation angle stated in degrees, axis (h,k,l) dimensionless. + - **Concept Links:** GBCD, GMT, pole figure, stereographic projection, Ensemble/phase data, MRD + - **Changes Made:** Major rewrite. Added "What is a GBCD Pole Figure?" defining grain boundary, GBCD, misorientation, pole figure, and MRD in plain language. Added "What This Filter Does" making explicit that GMT is an external toolkit and this filter only writes its input `.dat` file (with the Compute GBCD → this filter → GMT toolchain spelled out). Added "Parameter Guidance" documenting Phase of Interest (1-based index), the previously-undocumented Misorientation Axis-Angle (angle in degrees + crystal axis h,k,l, with the Σ3 example), and Output GMT File. Added a Required Input Sources section naming [Compute GBCD](ComputeGBCDFilter.md) (GBCD) and the EBSD readers (Crystal Structures). Fixed the GMT URL to generic-mapping-tools.org. Improved the figure caption to explain the MRD contours. + +### Tier 2 — Important + +| Filter | Plugin | Status | +|--------|--------|--------| +| ReadHDF5Dataset | SimplnxCore | Done | +| WriteBinaryData | SimplnxCore | Done | +| ReadStlFile | SimplnxCore | Done | +| ReadVtkStructuredPoints | SimplnxCore | Done | +| ReadVolumeGraphicsFile | SimplnxCore | Done | +| WriteAbaqusHexahedron | SimplnxCore | Done | +| WriteLAMMPSFile | SimplnxCore | Done | +| WriteSPParksSites | SimplnxCore | Done | +| WriteLosAlamosFFT | SimplnxCore | Done | +| ReadDeformKeyFileV12 | SimplnxCore | Done | +| WriteVtkRectilinearGrid | SimplnxCore | Done | +| WriteVtkStructuredPoints | SimplnxCore | Done | +| WriteAvizoRectilinearCoordinate | SimplnxCore | Done | +| WriteAvizoUniformCoordinate | SimplnxCore | Done | +| ReadDREAM3D | SimplnxCore | Done | +| ReadEnsembleInfo | OrientationAnalysis | Done | +| ReadAngData | OrientationAnalysis | Done | +| ReadCtfData | OrientationAnalysis | Done | +| ReadChannel5Data | OrientationAnalysis | Done | +| ReadH5Ebsd | OrientationAnalysis | Done | +| ReadH5EspritData | OrientationAnalysis | Done | +| ReadH5OimData | OrientationAnalysis | Done | +| WriteGBCDTriangleData | OrientationAnalysis | Done | +| WritePoleFigure | OrientationAnalysis | Done | + +- [x] **ReadHDF5DatasetFilter** (SimplnxCore) + - **Clarity:** Element-count matching rule is explained, but the worked examples confuse more than clarify (Example 1 is an error case; Example 2's arithmetic is internally inconsistent). + - **Completeness:** Missing description of key parameters (which dataset(s) to select, the file path, multi-dataset import in one pass). Only the dimension math is covered. + - **Accessibility:** Assumes the reader knows HDF5 dataset vs group; "component/tuple dimensions", "attribute matrix" undefined. + - **Figures Needed:** Diagram of a flat HDF5 dataset (N elements) reshaped into tuples × components. + - **Real-World Viz:** Screenshot of the HDF5 tree dataset-selection UI. + - **Units Clarity:** N/A (element counts, dimensionless). + - **Concept Links:** HDF5 dataset/group, component dimensions, tuple dimensions, attribute matrix, total element count + - **Changes Made:** Added a one-line definition of HDF5 and first-use definitions of tuple vs component dimensions. Described the dataset-selection behavior and the optional Attribute-Matrix parent placement in prose. Replaced the three inconsistent worked examples (including the '4-dims-labeled-3D' / mismatched-arithmetic case) with three internally consistent ones built on the rule total-element-count = tuples x components. Added Required Input Sources (None -- external .h5/.hdf5 file) and a License & Copyright section. + +- [x] **WriteBinaryDataFilter** (SimplnxCore) + - **Clarity:** Thin — one sentence plus an Endianess section. Does not state output file naming, extension, multi-component behavior, or that no header is written. + - **Completeness:** Only Endianess documented. Missing output directory/naming, raw-no-header behavior, on-disk component ordering, file extension parameter. + - **Accessibility:** The Endianess section itself is clear; the problem is omission. + - **Figures Needed:** None. + - **Real-World Viz:** Optional screenshot of the output files (low priority). + - **Units Clarity:** N/A. + - **Concept Links:** endianness, raw binary (no header), component ordering, output file naming + - **Changes Made:** Expanded the thin description to the actual behavior (one raw file per **Data Array**, `` naming with default `.bin`, interleaved components, no header written). Added the explicit warning that the user must record type/dims/endianness, and a cross-link to read the files back with [Read Raw Binary](ReadRawBinaryFilter.md). Italicized the endianness values; fixed the run-on/period grammar. + +- [x] **ReadStlFileFilter** (SimplnxCore) + - **Clarity:** Dives straight into binary layout/attribute-byte-count without first stating in plain terms that STL is a triangle surface mesh and the output is a Triangle Geometry. + - **Completeness:** Covers binary format, vendor detection, strictness, a Python fix script. Never states ASCII STL is unsupported; no mention of produced arrays/normals. + - **Accessibility:** Heading typo "## IMPORANT NOTES". Strictness warning repeated verbatim twice. Aimed at STL-format experts. + - **Figures Needed:** Illustration of one triangle (normal + 3 vertices) and how triangles form a surface mesh. + - **Real-World Viz:** Screenshot of an STL surface as a Triangle Geometry. + - **Units Clarity:** STL is unitless — one sentence stating coordinates are in the file author's units (dimensionless to the reader). + - **Concept Links:** Triangle Geometry, surface mesh, STL binary format, attribute byte count, face normals + - **Changes Made:** Added a plain-language opening (an STL file is a list of triangles -> **Triangle Geometry**, with Face Normals/Labels). Fixed the 'IMPORANT NOTES' heading typo. Added an explicit binary-only / ASCII-rejected caveat (confirmed against preflight). Collapsed the duplicated attribute-byte-count warning; noted STL coordinates are unitless. Required Input Sources: None; fixed the Wikipedia anchor. + +- [x] **ReadVtkStructuredPointsFilter** (SimplnxCore) + - **Clarity:** Core idea clear (legacy VTK structured-points → Image Geometry) but POINT_DATA vs CELL_DATA and "eight values per voxel" will confuse non-experts without a figure. Uses legacy SIMPL "Data Container" wording. + - **Completeness:** Explains attribute types, binary/ASCII, point vs cell data with an example. Missing: behavior when both POINT_DATA and CELL_DATA present (output naming/paths). + - **Accessibility:** "STRUCTURED_POINTS", "POINT_DATA", "CELL_DATA", "LOOKUP_TABLE" only partly explained. + - **Figures Needed:** A voxel cube showing cell-center value vs the 8 corner (point) values. + - **Real-World Viz:** Screenshot of the example GrainIds dataset as an Image Geometry. + - **Units Clarity:** State spacing/origin come from the file; length units file-defined. + - **Concept Links:** Image Geometry, Cell Attribute Matrix, structured points, point vs cell data, voxel corners vs center, SCALARS/VECTORS + - **Changes Made:** Replaced legacy 'Data Container' with **Image Geometry** throughout. Added a Point Data vs Cell Data subsection and described the two-output naming (`VTK Cell Data` / `VTK Point Data`) when both are present. Added the missing DREAM3D-NX Help footer and a License section, plus a Spacing/Origin/Units note. Required Input Sources: None. + +- [x] **ReadVolumeGraphicsFileFilter** (SimplnxCore) + - **Clarity:** Thin one-paragraph description; a non-expert won't know "Volume Graphics" data is a CT/VGStudio export. + - **Completeness:** Underspecified — no output geometry type, volume data type, cropping support, or created array named. Only caveat is "both files in same directory". + - **Accessibility:** "Volume Graphics data files" is a vendor term used without explanation. + - **Figures Needed:** Optional small diagram of the `.vgi` (metadata) + `.vol` (raw voxels) pairing. + - **Real-World Viz:** Screenshot of a CT volume from a `.vgi`/`.vol` pair. + - **Units Clarity:** Says units come from the `.vgi`; expand to state which units and that spacing/origin derive from it. + - **Concept Links:** Image Geometry, `.vgi`/`.vol` file pair, spacing/dimensions/units, CT volume + - **Changes Made:** Normalized the group to IO (Input). Defined Volume Graphics data (.vgi metadata + .vol raw voxels; a CT/VGStudio export). Stated the output is an **Image Geometry** with a single float32 density Cell array and origin (0,0,0) (confirmed from preflight); noted no sub-volume extraction. Added an Example Pipelines heading and Required Input Sources: None. + +- [x] **WriteAbaqusHexahedronFilter** (SimplnxCore) + - **Clarity:** Non-expert won't know Abaqus is a commercial FEA package or why one exports a voxel grid to it. Jumps into `.inp` files without framing the Image-Geometry → hexahedral-mesh conversion. + - **Completeness:** Five output files listed but their relationship (master `*Include`s the others) only implied. The `Write Dummy Node` parameter referenced at top but never explained. + - **Accessibility:** "Abaqus", ".inp", "hexahedron", "C3D8", "Hourglass Stiffness", "stress-strain" undefined. The huge raw `_elset.inp` dump hurts readability. + - **Figures Needed:** Diagram of a voxel grid mapping to a hexahedral mesh (8 nodes per voxel). + - **Real-World Viz:** Screenshot of the exported mesh in Abaqus/CAE colored by grain. + - **Units Clarity:** Node coordinates are physical units (matching spacing) but never stated; "Hourglass Stiffness 250" has no units/explanation. + - **Concept Links:** Abaqus/FEA, hexahedral mesh, Image Geometry, FeatureIds, element sets (grains), nodes/elements + - **Changes Made:** Defined Abaqus and FEA; framed the filter as converting an **Image Geometry** voxel grid into a C3D8 8-node hexahedral mesh. Documented the five `.inp` files and the master-file `*Include` relationship, the *Write Dummy Node* and *Hourglass Stiffness* parameters, and that node coordinates are in physical units. Trimmed the large `_elset.inp` dump; added Required Input Sources (FeatureIds + Image Geometry). + +- [x] **WriteLAMMPSFileFilter** (SimplnxCore) + - **Clarity:** Non-expert won't know LAMMPS is a molecular-dynamics code. Purpose stated but why/when unclear. + - **Completeness:** No output-format example. "Example Pipelines" heading empty. Names "Insert Atoms" as producer (good, but informal). + - **Accessibility:** "LAMMPS" never expanded. Legacy "Vertex Data Container" wording. Self-reference "Export LAMMPS Filter" is the wrong name. + - **Figures Needed:** Optional before/after of features filled with atoms. + - **Real-World Viz:** Screenshot of the resulting atom configuration (OVITO/VMD). + - **Units Clarity:** Atom-coordinate units undocumented; state them. + - **Concept Links:** LAMMPS/molecular dynamics, atomistic representation, Vertex Geometry, Insert Atoms + - **Changes Made:** Expanded LAMMPS (Sandia molecular-dynamics code); replaced 'Vertex Data Container' with **Vertex Geometry**; fixed the 'Export LAMMPS Filter' self-reference. Added an output-format example and atom-coordinate units. Added Required Input Sources (Vertex Geometry, e.g. from Insert Atoms -- referenced in plain text since no Insert Atoms doc exists in the repo). Removed the empty Example Pipelines heading. + +- [x] **WriteSPParksSitesFilter** (SimplnxCore) + - **Clarity:** Terse and oddly worded ("LINE 4 evidently must be what is shown"); non-expert won't understand a "sites" file or site/value pairs. + - **Completeness:** No Required Input Sources (needs FeatureIds on an Image Geometry). Line-by-line explanation partial (lines 1, 8 unexplained). + - **Accessibility:** "SPPARKS" linked but not contextualized as a Kinetic Monte Carlo grain-growth simulator. "Kinetic Monte Carlo", "max neighbors", "xlo xhi" undefined. Header style `## Description ##` inconsistent. + - **Figures Needed:** None. + - **Real-World Viz:** None. + - **Units Clarity:** Dimension lines (0 200) are cell-index extents (dimensionless cell counts) — clarify vs physical units. + - **Concept Links:** SPPARKS/Kinetic Monte Carlo, sites, FeatureIds, Image Geometry, Cells + - **Changes Made:** Defined SPPARKS (Sandia Kinetic Monte Carlo microstructure simulator); rewrote the tentative 'LINE 4 evidently' wording authoritatively. Explained site/value = cell/FeatureId, clarified the box-extent lines are dimensionless cell-index counts, and explained the blank separator lines. Normalized '## X ##' headings; added Required Input Sources (FeatureIds on an Image Geometry). + +- [x] **WriteLosAlamosFFTFilter** (SimplnxCore) + - **Clarity:** Output column layout (Phi1 Phi Phi2 X Y Z Feature_ID Phase_ID) explained well, but non-expert won't know what an "FFT 3D simulation code" is for or what Euler angles/phases are. + - **Completeness:** Good format detail and a real reference. No Required Input Sources (needs Euler angles, FeatureIds, Phases on an Image Geometry). Empty "Example Pipelines" heading. + - **Accessibility:** "Euler angles", "Phi1/Phi/Phi2", "phase", "FFT" undefined for a general reader. + - **Figures Needed:** None. + - **Real-World Viz:** None. + - **Units Clarity:** Excellent — Euler angles in degrees, X/Y/Z integer indices, IDs from 1. Model for the batch; keep. + - **Concept Links:** FFT/crystal plasticity, Euler angles, phases, FeatureIds, Image Geometry, CellData + - **Changes Made:** Contextualized Euler angles and the Lebensohn FFT crystal-plasticity code; preserved the existing (model) units paragraph. Added Required Input Sources (Euler angles from an EBSD reader, FeatureIds, Phases) and removed the empty Example Pipelines heading. + +- [x] **ReadDeformKeyFileV12Filter** (SimplnxCore) + - **Clarity:** Two sentences. Non-expert won't know DEFORM is a metal-forming FEA package or what a "key file" is; can't tell what data results. + - **Completeness:** Very thin. Lists variable names (stress, strain, ndtmp) without explanation. Does not describe the resulting DataStructure (a Quad Geometry plus cell/node attribute matrices). + - **Accessibility:** "DEFORM v12", "key file", "ndtmp", "quadrilateral mesh", legacy "Data Container" all undefined. + - **Figures Needed:** Optional screenshot of the imported quad mesh colored by a variable. + - **Real-World Viz:** Render of the loaded DEFORM mesh colored by stress/strain. + - **Units Clarity:** N/A (importer); note imported variable units are whatever DEFORM exported. + - **Concept Links:** DEFORM/FEA, key file, Quad Geometry, nodes/cells, cell vs node variables + - **Changes Made:** Defined DEFORM (metal-forming finite-element package) and a v12 key file. Described the created **Quad Geometry** plus node- and cell-level arrays (ndtmp = nodal temperature); replaced 'Data Container' with Quad Geometry. Added an example key-file snippet; Required Input Sources: None. + +- [x] **WriteVtkRectilinearGridFilter** (SimplnxCore) + - **Clarity:** Never says what a "VTK legacy file" or "RECTILINEAR_GRID dataset" is, nor why one wants this (ParaView/VisIt interop). + - **Completeness:** Single sentence. No ASCII vs binary mention, vertex vs cell data, extension, or that input must be an Image Geometry. + - **Accessibility:** "VTK legacy file", "RECTILINEAR_GRID" undefined. + - **Figures Needed:** Optional shared diagram contrasting rectilinear-grid vs structured-points (variable vs uniform spacing). + - **Real-World Viz:** Screenshot of the `.vtk` in ParaView. + - **Units Clarity:** N/A in prose; confirm in param table. + - **Concept Links:** VTK legacy format, ASCII vs binary VTK, RectilinearGrid vs Image Geometry, ParaView/VisIt + - **Changes Made:** Expanded the one-sentence description; defined VTK legacy format and RECTILINEAR_GRID and named ParaView/VisIt. Explained the **Image Geometry** input is written as an explicit-coordinate rectilinear grid; documented ASCII vs binary. Added Required Input Sources (Image Geometry + cell arrays) and a cross-link to the structured-points variant. + +- [x] **WriteVtkStructuredPointsFilter** (SimplnxCore) + - **Clarity:** Assumes the reader knows STRUCTURED_POINTS. The one useful caveat ("only writes cell data") is present. + - **Completeness:** Very thin. Doesn't explain how structured points differs from rectilinear grid, or when to pick this writer. + - **Accessibility:** "VTK legacy file", "STRUCTURED_POINTS" undefined; indistinguishable from the rectilinear writer to a non-expert. + - **Figures Needed:** Shared diagram (uniform structured points vs variable rectilinear spacing). + - **Real-World Viz:** Screenshot in ParaView. + - **Units Clarity:** N/A in prose. + - **Concept Links:** VTK legacy format, structured points vs rectilinear grid, uniform spacing, ParaView/VisIt + - **Changes Made:** Defined STRUCTURED_POINTS (uniform-spacing image data) with the same VTK/ParaView framing; kept the cell-data-only caveat. Added a 'when to use vs [Write Vtk Rectilinear Grid]' note and ASCII/binary documentation; added Required Input Sources. + +- [x] **WriteAvizoRectilinearCoordinateFilter** (SimplnxCore) + - **Clarity:** Confusing opening ("Values should be present from segmentation … cannot be determined by this filter") — vague about what "values" means (the FeatureIds array). + - **Completeness:** Helpful raw AmiraMesh header example, but never says what Avizo is, what FeatureIds are, or that input is an Image Geometry + Int32 FeatureIds. Example contains garbled DateTime bytes. + - **Accessibility:** "Avizo", "AmiraMesh", "Rectilinear Coordinate", "FeatureIds", "segmentation" undefined. + - **Figures Needed:** None. + - **Real-World Viz:** Screenshot of the output in Avizo. + - **Units Clarity:** Example shows "Coordinates microns" — note the Avizo file hardcodes microns regardless of the geometry's actual units (caveat). + - **Concept Links:** Avizo/AmiraMesh format, FeatureIds, segmentation, RectilinearGrid vs Image Geometry, units (microns) + - **Changes Made:** Rewrote the confusing opening to state the **Image Geometry** + Int32 FeatureIds input plainly; defined Avizo and AmiraMesh. Cleaned the garbled DateTime bytes in the header example; added the hardcoded-microns caveat and ASCII/binary note; added a Group line, Required Input Sources, and a link to the Uniform variant. + +- [x] **WriteAvizoUniformCoordinateFilter** (SimplnxCore) + - **Clarity:** Same vague "Values should be present…" sentence; doesn't clarify FeatureIds input or how "Uniform" differs from "Rectilinear". + - **Completeness:** Example header present but contains empty/garbled fields (blank DateTime, truncated Content/BoundingBox). Avizo/AmiraMesh undefined. + - **Accessibility:** Same undefined jargon as the rectilinear variant. + - **Figures Needed:** None. + - **Real-World Viz:** Screenshot in Avizo. + - **Units Clarity:** "Coordinates microns" hardcoded; caveat needed. BoundingBox units/order should tie to spacing/origin. + - **Concept Links:** Avizo/AmiraMesh format, uniform vs rectilinear coordinates, FeatureIds, BoundingBox, units (microns) + - **Changes Made:** Same clarifications as the Rectilinear variant (FeatureIds input, Avizo/AmiraMesh definitions, microns caveat, cleaned garbled example fields). Added the one-line contrast (single uniform spacing/bounding box vs per-axis coordinate arrays) and a link to the Rectilinear variant; added Required Input Sources. + +- [x] **ReadDREAM3DFilter** (SimplnxCore) + - **Clarity:** Core action clear (reads the DataStructure from a `.dream3d` HDF5 file), but omits the most important behavior: selective/partial import. + - **Completeness:** Missing partial-import behavior, merge-into-current-DataStructure and name-collision behavior, pipeline-metadata read. Lacks the "Group (Subgroup)" header other docs carry. No Required Input Sources statement. + - **Accessibility:** ".dream3d", "HDF5", "legacy" used without a one-line gloss. + - **Figures Needed:** None. + - **Real-World Viz:** Screenshot of the import-data tree selector showing partial-import checkboxes. + - **Units Clarity:** N/A. + - **Concept Links:** `.dream3d` file, HDF5, DataStructure import, partial import, legacy SIMPL vs NX format + - **Changes Made:** Added the missing Group header (IO (Input)) and the key selective/partial-import behavior; explained imported objects merge into the current **DataStructure** at their paths (overwrite on collision) and that pipeline metadata may be read. Glossed .dream3d/HDF5/'legacy'; added Required Input Sources (None) and the standard footer. + +- [x] **ReadEnsembleInfoFilter** (OrientationAnalysis) + - **Clarity:** Mechanics (format, sections, keys) well laid out with tables and a worked example, but the *purpose* is buried in EBSD jargon. + - **Completeness:** Strong on format/enum tables/phase-numbering caveat. Missing: what an Ensemble attribute matrix is, that this filter creates one, where the output goes; `.ini`/`.txt` are the same format. + - **Accessibility:** Main blocker — Ensemble, Feature, Cell, Crystal Structure, Phase Type, Laue class all undefined. + - **Figures Needed:** None (tables serve well). + - **Real-World Viz:** None high-value. + - **Units Clarity:** N/A (enumerated integer codes, well documented). + - **Concept Links:** Ensemble Info, Ensemble/phase attribute matrix, Crystal Structure / Laue class, Phase Type, Feature vs Cell, ASCII `.ini`/`.txt` + - **Changes Made:** Added a plain-language opening defining *ensemble* = phase and clarifying the filter reads a .ini/.txt file and writes an **Ensemble Attribute Matrix** into an existing Data Container. Added one-line glosses for Crystal Structure and Phase Type before the enum tables; documented downstream statistics consumers; removed the empty Example Pipelines heading. + +- [x] **ReadAngDataFilter** (OrientationAnalysis) + - **Clarity:** Reads a single EDAX/TSL `.ang` into an Image Geometry. Good, but never explains what the imported data MEANS (Euler angles, phases, CI, IQ named but undefined). + - **Completeness:** Field-ordering block useful but raw jargon; does not say phi1/Phi/phi2 ARE the three Euler angles (Bunge). Mask/threshold guidance present. + - **Accessibility:** Heavy undefined jargon (Euler angles, crystal/sample reference frame, Confidence Index, Image Quality, phase, ODF, IPF, hexagonal grid). + - **Figures Needed:** Sample vs crystal reference-frame diagram. + - **Real-World Viz:** IPF map of a freshly imported Small IN100 `.ang` slice. + - **Units Clarity:** Weak — should state `.ang` angles are in radians; step size/origin in microns; reference-frame rotations in degrees. + - **Concept Links:** Euler angles (Bunge), sample/crystal reference frame, confidence index, image quality, phases, IPF/ODF, hex-vs-square grid + - **Changes Made:** Glossed phi1/Phi/phi2 as the three Euler angles; defined crystal/sample reference frames and Confidence Index/Image Quality. Fixed 'he following'; converted the Hex-Grid `{ref}` and the bold-only 'Threshold Objects' to MyST links; fixed the broken 'Ensemble Attribute Matrix' bold; added Downstream Processing and Required Input Sources. + +- [x] **ReadCtfDataFilter** (OrientationAnalysis) + - **Clarity:** Clearly reads an Oxford/HKL `.ctf` into an Image Geometry. Good vendor ID. + - **Completeness:** Good on HKL default transforms, radians/degrees conversion, hexagonal phi2 +30°. Created-array meanings not explained. + - **Accessibility:** Same undefined jargon; hexagonal section highly expert-oriented (flagged as edge case). + - **Figures Needed:** Has Figure 1 (Hexagonal_Axis_Alignment); a reference-frame diagram would still help. + - **Real-World Viz:** IPF map before/after the +30° phi2 correction, or correct-vs-wrong radians/degrees. + - **Units Clarity:** Better than Ang (notes `.ctf` usually degrees, NX expects radians); still missing origin/step-size (microns). + - **Concept Links:** Euler angles, sample/crystal reference frame, radians vs degrees, hexagonal symmetry/Bravais lattice, pole figure/IPF + - **Changes Made:** Fixed the intro broken bold and the mangled Figure 1 caption; marked the hexagonal-alignment section Advanced. Converted `{ref}` and bold-only filter mentions to MyST links; added Downstream Processing (Convert Orientation Representation) and Required Input Sources. + +- [x] **ReadChannel5DataFilter** (OrientationAnalysis) + - **Clarity:** Reads an Oxford Channel 5 `.cpr`/`.crc` pair into an Image Geometry. Uses `ImageGeometry`/`ImageDataContainer` as code, inconsistent with the **Image Geometry** bolding used elsewhere. + - **Completeness:** Mirrors the Ctf doc; good note that `.cpr`/`.crc` angles are radians and that Error=0 marks valid TRUE. Created-array meanings not explained. + - **Accessibility:** Same undefined jargon; hexagonal section copied verbatim and wrongly says "(.ctf) files". + - **Figures Needed:** Has Figure 1; reference-frame diagram still helpful. + - **Real-World Viz:** IPF map of an imported Channel 5 dataset. + - **Units Clarity:** Good on radians; missing origin/step-size (microns). + - **Concept Links:** Euler angles, sample/crystal reference frame, hexagonal symmetry, pole figures, IPF, `.cpr`/`.crc` pair + - **Changes Made:** Fixed the broken bold and caption; corrected the phi2 +30-degree bullet that wrongly referenced '.ctf' to Channel 5 (.cpr/.crc). Standardized code-style 'ImageGeometry' to **Image Geometry**; removed the empty Example Pipelines heading; converted links to MyST and added Required Input Sources. + +- [x] **ReadH5EbsdFilter** (OrientationAnalysis) + - **Clarity:** Good — states it reads a `.h5ebsd` built by *Import Orientation File(s) to H5EBSD*; the UI screenshot + checkbox/slice-subset/transform description is genuinely helpful. The one reader with a real upstream dependency. + - **Completeness:** Strong on transforms, angle representation, slice subsetting, correct-vs-incorrect IPF example. Created-array meanings rely on auto-table (correct). Could note headless parameter equivalents for UI features. + - **Accessibility:** Same domain jargon undefined, but the IF-steel correct/incorrect example is excellent. + - **Figures Needed:** Already has UI + correct/incorrect + Hexagonal alignment figures; a reference-frame concept diagram would still help. + - **Real-World Viz:** Already present (IF-steel IPF maps). + - **Units Clarity:** Reference-frame rotations in degrees OK; lines 42/46 are missing the word "degrees" ("apparent 30 shifts", "add 30 to phi2"). + - **Concept Links:** H5Ebsd intermediate format, Euler angle representation (deg/rad), sample/crystal reference frame, slice stacking/subsetting, hexagonal symmetry, IPF + - **Changes Made:** Added a Required Input Sources section stating the .h5ebsd must be built by [Import Orientation File(s) to H5EBSD](EbsdToH5EbsdFilter.md). Converted the three `{ref}` links to MyST; fixed the truncated '30' -> '30 degrees' (two places) and 'excellant' typo; marked the hexagonal section Advanced; added Downstream Processing. + +- [x] **ReadH5EspritDataFilter** (OrientationAnalysis) + - **Clarity:** Clearly reads a single Bruker Nano Esprit `.h5`; before/after UI screenshots for Z Spacing and scan selection help. + - **Completeness:** Good — documents Z Spacing, multi-scan selection, X/Y Step=0 → 1.0 fallback, recommended rotation filters. "MAD" used without expansion. + - **Accessibility:** Same undefined jargon; "MAD" (Mean Angular Deviation) not expanded. + - **Figures Needed:** Has two UI screenshots; reference-frame diagram would help. + - **Real-World Viz:** IPF map of an imported multi-scan Bruker volume (illustrate Z-stacking). + - **Units Clarity:** Best of the `.h5` readers — Z Spacing "microns between each layer". Origin units not stated. + - **Concept Links:** Euler angles, sample/crystal reference frame, scan/slice (Z) stacking, MAD/image quality, Z spacing (microns), multi-scan files + - **Changes Made:** Expanded MAD -> Mean Angular Deviation on first use; converted all `{ref}` links to MyST; noted the zero-step fallback is 1.0 micron. Fixed the broken bold; added Downstream Processing and Required Input Sources; removed the empty Example Pipelines heading. + +- [x] **ReadH5OimDataFilter** (OrientationAnalysis) + - **Clarity:** Clearly reads an EDAX OIMAnalysis `.h5`. UI screenshots referenced for Z Spacing / scan selection. + - **Completeness:** Good — multi-slice import, the valuable unique "Perform Slice By Slice Transform" caveat, thresholding. Created-array meanings rely on auto-table (correct). + - **Accessibility:** Same undefined jargon; slice-by-slice transform note is clear and practical. + - **Figures Needed:** Two UI screenshots; reference-frame diagram would help. + - **Real-World Viz:** IPF map of imported multi-slice EDAX `.h5` showing the slice-by-slice transform consequence. + - **Units Clarity:** Weaker than Esprit — Z Spacing units (microns) not stated here; origin units absent. + - **Concept Links:** Euler angles, sample/crystal reference frame, slice-by-slice transform, scan/slice stacking, confidence index/image quality, IPF + - **Changes Made:** Stated Z Spacing and Origin units as microns (confirmed from parameters); cross-linked the 'Perform Slice By Slice Transform' mention to Rotate Sample Reference Frame. Converted `{ref}` links to MyST, fixed the broken bold, defined CI/IQ; added Downstream Processing and Required Input Sources; removed the empty Example Pipelines heading. + +- [x] **WriteGBCDTriangleDataFilter** (OrientationAnalysis) + - **Clarity:** Decent — writes per-triangle GBCD info (inward/outward Euler angles, normals, areas) with sample output. A general reader won't know why this matters or what "inward/outward" means. + - **Completeness:** Good example with column legend, but the legend has a numbering bug ("Column 8: surface area" should be Column 10; cols 7-9 are the normal). No parameter explanation, no Required Input Sources. + - **Accessibility:** "GBCD", "Euler angles", "triangle normals", "right/left hand average orientation" undefined. Cites Rohrer without a reference link. + - **Figures Needed:** Boundary-triangle diagram: two grains, their average orientations (left/right), triangle normal, area — maps to the columns. + - **Real-World Viz:** Optional screenshot of a surface mesh colored by feature. + - **Units Clarity:** Euler angles stated as RADIANS (good). Normals are unitless direction cosines — say so. Area units (square microns?) not stated. + - **Concept Links:** GBCD, Euler angles, triangle/surface mesh, feature average orientation, crystal structures + - **Changes Made:** Rewrote the description in plain language (grain boundary, **Triangle Geometry**, Euler angles, normal, area). Fixed the column-legend numbering bug (surface area is column 10, not 8). Stated units (Euler radians, unitless normals, square-micron areas), defined inward/outward (left/right) orientations, added a Rohrer citation, and added Required Input Sources naming each producer. NOTE: the same column-legend bug also exists in the C++ algorithm's emitted file header. + +- [x] **WritePoleFigureFilter** (OrientationAnalysis) + - **Clarity:** Output Options sections clear and well organized, but never defines "pole figure"; "modified Lambert square", "unit circle interpolation", "Laue Class" appear undefined. + - **Completeness:** Good coverage + example images. Missing Required Input Sources. The "In a practical sense…" bullet list (Cell Euler Angles, Phases, Mask; Ensemble Laue Class, Material Names) is effectively a hand-written input-array list — borderline defect; reframe as Required Input Sources. + - **Accessibility:** "pole figure", "Lambert projection/square", "Laue Class", "Ensemble", "stereographic" undefined. No MyST links. + - **Figures Needed:** Conceptual diagram of the stereographic/Lambert projection (3D orientation → 2D unit circle). + - **Real-World Viz:** Already shows colorized vs discrete examples; optionally a labeled example (color bar, hemisphere label, phase name). + - **Units Clarity:** "Lambert Image Size (Pixels)" and output size are pixels — state in prose. Euler angles radians (good). + - **Concept Links:** pole figure, Lambert projection, stereographic projection, Laue class/crystal structure, Ensemble/Feature data, IPF, GBCD + - **Changes Made:** Added a plain-language pole-figure definition and first-use definitions of Lambert/stereographic projection and Laue Class. Converted the hand-written 'In a practical sense' input-array list into a proper Required Input Sources section; stated pixel units for image sizes; matched the doc to the current refactored parameters; kept the example images. + +### Tier 3 — Polish + +| Filter | Plugin | Status | +|--------|--------|--------| +| ReadCSVFile | SimplnxCore | Done | +| ReadStringDataArray | SimplnxCore | Done | +| ReadTextDataArray | SimplnxCore | Done | +| WriteASCIIData | SimplnxCore | Done | +| WriteFeatureDataCSV | SimplnxCore | Done | +| ReadImage | SimplnxCore | Done | +| ReadImageStack | SimplnxCore | Done | +| ReadNIfTIFile | SimplnxCore | Done | +| ReadZeissTxmFile | SimplnxCore | Done | +| ReadBinaryCTNorthstar | SimplnxCore | Done | +| WriteNodesAndElementsFiles | SimplnxCore | Done | +| WriteStlFile | SimplnxCore | Done | +| ReadGrainMapper3D | OrientationAnalysis | Done | +| WriteINLFile | OrientationAnalysis | Done | +| WriteStatsGenOdfAngleFile | OrientationAnalysis | Done | + +- [x] **ReadCSVFileFilter** (SimplnxCore) + - **Changes Made:** Converted the bold-only 'Combine Attribute Arrays' mention to a MyST link; gave the 10 identical image alt-texts unique descriptive alts; added Required Input Sources (None). + +- [x] **ReadStringDataArrayFilter** (SimplnxCore) + - **Changes Made:** Fixed typos 'Created Arra Path' and 'mulplying'; converted the quoted 'Read CSV Filter' to a MyST link; added Required Input Sources (None). + +- [x] **ReadTextDataArrayFilter** (SimplnxCore) + - **Changes Made:** Fixed typos 'Created Arra Path', 'mulplying', 'Componenets'; converted 'Read CSV Filter' to a MyST link; added a descriptive image alt; confirmed via the cpp there is no 'New Line' delimiter option here; added Required Input Sources (None). + +- [x] **WriteASCIIDataFilter** (SimplnxCore) + - **Changes Made:** Cleaned the cluttered Group line to 'IO (Output)'; added a 'Maximum Tuples Per Line' description (units = tuples per row, multiple-files mode); noted inputs are user-selected Data Arrays. + +- [x] **WriteFeatureDataCSVFilter** (SimplnxCore) + - **Changes Made:** Defined **Feature** on first use; explained the leading output line is the total Feature count; added Required Input Sources naming [Compute Feature Neighbors](ComputeFeatureNeighborsFilter.md) and Compute Feature Neighbor Misorientations. + +- [x] **ReadImageFilter** (SimplnxCore) + - **Changes Made:** Added an up-front 'single 2D image' note with a link to the stack reader; stated Origin/Spacing units; added Required Input Sources (None). + +- [x] **ReadImageStackFilter** (SimplnxCore) + - **Changes Made:** Fixed the title to match humanName 'Read Images [3D Stack]'; converted the bold Read Image mention to a MyST link; added a 'File List and Slice Ordering' subsection; defined the luminosity algorithm; stated spacing/origin units; added Required Input Sources (None). + +- [x] **ReadNIfTIFileFilter** (SimplnxCore) + - **Changes Made:** Removed the hand-written `## Parameters` table that duplicated the auto-table (kept the Caveats list); added plain-language glosses for sform/qform/pixdim/vox_offset/scl_slope/scl_inter; noted spacing units come from the file (often mm); added Required Input Sources (None). + +- [x] **ReadZeissTxmFileFilter** (SimplnxCore) + - **Changes Made:** Expanded 'xCT' to X-ray computed tomography on first use; stated spacing/origin/units are read from the file and named the created output array; normalized trailing-## headings; added Required Input Sources (None). + +- [x] **ReadBinaryCTNorthstarFilter** (SimplnxCore) + - **Changes Made:** Normalized the Group line to 'IO (Input)'; defined CT on first use; named the created output array; noted the subvolume start/end are zero-based inclusive voxels; added Required Input Sources (None). + +- [x] **WriteNodesAndElementsFilesFilter** (SimplnxCore) + - **Changes Made:** Added Required Input Sources (any node-based geometry from a meshing/geometry-creation filter); fixed the 'requried' typo; stated node coordinates are in the geometry's physical units. + +- [x] **WriteStlFileFilter** (SimplnxCore) + - **Changes Made:** Fixed the 'implict' typo; clarified the 2-component Features array holds the two Feature IDs on either side of each triangle; noted vertex coordinates are in the Triangle Geometry's units; added Required Input Sources (Triangle Geometry + Face Labels). + +- [x] **ReadGrainMapper3DFilter** (OrientationAnalysis) + - **Changes Made:** Added a GrainMapper3D/XNovo LabDCT gloss; clarified the two IPF-color options; added a millimeters-vs-microns downstream caveat; added Required Input Sources (None). + +- [x] **WriteINLFileFilter** (OrientationAnalysis) + - **Changes Made:** Annotated the output columns with explicit units (Euler radians, positions/step sizes microns); explained the Symmetry column holds crystal-symmetry codes (43 = cubic m-3m, 62 = hexagonal); added Required Input Sources. + +- [x] **WriteStatsGenOdfAngleFileFilter** (OrientationAnalysis) + - **Changes Made:** Expanded ODF to Orientation Distribution Function on first use; fixed 'can not' -> 'cannot'; noted weight and sigma are dimensionless; added Required Input Sources (Euler angles from an EBSD reader; optional Mask from Multi-Threshold Objects). + +### Tier 4 — Adequate + +| Filter | Plugin | Status | +|--------|--------|--------| +| ReadRawBinary | SimplnxCore | Done (minor) | +| WriteImage | SimplnxCore | Done (minor) | +| WriteDREAM3D | SimplnxCore | Done (minor) | + +- [x] **ReadRawBinaryFilter** (SimplnxCore) + - **Changes Made:** Added a 'Required Input Sources: None' note. No other changes — the doc was already a model for the batch. + +- [x] **WriteImageFilter** (SimplnxCore) + - **Changes Made:** Added a Required Input Sources section naming the image readers / image-processing producers. No other changes — already publication-ready. + +- [x] **WriteDREAM3DFilter** (SimplnxCore) + - **Changes Made:** Added the missing Group (Subgroup) header and a Required Input Sources note (none; overwrites existing file). No other changes — already thorough. + +### Batch 8: Image Processing / ITK Wrappers (~88 filters) +**Plugin:** ITKImageProcessing +ITK-wrapped image processing filters (threshold, blur, morphological, etc.) + +## Batch 9: Remaining SimplnxCore Filters + +**Plugin:** SimplnxCore +**Filters:** 73 (catch-all for SimplnxCore filters not covered by Batches 1-7; the ITK plugin is Batch 8, deferred) + +> Triaged 2026-06-11. Tier split: T1=4, T2=35, T3=31, T4=3. Rewrites will be committed per tier (Tier 2 split into sub-theme sub-commits given its size). Recurring defects flagged: hand-duplicated parameter tables (HierarchicalSmooth; CreatePythonSkeleton — also missing the marker), a legacy `@ref` directive (ComputeBoundingBoxStats), Doxygen math/`@image` artifacts (Silhouette, FeatureFaceCurvature, PointSampleTriangleGeometry), legacy 'Data Container' wording (NearestPointFuseRegularGrids, RemoveFlaggedVertices, ExtractInternalSurfaces), and many bold-only filter mentions. + +### Tier 1 — Critical + +| Filter | Plugin | Status | +|--------|--------|--------| +| FlyingEdges3D | SimplnxCore | Done | +| TriangleDihedralAngle | SimplnxCore | Done | +| NearestPointFuseRegularGrids | SimplnxCore | Done | +| PointSampleEdgeGeometry | SimplnxCore | Done | + +- [x] **FlyingEdges3DFilter** (SimplnxCore) + - **Changes Made:** Expanded the one-sentence stub: added 'What is an Isosurface?' (contour-line analogy, isovalue), noted Flying Edges is a fast marching-cubes variant, added 'When to Use' contrasting with Surface Nets / Quick Surface Mesh for label maps, documented the Contour Value units (same as the data array) and Required Input Sources (Image Geometry + scalar array). Captioned the figure. + +- [x] **TriangleDihedralAngleFilter** (SimplnxCore) + - **Changes Made:** Replaced the 'matrix mathematics' stub with a plain explanation of the minimum interior angle as a mesh-quality metric (60 deg = equilateral, near-0 deg = sliver). Stated output units are degrees (0-60). Added Required Input Sources (Triangle Geometry from a surface-meshing filter). + +- [x] **NearestPointFuseRegularGridsFilter** (SimplnxCore) + - **Changes Made:** Replaced all legacy 'Data Container' terminology with Image Geometry. Explained Reference (destination) vs Sampling (source) roles, that assignment is by nearest cell-center using each grid's origin/spacing (no interpolation), and that the grids may differ in spacing/extent. Documented the Use Custom Fill Value behavior for out-of-overlap cells. Added Required Input Sources (the two Image Geometries). + +- [x] **PointSampleEdgeGeometryFilter** (SimplnxCore) + - **Changes Made:** Added the missing Group header (Sampling (Geometry)). Defined Edge Geometry, 'scan vector' (an additive-manufacturing laser-path segment), and 'edge ID'. Stated the Sampling Spacing units are millimeters and explained Cumulative Sample Distance. Added Required Input Sources (Edge Geometry from Slice Triangle Geometry / Create AM Scan Paths). + +### Tier 2 — Important + +| Filter | Plugin | Status | +|--------|--------|--------| +| ComputeArrayStatistics | SimplnxCore | Done | +| ComputeBoundingBoxStats | SimplnxCore | Done | +| ComputeVolumeFractions | SimplnxCore | Done | +| ComputeFeatureClustering | SimplnxCore | Done | +| ComputeBoundaryElementFractions | SimplnxCore | Done | +| ComputeEuclideanDistMap | SimplnxCore | Done | +| ComputeMomentInvariants2D | SimplnxCore | Done | +| ComputeKMeans | SimplnxCore | Done | +| ComputeKMedoids | SimplnxCore | Done | +| Silhouette | SimplnxCore | Done | +| ApproximatePointCloudHull | SimplnxCore | Done | +| MapPointCloudToRegularGrid | SimplnxCore | Done | +| IterativeClosestPoint | SimplnxCore | Done | +| IdentifyDuplicateVertices | SimplnxCore | Done | +| ComputeTriangleAreas | SimplnxCore | Done | +| ComputeTriangleGeomCentroids | SimplnxCore | Done | +| ComputeTriangleGeomVolumes | SimplnxCore | Done | +| TriangleCentroid | SimplnxCore | Done | +| TriangleNormal | SimplnxCore | Done | +| FeatureFaceCurvature | SimplnxCore | Done | +| SharedFeatureFace | SimplnxCore | Done | +| SurfaceNets | SimplnxCore | Done | +| LaplacianSmoothing | SimplnxCore | Done | +| UncertainRegularGridSampleSurfaceMesh | SimplnxCore | Done | +| ExtractInternalSurfacesFromTriangleGeometry | SimplnxCore | Done | +| ReverseTriangleWinding | SimplnxCore | Done | +| VerifyTriangleWinding | SimplnxCore | Done | +| RemoveFlaggedEdges | SimplnxCore | Done | +| RemoveFlaggedTriangles | SimplnxCore | Done | +| CropVertexGeometry | SimplnxCore | Done | +| CombineNodeBasedGeometries | SimplnxCore | Done | +| PointSampleTriangleGeometry | SimplnxCore | Done | +| ExtractFeatureBoundaries2D | SimplnxCore | Done | +| RobustAutomaticThreshold | SimplnxCore | Done | +| ComputeVectorColors | SimplnxCore | Done | + +- [x] **ComputeArrayStatisticsFilter** (SimplnxCore) + - **Changes Made:** Fixed the stale group to 'Statistics'; defined Feature/Ensemble; condensed the redundant Ranges Breakdown Options 1-4; fixed spelling (aproiri/achived/occurance/exisitng); added Required Input Sources (Feature Ids producer). Kept the statistic-type table. + +- [x] **ComputeBoundingBoxStatsFilter** (SimplnxCore) + - **Changes Made:** Converted the legacy @ref directive and the Compute Array Statistics / Compute Feature Bounding Boxes mentions to MyST links; explained the 1-to-many cell-to-box mapping; stated bounds are in physical coordinate units; fixed 'columns'->'tuples'; added Required Input Sources. + +- [x] **ComputeVolumeFractionsFilter** (SimplnxCore) + - **Changes Made:** Reconciled the count-vs-volume-fraction wording (equal-volume cells make them identical); stated output is a per-Ensemble dimensionless fraction in [0,1] summing to 1; added Required Input Sources (Cell Phases); removed the empty Example Pipelines. + +- [x] **ComputeFeatureClusteringFilter** (SimplnxCore) + - **Changes Made:** Defined RDF (normalized histogram of inter-centroid distances) and Ensemble; added when/why (clustering/ordering detection, >1 vs <1 interpretation); stated distances are physical length units; added Required Input Sources (Compute Feature Centroids + Phases). + +- [x] **ComputeBoundaryElementFractionsFilter** (SimplnxCore) + - **Changes Made:** Defined a 'surface element' (one whose Surface Elements input value > 0); stated output is a [0,1] fraction (boundary/total per Feature); added Required Input Sources (Feature Ids + Surface Elements); removed the empty Example Pipelines. + +- [x] **ComputeEuclideanDistMapFilter** (SimplnxCore) + - **Changes Made:** Defined Feature boundary/GB, triple line/TJ, quadruple point/QP; stated the Manhattan output is an integer cell count and the Euclidean output is a physical float distance; added Required Input Sources (Feature Ids). + +- [x] **ComputeMomentInvariants2DFilter** (SimplnxCore) + - **Changes Made:** Added a plain-language definition of 2D moment invariants and what high/low Omega-1/Omega-2 indicate; stated Omega values dimensionless and Z Delta in cells; fixed typos (appllication/particales/'et. al'); fixed the missing newline before the citations; added Required Input Sources (Feature Ids + Feature Rect). + +- [x] **ComputeKMeansFilter** (SimplnxCore) + - **Changes Made:** Defined cluster/centroid/Voronoi tessellation/within-cluster variance; fixed the broken 'Ensemble Attribute Matrix' bold and typos (randomnes, tesselation); added MyST links to Compute K Medoids/DBSCAN/Silhouette and Required Input Sources. + +- [x] **ComputeKMedoidsFilter** (SimplnxCore) + - **Changes Made:** Defined cluster/Voronoi/topology (kept the good medoid definition); fixed the broken bold and typos (randomnes, arbirtary); added MyST links to Compute K Means/DBSCAN/Silhouette and Required Input Sources. + +- [x] **SilhouetteFilter** (SimplnxCore) + - **Changes Made:** Converted the Doxygen math delimiters to MyST $$/$ math; stated the output array location and dimensionless [-1,1] range; added MyST links to Compute K Means/K Medoids and Required Input Sources. + +- [x] **ApproximatePointCloudHullFilter** (SimplnxCore) + - **Changes Made:** Fixed typos (of/or, hve, To/The, 'is able of', 'faster that'); added Parameter Guidance stating grid resolution is in the point cloud's coordinate units and the empty-neighbor threshold is a 0-26 count; added Required Input Sources. + +- [x] **MapPointCloudToRegularGridFilter** (SimplnxCore) + - **Changes Made:** Added a downstream link to Interpolate Point Cloud to Regular Grid; stated Manual-mode dimensions are voxel counts; fixed the uint64-max off-by-one and the 'User may to trace' grammar; added Required Input Sources. + +- [x] **IterativeClosestPointFilter** (SimplnxCore) + - **Changes Made:** Fixed the all-'1.' list to 1-6 and the trailing-period heading; stated the output is a row-major flattened 4x4 transform (translation in coordinate units), reported always but applied only when the apply-transform option is on; cross-linked Apply Transformation to Geometry; added Required Input Sources (two Vertex Geometries). + +- [x] **IdentifyDuplicateVerticesFilter** (SimplnxCore) + - **Changes Made:** Defined 'duplicate' as all-three-coordinate equality within machine epsilon (no user tolerance); reworded the 'visual explanation' claim (the example is text); converted the italic RemoveFlaggedVertices to a MyST link; fixed the 'this filters output' apostrophe. + +- [x] **ComputeTriangleAreasFilter** (SimplnxCore) + - **Changes Made:** Defined Triangle Geometry; added when/why (mesh quality, statistic weighting); stated output area units (length^2); added Required Input Sources. + +- [x] **ComputeTriangleGeomCentroidsFilter** (SimplnxCore) + - **Changes Made:** Defined Feature/Face Labels ('owners')/nodes; stated centroid coordinate units; documented the -1 exterior-label edge case; added Required Input Sources (Triangle Geometry + Face Labels); removed the empty Example Pipelines. + +- [x] **ComputeTriangleGeomVolumesFilter** (SimplnxCore) + - **Changes Made:** Defined Feature/Face Labels/winding; added a watertight-requirement note; stated volume units (length^3); added Required Input Sources (closed Triangle Geometry + Face Labels); removed the empty Example Pipelines. + +- [x] **TriangleCentroidFilter** (SimplnxCore) + - **Changes Made:** Added when/why; stated centroid coordinate units; cross-linked the per-Feature Compute Feature Centroids from Triangle Geometry to disambiguate (this is per-triangle); added Required Input Sources. + +- [x] **TriangleNormalFilter** (SimplnxCore) + - **Changes Made:** Stated the output is a dimensionless unit 3-vector whose direction depends on winding; defined normal/cross-product/winding; fixed 'vertexes'->'vertices'; added Required Input Sources. + +- [x] **FeatureFaceCurvatureFilter** (SimplnxCore) + - **Changes Made:** Removed the stray @image latex Doxygen line; fixed the missing-space bold; replaced the Google-Groups mailing-list footer with the standard DREAM3D-NX Help footer; converted the bold Parameter-Notes filter mentions to a MyST-linked Required Input Sources list; defined curvature; stated units (principal/mean 1/length, Gaussian 1/length^2, directions dimensionless). + +- [x] **SharedFeatureFaceFilter** (SimplnxCore) + - **Changes Made:** Added a prose explanation of the Randomize Face IDs parameter (visualization-only ID permutation); defined Feature/Face Labels/Feature Attribute Matrix; added Required Input Sources (Triangle Geometry + Face Labels). + +- [x] **SurfaceNetsFilter** (SimplnxCore) + - **Changes Made:** Fixed typos (mush/equivelent/Traingle/FaceLables); converted the Verify Triangle Winding and QuickMesh mentions to MyST links; defined isosurface/marching cubes/triple line/winding; stated units (iterations dimensionless, max distance physical length); added Required Input Sources (Image Geometry + Feature Ids); fixed the non-standard footer. + +- [x] **LaplacianSmoothingFilter** (SimplnxCore) + - **Changes Made:** Fixed the corrupted ref [1] author and the malformed Belyaev URL; removed the dangling 'visit the tutorial' line; added alt text to the equation images; cross-linked Hierarchical Smoothing; stated Iteration Steps as a count and lambda/mu as dimensionless; added Required Input Sources (Triangle Geometry + Node Type). + +- [x] **UncertainRegularGridSampleSurfaceMeshFilter** (SimplnxCore) + - **Changes Made:** Defined Cells/rectilinear grid/conformal mesh/Feature; stated uncertainty and resolution/origin values are physical lengths; cross-linked the non-uncertain sibling; added Required Input Sources (Triangle Geometry + Face Labels). + +- [x] **ExtractInternalSurfacesFromTriangleGeometryFilter** (SimplnxCore) + - **Changes Made:** Fixed the two unclosed '**Vertex' bolds; replaced legacy 'Data Container' with 'data group'; added the missing DREAM3D-NX Help footer; cross-linked the Node Type producers (Surface Nets / Quick Surface Mesh); added Required Input Sources. + +- [x] **ReverseTriangleWindingFilter** (SimplnxCore) + - **Changes Made:** Defined 'winding' (vertex ordering that sets normal direction); cross-linked Verify Triangle Winding and Compute Triangle Normals; added Required Input Sources; removed the empty Example Pipelines. + +- [x] **VerifyTriangleWindingFilter** (SimplnxCore) + - **Changes Made:** Converted all bold/italic filter mentions to MyST links; defined 'winding' and 'negative volume'; fixed typos (Traingle/addtionally/preform/untounched/'difference n output'/Zero's/convience); reconciled the group to 'Surface Meshing (Connectivity/Arrangement)'; added Required Input Sources. + +- [x] **RemoveFlaggedEdgesFilter** (SimplnxCore) + - **Changes Made:** Defined Edge Geometry and 'mask'; fixed the group to 'Surface Meshing (Cleanup)'; added Required Input Sources (mask producer); fixed the footer /discussions link. + +- [x] **RemoveFlaggedTrianglesFilter** (SimplnxCore) + - **Changes Made:** Fixed the Vertices->Triangles copy-paste error; defined Triangle Geometry/Face Data/mask; fixed the group to 'Surface Meshing (Cleanup)'; added Required Input Sources; corrected the example-pipeline name. + +- [x] **CropVertexGeometryFilter** (SimplnxCore) + - **Changes Made:** Expanded the thin doc; stated Min/Max are physical coordinates (not cell indices) with inclusive bounds; replaced the stale 'DREAM3D Review (Cropping/Cutting)' group with 'Geometry (Cropping/Cutting)'; cross-linked Crop Edge/Image Geometry; added Required Input Sources and the missing footer. + +- [x] **CombineNodeBasedGeometriesFilter** (SimplnxCore) + - **Changes Made:** Defined node-based and higher/lower-order geometry; clarified vertex-index renumbering and that duplicate vertices are NOT merged; set the group to 'Core (Combining)'; added Required Input Sources. + +- [x] **PointSampleTriangleGeometryFilter** (SimplnxCore) + - **Changes Made:** Added descriptive alt text to the equation PNGs (corrected to the actual barycentric sqrt form); fixed 'beloning'; removed a stale sample-count table that no longer matches the parameter; added a random-sampling/seed note; fixed the stale 'DREAM3D Review (Geometry)' group to 'Sampling (Geometry)'; added Required Input Sources. + +- [x] **ExtractFeatureBoundaries2DFilter** (SimplnxCore) + - **Changes Made:** Defined Feature IDs/Image Geometry/Edge Geometry/overscan; fixed '.d3dpipline'->'.d3dpipeline'; replaced the stale subgroup with 'Surface Meshing (Generation)'; converted bold filter mentions to MyST links; added image alt text and Required Input Sources. + +- [x] **RobustAutomaticThresholdFilter** (SimplnxCore) + - **Changes Made:** Fixed the stale group to 'Threshold'; stated the robust/automatic rationale up front; defined gradient magnitude / 2-norm; replaced the suspect a_i*g_i/g_i equation with a prose weighted-average description; replaced the nonexistent 'Find Derivatives' reference with the real gradient-magnitude producer (ITK Gradient Magnitude Image Filter) as a MyST link and Required Input Sources. + +- [x] **ComputeVectorColorsFilter** (SimplnxCore) + - **Changes Made:** Expanded the description: input is a 3-component float32 vector Cell array, output is uint8 RGB (0-255), each vector is normalized (direction only); documented the mask/bad-voxel behavior; added Required Input Sources. + +### Tier 3 — Polish + +| Filter | Plugin | Status | +|--------|--------|--------| +| ComputeArrayHistogram | SimplnxCore | Done | +| ComputeArrayHistogramByFeature | SimplnxCore | Done | +| ComputeDifferencesMap | SimplnxCore | Done | +| ComputeNumFeatures | SimplnxCore | Done | +| ComputeSurfaceAreaToVolume | SimplnxCore | Done | +| ComputeFeaturePhases | SimplnxCore | Done | +| ComputeFeaturePhasesBinary | SimplnxCore | Done | +| ComputeFeatureBounds | SimplnxCore | Done | +| ComputeFeatureCentroids | SimplnxCore | Done | +| ComputeFeatureRect | SimplnxCore | Done | +| ComputeLargestCrossSections | SimplnxCore | Done | +| ComputeCoordinateThreshold | SimplnxCore | Done | +| DBSCAN | SimplnxCore | Done | +| InterpolatePointCloudToRegularGrid | SimplnxCore | Done | +| ExtractVertexGeometry | SimplnxCore | Done | +| ComputeVertexToTriangleDistances | SimplnxCore | Done | +| LabelTriangleGeometry | SimplnxCore | Done | +| HierarchicalSmooth | SimplnxCore | Done | +| RegularGridSampleSurfaceMesh | SimplnxCore | Done | +| SliceTriangleGeometry | SimplnxCore | Done | +| RemoveFlaggedVertices | SimplnxCore | Done | +| CropEdgeGeometry | SimplnxCore | Done | +| CombineStlFiles | SimplnxCore | Done | +| MultiThresholdObjects | SimplnxCore | Done | +| CreateColorMap | SimplnxCore | Done | +| ChangeAngleRepresentation | SimplnxCore | Done | +| RandomizeFeatureIds | SimplnxCore | Done | +| ExecuteProcess | SimplnxCore | Done | +| CreatePythonSkeleton | SimplnxCore | Done | +| ExtractPipelineToFile | SimplnxCore | Done | +| CreateAMScanPaths | SimplnxCore | Done | + +- [x] **ComputeArrayHistogramFilter** (SimplnxCore) + - **Changes Made:** Trimmed the long raw 'Old Faithful' data dump; defined 'mode' on first use; stated bin bounds inherit the input array units; added Required Input Sources (None). + +- [x] **ComputeArrayHistogramByFeatureFilter** (SimplnxCore) + - **Changes Made:** Defined Feature/Feature Id; added Required Input Sources (Feature Ids producer); removed the empty Example Pipelines. + +- [x] **ComputeDifferencesMapFilter** (SimplnxCore) + - **Changes Made:** Stated the output inherits the input type/shape/location; added a brief Required Input Sources (None -- generic arrays); removed the empty Example Pipelines. + +- [x] **ComputeNumFeaturesFilter** (SimplnxCore) + - **Changes Made:** Defined Ensemble/phase; stated the output is a per-Ensemble count array; added Required Input Sources (Compute Feature Phases). + +- [x] **ComputeSurfaceAreaToVolumeFilter** (SimplnxCore) + - **Changes Made:** Defined 'aliasing'; stated the ratio units (1/length) and that sphericity is dimensionless; linked Compute Boundary Cells; added Required Input Sources (Feature Ids). + +- [x] **ComputeFeaturePhasesFilter** (SimplnxCore) + - **Changes Made:** Defined Feature/Ensemble/Element; stated the per-Feature phase output; added Required Input Sources (Feature Ids + Cell Phases). + +- [x] **ComputeFeaturePhasesBinaryFilter** (SimplnxCore) + - **Changes Made:** Added a generic non-materials framing; stated the boolean-mask input and binary Ensemble output; added Required Input Sources (Multi-Threshold Objects); removed the empty Example Pipelines. + +- [x] **ComputeFeatureBoundsFilter** (SimplnxCore) + - **Changes Made:** Stated bounds are physical coordinates (not cell indices); fixed the 'Dimesions' typo and the doubled ';;'; defined Feature/Cell; added Required Input Sources (Feature Ids). + +- [x] **ComputeFeatureCentroidsFilter** (SimplnxCore) + - **Changes Made:** Stated centroids are physical coordinates (3-component float32, not pixel indices); defined Feature/Cell; added Required Input Sources (Feature Ids). + +- [x] **ComputeFeatureRectFilter** (SimplnxCore) + - **Changes Made:** Fixed 'This values'->'These values'; clarified Pixel coords are zero-based voxel indices; cross-linked Compute Feature Bounding Boxes; added Required Input Sources. + +- [x] **ComputeLargestCrossSectionsFilter** (SimplnxCore) + - **Changes Made:** Stated the area is square physical units (cellCount x in-plane voxel area, confirmed from the cpp); described the per-feature float32 output; added Required Input Sources (Feature Ids). + +- [x] **ComputeCoordinateThresholdFilter** (SimplnxCore) + - **Changes Made:** Converted the prose Remove Flagged Vertices/Edges/Triangles mentions to MyST links; stated the rectangle min/max and sphere center/radius are physical coordinate units. + +- [x] **DBSCANFilter** (SimplnxCore) + - **Changes Made:** Converted eight bold/quoted inter-filter mentions to MyST links; fixed typos (sqaure_root, preforming/preform, 'vise versa'); added Required Input Sources. + +- [x] **InterpolatePointCloudToRegularGridFilter** (SimplnxCore) + - **Changes Made:** Converted the italic Map Point Cloud to Regular Grid to a MyST link; added Required Input Sources (Vertex Geometry producer). + +- [x] **ExtractVertexGeometryFilter** (SimplnxCore) + - **Changes Made:** Standardized the Rectilinear Grid / Vertex Geometry naming; added Required Input Sources. + +- [x] **ComputeVertexToTriangleDistancesFilter** (SimplnxCore) + - **Changes Made:** Fixed the 4x 'Geoemtry' typo; stated distance units (length unit); noted normals must be present/consistent for sign correctness; added Required Input Sources (Vertex + Triangle Geometry). + +- [x] **LabelTriangleGeometryFilter** (SimplnxCore) + - **Changes Made:** Added Required Input Sources with a note that STL is a common CAD mesh format; fixed the footer /discussions link. + +- [x] **HierarchicalSmoothFilter** (SimplnxCore) + - **Changes Made:** Removed the hand-written Parameters table (it duplicated the auto-table), replacing it with prose; added a MyST link to Laplacian Smoothing; added Required Input Sources; normalized the non-standard footer; removed the empty Example Pipelines. + +- [x] **RegularGridSampleSurfaceMeshFilter** (SimplnxCore) + - **Changes Made:** Stated Origin/Spacing physical units and Dimensions as voxel counts; cross-linked the Uncertain variant; added Required Input Sources (Triangle Geometry + Face Labels). + +- [x] **SliceTriangleGeometryFilter** (SimplnxCore) + - **Changes Made:** Fixed typos (geoemtry, bewteen, perimieter); stated Slice Spacing/range/area/perimeter are in the geometry's physical units; added Required Input Sources. + +- [x] **RemoveFlaggedVerticesFilter** (SimplnxCore) + - **Changes Made:** Replaced legacy 'Data Container' wording with NX terminology; added Required Input Sources (the boolean-mask producer). + +- [x] **CropEdgeGeometryFilter** (SimplnxCore) + - **Changes Made:** Added the missing Group header (Core (Conversion)); stated Min/Max are physical units, not indices; removed the empty Example Pipelines; cross-linked Crop Geometry (Image). + +- [x] **CombineStlFilesFilter** (SimplnxCore) + - **Changes Made:** Defined STL on first use; converted the bold Import/Write STL mentions to MyST links. + +- [x] **MultiThresholdObjectsFilter** (SimplnxCore) + - **Changes Made:** Defined Cell/Attribute Matrix/EBSD context; added Required Input Sources naming EBSD readers as typical producers; removed the empty Example Pipelines. + +- [x] **CreateColorMapFilter** (SimplnxCore) + - **Changes Made:** Added the missing Group header (Core (Image)); added Required Input Sources (scalar array + optional mask); noted the preset table is hand-maintained; removed the empty Example Pipelines; fixed the License line. + +- [x] **ChangeAngleRepresentationFilter** (SimplnxCore) + - **Changes Made:** Added a Required Input Sources one-liner naming EBSD readers as typical angle producers (units content already exemplary). + +- [x] **RandomizeFeatureIdsFilter** (SimplnxCore) + - **Changes Made:** Defined Feature Ids/Attribute Matrix/NeighborList; documented that the cpp exposes no seed parameter (not reproducible); added Required Input Sources; fixed the License line. + +- [x] **ExecuteProcessFilter** (SimplnxCore) + - **Changes Made:** Stated the absolute-path requirement; documented the Should Block / Timeout (ms) parameters; added an explicit Required Input Sources: None. + +- [x] **CreatePythonSkeletonFilter** (SimplnxCore) + - **Changes Made:** Removed the hand-written Configuration parameter list and ADDED the missing auto-table marker; added the missing Group header (Core (Generation)); added Required Input Sources: None. + +- [x] **ExtractPipelineToFileFilter** (SimplnxCore) + - **Changes Made:** Added the missing Group header (IO (Output)) and the missing DREAM3D-NX Help footer; noted the no-embedded-pipeline behavior; added Required Input Sources: None; fixed the License line. + +- [x] **CreateAMScanPathsFilter** (SimplnxCore) + - **Changes Made:** Added a Units section (Hatch Spacing/Length in geometry coordinate units, Hatch Rotation Angle in degrees per the cpp label); converted the quoted SliceTriangleGeometry to a MyST link and promoted it to Required Input Sources. + +### Tier 4 — Adequate + +| Filter | Plugin | Status | +|--------|--------|--------| +| ComputeFeatureSizes | SimplnxCore | Done | +| ComputeBoundaryCells | SimplnxCore | Done | +| ComputeGroupingDensity | SimplnxCore | Done | + +- [x] **ComputeFeatureSizesFilter** (SimplnxCore) + - **Changes Made:** Added Required Input Sources (Feature Ids from a segmentation filter). Otherwise adequate as triaged. + +- [x] **ComputeBoundaryCellsFilter** (SimplnxCore) + - **Changes Made:** Stated the output range 0-6 and volume-edge handling; added Required Input Sources (Feature Ids). Otherwise adequate. + +- [x] **ComputeGroupingDensityFilter** (SimplnxCore) + - **Changes Made:** Converted the quoted 'Compute Feature Neighborhoods' to a MyST link (and fixed the dangling quote); added Required Input Sources (Parent IDs, neighbor lists, Feature Volumes). Otherwise model-quality. + +--- + +## Real-World Visualization Wishlist + +These are pipeline-generated screenshots/visualizations that would enhance the documentation but require DREAM3DNX automation tooling (future work). + +| Filter | Desired Visualization | Priority | +|--------|----------------------|----------| +| ComputeAvgCAxes | IPF color map showing C-axis orientations per grain | Medium | +| ComputeCAxisLocations | C-axis direction map colored by orientation | Medium | +| ComputeGBCD | GBCD pole figure output from Write GBCD Pole Figure filter | High | +| ComputeSchmids | Microstructure colored by Schmid factor under a loading direction | High | +| ComputeKernelAvgMisorientations | KAM map showing orientation gradients within grains | High | +| ComputeAvgOrientations | IPF color map showing average orientation assignment per grain | Medium | +| ComputeFeatureReferenceMisorientations | Color scale legend for existing images; additional loading conditions | Low | +| ComputeShapes | Features colored by aspect ratio or Omega3 value | Medium | +| ComputeTwinBoundaries | Microstructure with twin boundaries highlighted and incoherence heat map | Medium | +| ComputeSlipTransmissionMetrics | Feature pairs with high vs low transmission metrics visualized | Medium | +| ComputeBoundaryStrengths | Boundary mesh colored by M' or fip values | Medium | +| AlignSectionsFeatureCentroid | Before/after comparison showing when centroid alignment is appropriate vs when it fails (e.g., sample with consistent vs inconsistent mask regions) | High | +| AlignSectionsMisorientation | Before/after slice alignment showing corrected vs uncorrected sections; side-by-side comparison of alignment with mask vs without mask showing when masking is needed (e.g., sample with mounting material or voids at edges) | High | +| AlignSectionsMutualInformation | Before/after alignment comparison; side-by-side with misorientation method | Medium | +| AlignSectionsList | Typical workflow showing shift output from another alignment filter used as input | Low | +| ITKNormalizeImage | Before/after images showing normalization effect with parameters used to generate result | High | +| ITKRescaleIntensityImage | Before/after images showing rescaling effect with parameters used to generate result | High | +| ScalarSegmentFeatures | Before/after FeatureIds map from a scalar-based segmentation (e.g., image-quality thresholding) | Medium | +| CAxisSegmentFeatures | Before/after segmentation on hexagonal (e.g., Ti) EBSD data | Medium | +| EBSDSegmentFeatures | EBSD IPF map → segmented grains visualization (flagship EBSD workflow) | High | +| MergeTwins | Before/after microstructure showing twin variants merged into parent grain | High | +| IdentifySample | Before/after showing overscan cleanup on a real FIB-SEM dataset | Low | +| RequireMinimumSizeFeatures | Before/after microstructure with minimum-size filter applied | Medium | +| RemoveFlaggedFeatures | Side-by-side comparison of Remove vs Extract vs Extract-then-Remove operation modes | Medium | +| ComputeFeatureNeighbors | Grain map colored by number of neighbors | Medium | +| AddBadData | Synthetic structure before and after random noise; same with boundary noise | High | +| FillBadData | Conceptual diagram: small defects (filled) vs large defects (preserved) at threshold | Medium | +| ErodeDilateBadData | Multi-frame iteration sequence diagram (iter 0 → 3) for both erode and dilate | High | +| ErodeDilateBadData | Erode-then-dilate ("opening") removing isolated single-cell noise but preserving a larger pore | Medium | +| ErodeDilateMask | Directional erosion (X-only vs uniform) on a mask | Medium | +| ErodeDilateCoordinationNumber | 3x3x3 cell cluster diagram with coordination numbers labeled (CN=6 isolated, CN=3 edge, etc.) | High | +| ReplaceElementAttributesWithNeighborValues | Conceptual diagram: flagged cell + neighbors with chosen replacement highlighted by max/min | Medium | +| NeighborOrientationCorrelation | Cell-with-6-neighbors diagram showing Cleanup Level=2,4,6 outcomes side by side | High | +| BadDataNeighborOrientationCheck | Voxel-and-neighbors diagram showing the false→true flip when criterion is met | Medium | +| RequireMinNumNeighbors | Microstructure before/after with isolated low-neighbor-count grains absorbed | Medium | +| ComputeNeighborhoods | Histogram of neighborhood counts for a real microstructure | Low | +| ComputeNeighborListStatistics | Example feature with its neighbor-misorientation list and computed statistics | Low | +| CreateGeometry | Side-by-side infographic of all 8 geometry types (Image, RectGrid, Vertex, Edge, Triangle, Quad, Tet, Hex) | High | +| CreateImageGeometry / SetImageGeomOriginScaling | Image Geometry dimensions/origin/spacing diagram (shared concept) | High | +| ApplyTransformationToGeometry | Axis-angle representation diagram | Medium | +| RotateSampleRefFrame | Sample frame rotation vs geometric rotation comparison | High | +| ResampleImageGeom | Before/after voxel grid showing 2x spacing reduction halving cell count | Medium | +| ResampleRectGridToImageGeom | Variable-spacing RectGrid → uniform Image Geom with "last one wins" cells highlighted | Medium | +| CropImageGeometry | Already adequate | - | +| PadImageGeometry | 3-panel diagram showing Update Origin ON vs OFF | Medium | +| AppendImageGeometry | Already comprehensive | - | +| QuickSurfaceMesh | Single voxel face → 2 triangles diagram | Low | +| PartitionGeometry | Already excellent | - | +| InitializeImageGeomCellData | Subvolume highlight before/after on real cube | Medium | +| CombineTransformationMatrices | Two 4x4 matrices multiplying into a single result | Low | +| ComputeCoordinatesImageGeom | Voxel grid with one cell highlighted showing (i,j,k) and (x,y,z) | Low | +| ReadImageStack | N 2D slices stacking into a 3D volume (Z = slice count) | Medium | +| ReadHDF5Dataset | Flat HDF5 dataset (N elements) reshaped into tuples x components | Medium | +| ReadStlFile | One triangle (normal + 3 vertices); many triangles forming a surface mesh | Low | +| ReadVtkStructuredPoints | Voxel cube showing cell-center value vs 8 corner (point) values | Medium | +| ReadH5Ebsd / ReadAng / ReadCtf | Sample vs crystal reference-frame diagram (why a rotation is needed); IPF map of freshly imported data | High | +| WriteAbaqusHexahedron | Image-geometry voxel grid mapping to a hexahedral element mesh (8 nodes per voxel) | Medium | +| WriteGBCDGMTFile | Data-flow: Compute GBCD -> Write GBCD GMT File -> .dat -> GMT -> rendered pole figure | High | +| WriteGBCDTriangleData | Boundary triangle: two grains, left/right average orientations, normal vector, area | Medium | +| WritePoleFigure | Stereographic/Lambert projection: 3D orientation/pole projected onto the 2D unit circle | High | +| WriteVtkRectilinearGrid / WriteVtkStructuredPoints | Rectilinear grid (variable spacing) vs structured points (uniform spacing) side by side | Medium | +| ReadDREAM3D | Import-data tree selector UI showing partial-import checkboxes | Medium | + +--- + +## Concept Pages Needed (Future Work) + +Domain concepts that appear across 3+ filters and should eventually become shared reference pages: + +| Concept | Filters That Need It | +|---------|---------------------| +| C-Axis / Hexagonal Crystals | ComputeAvgCAxes, ComputeCAxisLocations, ComputeFeatureNeighborCAxisMisalignments, ComputeFeatureReferenceCAxisMisorientations | +| Quaternions & Orientation Representations | ComputeAvgCAxes, ComputeAvgOrientations, ComputeCAxisLocations, ConvertOrientations | +| Misorientation | ComputeKernelAvgMisorientations, ComputeFeatureNeighborMisorientations, ComputeFeatureReferenceMisorientations, ComputeGBCD | +| Slip Systems & Crystal Plasticity | ComputeSchmids, ComputeSlipTransmissionMetrics, ComputeBoundaryStrengths | +| Grain Boundaries | ComputeGBCD, ComputeGBCDMetricBased, ComputeGBPDMetricBased, ComputeTwinBoundaries | +| Feature IDs & Grains | Nearly all filters | +| Reference Frames (Sample vs Crystal) | ComputeAvgCAxes, ComputeCAxisLocations, ComputeSchmids | +| Burn Algorithm / Segmentation | ScalarSegmentFeatures, CAxisSegmentFeatures, EBSDSegmentFeatures | +| Feature Cleanup / Isotropic Coarsening | RequireMinimumSizeFeatures, RemoveFlaggedFeatures | +| Cell vs Feature vs Ensemble Data | ScalarSegmentFeatures, RequireMinimumSizeFeatures, ComputeFeatureNeighbors, and most feature-level filters | +| Morphological Erosion / Dilation / Opening | ErodeDilateBadData, ErodeDilateMask, ErodeDilateCoordinationNumber | +| Coordination Number / Face Neighbors | ErodeDilateCoordinationNumber, NeighborOrientationCorrelation, BadDataNeighborOrientationCheck | +| Equivalent Sphere Diameter | ComputeFeatureSizes, ComputeNeighborhoods, ComputeShapes | +| Geometry Types (Image, RectGrid, Vertex, Edge, Triangle, Quad, Tet, Hex) | CreateGeometry, CreateImageGeometry, and every geometry-aware filter | +| Transformation Matrices (4x4 row-major) | ApplyTransformationToGeometry, CombineTransformationMatrices, RotateSampleRefFrame | +| Sample Reference Frame vs Crystal Reference Frame | RotateSampleRefFrame (already listed above) | +| HDF5 File Format (datasets, groups, tuples vs components) | ReadHDF5Dataset, ReadDREAM3D, WriteDREAM3D, ReadH5Ebsd, ReadH5Esprit, ReadH5Oim, ReadH5Oina, ReadGrainMapper3D | +| VTK Legacy Formats (structured points vs rectilinear grid; ASCII vs binary) | ReadVtkStructuredPoints, WriteVtkStructuredPoints, WriteVtkRectilinearGrid | +| EBSD Vendor File Formats & What They Contain (Euler angles, CI/IQ/MAD, phases) | ReadAngData, ReadCtfData, ReadChannel5Data, ReadH5Ebsd, ReadH5EspritData, ReadH5OimData, ReadH5OinaData | +| External Simulation Exporters (FEA / MD / KMC / FFT input files) | WriteAbaqusHexahedron, WriteLAMMPSFile, WriteSPParksSites, WriteLosAlamosFFT, ReadDeformKeyFileV12 | +| Pole Figures & Projections (stereographic, Lambert, Laue class) | WritePoleFigure, WriteGBCDGMTFile, ComputeGBCD | diff --git a/docs/filter-figure-style.md b/docs/filter-figure-style.md new file mode 100644 index 0000000000..bd847b5d7b --- /dev/null +++ b/docs/filter-figure-style.md @@ -0,0 +1,109 @@ +# Filter Documentation Figure Style Guide + +Visual style and file conventions for figures generated to support filter documentation. Established during the documentation review project (batches 1+) so that figures across plugins look consistent. Reference palette: `docs/style_palette_final.svg` in this repo. + +## When to Add a Figure + +**Add a figure when:** + +- The filter operates on spatial data and the spatial relationship matters (kernels, neighborhoods, alignment, neighbor counts). +- The filter has a multi-step algorithm that benefits from a flowchart or sequence diagram. +- The filter transforms data in a way easier to show than describe (orientation conversions, geometry operations). +- The filter has parameters whose effect is non-obvious (kernel radius, dilation iterations, coordination number). + +**Skip a figure when:** + +- The filter performs a simple mathematical operation (radians-to-degrees, threshold). +- The filter is a basic I/O operation (read file, write file). +- The filter's behavior is fully captured by its parameter names (delete data, rename data). + +## Font + +``` +'Segoe UI', 'Helvetica Neue', Arial, sans-serif +``` + +| Element | Size | Weight | Color | +|---------|------|--------|-------| +| Figure title | 17-18px | Bold (700) | #2C3E50 | +| Section heading | 14px | Semibold (600) | #2C3E50 | +| Body text | 13px | Regular (400) | #555555 | +| Captions / notes | 11px | Italic | #888888 | + +## Color Palette + +### Primary (Diagram Elements) + +| Role | Color | Hex | Usage | +|------|-------|-----|-------| +| Focus | Dark Blue | #2874A6 | Center cell, primary element, section headers | +| Active | Light Blue | #AED6F1 | Kernel neighbors, included elements | +| Inactive | Light Gray | #E8ECF0 | Outside kernel, excluded elements | + +### Semantic Accents + +| Role | Color | Hex | Usage | +|------|-------|-----|-------| +| Danger / Warning | Red | #E74C3C | Thread-safety warnings, invalid approaches, common mistakes | +| Good / Correct | Green | #27AE60 | Recommended approaches, valid results, correct measurements | +| Annotation | Purple | #8E44AD | Brackets, dimensions, labels, measurements | +| Tip / Highlight | Amber | #E67E22 | Tips, parameters of interest, optional recommendations | + +### Supporting + +| Role | Color | Hex | Usage | +|------|-------|-----|-------| +| Primary text | Dark Slate | #2C3E50 | Headings, primary labels | +| Secondary text | Medium Gray | #5D6D7E | Secondary labels, descriptions | +| Card background | White | #FFFFFF | Figure card background | +| Formula background | Pale Blue | #EBF5FB | Formula / equation highlight boxes | +| Warning background | Pale Red | #FDEDEC | Warning callout box fill | +| Success background | Pale Green | #EAFAF1 | Success callout box fill | +| Annotation background | Pale Purple | #F4ECF7 | Note callout box fill | +| Tip background | Pale Amber | #FEF5E7 | Tip callout box fill | +| Page background | Off-white | #F0F2F5 | Outer page fill (when used) | + +## Callout Boxes + +Four semantic callout box types are available: + +- **Warning (Red)** — `!` icon, #FDEDEC background, #E74C3C border. For dangers and things to watch out for. +- **Good / Correct (Green)** — checkmark icon, #EAFAF1 background, #27AE60 border. For recommended approaches. +- **Note (Purple)** — `i` icon, #F4ECF7 background, #8E44AD border. For general annotations and clarifications. +- **Tip (Amber)** — star icon, #FEF5E7 background, #E67E22 border. For tips and highlights. + +## Section Headers + +Colored bars with white text, using the semantic color that best fits the section content. Default to blue (#2874A6) for neutral sections. + +## File Format and Naming + +- **Author as SVG.** Hand-write or generate the source. +- **Convert to PNG at 2x resolution** using `rsvg-convert -z 2 source.svg -o source.png`. The 2x scale provides a clean appearance on high-DPI displays. +- **Keep both SVG and PNG** in the plugin's `/docs/Images/` directory (e.g., `src/Plugins/OrientationAnalysis/docs/Images/`). +- **Reference the PNG** in the filter documentation markdown, not the SVG. +- **Naming convention:** `_.png`. Examples: + - `ComputeKernelAvgMisorientations_1D_Radius1.png` + - `ComputeAvgCAxes_HexagonalCAxis.png` + - `ComputeSchmids_SchmidFactor.png` + +## Markdown Reference Pattern + +Use the figure caption as the alt text and as a short Fig. N descriptor: + +```markdown +![Fig. 1: The geometric relationship between the tensile axis, slip plane, and slip direction that defines the Schmid factor.](Images/ComputeSchmids_SchmidFactor.png) +``` + +For paired before/after figures, use a 2-column table: + +```markdown +| Before | After | +|----------------------------------|----------------------------------| +| ![](Images/ExampleFilter_1.png) | ![](Images/ExampleFilter_2.png) | +``` + +## Reference SVGs + +- `docs/style_palette_final.svg` — canonical color palette, font, and callout box styles. Open in any SVG viewer to copy colors. +- Existing finished figures in `src/Plugins/OrientationAnalysis/docs/Images/` (especially `ComputeKernelAvgMisorientations_*.svg` and `ComputeAvgCAxes_HexagonalCAxis.svg`) are good reference templates to fork from. diff --git a/docs/style_palette_final.svg b/docs/style_palette_final.svg new file mode 100644 index 0000000000..877e1680cb --- /dev/null +++ b/docs/style_palette_final.svg @@ -0,0 +1,257 @@ + + + + + + + + + + + + + + + + + + DREAM3DNX Figure Style Guide + Option A Refined: Ocean Blues + Semantic Accents + + + + + + + + Color Palette + + + Primary (Focus / Active / Inactive) + + + Focus + #2874A6 + + + Active + #AED6F1 + + + Inactive + #E8ECF0 + + + + Semantic Accents + + + Danger + #E74C3C + + + Good + #27AE60 + + + Annotation + #8E44AD + + + + Supporting + + + Text + #2C3E50 + + + Secondary Text + #5D6D7E + + + Highlight + #E67E22 + + + Backgrounds + + + Card BG + #FFFFFF + + + Formula BG + #EBF5FB + + + Page BG + #F0F2F5 + + + Warning BG + #FDEDEC + + + Success BG + #EAFAF1 + + + + + + + + + Typography + + Figure Title — 17-18px Bold + Section Heading — 14px Semibold + Body text and descriptions — 13px Regular, color #555 + Captions and notes — 11px Italic, color #888 + + Font Stack: + 'Segoe UI', 'Helvetica Neue', Arial, sans-serif + Cross-platform sans-serif with consistent rendering. + + + + + + + + Demo: Conceptual Diagram (Kernel Radius = 1) + + + + + ... + + + + + -1 + + + + Center + + + + +1 + + + + + ... + + + + + + R = 1 + + + + + R = 1 + + + + + + Kernel Size = 3 cells + + + + + + Focus / Center + + Active neighbor + + Outside kernel + + Annotation + + Good / Correct + + Warning / Danger + + + + + + + + + Demo: Semantic Callout Boxes + + + + + ! + Warning / Danger + DataArray is NOT thread-safe for concurrent access. + Writing to different indices from multiple threads may fail. + + + + + + Good / Correct + Use getDataRefAs<T>() when the parameter has + already validated that the object exists. + + + + + i + Note / Annotation + All Cells in the kernel are weighted equally during + averaging, though they are not equidistant from center. + + + + + + Tip / Highlight + Setting Z Radius to 0 restricts the kernel to a + single 2D slice — useful for thin-section data. + + + + + + + + Demo: Formula Box + + + Kernel Size = (2 × Radius) + 1 + + + + + + + + Usage Rules + + + + Blue — Default for all primary diagram elements (focus, active, borders, headers) + + + Purple — General annotations: brackets, dimensions, labels, measurements + + + Green — Positive semantics: correct approach, recommended, valid result + + + Red — Negative semantics: danger, thread-safety warning, common mistake, invalid + + + Amber — Tips, highlights, parameters of interest, optional but recommended + + \ No newline at end of file diff --git a/docs/superpowers/specs/2026-04-12-documentation-review-design.md b/docs/superpowers/specs/2026-04-12-documentation-review-design.md new file mode 100644 index 0000000000..cb5aea99d2 --- /dev/null +++ b/docs/superpowers/specs/2026-04-12-documentation-review-design.md @@ -0,0 +1,327 @@ +# DREAM3DNX Filter Documentation Review — Design Spec + +**Date:** 2026-04-12 +**Scope:** ~295 filter documentation files across SimplnxCore (154), OrientationAnalysis (53), and ITKImageProcessing (88) +**Branch:** Single PR when all batches are complete + +--- + +## 1. Goals + +### Primary Goals + +1. **Clarity for non-domain-experts** — Documentation should be understandable by a general engineer or scientist (audience B) who understands data processing concepts but may not know EBSD, crystallography, or microstructure terminology. +2. **Accessibility for non-native English speakers** — Straightforward language, short sentences, consistent terminology. Avoid idioms and ambiguous phrasing. +3. **Figures where they help** — Add conceptual diagrams for filters where visual explanation meaningfully aids understanding. Not every filter needs a figure (e.g., unit conversion filters don't). +4. **Parameter guidance** — Help users determine if a filter is appropriate for their use case and what parameter values to use. + +### Non-Goals (Future Work) + +- **Documentation architecture consolidation** — The existing concept docs are scattered across `wrapping/python/docs/source/`, `DREAM3DNX/Documentation/Sphinx/source/Concepts/`, and `Downloads/dream3d_infographics/`. Consolidating these into a single canonical location is a future task, not part of this review. +- **Sphinx format migration** — Current filter docs are Markdown. Converting to RST or standardizing format is a future task. +- **Real-world pipeline visualizations** — Pipeline-generated screenshots require DREAM3DNX automation tooling that is still in progress. This review will build a wishlist of desired visualizations, but generating them is a future task. + +--- + +## 2. Target Audience + +**Audience (B): General engineer/scientist** + +- Understands data processing, arrays, filtering, statistics concepts +- May know something about EBSD or have data they want to process +- Looks to DREAM3D to help with processing and needs help figuring out if a filter is appropriate +- May not know crystallography, quaternions, Euler angles, microstructure terminology +- English may not be their primary language + +The documentation should serve both this audience AND domain experts. Domain experts need parameter guidance and edge case documentation; non-experts need conceptual explanations of what the filter does and when to use it. + +--- + +## 3. Review Process + +### Phase 1: Triage Pass + +Claude autonomously reviews all ~295 filter docs and produces a tracker document (`docs/documentation_review_tracker.md`) that categorizes every filter into a priority tier. + +**Triage Rubric — 5 Dimensions:** + +| Dimension | What We're Assessing | +|-----------|---------------------| +| **Clarity** | Can audience (B) understand what the filter does and when to use it? | +| **Completeness** | Are all parameters explained? Are edge cases/caveats documented? | +| **Accessibility** | Is the language straightforward? Are domain terms explained or defined on first use? | +| **Figures Needed** | Would a conceptual diagram meaningfully help understanding? | +| **Real-World Viz** | Would a pipeline-generated screenshot/visualization add value? (wishlist only) | +| **Units Clarity** | Are all numeric parameters (sizes, distances, radii, tolerances, offsets) documented with explicit units (cells/voxels, degrees, physical units, dimensionless)? | + +Additionally, track: +- **Concept Links** — Domain concepts that should link to shared concept pages (e.g., Quaternions, Feature IDs, Image Geometry). When the same concept appears across 3+ filters, that signals a future shared concept page. + +**Priority Tiers:** + +| Tier | Description | Expected Action | +|------|-------------|-----------------| +| **Tier 1 (Critical)** | Domain-heavy filters with sparse or expert-only docs. Non-expert cannot understand what the filter does. | Major rewrite: add conceptual explanation, define terms, add figures | +| **Tier 2 (Important)** | Docs are functional but assume too much domain knowledge, or would clearly benefit from figures. | Moderate rewrite: add context, simplify language, generate figures | +| **Tier 3 (Polish)** | Docs are mostly clear but could benefit from minor language cleanup, consistency, or term definitions. | Light editing: clarify wording, add term definitions inline | +| **Tier 4 (Adequate)** | Docs are already clear, complete, and accessible. Simple utility/I/O filters that don't need more. | No action needed | + +### Phase 2: Batched Rewrites + +After triage, work through filters in batches grouped by functional category (e.g., all alignment filters, all orientation statistics filters). Working by category ensures: + +- Consistent explanations across related filters +- Shared domain concepts identified naturally +- Cross-references between related filters + +**Batch workflow:** + +1. Claude rewrites the batch of filter docs +2. Claude generates any needed conceptual figures (following the style guide) +3. User reviews the changes +4. User commits the batch when satisfied +5. Move to next batch + +All batches accumulate on one branch and are submitted as a single PR when complete. + +### Phase 3: Future Work + +- Consolidate shared concept pages into a canonical location within this repo +- Generate real-world pipeline visualizations using DREAM3DNX automation +- Consider RST migration for consistency with Sphinx build + +--- + +## 4. Tracker Document Format + +The tracker (`docs/documentation_review_tracker.md`) uses a two-level structure: + +**Level 1: Summary tables** — One table per priority tier for quick scanning. + +```markdown +## Tier 1: Critical + +| Filter | Plugin | Category | +|--------|--------|----------| +| ComputeAvgOrientations | OrientationAnalysis | Statistics | +| ConvertOrientations | OrientationAnalysis | Conversion | +``` + +**Level 2: Detailed checklists** — Below the summary tables, a checklist with full details for each filter, organized by tier. + +```markdown +### Tier 1 — Detailed Checklist + +- [ ] **ComputeAvgOrientations** (OrientationAnalysis) + - **Clarity:** Assumes deep quaternion knowledge; no intuitive explanation + - **Figures Needed:** Diagram showing orientations being averaged within a grain + - **Real-World Viz:** IPF color map showing average orientation assignment + - **Concept Links:** Quaternions, Symmetry Operators, Feature/Grain + - **Notes:** Only 36 lines; needs significant expansion + +- [ ] **ConvertOrientations** (OrientationAnalysis) + - **Clarity:** Lists 8 types but doesn't explain when to choose each + - **Figures Needed:** Visual comparison of orientation representations + - **Real-World Viz:** None + - **Concept Links:** Euler Angles, Quaternions, Rodrigues Vectors + - **Notes:** 113 lines but very dense; needs "which should I use?" guidance +``` + +Filters are checked off as their rewrites are completed and committed. + +--- + +## 5. Documentation Rewrite Guidelines + +### Structure for Each Filter Doc + +Every filter doc should follow this structure (scaled to the filter's complexity): + +1. **Title** — Filter name +2. **Group (Subgroup)** — Category classification +3. **Description** — What the filter does in plain language. Lead with the "what" and "when would I use this?" before diving into algorithm details. If domain terms are needed, define them on first use or link to a concept page. +4. **Algorithm Details** (if applicable) — How it works, with figures where they help +5. **Parameter Guidance** (if applicable) — What the parameters mean, what values are typical, how they affect results +6. **Figures** — Conceptual diagrams embedded as PNG images +7. **Auto-generated parameter table** — `% Auto generated parameter table will be inserted here` +8. **Example Pipelines** — Links to relevant pipelines +9. **License & Copyright** +10. **DREAM3D-NX Help** — Link to discussions + +### Writing Style + +- **Short sentences.** Prefer active voice. +- **Define domain terms on first use.** Example: "the misorientation (the angular difference between two crystal orientations)" +- **Lead with purpose.** Start with what the filter does and why someone would use it, not how it works internally. +- **Use "you" sparingly.** Prefer "the filter" or "this operation" for international clarity. +- **Avoid idioms and colloquialisms.** Write for translation-friendliness. +- **Be specific about parameters.** Don't just name them — explain what values are typical and how changing them affects results. +- **Always specify units for numeric parameters.** Any parameter that accepts a size, distance, radius, offset, tolerance, or similar numeric value must clearly state whether the value is in **cell/voxel units** (integer cell counts), **physical units** (micrometers, degrees, etc.), or **dimensionless** (e.g., a direction vector). This is critical for users who may not know whether a "radius of 3" means 3 cells or 3 micrometers. + +### Figure Decision Framework + +**Add a figure when:** +- The filter operates on spatial data and the spatial relationship matters (kernels, neighborhoods, alignment) +- The filter has a multi-step algorithm that benefits from a flowchart or step diagram +- The filter transforms data in a way that's easier to show than describe (orientation conversions, geometry operations) +- The filter has parameters whose effect is non-obvious (kernel radius, dilation distance) + +**Skip a figure when:** +- The filter performs a simple mathematical operation (radians to degrees, threshold) +- The filter is a basic I/O operation (read file, write file) +- The filter's behavior is fully captured by its parameter names (delete data, rename data) + +--- + +## 6. Figure Style Guide + +All generated figures follow a consistent visual style. The style guide is saved as `docs/style_palette_final.svg` for reference. + +### Font + +``` +'Segoe UI', 'Helvetica Neue', Arial, sans-serif +``` + +| Element | Size | Weight | Color | +|---------|------|--------|-------| +| Figure title | 17-18px | Bold (700) | #2C3E50 | +| Section heading | 14px | Semibold (600) | #2C3E50 | +| Body text | 13px | Regular (400) | #555555 | +| Captions/notes | 11px | Italic | #888888 | + +### Color Palette + +**Primary (Diagram Elements):** + +| Role | Color | Hex | Usage | +|------|-------|-----|-------| +| Focus | Dark Blue | #2874A6 | Center cell, primary element, section headers | +| Active | Light Blue | #AED6F1 | Kernel neighbors, included elements | +| Inactive | Light Gray | #E8ECF0 | Outside kernel, excluded elements | + +**Semantic Accents:** + +| Role | Color | Hex | Usage | +|------|-------|-----|-------| +| Danger/Warning | Red | #E74C3C | Thread-safety warnings, invalid approaches, common mistakes | +| Good/Correct | Green | #27AE60 | Recommended approaches, valid results, correct measurements | +| Annotation | Purple | #8E44AD | Brackets, dimensions, labels, measurements | +| Tip/Highlight | Amber | #E67E22 | Tips, parameters of interest, optional recommendations | + +**Supporting:** + +| Role | Color | Hex | Usage | +|------|-------|-----|-------| +| Primary text | Dark Slate | #2C3E50 | Headings, primary labels | +| Secondary text | Medium Gray | #5D6D7E | Secondary labels, descriptions | +| Card background | White | #FFFFFF | Figure card background | +| Formula background | Pale Blue | #EBF5FB | Formula/equation highlight boxes | +| Warning background | Pale Red | #FDEDEC | Warning callout box fill | +| Success background | Pale Green | #EAFAF1 | Success callout box fill | +| Annotation background | Pale Purple | #F4ECF7 | Note callout box fill | +| Tip background | Pale Amber | #FEF5E7 | Tip callout box fill | +| Page background | Off-white | #F0F2F5 | Outer page fill (when used) | + +### Callout Box Styles + +Four semantic callout box types are available: + +- **Warning (Red)** — `!` icon, #FDEDEC background, #E74C3C border. For dangers and things to watch out for. +- **Good/Correct (Green)** — checkmark icon, #EAFAF1 background, #27AE60 border. For recommended approaches. +- **Note (Purple)** — `i` icon, #F4ECF7 background, #8E44AD border. For general annotations and clarifications. +- **Tip (Amber)** — star icon, #FEF5E7 background, #E67E22 border. For tips and highlights. + +### Section Headers + +Colored bars with white text, using the semantic color that best fits the section content. Default to blue (#2874A6) for neutral sections. + +### Figure File Format + +- Generate as SVG source files +- Convert to PNG at 2x resolution using `rsvg-convert -z 2` +- Keep both SVG and PNG in `docs/Images/` (or the plugin's `docs/Images/` directory) +- Reference the PNG in documentation markdown +- Naming convention: `FilterName_Description.png` (e.g., `ComputeKernelAvgMisorientations_1D_Radius1.png`) + +--- + +## 7. Concept Link Strategy + +During triage and rewrite, track domain concepts that appear across multiple filters. When a concept appears in 3+ filter docs, it is a candidate for a shared concept page. + +**During this review:** +- Note concept links needed in the tracker document +- Define terms inline in filter docs on first use +- Use placeholder links in the format `[concept name](link-tbd)` where a shared page would be ideal + +**Future task:** +- Create shared concept pages in a canonical location within this repo +- Replace placeholder links with real links +- Consolidate existing concept docs from scattered locations + +**Likely concept pages based on initial survey:** +- Quaternions and Orientation Representations +- Feature IDs and Grains +- Image Geometry (Voxels, Dimensions, Spacing, Origin) +- Cell vs. Feature vs. Ensemble Data +- Misorientation +- Crystallographic Symmetry +- Reference Frames and Conventions + +--- + +## 8. Batch Organization + +Rewrites are organized by functional category. Suggested batch order (highest impact first): + +| Batch | Category | Approx. Count | Rationale | +|-------|----------|---------------|-----------| +| 1 | Orientation / Crystallography Statistics | ~15 | Highest domain complexity, most likely Tier 1 | +| 2 | Alignment Filters | ~8 | Spatial concepts benefit from figures | +| 3 | Segmentation / Feature Identification | ~10 | Core workflow, many users encounter these | +| 4 | Neighbor / Kernel Operations | ~12 | Spatial concepts, parameter guidance needed | +| 5 | Geometry Creation / Manipulation | ~15 | Many options, complex parameter interactions | +| 6 | Data Manipulation (Copy, Create, Delete, Rename) | ~20 | Mostly Tier 3-4, quick to process | +| 7 | I/O Filters (Read/Write) | ~15 | Mostly Tier 3-4 | +| 8 | Image Processing (ITK wrappers) | ~88 | Large batch, many follow a template pattern | +| 9 | Remaining SimplnxCore filters | ~varies | Catch-all for uncategorized | + +Exact batch boundaries will be refined after the triage pass reveals the actual distribution across tiers and categories. + +--- + +## 9. Workflow Summary + +``` +Phase 1: Triage + Claude reviews all ~295 filter docs + → Produces docs/documentation_review_tracker.md + → User reviews tracker, adjusts tiers if needed + → User commits tracker + +Phase 2: Batched Rewrites (repeat per batch) + Claude rewrites batch of related filter docs + Claude generates conceptual figures (SVG → PNG) + → User reviews changes + → User commits batch + → Check off completed filters in tracker + +Phase 3: Final + All batches complete + → Submit single PR to develop + → Future: concept page consolidation, real-world visualizations +``` + +--- + +## 10. Files Created During This Design Phase + +| File | Purpose | +|------|---------| +| `docs/style_palette_final.svg` | Visual style guide for all generated figures | +| `docs/style_palette_options.svg` | Palette options explored during design (can be deleted) | +| `kernel_radius_infographic.svg` | Original combined infographic (repo root, can be deleted) | +| `src/Plugins/OrientationAnalysis/docs/Images/ComputeKernelAvgMisorientations_*.svg` | Individual figure SVG sources | +| `src/Plugins/OrientationAnalysis/docs/Images/ComputeKernelAvgMisorientations_*.png` | Individual figure PNGs for documentation | +| `src/Plugins/OrientationAnalysis/docs/ComputeKernelAvgMisorientationsFilter.md` | Updated filter doc (serves as template for rewrite style) | diff --git a/docs/upstream-filter-sources.md b/docs/upstream-filter-sources.md new file mode 100644 index 0000000000..43ac21f919 --- /dev/null +++ b/docs/upstream-filter-sources.md @@ -0,0 +1,73 @@ +# Upstream Filter Sources + +Lookup table mapping common input arrays to the filter(s) that produce them. Used when writing the **Required Input Sources** section of a filter's documentation (see the `vv-filter-documentation` skill for the convention). + +This file is intended to be grown over time. As more filters are documented or new filters are added, append rows. The longer-term goal is to derive a dependency graph from this data so that pipeline order constraints can be visualized. + +## How To Use + +When documenting a filter that requires array X, look up X in the table below and link to the producing filter from your Required Input Sources section using MyST link syntax: + +```markdown +- **X** -- produced by [Producer Human Name](ProducerFilter.md). +``` + +For arrays produced by EBSD readers (Cell Quaternions, Cell Phases, ensemble Crystal Structures), name the typical readers explicitly rather than picking one: + +```markdown +- **Cell Quaternions** -- typically read from EBSD data via [Read H5EBSD](ReadH5EbsdFilter.md), [Read CTF Data](ReadCtfDataFilter.md), or [Read ANG Data](ReadAngDataFilter.md); can also be produced from Euler angles by [Convert Orientations](ConvertOrientationsFilter.md). +``` + +## Conventions for Growing This Table + +- **One row per array, multiple producers comma-separated** in the Producer column when the array can come from several filters. +- **Plugin column** lists where the *producer* lives, not where the consuming filter lives. This drives the relative-path direction of MyST links. +- **Cross-plugin links** must use `../OtherPlugin/FilterFile.md`. Within-plugin links use `FilterFile.md` only. +- **Filter names match `humanName()`** in the .cpp, not the file name. The link target file is always `Filter.md`. +- **Notes column** (optional) for caveats: ensemble-level vs feature-level vs cell-level, optional inputs, mode dependencies (e.g., "only when *Find Coherence* is enabled"). + +## Lookup Table + +| Input Array | Producer (humanName) | Plugin | Notes | +|---|---|---|---| +| Cell Quaternions | Read H5EBSD / Read CTF Data / Read ANG Data / Convert Orientations | OrientationAnalysis | From EBSD readers, or computed from Euler angles | +| Cell Eulers | Same EBSD readers | OrientationAnalysis | Bunge convention Z-X-Z | +| Cell Phases | Same EBSD readers | OrientationAnalysis | Read alongside quaternions | +| Crystal Structures | Same EBSD readers / Create Ensemble Info | OrientationAnalysis | Ensemble-level array | +| Cell Feature Ids | Segment Features (Misorientation) | OrientationAnalysis | Misorientation-based grain segmentation | +| Cell Feature Ids | Segment Features (C-Axis Misalignment) | OrientationAnalysis | Hexagonal-only | +| Cell Feature Ids | Segment Features (Scalar) | SimplnxCore | Scalar-based segmentation | +| Cell Parent Ids | Merge Twins | OrientationAnalysis | Cell-level grouping into parent grains | +| Feature Parent Ids | Merge Twins | OrientationAnalysis | Feature-level mapping | +| Feature Phases | Compute Feature Phases | SimplnxCore | Feature-level (one phase per feature) | +| Feature Phases (Binary) | Compute Feature Phases (Binary) | SimplnxCore | Two-phase classification | +| Average Quaternions | Compute Average Orientations | OrientationAnalysis | Per-feature average orientation | +| Average Euler Angles | Compute Average Orientations | OrientationAnalysis | Bunge convention Z-X-Z | +| Average C-Axes | Compute Average C-Axis Orientations | OrientationAnalysis | Hexagonal-only | +| Feature Centroids | Compute Feature Centroids | SimplnxCore | Cell-of-mass per feature | +| Feature Equivalent Diameters | Compute Feature Sizes | SimplnxCore | Diameter of equal-volume sphere | +| Feature Num. Cells (NumElements) | Compute Feature Sizes | SimplnxCore | Cell count per feature | +| Feature Volumes | Compute Feature Sizes | SimplnxCore | Physical volume | +| Surface Features | Compute Surface Features | SimplnxCore | Boolean per feature | +| Surface Features | Compute Feature Neighbors | SimplnxCore | Optional output (enable *Store Surface Features Array*) | +| Biased Features | Compute Biased Features (Bounding Box) | SimplnxCore | Boolean per feature | +| Number of Neighbors | Compute Feature Neighbors | SimplnxCore | Count per feature | +| Contiguous Neighbor List | Compute Feature Neighbors | SimplnxCore | NeighborList of contiguous Feature Ids | +| Shared Surface Area List | Compute Feature Neighbors | SimplnxCore | NeighborList in cell-face-count units | +| Boundary Cells | Compute Feature Neighbors | SimplnxCore | Optional output (enable *Store Boundary Cells Array*) | +| Neighborhoods Neighbor List | Compute Feature Neighborhoods | SimplnxCore | Sphere-radius-based neighbor list | +| Mask | Multi-Threshold Objects | SimplnxCore | Boolean per cell | +| Boundary Euclidean Distances | Compute Euclidean Distance Map | SimplnxCore | Cell-level distance to nearest boundary | +| Triangle Geometry | Quick Surface Mesh | SimplnxCore | Surface mesh from Feature Ids | +| Face Labels | Quick Surface Mesh | SimplnxCore | Per-face Feature ID pair (2-component) | +| Face Normals | Compute Triangle Normals | SimplnxCore | 3-component, on triangle face data | +| Face Areas | Compute Triangle Areas | SimplnxCore | Single-component, on triangle face data | +| Node Types | Quick Surface Mesh | SimplnxCore | Per-vertex node classification | +| Cell Shifts Array (alignment) | Align Sections (Feature Centroid) | SimplnxCore | Output of any Align Sections * filter | +| Cell Shifts Array (alignment) | Align Sections (Misorientation) | OrientationAnalysis | | +| Cell Shifts Array (alignment) | Align Sections (Mutual Information) | OrientationAnalysis | | +| Confidence Index / Image Quality | Read H5EBSD / Read CTF Data / Read ANG Data | OrientationAnalysis | Per-cell scalar quality metric | + +## Future: Graph Representation + +The lookup table is naturally a directed dependency graph: each row is an edge from a producer filter to the input-array node. A separate downstream effort may convert this into a graph (DOT, Mermaid, or networked JSON) to support pipeline-order checking, "what would I need to run before X?" queries, and visual dependency maps. Keep that future use in mind when adding rows -- be precise about producer humanName so the data is machine-parseable. diff --git a/src/Plugins/OrientationAnalysis/docs/AlignSectionsMisorientationFilter.md b/src/Plugins/OrientationAnalysis/docs/AlignSectionsMisorientationFilter.md index 0e9674d464..98fb777f7d 100644 --- a/src/Plugins/OrientationAnalysis/docs/AlignSectionsMisorientationFilter.md +++ b/src/Plugins/OrientationAnalysis/docs/AlignSectionsMisorientationFilter.md @@ -6,20 +6,34 @@ Reconstruction (Alignment) ## Description -This **Filter** attempts to align consecutive 'sections' perpendicular to the Z-direction of the sample by determining the position that results in the minimum amount of misorientation between **Cells** directly above-below each other. The algorithm of this **Filter** is as follows: +This **Filter** aligns serial sections (2D slices stacked along the Z-direction) by finding the shift that minimizes the crystal orientation mismatch between cells on neighboring slices. This is the most commonly used alignment method for EBSD data because it directly uses the orientation information measured at each point. -1. Calculate the misorientation between each **Cell** in a section and the **Cell** directly above it in the next section -2. Count the number of **Cell** pairs that have a misorientation above the user defined tolerance and store that as the misalignment value for that position -3. Repeat steps 1 and 2 for each position when shifting the second slice (relative to the first) from three (3) **Cells** to the left to three (3) **Cells** to the right, as well as from three (3) **Cells** up to three (3) **Cells** down. *Note that this creates a 7x7 grid* -4. Determine the position in the 7x7 grid that has the lowest misalignment value. (It will be the position with the fewest different **Cell** pairs) -5. Repeat steps 1-4 with the center of each (new) 7x7 grid at the best position from the last 7x7 grid until the best position in the current/new 7x7 grid is the same as the last 7x7 grid -6. Repeat steps 1-5 for each pair of neighboring sections +### When to Use This Method -**Note that this is similar to a downhill simplex and can get caught in a local minimum!** +Use this method when your data contains crystal orientation measurements (quaternions or Euler angles) and you want to align sections based on the actual crystallographic content. This works well for most EBSD datasets. For data without orientation information, consider the [Align Sections (Feature Centroid)](../SimplnxCore/AlignSectionsFeatureCentroidFilter.md) or [Align Sections (Mutual Information)](AlignSectionsMutualInformationFilter.md) methods instead. -If the user elects to use a mask array, the **Cells** flagged as *false* in the mask array will not be considered during the alignment process. +### How This Filter Works -The user can also decide to remove a *background shift* present in the sample. The process for this is to fit a line to the X and Y shifts along the Z-direction of the sample. The individual shifts are then modified to make the slope of the fit line be 0. Effectively, this process is trying to keep the top and bottom section of the sample fixed. Some combinations of sample geometry and internal features can result in this algorithm introducing a 'shear' in the sample and the *Linear Background Subtraction* will attempt to correct for this. +The filter uses an iterative grid search to find the optimal alignment for each pair of neighboring sections: + +1. For a given relative position of two sections, calculate the misorientation between each **Cell** on the lower section and the **Cell** directly above it on the upper section +2. Count the number of cell pairs whose misorientation exceeds the user-defined tolerance. This count is the "misalignment score" for that position -- lower is better +3. Evaluate the misalignment score at all 49 positions in a 7x7 grid (shifting the upper section from -3 to +3 cells in both X and Y) +4. Select the position with the lowest misalignment score +5. Re-center the 7x7 grid on the best position and repeat until the best position no longer changes +6. Repeat for each pair of neighboring sections + +### Local Minima Warning + +This iterative grid search is similar to a downhill simplex optimization and **can get caught in a local minimum**. If alignment results look incorrect, try adjusting the misorientation tolerance or consider using the [Align Sections (Feature Centroid)](../SimplnxCore/AlignSectionsFeatureCentroidFilter.md) method, which does not have this limitation. + +### Masking + +If a mask array is provided, **Cells** flagged as *false* are excluded from the alignment calculation. This is useful for ignoring regions of bad data or regions outside the sample boundary. + +### Linear Background Subtraction + +Some combinations of sample geometry and internal features can cause the alignment to introduce a gradual "shear" across the sample. Enabling *Linear Background Subtraction* corrects for this by fitting a line to the X and Y shifts along the Z-direction and removing the linear trend. This effectively keeps the top and bottom sections of the sample fixed relative to each other. ## Optional Output Data @@ -44,12 +58,18 @@ In this new structure, what follows is what the created structures represent: In previous versions a file would have been produced instead. If you wish to recreate this, you can write the Attribute Matrix as a CSV/Text file. +### Required Input Sources + +- **Cell Quaternions** -- typically read from EBSD data via [Read H5EBSD](ReadH5EbsdFilter.md), [Read CTF Data](ReadCtfDataFilter.md), or [Read ANG Data](ReadAngDataFilter.md). +- **Cell Phases** -- typically read from EBSD data alongside the quaternions. +- **Crystal Structures** -- ensemble-level array read from EBSD data or created by [Create Ensemble Info](CreateEnsembleInfoFilter.md). +- **Mask** (optional) -- a boolean array marking valid cells, typically produced by a threshold operation such as [Multi-Threshold Objects](../SimplnxCore/MultiThresholdObjectsFilter.md). % Auto generated parameter table will be inserted here ## Example Pipelines -+ (02) Small IN100 Full Reconstruction ++ `(02) Small IN100 Full Reconstruction` ## License & Copyright diff --git a/src/Plugins/OrientationAnalysis/docs/AlignSectionsMutualInformationFilter.md b/src/Plugins/OrientationAnalysis/docs/AlignSectionsMutualInformationFilter.md index 9fe3485150..7f267e4db7 100644 --- a/src/Plugins/OrientationAnalysis/docs/AlignSectionsMutualInformationFilter.md +++ b/src/Plugins/OrientationAnalysis/docs/AlignSectionsMutualInformationFilter.md @@ -6,25 +6,35 @@ Reconstruction (Alignment) ## Description -This **Filter** segments each 2D slice, creating *Feature Ids* that are used when determining the *mutual information* between neighboring slices. The slices are shifted relative to one another until the position of maximum *mutual information* is determined for each section. The *Feature Ids* are temporary, they apply to this **Filter** only and are not related to the *Feature Ids* generated in other **Filters**. The algorithm of this **Filter** is listed below: +This **Filter** aligns serial sections (2D slices stacked along the Z-direction) by maximizing the *mutual information* between the feature patterns on neighboring slices. Rather than comparing individual cell orientations (as in [Align Sections (Misorientation)](AlignSectionsMisorientationFilter.md)), this method first groups cells into temporary features on each slice, then finds the shift that best aligns those feature patterns between slices. -1. Segment *Features* on each 'section' of the sample perpendicular to the Z-direction. This is done using the same algorithm in the [Segment Features (Misorientation)](@ref alignsectionsmisorientation) **Filter** (only in 2D on each section) -2. Calculate the *mutual information* between neighboring sections and store that as the misalignment value for that position. *Mutual information* is related to the ratio of joint probability to individual probabilities of variables (i.e., p(x,y)/p(x)p(y) ). Details of the actual *mutual information* calculation can be found in the references below, but can be thought of as the inherent dependence between variables (here the *Feature Ids* on neighboring sections). -3. Repeat step 2 for each position when shifting the second slice (relative to the first) from three (3) **Cells** to the left -to three (3) **Cells** to the right, as well as from three (3) **Cells** up to three (3) **Cells** down -*Note that this creates a 7x7 grid* -4. Determine the position in the 7x7 grid that has the highest *mutual information* value -5. Repeat steps 2-4 with the center of each (new) 7x7 grid at the best position from the last 7x7 grid until the best position in the current/new 7x7 grid is the same as the last 7x7 grid +### When to Use This Method -6) Repeat steps 2-5 for each pair of neighboring sections +This method is useful when feature-level pattern matching is more appropriate than cell-level orientation comparison. It can sometimes produce better results than misorientation-based alignment when the data has significant noise or when features are large relative to the misalignment. -**Note that this is similar to a downhill simplex and can get caught in a local minimum!** +### What is Mutual Information? -The user choses the level of *misorientation tolerance* by which to align **Cells**, where here the tolerance means the *misorientation* cannot exceed a given value. If the rotation angle is below the tolerance, then the **Cell** is grouped with other **Cells** that satisfy the criterion. +Mutual information is a statistical measure of how much information one variable provides about another. In this context, it measures how well the feature patterns on two neighboring slices correspond to each other. High mutual information means the features on one slice strongly predict the features on the adjacent slice -- indicating good alignment. -The approach used in this **Filter** is to group neighboring **Cells** on a slice that have a *misorientation* below the tolerance the user entered. *Misorientation* here means the minimum rotation angle of one **Cell's** crystal axis needed to coincide with another **Cell's** crystal axis. When the **Features** in the slices are defined, they are moved until *disks* in neighboring slices align with each other. +### How This Filter Works -If the user elects to use a mask array, the **Cells** flagged as *false* in the mask array will not be considered during the alignment process. +1. **Segment features on each slice:** Neighboring cells on each 2D slice are grouped into temporary features using a misorientation tolerance (the same algorithm as [Segment Features (Misorientation)](EBSDSegmentFeaturesFilter.md), applied in 2D). These feature IDs are internal to this filter and are not stored. +2. **Calculate mutual information:** For a given relative position of two slices, compute the mutual information between the feature ID patterns on the two slices. +3. **Grid search:** Evaluate the mutual information at all 49 positions in a 7x7 grid (shifting the upper slice from -3 to +3 cells in both X and Y). Select the position with the highest mutual information. +4. **Iterate:** Re-center the 7x7 grid on the best position and repeat until the best position no longer changes. +5. **Repeat** for each pair of neighboring sections. + +### Misorientation Tolerance + +The *misorientation tolerance* parameter controls how cells are grouped into temporary features on each slice. Cells whose orientations differ by less than this tolerance are grouped together. Lower values produce more, smaller features; higher values produce fewer, larger features. + +### Local Minima Warning + +This iterative grid search is similar to a downhill simplex optimization and **can get caught in a local minimum**. If alignment results look incorrect, try adjusting the misorientation tolerance or consider using the [Align Sections (Feature Centroid)](../SimplnxCore/AlignSectionsFeatureCentroidFilter.md) method, which does not have this limitation. + +### Masking + +If a mask array is provided, **Cells** flagged as *false* are excluded from the alignment calculation. ## Optional Output Data @@ -49,6 +59,13 @@ In this new structure, what follows is what the created structures represent: In previous versions a file would have been produced instead. If you wish to recreate this, you can write the Attribute Matrix as a CSV/Text file. +### Required Input Sources + +- **Cell Quaternions** -- typically read from EBSD data via [Read H5EBSD](ReadH5EbsdFilter.md), [Read CTF Data](ReadCtfDataFilter.md), or [Read ANG Data](ReadAngDataFilter.md). +- **Cell Phases** -- typically read from EBSD data alongside the quaternions. +- **Crystal Structures** -- ensemble-level array read from EBSD data or created by [Create Ensemble Info](CreateEnsembleInfoFilter.md). +- **Mask** (optional) -- a boolean array marking valid cells, typically produced by a threshold operation such as [Multi-Threshold Objects](../SimplnxCore/MultiThresholdObjectsFilter.md). + % Auto generated parameter table will be inserted here ## References @@ -65,7 +82,7 @@ Journal articles on *Mutual Information* that are useful: ## Example Pipelines -AlignSectionsMutualInformation ++ `AlignSectionsMutualInformation` ## License & Copyright diff --git a/src/Plugins/OrientationAnalysis/docs/BadDataNeighborOrientationCheckFilter.md b/src/Plugins/OrientationAnalysis/docs/BadDataNeighborOrientationCheckFilter.md index a79b203db1..9f00a35546 100644 --- a/src/Plugins/OrientationAnalysis/docs/BadDataNeighborOrientationCheckFilter.md +++ b/src/Plugins/OrientationAnalysis/docs/BadDataNeighborOrientationCheckFilter.md @@ -6,49 +6,54 @@ Processing (Cleanup) ## Description -This filter will change the value of a cell's `mask` value from **False** to **True** based on the misorientation between the target -cell and it's 6-face neighbors. This filter should be used to target isolated -voxels inside potential features (grains). +This **Filter** rescues *bad* cells (those with *Mask = false*) that are surrounded by good cells with consistent orientations. It does **not** modify any cell-level attributes other than the **Mask** array; it only flips the *Mask* value of qualifying cells from **false** to **true**, effectively re-classifying them as good. -### Algorithm Description +This is a sister filter to [Neighbor Orientation Correlation](NeighborOrientationCorrelationFilter.md). The key difference: this filter only updates the mask, while *Neighbor Orientation Correlation* copies full cell attributes from a neighbor. Use this filter as the **first pass** to recover cells that were marked bad by an over-aggressive threshold but are genuinely surrounded by valid neighbors; use *Neighbor Orientation Correlation* afterward to clean up cells whose orientation is genuinely wrong. -For each cell (voxel) in the input Image Geometry, if the *Mask* value of the target cell is **FALSE**, -then the misorientation between that cell and each of its 6-face -neighbor cells is calculated. If the number of misorientation values that fall below the -user defined threshold is equal to or greater than the user defined value of -`Required Number of Neighbors` then the current cells `mask` value is changed from -**False** to **True**. +### How This Filter Works -The filter will iteratively reduce the required number of neighbors from 6 until -it reaches the user defined number. So, if the user selects a required number -of neighbors of 4, then the filter will run with a required number of neighbors -of 6, then 5, then 4 before finishing. +For each cell whose *Mask* is **false**: -During the algorithm since the `mask` array is being updated continuously, each time -the `mask` array is updated, any neighbors of that changed voxel are evaluated again -to check if that neighbor now has the required number of valid neighbors. If this -check ends up being true then that neighbor voxel is added to the list of voxels to check. -This can lead to a **Flood Fill** type of algorithm. The user should take care to examine -the output from this filter to ensure that the filter is not being overly aggressive about -changing voxels. +1. Compute the misorientation between the cell and each of its 6 face-neighbors (cells in the +X, -X, +Y, -Y, +Z, -Z directions). +2. Count the number of neighbors whose misorientation falls below the user-specified *Misorientation Tolerance*. +3. If that count is at least *Required Number of Neighbors*, flip the cell's *Mask* from **false** to **true**. -### 2D Versus 3D Note +The filter steps down through *Required Number of Neighbors* from 6 to the user-defined floor: setting it to 4 runs at levels 6, 5, and 4 in sequence. -If the user is processing a 2D data set, **none** of the voxels can have 6 neighbors -since there are no neighbors is the +-Z directions. +While the algorithm runs, the *Mask* array is updated continuously. When a cell's mask flips, its neighbors are re-evaluated -- they may now have enough valid neighbors to qualify themselves. **This can cascade into a flood fill**, especially if the user sets *Required Number of Neighbors* very low. Always inspect the output to confirm the filter is not overshooting. -### Warning - Data Modification +### Required Number of Neighbors -Only the *Mask* value defining the cell as *good* or *bad* is changed. No other cell level array is modified. +The *Required Number of Neighbors* parameter is the **count of agreeing face-neighbors needed to flip the mask** and ranges from **1 to 6**: -## Example Data +- **6** -- only rescue cells where all 6 face-neighbors agree. Very conservative. +- **4-5** -- rescues most over-thresholded cells while leaving genuinely uncertain cells alone. +- **2-3** -- aggressive; risks cascading. +- **1** -- one matching neighbor is enough; effectively a flood fill. + +### 2D vs 3D + +In 2D data (Z dimension = 1), no cell can have 6 face-neighbors because there are no neighbors in the +Z and -Z directions. The maximum count for 2D is therefore 4. + +### Warning -- Data Modification + +Only the *Mask* array is modified. Every other cell-level array (orientations, phases, etc.) is left unchanged. To replace orientation data on cells whose orientations are wrong, run [Neighbor Orientation Correlation](NeighborOrientationCorrelationFilter.md) afterward. + +### Example Data | Example Input Image | Example Output Image | |---------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------| | ![](Images/BadDataNeighborOrientationCheckFilter_1.png) | ![](Images/BadDataNeighborOrientationCheckFilter_2.png) | -| The Small IN100 data just after initial alignment filters have completed. | The Small IN100 data just after running this filter with a *Misorientation Tolerance* of 5 degrees and a *Required Number of Neighbors* of 4. | +| The Small IN100 data just after initial alignment filters have completed. | The Small IN100 data after running this filter with *Misorientation Tolerance* = 5° and *Required Number of Neighbors* = 4. | + +The cells that flipped from false (black) to true (IPF-colored) had Confidence Index just below the original mask threshold (CI > 0.1, IQ > 120) but had enough valid neighbors with consistent orientations to be rescued. + +### Required Input Sources -From the above before and after images you can see that this filter can help modify a mask that was generated through a simple threshold filter. This filter essentially uses neighbors to determine if a cell point should have had a mask value of false. The majority of cells that were changed from *false* or the black voxels, into valid IPF colored voxels, had a confidence index that fell just below the initial threshold applied (Confidence Index > 0.1 and Image Quality > 120). This filter determines that enough of that cell's neighbors had a mask value of true, the misorientation was < 5 degrees and the cell had enough valid neighbors that the cell's *mask* value was changed from **false** to **true**. +- **Mask Array** -- a boolean cell-level array, typically produced by [Multi-Threshold Objects](../SimplnxCore/MultiThresholdObjectsFilter.md) applied to EBSD confidence/quality scalars. +- **Cell Quaternions** -- typically read from EBSD data via [Read H5EBSD](ReadH5EbsdFilter.md), [Read CTF Data](ReadCtfDataFilter.md), or [Read ANG Data](ReadAngDataFilter.md). +- **Cell Phases** -- typically read from EBSD data alongside the quaternions. +- **Crystal Structures** -- ensemble-level array read from EBSD data or created by [Create Ensemble Info](CreateEnsembleInfoFilter.md). % Auto generated parameter table will be inserted here diff --git a/src/Plugins/OrientationAnalysis/docs/CAxisSegmentFeaturesFilter.md b/src/Plugins/OrientationAnalysis/docs/CAxisSegmentFeaturesFilter.md index 6983636597..a83a205477 100644 --- a/src/Plugins/OrientationAnalysis/docs/CAxisSegmentFeaturesFilter.md +++ b/src/Plugins/OrientationAnalysis/docs/CAxisSegmentFeaturesFilter.md @@ -6,17 +6,35 @@ Reconstruction (Segmentation) ## Description -This **Filter** segments the **Features** by grouping neighboring **Cells** that satisfy the *C-axis misalignment tolerance*, i.e., have misalignment angle less than the value set by the user. The *C-axis misalignment* refers to the angle between the <001> directions (C-axis in the hexagonal system) that is present between neighboring **Cells**. The process by which the **Features** are identified is given below and is a standard *burn algorithm*. +This **Filter** groups neighboring **Cells** (voxels) whose crystal C-axes are nearly aligned into **Features** (grains), producing a *FeatureIds* array that labels every cell in the input **Image Geometry** with a grain number. -1. Randomly select a **Cell**, add it to an empty list and set its *Feature Id* to the current **Feature** -2. Compare the **Cell** to each of its six (6) face-sharing neighbors (i.e., calculate the c-axis misalignment with each neighbor) -3. Add each neighbor **Cell** that has a C-axis misalignment below the user defined tolerance to the list created in 1. and set the *Feature Id* of the neighbor **Cell** to the current **Feature** -4. Remove the current **Cell** from the list and move to the next **Cell** and repeat 2. and 3.; continue until no **Cells** are left in the list -5. Increment the current **Feature** counter and repeat steps 1. through 4.; continue until no **Cells** remain unassigned in the dataset +This filter is **only valid for hexagonal phases**. For general EBSD grain segmentation (cubic, orthorhombic, or any other symmetry), use [Segment Features (Misorientation)](EBSDSegmentFeaturesFilter.md) instead; for scalar-based segmentation, use [Segment Features (Scalar)](../SimplnxCore/ScalarSegmentFeaturesFilter.md). -The user has the option to *Use Mask Array*, which allows the user to set a boolean array for the **Cells** that remove **Cells** with a value of *false* from consideration in the above algorithm. This option is useful if the user has an array that either specifies the domain of the "sample" in the "image" or specifies if the orientation on the **Cell** is trusted/correct. +### When to Use This Filter -After all the **Features** have been identified, a **Feature Attribute Matrix** is created for the **Features** and each **Feature** is flagged as *Active* in a boolean array in the matrix. +In hexagonal materials (titanium, magnesium, zinc, zirconium, etc.), the [C-axis](ComputeAvgCAxesFilter.md) is the unique, mechanically significant crystal direction. For many studies -- especially those focused on basal-plane slip, texture, or deformation -- it is more informative to group cells by how closely their C-axes point in the same direction than by their full orientation. Two cells may have very different full orientations (rotated differently about their own C-axis) but still belong to the same grain if their C-axes point the same way. + +If you need full misorientation-based grain segmentation (accounting for rotations about the C-axis), use [Segment Features (Misorientation)](EBSDSegmentFeaturesFilter.md) instead. + +### How This Filter Works + +The filter uses a standard *burn algorithm* to grow each feature outward from a seed cell: + +1. Randomly pick an unassigned **Cell** and give it a new *Feature Id*. +2. Compute the angle between the C-axis of the seed cell and the C-axis of each neighbor (see **Neighbor Scheme** below). +3. Any neighbor whose C-axis misalignment angle is less than the user-specified *Misalignment Tolerance* (in **degrees**) is added to the current feature and gets the same *Feature Id*. +4. Repeat step 2-3 from each newly added cell, growing the feature outward until no more neighbors qualify. +5. Increment the feature counter and pick a new unassigned seed cell. Continue until every eligible cell has been assigned. + +The C-axis direction for each cell is computed on-the-fly from the cell's orientation quaternion. See [Compute Average C-Axis Orientations](ComputeAvgCAxesFilter.md) for a full explanation of the C-axis concept and why it only makes physical sense for hexagonal symmetries. + +### Tolerance and Units + +The *Misalignment Tolerance* is in **degrees**. Typical values: + +- **1-3 degrees** -- very tight; splits grains with even slight C-axis variation (subgrains). +- **5 degrees** -- the common default for grain segmentation. +- **10+ degrees** -- loose; merges adjacent grains whose C-axes are within a cone. ### Neighbor Scheme @@ -25,11 +43,7 @@ The *Neighbor Scheme* parameter provides the following choices: - **Face Neighbors [0]**: Only the 6 face-sharing neighbors of a voxel are considered during segmentation. - **All Connected Neighbors [1]**: All 26 neighbors connected by a face, edge, or vertex are considered during segmentation. -## Note on Neighbor Scheme - -Historically DREAM.3D version 6.x has used *only* the 6 face neighbors of a voxel. This release introduces the option -of using all 26 neighboring voxels that are connected by a face, edge or vertex. The default for the filter -is to still use the 6 face neighbors ("Face Only") in order to stay consistent with the output from DREAM.3D version 6.x. +DREAM.3D version 6.x only used face neighbors. The default here is still *Face Only* for backward compatibility. | Neighbor Scheme = "Face Only" | Neighbor Scheme = "All Connected" | |:--:|:--:| @@ -47,6 +61,17 @@ is to still use the 6 face neighbors ("Face Only") in order to stay consistent w |:--:|:--:| | ![Shared Edges & Points With Disconnected Region - "Face Only"](Images/SegmentFeatures/combination_face_only.png) | ![Shared Edges & Points With Disconnected Region - "All Connected"](Images/SegmentFeatures/combination_all_connected.png) | +### Mask Array + +If *Use Mask Array* is enabled, cells flagged *false* in the mask are excluded from segmentation and left with a Feature Id of 0. Masks are commonly used to restrict segmentation to the sample region or to cells with reliable orientation data (for example, a threshold on an EBSD confidence index). + +### Required Input Sources + +- **Cell Quaternions** -- typically read from EBSD data via [Read H5EBSD](ReadH5EbsdFilter.md), [Read CTF Data](ReadCtfDataFilter.md), or [Read ANG Data](ReadAngDataFilter.md); can also be produced from Euler angles by [Convert Orientations](ConvertOrientationsFilter.md). +- **Cell Phases** -- typically read from EBSD data alongside the quaternions. +- **Crystal Structures** -- ensemble-level array read from EBSD data or created by [Create Ensemble Info](CreateEnsembleInfoFilter.md). Phases that are not hexagonal will produce invalid segmentation for those cells. +- **Mask Array** (optional) -- a boolean array marking valid cells, typically produced by [Multi-Threshold Objects](../SimplnxCore/MultiThresholdObjectsFilter.md). + % Auto generated parameter table will be inserted here ## Example Pipelines diff --git a/src/Plugins/OrientationAnalysis/docs/ComputeAvgCAxesFilter.md b/src/Plugins/OrientationAnalysis/docs/ComputeAvgCAxesFilter.md index ee93e24852..bbfe22e446 100644 --- a/src/Plugins/OrientationAnalysis/docs/ComputeAvgCAxesFilter.md +++ b/src/Plugins/OrientationAnalysis/docs/ComputeAvgCAxesFilter.md @@ -6,29 +6,44 @@ Statistics (Crystallography) ## Description -This **Filter** determines the average C-axis location of each **Feature** by the following algorithm: +This **Filter** computes the average C-axis direction for each **Feature** (grain) in hexagonal materials. The result is a unit vector per **Feature** that indicates where the grain's C-axis points in the sample reference frame. -1. Gather all **Elements** that belong to the **Feature** -2. Determine the location of the c-axis in the sample *reference frame* for the rotated quaternions for all **Elements**. This is achieved by converting the input quaternion to -an orientation matrix (which represents a passive transform matrix), taking the transpose of the matrix to convert it from passive to active, and then multiplying the -transposed matrix by the crystallographic C-Axis direction vector <001>. -3. Average the locations and store the average for the **Feature** +### What is the C-Axis? -*Note:* This **Filter** will only work properly for *Hexagonal* materials. The **Filter** does not apply any symmetry -operators because there is only one c-axis (<001>) in *Hexagonal* materials and thus all symmetry operators will leave -the c-axis in the same position in the sample *reference frame*. However, in *Cubic* materials, for example, the {100} -family of directions are all equivalent and the <001> direction will change location in the sample *reference frame* when -symmetry operators are applied. +In hexagonal crystal structures (such as titanium, magnesium, and zinc), the *C-axis* is the unique crystallographic direction that runs along the long axis of the hexagonal unit cell (the [001] direction). This axis is important because many mechanical and physical properties of hexagonal materials vary depending on whether they are measured along or perpendicular to the C-axis. -This filter will error out if **ALL** phases are non-hexagonal. Any non-hexagonal phases will have their computed values set to NaN value. +![Fig. 1: The C-axis in a hexagonal unit cell.](Images/ComputeAvgCAxes_HexagonalCAxis.png) -The output is a direction vector for each feature. +### How This Filter Works + +Each **Cell** (voxel) in a grain has its own measured orientation. This filter determines where each cell's C-axis points in the physical sample coordinate system, then averages those directions across all cells belonging to the same **Feature**: + +1. For each **Cell**, the filter uses the cell's orientation (quaternion) to rotate the crystal [001] direction into the sample reference frame. +2. The rotated C-axis directions are accumulated for each **Feature**, ensuring all directions point into the same hemisphere for a consistent average. +3. The accumulated directions are normalized to produce a unit vector for each **Feature**. + +### Hexagonal Materials Only + +This filter only produces valid results for hexagonal phases (6/mmm or 6/m symmetry). In hexagonal materials, the C-axis is unique -- there is only one [001] direction, so crystal symmetry does not create ambiguity. + +In cubic materials, the [001], [010], and [100] directions are all crystallographically equivalent. Applying symmetry operators would move the [001] direction to different positions in the sample frame, making a simple average meaningless. For this reason, **non-hexagonal phases will have their output values set to NaN**. + +The filter will produce an error if no hexagonal phases are present in the data. + +### Required Input Sources + +This filter operates on previously segmented data and requires that several prior operations have already been run: + +- **Cell Quaternions** -- typically read from EBSD data via [Read H5EBSD](ReadH5EbsdFilter.md), [Read CTF Data](ReadCtfDataFilter.md), or [Read ANG Data](ReadAngDataFilter.md); can also be produced from Euler angles by [Convert Orientations](ConvertOrientationsFilter.md). +- **Cell Feature Ids** -- produced by a segmentation filter such as [Segment Features (Misorientation)](EBSDSegmentFeaturesFilter.md) or [Segment Features (C-Axis Misalignment)](CAxisSegmentFeaturesFilter.md). +- **Cell Phases** -- typically read from EBSD data alongside the quaternions. +- **Crystal Structures** -- ensemble-level array read from EBSD data or created by [Create Ensemble Info](CreateEnsembleInfoFilter.md). % Auto generated parameter table will be inserted here ## Example Pipelines -EBSD_Hexagonal_Data_Analysis ++ `EBSD_Hexagonal_Data_Analysis` ## License & Copyright diff --git a/src/Plugins/OrientationAnalysis/docs/ComputeAvgOrientationsFilter.md b/src/Plugins/OrientationAnalysis/docs/ComputeAvgOrientationsFilter.md index b3e261622d..b189a67d83 100644 --- a/src/Plugins/OrientationAnalysis/docs/ComputeAvgOrientationsFilter.md +++ b/src/Plugins/OrientationAnalysis/docs/ComputeAvgOrientationsFilter.md @@ -6,7 +6,11 @@ Statistics (Crystallography) ## Description -This **Filter** computes the average orientation of each **Feature** using one or more of three available averaging methods. Each method can be independently enabled, and their results are stored in separate output arrays. +This **Filter** computes the average crystal orientation for each **Feature** (grain). Since each grain is made up of many **Cells** (voxels) that each have their own measured orientation, this filter combines those individual measurements into a single representative orientation per grain. + +The average orientation is used by many downstream filters (e.g., misorientation calculations, Schmid factor, GBCD) and is one of the fundamental statistics computed during microstructure characterization. + +Three averaging methods are available, and each can be independently enabled. Their results are stored in separate output arrays. ### Method 1: Rodrigues Average (Original) @@ -68,6 +72,13 @@ These values may be exposed as user-configurable parameters in a future release. - **Features with zero elements:** Features with no elements (phase <= 0 for all voxels) will have their output arrays initialized to NaN (for vMF/Watson) or identity quaternion / zero Euler angles (for Rodrigues). - **Phase indexing:** The filter requires that phase values be > 0 for elements to be included in the averaging. Phase index 0 is reserved for "Unknown" in the Crystal Structures array and is always skipped. +### Required Input Sources + +- **Cell Quaternions** -- typically read from EBSD data via [Read H5EBSD](ReadH5EbsdFilter.md), [Read CTF Data](ReadCtfDataFilter.md), or [Read ANG Data](ReadAngDataFilter.md); can also be produced from Euler angles by [Convert Orientations](ConvertOrientationsFilter.md). +- **Cell Feature Ids** -- produced by a segmentation filter such as [Segment Features (Misorientation)](EBSDSegmentFeaturesFilter.md). +- **Cell Phases** -- typically read from EBSD data alongside the quaternions. +- **Crystal Structures** -- ensemble-level array read from EBSD data or created by [Create Ensemble Info](CreateEnsembleInfoFilter.md). + % Auto generated parameter table will be inserted here ## Example Pipelines diff --git a/src/Plugins/OrientationAnalysis/docs/ComputeBoundaryStrengthsFilter.md b/src/Plugins/OrientationAnalysis/docs/ComputeBoundaryStrengthsFilter.md index 3504791f0f..4b12758f8a 100644 --- a/src/Plugins/OrientationAnalysis/docs/ComputeBoundaryStrengthsFilter.md +++ b/src/Plugins/OrientationAnalysis/docs/ComputeBoundaryStrengthsFilter.md @@ -6,39 +6,52 @@ Statistics (Crystallography) ## Description -**THIS FILTER ONLY WORKS ON Cubic m-3m LAUE CLASSES** +This **Filter** computes slip transmission metrics for each **Face** (triangle) on a grain boundary mesh. These metrics quantify how easily plastic deformation can transfer across a grain boundary, based on the geometric alignment of slip systems in the two grains on either side. -This **Filter** calculates the same metrics as in the Find Neighbor Slip Transmission Metrics **Filter**. However, this **Filter** stores the values in the **Face Attribute Matrix** of a **Triangle Geometry**. The algorithm the **Filter** uses is as follows: +This filter computes the same metrics as the [Compute Neighbor Slip Transmission Metrics](ComputeSlipTransmissionMetricsFilter.md) filter, but stores results per boundary **Face** rather than per **Feature**. This makes it suitable for visualization and analysis on a **Triangle Geometry** surface mesh. -1. Find the two **Features** that are separated by a **Face** in the **Triangle Geometry** -2. Get the average orientation of both of the **Features** -3. Calculate the transmission metrics from both directions (i.e. **Feature** 1 to **Feature** 2 and **Feature** 2 to **Feature** 1) -4. Store the metrics in the **Face** map -5. Repeat for all **Faces** +For a detailed explanation of the slip transmission concept and the individual metrics, see the [Compute Neighbor Slip Transmission Metrics](ComputeSlipTransmissionMetricsFilter.md) documentation. -*Note:* Each metric is calculated twice for the two different directions slip could approach the boundary. The values are stored on each **Face** in the **Face** map in a way that notes the direction (i.e., when **Feature** 1 has neighbor **Feature** 2 and when **Feature** 2 has neighbor **Feature** 1) because the direction across the boundary between the **Features** affects the value of the metric. +### Cubic Materials Only -## Luster-Morris Parameter (M' Values) +This filter only works on **cubic m-3m Laue classes**. -The values are calculated as presented in [1]. +### How This Filter Works -## Fracture Initiation Parameter (fip) +1. For each **Face** in the **Triangle Geometry**, the filter identifies the two **Features** on either side +2. The average orientation of both **Features** is retrieved +3. Transmission metrics are calculated in both directions (Feature 1 → Feature 2 and Feature 2 → Feature 1), since the direction of slip approaching the boundary affects the result +4. Both directional values are stored on the **Face** -Three (3) *fip* values are computed as outputs to this filter. These are best explained in [2], see page 021012-4 +### Luster-Morris Parameter (M') + +The Luster-Morris parameter measures geometric compatibility between slip systems across a boundary. Calculated as presented in [1]. + +### Fracture Initiation Parameters (F1, F1spt, F7) + +Three fracture initiation parameter values are computed per **Face**, as defined in [2] (see page 021012-4): ![Fracture Initiation Parameter F1](Images/ComputeNeighborSlipTransmission_F1.png) ![Fracture Initiation Parameter F1spt](Images/ComputeNeighborSlipTransmission_F1spt.png) -![Fracture Initiation Parameter F7.png](Images/ComputeNeighborSlipTransmission_F7.png) - +![Fracture Initiation Parameter F7](Images/ComputeNeighborSlipTransmission_F7.png) -## Citations +## References [1] [Luster, J., Morris, M.A., 1995. *Compatibility Of Deformation In Two-Phase Ti-Al Alloys: Dependence On Microstructure And Orientation Relationships*. **Metallurgical and Materials Transactions A 26, 1745**](https://link.springer.com/article/10.1007/BF02670762) [2] [D. Kumar, T. R. Bieler, P. Eisenlohr, D. E. Mason, M. A. Crimp, F. Roters, and D. Raabe. On Predicting Nucleation of Microcracks Due to Slip Twin Interactions at Grain Boundaries in Duplex Near γ-TiAl. Journal of Engineering Materials and Technology, 130(2):021012–12, 2008. doi:10.1115/1.2841620.](https://doi.org/10.1115/1.2841620) +### Required Input Sources + +This filter operates on a grain-boundary surface mesh and requires the following upstream steps: + +- **Triangle Geometry** and **Face Labels** -- produced by a surface meshing filter such as [Quick Surface Mesh](../SimplnxCore/QuickSurfaceMeshFilter.md). +- **Average Quaternions** -- the per-feature average orientation produced by [Compute Average Orientations](ComputeAvgOrientationsFilter.md). +- **Feature Phases** -- produced by [Compute Feature Phases](../SimplnxCore/ComputeFeaturePhasesFilter.md). +- **Crystal Structures** -- ensemble-level array read from EBSD data or created by [Create Ensemble Info](CreateEnsembleInfoFilter.md). + % Auto generated parameter table will be inserted here ## Example Pipelines diff --git a/src/Plugins/OrientationAnalysis/docs/ComputeCAxisLocationsFilter.md b/src/Plugins/OrientationAnalysis/docs/ComputeCAxisLocationsFilter.md index 9183413de0..b7bba6a59f 100644 --- a/src/Plugins/OrientationAnalysis/docs/ComputeCAxisLocationsFilter.md +++ b/src/Plugins/OrientationAnalysis/docs/ComputeCAxisLocationsFilter.md @@ -6,15 +6,41 @@ Statistics (Crystallography) ## Description -This **Filter** determines the direction of the C-axis for each **Element** by applying the quaternion of the **Element** to the <001> direction, which is the C-axis for *Hexagonal* materials. This will tell where the C-axis of the **Element** sits in the *sample reference frame*. +This **Filter** computes the C-axis direction for each individual **Cell** (voxel) in hexagonal materials. The result is a unit vector per **Cell** that indicates where that cell's C-axis points in the sample reference frame. -*Note:* This **Filter** will only work properly for *Hexagonal* materials. The **Filter** does not apply any symmetry operators because there is only one c-axis (<001>) in *Hexagonal* materials and thus all symmetry operators will leave the c-axis in the same position in the sample *reference frame*. However, in *Cubic* materials, for example, the {100} family of directions are all equivalent and the <001> direction will change location in the *sample reference frame* when symmetry operators are applied. +### What is the C-Axis? + +In hexagonal crystal structures (such as titanium, magnesium, and zinc), the *C-axis* is the unique crystallographic direction that runs along the long axis of the hexagonal unit cell (the [001] direction). This axis is important because many mechanical and physical properties of hexagonal materials vary depending on whether they are measured along or perpendicular to the C-axis. + +![Fig. 1: The C-axis in a hexagonal unit cell.](Images/ComputeAvgCAxes_HexagonalCAxis.png) + +### How This Filter Works + +Each **Cell** has a measured crystal orientation stored as a quaternion. This filter uses that orientation to rotate the crystal [001] direction into the physical sample coordinate system, producing a 3D unit vector that describes where the C-axis points. + +The output vectors are normalized to unit length and constrained to the upper hemisphere (positive Z component) to provide a unique, unambiguous representation. + +### Hexagonal Materials Only + +This filter only produces valid results for hexagonal phases (6/mmm or 6/m symmetry). In hexagonal materials, the C-axis is unique -- there is only one [001] direction, so crystal symmetry does not create ambiguity. + +In cubic materials, the [001], [010], and [100] directions are all crystallographically equivalent. Applying symmetry operators would move the [001] direction to different positions in the sample frame, making this computation ambiguous. For this reason, **non-hexagonal phases will have their output values set to NaN**. + +### Comparison with Compute Average C-Axis Orientations + +This filter computes the C-axis direction for each individual **Cell**. If you need the average C-axis direction for each **Feature** (grain) instead, use the [Compute Average C-Axis Orientations](ComputeAvgCAxesFilter.md) filter. + +### Required Input Sources + +- **Cell Quaternions** -- typically read from EBSD data via [Read H5EBSD](ReadH5EbsdFilter.md), [Read CTF Data](ReadCtfDataFilter.md), or [Read ANG Data](ReadAngDataFilter.md); can also be produced from Euler angles by [Convert Orientations](ConvertOrientationsFilter.md). +- **Cell Phases** -- typically read from EBSD data alongside the quaternions. +- **Crystal Structures** -- ensemble-level array read from EBSD data or created by [Create Ensemble Info](CreateEnsembleInfoFilter.md). % Auto generated parameter table will be inserted here ## Example Pipelines -EBSD_Hexagonal_Data_Analysis ++ `EBSD_Hexagonal_Data_Analysis` ## License & Copyright diff --git a/src/Plugins/OrientationAnalysis/docs/ComputeFeatureNeighborCAxisMisalignmentsFilter.md b/src/Plugins/OrientationAnalysis/docs/ComputeFeatureNeighborCAxisMisalignmentsFilter.md index d4ea2cc0b1..bc7d2006c7 100644 --- a/src/Plugins/OrientationAnalysis/docs/ComputeFeatureNeighborCAxisMisalignmentsFilter.md +++ b/src/Plugins/OrientationAnalysis/docs/ComputeFeatureNeighborCAxisMisalignmentsFilter.md @@ -6,25 +6,39 @@ Statistics (Crystallography) ## Description -For each feature, the C-Axis misalignments are determined for each neighbor of the feature. The neighbor list is a variable that is passed in by the user. This "NeighborList" could have been generated from any other appropriate filter. This means that a neighbor list could represent all neighbors that are physically connected to the current feature (Find Feature Neighbors), within a certain radius of the feature (Compute Feature Neighborhoods) or any other custom filter. +This **Filter** computes the C-axis misalignment angle between each **Feature** (grain) and its neighbors in hexagonal materials. The C-axis misalignment is the angular difference between the C-axis directions of two neighboring grains -- it measures how closely their unique crystallographic axes are aligned. -There are 2 outputs from this filter: -- The list of misalignments -- Optionally the average of all misalignments. +This is distinct from a full misorientation, which considers the complete rotational difference between two crystal orientations. C-axis misalignment only considers the alignment of the [001] direction, which is often the most mechanically significant axis in hexagonal materials. -**The misalignment values are stored as Degrees.** +### Flexible Neighbor Definition -### Notes +The neighbor list is supplied by the user and can come from any filter that produces neighbor relationships. For example: +- [Compute Feature Neighbors](../SimplnxCore/ComputeFeatureNeighborsFilter.md) -- neighbors that physically share a boundary +- [Compute Feature Neighborhoods](../SimplnxCore/ComputeNeighborhoodsFilter.md) -- neighbors within a specified radius +- Any other custom filter that generates a neighbor list -**NOTE:** Only features with identical phase values and a crystal structure of **Hexagonal_High** will be calculated. If two features have different phase values or a crystal structure that is *not* Hexagonal_High then a value of NaN is set for the misorientation. +The filter also optionally computes the average misalignment across all of a feature's neighbors. -Results from this filter can differ from its original version in DREAM.3D 6.5.171 by around 0.0001. This version uses double precision and Eigen for matrix operations which account for the differences in output. +### Hexagonal Materials Only + +Only **Features** with identical phase values and a crystal structure of **Hexagonal_High** (6/mmm) or **Hexagonal_Low** (Hexagonal 6/m (C6h)) are compared. If two **Features** have different phases or a non-hexagonal crystal structure, a value of NaN is stored for the misalignment. See the [Compute Average C-Axis Orientations](ComputeAvgCAxesFilter.md) documentation for an explanation of why C-axis calculations are restricted to hexagonal materials. + +### Note + +Results from this filter may differ from the original DREAM.3D 6.5 version by approximately 0.0001 degrees due to the use of double precision and Eigen for matrix operations. + +### Required Input Sources + +- **Neighbor List** -- produced by [Compute Feature Neighbors](../SimplnxCore/ComputeFeatureNeighborsFilter.md) or [Compute Feature Neighborhoods](../SimplnxCore/ComputeNeighborhoodsFilter.md). +- **Average Quaternions** -- produced by [Compute Average Orientations](ComputeAvgOrientationsFilter.md). +- **Feature Phases** -- produced by [Compute Feature Phases](../SimplnxCore/ComputeFeaturePhasesFilter.md). +- **Crystal Structures** -- ensemble-level array read from EBSD data or created by [Create Ensemble Info](CreateEnsembleInfoFilter.md). % Auto generated parameter table will be inserted here ## Example Pipelines -EBSD_Hexagonal_Data_Analysis ++ `EBSD_Hexagonal_Data_Analysis` ## License & Copyright diff --git a/src/Plugins/OrientationAnalysis/docs/ComputeFeatureNeighborMisorientationsFilter.md b/src/Plugins/OrientationAnalysis/docs/ComputeFeatureNeighborMisorientationsFilter.md index 1c5de9377c..875a29df4d 100644 --- a/src/Plugins/OrientationAnalysis/docs/ComputeFeatureNeighborMisorientationsFilter.md +++ b/src/Plugins/OrientationAnalysis/docs/ComputeFeatureNeighborMisorientationsFilter.md @@ -6,19 +6,28 @@ Statistics (Crystallography) ## Description -This **Filter** determines, for each **Feature**, the misorientations with each of the **Features** that are in contact with it. The misorientations are stored as a list (for each **Feature**) of angles (in degrees). The axis of the misorientation is not stored by this **Filter**. +This **Filter** computes the misorientation angle between each **Feature** (grain) and its neighboring **Features**. Misorientation is the angular difference between the crystal orientations of two grains -- it describes how much one grain's crystal lattice is rotated relative to another's. -The user can also calculate the average misorientation between the feature and all contacting features. +For each **Feature**, the filter produces a list of misorientation angles (in degrees), one for each neighboring **Feature** it shares a boundary with. The axis of the misorientation is not stored, only the angle. -### Notes +Optionally, the filter can also compute the average misorientation between a **Feature** and all of its neighbors. This average value provides a quick summary of how differently oriented a grain is compared to its surroundings. -**NOTE:** Only features with identical crystal structures will be calculated. If two features have different crystal structures then a value of NaN is set for the misorientation. +### Note + +Only **Features** with identical crystal structures are compared. If two neighboring **Features** have different crystal structures, a value of NaN is stored for their misorientation, since misorientation between different crystal systems is not physically meaningful. + +### Required Input Sources + +- **Neighbor List** -- produced by [Compute Feature Neighbors](../SimplnxCore/ComputeFeatureNeighborsFilter.md) or [Compute Feature Neighborhoods](../SimplnxCore/ComputeNeighborhoodsFilter.md). +- **Average Quaternions** -- produced by [Compute Average Orientations](ComputeAvgOrientationsFilter.md). +- **Feature Phases** -- produced by [Compute Feature Phases](../SimplnxCore/ComputeFeaturePhasesFilter.md). +- **Crystal Structures** -- ensemble-level array read from EBSD data or created by [Create Ensemble Info](CreateEnsembleInfoFilter.md). % Auto generated parameter table will be inserted here ## Example Pipelines -+ (05) SmallIN100 Crystallographic Statistics ++ `(05) SmallIN100 Crystallographic Statistics` ## License & Copyright diff --git a/src/Plugins/OrientationAnalysis/docs/ComputeFeatureReferenceCAxisMisorientationsFilter.md b/src/Plugins/OrientationAnalysis/docs/ComputeFeatureReferenceCAxisMisorientationsFilter.md index 197a9b68cf..96759db1c3 100644 --- a/src/Plugins/OrientationAnalysis/docs/ComputeFeatureReferenceCAxisMisorientationsFilter.md +++ b/src/Plugins/OrientationAnalysis/docs/ComputeFeatureReferenceCAxisMisorientationsFilter.md @@ -6,17 +6,40 @@ Statistics (Crystallography) ## Description -This **Filter** calculates the misorientation angle between the C-axis of each **Cell** within a **Feature** and the average C-axis for that **Feature** and stores that value for each **Cell**. The average and standard deviation of those values for all **Cells** belonging to the same **Feature** is also stored for each **Feature**. +This **Filter** measures how much the C-axis orientation varies within each **Feature** (grain) in hexagonal materials. It does this by comparing the C-axis direction of each individual **Cell** (voxel) to the average C-axis direction for the grain it belongs to. -This filter requires at least one Hexagonal crystal structure phase (Hexagonal-Low 6/m or Hexagonal-High 6/mmm). Although it is not recommended, you can give input data with mixed phase types and all non hexagonal phases will be skipped in the calculations. +This metric is useful for characterizing intragranular orientation gradients -- regions within a grain where the crystal lattice has rotated relative to the grain's average orientation, which can indicate deformation, subgrain boundaries, or measurement noise. -Results from this filter can differ from its original version in DREAM3D 6.6 by around 0.0001. This version uses double precision in part of its calculation to improve agreement and accuracy between platforms (notably ARM). +### What This Filter Computes + +For each **Cell**, the filter calculates the angle (in degrees) between that cell's C-axis and the average C-axis of its parent **Feature**. The filter then computes summary statistics per **Feature**: + +- **Average misalignment** -- the mean C-axis deviation across all cells in the grain +- **Standard deviation** -- how much the deviation varies within the grain + +A low average misalignment indicates a grain with a uniform C-axis orientation. A high value suggests significant internal orientation variation. + +### Hexagonal Materials Only + +This filter requires at least one hexagonal crystal structure phase (6/m or 6/mmm). Non-hexagonal phases are skipped. See the [Compute Average C-Axis Orientations](ComputeAvgCAxesFilter.md) documentation for an explanation of why C-axis calculations are restricted to hexagonal materials. + +### Note + +Results may differ from the DREAM3D 6.6 version by approximately 0.0001 degrees due to improved double-precision calculations for cross-platform accuracy. + +### Required Input Sources + +- **Cell Feature Ids** -- produced by a segmentation filter such as [Segment Features (Misorientation)](EBSDSegmentFeaturesFilter.md) or [Segment Features (C-Axis Misalignment)](CAxisSegmentFeaturesFilter.md). +- **Cell Quaternions** -- typically read from EBSD data via [Read H5EBSD](ReadH5EbsdFilter.md), [Read CTF Data](ReadCtfDataFilter.md), or [Read ANG Data](ReadAngDataFilter.md). +- **Cell Phases** -- typically read from EBSD data alongside the quaternions. +- **Average C-Axes** -- produced by [Compute Average C-Axis Orientations](ComputeAvgCAxesFilter.md). +- **Crystal Structures** -- ensemble-level array read from EBSD data or created by [Create Ensemble Info](CreateEnsembleInfoFilter.md). % Auto generated parameter table will be inserted here ## Example Pipelines -EBSD_Hexagonal_Data_Analysis ++ `EBSD_Hexagonal_Data_Analysis` ## License & Copyright diff --git a/src/Plugins/OrientationAnalysis/docs/ComputeFeatureReferenceMisorientationsFilter.md b/src/Plugins/OrientationAnalysis/docs/ComputeFeatureReferenceMisorientationsFilter.md index 4332b76d13..50bd9b9d53 100644 --- a/src/Plugins/OrientationAnalysis/docs/ComputeFeatureReferenceMisorientationsFilter.md +++ b/src/Plugins/OrientationAnalysis/docs/ComputeFeatureReferenceMisorientationsFilter.md @@ -6,16 +6,16 @@ Statistics (Crystallography) ## Description -This **Filter** calculates the misorientation angle between each **Cell** within a **Feature** and a -*reference orientation* for that **Feature**. The user can choose the *reference orientation* to -be used for the **Features** from a drop-down menu. The options for the *reference orientation* are -the average orientation of the **Feature** or the orientation of the **Cell** that is furthest from -the *boundary* of the **Feature**. +This **Filter** measures how much crystal orientation varies within each **Feature** (grain) by computing the misorientation angle between each **Cell** (voxel) and a chosen *reference orientation* for that **Feature**. -Note: the average orientation of the **Feature** is a typical choice, but if the **Feature** has -undergone plastic deformation and the amount of lattice rotation developed is of interest, then -it may be more reasonable to use the orientation *near the center* of the **Feature** as it may -not have rotated and thus serve as a better *reference orientation*. +This is useful for detecting intragranular orientation gradients caused by plastic deformation, subgrain formation, or other processes that cause the crystal lattice to rotate within a grain. + +### Choosing a Reference Orientation + +The user selects the reference orientation from two options. The choice depends on the physical question being asked: + +- **Average Feature Orientation** -- Uses the average orientation of all cells in the grain. This is the typical choice for characterizing overall orientation spread within a grain. +- **Orientation Farthest from Feature Boundary** -- Uses the orientation of the cell nearest to the Euclidean center of the grain (farthest from any boundary). If the grain has undergone plastic deformation, boundary regions tend to rotate more than the interior. Using the center cell as the reference provides a more stable baseline that better reveals the pattern of lattice rotation from the interior outward. ### Reference Orientation @@ -53,6 +53,15 @@ feature boundary, and use that voxel's orientation as the **reference orientatio ![ComputeFeatureReferenceMisorientations_1.png](Images/ComputeFeatureReferenceMisorientations_1.png) +### Required Input Sources + +- **Cell Feature Ids** -- produced by a segmentation filter such as [Segment Features (Misorientation)](EBSDSegmentFeaturesFilter.md). +- **Cell Quaternions** -- typically read from EBSD data via [Read H5EBSD](ReadH5EbsdFilter.md), [Read CTF Data](ReadCtfDataFilter.md), or [Read ANG Data](ReadAngDataFilter.md). +- **Cell Phases** -- typically read from EBSD data alongside the quaternions. +- **Average Quaternions** (for Average Feature Orientation mode) -- produced by [Compute Average Orientations](ComputeAvgOrientationsFilter.md). +- **Boundary Euclidean Distances** (for Orientation Farthest from Feature Boundary mode) -- produced by [Compute Euclidean Distance Map](../SimplnxCore/ComputeEuclideanDistMapFilter.md). +- **Crystal Structures** -- ensemble-level array read from EBSD data or created by [Create Ensemble Info](CreateEnsembleInfoFilter.md). + % Auto generated parameter table will be inserted here ## Example Pipelines diff --git a/src/Plugins/OrientationAnalysis/docs/ComputeGBCDFilter.md b/src/Plugins/OrientationAnalysis/docs/ComputeGBCDFilter.md index 5bb54a2536..8c5f756a67 100644 --- a/src/Plugins/OrientationAnalysis/docs/ComputeGBCDFilter.md +++ b/src/Plugins/OrientationAnalysis/docs/ComputeGBCDFilter.md @@ -6,13 +6,55 @@ Statistics (Crystallography) ## Description -This **Filter** computes the 5D grain boundary character distribution (GBCD) for a **Triangle Geometry**, which is the relative area of grain boundary for a given misorientation and normal. The GBCD can be visualized by using either the **Write GBCD Pole Figure (GMT)** or the **Write GBCD Pole Figure (VTK)** **Filters**. +This **Filter** computes the Grain Boundary Character Distribution (GBCD) for a **Triangle Geometry**. The GBCD is a statistical description of the types of grain boundaries present in a polycrystalline material. It answers the question: *"What fraction of the total grain boundary area has a given misorientation and boundary plane orientation?"* + +### What is the GBCD? + +In a polycrystalline material, grains meet at boundaries. Each boundary can be described by five parameters: + +- **3 parameters** for the *misorientation* -- the rotational difference between the crystal orientations of the two grains on either side of the boundary +- **2 parameters** for the *boundary plane normal* -- the direction the boundary surface faces, expressed in the crystal reference frame + +The GBCD is a histogram over this 5-dimensional space. It records how much grain boundary area exists for each combination of misorientation and boundary plane orientation, normalized so that a random distribution would give a value of 1.0. Results are reported in *multiples of a random distribution* (MRD), so a value of 2.0 means there is twice as much boundary of that type as would be expected in a random polycrystal. + +### How This Filter Works + +1. For each triangular face on the grain boundary mesh, the filter identifies the two grains on either side. +2. It computes the misorientation between the two grains and determines the boundary plane normal in the crystal reference frame. +3. Crystal symmetry is applied to map each boundary into a unique representation. +4. The boundary is placed into the appropriate bin of the 5D histogram, weighted by its area. +5. The result is normalized by the total boundary area. + +The **GBCD Resolution** parameter controls the bin size of the histogram. Smaller values give finer resolution but require more boundary data for statistical reliability. + +### Note + +Only boundaries between grains of the same phase are included in the calculation. The GBCD can be visualized by using the [Write GBCD Pole Figure (GMT)](WriteGBCDGMTFileFilter.md) or [Compute GBCD Pole Figure](ComputeGBCDPoleFigureFilter.md) filters. + +For an alternative approach to computing the GBCD using continuous metrics instead of binning, see the [Compute GBCD (Metric-Based Approach)](ComputeGBCDMetricBasedFilter.md) filter. + +### Required Input Sources + +This filter operates on a grain-boundary surface mesh and requires the following upstream steps: + +- **Triangle Geometry** -- produced by a surface meshing filter such as [Quick Surface Mesh](../SimplnxCore/QuickSurfaceMeshFilter.md), optionally followed by [Laplacian Smoothing](../SimplnxCore/LaplacianSmoothingFilter.md). +- **Face Labels** -- produced alongside the mesh by [Quick Surface Mesh](../SimplnxCore/QuickSurfaceMeshFilter.md). +- **Face Normals** -- produced by [Compute Triangle Normals](../SimplnxCore/TriangleNormalFilter.md). +- **Face Areas** -- produced by [Compute Triangle Areas](../SimplnxCore/ComputeTriangleAreasFilter.md). +- **Feature Euler Angles / Feature Phases** -- the feature-level average Euler angles and phases. Averages are produced by [Compute Average Orientations](ComputeAvgOrientationsFilter.md); phases by [Compute Feature Phases](../SimplnxCore/ComputeFeaturePhasesFilter.md). +- **Crystal Structures** -- ensemble-level array read from EBSD data or created by [Create Ensemble Info](CreateEnsembleInfoFilter.md). + +## References + +[1] G. S. Rohrer, "Grain boundary energy anisotropy: a review," *Journal of Materials Science*, vol. 46, pp. 5881-5895, 2011. DOI: [10.1007/s10853-011-5677-3](https://doi.org/10.1007/s10853-011-5677-3) + +[2] G. S. Rohrer, "Measuring and Interpreting the Structure of Grain-Boundary Networks," *Journal of the American Ceramic Society*, vol. 94, no. 3, pp. 633-646, 2011. DOI: [10.1111/j.1551-2916.2011.04384.x](https://doi.org/10.1111/j.1551-2916.2011.04384.x) % Auto generated parameter table will be inserted here ## Example Pipelines -+ (08) Small IN100 GBCD ++ `(08) Small IN100 GBCD` ## License & Copyright diff --git a/src/Plugins/OrientationAnalysis/docs/ComputeGBCDMetricBasedFilter.md b/src/Plugins/OrientationAnalysis/docs/ComputeGBCDMetricBasedFilter.md index 092dc86566..5ab6dffb45 100644 --- a/src/Plugins/OrientationAnalysis/docs/ComputeGBCDMetricBasedFilter.md +++ b/src/Plugins/OrientationAnalysis/docs/ComputeGBCDMetricBasedFilter.md @@ -6,11 +6,18 @@ Statistics (Crystallography) ## Description -This **Filter** computes a section through the five-dimensional grain boundary distirbution for a fixed misorientation. An example of such a section is shown in Fig. 1. Differently than **Compute GBCD Filter**, which uses a method based on partition of the boundary space into bins, this **Filter** implements an alternative metric-based approach described by K. Glowinski and A. Morawiec in [Analysis of experimental grain boundary distributions based on boundary-space metrics, Metall. Mater. Trans. A 45, 3189-3194 (2014)](https://link.springer.com/article/10.1007/s11661-014-2325-y) +This **Filter** computes a section through the five-dimensional grain boundary character distribution (GBCD) for a fixed misorientation, using a metric-based approach rather than binning. An example of such a section is shown in Fig. 1. + +Unlike the [Compute GBCD](ComputeGBCDFilter.md) filter, which partitions the boundary space into discrete bins, this filter uses a continuous metric-based approach described by K. Glowinski and A. Morawiec in [Analysis of experimental grain boundary distributions based on boundary-space metrics, Metall. Mater. Trans. A 45, 3189-3194 (2014)](https://link.springer.com/article/10.1007/s11661-014-2325-y). The metric-based approach avoids discretization artifacts and can produce smoother distributions, especially with limited data. ![Fig. 1: Section for the 17.9 deg./[111] misorientation through the grain boundary distribution obtained using this Filter for the small IN100 data set. Units are multiples of random distribution (MRDs).](Images/ComputeGBCDMetricBased_dist.png) -Metrics in the boundary space can be defined in a number of ways, but it is essential that two boundaries are close (distant) if they have similar (different) geometric features, and that symmetrically equivalent representations of boundaries are taken into consideration. Formally, the boundary space is a Cartesian product of the misorientation and boundary-normal subspaces. For computational reasons and because of considerably different resolutions in determinination of grain misorientation and boundary-plane parameters, it is convenient to use a separate metric in each subspace. With separate metrics, the procedure for computing distribution values for a selected misorientation has two stages. First, boundary segments with misorientations located not farther from the fixed misorientation than a limiting distance ρm are selected. In the second stage, the distribution is probed at evenly distributed normal directions (see Fig. 2), and areas of boundaries whose normals deviate from a given direction by less than ρp are summed. (The radii ρm and ρp should be tailored to resolution, amount, and quality of data and set.) Eventually, the obtained distribution is normalized in order to express it in the conventional units, i.e., multiples of the random distribution. +The metric-based approach defines distance measures in the boundary space so that boundaries with similar geometry are considered "close" and boundaries with different geometry are considered "distant," taking crystal symmetry into account. The procedure has two stages: + +1. **Misorientation selection:** Boundary segments whose misorientation is within a limiting angular distance ρm of the user-specified fixed misorientation are selected. +2. **Normal probing:** The distribution is sampled at evenly distributed normal directions (see Fig. 2). For each sampling direction, the areas of boundaries whose normals fall within ρp of that direction are summed. + +The limiting distances ρm and ρp should be chosen based on the resolution, amount, and quality of the data. The result is normalized and expressed in multiples of a random distribution (MRD). | Image | |-------| @@ -55,6 +62,14 @@ The *Limiting Distances* parameter selects the maximum angular deviations used w - **7 deg. Misorientations; 7 deg. Plane Inclinations [5]**: Use a 7-degree radius for both misorientations and plane inclinations. - **8 deg. Misorientations; 8 deg. Plane Inclinations [6]**: Use an 8-degree radius for both misorientations and plane inclinations. +### Required Input Sources + +This filter operates on a grain-boundary surface mesh and requires the following upstream steps: + +- **Triangle Geometry** with **Face Labels**, **Face Normals**, **Face Areas**, and **Node Types** -- produced by a surface meshing filter such as [Quick Surface Mesh](../SimplnxCore/QuickSurfaceMeshFilter.md), followed by [Compute Triangle Normals](../SimplnxCore/TriangleNormalFilter.md) and [Compute Triangle Areas](../SimplnxCore/ComputeTriangleAreasFilter.md). +- **Feature Euler Angles / Feature Phases** -- feature-level averages produced by [Compute Average Orientations](ComputeAvgOrientationsFilter.md) and [Compute Feature Phases](../SimplnxCore/ComputeFeaturePhasesFilter.md). +- **Crystal Structures** -- ensemble-level array read from EBSD data or created by [Create Ensemble Info](CreateEnsembleInfoFilter.md). + % Auto generated parameter table will be inserted here ## References diff --git a/src/Plugins/OrientationAnalysis/docs/ComputeGBPDMetricBasedFilter.md b/src/Plugins/OrientationAnalysis/docs/ComputeGBPDMetricBasedFilter.md index 6591151393..265e2664fd 100644 --- a/src/Plugins/OrientationAnalysis/docs/ComputeGBPDMetricBasedFilter.md +++ b/src/Plugins/OrientationAnalysis/docs/ComputeGBPDMetricBasedFilter.md @@ -6,7 +6,17 @@ Statistics (Crystallography) ## Description -This **Filter** computes the grain boundary plane distribution (GBPD) like that shown in Fig. 1. It should be noted that most GBPDs presented so far in literature were obtained using a method based on partition of the grain boundary space into bins, similar to that implemented in the *Compute GBCD* **Filter**. This **Filter** calculates the GBPD using an alternative approach adapted from the one included in the *Compute GBCD (Metric-based Approach)* **Filter** and described by K. Glowinski and A. Morawiec in [Analysis of experimental grain boundary distributions based on boundary-space metrics, Metall. Mater. Trans. A 45, 3189-3194 (2014)](http://link.springer.com/article/10.1007%2Fs11661-014-2325-y). Briefly, the GBPD is probed at evenly distributed sampling directions (similarly to *Compute GBCD (Metric-based Approach)* **Filter**) and areas of mesh segments with their normal vectors deviated by less than a limiting angle ρp from a given direction are summed. If *n*S is the number of crystal symmetry transformations, each boundary plane segment is represented by up to 4 × *n*S equivalent vectors, and all of them are processed. It is enough to sample the distribution at directions corresponding to the standard stereographic triangle (or, in general, to a fundamental region corresponding to a considered crystallographic point group); values at remaining points are obtained based on crystal symmetries. After summing the boundary areas, the distribution is normalized. First, the values at sampling vectors are divided by the total area of all segments. Then, in order to express the distribution in the conventional units, i.e., multiples of random distribution (MRDs), the obtained fractional values are divided by the volume *v* = (*A* nS) / (4π), where *A* is the area of a spherical cap determined by ρp. +This **Filter** computes the Grain Boundary Plane Distribution (GBPD), which describes the relative frequency of grain boundary plane orientations in a polycrystalline material, regardless of the misorientation across the boundary. While the GBCD (see [Compute GBCD](ComputeGBCDFilter.md)) describes boundaries in the full 5D space of misorientation + plane normal, the GBPD considers only the 2D distribution of boundary plane normals. + +An example GBPD is shown in Fig. 1. + +### Metric-Based Approach + +This filter uses a metric-based approach adapted from the [Compute GBCD (Metric-Based Approach)](ComputeGBCDMetricBasedFilter.md) filter, as described by K. Glowinski and A. Morawiec in [Analysis of experimental grain boundary distributions based on boundary-space metrics, Metall. Mater. Trans. A 45, 3189-3194 (2014)](http://link.springer.com/article/10.1007%2Fs11661-014-2325-y). + +The distribution is sampled at evenly distributed directions. For each sampling direction, the areas of mesh segments whose normals fall within a limiting angle ρp of that direction are summed. Crystal symmetry is applied so that each boundary segment is represented by up to 4 × *n*S equivalent vectors (where *n*S is the number of symmetry transformations). Only directions within the standard stereographic triangle need to be sampled; values at other points are obtained from symmetry. + +After summing boundary areas, the distribution is normalized to multiples of a random distribution (MRD). A value of 1.0 means that plane orientation is as frequent as in a random polycrystal; values above 1.0 indicate preferred boundary plane orientations. ![Fig. 1: GBPD obtained for Small IN100 with the limiting distance set to 7° and with triangles adjacent to triple lines removed. Units are MRDs.](Images/ComputeGBPDMetricBased_example.png) @@ -16,7 +26,7 @@ This **Filter** also calculates statistical errors of the distributions using th is the relative error of the distribution function at a given point, *f* is the value of the function at that point, and *n* stands for the number of grain boundaries (**not** the number of mesh triangles) in the considered network. The errors can be calculated either as their absolute values, i.e., ε × *f* or as relative errors, i.e., 100% × ε. The latter are computed in a way that if the relative error exceeds 100%, it is rounded down to 100%. -See also the documentation for {ref}`Compute GBCD (Metric-based Approach) Filter ` for additional information. +See also the documentation for [Compute GBCD (Metric-Based Approach)](ComputeGBCDMetricBasedFilter.md) for additional information. ## Format of Output Files @@ -32,6 +42,15 @@ Then, the directions are given as [ sin θ × cos φ , sin θ ## Feedback In the case of any questions, suggestions, bugs, etc., please feel free to email the author of this **Filter** at kglowinski *at* ymail.com + +### Required Input Sources + +This filter operates on a grain-boundary surface mesh and requires the following upstream steps: + +- **Triangle Geometry** with **Face Labels**, **Face Normals**, **Face Areas**, and **Node Types** -- produced by a surface meshing filter such as [Quick Surface Mesh](../SimplnxCore/QuickSurfaceMeshFilter.md), followed by [Compute Triangle Normals](../SimplnxCore/TriangleNormalFilter.md) and [Compute Triangle Areas](../SimplnxCore/ComputeTriangleAreasFilter.md). +- **Feature Phases** -- produced by [Compute Feature Phases](../SimplnxCore/ComputeFeaturePhasesFilter.md). +- **Crystal Structures** -- ensemble-level array read from EBSD data or created by [Create Ensemble Info](CreateEnsembleInfoFilter.md). + % Auto generated parameter table will be inserted here ## References diff --git a/src/Plugins/OrientationAnalysis/docs/ComputeKernelAvgMisorientationsFilter.md b/src/Plugins/OrientationAnalysis/docs/ComputeKernelAvgMisorientationsFilter.md index c6e615cc2a..375dd08423 100644 --- a/src/Plugins/OrientationAnalysis/docs/ComputeKernelAvgMisorientationsFilter.md +++ b/src/Plugins/OrientationAnalysis/docs/ComputeKernelAvgMisorientationsFilter.md @@ -6,21 +6,64 @@ Statistics (Crystallography) ## Description -This **Filter** determines the Kernel Average Misorientation (KAM) for each **Cell**. The user can select the size of the kernel to be used in the calculation. The kernel size entered by the user is the *radius* of the kernel (i.e., entering values of *1*, *2*, *3* will result in a kernel that is *3*, *5*, and *7* **Cells** in size in the X, Y and Z directions, respectively). The algorithm for determination of KAM is as follows: +This **Filter** determines the Kernel Average Misorientation (KAM) for each **Cell**. The user can select the size of the kernel (in voxels) to be used in the calculation. The algorithm for the determination of KAM is as follows: -1. Calculate the misorientation angle between each **Cell** in a kernel and the central **Cell** of the kernel +1. Calculate the misorientation angle between each **Cell** in a kernel and the central **Cell** of the kernel **only** if the kernel cell belongs to the same `FeatureId`. 2. Average all of the misorientations for the kernel and store at the central **Cell** -The calculation will **not** consider cells that belong to different 'feature Ids', ie.e, different grains. +Only **Cells** that belong to the same **Feature** (i.e., have the same Feature Id) as the central **Cell** are included in the average. -*Note:* All **Cells** in the kernel are weighted equally during the averaging, though they are not equidistant from the central **Cell**. +### Note + +All **Cells** in the kernel are weighted equally during the averaging, though they are not equidistant from the central **Cell**. + +### Understanding the Kernel Radius + +The *Kernel Radius* parameter has three components (X, Y, Z), and each value specifies how many **Cells** to extend outward from the center **Cell** along that axis. The resulting kernel size along each axis is: + +![Fig. 1: The kernel radius to kernel size formula.](Images/ComputeKernelAvgMisorientations_Formula.png) + +The kernel extends the specified radius in *both* directions (e.g., left and right) along each axis, plus includes the center **Cell** itself -- hence the formula. The radius can be set independently for each axis. For example, a Kernel Radius of *(1, 2, 3)* produces a kernel that is 3 × 5 × 7 **Cells** in the X, Y, and Z directions, respectively. + +#### 1D Examples + +Consider a single row of **Cells**. With a radius of 1, the kernel extends 1 **Cell** in each direction from the center, giving a kernel of size 3: + +![Fig. 2: 1D kernel with radius 1 produces a kernel size of 3.](Images/ComputeKernelAvgMisorientations_1D_Radius1.png) + +Increasing the radius to 2 extends 2 **Cells** in each direction, giving a kernel of size 5: + +![Fig. 3: 1D kernel with radius 2 produces a kernel size of 5.](Images/ComputeKernelAvgMisorientations_1D_Radius2.png) + +#### 2D Examples + +In 2D, the kernel forms a rectangular region around the center **Cell**. With a symmetric radius of (1, 1), the kernel is a 3 × 3 square: + +![Fig. 4: 2D kernel with radius (1, 1, 0) produces a 3x3 kernel of 9 cells.](Images/ComputeKernelAvgMisorientations_2D_Radius110.png) + +When different radii are used per axis, the kernel becomes non-square. With X Radius = 1 and Y Radius = 2, the kernel is 3 **Cells** wide and 5 **Cells** tall: + +![Fig. 5: 2D kernel with radius (1, 2, 0) produces a 3x5 kernel of 15 cells.](Images/ComputeKernelAvgMisorientations_2D_Radius120.png) + +In 3D, the Z Radius works the same way, extending into adjacent slices above and below the center **Cell**. + +#### Quick Reference + +![Fig. 6: Common radius values and their resulting kernel sizes.](Images/ComputeKernelAvgMisorientations_Table.png) + +### Required Input Sources + +- **Cell Feature Ids** -- produced by a segmentation filter such as [Segment Features (Misorientation)](EBSDSegmentFeaturesFilter.md). +- **Cell Quaternions** -- typically read from EBSD data via [Read H5EBSD](ReadH5EbsdFilter.md), [Read CTF Data](ReadCtfDataFilter.md), or [Read ANG Data](ReadAngDataFilter.md). +- **Cell Phases** -- typically read from EBSD data alongside the quaternions. +- **Crystal Structures** -- ensemble-level array read from EBSD data or created by [Create Ensemble Info](CreateEnsembleInfoFilter.md). % Auto generated parameter table will be inserted here ## Example Pipelines -+ MassifPipeline -+ (05) SmallIN100 Crystallographic Statistics ++ `MassifPipeline` ++ `(05) SmallIN100 Crystallographic Statistics` ## License & Copyright diff --git a/src/Plugins/OrientationAnalysis/docs/ComputeSchmidsFilter.md b/src/Plugins/OrientationAnalysis/docs/ComputeSchmidsFilter.md index fea1712097..dee10769d3 100644 --- a/src/Plugins/OrientationAnalysis/docs/ComputeSchmidsFilter.md +++ b/src/Plugins/OrientationAnalysis/docs/ComputeSchmidsFilter.md @@ -6,19 +6,47 @@ Statistics (Crystallography) ## Description -This **Filter** calculates the Schmid factor of each **Feature** given its average orientation and a user defined loading axis. The Schmid Factor is the combination of the component of the axial force *F* that lies parallel to the slip direction and the component that lies perpendicular to the slip plane. The equation for the Schmid Factor is given as: +This **Filter** calculates the Schmid factor for each **Feature** (grain), which measures how favorably oriented that grain is for plastic deformation under a given loading direction. A higher Schmid factor means the grain is more likely to deform (slip) under the applied load. -Schmid Factor = (cos φ cos λ) +### What is the Schmid Factor? -*The angle φ is the angle between the tensile axis and the slip plane normal, and λ is the angle between the tensile axis and the slip direction in the slip plane.* +When a force is applied to a polycrystalline material, each grain responds differently depending on how its internal crystal planes are oriented relative to the loading direction. Deformation occurs by *slip* -- atoms sliding along specific crystal planes in specific directions. Each combination of a slip plane and a slip direction is called a *slip system*. -The **Filter** determines the Schmid factor for each **Feature** by using the above equation for all possible slip systems (given the **Feature's** crystal structure). The largest Schmid factor from all of the slip systems is stored for the **Feature**. Only the Schmid factor is used in determining which slip system's Schmid factor to report. The critical resolved shear stress for the different slip systems is not considered. +The Schmid factor quantifies how much of the applied force is resolved onto a given slip system: + +**Schmid Factor = cos(φ) × cos(λ)** + +where: + +- **φ** is the angle between the loading axis and the *slip plane normal* (the direction perpendicular to the slip plane) +- **λ** is the angle between the loading axis and the *slip direction* (the direction atoms slide along within the slip plane) + +The Schmid factor ranges from 0 to 0.5. A value of 0.5 means the slip system is optimally aligned with the applied load. A value near 0 means the slip system is poorly oriented for deformation. + +![Fig. 1: The geometric relationship between the tensile axis, slip plane, and slip direction that defines the Schmid factor.](Images/ComputeSchmids_SchmidFactor.png) + +### How This Filter Works + +1. The user specifies a **Loading Direction** as a unit vector in the sample reference frame (e.g., [0, 0, 1] for loading along the Z-axis). This is a dimensionless direction, not a magnitude. +2. For each **Feature**, the filter rotates the loading direction from the sample frame into the grain's crystal frame using the grain's average orientation. +3. The filter evaluates the Schmid factor for every slip system available for that grain's crystal structure. +4. By default, the slip system with the **largest** Schmid factor is reported. Alternatively, the user can specify a particular slip plane and slip direction to evaluate. + +### Note + +Only the geometric Schmid factor is considered. The critical resolved shear stress (CRSS), which varies between slip systems in real materials, is not taken into account. This means the reported "most favorable" slip system is based purely on geometric alignment, not on the actual stress required to activate slip. + +### Required Input Sources + +- **Average Quaternions** -- the per-feature average orientation produced by [Compute Average Orientations](ComputeAvgOrientationsFilter.md). +- **Feature Phases** -- produced by [Compute Feature Phases](../SimplnxCore/ComputeFeaturePhasesFilter.md). +- **Crystal Structures** -- ensemble-level array read from EBSD data or created by [Create Ensemble Info](CreateEnsembleInfoFilter.md). % Auto generated parameter table will be inserted here ## Example Pipelines -+ (05) SmallIN100 Crystallographic Statistics ++ `(05) SmallIN100 Crystallographic Statistics` ## License & Copyright diff --git a/src/Plugins/OrientationAnalysis/docs/ComputeShapesFilter.md b/src/Plugins/OrientationAnalysis/docs/ComputeShapesFilter.md index afc6050c09..b0e5c862ad 100644 --- a/src/Plugins/OrientationAnalysis/docs/ComputeShapesFilter.md +++ b/src/Plugins/OrientationAnalysis/docs/ComputeShapesFilter.md @@ -6,33 +6,48 @@ Statistics (Morphological) ## Description -This **Filter** calculates the second-order moments of each **Feature** in order to determine the *principal axis lengths, principal axis directions, aspect ratios and moment invariant Omega3s*. The *principal axis lengths* are those of a "best-fit" ellipsoid. The algorithm for determining the moments and these values is as follows: +This **Filter** characterizes the 3D shape of each **Feature** (grain or particle) by fitting a best-fit ellipsoid to its voxels. The result is a set of shape descriptors including axis lengths, aspect ratios, axis orientations, and a shape invariant (Omega3). -1. For each **Cell**, determine the x, y and z distance to the centroid of the **Feature** that owns the **Cell** -2. For each **Cell**, calculate Ixx, Iyy, Izz, Ixy, Ixz and Iyz using the x, y and z distances determined in step 1. -3. Sum the individual Ixx, Iyy, Izz, Ixy, Ixz and Iyz values for all **Cells** belonging to the same **Feature** -4. Find the *eigenvalues* and *eigenvectors* of the *3x3* symmetric matrix defined by the *6* values calculated in step 3 for each **Feature** -5. Use the relationship of *principal moments* to the *principal axis lengths* for an ellipsoid, which can be found in [4], to determine the *Semi-Axis Lengths* -6. Calculate the *Aspect Ratios* from the *Semi-Axis Lengths* found in step 5. -7. Determine the Euler angles required to represent the *principal axis directions* in the *sample reference frame* and store them as the **Feature**'s *Axis Euler Angles*. -8. Calculate the moment variant Omega3 as definied in [2] and is discussed further in [1] and [3] +### What This Filter Produces + +- **Semi-Axis Lengths** -- The half-lengths of the three principal axes of the best-fit ellipsoid (a ≥ b ≥ c). These describe the size and elongation of the grain. +- **Aspect Ratios** -- The ratios b/a and c/a, which describe the grain's shape independent of its size. An equiaxed (roughly spherical) grain has aspect ratios near 1.0; an elongated grain has lower values. +- **Axis Euler Angles** -- The orientation of the ellipsoid's principal axes in the sample reference frame, stored as Euler angles. These describe which direction the grain is elongated. +- **Omega3** -- A dimensionless shape invariant derived from the second-order moments [2]. Omega3 is 1.0 for a perfect sphere and decreases for shapes that deviate from spherical. It provides a single-number summary of how "round" a grain is, independent of its size or orientation. + +### How This Filter Works + +1. For each **Cell**, compute the x, y, and z distances from the cell center to the centroid of its parent **Feature** +2. Accumulate the second-order moment terms (Ixx, Iyy, Izz, Ixy, Ixz, Iyz) for all **Cells** in each **Feature** +3. Solve for the eigenvalues and eigenvectors of the resulting 3x3 moment tensor for each **Feature** +4. Convert eigenvalues to ellipsoid semi-axis lengths using the relationship between principal moments and axis lengths [4] +5. Compute aspect ratios, axis orientation angles, and the Omega3 shape invariant + +### Note + +For shape analysis on triangle geometry meshes rather than voxelized image geometry, see the [Compute Feature Shapes (Triangle Geometry)](ComputeShapesTriangleGeomFilter.md) filter. + +### Required Input Sources + +- **Cell Feature Ids** -- produced by a segmentation filter such as [Segment Features (Misorientation)](EBSDSegmentFeaturesFilter.md) or [Segment Features (Scalar)](../SimplnxCore/ScalarSegmentFeaturesFilter.md). +- **Feature Centroids** -- produced by [Compute Feature Centroids](../SimplnxCore/ComputeFeatureCentroidsFilter.md). % Auto generated parameter table will be inserted here -## References ## +## References [1] Representation and Reconstruction of Three-dimensional Microstructures in Ni-based Superalloys, AFOSR FA9550-07-1-0179 Final Report, 20 Dec 2010. -[2] On the use of moment invariants for the automated classifcation of 3-D particle shapes, J. MacSleyne, J.P. Simmons and M. De Graef, Modeling and Simulations in Materials Science and Engineering, 16, 045008 (2008). +[2] J. MacSleyne, J.P. Simmons, and M. De Graef. On the use of moment invariants for the automated classification of 3-D particle shapes. *Modeling and Simulations in Materials Science and Engineering*, 16, 045008 (2008). -[3] n-Dimensional Moment Invariants and Conceptual Mathematical Theory of Recognition n-Dimensional Solids, Alexander G. Mamistvalov, IEEE TRANSACTIONS ON PATTERN ANALYSIS AND MACHINE INTELLIGENCE, VOL. 20, NO. 8, AUGUST 1998, p. 819-831. +[3] A.G. Mamistvalov. n-Dimensional Moment Invariants and Conceptual Mathematical Theory of Recognition n-Dimensional Solids. *IEEE Transactions on Pattern Analysis and Machine Intelligence*, 20(8), 819-831 (1998). -[4] M. Groeber, M. Uchic, D. Dimiduk, and S. Ghosh. A Framework for Automated Analysis and Simulation of 3D Polycrystalline Microstructures, Part 1: Statistical Characterization Acta Materialia, 56 (2008), 1257-1273. +[4] M. Groeber, M. Uchic, D. Dimiduk, and S. Ghosh. A Framework for Automated Analysis and Simulation of 3D Polycrystalline Microstructures, Part 1: Statistical Characterization. *Acta Materialia*, 56, 1257-1273 (2008). ## Example Pipelines -+ (03) Small IN100 Morphological Statistics -+ (06) SmallIN100 Synthetic ++ `(03) Small IN100 Morphological Statistics` ++ `(06) SmallIN100 Synthetic` ## License & Copyright diff --git a/src/Plugins/OrientationAnalysis/docs/ComputeShapesTriangleGeomFilter.md b/src/Plugins/OrientationAnalysis/docs/ComputeShapesTriangleGeomFilter.md index b87ee1bb6e..35344f98e7 100644 --- a/src/Plugins/OrientationAnalysis/docs/ComputeShapesTriangleGeomFilter.md +++ b/src/Plugins/OrientationAnalysis/docs/ComputeShapesTriangleGeomFilter.md @@ -4,23 +4,22 @@ Statistics (Morphological) -## Caveats +## Description -This filter has two caveats. +This **Filter** characterizes the 3D shape of each enclosed **Feature** in a **Triangle Geometry** surface mesh by fitting a best-fit ellipsoid. It produces the same types of shape descriptors as the [Compute Feature Shapes (Image Geometry)](ComputeShapesFilter.md) filter -- axis lengths, aspect ratios, axis orientations, and the Omega3 shape invariant -- but operates on triangle meshes rather than voxelized data. -Firstly, the axial lengths of this filter will be different than those produced by the voxelized version of this filter. This is for two reasons: +For a description of what each output represents (semi-axis lengths, aspect ratios, Omega3, etc.), see the [Compute Feature Shapes (Image Geometry)](ComputeShapesFilter.md) documentation. -- The sampling rate and density for the grid that was used to voxelize the mesh. See *Sample Triangle Geometry on Regular Grid* (RegularGridSampleSurfaceMesh). -- This filter determines axial lengths via distance from feature centroid to mesh intersection points along each of the principle axes. This means they are relative to the mesh itself rather than the grid it exists in. +### Differences from the Image Geometry Version -Secondly, shapes that exhibit rotational symmetry (e.g. cube, sphere, regular octahedron, etc.) may have different Euler Angles than those of the voxelized implementation, but they are functionally identical. This is more prevalent in meshes with less traingles, but this is seemly due to the fact the tested shapes are more uniform in low-poly. It is presumed that fiducial markers will stabilize ouputs for these specific shapes. +- **Axis lengths will differ** from the voxelized version because this filter measures distances from the feature centroid to mesh intersection points along the principal axes, rather than using voxel-based moment calculations. The voxelized result also depends on the sampling resolution used to create the grid. +- **Euler angles for symmetric shapes** (cube, sphere, octahedron, etc.) may differ numerically from the voxelized version but represent equivalent orientations. This is more apparent in low-polygon meshes. -## Description +### Mesh Quality Requirements -This **Filter** calculates the second-order moments of each enclosed **Feature** in a **Triangle Geometry**. The -second-order moments allow for the determination of the *principal axis lengths, principal axis directions, aspect -ratios and moment invariant Omega3s*. The *principal axis lengths* are those of a "best-fit" ellipsoid. The algorithm -for determining the moments and these values is as follows: +Accurate results require the mesh to be **watertight** (fully enclosed with no holes or gaps). The filter computes the Euler characteristic of each mesh region, which can indicate whether a mesh is watertight. See [Euler characteristic](https://en.wikipedia.org/wiki/Euler_characteristic) for more information. If a region is not watertight, the computed shape values may be inaccurate. + +### How This Filter Works 1. For each **Triangle** on the bounding surface of a **Feature**, construct a tetrahedron whose fourth vertex is the centroid of the **Feature**, ensuring normals are consistent (this **Filter** uses the convention where normals point @@ -41,14 +40,10 @@ for determining the moments and these values is as follows: represented, resulting in inaccurate Omega3 values. This problem is especially apparent for perfect rectangular prisms, but any shape with clear sharp corners may be affected. -This filter also computes the Euler Characteristic value which **can** be an indication of the __watertightness__ of the mesh(s). See -more information at [https://en.wikipedia.org/wiki/Euler_characteristic](https://en.wikipedia.org/wiki/Euler_characteristic) - -## WARNING +### Required Input Sources -Accurate computations depend on the mesh being water tight. If a triangle mesh has multiple regions -then these values will be computed for each region. If a region is not watertight then the computed -values are probably not correct. +- **Triangle Geometry** with **Face Labels** -- produced by a surface meshing filter such as [Quick Surface Mesh](../SimplnxCore/QuickSurfaceMeshFilter.md). +- **Feature Centroids** -- produced by [Compute Feature Centroids](../SimplnxCore/ComputeFeatureCentroidsFilter.md), typically on the voxelized feature data before meshing. % Auto generated parameter table will be inserted here diff --git a/src/Plugins/OrientationAnalysis/docs/ComputeSlipTransmissionMetricsFilter.md b/src/Plugins/OrientationAnalysis/docs/ComputeSlipTransmissionMetricsFilter.md index 4b2fa465ce..6ce3b6e6f2 100644 --- a/src/Plugins/OrientationAnalysis/docs/ComputeSlipTransmissionMetricsFilter.md +++ b/src/Plugins/OrientationAnalysis/docs/ComputeSlipTransmissionMetricsFilter.md @@ -6,35 +6,51 @@ Statistics (Crystallography) ## Description -**THIS FILTER ONLY WORKS ON Cubic m-3m LAUE CLASSES** +This **Filter** calculates a suite of *slip transmission metrics* for each pair of neighboring **Features** (grains). These metrics quantify how easily plastic deformation (slip) can transfer across a grain boundary from one grain to another, based on the geometric alignment of their slip systems. -This **Filter** calculates a suite of *slip transmission metrics* that are related to the alignment of slip directions and planes across **Feature** boundaries. The algorithm for calculation of these metrics is as follows: +When a material deforms, slip occurs along specific crystallographic planes and directions within each grain. At grain boundaries, slip in one grain must either transmit into the neighboring grain, be blocked, or nucleate new slip. The degree of geometric compatibility between the slip systems on each side of a boundary is a key factor in determining whether transmission occurs or whether stress concentrations develop that can lead to crack initiation. -1. Get the average orientation of the **Feature** -2. Get the **Feature**'s list of neighboring **Features** -3. Get the average orientation of each neighboring **Feature** -4. Calculate metrics given by equations in *slip transmission metrics* -5. Store metrics in lists for the **Feature** -6. Repeat for all **Features** +### Cubic Materials Only -*Note:* The transmission metrics are calculated using the average orientations for neighboring **Features** and not the local orientation near the boundary. Also, the metrics are calculated twice (i.e., when **Feature** 1 has neighbor **Feature** 2 and when **Feature** 2 has neighbor **Feature** 1) because the direction across the boundary between the **Features** affects the value of the metric. +This filter only works on **cubic m-3m Laue classes**. -## Luster-Morris Parameter (M' Values) +### How This Filter Works -The values are calculated as presented in [1]. +1. For each **Feature**, the filter retrieves its average orientation and list of neighboring **Features** +2. For each neighbor pair, the filter evaluates all possible combinations of slip systems across the boundary +3. The transmission metrics are computed in both directions (Feature 1 → Feature 2 and Feature 2 → Feature 1) because the directionality affects the result +4. Results are stored as lists per **Feature**, one value per neighbor -## Fracture Initiation Parameter (fip) +### Note -Three (3) *fip* values are computed as outputs to this filter. These are best explained in [2], see page 021012-4 +The metrics are calculated using the **average orientations** of neighboring grains, not the local orientations near the boundary. + +### Luster-Morris Parameter (M') + +The Luster-Morris parameter (M') measures the geometric compatibility between two slip systems across a boundary. A value of 1.0 indicates perfect alignment; lower values indicate poorer compatibility. Calculated as presented in [1]. + +### Fracture Initiation Parameters (F1, F1spt, F7) + +Three fracture initiation parameter (fip) values are computed, which relate to the likelihood of crack nucleation at grain boundaries due to slip incompatibility. These are defined in [2] (see page 021012-4): ![Fracture Initiation Parameter F1](Images/ComputeNeighborSlipTransmission_F1.png) ![Fracture Initiation Parameter F1spt](Images/ComputeNeighborSlipTransmission_F1spt.png) -![Fracture Initiation Parameter F7.png](Images/ComputeNeighborSlipTransmission_F7.png) +![Fracture Initiation Parameter F7](Images/ComputeNeighborSlipTransmission_F7.png) + +### Comparison with Compute Feature Boundary Strength Metrics + +This filter stores results per **Feature** (in neighbor lists). The [Compute Feature Boundary Strength Metrics](ComputeBoundaryStrengthsFilter.md) filter computes the same metrics but stores results per **Face** on a **Triangle Geometry**, which is useful for visualization on the boundary mesh. + +### Required Input Sources +- **Neighbor List** -- produced by [Compute Feature Neighbors](../SimplnxCore/ComputeFeatureNeighborsFilter.md) or [Compute Feature Neighborhoods](../SimplnxCore/ComputeNeighborhoodsFilter.md). +- **Average Quaternions** -- produced by [Compute Average Orientations](ComputeAvgOrientationsFilter.md). +- **Feature Phases** -- produced by [Compute Feature Phases](../SimplnxCore/ComputeFeaturePhasesFilter.md). +- **Crystal Structures** -- ensemble-level array read from EBSD data or created by [Create Ensemble Info](CreateEnsembleInfoFilter.md). -## Citations +## References [1] [Luster, J., Morris, M.A., 1995. *Compatibility Of Deformation In Two-Phase Ti-Al Alloys: Dependence On Microstructure And Orientation Relationships*. **Metallurgical and Materials Transactions A 26, 1745**](https://link.springer.com/article/10.1007/BF02670762) diff --git a/src/Plugins/OrientationAnalysis/docs/ComputeTwinBoundariesFilter.md b/src/Plugins/OrientationAnalysis/docs/ComputeTwinBoundariesFilter.md index 5712cbb442..08ea5bcffc 100644 --- a/src/Plugins/OrientationAnalysis/docs/ComputeTwinBoundariesFilter.md +++ b/src/Plugins/OrientationAnalysis/docs/ComputeTwinBoundariesFilter.md @@ -6,14 +6,36 @@ Statistics (Crystallography) ## Description -This **Filter** identifies all **Triangles** between neighboring **Features** that have a σ = 3 twin relationship. The **Filter** uses the average orientation of the **Features** on either side of the **Triangle** to determine the *misorientation* between the **Features**. If the *axis-angle* that describes the *misorientation* is within both the axis and angle user-defined tolerance, then the **Triangle** is flagged as being a twin. After the **Triangle** is flagged as a twin, the crystal direction parallel to the **Face** normal is determined and compared with the *misorientation axis* if *Compute Coherence* is selected. The misalignment of these two crystal directions is stored as the incoherence value for the **Triangle** (in degrees). Note that this **Filter** will only extract twin boundaries if the twin **Feature** is the same phase as the parent **Feature**. +This **Filter** identifies twin boundaries on a **Triangle Geometry** surface mesh. A twin boundary is a special type of grain boundary where two grains share a specific crystallographic relationship -- their crystal lattices are mirror images of each other across the boundary plane. + +### What is a Twin Boundary? + +Twins are grains that share a highly symmetric orientation relationship. The most common type is the Σ3 twin, where the two grains are related by a 60-degree rotation about the <111> crystal direction. Twin boundaries are significant because they tend to have very low energy and distinct mechanical properties compared to general grain boundaries. They are particularly common in FCC metals such as copper, nickel, and austenitic stainless steel. + +### How This Filter Works + +1. For each **Triangle** on the grain boundary mesh, the filter computes the misorientation between the two **Features** on either side using their average orientations. +2. If the misorientation axis and angle match the Σ3 twin relationship within the user-defined tolerances, the **Triangle** is flagged as a twin boundary. +3. If **Compute Coherence** is enabled, the filter additionally measures the *incoherence* -- the angle (in degrees) between the boundary plane normal and the misorientation axis, both expressed in the crystal reference frame. A perfectly coherent twin has an incoherence of 0 degrees, meaning the boundary plane is exactly the twin plane. Higher incoherence values indicate a boundary that has the correct misorientation but is not on the ideal twin plane. + +### Note + +Only boundaries between **Features** of the same phase are evaluated. ### Output Type for Twin Boundaries Array -The *Output Type for Twin Boundaries Array* parameter controls the data type used to store the twin boundary identification result: +- **boolean [0]**: Stores the result as true/false +- **uint8 [1]**: Stores the result as 1/0 + +### Required Input Sources + +This filter operates on a grain-boundary surface mesh and requires the following upstream steps: -- **boolean [0]**: Stores the twin boundary flag as a boolean array (true if the **Triangle** is a twin boundary, false otherwise). -- **uint8 [1]**: Stores the twin boundary flag as an unsigned 8-bit integer array (1 if the **Triangle** is a twin boundary, 0 otherwise). +- **Face Labels** -- produced by a surface meshing filter such as [Quick Surface Mesh](../SimplnxCore/QuickSurfaceMeshFilter.md). +- **Face Normals** (only when *Find Coherence* is enabled) -- produced by [Compute Triangle Normals](../SimplnxCore/TriangleNormalFilter.md). +- **Average Quaternions** -- produced by [Compute Average Orientations](ComputeAvgOrientationsFilter.md). +- **Feature Phases** -- produced by [Compute Feature Phases](../SimplnxCore/ComputeFeaturePhasesFilter.md). +- **Crystal Structures** -- ensemble-level array read from EBSD data or created by [Create Ensemble Info](CreateEnsembleInfoFilter.md). % Auto generated parameter table will be inserted here diff --git a/src/Plugins/OrientationAnalysis/docs/EBSDSegmentFeaturesFilter.md b/src/Plugins/OrientationAnalysis/docs/EBSDSegmentFeaturesFilter.md index 73e65dbedb..695179de4d 100644 --- a/src/Plugins/OrientationAnalysis/docs/EBSDSegmentFeaturesFilter.md +++ b/src/Plugins/OrientationAnalysis/docs/EBSDSegmentFeaturesFilter.md @@ -6,19 +6,39 @@ Reconstruction (Segmentation) ## Description -This **Filter** segments the **Features** by grouping neighboring **Cells** that satisfy the *misorientation tolerance*, i.e., have misorientation angle less than the value set by the user. The process by which the **Features** are identified is given below and is a standard *burn algorithm*. +This **Filter** groups neighboring **Cells** (voxels) that have similar crystal orientations into **Features** (grains), producing a *FeatureIds* array that labels every cell in the input **Image Geometry** with a grain number. This is the primary grain-segmentation filter for EBSD data and is usually the first feature-generating step in a reconstruction pipeline. -1. Randomly select a **Cell**, add it to an empty list and set its *Feature Id* to the current **Feature** -2. Compare the **Cell** to each of its six (6) face-sharing neighbors (i.e., calculate the misorientation with each neighbor) -3. Add each neighbor **Cell** that has a misorientation below the user defined tolerance to the list created in 1. and set the *Feature Id* of the neighbor **Cell** to the current **Feature** -4. Remove the current **Cell** from the list and move to the next **Cell** and repeat 2. and 3.; continue until no **Cells** are left in the list -5. Increment the current **Feature** counter and repeat steps 1. through 4.; continue until no **Cells** remain unassigned in the dataset +For segmentation based only on C-axis alignment in hexagonal materials, see [Segment Features (C-Axis Misalignment)](CAxisSegmentFeaturesFilter.md). For segmentation based on a scalar value rather than orientation, see [Segment Features (Scalar)](../SimplnxCore/ScalarSegmentFeaturesFilter.md). -The user has the option to *Use Mask Array*, which allows the user to set a boolean array for the **Cells** that remove **Cells** with a value of *false* from consideration in the above algorithm. This option is useful if the user has an array that either specifies the domain of the "sample" in the "image" or specifies if the orientation on the **Cell** is trusted/correct. +### What is Misorientation-Based Segmentation? -After all the **Features** have been identified, a **Feature Attribute Matrix** is created for the **Features** and each **Feature** is flagged as *Active* in a boolean array in the matrix. +A **grain** in a polycrystalline material is a region of crystal with a nearly-uniform lattice orientation. At grain boundaries the lattice rotates abruptly -- typically by many degrees -- from one grain to the next. Within a grain, orientation changes are small (sub-degree to a few degrees), due to noise, elastic strain, or mild plastic deformation. -If the data is specified as **Periodic**, the segmentation will check if features wrap around geometry bounds in a tileable fashion. If any such features are detected, the filter will throw a warning that centroid data may be incorrect. +*Misorientation* is the angular rotation that maps one crystal orientation onto another. By walking cell-to-cell and merging neighbors whose misorientation is below a threshold, this filter carves the cell-level orientation map into discrete grains. + +### How This Filter Works + +The filter uses a standard *burn algorithm* to grow each grain outward from a seed cell: + +1. Randomly pick an unassigned **Cell** and give it a new *Feature Id*. +2. Compute the misorientation angle between the seed cell and each neighbor (see **Neighbor Scheme** below). Crystal symmetry is applied so that the smallest symmetry-equivalent angle is used. +3. Any neighbor whose misorientation angle is less than the user-specified *Misorientation Tolerance* (in **degrees**) is added to the current feature and gets the same *Feature Id*. +4. Repeat step 2-3 from each newly added cell, growing the feature outward until no more neighbors qualify. +5. Increment the feature counter and pick a new unassigned seed cell. Continue until every eligible cell has been assigned. + +### Typical Tolerance Values + +The *Misorientation Tolerance* is in **degrees**. The right value depends on what you are trying to resolve: + +- **5 degrees** -- the industry-standard default for general grain segmentation. Works well across most materials. +- **2-3 degrees** -- tighter; useful when the data is very clean and you want to resolve subgrains or low-angle boundaries. +- **10-15 degrees** -- the classical "high-angle grain boundary" threshold. Useful if you want to ignore subgrain structure entirely and segment only the high-angle grains. + +Smaller tolerances produce more, smaller features and will pick up noise and subgrain boundaries as feature splits. Larger tolerances produce fewer, larger features at the cost of possibly merging neighboring grains that have a low-angle boundary between them. + +### Phase Handling + +Only cells belonging to the same phase are ever merged. Cells of different phases are always considered different features regardless of their orientation, because misorientation between different crystal systems is not physically meaningful. Cells with *phase = 0* (the "Unknown" phase) are treated as unsegmentable and receive Feature Id 0. ### Neighbor Scheme @@ -27,11 +47,7 @@ The *Neighbor Scheme* parameter provides the following choices: - **Face Neighbors [0]**: Only the 6 face-sharing neighbors of a voxel are considered during segmentation. - **All Connected Neighbors [1]**: All 26 neighbors connected by a face, edge, or vertex are considered during segmentation. -## Note on Neighbor Scheme - -Historically DREAM.3D version 6.x has used *only* the 6 face neighbors of a voxel. This release introduces the option -of using all 26 neighboring voxels that are connected by a face, edge or vertex. The default for the filter -is to still use the 6 face neighbors ("Face Only") in order to stay consistent with the output from DREAM.3D version 6.x. +DREAM.3D version 6.x only used face neighbors. The default here is still *Face Only* for backward compatibility; switch to *All Connected* when diagonal connectivity should merge a grain that would otherwise be split into two features. | Neighbor Scheme = "Face Only" | Neighbor Scheme = "All Connected" | |:--:|:--:| @@ -49,6 +65,21 @@ is to still use the 6 face neighbors ("Face Only") in order to stay consistent w |:--:|:--:| | ![Shared Edges & Points With Disconnected Region - "Face Only"](Images/SegmentFeatures/combination_face_only.png) | ![Shared Edges & Points With Disconnected Region - "All Connected"](Images/SegmentFeatures/combination_all_connected.png) | +### Mask Array + +If *Use Mask Array* is enabled, cells flagged *false* in the mask are excluded from segmentation and left with a Feature Id of 0. This is essential for EBSD data where low-confidence cells should not be merged into grains -- typically use a threshold on the confidence index or image quality to build the mask via [Multi-Threshold Objects](../SimplnxCore/MultiThresholdObjectsFilter.md). + +### Periodic Option + +If the input data represents a **periodic** volume (e.g., a synthetic microstructure that tiles across opposite faces), enable *Is Periodic*. The filter will detect features that wrap across the geometry bounds and emit a warning that centroid and other spatial statistics may be incorrect for those features. + +### Required Input Sources + +- **Cell Quaternions** -- typically read from EBSD data via [Read H5EBSD](ReadH5EbsdFilter.md), [Read CTF Data](ReadCtfDataFilter.md), or [Read ANG Data](ReadAngDataFilter.md); can also be produced from Euler angles by [Convert Orientations](ConvertOrientationsFilter.md). +- **Cell Phases** -- typically read from EBSD data alongside the quaternions. +- **Crystal Structures** -- ensemble-level array read from EBSD data or created by [Create Ensemble Info](CreateEnsembleInfoFilter.md). +- **Mask Array** (optional) -- a boolean array marking valid cells, typically produced by [Multi-Threshold Objects](../SimplnxCore/MultiThresholdObjectsFilter.md). + % Auto generated parameter table will be inserted here ## Example Pipelines diff --git a/src/Plugins/OrientationAnalysis/docs/Images/ComputeAvgCAxes_HexagonalCAxis.png b/src/Plugins/OrientationAnalysis/docs/Images/ComputeAvgCAxes_HexagonalCAxis.png new file mode 100644 index 0000000000..a9f41fe950 Binary files /dev/null and b/src/Plugins/OrientationAnalysis/docs/Images/ComputeAvgCAxes_HexagonalCAxis.png differ diff --git a/src/Plugins/OrientationAnalysis/docs/Images/ComputeAvgCAxes_HexagonalCAxis.svg b/src/Plugins/OrientationAnalysis/docs/Images/ComputeAvgCAxes_HexagonalCAxis.svg new file mode 100644 index 0000000000..63a28bcaa6 --- /dev/null +++ b/src/Plugins/OrientationAnalysis/docs/Images/ComputeAvgCAxes_HexagonalCAxis.svg @@ -0,0 +1,93 @@ + + + + + + + + Hexagonal Unit Cell + + + The C-axis [001] is the unique axis in hexagonal crystals + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + c + + + + + + a + + + 1 + + + + + + a + + + 2 + + + + + + a + + + 3 + + + + + + + + + + + + + + i + + + + + The C-axis is unique in hexagonal crystals. + + + diff --git a/src/Plugins/OrientationAnalysis/docs/Images/ComputeKernelAvgMisorientations_1D_Radius1.png b/src/Plugins/OrientationAnalysis/docs/Images/ComputeKernelAvgMisorientations_1D_Radius1.png new file mode 100644 index 0000000000..6e816e9f22 Binary files /dev/null and b/src/Plugins/OrientationAnalysis/docs/Images/ComputeKernelAvgMisorientations_1D_Radius1.png differ diff --git a/src/Plugins/OrientationAnalysis/docs/Images/ComputeKernelAvgMisorientations_1D_Radius1.svg b/src/Plugins/OrientationAnalysis/docs/Images/ComputeKernelAvgMisorientations_1D_Radius1.svg new file mode 100644 index 0000000000..cc5e0e9118 --- /dev/null +++ b/src/Plugins/OrientationAnalysis/docs/Images/ComputeKernelAvgMisorientations_1D_Radius1.svg @@ -0,0 +1,65 @@ + + + + + + + + + + + + 1D Example: Radius = 1 → Kernel Size = 3 + + + + + + ... + + + + + -1 + + + + Center + + + + +1 + + + + + ... + + + + + + R = 1 + + + + + R = 1 + + + + + + Kernel Size = 3 cells + + + + + + Center cell + + Kernel neighbor + + Outside kernel + + \ No newline at end of file diff --git a/src/Plugins/OrientationAnalysis/docs/Images/ComputeKernelAvgMisorientations_1D_Radius2.png b/src/Plugins/OrientationAnalysis/docs/Images/ComputeKernelAvgMisorientations_1D_Radius2.png new file mode 100644 index 0000000000..3c5406e949 Binary files /dev/null and b/src/Plugins/OrientationAnalysis/docs/Images/ComputeKernelAvgMisorientations_1D_Radius2.png differ diff --git a/src/Plugins/OrientationAnalysis/docs/Images/ComputeKernelAvgMisorientations_1D_Radius2.svg b/src/Plugins/OrientationAnalysis/docs/Images/ComputeKernelAvgMisorientations_1D_Radius2.svg new file mode 100644 index 0000000000..41a066aaaa --- /dev/null +++ b/src/Plugins/OrientationAnalysis/docs/Images/ComputeKernelAvgMisorientations_1D_Radius2.svg @@ -0,0 +1,71 @@ + + + + + + + + + + + + 1D Example: Radius = 2 → Kernel Size = 5 + + + + + + ... + + + + -2 + + + + -1 + + + + Center + + + + +1 + + + + +2 + + + + ... + + + + + + R = 2 + + + + + R = 2 + + + + + + Kernel Size = 5 cells + + + + + + Center cell + + Kernel neighbor + + Outside kernel + + \ No newline at end of file diff --git a/src/Plugins/OrientationAnalysis/docs/Images/ComputeKernelAvgMisorientations_2D_Radius110.png b/src/Plugins/OrientationAnalysis/docs/Images/ComputeKernelAvgMisorientations_2D_Radius110.png new file mode 100644 index 0000000000..73ea9abf3a Binary files /dev/null and b/src/Plugins/OrientationAnalysis/docs/Images/ComputeKernelAvgMisorientations_2D_Radius110.png differ diff --git a/src/Plugins/OrientationAnalysis/docs/Images/ComputeKernelAvgMisorientations_2D_Radius110.svg b/src/Plugins/OrientationAnalysis/docs/Images/ComputeKernelAvgMisorientations_2D_Radius110.svg new file mode 100644 index 0000000000..02684fce6b --- /dev/null +++ b/src/Plugins/OrientationAnalysis/docs/Images/ComputeKernelAvgMisorientations_2D_Radius110.svg @@ -0,0 +1,92 @@ + + + + + + + + + + + + 2D View: Radius (1, 1, 0) + 3 × 3 kernel = 9 cells examined per voxel + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + C + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + X (R=1) + Y (R=1) + + + + + + Center (C) + + Kernel neighbor + + Outside kernel + + \ No newline at end of file diff --git a/src/Plugins/OrientationAnalysis/docs/Images/ComputeKernelAvgMisorientations_2D_Radius120.png b/src/Plugins/OrientationAnalysis/docs/Images/ComputeKernelAvgMisorientations_2D_Radius120.png new file mode 100644 index 0000000000..5295564025 Binary files /dev/null and b/src/Plugins/OrientationAnalysis/docs/Images/ComputeKernelAvgMisorientations_2D_Radius120.png differ diff --git a/src/Plugins/OrientationAnalysis/docs/Images/ComputeKernelAvgMisorientations_2D_Radius120.svg b/src/Plugins/OrientationAnalysis/docs/Images/ComputeKernelAvgMisorientations_2D_Radius120.svg new file mode 100644 index 0000000000..01399ff105 --- /dev/null +++ b/src/Plugins/OrientationAnalysis/docs/Images/ComputeKernelAvgMisorientations_2D_Radius120.svg @@ -0,0 +1,93 @@ + + + + + + + + + + + + 2D View: Radius (1, 2, 0) + 3 × 5 kernel = 15 cells examined per voxel + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + C + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + X (R=1) + Y (R=2) + + + + + + Center (C) + + Kernel neighbor + + Outside kernel + + \ No newline at end of file diff --git a/src/Plugins/OrientationAnalysis/docs/Images/ComputeKernelAvgMisorientations_Formula.png b/src/Plugins/OrientationAnalysis/docs/Images/ComputeKernelAvgMisorientations_Formula.png new file mode 100644 index 0000000000..2cde8310d8 Binary files /dev/null and b/src/Plugins/OrientationAnalysis/docs/Images/ComputeKernelAvgMisorientations_Formula.png differ diff --git a/src/Plugins/OrientationAnalysis/docs/Images/ComputeKernelAvgMisorientations_Formula.svg b/src/Plugins/OrientationAnalysis/docs/Images/ComputeKernelAvgMisorientations_Formula.svg new file mode 100644 index 0000000000..26205b18bf --- /dev/null +++ b/src/Plugins/OrientationAnalysis/docs/Images/ComputeKernelAvgMisorientations_Formula.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + How Kernel Radius Relates to Kernel Size + + + + Kernel Size = (2 × Radius) + 1 + + + The radius extends in both directions along each axis, plus the center cell itself. + Each axis (X, Y, Z) can have a different radius value. + \ No newline at end of file diff --git a/src/Plugins/OrientationAnalysis/docs/Images/ComputeKernelAvgMisorientations_Table.png b/src/Plugins/OrientationAnalysis/docs/Images/ComputeKernelAvgMisorientations_Table.png new file mode 100644 index 0000000000..3b4134d670 Binary files /dev/null and b/src/Plugins/OrientationAnalysis/docs/Images/ComputeKernelAvgMisorientations_Table.png differ diff --git a/src/Plugins/OrientationAnalysis/docs/Images/ComputeKernelAvgMisorientations_Table.svg b/src/Plugins/OrientationAnalysis/docs/Images/ComputeKernelAvgMisorientations_Table.svg new file mode 100644 index 0000000000..df239d576b --- /dev/null +++ b/src/Plugins/OrientationAnalysis/docs/Images/ComputeKernelAvgMisorientations_Table.svg @@ -0,0 +1,47 @@ + + + + + + Quick Reference: Radius → Kernel Size + + + + Radius (X,Y,Z) + + Kernel Size + + Cells per Dim + + Total Cells + + + + (1, 1, 1) + + 3 × 3 × 3 + + 3 + + 27 + + + + (2, 2, 2) + + 5 × 5 × 5 + + 5 + + 125 + + + + (3, 3, 3) + + 7 × 7 × 7 + + 7 + + 343 + \ No newline at end of file diff --git a/src/Plugins/OrientationAnalysis/docs/Images/ComputeSchmids_SchmidFactor.png b/src/Plugins/OrientationAnalysis/docs/Images/ComputeSchmids_SchmidFactor.png new file mode 100644 index 0000000000..3cd47d2741 Binary files /dev/null and b/src/Plugins/OrientationAnalysis/docs/Images/ComputeSchmids_SchmidFactor.png differ diff --git a/src/Plugins/OrientationAnalysis/docs/Images/ComputeSchmids_SchmidFactor.svg b/src/Plugins/OrientationAnalysis/docs/Images/ComputeSchmids_SchmidFactor.svg new file mode 100644 index 0000000000..7b0c0e1557 --- /dev/null +++ b/src/Plugins/OrientationAnalysis/docs/Images/ComputeSchmids_SchmidFactor.svg @@ -0,0 +1,82 @@ + + + + + + + + Schmid Factor — Geometric Relationship + + + Schmid Factor = cos(φ) × cos(λ),  range: 0 to 0.5 + + + + + + + + + + + Slip plane + + + + + + + F (tensile) + + + + + + F (tensile) + + + + Slip plane + + + normal + + + + Slip + + + direction + + + + φ + + + + + + λ + + + + + + φ + = angle between tensile axis and slip plane normal + + + + λ + = angle between tensile axis and slip direction + + + + Slip plane (amber) + + + Maximum Schmid factor + 0.5 (at φ = λ = 45°) + + + diff --git a/src/Plugins/OrientationAnalysis/docs/MergeTwinsFilter.md b/src/Plugins/OrientationAnalysis/docs/MergeTwinsFilter.md index 2ce1719337..dddb01c786 100644 --- a/src/Plugins/OrientationAnalysis/docs/MergeTwinsFilter.md +++ b/src/Plugins/OrientationAnalysis/docs/MergeTwinsFilter.md @@ -6,9 +6,60 @@ Reconstruction (Grouping) ## Description -*THIS FILTER ONLY WORKS ON CUBIC-HIGH (m3m) Laue Classes.* +This **Filter** groups neighboring **Features** (grains) that share a *twin relationship* into a single *parent* grain. Twins are sub-grains of a parent grain that share a highly specific crystallographic relationship, and for many downstream analyses -- morphology, size distributions, neighbor statistics -- it is useful to treat a grain and its twin variants as one entity rather than as separate grains. -This **Filter** groups neighboring **Features** that are in a twin relationship with each other (currently only FCC σ = 3 twins). The algorithm for grouping the **Features** is analogous to the algorithm for segmenting the **Features** - only the average orientation of the **Features** are used instead of the orientations of the individual **Elements**. The user can specify a tolerance on both the *axis* and the *angle* that defines the twin relationship (i.e., a tolerance of 1 degree for both tolerances would allow the neighboring **Features** to be grouped if their misorientation was between 59-61 degrees about an axis within 1 degree of <111>, since the Sigma 3 twin relationship is 60 degrees about <111>). +Only the FCC *Σ3* twin relationship is detected by this filter. + +### What is a Twin? + +A **twin** is a region within a grain whose crystal lattice is a mirror image of the surrounding parent grain across a specific plane, called the *twin plane*. Mechanically, the twinned region is still part of the same grain structure; crystallographically, it has a different -- but highly specific -- orientation. + +The most common twin in FCC metals (copper, nickel, aluminum, austenitic stainless steels, superalloys such as IN100 and Inconel) is the **Σ3 twin**. Two grains are in a Σ3 twin relationship when they are related by a 60° rotation about the `<111>` crystal direction. This is often called an *annealing twin* because it frequently forms during recrystallization. + +The "Σ3" notation comes from *Coincidence Site Lattice* (CSL) theory: Σ is the reciprocal density of lattice sites shared between the two crystals, and Σ3 means 1 out of every 3 atomic sites line up exactly across the boundary. + +### Why Merge Twins? + +After segmentation (for example with the *Segment Features (Misorientation)* filter), each twin variant is identified as its own separate **Feature** because it has a distinct average orientation from its parent. This is correct from a pure orientation standpoint, but can mislead morphological and statistical analyses: + +- A grain with three twin bands will be counted as four separate grains, inflating the apparent grain count. +- Grain-size distributions will be skewed smaller because twin variants are smaller than the parent. +- Neighbor statistics will count twin-to-parent boundaries as regular grain boundaries. + +Merging twin variants back into a single parent grain produces a *post-twin* grain structure that more closely reflects what a metallurgist would call a "grain" under an optical microscope, and is usually the correct input for morphological statistics. + +### How This Filter Works + +The filter uses a burn-style grouping algorithm operating on the **Feature** level (not the **Cell** level): + +1. A **Feature** that has not yet been assigned a parent is selected as the starting point and given a new *Parent Id*. +2. For each of its contiguous neighbors (provided by the input *Contiguous Neighbor List*), the filter computes the misorientation between the two features using their average quaternions. +3. If the misorientation axis is within the *Axis Tolerance* of `<111>` **and** the misorientation angle is within the *Angle Tolerance* of 60°, the neighbor is in a Σ3 twin relationship with the current feature and is assigned the same *Parent Id*. +4. The grouping then extends recursively through the newly added neighbor's own neighbors, so that a chain of twins-of-twins is absorbed into one parent. +5. When no more features can be added to the current parent group, a new unassigned feature is picked and the process repeats until every eligible feature has a *Parent Id*. + +### Parameter Guidance + +- **Axis Tolerance (degrees)**: How far the misorientation rotation axis can deviate from the ideal `<111>` direction and still be accepted as a twin. Default is 3°. Typical values range from 1° to 5°. Tighter tolerance = fewer false positives but may miss slightly distorted real twins. +- **Angle Tolerance (degrees)**: How far the misorientation rotation angle can deviate from the ideal 60° and still be accepted as a twin. Default is 2°. Typical values range from 1° to 3°. + +Both tolerances are in **degrees**. A tolerance of 3°/2° accepts a neighbor as a twin if its misorientation falls within roughly 58°-62° about an axis within 3° of `<111>`. + +### Required Input Sources + +This filter requires that several prior operations have already been run: + +- **Cell Feature Ids** -- produced by a segmentation filter (e.g., [Segment Features (Misorientation)](EBSDSegmentFeaturesFilter.md)). +- **Contiguous Neighbor List** -- produced by [Compute Feature Neighbors](../SimplnxCore/ComputeFeatureNeighborsFilter.md). +- **Feature Phases** -- produced by [Compute Feature Phases](../SimplnxCore/ComputeFeaturePhasesFilter.md). +- **Average Quaternions** -- produced by [Compute Average Orientations](ComputeAvgOrientationsFilter.md). +- **Crystal Structures** -- the ensemble-level array describing each phase's Laue class. + +### Limitations + +- **Cubic-High (m3m) only.** The filter only evaluates twin relationships for phases with the m3m Laue class (FCC and BCC cubic materials). Phases with other symmetries are skipped with a warning; their features remain ungrouped. Only FCC materials actually exhibit Σ3 annealing twins in practice. +- **Σ3 only.** Other CSL boundaries (Σ5, Σ7, Σ9, etc.) are not detected. +- **Requires well-computed average orientations.** The twin detection is only as accurate as the input *Average Quaternions*. If twin variants were segmented together with the parent (too-loose segmentation tolerance), the average orientation will be wrong and this filter will not reliably detect twins. % Auto generated parameter table will be inserted here @@ -16,7 +67,6 @@ This **Filter** groups neighboring **Features** that are in a twin relationship + (02) Small IN100 Full Reconstruction - ## License & Copyright Please see the description file distributed with this **Plugin** diff --git a/src/Plugins/OrientationAnalysis/docs/NeighborOrientationCorrelationFilter.md b/src/Plugins/OrientationAnalysis/docs/NeighborOrientationCorrelationFilter.md index 2c63cb2dbb..7ca49758b0 100644 --- a/src/Plugins/OrientationAnalysis/docs/NeighborOrientationCorrelationFilter.md +++ b/src/Plugins/OrientationAnalysis/docs/NeighborOrientationCorrelationFilter.md @@ -6,11 +6,27 @@ Processing (Cleanup) ## Description -This filter first identifies all cells that have a *Confidence Index* below the minimum set by the user. Then, for each of those cells, their neighboring cells are checked to determine the number of neighbor cells with orientations different than the reference cell by more than the user defined *Misorientation Tolerance*. In addition the neighboring cells are compared with each other to determine the number of neighboring cells that have the same orientation (again within the user defined tolerance). The *Cleanup Level* set by the user is then used to determine which cells are replaced. If a level of 5 is set, at least 5 of the neighboring cells must be within the same misorientation tolerance (and so on for other *Cleanup Level*). If a cell meets the replacement criteria, then all of its attributes are replaced with the attributes of one of the neighboring cells that are the same as each other. +This **Filter** cleans up low-confidence EBSD cells by replacing their attributes with those of one of their neighbors -- but only when enough of that cell's neighbors agree on a common orientation. It is more conservative than [Replace Element Attributes with Neighbor (Threshold)](../SimplnxCore/ReplaceElementAttributesWithNeighborValuesFilter.md): rather than always replacing flagged cells, it requires a neighbor consensus before doing so. -*Note:* The filter will iteratively reduce the *Cleanup Level* from 6 until it reaches the user defined number. So, if the user selects a level of 4, then the filter will run with a level of 6, then 5, then 4 before finishing. +### How This Filter Works -Neighbors are defined as a the "nearest neighbors" which share a "face". For 3D structures it is 6 neighbors that share a common face with the current cell. +1. Identify all cells whose *Confidence Index* is below the user-defined minimum. +2. For each flagged cell, compare each of its 6 face-neighbors to the flagged cell using *Misorientation Tolerance*. Count how many neighbors are different from the flagged cell (i.e., misorientation > tolerance). +3. Compare the neighbors **to each other** to count how many of them share a common orientation (within the same misorientation tolerance). +4. If at least *Cleanup Level* of the neighbors share a common orientation, the flagged cell is replaced: all of its cell-level attributes are copied from one of those agreeing neighbors. + +The filter then reduces *Cleanup Level* by 1 and repeats. Starting from level 6 (all 6 neighbors must agree), the filter steps down to the user-defined floor. So setting *Cleanup Level* = 4 runs the algorithm at levels 6, 5, and 4 in sequence -- aggressive enough to clean most isolated bad cells, conservative enough to leave genuinely ambiguous regions alone. + +### Cleanup Level + +The *Cleanup Level* parameter is the **count of agreeing neighbors required to trigger replacement** and ranges from **1 to 6** (face neighbors only): + +- **6** -- only replace a cell when **all** of its 6 neighbors share a common orientation. Very conservative; cleans only the most obvious isolated bad voxels. +- **4-5** -- moderate. Most isolated low-confidence cells are cleaned; cells in genuinely noisy regions are left alone. +- **2-3** -- aggressive. Cleans more cells but risks propagating one orientation into regions that genuinely lack a confident measurement. +- **1** -- almost any agreement triggers replacement; effectively a flood fill. + +Because the filter steps down from 6 to the user-defined value, lower numbers always include the work done at higher numbers; setting *Cleanup Level* to 4 also performs the level-6 and level-5 passes first. ### Schematic Example @@ -20,24 +36,29 @@ Neighbors are defined as a the "nearest neighbors" which share a "face". For 3D | 1 | (13.0, 0.0, 0.0) CI=0.2 | (0.0, 0.0, 0.0) CI=0.05 | (12.0, 0.0, 0.0) CI=0.2 | | 2 | | (15.0, 0.0, 0.0) CI=0.2 | | -Schematic layout of the neighboring cells. Only the In-Plane neighbors are shown. - -In this example, cell (1,1) has a confidence index < 0.1 and the surrounding cells all have a misorientation tolerance not greater than 5 degrees. Comparing cell (1,1) with its neighbor cells we can see that the misorientation is greater than 5 Degrees. In this case the central cell (1,1) would have all of its attributes replaced with the "best" neighbor based on the phase of a neighbor cell matching the central cell. +Cell (1,1) has CI = 0.05, which is below a 0.1 minimum, so it is flagged. Its 4 in-plane neighbors all have orientations within 5 degrees of each other (Euler angles around (12-15, 0, 0)) but more than 5 degrees from (1,1)'s orientation (0, 0, 0). At *Cleanup Level* = 4, the four neighbors agree, so (1,1)'s attributes are replaced with one of them. -## Example Data +### Example Data | Example Input/Output Images | |--------------------------------| | ![](Images/BadDataNeighborOrientationCheckFilter_2.png) | -| The Small IN100 data just after some intial cleanup filters have been used. | +| The Small IN100 data just after some initial cleanup filters have been used. | | ![](Images/NeighborOrientationCorrelationFilter_1.png) | -| The Small IN100 data just after running this filter with a *Misorientation Tolerance* of 5 degrees, and a *Cleanup Level* of 2 and a minimum *Confidence Index* of 0.2 | +| The Small IN100 data after running this filter with *Misorientation Tolerance* = 5°, *Cleanup Level* = 2, and *Minimum Confidence Index* = 0.2. | + +These before-and-after images show how this filter can fill in non-indexed EBSD cells. Use it for small isolated bad regions, not for flood-filling entire low-confidence areas. + +### Warning - Cell-Level Data Modification -These before and after images show how this filter can be used to "fill in" data that was deemed non-indexed (in EBSD terms). The user should be careful with this filter as it is meant to clean up small sets of voxels and not flood fill an entire volume of voxels. +When a cell is replaced, **all** of its cell-level attributes (orientations, phases, confidence indices, and any other arrays in the same attribute matrix) are copied from the chosen neighbor. The filter does not preserve the original confidence index of the replaced cell. -### Warning - Cell Level Data Modification +### Required Input Sources -This filter will copy all attribute data from neighboring cells into the target cell if the criteria is met. +- **Cell Quaternions** -- typically read from EBSD data via [Read H5EBSD](ReadH5EbsdFilter.md), [Read CTF Data](ReadCtfDataFilter.md), or [Read ANG Data](ReadAngDataFilter.md). +- **Cell Phases** -- typically read from EBSD data alongside the quaternions. +- **Confidence Index** (or equivalent quality scalar) -- read from EBSD data; thresholded to identify cells for cleanup. +- **Crystal Structures** -- ensemble-level array read from EBSD data or created by [Create Ensemble Info](CreateEnsembleInfoFilter.md). % Auto generated parameter table will be inserted here diff --git a/src/Plugins/OrientationAnalysis/docs/ReadAngDataFilter.md b/src/Plugins/OrientationAnalysis/docs/ReadAngDataFilter.md index 0954623650..c591955ada 100644 --- a/src/Plugins/OrientationAnalysis/docs/ReadAngDataFilter.md +++ b/src/Plugins/OrientationAnalysis/docs/ReadAngDataFilter.md @@ -6,16 +6,20 @@ IO (Input) ## Description -This **Filter** will read a single .ang file into a new **Image Geometry**, allowing the immediate use of **Filters** on the data instead of having to generate the intermediate .h5ebsd file. A **Cell Attribute Matrix** and Ensemble Attribute Matrix** will also be created to hold the imported EBSD information. Currently, the user has no control over the names of the created **Attribute Arrays**. The user should be aware that simply reading the file then performing operations that are dependent on the proper crystallographic and sample reference frame will be undefined or simply **wrong**. In order to bring the crystal reference frame and sample reference frame into coincidence, rotations will need to be applied to the data. +This filter reads a single `.ang` file (the EBSD scan format written by EDAX/TSL OIM Analysis software) into a new **Image Geometry**. Reading the file directly lets the data be used immediately by other filters, instead of having to first build an intermediate `.h5ebsd` file. A **Cell Attribute Matrix** (per-pixel data) and an **Ensemble Attribute Matrix** (per-phase data) are created to hold the imported EBSD information. The user currently has no control over the names of the created **Attribute Arrays**. + +The scan stores an **orientation** at every pixel as three **Euler angles** (three angles, in the Bunge Z-X-Z convention, describing how the measured crystal at that pixel is rotated relative to the sample). In the `.ang` data fields these three Euler angles are named *phi1*, *Phi*, and *phi2*. + +The user should be aware that simply reading the file and then performing operations that depend on a correct crystal reference frame (the axes fixed to the crystal lattice) and sample reference frame (the axes fixed to the physical specimen) will be undefined or simply **wrong**. To bring the crystal and sample reference frames into coincidence, rotations may need to be applied to the data. ### Default TSL Transformations -If the data has come from a TSL acquisition system and the settings of the acquisition software were in the default modes, he following reference frame transformations may need to be performed based on the version of the OIM Analysis software being used to collect the data: +If the data has come from a TSL acquisition system and the settings of the acquisition software were in the default modes, the following reference frame transformations may need to be performed based on the version of the OIM Analysis software being used to collect the data. These rotations can be applied with [Rotate Sample Reference Frame](../SimplnxCore/RotateSampleRefFrameFilter.md) and [Rotate Euler Reference Frame](RotateEulerRefFrameFilter.md): + Sample Reference Frame: 180o about the <010> Axis + Crystal Reference Frame: 90o about the <001> Axis -The user also may want to assign un-indexed pixels to be ignored by flagging them as "bad". The Threshold Objects **Filter** can be used to define this *mask* by thresholding on values such as *Confidence Index* > 0.1 or *Image Quality* > desired quality. +The user also may want to assign un-indexed pixels to be ignored by flagging them as "bad". The [Multi-Threshold Objects](../SimplnxCore/MultiThresholdObjectsFilter.md) filter can be used to define this *mask* by thresholding on values such as *Confidence Index* > 0.1 or *Image Quality* > desired quality. **Confidence Index** and **Image Quality** are per-pixel metrics that describe how reliable each individual measurement is. ### Note About Sample Grid @@ -25,8 +29,15 @@ OIMAnalysis can create EBSD data sampled on a hexagonal grid. The user can look # GRID: HexGrid ``` -If the user's .ang files are hexagonal grid files then they will need to run the {ref}`Convert EDAX Hex Grid to Square Grid (.ang)` filter to first convert the input files square gridded files. +If the user's .ang files are hexagonal grid files then they will need to run the [Convert EDAX Hex Grid to Square Grid (.ang)](ConvertHexGridToSquareGridFilter.md) filter first to convert the input files to square-gridded files. + +### Downstream Processing + +Once the reference frames are correct, the imported Euler angles are typically converted to other orientation representations (quaternions, and so on) with [Convert Orientation Representation](ConvertOrientationsFilter.md) before computing misorientations, segmenting grains, or generating pole figures. + +### Required Input Sources +None — this filter reads directly from a `.ang` file on disk. ### Note on .ang file Data Ordering diff --git a/src/Plugins/OrientationAnalysis/docs/ReadChannel5DataFilter.md b/src/Plugins/OrientationAnalysis/docs/ReadChannel5DataFilter.md index 46e2d2ea8b..742479410c 100644 --- a/src/Plugins/OrientationAnalysis/docs/ReadChannel5DataFilter.md +++ b/src/Plugins/OrientationAnalysis/docs/ReadChannel5DataFilter.md @@ -6,31 +6,37 @@ IO (Input) ## Description -This filter will read a single .cpr/.crc file pair into a new ImageGeometry. A **Cell Attribute Matrix** and -Ensemble Attribute Matrix** will also be created to hold the imported EBSD information. Currently, the user has no -control over the names of the created **Attribute Arrays**. The user should be aware that simply reading the file -then performing operations that are dependent on the proper crystallographic and sample reference frame will be -**undefined, inaccurate and/or wrong**. In order to bring the crystal reference frame and sample reference frame -into coincidence, rotations will need to be applied to the data. An excellent reference for this is the following PDF file: +This filter reads a single `.cpr`/`.crc` file pair (the EBSD scan format written by Oxford Instruments / HKL Channel 5 software) into a new **Image Geometry**. Reading the files directly lets the data be used immediately by other filters, instead of having to first build an intermediate `.h5ebsd` file. A **Cell Attribute Matrix** (per-pixel data) and an **Ensemble Attribute Matrix** (per-phase data) are created to hold the imported EBSD information. The user currently has no control over the names of the created **Attribute Arrays**. + +The scan stores an **orientation** at every pixel as three **Euler angles** (three angles, in the Bunge Z-X-Z convention, describing how the measured crystal at that pixel is rotated relative to the sample). + +The user should be aware that simply reading the file and then performing operations that depend on a correct crystal reference frame (the axes fixed to the crystal lattice) and sample reference frame (the axes fixed to the physical specimen) will be **undefined, inaccurate and/or wrong**. To bring the crystal and sample reference frames into coincidence, rotations may need to be applied to the data. An excellent reference for this is the following PDF file: [http://pajarito.materials.cmu.edu/rollett/27750/L17-EBSD-analysis-31Mar16.pdf](http://pajarito.materials.cmu.edu/rollett/27750/L17-EBSD-analysis-31Mar16.pdf) ### Default HKL Transformations If the data has come from a HKL acquisition system and the settings of the acquisition software were in the -default modes, then the following reference frame transformations need to be performed: +default modes, then the following reference frame transformations need to be performed. These rotations can be applied with [Rotate Sample Reference Frame](../SimplnxCore/RotateSampleRefFrameFilter.md) and [Rotate Euler Reference Frame](RotateEulerRefFrameFilter.md): + Sample Reference Frame: 180o about the <010> Axis + Crystal Reference Frame: None -The user also may want to assign un-indexed pixels to be ignored by flagging them as "bad". The Threshold Objects -**Filter** can be used to define this *mask* by thresholding on values such as *Error* = 0. This will mark all scan points +The user also may want to assign un-indexed pixels to be ignored by flagging them as "bad". The [Multi-Threshold Objects](../SimplnxCore/MultiThresholdObjectsFilter.md) filter can be used to define this *mask* by thresholding on values such as *Error* = 0. This will mark all scan points that have Error=0 as TRUE, which means those scan points are valid for processing. ### Radians and Degrees -2D .cpr/.crc files have their angles in **radians**. +2D `.cpr`/`.crc` files store their angles in **radians**. + +### Downstream Processing + +Once the reference frames are correct, the imported Euler angles are typically converted to other orientation representations (quaternions, and so on) with [Convert Orientation Representation](ConvertOrientationsFilter.md) before computing misorientations, segmenting grains, or generating pole figures. + +### Required Input Sources -### The Axis Alignment Issue for Hexagonal Symmetry [1] +None — this filter reads directly from a `.cpr`/`.crc` file pair on disk. + +### The Axis Alignment Issue for Hexagonal Symmetry (Advanced) [1] + The issue with hexagonal materials is the alignment of the Cartesian coordinate system used for calculations with the crystal coordinate system (the Bravais lattice). + In one convention (e.g. EDAX.TSL), the x-axis, i.e. [1,0,0], is aligned with the crystal a1 axis, i.e. the [2,-1,-1,0] direction. In this case, the y-axis is aligned with the [0,1,-1,0] direction. (Green Axis in Figure 1) @@ -39,21 +45,17 @@ that have Error=0 as TRUE, which means those scan points are valid for processin + Caution: it appears that the axis alignment is a choice that must be made when installing TSL software so determination of which convention is in use must be made on a case-by-case basis. It is fixed to the y-convention in the HKL software. + The main clue that something is wrong in a conversion is that either the 2110 & 1010 pole figures are transposed, or that a peak in the inverse pole figure that should be present at 2110 has shifted over to 1010. + DREAM3D-NX uses the TSL/EDAX convention. -+ **The result of this is that the filter will by default add 30 degrees to the second Euler Angle (phi2) when reading Oxford Instr (.ctf) files. This can be disabled by the user if necessary.** ++ **The result of this is that the filter will by default add 30 degrees to the second Euler Angle (phi2) when reading Oxford Instr Channel 5 (.cpr/.crc) files. This can be disabled by the user if necessary.** | Figure 1 | |-----------------------------------------------------------------------------------------------------------| | ![Figure showing 30 Degree conversions](Images/Hexagonal_Axis_Alignment.png) | -| Figure 1:**showing TSL and Oxford Instr. conventions. EDAX/TSL is in **Green**. Oxford Inst. is in**Red | +| **Figure 1:** showing TSL and Oxford Instr. conventions. EDAX/TSL is in **Green**. Oxford Inst. is in **Red**. | % Auto generated parameter table will be inserted here -## Example Pipelines - - - ## License & Copyright Please see the description file distributed with this **Plugin** diff --git a/src/Plugins/OrientationAnalysis/docs/ReadCtfDataFilter.md b/src/Plugins/OrientationAnalysis/docs/ReadCtfDataFilter.md index 12e3dbeb4a..d40615886a 100644 --- a/src/Plugins/OrientationAnalysis/docs/ReadCtfDataFilter.md +++ b/src/Plugins/OrientationAnalysis/docs/ReadCtfDataFilter.md @@ -6,23 +6,35 @@ IO (Input) ## Description -This **Filter** will read a single .ctf file into a new **Image Geometry**, allowing the immediate use of **Filters** on the data instead of having to generate the intermediate .h5ebsd file. A **Cell Attribute Matrix** and Ensemble Attribute Matrix** will also be created to hold the imported EBSD information. Currently, the user has no control over the names of the created **Attribute Arrays**. The user should be aware that simply reading the file then performing operations that are dependent on the proper crystallographic and sample reference frame will be **undefined, inaccurate and/or wrong**. In order to bring the crystal reference frame and sample reference frame into coincidence, rotations will need to be applied to the data. An excellent reference for this is the following PDF file: +This filter reads a single `.ctf` file (the EBSD scan format written by Oxford Instruments / HKL Channel 5 software) into a new **Image Geometry**. Reading the file directly lets the data be used immediately by other filters, instead of having to first build an intermediate `.h5ebsd` file. A **Cell Attribute Matrix** (per-pixel data) and an **Ensemble Attribute Matrix** (per-phase data) are created to hold the imported EBSD information. The user currently has no control over the names of the created **Attribute Arrays**. + +The scan stores an **orientation** at every pixel as three **Euler angles** (three angles, in the Bunge Z-X-Z convention, describing how the measured crystal at that pixel is rotated relative to the sample). + +The user should be aware that simply reading the file and then performing operations that depend on a correct crystal reference frame (the axes fixed to the crystal lattice) and sample reference frame (the axes fixed to the physical specimen) will be **undefined, inaccurate and/or wrong**. To bring the crystal and sample reference frames into coincidence, rotations may need to be applied to the data. An excellent reference for this is the following PDF file: [http://pajarito.materials.cmu.edu/rollett/27750/L17-EBSD-analysis-31Mar16.pdf](http://pajarito.materials.cmu.edu/rollett/27750/L17-EBSD-analysis-31Mar16.pdf) ### Default HKL Transformations -If the data has come from a HKL acquisition system and the settings of the acquisition software were in the default modes, then the following reference frame transformations need to be performed: +If the data has come from a HKL acquisition system and the settings of the acquisition software were in the default modes, then the following reference frame transformations need to be performed. These rotations can be applied with [Rotate Sample Reference Frame](../SimplnxCore/RotateSampleRefFrameFilter.md) and [Rotate Euler Reference Frame](RotateEulerRefFrameFilter.md): + Sample Reference Frame: 180o about the <010> Axis + Crystal Reference Frame: None -The user also may want to assign un-indexed pixels to be ignored by flagging them as "bad". The Threshold Objects **Filter** can be used to define this *mask* by thresholding on values such as *Error* = 0. +The user also may want to assign un-indexed pixels to be ignored by flagging them as "bad". The [Multi-Threshold Objects](../SimplnxCore/MultiThresholdObjectsFilter.md) filter can be used to define this *mask* by thresholding on values such as *Error* = 0. ### Radians and Degrees -Most 2D .ctf files have their angles in **degrees** where as DREAM3D-NX expects radians. The filter provides an option to convert the Euler Angles to Radians and is turned on by default. The user is encouraged to create an IPF Image of their EBSD data to ensure that they do in-fact need to have this option enabled. +Most 2D `.ctf` files store their angles in **degrees**, whereas DREAM3D-NX expects radians. The filter provides an option to convert the Euler angles to radians, turned on by default. The user is encouraged to create an IPF (Inverse Pole Figure) image of their EBSD data to confirm whether this option actually needs to be enabled. + +### Downstream Processing + +Once the reference frames are correct, the imported Euler angles are typically converted to other orientation representations (quaternions, and so on) with [Convert Orientation Representation](ConvertOrientationsFilter.md) before computing misorientations, segmenting grains, or generating pole figures. + +### Required Input Sources + +None — this filter reads directly from a `.ctf` file on disk. -### The Axis Alignment Issue for Hexagonal Symmetry [1] +### The Axis Alignment Issue for Hexagonal Symmetry (Advanced) [1] + The issue with hexagonal materials is the alignment of the Cartesian coordinate system used for calculations with the crystal coordinate system (the Bravais lattice). + In one convention (e.g. EDAX.TSL), the x-axis, i.e. [1,0,0], is aligned with the crystal a1 axis, i.e. the [2,-1,-1,0] direction. In this case, the y-axis is aligned with the [0,1,-1,0] direction. (Green Axis in Figure 1) @@ -36,7 +48,7 @@ Most 2D .ctf files have their angles in **degrees** where as DREAM3D-NX expects | Figure 1 | |--------| | ![Figure showing 30 Degree conversions](Images/Hexagonal_Axis_Alignment.png) | -| Figure 1:**showing TSL and Oxford Instr. conventions. EDAX/TSL is in **Green**. Oxford Inst. is in**Red | +| **Figure 1:** showing TSL and Oxford Instr. conventions. EDAX/TSL is in **Green**. Oxford Inst. is in **Red**. | % Auto generated parameter table will be inserted here diff --git a/src/Plugins/OrientationAnalysis/docs/ReadEnsembleInfoFilter.md b/src/Plugins/OrientationAnalysis/docs/ReadEnsembleInfoFilter.md index e07d25fe00..381b53d596 100644 --- a/src/Plugins/OrientationAnalysis/docs/ReadEnsembleInfoFilter.md +++ b/src/Plugins/OrientationAnalysis/docs/ReadEnsembleInfoFilter.md @@ -6,7 +6,13 @@ IO (Input) ## Description -This **Filter** reads in information about the crystal structure and phase types of all the **Features** that are contained in a **Cell** based volume. These values are needed to allow the calculation of statistics on the volume, if they have not already been provided by some other means. The format of the input file is a simple ASCII text file with the extension .ini or .txt. The first group in the file is the name [EnsembleInfo] in square brackets with the key Number_Phases=*number of phases* that are contained in the volume. Subsequent groups in the file list the **Phase Number**, **Crystal Structure** and **Phase Type**. The proper values for the crystal structure and phase type come from internal constants within DREAM3D-NX and are listed here: +An **Ensemble** in DREAM3D-NX is a *phase*: a distinct material or crystal type present in the sample. This filter reads a small ASCII text file that describes each phase and creates the per-phase metadata that many statistics filters require. Specifically, for every phase it records a **Crystal Structure** (the crystal symmetry, which determines how orientations and misorientations are computed) and a **Phase Type** (the role the phase plays, such as a primary matrix phase or a precipitate phase). + +The filter does not create a new geometry. The *Data Container* parameter selects an existing geometry or data group, and the filter adds a new **Ensemble Attribute Matrix** (per-phase data) containing the **Crystal Structures** and **Phase Types** arrays into it. Downstream statistics and synthetic-structure filters read these arrays to know how to treat each phase. This information is needed to compute statistics on the volume when it has not already been provided by some other means (for example, by an EBSD reader). + +The input file is a simple ASCII text file with either a `.ini` or `.txt` extension; both use the same format. The first group is named `[EnsembleInfo]` in square brackets with the key `Number_Phases=`*number of phases* contained in the volume. Subsequent groups list the **Phase Number**, **Crystal Structure** and **Phase Type**. The valid string values for the crystal structure and phase type come from internal constants within DREAM3D-NX and are listed below. These tables describe the *content of the input file*, not the filter's parameters. + +A **Crystal Structure** value names the Laue (point-group) symmetry of the phase. A **Phase Type** value names the role the phase plays in subsequent analysis. **Crystal Structure** @@ -52,9 +58,11 @@ For example, if you have a structure that has 2 phases that consist of a Cubic P CrystalStructure=Hexagonal_High PhaseType=MatrixPhase -% Auto generated parameter table will be inserted here +### Required Input Sources + +None — this filter reads directly from a `.ini` or `.txt` file on disk. It does require an existing **Data Container** (a geometry or data group) into which the created **Ensemble Attribute Matrix** is placed. -## Example Pipelines +% Auto generated parameter table will be inserted here ## License & Copyright diff --git a/src/Plugins/OrientationAnalysis/docs/ReadGrainMapper3DFilter.md b/src/Plugins/OrientationAnalysis/docs/ReadGrainMapper3DFilter.md index 9731256294..9a13f73393 100644 --- a/src/Plugins/OrientationAnalysis/docs/ReadGrainMapper3DFilter.md +++ b/src/Plugins/OrientationAnalysis/docs/ReadGrainMapper3DFilter.md @@ -6,11 +6,11 @@ Readers ## Description -This filter will read Version 4 and Version 5 GrainMapper3D HDF5 files. +This filter reads Version 4 and Version 5 **GrainMapper3D** HDF5 (`.h5`) files. GrainMapper3D is [XNovo Technology](https://xnovotech.com)'s lab diffraction-contrast-tomography (LabDCT) reconstruction software, used to reconstruct 3D crystallographic grain maps from laboratory X-ray measurements. -- Euler data is read as radians -- The Image Geometry that is produced is in units of millimeters -- The user has the opportunity to create compatible Orientation Data and Phase data. See below. +- Euler data is read in **radians**. +- The **Image Geometry** that is produced is in units of **millimeters**. This differs from the micron length-unit assumption made by many downstream DREAM3D-NX filters (for example, size and spacing computations). Be aware of this difference when chaining this reader into a pipeline. +- The user has the opportunity to create DREAM3D-NX compatible Orientation Data and Phase data. See below. ## Parameter Discussion @@ -22,18 +22,22 @@ will be output. Specifically, the Rodrigues vector will be converted into a 4 component and the conjugate computed. The quaternion order will be changed from wxyz to xyzw and the conjugate will be computed. -PhaseId data will be converted to "int32" (as an option) to make that data immediately compatible -with DREAM3D's filters. +PhaseId data will be converted to *int32* (when the *Create Compatible Phase Data* option is checked) to make that data immediately compatible with DREAM3D-NX's filters. -IPFColors can be stored as either uint8 or float values. If you want to immediately view the IPF Colors then -the user should check the box for "Create Compatible IPF Color Data" +IPF (inverse pole figure) colors can be stored in the file as either *uint8* or *float32* values. To immediately view the IPF colors that came from the file, the user should check the box for *Create Compatible IPFColor Data*, which converts any *float32* color data to *uint8*. ## Special Notes -The IPF colors (if any) that are read in from the file are *NOT* compatible with the IPF -Color legends provided by DREAM3D-NX or EBSDLib. The user can use the "Compute IPF Colors" -if they need to specifically understand the crystallographic orientations or they -can obtain the IPF legends from XNovo. +The IPF colors (if any) that are read in from the file are **NOT** compatible with the IPF color legends provided by DREAM3D-NX or EBSDLib. There are two distinct options at play, and they should not be confused: + +- *Create Compatible IPFColor Data* only re-types the colors that were *already computed by GrainMapper3D* so they can be displayed; it does not recompute them against DREAM3D-NX's legends. +- To obtain IPF colors that match the DREAM3D-NX / EBSDLib legends, run [Compute IPF Colors](ComputeIPFColorsFilter.md) downstream on the imported orientation data. Alternatively, the user can obtain the matching IPF legends from XNovo. + +Use [Compute IPF Colors](ComputeIPFColorsFilter.md) if you need to specifically understand the crystallographic orientations using DREAM3D-NX's color conventions. + +## Required Input Sources + +None. This filter reads directly from a `.h5` GrainMapper3D file and creates the **Image Geometry**, **Cell** data, and **Ensemble** data itself. % Auto generated parameter table will be inserted here diff --git a/src/Plugins/OrientationAnalysis/docs/ReadH5EbsdFilter.md b/src/Plugins/OrientationAnalysis/docs/ReadH5EbsdFilter.md index 6d32874b7c..46adc1a0c9 100644 --- a/src/Plugins/OrientationAnalysis/docs/ReadH5EbsdFilter.md +++ b/src/Plugins/OrientationAnalysis/docs/ReadH5EbsdFilter.md @@ -6,7 +6,11 @@ IO (Input) ## Description -This **Filter** reads from the .h5ebsd file that was generated with the *Import Orientation File(s) to H5EBSD* **Filter**. +This filter reads orientation data from a `.h5ebsd` file into a new **Image Geometry**. A `.h5ebsd` file is an HDF5 container that bundles one or more EBSD scan slices (along with their metadata) into a single file, which makes reading a multi-slice 3D volume fast and convenient. + +### Required Input Sources + +The `.h5ebsd` file read by this filter is not a manufacturer's native export. It must first be produced from one or more raw EBSD scan files (such as `.ang` or `.ctf`) using the [Import Orientation File(s) to H5EBSD](EbsdToH5EbsdFilter.md) filter. ![Read H5Ebsd File User Interface](Images/ReadH5Ebsd_UI.png) @@ -21,11 +25,11 @@ The **user** is solely responsible for knowing any sample reference frame transf If the user does not want the **Read H5Ebsd** filter to perform any transformations then the checkbox can be unchecked and the user can manually perform any desired transformations by inserting the appropriate filters into the pipeline. The suggested filters are: -+ {ref}`Rotate Euler Reference Frame ` -+ {ref}`Rotate Sample Reference Frame ` -+ {ref}`Convert Angles to Degrees or Radians ` ++ [Rotate Euler Reference Frame](RotateEulerRefFrameFilter.md) ++ [Rotate Sample Reference Frame](../SimplnxCore/RotateSampleRefFrameFilter.md) ++ [Convert Angles to Degrees or Radians](../SimplnxCore/ChangeAngleRepresentationFilter.md) -An excellant reference for this is the following PDF file: +An excellent reference for this is the following PDF file: [http://pajarito.materials.cmu.edu/rollett/27750/L17-EBSD-analysis-31Mar16.pdf](http://pajarito.materials.cmu.edu/rollett/27750/L17-EBSD-analysis-31Mar16.pdf) | Incorrect | Correct | @@ -34,19 +38,23 @@ An excellant reference for this is the following PDF file: | Euler angles were treated as Radians | Euler angles were converted from Degrees to Radians | |"Interstitial Free (IF) Steel courtesy of [1]"| | -### The Axis Alignment Issue for Hexagonal Symmetry [2] +### The Axis Alignment Issue for Hexagonal Symmetry (Advanced) [2] + The issue with hexagonal materials is the alignment of the Cartesian coordinate system used for calculations with the crystal coordinate system (the Bravais lattice). + In one convention (e.g. EDAX.TSL), the x-axis, i.e. [1,0,0], is aligned with the crystal a1 axis, i.e. the [2,-1,-1,0] direction. In this case, the y-axis is aligned with the [0,1,-1,0] direction. (Green Axis in Figure 1) + In the other convention, (e.g. Oxford Instr, Univ. Metz software), the x-axis, i.e. [1,0,0], is aligned with the crystal [1,0,-1,0] direction. In this case, the y-axis is aligned with the [-1,2,-1,0] direction. (Red Axis in Figure 1) -+ This is important because texture analysis can lead to an ambiguity as to the alignment of [2,-1,-1,0] versus [1,0,-1,0], with apparent **30** shifts in the data. ++ This is important because texture analysis can lead to an ambiguity as to the alignment of [2,-1,-1,0] versus [1,0,-1,0], with apparent **30 degree** shifts in the data. + Caution: it appears that the axis alignment is a choice that must be made when installing TSL software so determination of which convention is in use must be made on a case-by-case basis. It is fixed to the y-convention in the HKL software. + The main clue that something is wrong in a conversion is that either the 2110 & 1010 pole figures are transposed, or that a peak in the inverse pole figure that should be present at 2110 has shifted over to 1010. + DREAM3D-NX uses the TSL/EDAX convention. -+ **The result of this is that the filter will *AUTOMATICALLY* add 30 to phi2 when reading Oxford Instr (.ctf) files or .h5ebsd files denoted with the HKL manufacturer ID. There is no way to turn off this behavior.** ++ **The result of this is that the filter will *AUTOMATICALLY* add 30 degrees to phi2 when reading Oxford Instr (.ctf) files or .h5ebsd files denoted with the HKL manufacturer ID. There is no way to turn off this behavior.** ![Figure 1 showing TSL \& Oxford Instr. conventions.](Images/Hexagonal_Axis_Alignment.png) +### Downstream Processing + +Once the reference frames are correct, the imported Euler angles (three angles, in the Bunge Z-X-Z convention, describing each crystal's orientation relative to the sample) are typically converted to other orientation representations (quaternions, and so on) with [Convert Orientation Representation](ConvertOrientationsFilter.md) before computing misorientations, segmenting grains, or generating pole figures. + % Auto generated parameter table will be inserted here ## Example Pipelines diff --git a/src/Plugins/OrientationAnalysis/docs/ReadH5EspritDataFilter.md b/src/Plugins/OrientationAnalysis/docs/ReadH5EspritDataFilter.md index b98dd6b163..24c223b796 100644 --- a/src/Plugins/OrientationAnalysis/docs/ReadH5EspritDataFilter.md +++ b/src/Plugins/OrientationAnalysis/docs/ReadH5EspritDataFilter.md @@ -6,7 +6,9 @@ IO (Input) ## Description -This **Filter** will read a single .h5 file into a new **Image Geometry**, allowing the immediate use of **Filters** on the data instead of having to generate the intermediate .h5ebsd file. A **Cell Attribute Matrix** and Ensemble Attribute Matrix** will also be created to hold the imported EBSD information. Currently, the user has no control over the names of the created **Attribute Arrays**. +This filter reads a single `.h5` file (the HDF5-based EBSD export from Bruker Nano's Esprit software) into a new **Image Geometry**. Reading the file directly lets the data be used immediately by other filters, instead of having to first build an intermediate `.h5ebsd` file. A **Cell Attribute Matrix** (per-pixel data) and an **Ensemble Attribute Matrix** (per-phase data) are created to hold the imported EBSD information. The user currently has no control over the names of the created **Attribute Arrays**. + +The scan stores an **orientation** at every pixel as three **Euler angles** (three angles, in the Bunge Z-X-Z convention, describing how the measured crystal at that pixel is rotated relative to the sample). | User interface before entering a proper "Z Spacing" value and selecting which scans to include. | |-------| @@ -18,25 +20,31 @@ This **Filter** will read a single .h5 file into a new **Image Geometry**, allow ## Notes About Reference Frames -The user should be aware that simply reading the file then performing operations that are dependent on the proper crystallographic and sample reference frame will be undefined or simply **wrong**. In order to bring the crystal reference frame and sample reference frame into coincidence, rotations will need to be applied to the data. The recommended filters are: +The user should be aware that simply reading the file then performing operations that are dependent on the proper crystal reference frame (the axes fixed to the crystal lattice) and sample reference frame (the axes fixed to the physical specimen) will be undefined or simply **wrong**. To bring the crystal and sample reference frames into coincidence, rotations may need to be applied to the data. The recommended filters are: -+ {ref}`Rotate Euler Reference Frame ` -+ {ref}`Rotate Sample Reference Frame ` ++ [Rotate Euler Reference Frame](RotateEulerRefFrameFilter.md) ++ [Rotate Sample Reference Frame](../SimplnxCore/RotateSampleRefFrameFilter.md) If the data has come from a TSL acquisition system and the settings of the acquisition software were in the default modes, the following reference frame transformations may need to be performed based on the version of the OIM Analysis software being used to collect the data: + Sample Reference Frame: 180o about the <010> Axis + Crystal Reference Frame: 90o about the <001> Axis -The user also may want to assign un-indexed pixels to be ignored by flagging them as "bad". The {ref}`Threshold Objects ` Filter can be used to define this *mask* by thresholding on values such as *MAD* > xx. +The user also may want to assign un-indexed pixels to be ignored by flagging them as "bad". The [Multi-Threshold Objects](../SimplnxCore/MultiThresholdObjectsFilter.md) filter can be used to define this *mask* by thresholding on values such as *Mean Angular Deviation (MAD)* > xx. The **Mean Angular Deviation (MAD)** is a per-pixel metric describing how well the indexed solution fit the measured pattern (lower is better). -+ Note: If the X Step or Y Step within the HDF5 file for a scan is ZERO, those values will be set to 1.0 when the filter runs. This is needed ++ Note: If the X Step or Y Step within the HDF5 file for a scan is ZERO, those values will be set to 1.0 micron when the filter runs. This is needed as the user has no effective way to fix the HDF5 file. If the user needs a different -spacing value, the user can utilize the {ref}`Set Origin and Spacing` filter. +spacing value, the user can utilize the [Set Origin & Spacing (Image Geom)](../SimplnxCore/SetImageGeomOriginScalingFilter.md) filter. -% Auto generated parameter table will be inserted here +### Downstream Processing + +Once the reference frames are correct, the imported Euler angles are typically converted to other orientation representations (quaternions, and so on) with [Convert Orientation Representation](ConvertOrientationsFilter.md) before computing misorientations, segmenting grains, or generating pole figures. -## Example Pipelines +### Required Input Sources + +None — this filter reads directly from a `.h5` file on disk. + +% Auto generated parameter table will be inserted here ## License & Copyright diff --git a/src/Plugins/OrientationAnalysis/docs/ReadH5OimDataFilter.md b/src/Plugins/OrientationAnalysis/docs/ReadH5OimDataFilter.md index 4c604e0921..055dc6ae90 100644 --- a/src/Plugins/OrientationAnalysis/docs/ReadH5OimDataFilter.md +++ b/src/Plugins/OrientationAnalysis/docs/ReadH5OimDataFilter.md @@ -6,7 +6,9 @@ IO (Input) ## Description -This **Filter** will read a single .h5 file into a new **Image Geometry**, allowing the immediate use of **Filters** on the data instead of having to generate the intermediate .h5ebsd file. A **Cell Attribute Matrix** and Ensemble Attribute Matrix** will also be created to hold the imported EBSD information. Currently, the user has no control over the names of the created **Attribute Arrays**. +This filter reads a single `.h5` file (the HDF5-based EBSD export from EDAX OIM Analysis software) into a new **Image Geometry**. Reading the file directly lets the data be used immediately by other filters, instead of having to first build an intermediate `.h5ebsd` file. A **Cell Attribute Matrix** (per-pixel data) and an **Ensemble Attribute Matrix** (per-phase data) are created to hold the imported EBSD information. The user currently has no control over the names of the created **Attribute Arrays**. + +The scan stores an **orientation** at every pixel as three **Euler angles** (three angles, in the Bunge Z-X-Z convention, describing how the measured crystal at that pixel is rotated relative to the sample). When stacking multiple slices into a 3D volume, the *Z Spacing* parameter sets the out-of-plane distance between adjacent slices in microns, and the *Origin* parameter sets the location of the volume's corner in microns. ![User interface before entering a proper "Z Spacing" value and selecting which scans to include.](Images/ReadEDAXH5_1.png) @@ -14,10 +16,10 @@ This **Filter** will read a single .h5 file into a new **Image Geometry**, allow ## Notes About Reference Frames -The user should be aware that simply reading the file then performing operations that are dependent on the proper crystallographic and sample reference frame will be undefined or simply **wrong**. In order to bring the crystal reference frame and sample reference frame into coincidence, rotations will need to be applied to the data. The recommended filters are: +The user should be aware that simply reading the file then performing operations that are dependent on the proper crystal reference frame (the axes fixed to the crystal lattice) and sample reference frame (the axes fixed to the physical specimen) will be undefined or simply **wrong**. To bring the crystal and sample reference frames into coincidence, rotations may need to be applied to the data. The recommended filters are: -- {ref}`Rotate Euler Reference Frame ` -- {ref}`Rotate Sample Reference Frame ` +- [Rotate Euler Reference Frame](RotateEulerRefFrameFilter.md) +- [Rotate Sample Reference Frame](../SimplnxCore/RotateSampleRefFrameFilter.md) If the data has come from a TSL acquisition system and the settings of the acquisition software were in the default modes, the following reference frame transformations may need to be performed based on the version of the OIM Analysis software being used to collect the data: @@ -26,16 +28,22 @@ If the data has come from a TSL acquisition system and the settings of the acqui ### Important Consideration for Sample Reference Frame -If the user is importing more than a single slice from the HDF5 file and using the "Rotate Sample Reference Frame" filter, +If the user is importing more than a single slice from the HDF5 file and using the [Rotate Sample Reference Frame](../SimplnxCore/RotateSampleRefFrameFilter.md) filter, the user should **CHECK** the option **ON** for "Perform Slice By Slice Transform". ## Thresholding out Unindexed Scan Points -The user also may want to assign un-indexed pixels to be ignored by flagging them as "bad". The {ref}`Threshold Objects ` **Filter** can be used to define this *mask* by thresholding on values such as *Confidence Index* > xx or *Image Quality* > desired quality. +The user also may want to assign un-indexed pixels to be ignored by flagging them as "bad". The [Multi-Threshold Objects](../SimplnxCore/MultiThresholdObjectsFilter.md) filter can be used to define this *mask* by thresholding on values such as *Confidence Index* > xx or *Image Quality* > desired quality. **Confidence Index** and **Image Quality** are per-pixel metrics that describe how reliable each individual measurement is. -% Auto generated parameter table will be inserted here +## Downstream Processing + +Once the reference frames are correct, the imported Euler angles are typically converted to other orientation representations (quaternions, and so on) with [Convert Orientation Representation](ConvertOrientationsFilter.md) before computing misorientations, segmenting grains, or generating pole figures. -## Example Pipelines +## Required Input Sources + +None — this filter reads directly from a `.h5` file on disk. + +% Auto generated parameter table will be inserted here ## License & Copyright diff --git a/src/Plugins/OrientationAnalysis/docs/ReadH5OinaDataFilter.md b/src/Plugins/OrientationAnalysis/docs/ReadH5OinaDataFilter.md index 0aba362da8..191ca58f05 100644 --- a/src/Plugins/OrientationAnalysis/docs/ReadH5OinaDataFilter.md +++ b/src/Plugins/OrientationAnalysis/docs/ReadH5OinaDataFilter.md @@ -6,32 +6,36 @@ IO (Input) ## Description -This filter will read data from a single .h5oina file into a new **Image Geometry**, allowing the immediate use of -**Filters** on the data instead of having to generate the intermediate .h5ebsd file. A **Cell Attribute Matrix** and -**Ensemble Attribute Matrix** will also be created to hold the imported EBSD information. Currently, the user has no control -over the names of the created **Attribute Arrays**. +This filter reads data from a single `.h5oina` file (the HDF5-based export from Oxford Instruments' AZtec software) into a new **Image Geometry**. Reading the file directly lets the data be used immediately by other filters, instead of having to first build an intermediate `.h5ebsd` file. A **Cell Attribute Matrix** (per-pixel data) and an **Ensemble Attribute Matrix** (per-phase data) are created to hold the imported EBSD information. The user currently has no control over the names of the created **Attribute Arrays**. + +### What This Filter Produces + +The file is EBSD (Electron Backscatter Diffraction) scan data. The most important imported arrays are: + +- **Orientation** — stored as three **Euler angles** per pixel (the three angles, in Bunge Z-X-Z convention, that describe how each measured crystal is rotated relative to the sample). Orientation is the basis for almost all downstream crystallographic analysis. +- **Phase** — a per-pixel index identifying which material (phase) was measured at that point. +- **Pattern-quality metrics** — values such as Band Contrast, Band Slope, Bands, and Mean Angular Deviation describe how clear and reliable each measurement is. These are commonly used to flag unreliable pixels (see *Reference Frames* below). +- **Per-phase (Ensemble) data** — the crystal structure, lattice constants, and material name for each phase. An **Ensemble** here means one distinct material/crystal type. ### Limitations of the Filter -The current implementation only understands the FORMAT VERSION 2.0 of the H5OINA file. This means that a user -can use a newer H5OINA file but the filter will only extract out the VERSION 2.0 headers and data. If the user -needs additional data from the file, the "Import HDF5 Dataset" filter can be used to agment this filter. +The current implementation only understands **FORMAT VERSION 2.0** of the H5OINA file. A user can still read a newer H5OINA file, but the filter will only extract the VERSION 2.0 headers and data. If additional data is needed from the file, the [Read HDF5 Dataset](../SimplnxCore/ReadHDF5DatasetFilter.md) filter can be used to augment this filter. ![Overview of the user interface.](Images/ImportH5OinaFilter_1.png) ## Notes About Reference Frames -In order to bring the crystal reference frame and sample reference frame into coincidence, rotations **MAY** need to be applied to the data. There are 2 filters that can perform the necessary rotations. +In order to bring the crystal reference frame and the sample reference frame into coincidence, rotations **MAY** need to be applied to the data. Two filters can perform the necessary rotations: -- {ref}`Rotate Euler Reference Frame ` -- {ref}`Rotate Sample Reference Frame ` +- [Rotate Euler Reference Frame](RotateEulerRefFrameFilter.md) +- [Rotate Sample Reference Frame](../SimplnxCore/RotateSampleRefFrameFilter.md) -Historical reference frame operations for a .ctf file are the following: +Historical reference frame operations for Oxford data are the following: + Sample Reference Frame: 180o about the <010> Axis + Crystal Reference Frame: None -The user also may want to assign un-indexed pixels to be ignored by flagging them as "bad". The Threshold Objects **Filter** can be used to define this *mask* by thresholding on values such as *Error* = 0. +The user also may want to assign un-indexed pixels to be ignored by flagging them as "bad". The [Multi-Threshold Objects](../SimplnxCore/MultiThresholdObjectsFilter.md) filter can be used to define this *mask* by thresholding on values such as *Error* = 0. ### Radians and Degrees @@ -46,44 +50,22 @@ All orientation data in the H5OINA file are in radians. + Caution: it appears that the axis alignment is a choice that must be made when installing TSL software so determination of which convention is in use must be made on a case-by-case basis. It is fixed to the y-convention in the HKL software. + The main clue that something is wrong in a conversion is that either the 2110 & 1010 pole figures are transposed, or that a peak in the inverse pole figure that should be present at 2110 has shifted over to 1010. + DREAM3D-NX uses the TSL/EDAX convention. -+ __The result of this is that the filter will by default add 30 degrees to the second Euler Angle (phi2) when reading Oxford Instr (.ctf) files. This can be disabled by the user if necessary.__ ++ __The result of this is that the filter will by default add 30 degrees to the second Euler Angle (phi2) when reading Oxford `.h5oina` files. This can be disabled by the user if necessary.__ | Figure 1 | |--------| | ![Figure showing 30 Degree conversions](Images/Hexagonal_Axis_Alignment.png) | | **Figure 1:** showing TSL and Oxford Instr. conventions. EDAX/TSL is in **Green**. Oxford Inst. is in **Red** | -## Parameters - -| Name | Type | Description | -|------|------| ----------- | -| Input File | File Path | The input .h5 file path | -| Scan Name | String | The name of the scan in the .h5oina file. | -| Z Spacing | float | The spacing in microns between each layer. | -| Origin | float (3x1) | The origin of the volume | -| Import Pattern Data | bool | Default=OFF | -| Hexagonal Axis Alignment | bool | Should the filter convert a Hexagonal phase to the EDAX standard for x-axis alignment | -| Convert Phase data to Int32 | bool | Should the phase data be converted to Int32 or keep the original uint8 | - -## Created Objects - -| Kind | Default Name | Type | Comp Dims | Description | -|-------------|--------------|------|-----------|----------------------------------------| -| Data Container | ImageDataContainer | N/A | N/A | Created Data Container name with an **Image Geometry** | -| Attribute Matrix | Cell Data | Cell | N/A | Created **Cell Attribute Matrix** name | -| Attribute Matrix | Cell Ensemble Data | Cell Ensemble | N/A | Created **Cell Ensemble Attribute Matrix** name | -| Cell Attribute Array | Band Contrast | uint8 | (1) | | -| Cell Attribute Array | Band Slope | uint8 | (1) | | -| Cell Attribute Array | Bands | uint8 | (1) | | -| Cell Attribute Array | Error | uint8 | (1) | The error descriptions are saved as attributes in the .h5oina file | -| Cell Attribute Array | Euler | float | (3) | Three angles defining the orientation of the **Cell** in Bunge convention (Z-X-Z) | -| Cell Attribute Array | MeanAngularDeviation | float | (1) | | -| Cell Attribute Array | Phase | uint8 | (1) | | -| Cell Attribute Array | X | float | (1) | The X Position of the scan point | -| Cell Attribute Array | Y | float | (1) | The Y Position of the scan point | -| Ensemble Attribute Array | CrystalStructures | uint32_t | (1) | Enumeration representing the crystal structure for each **Ensemble** | -| Ensemble Attribute Array | LatticeConstants | float | (6) | The 6 values that define the lattice constants for each **Ensemble**| -| Ensemble Attribute Array | MaterialName | String | (1) | Name of each **Ensemble** | +### Downstream Processing + +Once the reference frames are correct, the imported Euler angles are typically converted to other orientation representations (quaternions, etc.) with [Convert Orientation Representation](ConvertOrientationsFilter.md) before computing misorientations, segmenting grains, or generating pole figures. + +## Required Input Sources + +None — this filter reads directly from a `.h5oina` file on disk. + +% Auto generated parameter table will be inserted here ## Example Pipelines @@ -91,6 +73,6 @@ All orientation data in the H5OINA file are in radians. [1] Rollett, A.D. Lecture Slides located at [http://pajarito.materials.cmu.edu/rollett/27750/L17-EBSD-analysis-31Mar16.pdf](http://pajarito.materials.cmu.edu/rollett/27750/L17-EBSD-analysis-31Mar16.pdf) -## DREAM3DNX Help +## DREAM3D-NX Help -Check out our GitHub community page at [DREAM3DNX-Issues](https://github.com/BlueQuartzSoftware/DREAM3DNX-Issues/discussions) to report bugs, ask the community for help, discuss features, or get help from the developers. +If you need help, need to file a bug report or want to request a new feature, please head over to the [DREAM3DNX-Issues](https://github.com/BlueQuartzSoftware/DREAM3DNX-Issues/discussions) GitHub site where the community of DREAM3D-NX users can help answer your questions. diff --git a/src/Plugins/OrientationAnalysis/docs/WriteGBCDGMTFileFilter.md b/src/Plugins/OrientationAnalysis/docs/WriteGBCDGMTFileFilter.md index add24285be..c4f33b475d 100644 --- a/src/Plugins/OrientationAnalysis/docs/WriteGBCDGMTFileFilter.md +++ b/src/Plugins/OrientationAnalysis/docs/WriteGBCDGMTFileFilter.md @@ -6,9 +6,34 @@ IO (Output) ## Description -This **Filter** creates a .dat file that can be used in conjunction with [GMT](http://gmt.soest.hawaii.edu/) to generate a grain boundary character distribution (GBCD) pole figure. The user must select the relevant phase for which to write the pole figure by entering the *phase index*. +This filter exports a **grain boundary character distribution (GBCD)** as a plain-text `.dat` file that the external [Generic Mapping Tools (GMT)](https://www.generic-mapping-tools.org/) package can render into a pole figure image. The filter does not draw the pole figure itself — it writes the data file that GMT then turns into a picture. -![GMT Visualization of the Small IN100 GBCD Results](Images/WriteGBCDGMTFile.png) +### What is a GBCD Pole Figure? + +A **grain boundary** is the internal interface where two grains (individual crystals) meet inside a material. The **grain boundary character distribution (GBCD)** measures how often boundaries of a particular crystallographic character occur, compared to what a completely random arrangement would produce. + +For a chosen **misorientation** (the rotation that relates the crystal orientations of the two grains on either side of a boundary), the GBCD describes how the boundary-plane normals are distributed in space. That distribution is displayed on a **pole figure**: a 2D circular plot that maps 3D directions onto a disk. The plotted values are in **multiples of a random distribution (MRD)**, where *1.0* means "as common as a random arrangement" and values above *1.0* mark boundary planes that occur more often than random. + +### What This Filter Does + +This filter is one step in an external toolchain: + +[Compute GBCD](ComputeGBCDFilter.md) → **Write GBCD Pole Figure (GMT 5)** → GMT → rendered pole figure + +It samples the GBCD for the selected phase and misorientation and writes the result to a `.dat` text file. GMT (a separate, freely available command-line mapping toolkit) reads that file to produce the final image. + +### Parameter Guidance + +- **Phase of Interest** — the 1-based index of the **Ensemble** (phase) whose boundaries are plotted. A value of *1* selects the first real phase; index *0* is reserved for the unindexed/background ensemble. This value is a dimensionless index. +- **Misorientation Axis-Angle** — selects which boundary misorientation to plot. The first value is the misorientation **angle in degrees**; the remaining three are the crystallographic axis **(h, k, l)**, a dimensionless crystal direction. For example, *60° about (1, 1, 1)* selects the Σ3 twin misorientation common in cubic materials. +- **Output GMT File** — the path of the `.dat` file to write. GMT reads this file to draw the pole figure. + +![GMT visualization of the Small IN100 GBCD results. The contours show the distribution of grain-boundary plane normals (in MRD) for the selected misorientation.](Images/WriteGBCDGMTFile.png) + +### Required Input Sources + +- **GBCD** -- produced by [Compute GBCD](ComputeGBCDFilter.md). +- **Crystal Structures** -- typically read from EBSD data via [Read H5EBSD File](ReadH5EbsdFilter.md), [Read EDAX EBSD Data (.ang)](ReadAngDataFilter.md), or [Read Oxford Instr. EBSD Data (.ctf)](ReadCtfDataFilter.md). % Auto generated parameter table will be inserted here diff --git a/src/Plugins/OrientationAnalysis/docs/WriteGBCDTriangleDataFilter.md b/src/Plugins/OrientationAnalysis/docs/WriteGBCDTriangleDataFilter.md index e354bea86b..672ab37b22 100644 --- a/src/Plugins/OrientationAnalysis/docs/WriteGBCDTriangleDataFilter.md +++ b/src/Plugins/OrientationAnalysis/docs/WriteGBCDTriangleDataFilter.md @@ -6,27 +6,43 @@ IO (Output) ## Description -This **Filter** writes relevant information about the Grain Boundary Character Distribution (GBCD) on an existing set of triangles. The information written includes the inward and outward Euler angles, normals, and areas for each triangle. The file format was originally defined by Prof. Greg Rohrer (CMU). +This filter writes a plain-text file describing the **grain boundary character distribution (GBCD)** for each triangle in a surface mesh. A **grain boundary** is the internal interface where two grains (individual crystals) meet inside a material; a surface mesh represents those interfaces as a collection of triangles in a **Triangle Geometry**. -## Example Output +For every boundary triangle the filter writes one line per triangle containing: - # Triangles Produced from DREAM3D version 5.2 - # Column 1-3: right hand average orientation (phi1, PHI, phi2 in RADIANS) - # Column 4-6: left hand average orientation (phi1, PHI, phi2 in RADIANS) - # Column 7-9: triangle normal - # Column 8: surface area +- The **average crystal orientation** of the grain on each side of the boundary, expressed as a set of Bunge **Euler angles** (phi1, PHI, phi2) in *radians*. +- The triangle **normal**, a unit direction (three unitless direction cosines) pointing perpendicular to the triangle face. +- The triangle **surface area**, in the squared units of the mesh vertex coordinates (square microns for typical EBSD data). + +### Inward / Outward (Left / Right) Average Orientations + +Each boundary triangle separates exactly two grains. The "right hand" (outward) and "left hand" (inward) average orientations are simply the average crystal orientations of those two grains, one on each side of the triangle. Listing both sides lets downstream tools reconstruct the **misorientation** (the rotation relating the two grains) across the boundary. + +### File Format + +The file begins with comment lines describing the ten data columns, followed by one row per triangle. Each row has ten space-separated values: + + # Column 1-3: right hand (outward) average orientation (phi1, PHI, phi2 in RADIANS) + # Column 4-6: left hand (inward) average orientation (phi1, PHI, phi2 in RADIANS) + # Column 7-9: triangle normal (unitless direction cosines) + # Column 10: triangle surface area 0.2662 0.6970 4.4347 0.7993 0.6738 3.5200 0.0000 0.8829 -0.4696 0.0240 0.2662 0.6970 4.4347 0.7993 0.6738 3.5200 0.4532 0.3203 -0.8319 0.0211 0.2662 0.6970 4.4347 0.7993 0.6738 3.5200 1.0000 0.0000 0.0000 0.0312 - 0.2662 0.6970 4.4347 0.7993 0.6738 3.5200 0.9939 0.0780 0.0780 0.0315 - 0.2662 0.6970 4.4347 0.7993 0.6738 3.5200 0.0000 0.9985 0.0551 0.0332 - 0.2662 0.6970 4.4347 0.7993 0.6738 3.5200 0.5074 0.7638 -0.3989 0.0260 0.7993 0.6738 3.5200 0.2662 0.6970 4.4347 0.0000 -0.7792 0.6268 0.0182 - 0.7993 0.6738 3.5200 0.2662 0.6970 4.4347 -0.5737 -0.0995 0.8130 0.0221 - 3.4109 0.6178 1.0586 0.2662 0.6970 4.4347 1.0000 0.0000 0.0000 0.0312 - 3.4109 0.6178 1.0586 0.2662 0.6970 4.4347 0.9822 0.1328 0.1328 0.0256 .. +The file format was originally defined by Prof. Gregory S. Rohrer (Carnegie Mellon University) for use with the Rohrer group's stereological grain-boundary analysis tools. See G. S. Rohrer, "Grain boundary energy anisotropy: a review," *Journal of Materials Science* 46 (2011) 5881-5895, and the associated GBCD/stereology software distributed by his group. + +### Required Input Sources + +- **Face Labels** -- produced by the surface-meshing step, [Create Surface Mesh (QuickMesh)](../SimplnxCore/QuickSurfaceMeshFilter.md). Identifies the two **Features** (grains) on either side of each triangle. +- **Face Normals** -- produced by [Compute Triangle Normals](../SimplnxCore/TriangleNormalFilter.md). +- **Face Areas** -- produced by [Compute Triangle Areas](../SimplnxCore/ComputeTriangleAreasFilter.md). +- **Average Euler Angles** -- per-**Feature** average orientations produced by [Compute Feature Average Orientations](ComputeAvgOrientationsFilter.md). + +Phase and orientation data for the grains ultimately come from an EBSD reader such as [Read H5EBSD File](ReadH5EbsdFilter.md), [Read EDAX EBSD Data (.ang)](ReadAngDataFilter.md), or [Read Oxford Instr. EBSD Data (.ctf)](ReadCtfDataFilter.md). + % Auto generated parameter table will be inserted here ## Example Pipelines diff --git a/src/Plugins/OrientationAnalysis/docs/WriteINLFileFilter.md b/src/Plugins/OrientationAnalysis/docs/WriteINLFileFilter.md index a53b3c674a..1b1f02138a 100644 --- a/src/Plugins/OrientationAnalysis/docs/WriteINLFileFilter.md +++ b/src/Plugins/OrientationAnalysis/docs/WriteINLFileFilter.md @@ -8,17 +8,19 @@ IO (Output) This **Filter** writes out **Cell** data from an **Image Geometry** to a file format used by the Idaho National Laboratory (INL). The format is columnar and space delimited, with header lines denoted by the "#" character. The columns are the following: -- phi1 -- Phi -- phi2 -- x Position (Microns) -- y Position (Microns) -- z Position (Microns) -- Feature Id -- Phase Id -- Symmetry - -Some information about the phase is included in the header section of the file in addition to values for the origin, step size, dimensions and number of **Features** in the file. +- phi1 -- first Bunge Euler angle, in **radians** +- Phi -- second Bunge Euler angle, in **radians** +- phi2 -- third Bunge Euler angle, in **radians** +- x Position -- in **microns** +- y Position -- in **microns** +- z Position -- in **microns** +- Feature Id -- the grain (feature) each cell belongs to +- Phase Id -- the ensemble (phase) each cell belongs to +- Symmetry -- the crystal-symmetry code for the cell's phase + +The **Symmetry** column holds the integer crystal-symmetry code corresponding to the cell's crystal structure (for example, *43* denotes cubic m-3m and *62* denotes hexagonal 6/mmm). The codes follow the EBSDLib `CrystalStructure` enumeration and are taken from the **Crystal Structures** ensemble array. + +Some information about the phase is included in the header section of the file in addition to values for the origin, step size, and dimensions. The origin, **step sizes** (`X_STEP`, `Y_STEP`, `Z_STEP`), and min/max positions in the header are all in **microns**. The header also reports the number of **Features** in the file. ## Example Output @@ -64,6 +66,13 @@ Some information about the phase is included in the header section of the file i 0.266234 0.697020 4.434729 -34.750004 10.250000 -29.000000 639 1 43 0.266234 0.697020 4.434729 -34.500004 10.250000 -29.000000 639 1 43 +## Required Input Sources + +- **Cell Euler Angles** -- typically read from EBSD data via [Read H5EBSD File](ReadH5EbsdFilter.md), [Read EDAX EBSD Data (.ang)](ReadAngDataFilter.md), or [Read Oxford Instr. EBSD Data (.ctf)](ReadCtfDataFilter.md). Must be in radians (Bunge Z-X-Z convention). +- **Cell Phases** -- read alongside the Euler angles from the same EBSD reader. +- **Crystal Structures** -- the **Ensemble**-level array read alongside the phases from the same EBSD reader. +- **Cell Feature Ids** -- produced by a segmentation filter such as [Segment Features (Misorientation)](EBSDSegmentFeaturesFilter.md) or [Segment Features (Scalar)](../SimplnxCore/ScalarSegmentFeaturesFilter.md). + % Auto generated parameter table will be inserted here ## Example Pipelines diff --git a/src/Plugins/OrientationAnalysis/docs/WritePoleFigureFilter.md b/src/Plugins/OrientationAnalysis/docs/WritePoleFigureFilter.md index 4010cb9aac..1d8e527114 100644 --- a/src/Plugins/OrientationAnalysis/docs/WritePoleFigureFilter.md +++ b/src/Plugins/OrientationAnalysis/docs/WritePoleFigureFilter.md @@ -6,51 +6,48 @@ IO (Output) ## Description -This **Filter** creates a standard crystallographic pole figure image for each **Ensemble** (phase) in a selected **Data Container**. The **Filter** uses Euler angles in radians and requires the crystal structures and material names for each **Ensemble** array and the corresponding **Ensemble** Ids on the **Cells**. The **Filter** also optionally can use a *mask* array to determine which angles are valid for the pole figure computation. +This filter creates standard crystallographic **pole figure** images, one set per **Ensemble** (phase) present in the data. A pole figure is a 2D circular plot that maps selected 3D crystal-orientation directions onto a flat disk, making it easy to see whether a material has a preferred orientation (texture) or is randomly oriented. This filter produces pole figures for the **<001>**, **<011>**, and **<111>** crystal directions. -In a practical sense, this means that the following information is available to the filter: +The filter reads **Euler angles** (in *radians*, Bunge Z-X-Z convention) describing the orientation of each cell, the phase each cell belongs to, and per-phase crystal-structure information. An optional **Mask** array can exclude non-indexed or invalid points from the plot. -- Cell Level +### How the Pole Figure Is Drawn - - Euler Angles (Float 32) ordered as sets of (phi1, Phi, phi2). - - Phases (Int32) This is the phase that each Euler angle belongs to - - Optional Mask(boolean or uint8) True/1 if the Euler angle should be included in the pole figure. +Two rendering methods are available through the *Pole Figure Type* parameter: -- Ensemble Level (Phase Information) +- **Color Intensity [0]**: Produces a continuous color intensity map. To do this the filter accumulates orientation counts onto a **modified Lambert square** -- an equal-area grid laid over a square that can be folded onto a hemisphere -- and interpolates that grid onto the unit circle. This is a **Lambert (equal-area) projection**. EBSD OEM software does not use this exact interpolation, so the output may look slightly different from an OEM-generated pole figure. +- **Discrete [1]**: Produces a point-based plot, marking each pixel that received at least one orientation count as a single colored point. This uses a **stereographic** projection, the classic pole-figure projection that maps directions from a sphere onto a plane while preserving angles. - - Laue Class (UInt32) - - Material Names (String) +The crystal symmetry used when folding orientations into the pole figure is determined by each phase's **Laue Class** -- the point-group symmetry class of the crystal (for example, cubic m-3m or hexagonal 6/mmm). The Laue Class is looked up from the per-**Ensemble** Crystal Structures array. -### Algorithm Choice +**Only an advanced user with intimate knowledge of the modified Lambert projection should change the *Lambert Image Size (Pixels)* parameter.** This value is the height/width, in *pixels*, of the internal Lambert square used for interpolation. -1: The pole figure algorithm uses a *modified Lambert square* to perform the interpolations onto the unit circle. This is an alternate type -of interpolation that the EBSD OEMs do not perform which may make the output from DREAM3D-NX look slightly different than output -obtained from the OEM programs. +### Required Input Sources -**Only an advanced user with intimate knowledge of the modified Lambert projection should attempt to change the value for -the "Lambert Image Size (Pixels)" input parameter.** - -2: Discrete Pole figure. The algorithm will simply mark each pixel that had at least 1 count as a black pixel. +- **Euler Angles** and **Phases** -- per-cell orientation and phase data, typically read from EBSD data via [Read H5EBSD File](ReadH5EbsdFilter.md), [Read EDAX EBSD Data (.ang)](ReadAngDataFilter.md), or [Read Oxford Instr. EBSD Data (.ctf)](ReadCtfDataFilter.md). +- **Crystal Structures** (per-**Ensemble**, used to derive each phase's Laue Class) and **Material Name** -- created as part of the **Ensemble** data by the same EBSD reader. +- **Mask** (optional) -- a per-cell boolean array marking valid points, produced by [Multi-Threshold Objects](../SimplnxCore/MultiThresholdObjectsFilter.md). Enable *Use Mask Array* to apply it. ## Output Options ### Write Image to Disk -The user can select to have the combined set of pole figures written to disk as a tiff image file +When *Write Pole Figure as Image* is enabled, the combined set of pole figures is written to disk as a TIFF image file, one file per phase, in the selected output directory. ### Save Pole Figure as Image Geometry -The combined pole figure image will be saved into the DataStructure as an Image Geometry +When *Save Output as Image Geometry* is enabled, the combined pole-figure image is stored in the DataStructure as an **Image Geometry** so it can be viewed inside DREAM3D-NX. + +### Save Count Data Arrays + +When *Save Count Images* is enabled, the per-direction count data for each pole figure is stored as a Data Array inside an **Image Geometry**, allowing custom color plots to be made later. A string Data Array is also stored that records the metadata used to build each plot (number of points, hemisphere, phase name, etc.). When *Normalize Count Data to MRD* is enabled, the counts are normalized to **multiples of a random distribution (MRD)**, where *1.0* means "as common as a random arrangement." -### Save Raw Intensity Data +### Image Size -The normalized count data is saved for each pole figure into a Data Array that is stored inside an Image Geometry. This allows -the user to select their own color plots. The Image Geometry will also have a string DataArray that lists the pertinent -data that went into the creation: Number of points, which hemisphere, Phase Name, etc. +The *Image Size (Square Pixels)* parameter sets the height and width, in *pixels*, of each individual pole figure in the output image. ### Image Layout -The *Image Layout* parameter controls how the pole figures are arranged in the output image. Supporting information (including the color bar legend for color pole figures) will also be printed on the image. +The *Image Layout* parameter controls how the pole figures are arranged in the output image. Supporting information (including the color bar legend for color pole figures) is also drawn on the image. | Colorized Intensity | Discrete | |--------------------|----------| @@ -62,13 +59,6 @@ The available layout choices are: - **Vertical [1]**: Pole figures are arranged in a single vertical column. - **Square [2]**: Pole figures are arranged in a square grid. -### Pole Figure Type - -The *Pole Figure Type* parameter selects the rendering method for the pole figure: - -- **Color Intensity [0]**: Generates a continuous color intensity map using a modified Lambert square interpolation onto the unit circle. -- **Discrete [1]**: Generates a discrete point-based pole figure by marking each pixel that received at least one orientation count. - % Auto generated parameter table will be inserted here ## Example Pipelines diff --git a/src/Plugins/OrientationAnalysis/docs/WriteStatsGenOdfAngleFileFilter.md b/src/Plugins/OrientationAnalysis/docs/WriteStatsGenOdfAngleFileFilter.md index a247014250..9fe88d1efd 100644 --- a/src/Plugins/OrientationAnalysis/docs/WriteStatsGenOdfAngleFileFilter.md +++ b/src/Plugins/OrientationAnalysis/docs/WriteStatsGenOdfAngleFileFilter.md @@ -6,7 +6,7 @@ IO (Output) ## Description -This **Filter** is used in a workflow where the user would like to generate a synthetic microstructure with an ODF that matches (as closely as possible) an existing experimental data set or other data set that is being mimicked. The basic workflow is the following: +This **Filter** is used in a workflow where the user would like to generate a synthetic microstructure with an **Orientation Distribution Function (ODF)** that matches (as closely as possible) an existing experimental data set or other data set that is being mimicked. The ODF describes how crystallographic orientations are statistically distributed in the material. The basic workflow is the following: 1. Import Euler angle data (e.g., ANG or CTF files) 2. Optionally threshold the data so each cell is marked as allowable or not-allowable @@ -21,13 +21,13 @@ This **Filter** is used in a workflow where the user would like to generate a sy ## Important Change from Earlier Versions of StatsGenerator -StatsGenerator can not load data from standard .ang or .ctf files. If you want to get the ODF from an existing experimental data set and you have one of those files then you must use the functionality of this filter +StatsGenerator cannot load data from standard .ang or .ctf files. If you want to get the ODF from an existing experimental data set and you have one of those files then you must use the functionality of this filter. ## Notes on Implementation + A separate file is written for each phase + Spaces are the default as the delimiters between values. The user can select another value -+ Default values of 1.0 are used for both the *weight* and *sigma*. **If the user needs a stronger texture due to a low number of angles then larger values should be used such as 10, 100 or even 1000.** ++ Default values of 1.0 are used for both the *weight* and *sigma*. Both values are dimensionless. **If the user needs a stronger texture due to a low number of angles then larger values should be used such as 10, 100 or even 1000.** + The user has the option to convert the supplied Euler angles to degrees. **StatsGenerator** is able to import Euler angles as either degrees or radians based on user input, so the output type from this **Filter** could remain as radians or be converted to degrees. The user should remain cognizant of what representation their angles are in so that the correct option is chosen during the import process in **StatsGenerator** ## Example File @@ -62,6 +62,12 @@ The *Delimiter* parameter provides the following choices: - **: (colon) [3]**: Uses a colon as the column separator. - **\t (tab) [4]**: Uses a tab character as the column separator. +## Required Input Sources + +- **Euler Angles** -- typically read from EBSD data via [Read H5EBSD File](ReadH5EbsdFilter.md), [Read EDAX EBSD Data (.ang)](ReadAngDataFilter.md), or [Read Oxford Instr. EBSD Data (.ctf)](ReadCtfDataFilter.md). Supplied in radians (Bunge Z-X-Z convention); use the *Convert to Degrees* option only if **StatsGenerator** will import them as degrees. +- **Phases** -- read alongside the Euler angles from the same EBSD reader. A separate output file is written for each phase. +- **Mask** (optional) -- typically produced by [Multi-Threshold Objects](../SimplnxCore/MultiThresholdObjectsFilter.md). Only required when *Only Write Good Elements* is checked. + % Auto generated parameter table will be inserted here ## Example Pipelines diff --git a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/Algorithms/WriteGBCDTriangleData.cpp b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/Algorithms/WriteGBCDTriangleData.cpp index 3640b156eb..4491620267 100644 --- a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/Algorithms/WriteGBCDTriangleData.cpp +++ b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/Algorithms/WriteGBCDTriangleData.cpp @@ -43,7 +43,7 @@ Result<> WriteGBCDTriangleData::operator()() fprintf(f, "# Column 1-3: right hand average orientation (phi1, PHI, phi2 in RADIANS)\n"); fprintf(f, "# Column 4-6: left hand average orientation (phi1, PHI, phi2 in RADIANS)\n"); fprintf(f, "# Column 7-9: triangle normal\n"); - fprintf(f, "# Column 8: surface area\n"); + fprintf(f, "# Column 10: surface area\n"); int32 gid0 = 0; // Feature identifier 0 int32 gid1 = 0; // Feature identifier 1 diff --git a/src/Plugins/SimplnxCore/docs/AddBadDataFilter.md b/src/Plugins/SimplnxCore/docs/AddBadDataFilter.md index fd8d6ea231..c8095347ce 100644 --- a/src/Plugins/SimplnxCore/docs/AddBadDataFilter.md +++ b/src/Plugins/SimplnxCore/docs/AddBadDataFilter.md @@ -6,11 +6,43 @@ Synthetic Building (Misc) ## Description -This **Filter** adds "bad" data to an **Image Geometry**. This **Filter** is intended to add "realism" (i.e., more representative of an experimental dataset) to synthetic structures that don not have any "bad" **Cells**. The user can choose to add "random noise" and/or "noise" along **Feature** boundaries. For a given type of noise, the user must then set the volume fraction of **Cells** to set as "bad". The volume fractions entered apply to only the set of **Cells** that the noise would affect. For example, if the user chose *0.2* for the volume fraction of boundary "noise", then each boundary **Cell** would have a *20%* chance of being changed to a "bad" **Cell** and all other **Cells** would have a *0%* chance of being changed. In order to compute noise over the **Feature** boundaries, the **Filter** needs the Manhattan distances for each **Cell** from the **Feature** boundaries. Note that the computed Manhattan distances are floating point values, but this **Filter** requires an integer array. To create the necessary integer array, use the Convert Attributer Data Type **Filter** to cast the Manhattan distance array to an integer array. +This **Filter** adds synthetic *bad data* to a clean **Image Geometry**. It is intended to make synthetic microstructures look more like real experimental data, which always contains some unindexed cells, noise points, and boundary artifacts. The user controls how much noise to add and where (random throughout the volume, along feature boundaries, or both). -All **Attribute Arrays** that belong to the same **Attribute Matrix** as the selected *Feature Boundary Euclidean Distances* array will have noise added to them. To flag a value as "noise", this **Filter** will initialize a selected *tuple* in the **Attribute Array** to **0**. Note that a zero value *may not* necessarily represent a "bad" data point in any kind of **Attribute Array**. +### Why Use This Filter? -For more information on synthetic building, visit the tutorial. +Synthetic microstructures generated by reconstruction or packing pipelines have perfectly clean cell data -- every cell is assigned to a feature with a valid orientation. Real EBSD scans never look like that. When a synthetic structure is used to seed a downstream simulation that will eventually be compared against experimental measurements, that perfection becomes a problem: the cleanup filters in the experimental pipeline (e.g., [Fill Bad Data](FillBadDataFilter.md), [Neighbor Orientation Correlation](../OrientationAnalysis/NeighborOrientationCorrelationFilter.md)) have nothing to do, and the comparison stops being apples-to-apples. Adding synthetic bad data lets you exercise the same cleanup pipeline on synthetic data as on experimental data. + +### Random vs. Boundary Noise + +The filter supports two independent noise modes; either, both, or neither can be enabled. + +- **Random Noise** (Poisson) -- bad cells are scattered uniformly throughout the volume. Models random non-indexed points caused by detector dropout, surface contamination, or low signal. +- **Boundary Noise** -- bad cells are placed only on cells near a **Feature** boundary. Models the practical reality that EBSD signal is weakest right at grain boundaries, where the beam straddles two crystal orientations. + +### Volume Fraction Semantics + +For each enabled noise mode, the user specifies a *volume fraction* between 0 and 1. **The fraction applies only to the cells that the noise mode would affect, not the whole volume:** + +- *Random* volume fraction = 0.2 -> each cell anywhere in the volume has a 20% chance of being marked bad. +- *Boundary* volume fraction = 0.2 -> each *boundary* cell has a 20% chance of being marked bad. Non-boundary cells are unaffected (0% chance). + +This means a volume fraction of 0.2 in boundary-only mode introduces far fewer bad cells than 0.2 in random mode, because only boundary cells are at risk. + +### What "Bad" Means in Output + +To flag a cell as bad, the filter sets the corresponding tuple in every **Attribute Array** in the same **Attribute Matrix** as the *Boundary Euclidean Distances* input to **0**. This includes Feature Ids, Phases, Quaternions, and any other cell-level data sharing that matrix. Be aware that "0" may be a legitimate value for some arrays (e.g., a phase index) and that the convention here is shared with experimental cleanup filters that interpret Feature Id 0 as bad. + +### Prerequisite Steps + +This filter needs to know which cells are near a feature boundary. That information comes from a Manhattan-distance map, which must be computed and converted before this filter runs: + +1. Run [Compute Euclidean Distance Map](ComputeEuclideanDistMapFilter.md) on the segmented data to produce a *Boundary Euclidean Distances* array (cell-level, float32). +2. Run [Convert Data Type](ConvertDataFilter.md) on that array to cast it to an integer type. This filter's input requires an integer array. + +### Required Input Sources + +- **Boundary Euclidean Distances** (integer array) -- produced by [Compute Euclidean Distance Map](ComputeEuclideanDistMapFilter.md), then cast to integer with [Convert Data Type](ConvertDataFilter.md). +- **Image Geometry** containing cell-level data -- typically a synthetic structure from a packing or reconstruction pipeline. % Auto generated parameter table will be inserted here diff --git a/src/Plugins/SimplnxCore/docs/AlignSectionsFeatureCentroidFilter.md b/src/Plugins/SimplnxCore/docs/AlignSectionsFeatureCentroidFilter.md index aa02d810ce..3694e5302f 100644 --- a/src/Plugins/SimplnxCore/docs/AlignSectionsFeatureCentroidFilter.md +++ b/src/Plugins/SimplnxCore/docs/AlignSectionsFeatureCentroidFilter.md @@ -6,17 +6,27 @@ Reconstruction (Alignment) ## Description -This **Filter** attempts to align 'sections' of the sample perpendicular to the Z-direction by determining the position that closest aligns the centroid(s) of previously defined "regions". The "regions" are defined by a boolean array where the **Cells** have been flagged by another **Filter**. Typically, during reading/processing of the data, each **Cell** is subject to a "quality metric" (or threshold) that defines if the **Cell** is *good*. This threshold can be used to define areas of each slice that are bad, either due to actual features in the microstructure or external references inserted by the user/experimentalist. If these "regions" of *bad* **Cells** are believed to be consistent through sections, then this **Filter** will preserve that by aligning those "regions" on top of one another on consecutive sections. The algorithm of this **Filter** is as follows: +This **Filter** aligns serial sections (2D slices stacked along the Z-direction) by shifting each section so that the centroid of a user-defined region lines up from one section to the next. This is one of several section alignment methods available in DREAM3DNX. -1. Determine the centroid of all **Cells** that are flagged with a boolean value equal to *true* for each section -2. Determine the shifts that place centroids of consecutive sections on top of one another -3. Round the shifts determined in step 2 to the nearest multiple of the **Cell** resolution. (This forces the sections to be shifted by full **Cell** increments) +### When to Use This Method -If the user elects to *Use Reference Slice*, then each section's centroid is shifted to lie on top of the reference slice's centroid position and not its neighboring section's centroid position. +This method works well when a consistent region of interest (defined by a boolean mask) can be identified across all slices. For example, if a quality threshold has been applied so that "good" cells are flagged as *true*, the centroid of those *true* cells represents the center of the usable data on each slice. Aligning these centroids stacks the usable regions on top of each other. -**Note that this is algorithm cannot get caught in a local minimum!** +Unlike the misorientation-based and mutual-information-based alignment methods, the centroid method **cannot get caught in a local minimum**, making it more robust for certain datasets. -The user can also decide to remove a *background shift* present in the sample. The process for this is to fit a line to the X and Y shifts along the Z-direction of the sample. The individual shifts are then modified to make the slope of the fit line be 0. Effectively, this process is trying to keep the top and bottom section of the sample fixed. Some combinations of sample geometry and internal features can result in this algorithm introducing a 'shear' in the sample and the *Linear Background Subtraction* will attempt to correct for this. +### How This Filter Works + +1. For each section (Z-slice), compute the centroid of all **Cells** where the boolean mask is *true* +2. Compute the X and Y shifts needed to align each section's centroid with the previous section's centroid +3. Round the shifts to the nearest multiple of the **Cell** resolution (sections are shifted by whole-cell increments) + +### Reference Slice Option + +If *Use Reference Slice* is enabled, each section is shifted to align with a single fixed reference slice rather than its immediate neighbor. This prevents small errors from accumulating across many sections. + +### Linear Background Subtraction + +Some combinations of sample geometry and internal features can cause the alignment to introduce a gradual "shear" across the sample. Enabling *Linear Background Subtraction* corrects for this by fitting a line to the X and Y shifts along the Z-direction and removing the linear trend. This effectively keeps the top and bottom sections of the sample fixed relative to each other. ## Optional Output Data @@ -43,12 +53,15 @@ In this new structure, what follows is what the created structures represent: In previous versions a file would have been produced instead. If you wish to recreate this, you can write the Attribute Matrix as a CSV/Text file. +### Required Input Sources + +- **Mask** -- a boolean array marking valid cells, typically produced by a threshold operation such as [Multi-Threshold Objects](MultiThresholdObjectsFilter.md) applied to quality or confidence-index arrays. % Auto generated parameter table will be inserted here ## Example Pipelines -+ (02) Small IN100 Full Reconstruction ++ `(02) Small IN100 Full Reconstruction` ## License & Copyright diff --git a/src/Plugins/SimplnxCore/docs/AlignSectionsListFilter.md b/src/Plugins/SimplnxCore/docs/AlignSectionsListFilter.md index f361fc9597..61abab9ac6 100644 --- a/src/Plugins/SimplnxCore/docs/AlignSectionsListFilter.md +++ b/src/Plugins/SimplnxCore/docs/AlignSectionsListFilter.md @@ -6,81 +6,57 @@ Reconstruction (Alignment) ## Description -This **Filter** will apply the precalculated cell shifts to each section of an Image Geometry. It allows for both *relative* or *cumulative* cell shifts. The difference between the two being the former is dependent on the previous slice's position. Under the covers, relative is translated to cumulative before applying shifts to the cells themselves. Previously, the only accepted input was utilizing relative shifts, so use those for backwards compatibility. See the **Handling User Created Shifts File** and **Example Pipelines** sections of this documentation for further hints. +This **Filter** applies precomputed cell shifts to each section of an **Image Geometry**. Unlike the other alignment filters (which calculate shifts automatically), this filter takes a set of known X and Y shifts as input and applies them directly. This is useful for: -### Input Array Type +- Applying shifts that were computed by another alignment filter in a previous run +- Applying user-measured or externally-calculated alignment corrections +- Re-applying a known good alignment to a dataset -The *Input Array Type* parameter controls how the shift values in the input arrays are interpreted: +### Shift Units -- **Relative [0]**: Each shift value is a relative offset between adjacent sections. The shift for section N describes how far section N has moved compared to section N-1. These values are internally converted to cumulative shifts before being applied. -- **Cumulative [1]**: Each shift value is an absolute (cumulative) offset measured from a fixed reference point. The shift for section N describes how far section N has moved from that reference. +All shift values are in **cell (voxel) units**, not physical units. A shift of 3 means move the section by 3 cells, regardless of the cell's physical size (spacing). The shifts must be integers. -## Handling User Created Shifts File +### Relative vs. Cumulative Shifts -In this section we will be covering how to get a user defined shift file into the algorithm. This has been included in the documentation for posterity, as the capability was removed in order to offer a less rigid file structuring and to centralize the I/O paradigm. +The input shifts can be provided in either format: -### File Information +- **Relative [0]**: Each shift describes the offset of section N relative to section N-1. The filter internally converts these to cumulative shifts before applying them. +- **Cumulative [1]**: Each shift describes the absolute offset of section N from a fixed reference point. -**Requirements:** - -- The number of shifts (`x` and `y` both) must be equivalent to the number of slices (Z dimension of the geometry) -- The slices must be ordered from the bottom of the sample to the top of the sample. +### Preparing Shift Data from a File -If using relative shifts for the algorithm, the first line of shifts should be the second slice relative to the first, then the next line is the third slice relative to the second, and so on +If your shifts are stored in an external file, you need to import them into a DataArray before using this filter: -**Recommendations:** +**Requirements:** +- The number of shift entries must equal the number of slices (Z dimension of the geometry) +- Slices must be ordered from bottom to top -The **user** created alignment file is recommended have the format as follows: +**Recommended file format** (space-delimited, two values per line): ```console xshift yshift xshift yshift xshift yshift -etc... -``` - -**Backwards Compatibility Information:** - -For versions of 7.0.3 and below, the DREAM3D and DREAM3DNX produced had the following format: - -```console -slice_m slice_m+1 newxshift newyshift xshifts yshifts -slice_n slice_n+1 newxshift newyshift xshifts yshifts -etc... +... ``` -Where: - -- `newxshift` and `newyshift` were the relative shifts -- `xshifts` and `yshifts` were the cumulative shifts. -- `xcentroid` and `ycentroid` were appended to the end for `AlignSectionsFeatureCentroid` - -**Note: Previous implementations of `AlignSectionsFeatureCentroid` were printing zeros for the relative shifts, so if you are using a file produced by that you must use cumulative shifts.** - -### Importing - -Use "Read CSV File" (`ReadCSVFileFilter`) or "Read Text Data Array" (`ReadTextDataArrayFilter`) to get your data into an array. - -**Recommendations:** - -If you have a file matching the recommended **user** created alignement file above, the process can be expidited with "Read Text Data Array" (`ReadTextDataArrayFilter`). +**To import this format:** -To do so: +1. Use the [Read Text Data Array](ReadTextDataArrayFilter.md) filter +2. Set *Input Numeric Type* to `signed int 64 bit` +3. Set *Number of Components* to `2` +4. Set *Delimiter* to space +5. Set the *Data Array Dimensions* to match the Z dimension of your geometry -1. supply your file in the "Input Text File" parameter -2. set "Input Numeric Type" parameter to `signed int 64 bit` -3. set "Number of Components" parameter to `2` -4. change the "Delimiter" parameter to ` (space)` (index number `2` for python) -5. in the "Created Array Path" parameter, leave the path empty, and name it according to the type of shifts ("relative_shifts" or "cumulative_shifts") -6. get the tuple dims of the Z dimension of your geometry, and put it into the "Data Array Dimensions (Slowest to Fastest)" parameter +For more complex file formats (e.g., legacy DREAM3D alignment files with 6 columns), use the [Read CSV File](ReadCSVFileFilter.md) filter instead. See the backwards compatibility example pipeline for details. -**Backwards Compatibility Information:** +### Note on Legacy Files -For alignment shifts files from the previous version, you **must** use the "Read CSV File" (`ReadCSVFileFilter`). This is a complicated filter parameter wise, so see the documentation provided with the filter. It is recommended to store these in an Attribute Matrix with dimensions equivalent to that of the Z dimension of the target geometry. +Alignment shift files from DREAM3D/DREAM3DNX versions 7.0.3 and earlier used a 6-column format with both relative and cumulative shifts. If using these files, import via the [Read CSV File](ReadCSVFileFilter.md) filter and select the appropriate columns. Files produced by the legacy `AlignSectionsFeatureCentroid` contained zeros for relative shifts -- use cumulative shifts for those. -### Conclusion +### Required Input Sources -The imported data should be prepared and compatible with the Align Sections List input by now. If you have further questions see one of the example pipelines below. +- **Cell Shifts Array** -- a two-component int64 array with one entry per Z-slice. Import this from an external file using [Read Text Data Array](ReadTextDataArrayFilter.md) (simple format) or [Read CSV File](ReadCSVFileFilter.md) (complex/legacy format); or pass the *Relative Shifts* / *Cumulative Shifts* array produced by another alignment filter such as [Align Sections (Feature Centroid)](AlignSectionsFeatureCentroidFilter.md), [Align Sections (Misorientation)](../OrientationAnalysis/AlignSectionsMisorientationFilter.md), or [Align Sections (Mutual Information)](../OrientationAnalysis/AlignSectionsMutualInformationFilter.md). % Auto generated parameter table will be inserted here diff --git a/src/Plugins/SimplnxCore/docs/AppendImageGeometryFilter.md b/src/Plugins/SimplnxCore/docs/AppendImageGeometryFilter.md index 461278fb64..a5193b6835 100644 --- a/src/Plugins/SimplnxCore/docs/AppendImageGeometryFilter.md +++ b/src/Plugins/SimplnxCore/docs/AppendImageGeometryFilter.md @@ -6,8 +6,9 @@ Sampling (Memory/Management) ## Description -This filter allows the user to append one or multiple image geometries to a given image geometry, in any direction (X,Y,Z). The input and -destination **ImageGeometry** objects must have the same dimensions in the directions that are NOT chosen. If the X direction is chosen, the geometries must match in Y & Z. If the Y direction is chosen, the geometries must match in X & Z. If the Z direction is chosen, the geometries must match in X & Y. Optional checks for equal **Resolution** values can also be performed. +This **Filter** appends one or more **Image Geometries** to a destination Image Geometry along a chosen axis (X, Y, or Z), producing a single larger Image Geometry. The input geometries must have matching dimensions in the two axes that are *not* the append direction. Optionally, the filter can also verify that the input and destination geometries have matching spacing on all axes before appending. + +For an introduction to Image Geometry dimensions and spacing, see [Create Image Geometry](CreateImageGeometryFilter.md). This filter also has an option to mirror the resulting geometry in the chosen direction. If the X direction is chosen, it will mirror the positions of the YZ planes. If the Y direction is chosen, it will mirror the positions of the XZ planes. If the Z direction is chosen, it will mirror the positions of the XY planes. @@ -94,6 +95,10 @@ And here is what the geometry looks like after appending the three pieces togeth | ![](Images/AppendImageGeometry/z_complete.png) | ![](Images/AppendImageGeometry/z_mirrored.png) | |:----------------------:|:----------------------:| +### Required Input Sources + +- **Destination Image Geometry** and **Input Image Geometries** -- all geometries to be appended. Typically produced by [Create Image Geometry](CreateImageGeometryFilter.md), [ITK Import Image Stack](../ITKImageProcessing/ITKImportImageStackFilter.md), or an EBSD reader. All must share matching cell-level Attribute Array names if cell data is to be preserved during the append. + % Auto generated parameter table will be inserted here ## Example Pipelines diff --git a/src/Plugins/SimplnxCore/docs/ApplyTransformationToGeometryFilter.md b/src/Plugins/SimplnxCore/docs/ApplyTransformationToGeometryFilter.md index 17595465f7..a7d16af34d 100644 --- a/src/Plugins/SimplnxCore/docs/ApplyTransformationToGeometryFilter.md +++ b/src/Plugins/SimplnxCore/docs/ApplyTransformationToGeometryFilter.md @@ -6,137 +6,95 @@ Rotation, Scale & Transformation ## Description -This **Filter** applies a spatial transformation to either a node **Geometry** or an **Image Geometry**. +This **Filter** applies a spatial transformation -- rotation, translation, scaling, or an arbitrary 4x4 matrix -- to a **Geometry**. Both **Image Geometries** and node-based geometries (Vertex, Edge, Triangle, Quadrilateral, Tetrahedral, Hexahedral) are supported. ### Node Geometries - A node **Geometry** is any geometry that requires explicit definition of **Vertex** positions. Specifically, **Vertex**, **Edge**, **Triangle**, **Quadrilateral**, and **Tetrahedral** **Geometries** may be transformed by this **Filter**. The transformation is applied in place, so the input **Geometry** will be modified. - -- **NO** interpolation will take place as the only changes that take place are the actual coordinates of the vertices. +For node-based geometries, the transformation modifies vertex positions only. No interpolation occurs. Multiple transformations can be applied in succession without artifacts. ### Image Geometry -If the user selects an **Image Geometry** then there are 2 additional required filter parameters that need to be set: - -- **Interpolation Method**: This will be used when transferring the data from the old geometry to the newly transformed geometry. -- **Cell Attribute Matrix**: This Attribute Matrix holds the data that is associated with each cell of the image geometry. - -The linear/Bi-Linear/Tri-Linear Interpolation is adapted from the equations presented -in [https://www.cs.purdue.edu/homes/cs530/slides/04.DataStructure.pdf, page 36}](https://www.cs.purdue.edu/homes/cs530/slides/04.DataStructure.pdf) - -## Example Image Geometry Transformations - -| Description | Example Output Image | -|-------------|----------------------| -| Input Image | ![Input Image](Images/ApplyTransformation_AsRead.png) | -| After Rotation of 45 Degrees around the <001> axis | ![Rotation of 45 Degrees around the <0,0,1> axis](Images/ApplyTransformation_Rotated.png) | -| Scaled by 2x in the X and Y axis | ![Scaled by 2x in the X and Y axis.](Images/ApplyTransformation_Scaled.png) | - -## Image Geometry Caveat +For Image Geometries, transformation requires re-gridding because cell positions are implicit in the grid spacing and origin. After transformation, a new grid is generated and cell data is interpolated onto it. This is governed by two extra parameters: -Using this filter several times in a row to apply several transforms in succession to the same image geometry is highly likely to result in visual artifacts related to the intermediate re-gridding of the image geometry between transformations. For example, let's rotate an image geometry 90 degrees along the Z axis: +- **Interpolation Method** -- how cell data values are sampled from the old grid (see below). +- **Cell Attribute Matrix** -- which attribute matrix holds the cell data to transform. -| Description | Image | -|-------------|----------------------| -| Input Image | ![Input Image](Images/ApplyTransformation_ImageGeom.png) | -| After Rotation of 90 Degrees around the <001> axis | ![Rotation of 90 Degrees around the <0,0,1> axis](Images/ApplyTransformation_ImageGeom_Final.png) | +### Image Geometry Caveat: Successive Transformations -Instead of using a single rotation of 90 degrees, if the user has a need to instead apply several rotations that still add up to 90 degrees, for example a pair of 45 degree rotations, potential unwanted artifacts can occur due to the intermediate regridding for each rotation. +Applying multiple transformations one-at-a-time to an Image Geometry produces visible re-gridding artifacts because each intermediate step re-samples the data. The following example shows a 90-degree rotation done as a single step versus as two 45-degree steps: | Description | Image | |-------------|----------------------| | Input Image | ![Input Image](Images/ApplyTransformation_ImageGeom.png) | -| After 1st Rotation of 45 Degrees around the <001> axis | ![1st Rotation of 45 Degrees around the <0,0,1> axis](Images/ApplyTransformation_ImageGeom_Intermediate.png) | -| After 2nd Rotation of 45 Degrees around the <001> axis | ![2nd Rotation of 45 Degrees around the <0,0,1> axis](Images/ApplyTransformation_ImageGeom_Final_Artifacts.png) | +| After single 90-degree rotation around <001> | ![Rotation of 90 Degrees around the <0,0,1> axis](Images/ApplyTransformation_ImageGeom_Final.png) | +| After first 45-degree rotation | ![1st Rotation of 45 Degrees around the <0,0,1> axis](Images/ApplyTransformation_ImageGeom_Intermediate.png) | +| After second 45-degree rotation (artifacts visible) | ![2nd Rotation of 45 Degrees around the <0,0,1> axis](Images/ApplyTransformation_ImageGeom_Final_Artifacts.png) | -Why does this happen? Let's overlay the centers of each cell on top of the original image geometry. +The problem is that after the first 45-degree rotation, the cell centers no longer align with the new grid cells -- the re-gridding has shifted them. On the second rotation, those misalignments compound. | Description | Image | |-------------|----------------------| | Input Image | ![Input Image](Images/ApplyTransformation_ImageGeom_WithVertices.png) | -| After 1st Rotation of 45 Degrees around the <001> axis | ![1st Rotation of 45 Degrees around the <0,0,1> axis](Images/ApplyTransformation_ImageGeom_Intermediate_WithVertices.png) | - -The green vertices refer to the center of each image geometry cell. As you can see, after the first 45 degree rotation, the image geometry is re-gridded and now the transformed green vertices are no longer in the center of each cell. - -On the 2nd and final 45 degree rotation, the image geometry is going to double in size because the algorithm doesn't know the final image geometry's exact size and doubles its size to account for the worst case scenario. +| After 1st 45-degree rotation (cell centers in green) | ![1st Rotation of 45 Degrees around the <0,0,1> axis](Images/ApplyTransformation_ImageGeom_Intermediate_WithVertices.png) | -Let's see how the transformed green vertices overlay on the intermediate image geometry when the field of vertices has doubled in size but the image geometry hasn't actually been transformed a 2nd time yet. +To avoid these artifacts, **combine all transformations into a single 4x4 matrix first** using [Combine Transformation Matrices](CombineTransformationMatricesFilter.md), then apply that combined matrix as a single transformation: | Description | Image | |-------------|----------------------| -| After 1st Rotation of 45 Degrees around the <001> axis | ![1st Rotation of 45 Degrees around the <0,0,1> axis](Images/ApplyTransformation_ImageGeom_Intermediate_WithVertices2.png) | +| Combined 90-degree rotation applied once | ![Combined Rotation of 90 Degrees around the <0,0,1> axis](Images/ApplyTransformation_ImageGeom_Final.png) | -The cell circled in purple has two green vertices inside it. This means that once the 2nd 45 degree transformation is completed, the final image geometry will have that orange color shifted outside where we would expect it to be. And sure enough: +This caveat only applies to Image Geometries. Node-based geometries can have any number of transformations chained without issue. -| Description | Image | -|-------------|----------------------| -| After 2nd Rotation of 45 Degrees around the <001> axis | ![2nd Rotation of 45 Degrees around the <0,0,1> axis](Images/ApplyTransformation_ImageGeom_Final_Artifacts2.png) | +### Example Transformations (Image Geometry) -To avoid this problem, it is considered best practice to use the *[Combine Transformation Matrices](CombineTransformationMatricesFilter.md)* filter to combine all transforms together into one transform before applying the transform to an image geometry. - -| Description | Image | +| Description | Example Output Image | |-------------|----------------------| -| After combining both 45 degree rotations and applying around the <001> axis | ![Rotation of 90 Degrees around the <0,0,1> axis](Images/ApplyTransformation_ImageGeom_Final.png) | - -## NOTE: - -This caveat is ONLY for image geometries. Multiple transformations can be applied in succession to any of the "Node" based geometries without any issues. Those are: - -- Vertex -- Edge -- Triangle -- Quad -- Tetrahedral -- Hexahedral - -## Transformation Information +| Input Image | ![Input Image](Images/ApplyTransformation_AsRead.png) | +| 45-degree rotation around <001> | ![Rotation of 45 Degrees around the <0,0,1> axis](Images/ApplyTransformation_Rotated.png) | +| 2x scale in X and Y | ![Scaled by 2x in the X and Y axis.](Images/ApplyTransformation_Scaled.png) | ### Transformation Type -The *Transformation Type* parameter provides the following choices: - -- **No Transform [0]**: Applies an identity transformation; the geometry is unchanged. -- **Pre-Computed Transformation Matrix (4x4) [1]**: Uses a 4x4 transformation matrix supplied as an Attribute Array in row major order. -- **Manual Transformation Matrix [2]**: Uses a manually entered 4x4 transformation matrix. -- **Rotation [3]**: Rotates about a supplied axis-angle with the angle specified in degrees. -- **Translation [4]**: Translates the geometry by the supplied (x, y, z) values. -- **Scale [5]**: Scales the geometry by the supplied (x, y, z) values. +The *Transformation Type* parameter selects how the transformation is specified: -The user may select from a variety of options for the type of transformation to apply: +| Value | Type | Description | +|---|---|---| +| 0 | No Transform | Identity (geometry unchanged). | +| 1 | Pre-Computed Transformation Matrix (4x4) | A 4x4 matrix supplied as a 16-element float32 Attribute Array in row-major order. | +| 2 | Manual Transformation Matrix | A 4x4 matrix typed in directly. | +| 3 | Rotation | Axis-angle: a unit vector (x, y, z) and an angle in **degrees**. | +| 4 | Translation | A (dx, dy, dz) translation vector in the geometry's physical units. | +| 5 | Scale | A (sx, sy, sz) scaling vector (dimensionless multipliers). | -| Enum Value | Transformation Type | Representation | -|------------|------------------------------------|--------------------------------------------------------------------------------------| -| 0 | No Transformation | Identity transformation | -| 1 | Pre-Computed Transformation Matrix | A 4x4 transformation matrix, supplied by an **Attribute Array** in *row major* order | -| 2 | Manual Transformation Matrix | Manually entered 4x4 transformation matrix | -| 3 | Rotation | Rotation about the supplied axis-angle (Angle in Degrees). | -| 4 | Translation | Translation by the supplied (x, y, z) values | -| 5 | Scale | Scaling by the supplied (x, y, z) values | +The linear / bi-linear / tri-linear interpolation math is adapted from [Purdue CS530 slides, page 36](https://www.cs.purdue.edu/homes/cs530/slides/04.DataStructure.pdf). -The **Translate Geometry To Global Origin Before Transformation** option must be selected if the user wants to translate their volume to (0, 0, 0), apply the transform, and then translate the volume back to its original location. +If *Translate Geometry To Global Origin Before Transformation* is enabled, the geometry is shifted so its centroid sits at (0, 0, 0) before the transformation is applied, then translated back. Use this to rotate about the geometry's center rather than the world origin. -### Resampling or Interpolation (Image Geometry Only) +### Interpolation Method (Image Geometry Only) -When transforming an **Image Geometry**, the *Resampling or Interpolation* parameter controls how cell data values are assigned in the newly created grid: +- **Nearest Neighbor [0]** -- each output cell takes the value of the nearest input cell. Fast; preserves sharp boundaries; blocky. +- **Linear (trilinear in 3D) [1]** -- each output cell value is interpolated from surrounding input cells. Smoother; may blur sharp features. +- **No Interpolation [2]** -- no resampling. Use only when the transformation does not change the grid topology (e.g., integer translations that align exactly with the existing grid). -- **Nearest Neighbor Resampling [0]**: Each output cell takes the value of the nearest input cell. This is fast and preserves sharp boundaries, but may produce a blocky appearance. -- **Linear Interpolation [1]**: Each output cell value is computed using trilinear interpolation from the surrounding input cells. This produces smoother results but may blur sharp features. -- **No Interpolation [2]**: The transformation is applied without any resampling of cell data. Use this option when the transformation does not change the grid topology (e.g., integer translations that align exactly with the existing grid). +### Saving the Final Transformation Matrix -## Saving the final transformation Matrix. - -There is an option to save the final transformation matrix into its own array. The format of the output DataArray is a -flattened array 16 elements in size that represents a 4x4 matrix. The elements are encoded in a ROW MAJOR array, i.e., +Optionally, the final 4x4 transformation matrix can be saved as an Attribute Array. The output is a 16-element float32 array in **row-major** order: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 -represents the following 4x4 Matrix +represents the 4x4 matrix: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 +### Required Input Sources + +- **Geometry** -- any supported geometry; for Image Geometry workflows, typically produced by [Create Image Geometry](CreateImageGeometryFilter.md), [ITK Import Image Stack](../ITKImageProcessing/ITKImportImageStackFilter.md), or an EBSD reader. +- **Pre-Computed Transformation Matrix** (only for Transformation Type 1) -- typically produced by [Combine Transformation Matrices](CombineTransformationMatricesFilter.md). +- **Cell Attribute Matrix** (Image Geometry only) -- the cell-level data to be re-gridded. + % Auto generated parameter table will be inserted here ## Example Pipelines diff --git a/src/Plugins/SimplnxCore/docs/ApproximatePointCloudHullFilter.md b/src/Plugins/SimplnxCore/docs/ApproximatePointCloudHullFilter.md index 573882d2b4..ce9eb94b30 100644 --- a/src/Plugins/SimplnxCore/docs/ApproximatePointCloudHullFilter.md +++ b/src/Plugins/SimplnxCore/docs/ApproximatePointCloudHullFilter.md @@ -6,24 +6,33 @@ Point Cloud (Geometry) ## Description -This **Filter** determines a set of points that approximates the surface (or *hull*) or a 3D point cloud represented by a **Vertex Geometry**. The hull is approximate in that the surface points are not guaranteed to hve belonged to the original point cloud; instead, the determined set of points is meant to represent a sampling of where the 3D point cloud surface occurs. To following steps are used to approximate the hull: +This **Filter** determines a set of points that approximates the surface (or *hull*) of a 3D point cloud represented by a **Vertex Geometry**. The hull is approximate in that the surface points are not guaranteed to have belonged to the original point cloud; instead, the determined set of points is meant to represent a sampling of where the 3D point cloud surface occurs. The following steps are used to approximate the hull: -1. A structured rectilinear grid with user-defined resolution is overlaid on the point cloud. +1. A structured rectilinear grid with user-defined resolution is overlaid on the point cloud. 2. Each point is mapped to the voxel it occupies in the sampling grid. 3. For each voxel in the sampling grid: 1. Each of its 26 neighbors is inspected to see if that neighbor contains any points. 2. If the number of empty neighbors exceeds a user-defined threshold, the voxel is flagged as a "surface voxel". 4. For each voxel flagged as a "surface voxel", the coordinates of the points in that voxel are averaged to produce a new point that is inserted into the hull. -The above algorithm is significantly faster that other geometric approaches for determining a point cloud surface, but yields only an approximate solution. Note that this approach is able of handling concavities in the point cloud, assuming the grid resolution is small enough to resolve any concavities. In general, a grid resolution should be chosen small enough to resolve any surface features of interest. The algorithm is also sensitive to the minimum number of empty neighbors parameter: consider modifying this parameter if the resulting hull is unsatisfactory. +The above algorithm is significantly faster than other geometric approaches for determining a point cloud surface, but yields only an approximate solution. Note that this approach is capable of handling concavities in the point cloud, assuming the grid resolution is small enough to resolve any concavities. In general, a grid resolution should be chosen small enough to resolve any surface features of interest. The algorithm is also sensitive to the minimum number of empty neighbors parameter: consider modifying this parameter if the resulting hull is unsatisfactory. + +### Parameter Guidance + +- **Grid Resolution** -- the X, Y, and Z edge lengths of the sampling grid voxels, expressed in the same coordinate units as the input point cloud's vertex coordinates. +- **Minimum Number of Empty Neighbors** -- a dimensionless count in the range 0 to 26 (a voxel has 26 neighbors in a 3D grid). A voxel is flagged as a surface voxel when its number of empty neighbors exceeds this value. Larger values flag fewer voxels (only those more exposed on the surface). Note that the resulting hull geometry does not inherit any **Attribute Arrays** from the original point cloud. +### Required Input Sources + +- **Vertex Geometry** -- the input 3D point cloud, typically created by an import step or by a filter that produces a **Vertex Geometry**. + % Auto generated parameter table will be inserted here ## License & Copyright -Please see the description file distributed with this plugin. +Please see the description file distributed with this **Plugin** ## DREAM3D-NX Help diff --git a/src/Plugins/SimplnxCore/docs/ArrayCalculatorFilter.md b/src/Plugins/SimplnxCore/docs/ArrayCalculatorFilter.md index bc12de72e2..bd119f7a2e 100644 --- a/src/Plugins/SimplnxCore/docs/ArrayCalculatorFilter.md +++ b/src/Plugins/SimplnxCore/docs/ArrayCalculatorFilter.md @@ -135,6 +135,11 @@ This equation takes the cube root of *8* and stores the result in an array with This equation raises *3* to the power of the value stored in every component of every tuple in *Array1*. The resulting array has the same tuple and component size of *Array1*. +### Required Input Sources + +- **Source Attribute Matrix** -- the Attribute Matrix that contains the input arrays referenced in the *Infix Expression*. +- **Output Attribute Matrix** -- an existing Attribute Matrix with the matching tuple count (or with exactly one tuple, when the expression contains no arrays). + % Auto generated parameter table will be inserted here ## Example Pipelines diff --git a/src/Plugins/SimplnxCore/docs/ChangeAngleRepresentationFilter.md b/src/Plugins/SimplnxCore/docs/ChangeAngleRepresentationFilter.md index 0071c9233d..d8e35bf9f3 100644 --- a/src/Plugins/SimplnxCore/docs/ChangeAngleRepresentationFilter.md +++ b/src/Plugins/SimplnxCore/docs/ChangeAngleRepresentationFilter.md @@ -23,6 +23,10 @@ Generally, all **Filters** within DREAM3D-NX use radians as a default unit, but If the wrong conversion is selected (e.g., the user chooses *degrees to radians*, but their data is already in radians), the **Filter** will apply the conversion anyway and will result in erroneous data being used for the rest of the pipeline. If unsure about the units, check with the software supplier. +### Required Input Sources + +- An angle **Attribute Array** (e.g., Euler angles), typically read from EBSD data via [Read H5EBSD](../OrientationAnalysis/ReadH5EbsdFilter.md), [Read CTF Data](../OrientationAnalysis/ReadCtfDataFilter.md), or [Read ANG Data](../OrientationAnalysis/ReadAngDataFilter.md). + % Auto generated parameter table will be inserted here ## Example Pipelines diff --git a/src/Plugins/SimplnxCore/docs/CombineAttributeArraysFilter.md b/src/Plugins/SimplnxCore/docs/CombineAttributeArraysFilter.md index 7284e2f57c..4b1925d925 100644 --- a/src/Plugins/SimplnxCore/docs/CombineAttributeArraysFilter.md +++ b/src/Plugins/SimplnxCore/docs/CombineAttributeArraysFilter.md @@ -32,6 +32,12 @@ The user may also select to normalize the resulting combined array. The normaliz **NOTE:** If you are wanting to instead concatenate/append data arrays together into a longer array, please see the [Concatenate Data Arrays](ConcatenateDataArraysFilter.md) filter. +A typical use case is building a multi-component coordinate or quaternion array from three or four separate single-component scalar arrays (e.g., combining `X_Coord`, `Y_Coord`, `Z_Coord` into a single 3-component `Vertices` array before passing to [Create Geometry](CreateGeometryFilter.md)). + +### Required Input Sources + +- **Input Attribute Arrays** -- two or more arrays of the same primitive type and tuple count, in the order you want their components to appear in the combined array. + % Auto generated parameter table will be inserted here ## Example Pipelines diff --git a/src/Plugins/SimplnxCore/docs/CombineNodeBasedGeometriesFilter.md b/src/Plugins/SimplnxCore/docs/CombineNodeBasedGeometriesFilter.md index 84f7150520..63a0273899 100644 --- a/src/Plugins/SimplnxCore/docs/CombineNodeBasedGeometriesFilter.md +++ b/src/Plugins/SimplnxCore/docs/CombineNodeBasedGeometriesFilter.md @@ -2,15 +2,19 @@ ## Group (Subgroup) -Core +Core (Combining) ## Description -This **Filter** will combine any node-based geometries together into one node-based geometry. The algorithm is governed by several rules: +This **Filter** merges two or more **node-based geometries** into a single combined geometry. A **node-based geometry** is any geometry built from a shared list of vertices (nodes) plus a connectivity that defines its elements: a **Vertex Geometry** (points only), an **Edge Geometry** (line segments), a **Triangle** or **Quadrilateral Geometry** (surface faces), or a **Tetrahedral** or **Hexahedral Geometry** (solid cells). -1. All input geometries must have the same geometry type. For example, inputting all Triangle geometries will output a combined Triangle geometry, all Edge geometries will output a combined Edge geometry, etc. -2. All input geometries must contain vertex and node data that have the exact same names, types, and component dimensions. For example, if one input geometry has an edges array with edges data arrays, all input geometries must have an edges array with edges data arrays that have the exact same names, types, and component dimensions. If one input geometry has vertex data arrays, then all input geometries must have vertex data arrays that all have the exact same names, types, and component dimensions. -3. Higher order input geometries can include lower order node data. For example, an input tetrahedral geometry can include edge data (as long as all input tetrahedral geometries contain edge data with the same names, types, and component dimensions). +When combining, the filter concatenates the vertex lists of all inputs into one list and then renumbers the connectivity. The element (cell) indices from each input geometry are shifted by the running total number of vertices contributed by all preceding geometries, so that every element continues to reference the correct vertices in the merged vertex list. **Duplicate or coincident vertices are *not* detected or merged** — if two inputs contain a vertex at the same physical location, both copies appear in the output. + +The algorithm is governed by several rules: + +1. All input geometries must have the same geometry type. For example, combining only **Triangle Geometries** produces a combined **Triangle Geometry**, and combining only **Edge Geometries** produces a combined **Edge Geometry**. +2. All input geometries must contain vertex and element data arrays with the exact same names, types, and component dimensions. For example, if one input has an edge data array, every input must have an edge data array with a matching name, type, and component dimension; the same requirement applies to vertex data arrays. +3. A **higher-order** geometry (one whose elements are built from more vertices, such as a **Tetrahedral Geometry**) may also carry the data of its **lower-order** elements. For example, a tetrahedral geometry may include edge data, as long as every input tetrahedral geometry includes matching edge data. *NOTE:* Any additional groups, attribute matrices, or arrays that are not one of the following: @@ -19,11 +23,13 @@ This **Filter** will combine any node-based geometries together into one node-ba 3. Face arrays or face data 4. Polyhedra arrays or polyhedra data -WILL BE ignored and will not exist in the geometry outputted by this filter. +will be ignored and will not appear in the geometry produced by this filter. -% Auto generated parameter table will be inserted here +### Required Input Sources -## Example Pipelines +- **Input Geometries** -- two or more **node-based geometries** of the *same* type. Surface meshes are typically produced by [Create Surface Mesh (QuickMesh)](QuickSurfaceMeshFilter.md); edge geometries by [Slice Triangle Geometry](SliceTriangleGeometryFilter.md) or [Create AM Scan Paths](CreateAMScanPathsFilter.md). + +% Auto generated parameter table will be inserted here ## License & Copyright diff --git a/src/Plugins/SimplnxCore/docs/CombineStlFilesFilter.md b/src/Plugins/SimplnxCore/docs/CombineStlFilesFilter.md index a951a6ef42..d8180d4bce 100644 --- a/src/Plugins/SimplnxCore/docs/CombineStlFilesFilter.md +++ b/src/Plugins/SimplnxCore/docs/CombineStlFilesFilter.md @@ -6,10 +6,10 @@ Reader/Input ## Description -This **Filter** combines all of the STL files from a given directory into a single triangle geometry. This filter will make use of the **Import STL File Filter** to read in each stl file in the given directory and then will proceed to combine each of the imported files into a single triangle geometry. +This **Filter** combines all of the STL files from a given directory into a single triangle geometry. STL (STereoLithography) is a common 3D surface-mesh file format that describes a geometry as an unstructured collection of triangular facets. This filter will make use of the [Read STL File](ReadStlFileFilter.md) filter to read in each STL file in the given directory and then will proceed to combine each of the imported files into a single triangle geometry. There is an option to label the faces and vertices with a "Part Number" that represents the index into the list of files that was used as the input. This would be based on the lexographical index and starts from 1. This allows for the immediate "segmentation" of the resulting triangle geometry or just as a convenience to "color by" in the visualization widget. This can -also be used in the "Write STL Files from Triangle Geometry" Filter if the selection for +also be used in the [Write STL Files from Triangle Geometry](WriteStlFileFilter.md) filter if the selection for the "File Grouping Type" is set to "Part Index" in the UI. Then use the "Part Number" array that is created in this filter for the "Part Index". diff --git a/src/Plugins/SimplnxCore/docs/CombineTransformationMatricesFilter.md b/src/Plugins/SimplnxCore/docs/CombineTransformationMatricesFilter.md index f053420f05..42932532e5 100644 --- a/src/Plugins/SimplnxCore/docs/CombineTransformationMatricesFilter.md +++ b/src/Plugins/SimplnxCore/docs/CombineTransformationMatricesFilter.md @@ -6,24 +6,41 @@ Core ## Description -The **Combine Transformation Matrices** filter merges multiple 4×4 transformation matrices into a single composite transformation. +This **Filter** multiplies multiple 4x4 transformation matrices together to produce a single composite 4x4 matrix. Use it when you have a sequence of transformations (rotations, translations, scales, etc.) that need to be combined before applying them to an Image Geometry. -Each input matrix must be provided as a 16-element float32 DataArray in row-major order, representing operations such as translation, rotation, scaling, or shear. During the preflight phase, the filter verifies that at least two matrices are selected, each contains exactly 16 elements (4 tuples × 4 components OR 16 tuples x 1 component OR 1 tuple x 16 components, etc), and all input arrays share the same tuple and component layout. +### When to Use This Filter -## Saving the Output Transformation Matrix. +[Apply Transformation to Geometry](ApplyTransformationToGeometryFilter.md) re-grids cell data each time it runs. Applying multiple transformations one at a time to an Image Geometry compounds re-gridding artifacts. The correct approach is to combine all the transformations into a single 4x4 matrix first using this filter, then apply that combined matrix as a single transformation. See the *Image Geometry Caveat* section in [Apply Transformation to Geometry](ApplyTransformationToGeometryFilter.md) for the visual demonstration. -The format of the output DataArray is a flattened array 16 elements in size that represents a 4x4 matrix. -The elements are encoded in ROW MAJOR order, i.e., +For node-based geometries (Vertex, Edge, Triangle, Quad, Tet, Hex), there is no re-gridding step, so successive transformations are safe and this filter is not strictly needed -- but combining is still slightly more efficient than chaining. + +### Input Format + +Each input matrix must be a 16-element float32 **Attribute Array** in **row-major** order: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 -represents the following 4x4 Matrix +represents the 4x4 matrix: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 +The component shape can be any layout that yields 16 total elements (4×4, 16×1, or 1×16). All input matrices must share the same tuple and component layout. + +### Multiplication Order + +The matrices are multiplied in the order listed in the parameter. The result represents applying the **first** matrix first, then the second, and so on. In matrix algebra, this means: + + M_combined = M_last * M_(last-1) * ... * M_2 * M_1 + +which corresponds to applying M_1 first to a vector v: `v' = M_combined * v = M_last * ... * M_2 * M_1 * v`. + +### Required Input Sources + +- **Transformation Matrices** -- at least two 4x4 float32 matrices, typically authored by hand or produced by an earlier [Apply Transformation to Geometry](ApplyTransformationToGeometryFilter.md) run with the *Saving the Final Transformation Matrix* option enabled. + % Auto generated parameter table will be inserted here ## License & Copyright diff --git a/src/Plugins/SimplnxCore/docs/ComputeArrayHistogramByFeatureFilter.md b/src/Plugins/SimplnxCore/docs/ComputeArrayHistogramByFeatureFilter.md index f487c7d610..7b2ff75c19 100644 --- a/src/Plugins/SimplnxCore/docs/ComputeArrayHistogramByFeatureFilter.md +++ b/src/Plugins/SimplnxCore/docs/ComputeArrayHistogramByFeatureFilter.md @@ -2,7 +2,7 @@ ## Description -This **Filter** accepts one or more numeric **DataArray** inputs and computes feature-specific histograms. For each selected array, values are grouped by feature, then divided into equal-width bins—using either automatically derived or user-defined minimum/maximum bounds—and counted per bin. +This **Filter** accepts one or more numeric **DataArray** inputs and computes per-**Feature** histograms. A **Feature** is a connected region of **Cells** that share the same **Feature Id** (the integer label assigned by a segmentation filter). For each selected array, the per-Cell values are grouped according to their owning **Feature Id**, then divided into equal-width bins—using either automatically derived or user-defined minimum/maximum bounds—and counted per bin. Optionally, a mask **DataArray** can be provided to include only specific elements in the histogram computation. @@ -16,9 +16,11 @@ Outputs include: - **Modal Bin Ranges INeighborList** (optional): One NeighborList that contains one list per feature specifying inclusive lower bound and exclusive upper bound containing the feature's mode(s). Because there can be multiple modes, each list may include more than 2 entries. - *Example*: list 5 contains `[0.5, 10.2, 41.3, 54.1]` if feature 5 has two mode values and they fall between 0.5 and 10.2 and between 41.3 and 54.1. -% Auto generated parameter table will be inserted here +### Required Input Sources + +- **Cell Feature Ids** -- the per-Cell **Feature** label array, typically produced by [Segment Features (Scalar)](ScalarSegmentFeaturesFilter.md) or another segmentation filter. -## Example Pipelines +% Auto generated parameter table will be inserted here ## License & Copyright diff --git a/src/Plugins/SimplnxCore/docs/ComputeArrayHistogramFilter.md b/src/Plugins/SimplnxCore/docs/ComputeArrayHistogramFilter.md index 5ae0d38023..ab03a75adb 100644 --- a/src/Plugins/SimplnxCore/docs/ComputeArrayHistogramFilter.md +++ b/src/Plugins/SimplnxCore/docs/ComputeArrayHistogramFilter.md @@ -6,15 +6,20 @@ This **Filter** accepts one or more numeric **DataArray** inputs and generates c Optionally, a mask **DataArray** can be provided to include only specific elements in the histogram computation. -Outputs include: +The created histogram arrays are written into the target **DataGroup**. For each input array the following arrays are produced: + - **Counts DataArray**: A tuple for each bin representing the number of elements in that bin. -- **Bin Ranges DataArray**: A two-component tuple per bin defining the inclusive lower bound and exclusive upper bound. +- **Bin Ranges DataArray**: A two-component tuple per bin defining the inclusive lower bound and exclusive upper bound. The bin bounds carry the same units as the input array (for example, if the input array is in micrometers, the bin bounds are in micrometers). - **Most Populated Bin DataArray**: Reports the index of the bin that has the most values. -- **Modal Bin Ranges NeighborList** (optional): Specifies the inclusive lower and exclusive upper bound bin indices containing the input data’s mode(s). Because there can be multiple modes, this list may include more than two entries. +- **Modal Bin Ranges NeighborList** (optional): Specifies the inclusive lower and exclusive upper bound bin indices containing the input data's *mode(s)*. The *mode* is the value (or values) that occurs most frequently in the data. Because there can be multiple modes, this list may include more than two entries. + +### Required Input Sources + +None -- this filter operates on any generic numeric **DataArray** regardless of how it was produced. ## Example Data -Using some data about the "Old Faithful" geyser in the United States from the [R site](http://www.r-tutor.com/elementary-statistics/quantitative-data/frequency-distribution-quantitative-data), here is the top few lines of data: +Using the "Old Faithful" geyser data set from the [R site](http://www.r-tutor.com/elementary-statistics/quantitative-data/frequency-distribution-quantitative-data) (272 eruptions; the full data set is not reproduced here), the first few rows of the *Duration* and *Wait Time* columns are: Duration, Wait Time {3.6,79}, @@ -61,281 +66,3 @@ Please see the description file distributed with this **Plugin** ## DREAM3D-NX Help If you need help, need to file a bug report or want to request a new feature, please head over to the [DREAM3DNX-Issues](https://github.com/BlueQuartzSoftware/DREAM3DNX-Issues/discussions) GitHub site where the community of DREAM3D-NX users can help answer your questions. - -### Example Data (Raw) - -```text - Index, Duration, Wait Time - {1,3.6,79}, - {2,1.8,54}, - {3,3.333,74}, - {4,2.283,62}, - {5,4.533,85}, - {6,2.883,55}, - {7,4.7,88}, - {8,3.6,85}, - {9,1.95,51}, - {10,4.35,85}, - {11,1.833,54}, - {12,3.917,84}, - {13,4.2,78}, - {14,1.75,47}, - {15,4.7,83}, - {16,2.167,52}, - {17,1.75,62}, - {18,4.8,84}, - {19,1.6,52}, - {20,4.25,79}, - {21,1.8,51}, - {22,1.75,47}, - {23,3.45,78}, - {24,3.067,69}, - {25,4.533,74}, - {26,3.6,83}, - {27,1.967,55}, - {28,4.083,76}, - {29,3.85,78}, - {30,4.433,79}, - {31,4.3,73}, - {32,4.467,77}, - {33,3.367,66}, - {34,4.033,80}, - {35,3.833,74}, - {36,2.017,52}, - {37,1.867,48}, - {38,4.833,80}, - {39,1.833,59}, - {40,4.783,90}, - {41,4.35,80}, - {42,1.883,58}, - {43,4.567,84}, - {44,1.75,58}, - {45,4.533,73}, - {46,3.317,83}, - {47,3.833,64}, - {48,2.1,53}, - {49,4.633,82}, - {50,2,59}, - {51,4.8,75}, - {52,4.716,90}, - {53,1.833,54}, - {54,4.833,80}, - {55,1.733,54}, - {56,4.883,83}, - {57,3.717,71}, - {58,1.667,64}, - {59,4.567,77}, - {60,4.317,81}, - {61,2.233,59}, - {62,4.5,84}, - {63,1.75,48}, - {64,4.8,82}, - {65,1.817,60}, - {66,4.4,92}, - {67,4.167,78}, - {68,4.7,78}, - {69,2.067,65}, - {70,4.7,73}, - {71,4.033,82}, - {72,1.967,56}, - {73,4.5,79}, - {74,4,71}, - {75,1.983,62}, - {76,5.067,76}, - {77,2.017,60}, - {78,4.567,78}, - {79,3.883,76}, - {80,3.6,83}, - {81,4.133,75}, - {82,4.333,82}, - {83,4.1,70}, - {84,2.633,65}, - {85,4.067,73}, - {86,4.933,88}, - {87,3.95,76}, - {88,4.517,80}, - {89,2.167,48}, - {90,4,86}, - {91,2.2,60}, - {92,4.333,90}, - {93,1.867,50}, - {94,4.817,78}, - {95,1.833,63}, - {96,4.3,72}, - {97,4.667,84}, - {98,3.75,75}, - {99,1.867,51}, - {100,4.9,82}, - {101,2.483,62}, - {102,4.367,88}, - {103,2.1,49}, - {104,4.5,83}, - {105,4.05,81}, - {106,1.867,47}, - {107,4.7,84}, - {108,1.783,52}, - {109,4.85,86}, - {110,3.683,81}, - {111,4.733,75}, - {112,2.3,59}, - {113,4.9,89}, - {114,4.417,79}, - {115,1.7,59}, - {116,4.633,81}, - {117,2.317,50}, - {118,4.6,85}, - {119,1.817,59}, - {120,4.417,87}, - {121,2.617,53}, - {122,4.067,69}, - {123,4.25,77}, - {124,1.967,56}, - {125,4.6,88}, - {126,3.767,81}, - {127,1.917,45}, - {128,4.5,82}, - {129,2.267,55}, - {130,4.65,90}, - {131,1.867,45}, - {132,4.167,83}, - {133,2.8,56}, - {134,4.333,89}, - {135,1.833,46}, - {136,4.383,82}, - {137,1.883,51}, - {138,4.933,86}, - {139,2.033,53}, - {140,3.733,79}, - {141,4.233,81}, - {142,2.233,60}, - {143,4.533,82}, - {144,4.817,77}, - {145,4.333,76}, - {146,1.983,59}, - {147,4.633,80}, - {148,2.017,49}, - {149,5.1,96}, - {150,1.8,53}, - {151,5.033,77}, - {152,4,77}, - {153,2.4,65}, - {154,4.6,81}, - {155,3.567,71}, - {156,4,70}, - {157,4.5,81}, - {158,4.083,93}, - {159,1.8,53}, - {160,3.967,89}, - {161,2.2,45}, - {162,4.15,86}, - {163,2,58}, - {164,3.833,78}, - {165,3.5,66}, - {166,4.583,76}, - {167,2.367,63}, - {168,5,88}, - {169,1.933,52}, - {170,4.617,93}, - {171,1.917,49}, - {172,2.083,57}, - {173,4.583,77}, - {174,3.333,68}, - {175,4.167,81}, - {176,4.333,81}, - {177,4.5,73}, - {178,2.417,50}, - {179,4,85}, - {180,4.167,74}, - {181,1.883,55}, - {182,4.583,77}, - {183,4.25,83}, - {184,3.767,83}, - {185,2.033,51}, - {186,4.433,78}, - {187,4.083,84}, - {188,1.833,46}, - {189,4.417,83}, - {190,2.183,55}, - {191,4.8,81}, - {192,1.833,57}, - {193,4.8,76}, - {194,4.1,84}, - {195,3.966,77}, - {196,4.233,81}, - {197,3.5,87}, - {198,4.366,77}, - {199,2.25,51}, - {200,4.667,78}, - {201,2.1,60}, - {202,4.35,82}, - {203,4.133,91}, - {204,1.867,53}, - {205,4.6,78}, - {206,1.783,46}, - {207,4.367,77}, - {208,3.85,84}, - {209,1.933,49}, - {210,4.5,83}, - {211,2.383,71}, - {212,4.7,80}, - {213,1.867,49}, - {214,3.833,75}, - {215,3.417,64}, - {216,4.233,76}, - {217,2.4,53}, - {218,4.8,94}, - {219,2,55}, - {220,4.15,76}, - {221,1.867,50}, - {222,4.267,82}, - {223,1.75,54}, - {224,4.483,75}, - {225,4,78}, - {226,4.117,79}, - {227,4.083,78}, - {228,4.267,78}, - {229,3.917,70}, - {230,4.55,79}, - {231,4.083,70}, - {232,2.417,54}, - {233,4.183,86}, - {234,2.217,50}, - {235,4.45,90}, - {236,1.883,54}, - {237,1.85,54}, - {238,4.283,77}, - {239,3.95,79}, - {240,2.333,64}, - {241,4.15,75}, - {242,2.35,47}, - {243,4.933,86}, - {244,2.9,63}, - {245,4.583,85}, - {246,3.833,82}, - {247,2.083,57}, - {248,4.367,82}, - {249,2.133,67}, - {250,4.35,74}, - {251,2.2,54}, - {252,4.45,83}, - {253,3.567,73}, - {254,4.5,73}, - {255,4.15,88}, - {256,3.817,80}, - {257,3.917,71}, - {258,4.45,83}, - {259,2,56}, - {260,4.283,79}, - {261,4.767,78}, - {262,4.533,84}, - {263,1.85,58}, - {264,4.25,83}, - {265,1.983,43}, - {266,2.25,60}, - {267,4.75,75}, - {268,4.117,81}, - {269,2.15,46}, - {270,4.417,90}, - {271,1.817,46}, - {272,4.467,74}} -``` diff --git a/src/Plugins/SimplnxCore/docs/ComputeArrayStatisticsFilter.md b/src/Plugins/SimplnxCore/docs/ComputeArrayStatisticsFilter.md index ee5ab4158c..bd3be225cc 100644 --- a/src/Plugins/SimplnxCore/docs/ComputeArrayStatisticsFilter.md +++ b/src/Plugins/SimplnxCore/docs/ComputeArrayStatisticsFilter.md @@ -2,13 +2,13 @@ ## Group (Subgroup) -DREAM3D Review (Statistics) +Statistics ## Description ***WARNING: The Histogram functionality has been moved to a new filter.*** -This **Filter** computes a variety of statistics for a given scalar array. The currently available statistics are array length, minimum, maximum, (arithmetic) mean, median, mode, standard deviation, and summation; any combination of these statistics may be computed by this **Filter**. Any scalar array, of any primitive type, may be used as input. The type of the output arrays depends on the kind of statistic computed: +This filter computes a variety of statistics for a given scalar array. The currently available statistics are array length, minimum, maximum, (arithmetic) mean, median, mode, standard deviation, and summation; any combination of these statistics may be computed. Any scalar array, of any primitive type, may be used as input. The type of each output array depends on the kind of statistic computed: | Statistic | Primitive Type | |-------------------------|-------------------------------------| @@ -23,64 +23,41 @@ This **Filter** computes a variety of statistics for a given scalar array. The c | Standardized | 32-bit float | | Number of Unique Values | signed 32-bit integer | -The user may optionally use a mask to specify points to be ignored when computing the statistics; only points where the supplied mask is *true* will be considered when computing statistics. Additionally, the user may select to have the statistics computed per **Feature** or **Ensemble** by supplying an Ids array. For example, if the user opts to compute statistics per **Feature** and selects an array that has 10 unique **Feature** Ids, then this **Filter** will compute 10 sets of statistics (e.g., find the mean of the supplied array for each **Feature**, find the total number of points in each **Feature** (the length), etc.). +A **Feature** is a contiguous region of the data (such as a grain) identified by a unique integer **Feature** Id; an **Ensemble** is a higher-level grouping of **Features** (such as a phase). The filter can compute statistics over the whole array, or per **Feature**/**Ensemble** when a **Feature** Ids array is supplied. -The input array may also be *standardized*, meaning that the array values will be adjusted such that they have a mean of 0 and unit variance. This *Standardize Data* option requires the selection of both the *Find Mean* and *Find Standard Deviation* options. The standardized data will be saved as a new array object stored in the same **Attribute Matrix** as the input array. Note that if the *Standardize Data* option is selected, the mean and standard deviation values created by this **Filter** reflect the mean and standard deviation of the *original* array; the new standardized array has a mean of 0 and unit variance. The standardized array will be computed in double precision. If the statistics are being computed per **Feature** or **Ensemble**, then the array values are standardized according to the mean and standard deviation *for each **Feature/Ensemble***. For example, if 5 unique **Features** were being analyzed and *Standardize Data* was selected, then the array values for **Feature** 1 would be standardized according to the mean and standard deviation for **Feature** 1, then the array values for **Feature** 2 would be standardized according to the mean and standard deviation for **Feature** 2, and so on for the remaining **Features**. +The user may optionally use a mask to specify points to be ignored when computing the statistics; only points where the supplied mask is *true* are considered. Additionally, the user may compute the statistics per **Feature** or **Ensemble** by supplying a **Feature** Ids array. For example, if the user computes statistics per **Feature** and selects an array that has 10 unique **Feature** Ids, then the filter computes 10 sets of statistics (the mean of the supplied array for each **Feature**, the total number of points in each **Feature** (the length), and so on). -Special operations occur for certain statistics if the supplied array is of type *bool* (for example, a mask array produced from threshold filters). The *length*, *minimum*, *maximum*, *median*, *mode*, and *summation* are computed as normal (although the resulting values may be platform dependent). The *mean* and *standard deviation* for a boolean array will be true if there are more instances of true in the array than false. If *Standardize Data* is chosen for a boolean array, no actual modifications will be made to the input. These operations for boolean inputs are chosen as a basic convention, and are not intended be representative of true boolean logic. +The input array may also be *standardized*, meaning that the array values are adjusted so that they have a mean of 0 and unit variance. This *Standardize Data* option requires that both *Find Mean* and *Find Standard Deviation* are also selected. The standardized data is saved as a new array stored in the same **Attribute Matrix** as the input array. When *Standardize Data* is selected, the mean and standard deviation values created by this filter reflect the mean and standard deviation of the *original* array; the new standardized array has a mean of 0 and unit variance. The standardized array is computed in double precision. If statistics are computed per **Feature** or **Ensemble**, then the array values are standardized according to the mean and standard deviation *for each **Feature**/**Ensemble***. For example, with 5 unique **Features** and *Standardize Data* selected, the values for **Feature** 1 are standardized using the mean and standard deviation of **Feature** 1, the values for **Feature** 2 are standardized using those of **Feature** 2, and so on. -## Destination Attribute Matrix +Special operations occur for certain statistics if the supplied array is of type *bool* (for example, a mask array produced from threshold filters). The *length*, *minimum*, *maximum*, *median*, *mode*, and *summation* are computed as normal (although the resulting values may be platform dependent). The *mean* and *standard deviation* for a boolean array are *true* if there are more instances of *true* in the array than *false*. If *Standardize Data* is chosen for a boolean array, no modifications are made to the input. These operations for boolean inputs are chosen as a basic convention, and are not intended to be representative of true boolean logic. -The user must create a destination **Attribute Matrix** in which the computed statistics will be stored. DREAM3D-NX enforces a rule where any Attribute Matrix cannot contain another Attribute Matrix. With this in mind, the user should select a destination that is not itself an Attribute Matrix, such as the top level of a Geometry or the top level of the Data Structure itself. The user could have also created a group (using a previous filter) and use that group as the destination. +## Destination Attribute Matrix + +The user must create a destination **Attribute Matrix** in which the computed statistics are stored. DREAM3D-NX enforces a rule that an **Attribute Matrix** cannot contain another **Attribute Matrix**. With this in mind, the user should select a destination that is not itself an **Attribute Matrix**, such as the top level of a **Geometry** or the top level of the Data Structure itself. The user could also have created a group (using a previous filter) and use that group as the destination. ![Images/Compute_Array_Statistics_1.png](Images/Compute_Array_Statistics_1.png) -The user is creating the destination Attribute Matrix inside the `DataContainer` geometry. +The user is creating the destination **Attribute Matrix** inside the `DataContainer` geometry. ![Images/Compute_Array_Statistics_2.png](Images/Compute_Array_Statistics_2.png) -The user is creating the destination Attribute Matrix inside the `Statistics` group which was created by filter #2 in the pipeline. +The user is creating the destination **Attribute Matrix** inside the `Statistics` group which was created by filter #2 in the pipeline. ### Feature Range Type -The *Feature Range Type* parameter provides the following choices: - -- **None [0]**: No feature-based range is applied; statistics are computed over the entire array without range constraints. -- **Ignore Feature 0 [1]**: Excludes Feature Id 0 (the invalid/background feature) from statistics calculations. -- **Shrink To Fit [2]**: Automatically determines the minimum and maximum Feature Ids present and uses that as the range, removing empty entries. -- **Padded Custom Range [3]**: Uses a user-specified range and pads with generated/filled values for Feature Ids below the minimum and above the maximum actually present in the data. -- **Minimum Size in Custom Range [4]**: Uses a user-specified range but clamps to the actual min/max Feature Ids if the specified bounds exceed them, avoiding padding. - -## Ranges Breakdown - -The ranges feature was added to primarily offer the following functionality: - -1. option to output an array that has the Feature id in it. (Feature Ids Indexing Array) -2. option to set the "Feature Id" range. - -- Allow the user to "pad out the feature ids" to a specific range -- Allow the user to only compute stats for specific feature Ids - -3. option to Ignore Feature Id Zero. -4. remove empty spaces for feature ids that start above 1 - -All of these can be achieved with the new functionality, here's how: - -### Option 1 - -For option 1, this array (Feature Ids Indexing Array) is automatically created for any Range selection other than `None`. The nuance here is that if your range or `Shrink To Fit` contains all the features this array will be redundant and can be removed, however, this is a very niche occurance and users are encouraged to just select `None` if they know this to be the case. - -### Option 2 - -For option 2, this is provided with both the `Padded Custom Range` and `Minimum Size in Custom Range`. The latter is intended for users who are trying to cut down size without aproiri knowledge of the number of features. It will chop anything outside the upper bound or take the max feature if the custom upper bound exceeds it. The same is true for the lower bound in that it will take the higher of the two between provided range and the min Feature Id. `Padded Custom Range` will fill generate/fill extra values for values below and above the minimum and maximum Feature Id respectively. See the bonus section for additional range features. +When computing per-**Feature** statistics, the *Feature Range Type* parameter controls which **Feature** Ids are included and how the output is indexed (these are all dimensionless integer **Feature** Id selections): -### Option 3 +- **None [0]**: No feature-based range is applied; statistics are computed for every **Feature** Id present. +- **Ignore Feature 0 [1]**: Excludes **Feature** Id 0 (the invalid/background feature) from the calculations. +- **Shrink To Fit [2]**: Automatically determines the minimum and maximum **Feature** Ids present and uses that as the range, removing empty entries. +- **Padded Custom Range [3]**: Uses the user-specified *Feature Ids Min Max Range* and generates filled values for **Feature** Ids below the minimum and above the maximum actually present in the data. +- **Minimum Size in Custom Range [4]**: Uses the user-specified range but clamps to the actual min/max **Feature** Ids if the specified bounds exceed them, avoiding padding. -For option 3, the ability to ignore Feature Id Zero (the invalid Feature Id) is provided directly in the form of `Ignore Feature 0` and indirectly through ranges. +For any range selection other than *None*, the filter also creates a *Feature Ids Indexing Array* that records the **Feature** Id each row of statistics corresponds to. If the selected range already contains every **Feature**, this indexing array is redundant and may be removed; in that niche case selecting *None* is simpler. -### Option 4 +*Tip: If the maximum **Feature** Id in a custom range is unknown, supplying `-1` for the upper bound causes the filter to determine the maximum **Feature** Id at run time and use it as the upper bound.* -For option 4, the most direct feature to address this is the `Shrink to Fit` range option, however it can also be achived with `Minimum Size in Custom Range`. +### Required Input Sources -*Bonus: If you are unsure of the max feature id in your range, supplying a `-1` will determine the maximum feature id and use it as the upper bound in execution.* +- **Cell Feature Ids** -- required only when computing statistics per **Feature**/**Ensemble**; produced by a segmentation filter such as [Segment Features (Scalar)](ScalarSegmentFeaturesFilter.md). % Auto generated parameter table will be inserted here @@ -88,7 +65,7 @@ For option 4, the most direct feature to address this is the `Shrink to Fit` ran ## License & Copyright -Please see the description file distributed with this plugin. +Please see the description file distributed with this **Plugin** ## DREAM3D-NX Help diff --git a/src/Plugins/SimplnxCore/docs/ComputeBiasedFeaturesFilter.md b/src/Plugins/SimplnxCore/docs/ComputeBiasedFeaturesFilter.md index 14bfa04e6f..1820b1f91c 100644 --- a/src/Plugins/SimplnxCore/docs/ComputeBiasedFeaturesFilter.md +++ b/src/Plugins/SimplnxCore/docs/ComputeBiasedFeaturesFilter.md @@ -6,7 +6,15 @@ Generic (Spatial) ## Description -This **Filter** determines which **Features** are *biased* by the outer surfaces of the sample. Larger **Features** are more likely to intersect the outer surfaces and thus it is not sufficient to only note which **Features** touch the outer surfaces of the sample. Denoting which **Features** are biased is important so that they may be excluded from any statistical analyses. The algorithm for determining whether a **Feature** is *biased* is as follows: +This **Filter** flags each **Feature** as *biased* or *unbiased* by the outer surfaces of the sample, producing a feature-level boolean array suitable for excluding biased features from downstream statistical analyses (size distributions, shape distributions, ODFs, etc.). + +### Why Bias Matters for Statistics + +When a sample volume is cut out of a larger material, some grains are truncated by the cut. If only size or shape statistics are needed, surface-touching features like those flagged by [Compute Surface Features](ComputeSurfaceFeaturesFilter.md) can be excluded -- but that undercounts the problem. Larger grains are more likely to touch any given surface simply because they are larger, so excluding only surface-touching features still leaves a size-dependent sampling bias: *small* grains that don't touch the surface are over-represented relative to *large* grains that do. The biased-feature flag produced here corrects for this by identifying which features' centroids are close enough to a boundary that they are statistically suspect, regardless of whether the feature itself touches the boundary. + +### How This Filter Works + +The algorithm for determining whether a **Feature** is *biased* is as follows: 1. The *centroids* of all **Features** are calculated 2. All **Features** are tested to determine if they touch an outer surface of the sample @@ -22,6 +30,12 @@ By definition of the box, no **Feature** that intersects an outer surface of the The images below show the feature ids before and after running this filter. The image on the right shows the biased features colored in red, the unbiased features colored by their feature id, the bounding box (described in step 3 of the algorithm above), and the feature centroids (white for unbiased and purple for biased). ![2D Before and After Biased Features](Images/ComputeBiasedFeaturesBeforeAndAfter.png) +### Required Input Sources + +- **Feature Centroids** -- produced by [Compute Feature Centroids](ComputeFeatureCentroidsFilter.md). +- **Surface Features** -- produced by [Compute Surface Features](ComputeSurfaceFeaturesFilter.md) or as an optional output of [Compute Feature Neighbors](ComputeFeatureNeighborsFilter.md). +- **Feature Phases** (only when applying to a single phase) -- produced by [Compute Feature Phases](ComputeFeaturePhasesFilter.md). + % Auto generated parameter table will be inserted here ## Example Pipelines diff --git a/src/Plugins/SimplnxCore/docs/ComputeBoundaryCellsFilter.md b/src/Plugins/SimplnxCore/docs/ComputeBoundaryCellsFilter.md index 9f3a965755..5c6332366b 100644 --- a/src/Plugins/SimplnxCore/docs/ComputeBoundaryCellsFilter.md +++ b/src/Plugins/SimplnxCore/docs/ComputeBoundaryCellsFilter.md @@ -17,6 +17,12 @@ This **Filter** determines, for each **Cell**, the number of neighboring **Cells |--|--| | ![Feature Ids](Images/ComputeBoundaryCellsInput.png) | ![Boundary Cells](Images/ComputeBoundaryCellsOutput.png) | +The output is a per-**Cell** count ranging from **0** (an interior cell whose six neighbors all belong to the same **Feature**) to **6** (an isolated cell differing from all six neighbors). Cells on the outer edge of the volume have fewer than six in-bounds neighbors, so their count reflects only the neighbors that exist. + +### Required Input Sources + +- **Feature Ids** -- a per-**Cell** integer label array produced by a segmentation filter such as [Segment Features (Scalar)](ScalarSegmentFeaturesFilter.md). + % Auto generated parameter table will be inserted here ## Example Pipelines diff --git a/src/Plugins/SimplnxCore/docs/ComputeBoundaryElementFractionsFilter.md b/src/Plugins/SimplnxCore/docs/ComputeBoundaryElementFractionsFilter.md index 776055835c..de3b5a8aa8 100644 --- a/src/Plugins/SimplnxCore/docs/ComputeBoundaryElementFractionsFilter.md +++ b/src/Plugins/SimplnxCore/docs/ComputeBoundaryElementFractionsFilter.md @@ -6,11 +6,20 @@ Statistics (Morphological) ## Description -This **Filter** calculates the fraction of **Elements** of each **Feature** that are on the "surface" of that **Feature**. The **Filter** simply iterates through all **Elements** asking for the **Feature** that owns them and if the **Element** is a "surface" **Element**. Each **Feature** counts the total number of **Elements** it owns and the number of those **Elements** that are "surface" **Elements**. The fraction is then stored for each **Feature**. +This **Filter** calculates, for each **Feature**, the fraction of its **Elements** that lie on the boundary ("surface") of that **Feature**. A **Feature** is a contiguous region of like-segmented cells (for example a grain), and an **Element** is a single cell of the geometry. An **Element** is considered a *surface* (boundary) **Element** when at least one of its neighboring **Elements** belongs to a different **Feature**. This boundary flag is not computed here; it is supplied through the *Surface Elements* input array, where any value greater than zero (the count of differing neighbors) marks the **Element** as a boundary **Element**. -% Auto generated parameter table will be inserted here +The **Filter** iterates through every **Element**, asking which **Feature** owns it and whether it is a boundary **Element**. Each **Feature** accumulates the total number of **Elements** it owns and the number of those that are boundary **Elements**. The output for each **Feature** is the ratio: + +> boundary Elements / total Elements + +This is a dimensionless fraction in the range [0, 1]. A value near 0 means the **Feature** is large and compact relative to its surface; a value near 1 means nearly all of the **Feature**'s **Elements** touch a neighbor of a different **Feature** (a thin or small **Feature**). -## Example Pipelines +### Required Input Sources + +- **Cell Feature Ids** -- the Feature that owns each Element, produced by a segmentation filter such as [Segment Features (Scalar)](ScalarSegmentFeaturesFilter.md). +- **Surface Elements** -- the per-Element count of neighbors belonging to a different Feature, produced by [Compute Boundary Cells (Image)](ComputeBoundaryCellsFilter.md). + +% Auto generated parameter table will be inserted here ## License & Copyright diff --git a/src/Plugins/SimplnxCore/docs/ComputeBoundingBoxStatsFilter.md b/src/Plugins/SimplnxCore/docs/ComputeBoundingBoxStatsFilter.md index 7c20b22428..165565b97c 100644 --- a/src/Plugins/SimplnxCore/docs/ComputeBoundingBoxStatsFilter.md +++ b/src/Plugins/SimplnxCore/docs/ComputeBoundingBoxStatsFilter.md @@ -6,9 +6,9 @@ Statistics ## Description -***NOTE:* This filter is intended to allow each cell value to map to 0 or more bounding boxes (1 to Many architecture). This comes with the caveat that the option `Standardize Data` offered by `Compute Array Statistics` cannot be included as functionality in this filter.** +***NOTE:* This filter allows each **Cell** value to contribute to 0 or more bounding boxes (a 1-to-many architecture). This comes with the caveat that the *Standardize Data* option offered by [Compute Attribute Array Statistics](ComputeArrayStatisticsFilter.md) cannot be included as functionality in this filter.** -This **Filter** computes a variety of statistics for a given scalar array. The currently available statistics are array length, minimum, maximum, (arithmetic) mean, median, mode, standard deviation, summation, and Number of Unique values; any combination of these statistics may be computed by this **Filter**. Any scalar array, of any primitive type, may be used as input. The type of the output arrays depends on the kind of statistic computed: +This filter computes a variety of statistics for a given scalar array, restricted to the **Cells** that fall inside each supplied bounding box. Because boxes may overlap (or leave gaps), a single **Cell** may be counted toward several boxes, exactly one box, or none. The currently available statistics are array length, minimum, maximum, (arithmetic) mean, median, mode, standard deviation, summation, and number of unique values; any combination of these statistics may be computed. Any scalar array, of any primitive type, may be used as input. The type of each output array depends on the kind of statistic computed: | Statistic | Primitive Type | |-------------------------|-------------------------------------| @@ -22,11 +22,15 @@ This **Filter** computes a variety of statistics for a given scalar array. The c | Summation | 32-bit float | | Number of Unique Values | signed 32-bit integer | -The *Unified Bounds Array* is a 6 component **DataArray** that contains the lower XYZ bound and upper XYZ bound for the bounding box. The component ordering is expected as follows `{Min-X, Min-Y, Min-Z, Max-X, Max-Y, Max-Z}`. This ordering is provided so the user knows how to format imported external data. The *Compute Feature Bounds* filter's `Unified Array` option puts out a correctly formatted array for input to this filter. +The *Unified Bounds Array* is a 6-component **DataArray** that contains the lower XYZ bound and upper XYZ bound for each bounding box. The component ordering is `{Min-X, Min-Y, Min-Z, Max-X, Max-Y, Max-Z}`. These bounds are expressed in the **Geometry**'s physical coordinate units (the same length units as the geometry's origin and spacing, typically microns). This ordering is provided so the user knows how to format imported external data. The [Compute Feature Bounding Boxes](ComputeFeatureBoundsFilter.md) filter's *Unified Array* option produces a correctly formatted array for input to this filter. -The user must select or create a destination **Attribute Matrix** in which the computed statistics will be stored. If selecting an exisitng **Attribute Matrix**, then a reasonable selection for this array is the **Attribute Matrix** that the *Unified Bounds Array* comes from. However, the only requirement is that the number of columns in the selected destination **Attribute Matrix** match the number of tuples in the *Unified Bounds Array*. This requirement is enforced during preflight. If the option to create an Attribute Matrix is selected, it will be created in the supplied geometry sized appropriately. +The user must select or create a destination **Attribute Matrix** in which the computed statistics are stored. When selecting an existing **Attribute Matrix**, a reasonable choice is the **Attribute Matrix** that the *Unified Bounds Array* comes from. However, the only requirement is that the number of tuples in the selected destination **Attribute Matrix** match the number of tuples (boxes) in the *Unified Bounds Array*. This requirement is enforced during preflight. If the option to create a new **Attribute Matrix** is selected, it is created in the supplied **Geometry**, sized appropriately. -Special operations occur for certain statistics if the supplied array is of type *bool* (for example, a mask array produced [when thresholding](@ref multithresholdobjects)). The length, minimum, maximum, median, mode, and summation are computed as normal (although the resulting values may be platform dependent). The mean and standard deviation for a boolean array will be true if there are more instances of true in the array than false. These operations for boolean inputs are chosen as a basic convention, and are not intended be representative of true boolean logic. +Special operations occur for certain statistics if the supplied array is of type *bool* (for example, a mask array produced by [Multi-Threshold Objects](MultiThresholdObjectsFilter.md)). The length, minimum, maximum, median, mode, and summation are computed as normal (although the resulting values may be platform dependent). The mean and standard deviation for a boolean array are *true* if there are more instances of *true* in the array than *false*. These operations for boolean inputs are chosen as a basic convention, and are not intended to be representative of true boolean logic. + +### Required Input Sources + +- **Unified Bounds Array** -- a 6-component bounds array produced by the *Unified Array* output option of [Compute Feature Bounding Boxes](ComputeFeatureBoundsFilter.md). % Auto generated parameter table will be inserted here diff --git a/src/Plugins/SimplnxCore/docs/ComputeCoordinateThresholdFilter.md b/src/Plugins/SimplnxCore/docs/ComputeCoordinateThresholdFilter.md index 5e98fa94d2..50c14140f5 100644 --- a/src/Plugins/SimplnxCore/docs/ComputeCoordinateThresholdFilter.md +++ b/src/Plugins/SimplnxCore/docs/ComputeCoordinateThresholdFilter.md @@ -6,7 +6,9 @@ Geometry ## Description -This filter produces a mask that marks cells that fall inside or outside a given bounding shape within a supplied geometry. The filter outputs a mask to provide the greatest flexibility, while leveraging existing algorithms. This filter doesn't modify the input geometry in any way if you wish to modify the data within the bounding box, consider using one of the cleanup filters on the marked values. See *Remove Flagged Vertices/Edges/Triangles* for an example of a potential followup filter. +This filter produces a mask that marks cells that fall inside or outside a given bounding shape within a supplied geometry. The filter outputs a mask to provide the greatest flexibility, while leveraging existing algorithms. This filter doesn't modify the input geometry in any way; if you wish to modify the data within the bounding box, consider using one of the cleanup filters on the marked values. See [Remove Flagged Vertices](RemoveFlaggedVerticesFilter.md), [Remove Flagged Edges](RemoveFlaggedEdgesFilter.md), or [Remove Flagged Triangles](RemoveFlaggedTrianglesFilter.md) for examples of potential followup filters. + +All threshold bounds (the rectangle minimum/maximum coordinates and the sphere center/radius) are specified in **physical coordinates** — the same length units as the input geometry's vertex positions (or, for an **Image Geometry**, its origin and spacing) — not in cell/voxel indices. ### Coordinate Container Shape @@ -33,6 +35,8 @@ The way a point is determined to be in the sphere uses the following calculation `(p_x - c_x)^2 + (p_y - c_y)^2 + (p_z - c_z)^2 <= r^2` +The center `c` (first 3 values of *Sphere Info*) and radius `r` (4th value) are both given in **physical coordinate** units matching the geometry. + ### Inverting the Mask This is primarily a convenience option provided to the user. If toggled on the values will be true (`1`) by default and values withing the bounds will be marked false (`0`). This doesn't modify anything other than switching what value is set for bounds that fall inside or outside respectively. diff --git a/src/Plugins/SimplnxCore/docs/ComputeCoordinatesImageGeomFilter.md b/src/Plugins/SimplnxCore/docs/ComputeCoordinatesImageGeomFilter.md index 1f457470c2..f7a4201f64 100644 --- a/src/Plugins/SimplnxCore/docs/ComputeCoordinatesImageGeomFilter.md +++ b/src/Plugins/SimplnxCore/docs/ComputeCoordinatesImageGeomFilter.md @@ -6,19 +6,25 @@ Statistics ## Description -This **Filter** produces one or two arrays that stores implicit image information (indices and physical coordinates of each point) as explicit cell level data. The produced arrays are in XYZ component format and stored as X by Y by Z, starting from the origin. The intention behind this filter is primarily for output compatibility and readability. +This **Filter** writes the per-cell coordinates and/or grid indices of an **Image Geometry** into regular cell-level **Attribute Arrays**. In an Image Geometry, each cell's (i, j, k) index and (x, y, z) physical position are implicit -- derivable from the geometry's dimensions, origin, and spacing. This filter makes them explicit so they can be exported to CSV/text, used as inputs to downstream math filters, or visualized directly. + +### When to Use This Filter + +Most commonly used as a preparation step before exporting cell data to CSV or other text formats that need explicit coordinate columns. Also useful when a downstream filter needs the (x, y, z) of each cell as a regular array (e.g., for distance calculations). ### Output Array(s) Type -The *Output Array(s) Type* parameter controls which arrays are produced by the filter: +- **Physical Coordinates [0]**: produces a single 3-component float array containing the (x, y, z) physical coordinates of the center of each cell, computed from the geometry's origin and spacing. +- **Indices [1]**: produces a single 3-component integer array containing the (i, j, k) grid indices of each cell. Indices are **0-based**. +- **Both [2]**: produces both arrays. -- **Physical Coordinates [0]**: Outputs a single 3-component array containing the physical (spatial) XYZ coordinates of the center of each cell, computed from the geometry's origin and spacing. -- **Indices [1]**: Outputs a single 3-component array containing the integer ijk grid indices of each cell. -- **Both [2]**: Outputs both the physical coordinates array and the indices array. +### Cell Order -The arrays follow the following cell parsing scheme: `0,0,0 -> 1,0,0 -> 2,0,0 -> ... n,0,0 -> 0,1,0 -> 1,1,0 -> 2,1,0 -> ... n,n,0 -> 0,0,1 -> 1,0,1 -> 2,0,1 -> ... n,n,n`. +The arrays are stored in the geometry's default cell raster order: X varies fastest, then Y, then Z. -The printed output will look something like this: + (0,0,0) → (1,0,0) → (2,0,0) → ... (n,0,0) → (0,1,0) → (1,1,0) → ... (n,n,0) → (0,0,1) → ... + +A sample of the output for a 9-column slice (showing both indices and physical coordinates): ```console Image Indices_0,Image Indices_1,Image Indices_2,Image Physical Coordinates_0,Image Physical Coordinates_1,Image Physical Coordinates_2 @@ -33,6 +39,15 @@ Image Indices_0,Image Indices_1,Image Indices_2,Image Physical Coordinates_0,Ima 8,0,0,-45.125,0.125,-0.37500411 ``` +### Units + +- **Physical coordinates** are in the geometry's physical units (microns, millimeters, etc.). +- **Indices** are dimensionless integers (0-based cell indices along each axis). + +### Required Input Sources + +- **Input Image Geometry** -- the geometry whose per-cell coordinates/indices will be made explicit. Typically produced by [Create Image Geometry](CreateImageGeometryFilter.md), [ITK Import Image Stack](../ITKImageProcessing/ITKImportImageStackFilter.md), or an EBSD reader. + % Auto generated parameter table will be inserted here ## Example Pipelines diff --git a/src/Plugins/SimplnxCore/docs/ComputeDifferencesMapFilter.md b/src/Plugins/SimplnxCore/docs/ComputeDifferencesMapFilter.md index 065ea70601..5d6bee7e7e 100644 --- a/src/Plugins/SimplnxCore/docs/ComputeDifferencesMapFilter.md +++ b/src/Plugins/SimplnxCore/docs/ComputeDifferencesMapFilter.md @@ -18,9 +18,13 @@ Note that in the above algorithm, the difference is taken as the *first selected **WARNING: The resulting difference values *may be negative* if the values of the first array are smaller than those in the second array. Therefore, if the two arrays are *unsigned integers*, it may be possible to underflow the resulting difference map values if the first array is sufficiently smaller than the second array. "Underflow" means that what should be a negative value will end up being a potentially very large value!** -% Auto generated parameter table will be inserted here +The output Difference Map is created at the user-specified path and inherits the primitive type, component shape, and number of tuples of the two input arrays. + +### Required Input Sources -## Example Pipelines +None -- this filter operates on any two generic **Attribute Arrays** that share the same primitive type, component dimensions, and number of tuples, regardless of how they were produced. + +% Auto generated parameter table will be inserted here ## License & Copyright diff --git a/src/Plugins/SimplnxCore/docs/ComputeEuclideanDistMapFilter.md b/src/Plugins/SimplnxCore/docs/ComputeEuclideanDistMapFilter.md index c96875a13a..d5fb24a214 100644 --- a/src/Plugins/SimplnxCore/docs/ComputeEuclideanDistMapFilter.md +++ b/src/Plugins/SimplnxCore/docs/ComputeEuclideanDistMapFilter.md @@ -6,19 +6,29 @@ Statistics (Morphological) ## Description -This **Filter** calculates the distance of each **Cell** from the nearest **Feature** boundary, **triple line** and/or **quadruple point**. The following algorithm explains the process: +This **Filter** calculates, for every **Cell**, how far that **Cell** is from the nearest **Feature** boundary, **triple line**, and/or **quadruple point**. A **Feature** is a contiguous region of like-segmented cells (for example a grain). These three terms describe the interfaces between **Features**: -1. Find the **Feature** that owns each **Cell** and its six face-face neighbors of each **Cell** -2. For all **Cells** that have *at least 2* different neighbors, set their *GBEuclideanDistance* to *0*. For all **Cells** that have *at least 3* different neighbors, set their *TJEuclideanDistance* to *0*. For all **Cells** that have *at least 4* different neighbors, set their *QPEuclideanDistance* to *0* -3. For each of the three *EuclideanDistace* maps, iteratively "grow" out from the **Cells** identified to have a distance of *0* by the following sub-steps: +- A **Feature boundary** (abbreviated **GB**, grain boundary) is the interface where two different **Features** meet. +- A **triple line** (abbreviated **TJ**, triple junction) is where three different **Features** meet. +- A **quadruple point** (abbreviated **QP**) is where four different **Features** meet. -- Determine the **Cells** that neighbor a **Cell** of distance *0* in the current map. -- Assign a distance of *1* to those **Cells** and track the *0* **Cell** neighbor internally as their *nearest neighbor* -- Repeat previous two sub-steps, increasing the distances by *1* each iteration, until no **Cells** remain without a distance assigned. +The following algorithm explains the process: - *Note:* the distances calculated at this point are "city-block" distances and not "shortest distance" distances. The nearest neighbor information is used internally by the algorithm but is not saved as an output array. +1. Find the **Feature** that owns each **Cell** and the **Features** that own each of its six face-sharing neighbors. +2. For all **Cells** that have *at least 2* different neighboring **Features**, set their *GB* distance to *0*. For all **Cells** that have *at least 3*, set their *TJ* distance to *0*. For all **Cells** that have *at least 4*, set their *QP* distance to *0*. +3. For each of the three distance maps, iteratively "grow" outward from the **Cells** identified as distance *0* using the following sub-steps: -4. If the option *Calculate Manhattan Distance* is *false*, then the "city-block" distances are overwritten with the *Euclidean Distance* from the **Cell** to its internally tracked *nearest neighbor* **Cell** and stored in a *float* array instead of an *integer* array. + - Determine the **Cells** that neighbor a **Cell** of distance *0* in the current map. + - Assign a distance of *1* to those **Cells** and internally track the distance-*0* **Cell** as their *nearest neighbor*. + - Repeat the previous two sub-steps, increasing the distance by *1* each iteration, until every **Cell** has a distance assigned. + + *Note:* the distances calculated at this point are integer "city-block" (Manhattan) distances, expressed as a count of **Cells** (voxels), not shortest straight-line distances. The nearest-neighbor information is used internally and is not saved as an output array. + +4. If *Output arrays are Manhattan distance* is *false*, then the integer city-block distances are overwritten with the true straight-line (Euclidean) distance from each **Cell** to its internally tracked nearest-neighbor **Cell**. This Euclidean result is a physical distance expressed in the **Image Geometry** length units (for example microns) and is stored in a *float32* array instead of an *int32* array. + +### Required Input Sources + +- **Cell Feature Ids** -- the Feature that owns each Cell, produced by a segmentation filter such as [Segment Features (Scalar)](ScalarSegmentFeaturesFilter.md). % Auto generated parameter table will be inserted here diff --git a/src/Plugins/SimplnxCore/docs/ComputeFeatureBoundsFilter.md b/src/Plugins/SimplnxCore/docs/ComputeFeatureBoundsFilter.md index 09dd010efc..2d76baf40a 100644 --- a/src/Plugins/SimplnxCore/docs/ComputeFeatureBoundsFilter.md +++ b/src/Plugins/SimplnxCore/docs/ComputeFeatureBoundsFilter.md @@ -8,7 +8,9 @@ Geometry **Warning**: *Potential Runtime Error* - It is expected that the max feature id plus one (`max_feature_id_value` + 1) is equal to or less than the number of tuples in the supplied feature Attribute Matrix. This cannot be checked in preflight and will terminate the pipeline if encountered. -This filter calculates the bounding boxes for each feature given Feature Ids and Geometry (refer to table below for supported geometry types and their corresponding feature id sizing). _**This filter does output `NaN`s for empty features**_, cases where a point can not be associated to a feature. The bounding boxes are defined and stored as two points in space, a lower and upper point. The optimal storage solution is use case defined, and as such there are two options provided `split` and `unified`. +This filter calculates the bounding boxes for each **Feature** given Feature Ids and Geometry (refer to table below for supported geometry types and their corresponding feature id sizing). A **Feature** is a contiguous region of cells (voxels, vertices, edges, or faces) that share the same Feature Id; a **Cell** is the smallest addressable element of the geometry. _**This filter does output `NaN`s for empty features**_, cases where a point can not be associated to a feature. The bounding boxes are defined and stored as two points in space, a lower and upper point. The optimal storage solution is use case defined, and as such there are two options provided `split` and `unified`. + +The bounding box values are stored in **physical coordinates** (the same length units as the geometry's origin and spacing), not cell/voxel indices. For an **Image Geometry** each coordinate is computed as `origin + index * spacing`; for node-based geometries (Vertex, Edge, Triangle, Quad) the vertex coordinates are used directly. ### Output Array(s) Type @@ -19,9 +21,9 @@ The *Output Array(s) Type* parameter controls how the bounding box data is store | Geometry Type | Expected Feature ID Length| |---------------|---------------------------| -| Image | Equal to Image Dimesions; typically equivalent to the `Cell Data` Attribute Matrix | +| Image | Equal to the Image Dimensions; typically equivalent to the `Cell Data` Attribute Matrix | | Vertex | Equal to the Number of Vertices/Points; typically equivalent to the `Vertex Data` Attribute Matrix | -| Edge | Equal to the Number of Edges; ; typically equivalent to the `Edge Data` Attribute Matrix | +| Edge | Equal to the Number of Edges; typically equivalent to the `Edge Data` Attribute Matrix | | Triangle | Equal to the Number of Triangles/Faces; typically equivalent to the `Face Data` Attribute Matrix | | Quad | Equal to the Number of Quads/Faces; typically equivalent to the `Face Data` Attribute Matrix | @@ -86,6 +88,10 @@ The edges for each bounding box are 12 in number and constructed in following or Since edges are the cell level data in edge geometries, the feature ids map to the edges. This means that the feature ids array will always contain 11 more consecutive instances of the same feature from when it first appears (12 total). To know the number of features in the edge geom, just divide the number of edges by 12. +### Required Input Sources + +This filter requires a **Cell Feature Ids** array, typically produced by a segmentation filter such as [Segment Features (Scalar)](ScalarSegmentFeaturesFilter.md) or one of the misorientation-based segmentation filters in the OrientationAnalysis plugin. The selected **Feature Data Attribute Matrix** is where the output bounds arrays are created. + % Auto generated parameter table will be inserted here ## Example Pipelines diff --git a/src/Plugins/SimplnxCore/docs/ComputeFeatureCentroidsFilter.md b/src/Plugins/SimplnxCore/docs/ComputeFeatureCentroidsFilter.md index 77e435ffbb..1b64841a51 100644 --- a/src/Plugins/SimplnxCore/docs/ComputeFeatureCentroidsFilter.md +++ b/src/Plugins/SimplnxCore/docs/ComputeFeatureCentroidsFilter.md @@ -6,7 +6,13 @@ Generic (Misc) ## Description -This **Filter** calculates the *centroid* of each **Feature** by determining the average X, Y, and Z position of all the **Cells** belonging to the **Feature**. An *Is Periodic* option is available: when enabled, **Features** that extend beyond the boundary of the **Image Geometry** are treated as wrapping around to the opposite face, and centroids are computed accordingly. When *Is Periodic* is disabled, **Features** that intersect the outer surfaces of the sample will still have *centroids* calculated, but they will be *centroids* of the truncated part of the **Feature** that lies inside the sample. +This **Filter** calculates the *centroid* of each **Feature** by determining the average X, Y, and Z position of all the **Cells** belonging to the **Feature**. A **Feature** is a contiguous group of **Cells** (voxels) that share the same Feature Id; a **Cell** is a single voxel of the **Image Geometry**. An *Is Periodic* option is available: when enabled, **Features** that extend beyond the boundary of the **Image Geometry** are treated as wrapping around to the opposite face, and centroids are computed accordingly. When *Is Periodic* is disabled, **Features** that intersect the outer surfaces of the sample will still have *centroids* calculated, but they will be *centroids* of the truncated part of the **Feature** that lies inside the sample. + +The centroid of each **Feature** is computed by averaging the **physical-coordinate** voxel-center positions (`origin + (index + 0.5) * spacing`) of every **Cell** in that **Feature**. The result is therefore expressed in the same length units as the **Image Geometry** origin and spacing, not in pixel/voxel indices. The output `Centroids` array is a single 3-component `float32` array holding the (X, Y, Z) centroid for each **Feature**, created in the selected **Feature Attribute Matrix**. + +### Required Input Sources + +This filter requires a **Cell Feature Ids** array, typically produced by a segmentation filter such as [Segment Features (Scalar)](ScalarSegmentFeaturesFilter.md) or one of the misorientation-based segmentation filters in the OrientationAnalysis plugin. % Auto generated parameter table will be inserted here diff --git a/src/Plugins/SimplnxCore/docs/ComputeFeatureClusteringFilter.md b/src/Plugins/SimplnxCore/docs/ComputeFeatureClusteringFilter.md index 018999d1aa..63a980551f 100644 --- a/src/Plugins/SimplnxCore/docs/ComputeFeatureClusteringFilter.md +++ b/src/Plugins/SimplnxCore/docs/ComputeFeatureClusteringFilter.md @@ -6,15 +6,26 @@ Statistics (Morphological) ## Description -This Filter determines the radial distribution function (RDF), as a histogram, of a given set of **Features**. Currently, the **Features** need to be of the same **Ensemble** (specified by the user), and the resulting RDF is stored as **Ensemble** data. This Filter also returns the clustering list (the list of all the inter-**Feature** distances) and the minimum and maximum separation distances. The algorithm proceeds as follows: +This **Filter** computes the **radial distribution function (RDF)** of a set of **Features**. A **Feature** is a contiguous region of like-segmented cells (for example a grain or particle). An **RDF** is a histogram that describes how the **Features** are spatially distributed relative to each other: for each distance bin, it counts how many other **Feature** centroids lie at that separation distance, then normalizes that count against the count expected if the same number of **Features** were scattered randomly in the same volume. Values above 1.0 at a given distance indicate the **Features** are more likely to be found at that separation than random (clustering or ordering); values below 1.0 indicate they are less likely (exclusion). Use this **Filter** to detect and quantify clustering, ordering, or repulsion in a population of **Features**. -1. Find the Euclidean distance from the current **Feature** centroid to all other **Feature** centroids of the same specified phase -2. Put all caclulated distances in a clustering list -3. Repeat 1-2 for all **Features** -4. Sort the data into the specified number of bins, all equally sized in distance from the minimum distance to the maximum distance between **Features**. For example, if the user chooses 10 bins, and the minimum distance between **Features** is 10 units and the maximum distance is 80 units, each bin will be 8 units -5. Normalize the RDF by the probability of finding the **Features** if distributed randomly in the given box +An **Ensemble** is a group of **Features** that share a common phase (a distinct material or crystal structure). This **Filter** operates on a single **Ensemble** at a time, specified by the *Phase Index* parameter, and the resulting **RDF** is stored as **Ensemble** data. -*Note:* Because the algorithm iterates over all the **Features**, each distance will be double counted. For example, the distance from **Feature** 1 to **Feature** 2 will be counted along with the distance from **Feature** 2 to **Feature** 1, which will be identical. +All distances in this **Filter** are physical lengths expressed in the same length units as the **Image Geometry** spacing (for example microns). The algorithm proceeds as follows: + +1. Find the straight-line (Euclidean) distance from the current **Feature** centroid to every other **Feature** centroid of the selected phase. +2. Put all calculated distances in a clustering list. +3. Repeat steps 1-2 for all **Features**. +4. Sort the distances into the specified number of bins, all equally sized in distance from the minimum separation to the maximum separation. For example, if the user chooses 10 bins, the minimum separation is 10 microns, and the maximum separation is 80 microns, each bin spans 7 microns. +5. Normalize the **RDF** by the probability of finding the **Features** at that distance if they were distributed randomly in the bounding box. + +The **Filter** also outputs the clustering list (every inter-**Feature** distance) and the minimum and maximum separation distances (both in physical length units). + +*Note:* Because the algorithm iterates over all **Features**, each distance is double-counted. For example, the distance from **Feature** 1 to **Feature** 2 is counted along with the identical distance from **Feature** 2 to **Feature** 1. + +### Required Input Sources + +- **Centroids** -- the X, Y, Z coordinates of each Feature's center of mass, produced by [Compute Feature Centroids](ComputeFeatureCentroidsFilter.md). +- **Phases** -- the phase (Ensemble) that each Feature belongs to, produced by [Compute Feature Phases](ComputeFeaturePhasesFilter.md). % Auto generated parameter table will be inserted here diff --git a/src/Plugins/SimplnxCore/docs/ComputeFeatureNeighborsFilter.md b/src/Plugins/SimplnxCore/docs/ComputeFeatureNeighborsFilter.md index fd976848ab..5cfde8a531 100644 --- a/src/Plugins/SimplnxCore/docs/ComputeFeatureNeighborsFilter.md +++ b/src/Plugins/SimplnxCore/docs/ComputeFeatureNeighborsFilter.md @@ -6,14 +6,33 @@ Statistics (Morphological) ## Description -This **Filter** determines, for each **Feature**, the number of other **Features** that are in contact with it. The algorithm for determining the number of "contiguous" neighbors of each **Feature** is as follows: +This **Filter** determines, for each **Feature**, which other **Features** it is in direct contact with and how much boundary they share. The result is a set of feature-level arrays that many downstream filters depend on -- neighbor misorientation statistics, GBCD, twin merging, boundary strength analysis, and more. -1. Identify the **Feature** to which a **Cell** belongs -2. Identify the **Features** to which each of the current **Cell**'s six (6) face-face neighboring **Cells** (front, back, left, right, up, down) belong -3. If a neighboring **Cell** belongs to a different **Feature** than the current **Cell**, then that **Feature** (owner of the neighboring **Cell**) is added to the list of contiguous neighbors of the **Feature** that owns the current **Cell** -4. Repeat 1-3 for all **Cells** +### How This Filter Works -While performing the above steps, the number of neighboring **Cells** with a different **Feature** owner than a given **Cell** is stored, which identifies whether a **Cell** lies on the surface/edge/corner of a **Feature** (i.e. the **Feature** boundary). Additionally, the surface area shared between each set of contiguous **Features** is calculated by tracking the number of times two neighboring **Cells** correspond to a contiguous **Feature** pair. The **Filter** also notes which **Features** touch the outer surface of the sample (this is obtained for "free" while performing the above algorithm). The **Filter** gives the user the option whether or not they want to store this additional information. +The filter walks every cell in the input **Image Geometry** and compares each cell's *Feature Id* to the *Feature Ids* of its six face-sharing neighbors (front, back, left, right, up, down): + +1. Identify the **Feature** the current cell belongs to. +2. For each of the cell's six face-neighbors, check whether the neighbor cell belongs to a different feature. +3. If so, record that neighbor feature in the current feature's *contiguous neighbor* list and increment the count of shared cell-faces between the two features. +4. While iterating, the filter also tracks which cells lie on a feature boundary (any cell with at least one differently-labeled neighbor) and which features touch the outer geometry boundary (any cell whose neighbor is outside the volume). + +### What This Filter Produces + +The main feature-level outputs are: + +- **Neighbor List** -- for each feature, the list of *Feature Ids* of the features it touches. +- **Number of Neighbors** -- for each feature, the integer count of its contiguous neighbors. Equivalent to the length of each *Neighbor List* entry. +- **Shared Surface Area List** -- for each pair of neighboring features, the number of cell-faces they share. This is in **cell-face units** (a dimensionless count), not physical area. To convert to physical area, multiply by the area of one cell face (which depends on the cell spacing and the orientation of the shared face). + +Two optional outputs can also be stored: + +- **Boundary Cells** (enable *Store Boundary Cells Array*) -- a cell-level array marking which cells sit on any feature boundary. Useful for visualization and for flagging the cells that contribute to grain-boundary statistics. +- **Surface Features** (enable *Store Surface Features Array*) -- a feature-level boolean marking which features touch the outer volume bounds. Downstream statistical filters often exclude surface features from distributions because they are biased by sample truncation (see [Compute Biased Features](ComputeBiasedFeaturesFilter.md)). + +### Required Input Sources + +- **Cell Feature Ids** -- produced by a segmentation filter such as [Segment Features (Misorientation)](../OrientationAnalysis/EBSDSegmentFeaturesFilter.md) or [Segment Features (Scalar)](ScalarSegmentFeaturesFilter.md). This filter handles Image Geometries of all dimensions (0D/1D/2D/3D). Thus, it is up to the user to ensure spacing is set inline with intended behavior, specifically for Shared Surface Area List calculation. For more details see the Image Geometry section of the Geometry documentation (currently in the python docs). @@ -26,7 +45,6 @@ This filter handles Image Geometries of all dimensions (0D/1D/2D/3D). Thus, it i + (02) Single Hexagonal Phase Equiaxed + (03) Single Cubic Phase Rolled + (05) Composite - + (01) Single Cubic Phase Equiaxed + (04) Two Phase Cubic Hexagonal Particles Equiaxed + (06) SmallIN100 Synthetic diff --git a/src/Plugins/SimplnxCore/docs/ComputeFeaturePhasesBinaryFilter.md b/src/Plugins/SimplnxCore/docs/ComputeFeaturePhasesBinaryFilter.md index 586ac80ffd..b47c738721 100644 --- a/src/Plugins/SimplnxCore/docs/ComputeFeaturePhasesBinaryFilter.md +++ b/src/Plugins/SimplnxCore/docs/ComputeFeaturePhasesBinaryFilter.md @@ -6,11 +6,15 @@ Generic (Misc) ## Description -This **Filter** assigns an **Ensemble** Id number to binary data. The *true* **Cells** will be **Ensemble** 1, and *false* **Cells** will be **Ensemble** 0. This **Filter** is generally useful when the **Cell Ensembles** were not known ahead of time. For example, if an image is segmented into precipitates and non-precipitates, this **Filter** will assign the precipitates to **Ensemble** 1, and the non-precipitates to **Ensemble** 0. +This **Filter** assigns a binary **Ensemble** Id number to each **Cell** based on a boolean (true/false) mask. A **Cell** is a single voxel of an **Image Geometry**, and an **Ensemble** is a group of **Cells** that share a common phase or classification. The input is a single-component boolean mask array; the output is a single-component **Ensemble** array in which every *true* **Cell** is assigned **Ensemble** 1 and every *false* **Cell** is assigned **Ensemble** 0. -% Auto generated parameter table will be inserted here +This **Filter** is generally useful any time data has already been reduced to a two-class (binary) distinction and you need an integer **Ensemble** label for downstream processing — for example separating "selected" from "unselected", "inside" from "outside", or any pass/fail criterion. A common materials-science example is an image segmented into precipitates and non-precipitates: the precipitates (mask *true*) are assigned to **Ensemble** 1 and the non-precipitates (mask *false*) to **Ensemble** 0. + +### Required Input Sources -## Example Pipelines +- **Mask** -- the per-**Cell** boolean mask array, typically produced by [Multi-Threshold Objects](MultiThresholdObjectsFilter.md). + +% Auto generated parameter table will be inserted here ## License & Copyright diff --git a/src/Plugins/SimplnxCore/docs/ComputeFeaturePhasesFilter.md b/src/Plugins/SimplnxCore/docs/ComputeFeaturePhasesFilter.md index 10d0166308..b4601ee91c 100644 --- a/src/Plugins/SimplnxCore/docs/ComputeFeaturePhasesFilter.md +++ b/src/Plugins/SimplnxCore/docs/ComputeFeaturePhasesFilter.md @@ -6,7 +6,14 @@ Generic (Misc) ## Description -This **Filter** determines the **Ensemble** of each **Feature** by querying the **Ensemble** of the **Elements** that belong to the **Feature**. Note that it is assumed that all **Elements** belonging to a **Feature** are of the same **Feature**, and thus any **Element** can be used to determine the **Ensemble** of the **Feature** that owns that **Element**. +This **Filter** determines the **Ensemble** (phase) of each **Feature** by querying the **Ensemble** of the **Elements** that belong to the **Feature**. A **Feature** is a connected region of **Elements** sharing the same **Feature Id**; an **Element** is a single member of a geometry (for an **Image Geometry** this is a **Cell**, i.e. a voxel); and an **Ensemble** is a group of **Features** that share a common phase. Note that it is assumed that all **Elements** belonging to a **Feature** are of the same phase, and thus any **Element** can be used to determine the **Ensemble** of the **Feature** that owns that **Element**. + +The output is a single-component, per-**Feature** phase array: tuple *i* holds the **Ensemble** (phase) Id of **Feature** *i*. + +### Required Input Sources + +- **Cell Feature Ids** -- the per-**Element** **Feature** label array, typically produced by [Segment Features (Scalar)](ScalarSegmentFeaturesFilter.md) or another segmentation filter. +- **Cell Phases** -- the per-**Element** phase array, typically read from EBSD data via [Read H5EBSD](../OrientationAnalysis/ReadH5EbsdFilter.md), [Read CTF Data](../OrientationAnalysis/ReadCtfDataFilter.md), or [Read ANG Data](../OrientationAnalysis/ReadAngDataFilter.md). % Auto generated parameter table will be inserted here diff --git a/src/Plugins/SimplnxCore/docs/ComputeFeatureRectFilter.md b/src/Plugins/SimplnxCore/docs/ComputeFeatureRectFilter.md index f023cd356c..81adf9338f 100644 --- a/src/Plugins/SimplnxCore/docs/ComputeFeatureRectFilter.md +++ b/src/Plugins/SimplnxCore/docs/ComputeFeatureRectFilter.md @@ -6,7 +6,9 @@ Reconstruction (Reconstruction) ## Description -This **Filter** computes the XYZ minimum and maximum coordinates for each **Feature** in a segmentation. This data can be important for finding the smallest encompassing volume. This values are given in **Pixel** coordinates. +This **Filter** computes the XYZ minimum and maximum coordinates for each **Feature** in a segmentation. A **Feature** is a contiguous group of **Cells** (voxels) that share the same Feature Id; a **Cell** is a single voxel. This data can be important for finding the smallest encompassing volume. These values are given in **Pixel** coordinates (zero-based voxel indices), not physical length units. + +If you instead need the bounding box corners in physical coordinates, see [Compute Feature Bounding Boxes](ComputeFeatureBoundsFilter.md). | | 0 | 1 | 2 | 3 | 4 | |-------|---|---|---|---|---| @@ -26,6 +28,10 @@ If the example matrix above which represents a single feature where the feature Y Max = 3 Z Max = 0 +### Required Input Sources + +This filter requires a **Cell Feature Ids** array, typically produced by a segmentation filter such as [Segment Features (Scalar)](ScalarSegmentFeaturesFilter.md) or one of the misorientation-based segmentation filters in the OrientationAnalysis plugin. + % Auto generated parameter table will be inserted here ## Example Pipelines diff --git a/src/Plugins/SimplnxCore/docs/ComputeFeatureSizesFilter.md b/src/Plugins/SimplnxCore/docs/ComputeFeatureSizesFilter.md index f0eb4e4b54..1cd86cdf68 100644 --- a/src/Plugins/SimplnxCore/docs/ComputeFeatureSizesFilter.md +++ b/src/Plugins/SimplnxCore/docs/ComputeFeatureSizesFilter.md @@ -25,6 +25,10 @@ it will be turned into a 2D calculation instead. This means **Areas instead of V To illustrate why this is think about an image geometry with the dimensions of `1x1x5 (XYZ)`. There is no way to tell whether a `Z * X` or `Z * Y` scaling would be appropriate for the area calculation, given the current information accessible in the algorithm. +### Required Input Sources + +- **Feature Ids** -- a per-**Cell** integer label array produced by a segmentation filter such as [Segment Features (Scalar)](ScalarSegmentFeaturesFilter.md). + % Auto generated parameter table will be inserted here ## Example Pipelines diff --git a/src/Plugins/SimplnxCore/docs/ComputeGroupingDensityFilter.md b/src/Plugins/SimplnxCore/docs/ComputeGroupingDensityFilter.md index c8788beac8..c087201512 100644 --- a/src/Plugins/SimplnxCore/docs/ComputeGroupingDensityFilter.md +++ b/src/Plugins/SimplnxCore/docs/ComputeGroupingDensityFilter.md @@ -29,7 +29,7 @@ If a **Parent Feature** has no child **Features** (total checked volume is zero) #### Use Non-Contiguous Neighbors -When enabled, the filter also queries the **Non-Contiguous Neighbor List** for each child **Feature** in addition to the standard **Contiguous Neighbor List**. This expands the set of checked **Features** to include neighbors that are nearby but do not share a direct face/edge/vertex with the child **Feature**. Enable this option if non-contiguous neighbors were used during the original grouping step. Typically the filter "Compute Feature NeighborHoods" is used to generate the Non-contiguous Neighbors lists. That filter's parameter for the "Multiples of Average Diameter can have a large effect on the final Grouping Density value that is computed. +When enabled, the filter also queries the **Non-Contiguous Neighbor List** for each child **Feature** in addition to the standard **Contiguous Neighbor List**. This expands the set of checked **Features** to include neighbors that are nearby but do not share a direct face/edge/vertex with the child **Feature**. Enable this option if non-contiguous neighbors were used during the original grouping step. Typically the [Compute Feature Neighborhoods](ComputeNeighborhoodsFilter.md) filter is used to generate the non-contiguous neighbor lists. That filter's *Multiples of Average Diameter* parameter can have a large effect on the final Grouping Density value that is computed. #### Find Checked Features @@ -70,6 +70,12 @@ Note that both densities are less than 1.0 because each parent's children have n | 0.0 < d < 1.0 | Parent volume is smaller than the total checked region; the grouping is dispersed | | -1.0 | No child features found for this parent (invalid/empty parent) | +### Required Input Sources + +- **Parent IDs** -- produced by a hierarchical grouping/merge filter (for example a twin- or parent-grain merge step). +- **Contiguous Neighbor List** (and optionally the **Non-Contiguous Neighbor List**) -- produced by [Compute Feature Neighbors](ComputeFeatureNeighborsFilter.md) / [Compute Feature Neighborhoods](ComputeNeighborhoodsFilter.md). +- **Feature Volumes** -- produced by [Compute Feature Sizes](ComputeFeatureSizesFilter.md). + % Auto generated parameter table will be inserted here diff --git a/src/Plugins/SimplnxCore/docs/ComputeKMeansFilter.md b/src/Plugins/SimplnxCore/docs/ComputeKMeansFilter.md index 9f4924be10..b9beaf1f90 100644 --- a/src/Plugins/SimplnxCore/docs/ComputeKMeansFilter.md +++ b/src/Plugins/SimplnxCore/docs/ComputeKMeansFilter.md @@ -6,9 +6,11 @@ DREAM3D Review (Clustering) ## Description -***Warning:* The randomnes in this filter is not currently consistent between operating systems even if the same seed is used. Specifically between Unix and Windows. This does not affect the results, but the IDs will not correspond. For example if the Cluster Identifier at index one on Linux is 1 it could be 2 on Windows, the overarching clusters will be the same, but their IDs will be different.** +***Warning:* The randomness in this filter is not currently consistent between operating systems even if the same seed is used. Specifically between Unix and Windows. This does not affect the results, but the IDs will not correspond. For example if the Cluster Identifier at index one on Linux is 1 it could be 2 on Windows, the overarching clusters will be the same, but their IDs will be different.** -This **Filter** applies the k means algorithm to an **Attribute Array**. K means is a *clustering algorithm* that assigns to each point of the **Attribute Array** a *cluster Id*. The user must specify the number of clusters in which to partition the array. Specifically, a k means partitioning is a *Voronoi tesselation*; an optimal solution to the k means problem is such that each point in the data set is associated with the cluster that has the closest mean. This partitioning is the one that minimizes the within cluster variance (i.e., minimizes the within cluster sum of squares differences). The user may select from several distance metrics: *Euclidean*, *Squared Euclidean*, *Manhattan*, *Cosine*, *Pearson*, and *Squared Pearson*. +This **Filter** applies the k means algorithm to an **Attribute Array**. K means is a *clustering algorithm* that assigns each point (each tuple) of the **Attribute Array** to a *cluster Id*. A **cluster** is a group of data points that are more similar to each other than to points in other groups. The user must specify the number of clusters (a dimensionless count, *k*) in which to partition the array. + +Each cluster is summarized by its **centroid**, which is the arithmetic mean (the average position) of all the points assigned to that cluster. A k means partitioning is a *Voronoi tessellation*: every point is assigned to the cluster whose centroid is closest to it, so the data space is carved into regions where each region contains all the points nearer to one centroid than to any other. An optimal solution to the k means problem is one in which each point is associated with the cluster that has the closest mean. This partitioning minimizes the **within-cluster variance**, that is, the sum over all clusters of the squared distances from each point to its cluster centroid; minimizing it makes the points within each cluster as tightly grouped as possible. The user may select from several distance metrics: *Euclidean*, *Squared Euclidean*, *Manhattan*, *Cosine*, *Pearson*, and *Squared Pearson*. ### Distance Metric @@ -27,13 +29,13 @@ Optimal solutions to the k means partitioning problem are computationally diffic 2. Until convergence, repeat the following steps: - Associate each point with the closest mean, where "closest" is determined by the selected distance metric -- Recompute the means based on the new tesselation +- Recompute the means based on the new tessellation Convergence is defined as when the computed means change very little (precisely, when the differences are within machine epsilon). Since Lloyd's algorithm is iterative, it only serves as an approximation, and may result in different classifications on each execution with the same input data. The user may opt to use a mask to ignore certain points; where the mask is *false*, the points will be placed in cluster 0. Note: In SIMPLNX there is no explicit positional subtyping for Attribute Matrix, so the next section should be treated as a high-level understanding of what is being created. Naming the Attribute Matrix to include the type listed on the respective line in the 'Attribute Matrix Created' column is encouraged to help with readability and comprehension. -A clustering algorithm can be considered a kind of segmentation; this implementation of k means does not rely on the **Geometry** on which the data lie, only the *topology* of the space that the array itself forms. Therefore, this **Filter** has the effect of creating either **Features** or **Ensembles** depending on the kind of array passed to it for clustering. If an **Element** array (e.g., voxel-level **Cell** data) is passed to the **Filter**, then **Features** are created (in the previous example, a **Cell Feature Attribute Matrix** will be created). If a **Feature** array is passed to the **Filter**, then an Ensemble Attribute Matrix** is created. The following table shows what type of **Attribute Matrix** is created based on what sort of array is used for clustering: +A clustering algorithm can be considered a kind of segmentation; this implementation of k means does not rely on the **Geometry** on which the data lie, only on the arrangement of the values within the array itself (the *topology* of the space that the array forms). Therefore, this **Filter** has the effect of creating either **Features** or **Ensembles** depending on the kind of array passed to it for clustering. If an **Element** array (e.g., voxel-level **Cell** data) is passed to the **Filter**, then **Features** are created (in the previous example, a **Cell Feature Attribute Matrix** will be created). If a **Feature** array is passed to the **Filter**, then an **Ensemble Attribute Matrix** is created. The following table shows what type of **Attribute Matrix** is created based on what sort of array is used for clustering: | Attribute Matrix Source | Attribute Matrix Created | |------------------|--------------------| @@ -51,7 +53,17 @@ A clustering algorithm can be considered a kind of segmentation; this implementa | Face Ensemble | Face Ensemble | | Cell Ensemble | Cell Ensemble| -This **Filter** will store the means for the final clusters within the created **Attribute Matrix**. +The filter creates a *cluster Ids* array (one dimensionless integer cluster label per input point) alongside the input array, and stores the final cluster means (one mean vector per cluster, in the units of the input array) within the created **Attribute Matrix**. + +### Related Filters + +- [Compute K Medoids](ComputeKMedoidsFilter.md) uses representative data points (medoids) instead of means as the cluster centers. +- [DBSCAN](DBSCANFilter.md) is a density-based clustering algorithm that does not require the number of clusters to be specified in advance. +- [Silhouette](SilhouetteFilter.md) evaluates the quality of a clustering produced by this filter. + +### Required Input Sources + +- **Clustered Attribute Array** -- any **Attribute Array** (cell-level, feature-level, or generic) whose tuples are to be partitioned into clusters. This is typically an output of an earlier computation or import step. % Auto generated parameter table will be inserted here @@ -63,7 +75,7 @@ This **Filter** will store the means for the final clusters within the created * ## License & Copyright -Please see the description file distributed with this plugin. +Please see the description file distributed with this **Plugin** ## DREAM3D-NX Help diff --git a/src/Plugins/SimplnxCore/docs/ComputeKMedoidsFilter.md b/src/Plugins/SimplnxCore/docs/ComputeKMedoidsFilter.md index 2f3f4f931c..c7a6c8862e 100644 --- a/src/Plugins/SimplnxCore/docs/ComputeKMedoidsFilter.md +++ b/src/Plugins/SimplnxCore/docs/ComputeKMedoidsFilter.md @@ -6,9 +6,9 @@ DREAM3D Review (Clustering) ## Description -***Warning:* The randomnes in this filter is not currently consistent between operating systems even if the same seed is used. Specifically between Unix and Windows. This does not affect the results, but the IDs will not correspond. For example if the Cluster Identifier at index one on Linux is 1 it could be 2 on Windows, the overarching clusters will be the same, but their IDs will be different.** +***Warning:* The randomness in this filter is not currently consistent between operating systems even if the same seed is used. Specifically between Unix and Windows. This does not affect the results, but the IDs will not correspond. For example if the Cluster Identifier at index one on Linux is 1 it could be 2 on Windows, the overarching clusters will be the same, but their IDs will be different.** -This **Filter** applies the k medoids algorithm to an **Attribute Array**. K medoids is a *clustering algorithm* that assigns to each point of the **Attribute Array** a *cluster Id*. The user must specify the number of clusters in which to partition the array. Specifically, a k medoids partitioning is such that each point in the data set is associated with the cluster that minimizes the sum of the pair-wise distances between the data points and their associated cluster centers (medoids). This approach is analogous to k means, but uses actual data points (the medoids) as the cluster exemplars instead of the means. Medoids in this context refer to the data point in each cluster that is most like all other data points, i.e., that data point whose average distance to all other data points in the cluster is smallest. Unlike k means, since pair-wise distances are minimized instead of variance, any arbirtary concept of "distance" may be used; this **Filter** allows for the selection of a variety of distance metrics. +This **Filter** applies the k medoids algorithm to an **Attribute Array**. K medoids is a *clustering algorithm* that assigns each point (each tuple) of the **Attribute Array** to a *cluster Id*. A **cluster** is a group of data points that are more similar to each other than to points in other groups. The user must specify the number of clusters (a dimensionless count, *k*) in which to partition the array. Specifically, a k medoids partitioning is such that each point in the data set is associated with the cluster that minimizes the sum of the pair-wise distances between the data points and their associated cluster centers (medoids). This approach is analogous to k means, but uses actual data points (the medoids) as the cluster exemplars instead of the means. Medoids in this context refer to the data point in each cluster that is most like all other data points, i.e., that data point whose average distance to all other data points in the cluster is smallest. Unlike k means, since pair-wise distances are minimized instead of variance, any arbitrary concept of "distance" may be used; this **Filter** allows for the selection of a variety of distance metrics. ### Distance Metric @@ -21,7 +21,7 @@ The *Distance Metric* parameter determines how distances between data points are - **Pearson [4]**: One minus the Pearson correlation coefficient. Measures the linear correlation between two points, normalized by their standard deviations. - **Squared Pearson [5]**: The square of the Pearson distance metric. -This **Filter** uses the *Voronoi iteration* algorithm to produce the clustering. The algorithm is iterative and proceeds as follows: +This **Filter** uses the *Voronoi iteration* algorithm to produce the clustering. A **Voronoi** partitioning assigns every point to the cluster whose center (here, the medoid) is closest, carving the data space into regions where each region holds all the points nearer to one medoid than to any other. The algorithm is iterative and proceeds as follows: 1. Choose k points at random to serve as the initial cluster medoids 2. Associate each point to the closest medoid @@ -34,7 +34,7 @@ Convergence is defined as when the medoids no longer change position. Since the Note: In SIMPLNX there is no explicit positional subtyping for Attribute Matrix, so the next section should be treated as a high-level understanding of what is being created. Naming the Attribute Matrix to include the type listed on the respective line in the 'Attribute Matrix Created' column is encouraged to help with readability and comprehension. -A clustering algorithm can be considered a kind of segmentation; this implementation of k medoids does not rely on the **Geometry** on which the data lie, only the *topology* of the space that the array itself forms. Therefore, this **Filter** has the effect of creating either **Features** or **Ensembles** depending on the kind of array passed to it for clustering. If an **Element** array (e.g., voxel-level **Cell** data) is passed to the **Filter**, then **Features** are created (in the previous example, a **Cell Feature Attribute Matrix** will be created). If a **Feature** array is passed to the **Filter**, then an Ensemble Attribute Matrix** is created. The following table shows what type of **Attribute Matrix** is created based on what sort of array is used for clustering: +A clustering algorithm can be considered a kind of segmentation; this implementation of k medoids does not rely on the **Geometry** on which the data lie, only on the arrangement of the values within the array itself (the *topology* of the space that the array forms). Therefore, this **Filter** has the effect of creating either **Features** or **Ensembles** depending on the kind of array passed to it for clustering. If an **Element** array (e.g., voxel-level **Cell** data) is passed to the **Filter**, then **Features** are created (in the previous example, a **Cell Feature Attribute Matrix** will be created). If a **Feature** array is passed to the **Filter**, then an **Ensemble Attribute Matrix** is created. The following table shows what type of **Attribute Matrix** is created based on what sort of array is used for clustering: | Attribute Matrix Source | Attribute Matrix Created | |------------------|--------------------| @@ -52,7 +52,17 @@ A clustering algorithm can be considered a kind of segmentation; this implementa | Face Ensemble | Face Ensemble | | Cell Ensemble | Cell Ensemble| -This **Filter** will store the medoids for the final clusters within the created **Attribute Matrix**. +The filter creates a *cluster Ids* array (one dimensionless integer cluster label per input point) alongside the input array, and stores the final cluster medoids (one medoid vector per cluster, in the units of the input array) within the created **Attribute Matrix**. + +### Related Filters + +- [Compute K Means](ComputeKMeansFilter.md) uses the arithmetic mean of each cluster as its center instead of a representative data point. +- [DBSCAN](DBSCANFilter.md) is a density-based clustering algorithm that does not require the number of clusters to be specified in advance. +- [Silhouette](SilhouetteFilter.md) evaluates the quality of a clustering produced by this filter. + +### Required Input Sources + +- **Clustered Attribute Array** -- any **Attribute Array** (cell-level, feature-level, or generic) whose tuples are to be partitioned into clusters. This is typically an output of an earlier computation or import step. % Auto generated parameter table will be inserted here @@ -64,7 +74,7 @@ This **Filter** will store the medoids for the final clusters within the created ## License & Copyright -Please see the description file distributed with this plugin. +Please see the description file distributed with this **Plugin** ## DREAM3D-NX Help diff --git a/src/Plugins/SimplnxCore/docs/ComputeLargestCrossSectionsFilter.md b/src/Plugins/SimplnxCore/docs/ComputeLargestCrossSectionsFilter.md index ffe68cfff2..cd33942a50 100644 --- a/src/Plugins/SimplnxCore/docs/ComputeLargestCrossSectionsFilter.md +++ b/src/Plugins/SimplnxCore/docs/ComputeLargestCrossSectionsFilter.md @@ -6,7 +6,9 @@ Statistics (Morphological) ## Description -This **Filter** calculates the largest cross-sectional area on a user-defined plane for all **Features**. The **Filter** simply iterates through all **Cells** (on each section) asking for **Feature** that owns them. On each section, the count of **Cells** for each **Feature** is then converted to an area and stored as the *LargestCrossSection* if the area for the current section is larger than the existing *LargestCrossSection* for that **Feature**. +This **Filter** calculates the largest cross-sectional area on a user-defined plane for all **Features**. A **Feature** is a contiguous group of **Cells** (voxels) that share the same Feature Id; a **Cell** is a single voxel. The **Filter** simply iterates through all **Cells** (on each section) asking for the **Feature** that owns them. On each section, the count of **Cells** for each **Feature** is then converted to an area and stored as the *LargestCrossSection* if the area for the current section is larger than the existing *LargestCrossSection* for that **Feature**. + +The area is reported in **square physical units**, not a raw cell count. For each section the per-**Feature** **Cell** count is multiplied by the in-plane voxel area (the product of the two **Image Geometry** spacing values that lie in the chosen plane, e.g. `spacing-X * spacing-Y` for the XY plane). The output `LargestCrossSections` array is a single-component `float32` array created in the **Cell Feature Attribute Matrix**, holding the largest cross-sectional area found for each **Feature**. ### Plane of Interest @@ -16,6 +18,10 @@ The *Plane of Interest* parameter selects the plane along which cross-sections a - **XZ [1]**: Cross-sections are taken on planes perpendicular to the Y axis. Each Y slice is one cross-section. - **YZ [2]**: Cross-sections are taken on planes perpendicular to the X axis. Each X slice is one cross-section. +### Required Input Sources + +This filter requires a **Cell Feature Ids** array, typically produced by a segmentation filter such as [Segment Features (Scalar)](ScalarSegmentFeaturesFilter.md) or one of the misorientation-based segmentation filters in the OrientationAnalysis plugin. + % Auto generated parameter table will be inserted here ## Example Pipelines diff --git a/src/Plugins/SimplnxCore/docs/ComputeMomentInvariants2DFilter.md b/src/Plugins/SimplnxCore/docs/ComputeMomentInvariants2DFilter.md index 2782d328a6..6b7d675774 100644 --- a/src/Plugins/SimplnxCore/docs/ComputeMomentInvariants2DFilter.md +++ b/src/Plugins/SimplnxCore/docs/ComputeMomentInvariants2DFilter.md @@ -6,13 +6,24 @@ Statistics (Statistics) ## Description -This **Filter** computes the 2D Omega-1 and Omega 2 values from the *Central Moments* matrix and optionally will normalize the values to a unit circle and also optionally save the *Central Moments* matrix as a DataArray to the *Cell Feature Attribute Matrix*. Based off the paper by MacSleyne et. al [1], the algorithm will calculate the 2D central moments for each feature starting at *feature id = 1*. Because *feature id 0* is of special significance and typically is a matrix or background it is ignored in this filter. If any feature id has a Z Delta of > 1, the feature will be skipped. This algorithm works strictly in the XY plane and is meant to be applied to a 2D image. Using the research from the cited paper certain shapes can be detected using the Omega-1 and Omega-2 values. An example usage is finding elliptical shapes in an image: +This **Filter** computes the 2D **moment invariants** Omega-1 and Omega-2 for each **Feature** in a 2D image. A **Feature** is a contiguous region of like-segmented cells (for example a particle). **Moment invariants** are scalar shape descriptors derived from the *Central Moments* of a **Feature**: the **Filter** treats each **Feature** as a flat 2D shape, measures how its area is distributed about its own centroid, and condenses that distribution into two numbers that do not change when the shape is translated, rotated, or (after normalization) scaled. Omega-1 and Omega-2 are therefore dimensionless values that describe the *shape* of a **Feature**, independent of its position, orientation, or size. -See below figure from [1] that can help the user classify objects. +In practice these values measure how elongated or irregular a **Feature** is. A perfect circle gives the smallest possible Omega values; the more a **Feature** deviates toward an elongated ellipse or an irregular shape, the larger the Omega values become. By thresholding Omega-1 and Omega-2, you can classify **Features** by shape, for example separating round particles from elongated or irregular ones. -![Example appllication of filter to identify elliptical particales (red) which are differentiated from non-elliptical particals (purple)](Images/ComputeMomentInvariants_Fig1.png) +Based on the paper by MacSleyne et al. [1], the algorithm calculates the 2D central moments for each **Feature** starting at *feature id = 1*. Because *feature id 0* is of special significance and is typically a matrix or background, it is ignored. If any **Feature** has a Z extent (Z Delta) greater than 1 cell, that **Feature** is skipped. The algorithm works strictly in the XY plane and is meant to be applied to a 2D image. -![Example appllication of filter to identify elliptical particales (red) which are differentiated from non-elliptical particals (purple)](Images/ComputeMomentInvariants2D.png) +The **Filter** can optionally normalize the values to a unit circle (the *Normalize Moment Invariants* parameter) and can optionally save the full 3x3 *Central Moments* matrix as a Data Array in the *Feature Attribute Matrix*. + +The figures below, from [1], can help classify objects by their Omega values. An example usage is finding elliptical shapes (red) and differentiating them from non-elliptical shapes (purple): + +![Example application of the filter to identify elliptical particles (red), differentiated from non-elliptical particles (purple)](Images/ComputeMomentInvariants_Fig1.png) + +![Example application of the filter to identify elliptical particles (red), differentiated from non-elliptical particles (purple)](Images/ComputeMomentInvariants2D.png) + +### Required Input Sources + +- **Cell Feature Ids** -- the Feature that owns each Cell, produced by a segmentation filter such as [Segment Features (Scalar)](ScalarSegmentFeaturesFilter.md). +- **Feature Rect** -- the min/max XY pixel coordinates (bounding corners) of each Feature, produced by [Compute Feature Corners](ComputeFeatureRectFilter.md). % Auto generated parameter table will be inserted here @@ -24,11 +35,10 @@ See below figure from [1] that can help the user classify objects. # Acknowledgements The authors would like to thank Dr. Marc De Graef from Carnegie Mellon University for enlightening discussions and a concrete implementation from which to start this filter. -## Example Pipelines ## License & Copyright -Please see the description file distributed with this plugin. +Please see the description file distributed with this **Plugin** ## DREAM3D-NX Help diff --git a/src/Plugins/SimplnxCore/docs/ComputeNeighborListStatisticsFilter.md b/src/Plugins/SimplnxCore/docs/ComputeNeighborListStatisticsFilter.md index c05c009cc0..098209f9fa 100644 --- a/src/Plugins/SimplnxCore/docs/ComputeNeighborListStatisticsFilter.md +++ b/src/Plugins/SimplnxCore/docs/ComputeNeighborListStatisticsFilter.md @@ -6,15 +6,27 @@ Statistics (Misc Filters) ## Description -This **Filter** computes the selected statistics for each list contained in a NeighborList container. Each of those statistics are reported back as new Attribute Arrays. The user selectable statistics are: - -+ Length of each list -+ Minimum value from each list -+ Maximum value from each list -+ Mean of each list -+ Median of each list -+ Standard Deviation of each list -+ Summation of each list +This **Filter** reduces a **NeighborList** -- a per-feature list of values, one entry per neighbor -- into per-feature scalar summary statistics. Each chosen statistic becomes its own output **Attribute Array** at the feature level. + +A typical use is summarizing per-feature neighbor misorientations: [Compute Feature Neighbor Misorientations](../OrientationAnalysis/ComputeFeatureNeighborMisorientationsFilter.md) produces a NeighborList containing the misorientation between a feature and each of its neighbors; this filter reduces that list to "average misorientation per feature" or "max neighbor misorientation per feature" so the result can be plotted or thresholded. + +### Available Statistics + +The user can independently enable any combination of: + +- **Length** -- the number of entries in the list (i.e., the number of neighbors). +- **Minimum** -- smallest value in the list. +- **Maximum** -- largest value in the list. +- **Mean** -- arithmetic mean of the list. +- **Median** -- median of the list. +- **Standard Deviation** -- sample standard deviation of the list. +- **Summation** -- sum of all values in the list. + +Output statistics inherit the units of the input list (e.g., degrees for a misorientation list, dimensionless count for a neighbor count list). + +### Required Input Sources + +- **Input NeighborList** -- a feature-level list-of-lists. Common producers include [Compute Feature Neighbors](ComputeFeatureNeighborsFilter.md) (shared surface area), [Compute Feature Neighbor Misorientations](../OrientationAnalysis/ComputeFeatureNeighborMisorientationsFilter.md) (misorientation per neighbor), [Compute Feature Neighbor C-Axis Misalignments](../OrientationAnalysis/ComputeFeatureNeighborCAxisMisalignmentsFilter.md), or [Compute Slip Transmission Metrics](../OrientationAnalysis/ComputeSlipTransmissionMetricsFilter.md). % Auto generated parameter table will be inserted here diff --git a/src/Plugins/SimplnxCore/docs/ComputeNeighborhoodsFilter.md b/src/Plugins/SimplnxCore/docs/ComputeNeighborhoodsFilter.md index 0df45ba41d..15802a131b 100644 --- a/src/Plugins/SimplnxCore/docs/ComputeNeighborhoodsFilter.md +++ b/src/Plugins/SimplnxCore/docs/ComputeNeighborhoodsFilter.md @@ -6,22 +6,32 @@ Statistics (Morphological) ## Description -For each feature, determine how many other features are within a user defined multiple of the average *Equivalent Sphere Diameter* of the centroid of the feature. +For each **Feature**, this **Filter** counts how many other features have centroids within a sphere centered on the current feature. The sphere's radius is a user-specified multiple of the **Equivalent Sphere Diameter (ESD)** of features in the same phase, so the search radius scales naturally with grain size. -The algorithm for determining the number of **Features** is given below: +This is useful for second-nearest-neighbor and clustering analyses -- studying spatial arrangement, cluster identification, or the distribution of nearby features beyond just the immediate face-sharing neighbors counted by [Compute Feature Neighbors](ComputeFeatureNeighborsFilter.md). -1. Compute the average equivalent diameter for all features in a given phase -2. Define a sphere centered at the **Feature**'s *centroid* and with radius equal to the average equivalent sphere diameter multiplied by the user defined multiple -3. Check every other **Feature**'s *centroid* to see if it lies within the sphere and keep count and list of those that satisfy -4. Repeat 2. & 3. for all **Features** +### How This Filter Works + +1. Compute the average ESD across all features within each phase. The ESD of a feature is the diameter of a sphere with the same volume as the feature; it is produced by [Compute Feature Sizes](ComputeFeatureSizesFilter.md). +2. For each feature, define a search sphere centered at the feature's centroid with radius = (average ESD) * (user-specified *Multiplier*). +3. Count how many other features have centroids inside that sphere, and store the list of those features. ![](images/ComputeFeatureNeighborhoods_MultiplesOfAvgDiameter.png) -## Output Notes +### Multiplier + +The *Multiplier* parameter is **dimensionless** -- a multiple of the average ESD. Common values: + +- **1.0** -- search sphere is the same size as the average grain. Catches a feature's immediate neighbors and slightly beyond. +- **2.0-3.0** -- second-nearest-neighbor analysis. +- **5.0+** -- broader clustering / long-range arrangement studies. + +### Required Input Sources -There are 2 outputs from this filter: -- The "Number of Neighbors" for each feature -- The list of "neighbor" features for each neighbor +- **Cell Feature Ids** -- produced by a segmentation filter such as [Segment Features (Misorientation)](../OrientationAnalysis/EBSDSegmentFeaturesFilter.md). +- **Feature Centroids** -- produced by [Compute Feature Centroids](ComputeFeatureCentroidsFilter.md). +- **Feature Equivalent Diameters** -- produced by [Compute Feature Sizes](ComputeFeatureSizesFilter.md). +- **Feature Phases** -- produced by [Compute Feature Phases](ComputeFeaturePhasesFilter.md). % Auto generated parameter table will be inserted here diff --git a/src/Plugins/SimplnxCore/docs/ComputeNumFeaturesFilter.md b/src/Plugins/SimplnxCore/docs/ComputeNumFeaturesFilter.md index aecdb6ab33..6cf8a38bfa 100644 --- a/src/Plugins/SimplnxCore/docs/ComputeNumFeaturesFilter.md +++ b/src/Plugins/SimplnxCore/docs/ComputeNumFeaturesFilter.md @@ -6,7 +6,13 @@ Statistics (Morphological) ## Description -This **Filter** determines the number of **Features** in each **Ensemble** by summing the total number of rows in the feature attribute matrix belonging to each phase. +This **Filter** determines the number of **Features** in each **Ensemble** by counting the **Features** assigned to each **Ensemble**. An **Ensemble** is a group of **Features** that share common characteristics — most commonly a *phase* (a distinct material or crystallographic constituent in the sample). The filter reads the per-**Feature** phase array and tallies how many **Features** belong to each phase. + +The output is a single-component count array indexed by **Ensemble** (phase) Id: tuple *i* holds the number of **Features** belonging to **Ensemble** *i*. + +### Required Input Sources + +- **Feature Phases** -- the per-**Feature** phase (**Ensemble** Id) array, produced by [Compute Feature Phases](ComputeFeaturePhasesFilter.md). % Auto generated parameter table will be inserted here diff --git a/src/Plugins/SimplnxCore/docs/ComputeSurfaceAreaToVolumeFilter.md b/src/Plugins/SimplnxCore/docs/ComputeSurfaceAreaToVolumeFilter.md index 52117bd1fb..efe9c63b12 100644 --- a/src/Plugins/SimplnxCore/docs/ComputeSurfaceAreaToVolumeFilter.md +++ b/src/Plugins/SimplnxCore/docs/ComputeSurfaceAreaToVolumeFilter.md @@ -6,9 +6,9 @@ Statistics (Morphological) ## Description -This **Filter** calculates the ratio of surface area to volume for each **Feature** in an **Image Geometry**. +This **Filter** calculates the ratio of surface area to volume for each **Feature** in an **Image Geometry**. A **Feature** is a connected region of **Cells** that share the same **Feature Id**. Because surface area has units of length squared and volume has units of length cubed, the resulting ratio has units of *1/length* (the reciprocal of the **Image Geometry** spacing units; for example, if the spacing is in micrometers the ratio is in 1/micrometers). -This filter also optionally calculate the [Sphericity](https://en.wikipedia.org/wiki/Sphericity) of each feature. +This filter also optionally calculates the [Sphericity](https://en.wikipedia.org/wiki/Sphericity) of each feature. Sphericity is a *dimensionless* (unitless) measure of how closely a **Feature**'s shape approaches that of a perfect sphere. ![Equation for Sphericity used in the filter](Images/Sphericity_Equation.png) @@ -17,15 +17,19 @@ This **Filter** determines whether a **Feature** touches an outer *Surface* of t + Any cell location is xmin, xmax, ymin, ymax, zmin or zmax + Any cell has **Feature ID = 0** as a neighbor. +### Required Input Sources + +- **Cell Feature Ids** -- the per-**Cell** **Feature** label array, typically produced by [Segment Features (Scalar)](ScalarSegmentFeaturesFilter.md) or another segmentation filter. + ## Algorithm Details -- First, all the boundary **Cells** are found for each **Feature**. +- 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**. ### 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. As a result, the surface area to volume will likely be over-estimated with respect to the *real* **Feature**. +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 diff --git a/src/Plugins/SimplnxCore/docs/ComputeSurfaceFeaturesFilter.md b/src/Plugins/SimplnxCore/docs/ComputeSurfaceFeaturesFilter.md index 395152e694..985aa69f56 100644 --- a/src/Plugins/SimplnxCore/docs/ComputeSurfaceFeaturesFilter.md +++ b/src/Plugins/SimplnxCore/docs/ComputeSurfaceFeaturesFilter.md @@ -6,14 +6,14 @@ Generic (Spatial) ## Description -This **Filter** determines whether a **Feature** touches an outer surface of the sample. This is accomplished by simply querying the **Feature** owners of the **Cells** that sit at either . Any **Feature** that owns one of those **Cells** is said to touch an outer surface and all other **Features** are said to not touch an outer surface of the sample. +This **Filter** flags each **Feature** with whether it touches an outer surface of the sample volume. The output is a feature-level boolean array where *false* (0) means the feature is fully enclosed in the interior and *true* (1) means at least one of its cells sits on the sample surface. -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: +A **Feature** is considered a "surface feature" if either of the following is true: -+ Any cell location is xmin, xmax, ymin, ymax, zmin or zmax -+ Any cell has **Feature ID = 0** as a neighbor. +- Any of its cells sits on the outermost voxel layer of the geometry -- i.e., a cell location equal to xmin, xmax, ymin, ymax, zmin, or zmax. +- Any of its cells has a neighbor with **Feature ID = 0**. (Feature ID 0 is the "unassigned" / "outside sample" label, typically produced by a mask or by [Isolate Largest Feature](IdentifySampleFilter.md).) -The output of this filter is a **Feature** level array of booleans where 0=Interior/Not touching and 1=Surface/Touching. +Surface features are usually excluded from size distributions, neighbor statistics, and other analyses because their measured volume is artificially truncated by the sample boundary. See [Compute Biased Features](ComputeBiasedFeaturesFilter.md) for a more statistically rigorous treatment of boundary bias. ### WARNING - Feature ID=0 Voxels @@ -34,6 +34,10 @@ If the structure/data is actually 2D, then the dimension that is planar is not c | ![ComputeSurfaceFeatures_Cylinder](Images/ComputeSurfaceFeatures_Cylinder.png) | ![ComputeSurfaceFeatures_Square](Images/ComputeSurfaceFeatures_Square.png) | | Example showing features touching Feature ID=0 (Black voxels) "Mark Feature 0 Neighbors" is **ON** | Example showing features touching the outer surface of the bounding box | +### Required Input Sources + +- **Cell Feature Ids** -- produced by a segmentation filter such as [Segment Features (Misorientation)](../OrientationAnalysis/EBSDSegmentFeaturesFilter.md) or [Segment Features (Scalar)](ScalarSegmentFeaturesFilter.md). + % Auto generated parameter table will be inserted here ## Example Pipelines diff --git a/src/Plugins/SimplnxCore/docs/ComputeTriangleAreasFilter.md b/src/Plugins/SimplnxCore/docs/ComputeTriangleAreasFilter.md index ced548ef84..d5c97ab7e4 100644 --- a/src/Plugins/SimplnxCore/docs/ComputeTriangleAreasFilter.md +++ b/src/Plugins/SimplnxCore/docs/ComputeTriangleAreasFilter.md @@ -6,11 +6,25 @@ Surface Meshing (Misc) ## Description -This **Filter** computes the area of each **Triangle** in a **Triangle Geometry** by calculating the following: +This filter computes the surface area of every **Triangle** in a **Triangle Geometry** (a surface mesh built from triangles) and stores the result as a per-triangle **Face Data** array. - 1/2*|AB||AC|sin(O) +### What This Measures and Why -where *O* is the angle between |AB| and |AC|. +Each triangle is defined by three corner **vertices** (nodes). The filter computes the area enclosed by those three vertices using + + Area = 1/2 * |AB| * |AC| * sin(O) + +where *AB* and *AC* are two edge vectors of the triangle and *O* is the angle between them. + +Per-triangle area is a basic mesh-quality and statistics input. It is used to weight other per-triangle quantities (for example, area-weighting triangle normals or curvature when computing feature-level averages) so that large triangles contribute proportionally more than small ones, and it can be summed to report the total surface area of a **Feature** or boundary. + +### Units + +The output area is reported in **squared geometry length units** (length^2). The value uses whatever length unit the **Triangle Geometry** vertices are stored in (for example, micrometers^2 if the mesh coordinates are in micrometers). + +### Required Input Sources + +- **Triangle Geometry** -- a surface mesh, typically produced by a surface-meshing filter such as [Create Surface Mesh (Surface Nets)](SurfaceNetsFilter.md) or [Create Surface Mesh (QuickMesh)](QuickSurfaceMeshFilter.md). % Auto generated parameter table will be inserted here diff --git a/src/Plugins/SimplnxCore/docs/ComputeTriangleGeomCentroidsFilter.md b/src/Plugins/SimplnxCore/docs/ComputeTriangleGeomCentroidsFilter.md index 8928f755cb..b6918b20af 100644 --- a/src/Plugins/SimplnxCore/docs/ComputeTriangleGeomCentroidsFilter.md +++ b/src/Plugins/SimplnxCore/docs/ComputeTriangleGeomCentroidsFilter.md @@ -6,21 +6,34 @@ Statistics (Morphological) ## Description -This **Filter** determines the centroids of each **Feature** in a **Triangle Geometry**. The centroids are determined -using the following algorithm: +This filter computes the centroid (the average position of the bounding nodes) of each **Feature** in a **Triangle Geometry** (a surface mesh built from triangles). -1. Query each triangle within the **Triangle Geometry** to determine its two owners -2. Add the 3 nodes of that triangle to the set of nodes bounding those two owners (*Note that a set will only allow each - node to be entered once for a given owner*) -3. For each **Feature**, find the average (x,y,z) coordinate from the set of nodes that bound it +In a surface mesh, each triangle carries a **Face Labels** value: a pair of **Feature** Ids naming the two features that meet at that triangle. These two features are the triangle's "owners". A **Feature** is the volume of material enclosed by the triangles that reference its Id. The corner points of each triangle are its **nodes** (also called vertices). -% Auto generated parameter table will be inserted here +The centroid of each feature is determined as follows: + +1. For each triangle, read its two owners from the **Face Labels** array. +2. Add the 3 nodes of that triangle to the set of nodes bounding each of those two owners. A set stores each node only once per owner, so shared nodes are not double-counted. +3. For each **Feature**, average the (x, y, z) coordinates of the set of nodes that bound it to obtain the centroid. + +### Boundary / Exterior Label + +A **Face Labels** value of -1 indicates the exterior of the sample (the triangle faces open space rather than another feature). Feature Id -1 is the exterior and is not a real feature; its accumulated "centroid" entry is therefore not physically meaningful and should be ignored. + +### Units -## Example Pipelines +Centroid coordinates are reported in the **geometry length units** of the **Triangle Geometry** vertices (for example, micrometers if the mesh coordinates are stored in micrometers). + +### Required Input Sources + +- **Triangle Geometry** -- a surface mesh, typically produced by a surface-meshing filter such as [Create Surface Mesh (Surface Nets)](SurfaceNetsFilter.md) or [Create Surface Mesh (QuickMesh)](QuickSurfaceMeshFilter.md). +- **Face Labels** -- the per-triangle pair of **Feature** Ids, produced alongside the mesh by [Create Surface Mesh (QuickMesh)](QuickSurfaceMeshFilter.md) or [Create Surface Mesh (Surface Nets)](SurfaceNetsFilter.md). + +% Auto generated parameter table will be inserted here ## License & Copyright -Please see the description file distributed with this plugin. +Please see the description file distributed with this **Plugin** ## DREAM3D-NX Help diff --git a/src/Plugins/SimplnxCore/docs/ComputeTriangleGeomVolumesFilter.md b/src/Plugins/SimplnxCore/docs/ComputeTriangleGeomVolumesFilter.md index 5085e66723..b3912c7ae7 100644 --- a/src/Plugins/SimplnxCore/docs/ComputeTriangleGeomVolumesFilter.md +++ b/src/Plugins/SimplnxCore/docs/ComputeTriangleGeomVolumesFilter.md @@ -6,25 +6,36 @@ Statistics (Morphological) ## Description -This **Filter** computes the enclosed volume of each **Feature** in a **Triangle Geometry**. The result is the volume of -each surface meshed **Feature**, or alternatively the volume of each unique polyhedron defined by the given _Face -Labels_ array. The volume of any generic polyhedron can be computed using the following algorithm: - -1. Triangulate each face of the polyhedron (in this case, each face is already a triangle within the **Triangle - Geometry**) -2. For each triangular face, ensure the normals are all consistent (this **Filter** uses the convention where normals - point inwards; note that the actual winding of the **Triangle Geometry** is not modified) -3. For each triangular face, create a tetrahedron where the fourth vertex is the origin -4. Compute the signed volume of each tetrahedron -5. Sum the signed tetrahedra volumes to obtain the volume of the enclosing polyhedron +This filter computes the enclosed volume of each **Feature** in a **Triangle Geometry** (a surface mesh built from triangles). The result is the volume of each surface-meshed **Feature**, equivalently the volume of each unique closed polyhedron defined by the **Face Labels** array. -% Auto generated parameter table will be inserted here +In a surface mesh, each triangle carries a **Face Labels** value: a pair of **Feature** Ids naming the two features on either side of that triangle. The set of triangles that reference a given **Feature** Id forms the closed shell of that feature. The **winding** of a triangle is the order in which its three corner vertices are listed; that order defines which way the triangle's surface normal points (inward vs. outward). + +The volume of any generic closed polyhedron is computed as follows: + +1. Triangulate each face of the polyhedron (here, each face is already a triangle in the **Triangle Geometry**). +2. Make the triangle normals consistent. This filter uses the convention where normals point inward. The actual winding stored in the **Triangle Geometry** is not modified. +3. For each triangular face, form a tetrahedron whose fourth vertex is the coordinate-system origin. +4. Compute the signed volume of each tetrahedron. +5. Sum the signed tetrahedra volumes to obtain the volume enclosed by the polyhedron. + +### Watertight Requirement + +This method only yields a correct value for a **watertight** (closed, gap-free) surface. The signed-tetrahedron sum relies on the feature's triangles forming a complete enclosing shell; if the surface has holes or is otherwise open, the computed volume is not meaningful. Surfaces produced by the standard surface-meshing filters are closed per feature and satisfy this requirement. -## Example Pipelines +### Units + +Volume is reported in **cubed geometry length units** (length^3), using whatever length unit the **Triangle Geometry** vertices are stored in (for example, micrometers^3 if the mesh coordinates are in micrometers). + +### Required Input Sources + +- **Triangle Geometry** -- a closed (watertight) surface mesh, typically produced by a surface-meshing filter such as [Create Surface Mesh (Surface Nets)](SurfaceNetsFilter.md) or [Create Surface Mesh (QuickMesh)](QuickSurfaceMeshFilter.md). +- **Face Labels** -- the per-triangle pair of **Feature** Ids, produced alongside the mesh by [Create Surface Mesh (QuickMesh)](QuickSurfaceMeshFilter.md) or [Create Surface Mesh (Surface Nets)](SurfaceNetsFilter.md). + +% Auto generated parameter table will be inserted here ## License & Copyright -Please see the description file distributed with this plugin. +Please see the description file distributed with this **Plugin** ## DREAM3D-NX Help diff --git a/src/Plugins/SimplnxCore/docs/ComputeVectorColorsFilter.md b/src/Plugins/SimplnxCore/docs/ComputeVectorColorsFilter.md index 1d036e9314..a20d3b26c9 100644 --- a/src/Plugins/SimplnxCore/docs/ComputeVectorColorsFilter.md +++ b/src/Plugins/SimplnxCore/docs/ComputeVectorColorsFilter.md @@ -6,10 +6,16 @@ Generic (Coloring) ## Description -This **Filter** generates a color for each **Element** based on the vector assigned to that **Element** in the input vector data. The color scheme assigns a unique color to all points on the unit hemisphere using a HSV-like scheme. The color space is approximately represented by the following legend. +This filter generates an RGB color for each **Cell** based on the vector assigned to that **Cell** in the input vector data. The input is a 3-component (float32) vector **Cell** array, and the output is a 3-component unsigned 8-bit (uint8) RGB array with values in the range 0-255. Each input vector is normalized to unit length before its direction is mapped to a color, so only the *direction* of the vector affects the color; its magnitude is ignored. The color scheme assigns a unique color to every direction on the unit hemisphere using an HSV-like scheme. The color space is approximately represented by the following legend. ![Images/VectorColors](Images/VectorColors.png) +When *Apply to Good Voxels Only* is enabled, the supplied boolean or uint8 **Mask** array marks which **Cells** are valid; **Cells** flagged as bad are left black (RGB 0,0,0) instead of being colored. + +### Required Input Sources + +- **Vector Attribute Array** -- a 3-component float32 per-**Cell** vector array. This may come from any filter that produces a per-**Cell** vector field (for example, a dipole, gradient, or orientation-derived vector array). + % Auto generated parameter table will be inserted here ## Example Pipelines diff --git a/src/Plugins/SimplnxCore/docs/ComputeVertexToTriangleDistancesFilter.md b/src/Plugins/SimplnxCore/docs/ComputeVertexToTriangleDistancesFilter.md index 8129b68d76..57788f5734 100644 --- a/src/Plugins/SimplnxCore/docs/ComputeVertexToTriangleDistancesFilter.md +++ b/src/Plugins/SimplnxCore/docs/ComputeVertexToTriangleDistancesFilter.md @@ -6,7 +6,17 @@ Sampling (Spatial) ## Description -This **Filter** computes distances between points in a **Vertex Geoemtry** and triangles in a **Triangle Geoemtry**. Specifically, for each point in the **Vertex Geometry**, the Euclidean distance to the closest triangle in the **Triangle Geoemtry** is stored. This distance is *signed*: if the point lies on the side of the triangle to which the triangle normal points, then the distance is positive; otherwise, the distance is negative. Additionally, the ID the closest triangle is stored for each point. +This **Filter** computes distances between points in a **Vertex Geometry** and triangles in a **Triangle Geometry**. Specifically, for each point in the **Vertex Geometry**, the Euclidean distance to the closest triangle in the **Triangle Geometry** is stored. This distance is *signed*: if the point lies on the side of the triangle to which the triangle normal points, then the distance is positive; otherwise, the distance is negative. Additionally, the ID of the closest triangle is stored for each point. + +The computed distance is reported in the same length unit as the coordinates of the two input geometries (e.g., microns, millimeters); both geometries must share the same unit system for the result to be meaningful. + +The sign of each distance depends on the **Triangle Normals**. For the sign to be correct, the normals must be present and consistently oriented across the mesh (all pointing to the same "outside"). Inconsistent or flipped normals will produce sign errors even when the distance magnitude is correct. + +### Required Input Sources + +- **Vertex Geometry** -- the point cloud whose distances are measured. +- **Triangle Geometry** -- the surface mesh measured against, typically produced by a surface-meshing filter such as [Quick Surface Mesh](QuickSurfaceMeshFilter.md) or read from a CAD mesh via [Read STL File](ReadStlFileFilter.md). +- **Triangle Normals** -- per-face normals on the **Triangle Geometry**, produced by [Compute Triangle Normals](TriangleNormalFilter.md); required for correct distance signs. % Auto generated parameter table will be inserted here diff --git a/src/Plugins/SimplnxCore/docs/ComputeVolumeFractionsFilter.md b/src/Plugins/SimplnxCore/docs/ComputeVolumeFractionsFilter.md index 919b4cb0bb..27b6a57297 100644 --- a/src/Plugins/SimplnxCore/docs/ComputeVolumeFractionsFilter.md +++ b/src/Plugins/SimplnxCore/docs/ComputeVolumeFractionsFilter.md @@ -6,11 +6,17 @@ Statistics (Morphological) ## Description -This **Filter** determines the volume fraction of each **Ensemble**. The **Filter** counts the number of **Cells** belonging to each **Ensemble** and stores the number fraction. +This filter determines the volume fraction of each **Ensemble**. An **Ensemble** is a grouping of **Features** that share a common characteristic, such as a crystallographic phase. The filter counts the number of **Cells** belonging to each **Ensemble** and divides by the total number of **Cells**. -% Auto generated parameter table will be inserted here +On an **Image Geometry** every **Cell** has the same volume, so this count fraction is identical to the true volume fraction: dividing each **Ensemble**'s **Cell** count by the total **Cell** count gives the same result as dividing each **Ensemble**'s summed **Cell** volume by the total volume. The output is therefore a per-**Ensemble**, dimensionless volume fraction in the range [0, 1], where all of the fractions sum to 1. + +The result is written to the *Volume Fractions* array in the selected **Ensemble Attribute Matrix**. + +### Required Input Sources -## Example Pipelines +- **Cell Phases** -- a per-**Cell** integer array specifying which **Ensemble** each **Cell** belongs to. This array is typically read directly from EBSD data; the related feature-level array is produced by [Compute Feature Phases](ComputeFeaturePhasesFilter.md). + +% Auto generated parameter table will be inserted here ## License & Copyright diff --git a/src/Plugins/SimplnxCore/docs/ConcatenateDataArraysFilter.md b/src/Plugins/SimplnxCore/docs/ConcatenateDataArraysFilter.md index edabd3f966..f509fd2b79 100644 --- a/src/Plugins/SimplnxCore/docs/ConcatenateDataArraysFilter.md +++ b/src/Plugins/SimplnxCore/docs/ConcatenateDataArraysFilter.md @@ -14,6 +14,12 @@ This filter is designed to handle arrays of matching array types and component d **NOTE:** If you are wanting to instead combine data arrays into a multi-component array, please see the [Combine Attribute Arrays](CombineAttributeArraysFilter.md) filter. +For example, given two 3-component float arrays of 5 and 7 tuples respectively, the output is a 3-component float array of 12 tuples whose first 5 tuples are the first input and last 7 tuples are the second input. + +### Required Input Sources + +- **Input Data Arrays** -- two or more arrays sharing the same primitive type and the same component dimensions. + % Auto generated parameter table will be inserted here ## Example Pipelines diff --git a/src/Plugins/SimplnxCore/docs/ConditionalSetValueFilter.md b/src/Plugins/SimplnxCore/docs/ConditionalSetValueFilter.md index d7ecf3ce78..f2fc44f8a7 100644 --- a/src/Plugins/SimplnxCore/docs/ConditionalSetValueFilter.md +++ b/src/Plugins/SimplnxCore/docs/ConditionalSetValueFilter.md @@ -6,23 +6,42 @@ Core (Misc) ## Description -This **Filter** replaces values in a user specified **Attribute Array** with a user specified value a second boolean **Attribute Array** specifies, but only when **Use Conditional Mask** is *true*. For example, if the user entered a *Replace Value* of *5.5*, then for every occurence of *true* in the conditional boolean array, the selected **Attribute Array** would be changed to 5.5. If **Use Conditional Mask** is *false*, then **Value to Replace** will be searched for in the provided **Attribute Array** and all instances will be replaced. Below are the ranges for the values that can be entered for the different primitive types of arrays (for user reference). The selected **Attribute Array** must be a scalar array. - -### Primitive Data Types - -| Type | Size | Range | -|------------------|------|--------------------| -| Signed Integer | 8 bit |-128 to 127| -| Unsigned Integer | 8 bit |0 to 255| -| Signed Integer | 16 bit |-32,768 to 32,767| -| Unsigned Integer | 16 bit |0 to 65,535| -| Signed Integer | 32 bit |-2,147,483,648 to 2,147,483,647| -| Unsigned Integer | 32 bit |0 to 4,294,967,295| -| Signed Integer | 64 bit | 9,223,372,036,854,775,808 to 9,223,372,036,854,775,807| -| Unsigned Integer | 64 bit |0 to 18,446,744,073,709,551,615| -| Float | 32 bit | -3.4e+38 to -1.1e-38, 0.0, 1.1e-38 to 3.4e+38 (7 digits)| -| Double | 64 bit | -1.7e+308 to -2.2e-308, 0.0, 2.2e-308 to 1.7e+308 (15 digits)| -| Boolean | 8 bit |0 = false and any other value will be forced to 1 = true| +This **Filter** replaces selected values in a scalar **Attribute Array** with a user-specified value. The filter operates in one of two modes selected by the *Use Conditional Mask* parameter. + +### Mode 1 -- Conditional Mask (Use Conditional Mask = ON) + +A second boolean array (the *Conditional Mask*) of the same length picks which tuples to overwrite. Every tuple where the mask is *true* has its scalar value set to *Replace Value*; tuples where the mask is *false* are unchanged. + +Typical use case: replace cell values flagged by an upstream threshold (e.g., set all "bad" cells to 0). + +### Mode 2 -- Value Match (Use Conditional Mask = OFF) + +Every occurrence of *Value to Replace* in the target array is replaced with *Replace Value*. The Conditional Mask parameter is ignored. + +Typical use case: remap a specific sentinel value (e.g., turn every -1 into 0). + +### Numeric Type Compatibility + +The target array must be a **scalar** (single-component) array. *Replace Value* (and *Value to Replace* in Mode 2) are reinterpreted as the array's data type. The valid range for each primitive type: + +| Type | Size | Range | +|------|------|-------| +| Signed Integer | 8 bit | -128 to 127 | +| Unsigned Integer | 8 bit | 0 to 255 | +| Signed Integer | 16 bit | -32,768 to 32,767 | +| Unsigned Integer | 16 bit | 0 to 65,535 | +| Signed Integer | 32 bit | -2,147,483,648 to 2,147,483,647 | +| Unsigned Integer | 32 bit | 0 to 4,294,967,295 | +| Signed Integer | 64 bit | -9.2e18 to 9.2e18 | +| Unsigned Integer | 64 bit | 0 to 1.8e19 | +| Float | 32 bit | ±1.1e-38 to ±3.4e+38 (7 digits) | +| Double | 64 bit | ±2.2e-308 to ±1.7e+308 (15 digits) | +| Boolean | 8 bit | 0 = false, non-zero = true | + +### Required Input Sources + +- **Target Array** -- the scalar cell-level (or other tuple-level) array whose values will be overwritten. +- **Conditional Mask** (only when *Use Conditional Mask* is enabled) -- a boolean array with the same number of tuples; typically produced by [Multi-Threshold Objects](MultiThresholdObjectsFilter.md). % Auto generated parameter table will be inserted here diff --git a/src/Plugins/SimplnxCore/docs/ConvertColorToGrayScaleFilter.md b/src/Plugins/SimplnxCore/docs/ConvertColorToGrayScaleFilter.md index 6f9a905448..1b218367df 100644 --- a/src/Plugins/SimplnxCore/docs/ConvertColorToGrayScaleFilter.md +++ b/src/Plugins/SimplnxCore/docs/ConvertColorToGrayScaleFilter.md @@ -6,25 +6,34 @@ Processing (Image) ## Description -This **Filter** allows the user to select a *flattening* method for turning an array of RGB or RGBa values into grayscale values. +This **Filter** converts one or more color image arrays (3-component RGB or 4-component RGBA, uint8) into single-component grayscale image arrays using one of four standard flattening algorithms. Use this filter as a preprocessing step before any image-processing filter that expects single-channel intensity data. ### Conversion Algorithm -The *Conversion Algorithm* parameter provides the following choices: +The *Conversion Algorithm* parameter selects how the three (or four) color channels are combined into a single value: -- **Luminosity [0]**: A weighted average of RGB channels that accounts for human perception (more sensitive to green). Uses the BT709 formula by default: Red: 0.2125, Green: 0.7154, Blue: 0.0721. The user can set custom weightings. -- **Average [1]**: Computes a simple arithmetic average of R, G, and B channel values: (R + G + B) / 3. -- **Lightness [2]**: Averages the maximum and minimum channel values: (max(R, G, B) + min(R, G, B)) / 2. -- **SingleChannel [3]**: The user selects a specific R, G, or B channel to use directly as the grayscale values. +- **Luminosity [0]**: weighted average accounting for human perception (more sensitive to green). Default weights are the BT.709 standard: R=0.2125, G=0.7154, B=0.0721. The user may supply custom weights. +- **Average [1]**: simple arithmetic mean of the three channels: (R + G + B) / 3. +- **Lightness [2]**: average of the maximum and minimum channel values: (max(R, G, B) + min(R, G, B)) / 2. +- **SingleChannel [3]**: the user picks one channel (R, G, or B) and that channel's value is used directly. -The user can select 1 or more image data arrays which are assumed to be multi-component arrays of unsigned 8 bit values. The user can create a new AttributeMatrix if they want to store all the newly created arrays in a separate AttributeMatrix. +### Additional Standard Weights -### Additional GrayScale Conversions +Other widely-used weighting schemes (not built-in, but easy to supply as custom Luminosity weights): -The following are some additional accepted grayscale conversions +- **RMY Greyscale**: R=0.500, G=0.419, B=0.081 +- **YIQ / NTSC**: R=0.299, G=0.587, B=0.114 -+ RMY Greyscale: Red: 0.5 Green: 0.419 Blue: 0.081 -+ (YIQ/NTSC): Red: 0.299 Green: 0.587 Blue: 0.114 +### Input/Output Format + +- **Input arrays** must be uint8 with 3 components (RGB) or 4 components (RGBA). With RGBA input, the alpha channel is ignored. +- **Output arrays** are single-component uint8. + +Multiple input arrays can be processed in one filter pass; each produces its own output array. If *Output to New Attribute Matrix* is enabled, the new arrays are placed in a separate Attribute Matrix to keep them organized; otherwise they live alongside the originals. + +### Required Input Sources + +- **Input Image Arrays** -- 3- or 4-component uint8 arrays, typically produced by [ITK Import Image Stack](../ITKImageProcessing/ITKImportImageStackFilter.md) or another color-image reader. % Auto generated parameter table will be inserted here diff --git a/src/Plugins/SimplnxCore/docs/ConvertDataFilter.md b/src/Plugins/SimplnxCore/docs/ConvertDataFilter.md index ac99b56623..be86bac737 100644 --- a/src/Plugins/SimplnxCore/docs/ConvertDataFilter.md +++ b/src/Plugins/SimplnxCore/docs/ConvertDataFilter.md @@ -40,6 +40,15 @@ Down casting can have undefined behavior depending on the primitive types involv When converting data from signed values to unsigned values or vice-versa, there can also be undefined behavior. For example, if the user were to convert a signed 4 byte integer array to an unsigned 4 byte integer array and the input array has negative values, then the conversion rules are undefined and may differ from operating system to operating system. +### Related Filters + +- [Reshape Data Array](ReshapeDataArrayFilter.md) -- changes the tuple-dimensions interpretation of an array without converting its underlying data type. Use Reshape (not Convert) when you want to interpret existing bytes under a different shape. +- [Create Data Array](CreateDataArrayFilter.md) -- create a fresh array of the desired type and copy values into it manually. + +### Required Input Sources + +- **Input Array** -- the **Data Array** whose values will be cast to the new type. + % Auto generated parameter table will be inserted here ## Example Pipelines diff --git a/src/Plugins/SimplnxCore/docs/CopyDataObjectFilter.md b/src/Plugins/SimplnxCore/docs/CopyDataObjectFilter.md index 5e94261624..9a4f24e8af 100644 --- a/src/Plugins/SimplnxCore/docs/CopyDataObjectFilter.md +++ b/src/Plugins/SimplnxCore/docs/CopyDataObjectFilter.md @@ -19,7 +19,12 @@ Commonly used _BaseGroup_ children: See the DataStructure section of the reference manual for a complete hierarchy. -When the _Copy to New Parent_ is toggled true a new parameter will appear. This parameter, _Copied Parent Group_, allows for the selected arrays to all be copied into whatever data container you place here. +When *Copy to New Parent* is toggled on, a new parameter appears. This parameter, *Copied Parent Group*, lets the selected objects be copied into a different parent **DataGroup**, **Attribute Matrix**, or **Geometry** rather than alongside their originals. + +### Required Input Sources + +- **Objects to Copy** -- one or more existing **DataObjects** in the Data Structure. +- **Copied Parent Group** (only when *Copy to New Parent* is enabled) -- an existing parent container where the copies will be placed. % Auto generated parameter table will be inserted here diff --git a/src/Plugins/SimplnxCore/docs/CopyFeatureArrayToElementArrayFilter.md b/src/Plugins/SimplnxCore/docs/CopyFeatureArrayToElementArrayFilter.md index fa5affa7dd..ff840386b0 100644 --- a/src/Plugins/SimplnxCore/docs/CopyFeatureArrayToElementArrayFilter.md +++ b/src/Plugins/SimplnxCore/docs/CopyFeatureArrayToElementArrayFilter.md @@ -6,7 +6,19 @@ Core (Memory/Management) ## Description -This **Filter** copies the values associated with a **Feature** to all the **Elements** that belong to that **Feature**. Xmdf visualization files write only the **Element** attributes, so if the user wants to display a spatial map of a **Feature** level attribute, this **Filter** will transfer that information down to the **Element** level. +This **Filter** broadcasts a per-**Feature** value to every **Cell** (element) that belongs to that Feature, producing a new cell-level **Data Array** that has the same length as the Feature Ids array. Each cell receives the value of the Feature it belongs to. + +### When to Use This Filter + +- **Visualization.** Most exporters (Xdmf, VTK, ParaView state files) treat Cell-level arrays as the natural per-voxel scalar to render. Broadcasting a per-grain statistic (size, average misorientation, Schmid factor, biased flag, etc.) down to the Cell level produces a colorable map of that quantity. +- **Downstream filtering on cells.** When you want to threshold cells based on a Feature-level criterion (e.g., "keep cells whose parent grain is unbiased"), it is simpler to broadcast the Feature flag to all cells and then apply a cell-level threshold. + +The output is always the same data type and component shape as the source Feature array. + +### Required Input Sources + +- **Feature Array to Copy** -- any feature-level array; common sources include [Compute Feature Sizes](ComputeFeatureSizesFilter.md), [Compute Average Orientations](../OrientationAnalysis/ComputeAvgOrientationsFilter.md), [Compute Schmid Factors](../OrientationAnalysis/ComputeSchmidsFilter.md), or a custom flag from [Compute Biased Features](ComputeBiasedFeaturesFilter.md) / [Compute Surface Features](ComputeSurfaceFeaturesFilter.md). +- **Cell Feature Ids** -- produced by a segmentation filter such as [Segment Features (Misorientation)](../OrientationAnalysis/EBSDSegmentFeaturesFilter.md) or [Segment Features (Scalar)](ScalarSegmentFeaturesFilter.md). % Auto generated parameter table will be inserted here diff --git a/src/Plugins/SimplnxCore/docs/CreateAMScanPathsFilter.md b/src/Plugins/SimplnxCore/docs/CreateAMScanPathsFilter.md index 0046971cc4..09e4283984 100644 --- a/src/Plugins/SimplnxCore/docs/CreateAMScanPathsFilter.md +++ b/src/Plugins/SimplnxCore/docs/CreateAMScanPathsFilter.md @@ -6,7 +6,16 @@ Core (Geometry/Processing) ## Description -Given an input **Edge Geometry**, hatch spacing, hatch length, and hatch rotation angle, this **Filter** will generate an **Edge Geometry** representing the additive manufacturing scan paths along with arrays containing region ids and slice ids for each scan path. The "SliceTriangleGeometry" filter is typically used before this filter to generate the proper edge geometry. +Given an input **Edge Geometry**, hatch spacing, hatch length, and hatch rotation angle, this **Filter** will generate an **Edge Geometry** representing the additive manufacturing scan paths along with arrays containing region ids and slice ids for each scan path. + +### Units + +- **Hatch Spacing** and **Hatch Length** are lengths expressed in the same coordinate units as the input **Edge Geometry** (e.g., millimeters if the slicing was done in millimeters). They are not dimensionless and not pixels. +- **Hatch Rotation Angle** is specified in **degrees**. It is the per-slice rotation applied to the hatch direction. + +### Required Input Sources + +- An input **Edge Geometry** together with its per-edge **Slice Ids** and **Region Ids** arrays. These are typically produced by the [Slice Triangle Geometry](SliceTriangleGeometryFilter.md) filter, which slices a surface-mesh **Triangle Geometry** into the edge geometry consumed here. ![](Images/CreateAMScanVectors_5.png) diff --git a/src/Plugins/SimplnxCore/docs/CreateAttributeMatrixFilter.md b/src/Plugins/SimplnxCore/docs/CreateAttributeMatrixFilter.md index a4a3ac885f..3298120e1e 100644 --- a/src/Plugins/SimplnxCore/docs/CreateAttributeMatrixFilter.md +++ b/src/Plugins/SimplnxCore/docs/CreateAttributeMatrixFilter.md @@ -6,11 +6,29 @@ Core (Generation) ## Description -This **Filter** creates a new **Attribute Matrix**. +This **Filter** creates a new empty **Attribute Matrix** at a user-specified location in the **Data Structure**. The matrix is created with a user-specified set of *tuple dimensions* but contains no arrays initially; subsequent filters can add arrays to it. -### Example Usage +### What is an Attribute Matrix? -If you wanted to create an **Attribute Matrix** to represent a 3D volume where the dimensions of the 3 orthogonal axesare X=3, y=4 and Z=5, then the *Tuple Dimensions* would have a value of (3, 4, 5). +An **Attribute Matrix** is a container for **Data Arrays** that share the same *number of tuples* and the same *tuple shape*. All arrays inside one Attribute Matrix represent values "at the same set of points" -- for example, all per-cell arrays of an Image Geometry live in a single Cell Attribute Matrix, all per-feature arrays for a segmented dataset live in a single Feature Attribute Matrix, and all per-ensemble (phase) arrays live in an Ensemble Attribute Matrix. + +This shared-tuple-shape contract is enforced: any array added to an existing Attribute Matrix must match the matrix's tuple dimensions. Use an Attribute Matrix when the values you are grouping are all parallel arrays over the same domain. + +### When to Use This Filter + +- Pre-building the destination for a future filter that creates new feature-level or ensemble-level arrays. +- Creating a custom Attribute Matrix for organizational purposes (e.g., grouping all "computed" arrays separately from the "raw" arrays in the same Cell-level domain). +- Restructuring imported data so that arrays sharing a common dimension end up in the same matrix. + +For containers that hold heterogeneous data (arrays of different sizes, geometries, sub-groups), use [Create Data Group](CreateDataGroupFilter.md) instead. + +### Tuple Dimensions + +For a 3D volume with axes X=3, Y=4, Z=5, the *Tuple Dimensions* are (3, 4, 5). For a 1D feature-list with 100 features, the tuple dimensions are (100). The product of all dimensions equals the total number of tuples that any array added to this matrix must have. + +### Required Input Sources + +- **Parent Data Object Path** -- an existing **DataGroup** or **Geometry** under which the new Attribute Matrix will be created. Typically the output of [Create Image Geometry](CreateImageGeometryFilter.md), [Create Geometry](CreateGeometryFilter.md), or [Create Data Group](CreateDataGroupFilter.md). % Auto generated parameter table will be inserted here diff --git a/src/Plugins/SimplnxCore/docs/CreateColorMapFilter.md b/src/Plugins/SimplnxCore/docs/CreateColorMapFilter.md index 65469ab752..70cf8f46e5 100644 --- a/src/Plugins/SimplnxCore/docs/CreateColorMapFilter.md +++ b/src/Plugins/SimplnxCore/docs/CreateColorMapFilter.md @@ -1,5 +1,9 @@ # Create Color Map +## Group (Subgroup) + +Core (Image) + ## Description This **Filter** generates a color table array for a given 1-component input array. Each element of the input array @@ -8,9 +12,14 @@ is normalized and converted to a color based on where the value falls in the spe The user can apply an optional data mask and then set the RGB values (0-255) that will be used if the data mask has a FALSE value. +### Required Input Sources + +- A single-component (scalar) **Data Array** to colorize. This can be any scalar array already present in the **DataStructure**, for example a Confidence Index or Image Quality array read by an EBSD reader, a Feature ID array, or any computed scalar metric. +- (Optional) A **Mask Array** (boolean or uint8) used to flag elements as good/bad; flagged-FALSE elements receive the user-specified RGB color. + ## Preset Values -These are the valid preset strings that can be used. +These are the valid preset strings that can be used. This table is maintained by hand and lists the presets shipped with DREAM3D-NX along with a swatch of each color scheme. | Preset Name | Color Space | Example | |-------------|-------------|---------| @@ -135,11 +144,9 @@ These are the valid preset strings that can be used. % Auto generated parameter table will be inserted here -## Example Pipelines - ## License & Copyright -Please see the description file distributed with this plugin. +Please see the description file distributed with this **Plugin** ## DREAM3D-NX Help diff --git a/src/Plugins/SimplnxCore/docs/CreateDataArrayAdvancedFilter.md b/src/Plugins/SimplnxCore/docs/CreateDataArrayAdvancedFilter.md index 48a0ee1553..1d00a19811 100644 --- a/src/Plugins/SimplnxCore/docs/CreateDataArrayAdvancedFilter.md +++ b/src/Plugins/SimplnxCore/docs/CreateDataArrayAdvancedFilter.md @@ -68,7 +68,13 @@ If the parent is **NOT an Attribute Matrix**, then the user ***MUST*** set the t | Double | 64 bit | -1.7e+308 to -2.2e-308, 0.0, 2.2e-308 to 1.7e+308 (15 digits)| | Boolean | 8 bit |0 = false and any other value will be forced to 1 = true| -The component dimensions should multiply together into a total number of components equal to at least 1. Examples of *Component Dimensions* would be [3] for an RGB Image, [1] for a gray scale image, [1] for a scalar array, [4] for a quaternions array, [10x5] for an array with 10x5 grids at each tuple, etc. All values of the array will be initialized using the chosen initialization option. +The component dimensions should multiply together into a total number of components of at least 1. Examples of *Component Dimensions* would be [3] for an RGB image, [1] for a grayscale image or scalar array, [4] for a quaternions array, [3, 3] for a 3×3 tensor at each tuple, etc. All values of the array are initialized using the chosen initialization option. + +For the simpler case of a single-component-dimension array (most data), use [Create Data Array](CreateDataArrayFilter.md). This advanced version is required only when the component shape itself has more than one dimension. + +### Required Input Sources + +None. The array is created from user-supplied parameters; when the parent is an Attribute Matrix, the tuple dimensions are inherited from it. % Auto generated parameter table will be inserted here diff --git a/src/Plugins/SimplnxCore/docs/CreateDataArrayFilter.md b/src/Plugins/SimplnxCore/docs/CreateDataArrayFilter.md index 05150bfd51..967cbbeb27 100644 --- a/src/Plugins/SimplnxCore/docs/CreateDataArrayFilter.md +++ b/src/Plugins/SimplnxCore/docs/CreateDataArrayFilter.md @@ -52,8 +52,13 @@ If the parent is **NOT an Attribute Matrix**, then the user ***MUST*** set the t | Double | 64 bit | -1.7e+308 to -2.2e-308, 0.0, 2.2e-308 to 1.7e+308 (15 digits)| | Boolean | 8 bit |0 = false and any other value will be forced to 1 = true| -The number of components should be at least 1. Examples of *Number of Components* would be 3 for an RGB Image, 1 for a gray scale image, 1 for a scalar array, 4 for a quaternions array, etc. All values of the array will be initialized to the user set value. The initialization value text box -must have a user entry or the default value *0* will be used. +The number of components should be at least 1. Examples of *Number of Components* would be 3 for an RGB image, 1 for a grayscale image or scalar array, 4 for a quaternions array, etc. All values of the array are initialized to the user-set value. The initialization value text box must have a user entry or the default value *0* will be used. + +This filter creates an array with a **single component dimension** (e.g., (1), (3), (4)). For arrays with multi-dimensional component shapes such as a 3×3 stiffness tensor, use [Create Data Array (Advanced)](CreateDataArrayAdvancedFilter.md) instead. + +### Required Input Sources + +None. The array is created from user-supplied parameters; when the parent is an Attribute Matrix, the tuple dimensions are inherited from it. % Auto generated parameter table will be inserted here diff --git a/src/Plugins/SimplnxCore/docs/CreateDataGroupFilter.md b/src/Plugins/SimplnxCore/docs/CreateDataGroupFilter.md index 18cb01ed8e..552224a95a 100644 --- a/src/Plugins/SimplnxCore/docs/CreateDataGroupFilter.md +++ b/src/Plugins/SimplnxCore/docs/CreateDataGroupFilter.md @@ -6,9 +6,17 @@ Core (Generation) ## Description -This **Filter** creates a new **DataGroup**. +This **Filter** creates a new empty **DataGroup** at a user-specified location in the **Data Structure**. The new DataGroup contains nothing initially; subsequent filters can add child objects to it. -Unlike _AttributeMatrix_, _DataGroup_s are capable of holding any _DataObject_ of any size. +### What is a DataGroup? + +A **DataGroup** is a general-purpose container. Unlike an **Attribute Matrix**, a DataGroup can hold *any* DataObject of *any size* -- geometries, attribute matrices, arrays of varying sizes, even other DataGroups. There is no shared-tuple-shape contract. + +Use a DataGroup when you need to organize heterogeneous data, such as a logical grouping of unrelated arrays or geometries. Use [Create Attribute Matrix](CreateAttributeMatrixFilter.md) instead when all the arrays you are grouping share a common tuple shape and represent values over the same domain. + +### Required Input Sources + +- **Parent Data Object Path** -- an existing **DataGroup**, **Attribute Matrix**, or **Geometry** under which the new DataGroup will be created. The top-level of the Data Structure can also be selected. % Auto generated parameter table will be inserted here diff --git a/src/Plugins/SimplnxCore/docs/CreateFeatureArrayFromElementArrayFilter.md b/src/Plugins/SimplnxCore/docs/CreateFeatureArrayFromElementArrayFilter.md index 096c27d794..77021730c0 100644 --- a/src/Plugins/SimplnxCore/docs/CreateFeatureArrayFromElementArrayFilter.md +++ b/src/Plugins/SimplnxCore/docs/CreateFeatureArrayFromElementArrayFilter.md @@ -6,7 +6,26 @@ Core (Memory/Management) ## Description -This **Filter** copies all the associated **Element** data of a selected **Element Array** to the **Feature** to which the **Elements** belong. The value stored for each **Feature** will be the value of the *last element copied*. +This **Filter** collapses a per-**Cell** (element) array down to a per-**Feature** array by storing one value per Feature. The value stored for each Feature is the **last cell value visited** during the scan -- not an average or majority vote. + +## WARNING: Lossy for Within-Feature Variation + +If the source cell array varies across cells *within* the same Feature, almost all of those values are discarded -- only the last cell scanned wins. **This filter is the correct choice only when every cell in a given Feature is guaranteed to hold the same value** (e.g., a cell-level phase array where every cell of a grain shares the same phase). + +For situations where you want a meaningful per-Feature summary (mean, max, min, median, etc.) of a cell-level array, use: + +- [Compute Array Statistics](ComputeArrayStatisticsFilter.md) -- computes mean, std dev, min, max, etc. per Feature. +- [Compute Average Orientations](../OrientationAnalysis/ComputeAvgOrientationsFilter.md) -- per-Feature average orientation specifically. + +### When This Filter Is Appropriate + +- Copying a uniform-within-feature cell-level array (cell phases, cell ensemble labels) to its Feature-level equivalent. +- Quick "any one example" extraction for diagnostic purposes. + +### Required Input Sources + +- **Cell Array to Copy** -- a cell-level array whose values are uniform within each Feature. +- **Cell Feature Ids** -- produced by a segmentation filter such as [Segment Features (Misorientation)](../OrientationAnalysis/EBSDSegmentFeaturesFilter.md). % Auto generated parameter table will be inserted here diff --git a/src/Plugins/SimplnxCore/docs/CreateGeometryFilter.md b/src/Plugins/SimplnxCore/docs/CreateGeometryFilter.md index e310c729e9..52b2a0bd37 100644 --- a/src/Plugins/SimplnxCore/docs/CreateGeometryFilter.md +++ b/src/Plugins/SimplnxCore/docs/CreateGeometryFilter.md @@ -6,141 +6,90 @@ DREAM3D Review (Geometry) ## Description -This **Filter** creates a **Geometry** object and the necessary **Element Attribute Matrices** on which to store **Attribute Arrays** and **Element Attribute Arrays** which define the geometry. The type of **Attribute Matrices** and **Attribute Arrays** created depends on the kind of **Geometry** being created: +This **Filter** creates a new **Geometry** object of one of eight supported types, together with the **Attribute Matrices** and **Attribute Arrays** needed to define its topology. Use this filter when you have raw coordinate/connectivity data (typically from an external file or an upstream filter) and need to wrap it in a DREAM3D-NX geometry object. -| Type | Attribute Matrices | Attribute Arrays | -|------------------|--------------------|-------------| -| Image | Cell | -| Rectilinear Grid | Cell | x, y, & z Bounds | -| Vertex | Vertex | Vertices | -| Edge | Vertex + Edge | Vertices + Edges | -| Triangle | Vertex + Face | Vertices + Faces | -| Quadrilateral | Vertex + Face | Vertices + Faces | -| Tetrahedral | Vertex + Cell | Vertices + Cells | -| Hexahedral | Vertex + Cell | Vertices + Cells | +For grid-type geometries (Image, Rectilinear Grid), the topology is defined entirely by numeric parameters (dimensions, spacing, origin, or bounds arrays). For mesh-type geometries (Vertex, Edge, Triangle, Quadrilateral, Tetrahedral, Hexahedral), the user supplies a *shared vertex list* and an *element connectivity list* as input arrays. -### Understanding Geometries +### Supported Geometry Types -This **Filter** requires the user to enter information that defines the topological information for the chosen **Geometry**. Choosing valid information for a given **Geometry** necessitates an understanding of how **DREAM3D-NX** stores and interprets this information. A general overview of the data model used in **DREAM3D-NX** may be found here. More specific information for **Geometry** objects is provided below. +| Type | Topology | Element Type | Required Inputs | +|---|---|---|---| +| Image | Regular voxel grid | Cell (voxel) | Dimensions + Spacing + Origin | +| Rectilinear Grid | Variable-spacing grid | Cell | x/y/z Bounds arrays | +| Vertex | Point cloud | Vertex | Vertex coordinates | +| Edge | Line mesh | Edge (2 vertices) | Vertex list + Edge list | +| Triangle | Surface mesh | Face (3 vertices) | Vertex list + Triangle list | +| Quadrilateral | Surface mesh | Face (4 vertices) | Vertex list + Quad list | +| Tetrahedral | Volume mesh | Cell (4 vertices) | Vertex list + Tet list | +| Hexahedral | Volume mesh | Cell (8 vertices) | Vertex list + Hex list | -#### Grid Geometries +### Grid Geometries -##### Image +**Image Geometry** is a *regular, rectilinear grid* defined by three vectors of three numbers each: dimensions, spacing, and origin. -An **Image Geometry** is a *grid-like* **Geometry**, and is the simplest and most widely used of the basic **Geometry** types. An **Image Geometry** is a *regular, rectilinear grid*; if the *dimenionality* of the image is *d*, then only *3*d* numbers are needed to completely define the **Geometry**: three *d*-vectors for the *dimensions*, *origin*, and *spacing*. +- **Dimensions** -- grid extents stored as unsigned 64-bit integers. Dimensions are **0-based**, so a dimension of 10 has extents 0-9. No dimension may be zero or negative. +- **Spacing** -- physical distance between grid planes along each axis, stored as 32-bit floats. Units match whatever the source data uses (e.g., microns per voxel). Spacing must be positive and non-zero. (Older docs called this *resolution*; *spacing* is preferred because *resolution* is ambiguous.) +- **Origin** -- physical location of the bottom-left grid point in the geometry's coordinate system. Stored as 32-bit floats. No value restriction. -- Dimensions define the extents of the grid. Stored as unsigned 64 bit integers. The dimensions are also known as the **extents** and are *zero* based thus a dimension with a value of 10 has extents from 0-9. -- Spacing defines the physical distance between grid planes for each orthogonal direction (constant along a given direction). Stored as 32 bit floating point numbers. Spacing has been known in the past as *resolution* but this term is ambiguous so spacing is used. A value of "microns per pixel" is a good example of "Spacing" units. -- Origin defines the physical location of the *bottom left* grid point in *d*-dimensional space. Stored as 32 bit floating point numbers. +All Image Geometries are stored as 3D; a 2D image is represented by setting one dimension to exactly 1, producing a plane. Downstream filters that care (e.g., *Compute Feature Shapes*) detect this automatically. -All **Image Geometries** in **DREAM3D-NX** are defined as 3D images. A 2D image is assumed when one of the dimension values is exactly 1; the 2D image is then considered a plane. Most **DREAM3D-NX** **Filters** will properly take account for the **Image** dimension if it matters (for example, the Find Feature Shapes **Filter** accounts for whether the **Image** is 2D or 3D when computing values such as *aspect ratios* or *axis Euler angles*). No dimension may be negative or equal to 0. The spacing must be a positive, non-zero value. The Origin has no value restrictions. This **Filter** requires the user to enter the nine values for the dimenions, origin, and spacing. +**Rectilinear Grid Geometry** is similar to an Image Geometry but allows variable spacing along each axis. It is defined by three monotonically-increasing 32-bit float bounds arrays (x, y, z). The spacing between any two adjacent planes is the difference between consecutive entries in the bounds array. No origin is needed -- the bounds arrays explicitly encode position. -Since all **Image Geometries** are implicitly 3D (even when plane-like), the fundamental building-block of an image is a *voxel*, which is a 3D object; therefore, the basic **Element** type for an **Image Geometry** is **Cell**. **Attribute Arrays** associated with **Image Cells** are assumed to raster *x-y-z*, fastest to slowest. +### Unstructured (Mesh) Geometries -##### Rectilinear Grid +Mesh geometries are defined by a **shared vertex list** (a 3-component float array of vertex coordinates) plus an **element connectivity list** (a multi-component unsigned 64-bit integer array, where each tuple is the list of vertex IDs that make up one element). -A **Rectilinear Grid Geometry** is a *grid-like* **Geometry**. Similar to an **Image Geometry**, a **Rectilinear Grid Geometry** has grid extents (dimensions), but is allowed to have variable *spacing* along each orthogonal direction. The **Geometry** then requires a total of (xdim + 1) + (ydim + 1) + (zdim + 1) numbers to define the topology. The values are stored in three separate arrays termed the *x bounds*, *y bounds*, and *z bounds*. These bounds arrays store the spatial location of all the planes along a given orthogonal direction. The spacing for a given plane (equivalent to the spacing for an **Image Geometry**) is then the difference between two of these contiguous array values. An origin does not need to be defined for a **Rectilinear Grid Geometry**, since the grid's location in space is explicitly encoded in its bounds arrays. This **Filter** requires the user to select **Attribute Arrays** that define the three bounds arrays. These arrays must be *single component, 32-bit float* arrays. Additionally, the values for each of the bounds arrays must be *strictly increasing*, which guarantees that computing the spacing for a given plane yields a postive value. +**Shared vertex** means a vertex used by multiple elements appears only once in the vertex list. For example, two quadrilaterals sharing one edge have 6 unique vertices (not 8). Element IDs are always **0-based**. -A **Rectilinear Grid Geometry** may be defined as 2D; the associated bounds array for the plane dimension is then exactly two. No bounds arrays may have less than two values. Since all **Rectilinear Grid Geometries** are implicitly 3D (even when plane-like), the fundamental building-block of an image is a *voxel*, which is a 3D object; therefore, the basic **Element** type for an **Image Geometry** is **Cell**. **Attribute Arrays** associated with **Rectilinear Grid Cells** are assumed to raster *x-y-z*, fastest to slowest. +**Element winding** matters for surface meshes. By convention, vertex order in each element tuple follows the **right-hand rule** -- when fingers curl in the order of the vertices, the thumb points in the direction of the element's surface normal. For tetrahedra, the first three vertices define the base; their winding by the right-hand rule defines a normal pointing toward the fourth vertex. Consistent winding makes tetrahedron volume *signed*, which lets downstream filters detect inverted elements. -#### Unstructured and Mesh-Like Geometries +The shared-list scheme is space-efficient and supports *nonmanifold* meshes (e.g., triangle meshes where more than two triangles share an edge, which occurs at triple lines and quadruple points in polycrystalline surface meshes). Its downside: computing adjacency (e.g., "what elements share this vertex?") requires iterating the whole mesh. -##### Vertex - -A **Vertex Geometry** is an *unstructured* **Geometry**. An unstructured **Geometry** requires explicit definition of point coordinates. Sometimes referred to as a *point cloud*, a **Vertex Geometry** is simply a collection of points. Defining this topology requires a total number of values equal to *d* times the total number of points, where *d* is the dimensionality of the point cloud; within **DREAM3D-NX**, *d* is always taken to be three. The point coordinates are stored as *32-bit floats*; no other range restrictions are enforced. This **Filter** requires the user to select an **Attribute Array** that defines these point coordinates. The array must have *three components* and consist of *32-bit floats*. The number of *tuples* in the array defines the number of vertices in the resulting **Vertex Geometry**. - -The fundamental **Element** type of a **Vertex Geometry** is *vertices*. Data stored in a **Vertex Attribute Matrix** is ordered according to **Vertex** *Ids*. Therefore, the nth tuple in the supplied **Vertex** list corresponds to the data stored in the nth column of the **Vertex Attribute Matrix**. By convetion, **Vertex** Ids are *zero indexed*. - -##### Mesh-Like Geometries - -The following **Geometries** are considered *mesh-like*, and all share similar features concerning their storage and interpretation. A mesh-like **Geometry** is an unstructured **Geometry** that additionally requires explicit definition of the connectivity of its **Elements** and its **Vertices**. The **Element** type defines the kind of **Geometry** and the number of **Vertices** needed to define that **Element**: - -| Name | Element Type | Number of Vertices Per Element | -|------------------|--------------------|--------------------| -| Edge | line | 2 | -| Triangle | triangle | 3 | -| Quadrilateral | quadrilateral | 4 | -| Tetrahedral | tetrahedron | 4 | -| Hexahedral | hexahedron | 8 | - -The storage scheme adopted by **DREAM3D-NX** requires at least two arrays to define mesh-like **Geometries**: a list of **Vertices** (i.e., the vertex coordinates) and the **Element** connectivities (i.e., which vertices belong to a given **Element**). To maintain simplicity, flexibility, and small memory overhead, **DREAM3D-NX** uses the concept of *shared vertex lists*. In this paradigm, the vertex coordinates are stored only once per *unique* vertex. Consider a **Quadrilateral Geometry** that consists of just two squares that share one side. In this example, there are exactly *six* unique vertices. The **Attribute Array** that defines the coordinates of these **Vertices** would then have six *tuples*, with three values at each tuple (the x, y, and z positions of that **Vertex**). Writing each tuple on one line, the array could look like this: - - 0.0 0.0 0.0 // Vertex Id 0 - 1.0 0.0 0.0 // Vertex Id 1 - 0.0 1.0 0.0 // Vertex Id 2 - 1.0 1.0 0.0 // Vertex Id 3 - 2.0 0.0 0.0 // Vertex Id 4 - 2.0 1.0 0.0 // Vertex Id 5 - -**Element** connectivities are stored in **Attribute Arrays** that have a number of tuples equal to the total number of **Elements**, with a number of components at each tuple equal to the number of vertices per element. In this example, a quadrilateral list would have two tuples, with four values stored at each tuple (the four vertex Ids that define that quadrilateral). When defining **Elements**, the order in which the **Vertex** Ids are listed, called the *winding*, is important, since this ordering defines the direction of the normal. By convention, the *right hand rule* used. Thus, given the above vertex positions, the following list of **Vertex** Ids defines two quadrilaterals whose normals point along the positive z direction: - - 0 1 3 2 // Quad Id 0 - 1 4 5 3 // Quad Id 1 - -Creating any mesh-like **Geometry** requires the user to supply two arrays: one that defines the vertex coordinates (the *shared vertex list*), which is a three component array of floats; and one that defines the **Element** connectivities, which is a n-component array (where n is the number of vertices per element) of *unsigned 64-bit integers*. Note that any **Element** Id values (**Vertex** or otherwise) are *zero indexed*. - -The shared list schema for mesh storage has the benefit of being space efficient, time efficient when iterating in sequence over vertices or elements, and capable of storing *nonmanifold* meshes. An example of a nonmanifold mesh is a **Triangle Geometry** that has more than two triangles sharing the same edge. This specific example of nonmanifold meshes occurs frequently in **DREAM3D-NX** surface meshes of polycrystals, where many nonmanifold entities may exist (i.e., triple lines and quad points). A significant downside of shared lists is that computing adjacency information, such as the neighbors of a given element or the elements that share a vertex, requires iterating over the entire **Geometry**; other mesh data structures avoid this limitation. Additionally, since the lists are stored as **Attribute Arrays**, which hold information contiguously in memory, adding or removing vertices or elements is tedious and potentially slow. - -Note that although the default interpretation of lists that define mesh-like **Geometries** is shared, no undefined behavior should be observed if the information is not stored shared (i.e., if the same **Vertex** is stored more than once with a different Id). Additionally, not all **Vertices** are required to be associated with an **Element**. The primary requirement is that the largest **Vertex** Ids listed in the **Element** list must not be larger than the total number of **Vertices**. - -##### Edge - -An **Edge Geometry** is the simplest *mesh-like* **Geometry**, consisting of a collection of edges connecting two vertices. Creating an **Edge Geometry** requires supplying a shared **Vertex** list and an **Edge** list. - -##### Triangle - -A **Triangle Geometry** is a *mesh-like* **Geometry**, consisting of a collection of triangles connecting three vertices; it is a type of *surface mesh*. Creating a **Triangle Geometry** requires supplying a shared **Vertex** list and a **Triangle** list. - -##### Quadrilateral - -A **Quadrilateral Geometry** is a *mesh-like* **Geometry**, consisting of a collection of quadrilaterals connecting four vertices; it is a type of *surface mesh*. Creating a **Quadrilateral Geometry** requires supplying a shared **Vertex** list and a **Quadrilateral** list. - -##### Tetrahedral - -A **Tetrahedral Geometry** is a *mesh-like* **Geometry**, consisting of a collection of tetrahedra connecting four vertices; it is a type of *volume mesh*. Creating a **Tetrahedral Geometry** requires supplying a shared **Vertex** list and a **Tetrahedral** list. The winding that define tetrahedra require one additional convention to complement the right hand rule. By convention, the first three vertices define the tetrahedra *base*; the winding of these vertices by the right hand rule defines a normal that points *towards the fourth vertex*. This convention is useful since applying it consistently allows for the volume of the tetrahedra to be *signed*, which is important for determining if a tetrahedron is "inverted". - -##### Hexahedral - -A **Hexahedral Geometry** is a *mesh-like* **Geometry**, consisting of a collection of hexahedra connecting eight vertices; it is a type of *volume mesh*. Creating a **Hexahedral Geometry** requires supplying a shared **Vertex** list and a **Hexahedral** list. - -### Defining Geometries with Attribute Arrays +### Array Handling - For **Geometries** that require the selection of **Attribute Arrays** (all **Geometries** except **Image**), the arrays will be *copied* to create the new **Geometry**. Therefore, any operations on the original array will not affect the topology of the **Geometry**, and any geometric operations will not affect the original array. This behavior can be adjusted in the filter by using the *Array Handling* boolean. +The *Array Handling* parameter controls what happens to the input arrays passed to this filter: -### Array Handling +- **Copy Attribute Arrays [0]**: input arrays are copied into the new geometry. Originals are left in place. +- **Move Attribute Arrays [1]**: input arrays are moved into the new geometry and removed from their original location. Saves memory when the original copies are no longer needed. -The *Array Handling* parameter controls how the input **Attribute Arrays** (vertex list, element connectivity, etc.) are transferred to the new **Geometry**: +### Validation -- **Copy Attribute Arrays [0]**: The input arrays are copied into the new **Geometry**. The original arrays remain in the **Data Structure** and are unaffected by any subsequent geometric operations. -- **Move Attribute Arrays [1]**: The input arrays are moved into the new **Geometry**. The original array paths are removed from the **Data Structure**, reducing memory usage when the originals are no longer needed. +The filter validates that the supplied arrays "make sense" for the chosen geometry type (e.g., bounds arrays for a Rectilinear Grid have at least 2 values; no vertex ID in a connectivity list exceeds the vertex count). Checks that require reading actual values run at execute time. By default these checks produce warnings; enable *Treat Geometry Warnings as Errors* to make them fail the pipeline. -This **Filter** will validate that the arrays selected to define a **Geometry** "make sense", given the above information for how **Geometries** are stored in **DREAM3D-NX** (for example, no dimension for an **Image** may be less than or equal to zero, no bounds arrays for a **Rectilinear Grid** may have less than two values, and no **Vertex** Ids stored in a shared **Element** list may be larger than the total number of **Vertices** in the shared **Vertex** list). The checks that require accessing the actual array values (as opposed to just descriptive information) will be performed at run time. By default, these checks will only produce warnings, allowing the **Pipeline** to continue; the user may opt to change these warnings to errors by selecting the *Treat Geometry Warnings as Errors* option. +### Example: Importing a Tetrahedral Mesh from Text Files -Generally, arrays used by this **Filter** to create **Geometries** must be supplied by the user. One method to import geometric information into **DREAM3D-NX** is to read the information in from a text file using the Import ASCII Data **Filter**. For example, imagine having an external simulation code that creates a tetrahedral volume mesh with two associated field values, one stored on the mesh vertices and one stored on the mesh tetrahedra. It is possible to import this mesh and corresponding information into **DREAM3D-NX** for further analysis. The user must supply at least two files: one that contains the vertex information and one that contains the tetrahedra information. The vertex file would contain, on each line, the three coordinates of the vertex and the value of the field array on that vertex. It may, for example, look like this: +Suppose an external simulation produces a tetrahedral mesh with one vertex-level value and one tet-level value, stored across two text files. The vertex file looks like: - # Some header information - # Some more header information + # header + # header x_pos y_pos z_pos value 1.235 2.323 1.562 465.2 -12.3 3.456 2.323 567.4 3.450 9.782 6.567 120.2 ..... -In this above example, the vertex information begins on line 4; thus, line 4 defines **Vertex** Id 0, line 5 defines **Vertex** Id 1, etc. Similarly, a file containing information about tetrahedra is needed: +And the tetrahedra file: - # Some header information - # Some more header information + # header + # header vert_0 vert_1 vert_2 vert_3 value 1 2 0 3 12.42 2 7 5 4 14.71 - 6 9 7 8 16.78 - ..... + ..... + +The workflow is: - Again, the real information begins on line 4, which defines the connectivity for **Tetrahedra** Id 0. These Id values refer to the **Vertex** Ids from the first file (for example, a **Vertex** Id of 0 corresponds to the information on line 4 of the first file). Remember to consider the *right hand rule* when dealing with mesh-like **Geometries**, as this will affect the **Vertex** ordering! +1. Create an empty Data Container. +2. Run [Read Text Data Array](ReadTextDataArrayFilter.md) (or [Read CSV File](ReadCSVFileFilter.md)) once for the vertex file (float32) and once for the tetrahedra file (int64). +3. Use [Combine Attribute Arrays](CombineAttributeArraysFilter.md) to combine the three vertex-position components into one 3-component array and the four tetrahedra vertex-ID components into one 4-component array. +4. Run this **Create Geometry** filter, selecting Tetrahedral type and pointing it at the combined arrays. +5. Use [Move Data](MoveDataFilter.md) to move the per-vertex and per-tetrahedron value arrays into the new geometry's Vertex and Cell attribute matrices. - Assuming it is possible to get the mesh into files similar to the above ones, it is straightforward to import the information into **DREAM3D-NX**. First, create an emtpy Data Container. Then, run the Import ASCII Data **Filter** for the vertex file. In the above example, line 3 could be used as headers to define the array names (remember that **Vertex** positions must be of type *float*!). Allow the reader wizard to create an **Attribute Matrix** in which to store the arrays. Repeat the process with another Import ASCII Data **Filter** to read the tetrahedra information (remember in this case that Id values must be of type *int64\_t*!). At this point, there will be two **Attribute Matrices** in the **Data Container**, one with 4 arrays (the **Vertex** information) and one with 5 arrays (the **Tetrahedra** information). The Create Geometry **Filter** wants the **Vertex** list as a three component array and the **Tetrahedra** list as a four component array. To combine the individual arrays into ones of the proper component dimension, run the Combine Attribute Arrays **Filter**. At this point, the Create Geometry **Filter** may be used to create a **Tetrahedral Geometry** using the combined arrays. After this **Filter**, the Move Data **Filter** may be used to move the arrays that represent the values stored on the **Vertices** and **Tetrahedra** into the created **Vertex** and **Cell Attribute Matrices**. +### Required Input Sources - When creating **Geometries**, remember to consider all the various rules for how a **Geometry** is stored and interpreted. In particular, remeber that **Element** Ids are always zero indexed, mesh-like **Geometries** obey the *right hand rule* for windings and normal directions, and **Element** lists are by default considered *shared*. Note that although the storage scheme used by **DREAM3D-NX** (shared lists) is highly generic, some **Filters** may assume that the **Geometry** is reasonably *well formed*. +- **Vertex / Connectivity Arrays** (mesh geometries) -- raw arrays supplied by the user, typically imported from external files via [Read Text Data Array](ReadTextDataArrayFilter.md) or [Read CSV File](ReadCSVFileFilter.md) and combined into the required component shape via [Combine Attribute Arrays](CombineAttributeArraysFilter.md). +- **Bounds Arrays** (Rectilinear Grid only) -- single-component float32 arrays, strictly monotonically increasing. +- **Image / Rectilinear Grid** parameters -- supplied directly by the user; no upstream filter needed. % Auto generated parameter table will be inserted here diff --git a/src/Plugins/SimplnxCore/docs/CreateImageGeometryFilter.md b/src/Plugins/SimplnxCore/docs/CreateImageGeometryFilter.md index 027f2d8d7b..e37a51b4ea 100644 --- a/src/Plugins/SimplnxCore/docs/CreateImageGeometryFilter.md +++ b/src/Plugins/SimplnxCore/docs/CreateImageGeometryFilter.md @@ -1,30 +1,32 @@ # Create Geometry (Image) -## This filter should be considered deprecated. Use the "Create Geometry" filter instead - ## Group (Subgroup) Core (Generation) +> ⚠ **Deprecation Notice.** This filter is deprecated. Use the more general [Create Geometry](CreateGeometryFilter.md) filter instead. This filter is retained for compatibility with legacy pipelines. + ## Description -This **Filter** creates an **Image Geometry** specifically for the representation of a 3D rectilinear grid of voxels (3D) or pixels -(2D). Each axis can have its starting point (origin), resolution, and length defined for the **Geometry**. The **Data Container** in which to place the **Image Geometry** must be specified. +This **Filter** creates an **Image Geometry** -- a regular grid of voxels (3D) or pixels (2D). The user supplies the dimensions, spacing, and origin; the filter creates a new geometry object with no cell data attached. Use it before reading raw binary data into a grid, before creating synthetic data on a regular grid, or whenever you need a fresh empty Image Geometry. -An **Image Geometry** is a *grid-like* **Geometry**, and is the simplest and most widely used of the basic **Geometry** types. An **Image Geometry** is a *regular, rectilinear grid*; if the *dimenionality* of the image is *d*, then only *3*d* numbers are needed to completely define the **Geometry**: three *d*-vectors for the *dimensions*, *origin*, and *spacing*. +An Image Geometry is the simplest and most widely used DREAM3D-NX geometry type. For dimensionality *d*, only 3 × *d* numbers are needed to completely define it: three *d*-vectors for the dimensions, origin, and spacing. -- Dimensions define the extents of the grid. Stored as unsigned 64 bit integers. The dimensions are also known as the **extents** and are *zero* based thus a dimension with a value of 10 has extents from 0-9. -- Spacing defines the physical distance between grid planes for each orthogonal direction (constant along a given direction). Stored as 32 bit floating point numbers. Spacing has been known in the past as *resolution* but this term is ambiguous so spacing is used. A value of "microns per pixel" is a good example of "Spacing" units. -- Origin defines the physical location of the *bottom left* grid point in *d*-dimensional space. Stored as 32 bit floating point numbers. +- **Dimensions** -- grid extents. Stored as unsigned 64-bit integers. Dimensions are **0-based**, so a dimension of 10 spans extents 0-9. No dimension may be zero or negative. +- **Spacing** -- physical distance between grid planes along each axis. Stored as 32-bit floats. Units match the source data (e.g., microns per voxel). Spacing must be positive and non-zero. (*Resolution* was the older name; *spacing* is preferred because *resolution* is ambiguous.) +- **Origin** -- physical location of the bottom-left grid point in the geometry's coordinate system. Stored as 32-bit floats. No value restriction. -All **Image Geometries** in **DREAM3D-NX** are defined as 3D images. A 2D image is assumed when one of the dimension values is exactly 1; the 2D image is then considered a plane. Most **DREAM3D-NX** **Filters** will properly take account for the **Image** dimension if it matters (for example, the Find Feature Shapes **Filter** accounts for whether the **Image** is 2D or 3D when computing values such as *aspect ratios* or *axis Euler angles*). No dimension may be negative or equal to 0. The spacing must be a positive, non-zero value. The Origin has no value restrictions. This **Filter** requires the user to enter the nine values for the dimenions, origin, and spacing. +All Image Geometries are stored as 3D; a 2D image is represented by setting one dimension to exactly 1, producing a plane. Downstream filters that care about dimensionality (e.g., *Compute Feature Shapes*) detect the 2D case automatically. -Since all **Image Geometries** are implicitly 3D (even when plane-like), the fundamental building-block of an image is a *voxel*, which is a 3D object; therefore, the basic **Element** type for an **Image Geometry** is **Cell**. **Attribute Arrays** associated with **Image Cells** are assumed to raster *x-y-z*, fastest to slowest. +Since all Image Geometries are implicitly 3D, the building block is a *voxel*, which is a 3D object. The basic **Element** type for an Image Geometry is **Cell**. Attribute arrays associated with cells are stored in x-y-z raster order (fastest to slowest). ### Example Usage -If you are reading in raw binary data that represents data on a regular grid, the user will need to run this -filter first to create a description of the **Geometry**. +When importing raw binary data on a regular grid, run this filter first to create the geometry description; then attach data via subsequent reader filters. + +### Required Input Sources + +None. The geometry is created from user-supplied parameters. % Auto generated parameter table will be inserted here diff --git a/src/Plugins/SimplnxCore/docs/CreatePythonSkeletonFilter.md b/src/Plugins/SimplnxCore/docs/CreatePythonSkeletonFilter.md index af0f56db77..ab03b78d5c 100644 --- a/src/Plugins/SimplnxCore/docs/CreatePythonSkeletonFilter.md +++ b/src/Plugins/SimplnxCore/docs/CreatePythonSkeletonFilter.md @@ -1,21 +1,16 @@ # Create Python Plugin and/or Filters -## Description +## Group (Subgroup) -The **Create Python Plugin and/or Filters** is a tool in the DREAM3D-NX environment that allows users to generate or update Python plugins and filter codes. This filter provides an interface for setting up and configuring Python filters within DREAM3D-NX pipelines, either by creating new plugins or by adding to existing ones. +Core (Generation) -## Usage +## Description -### Configuration +The **Create Python Plugin and/or Filters** is a tool in the DREAM3D-NX environment that allows users to generate or update Python plugins and filter codes. This filter provides an interface for setting up and configuring Python filters within DREAM3D-NX pipelines, either by creating new plugins or by adding to existing ones. -The filter requires several parameters to be set, which dictate whether a new plugin is created or an existing one is modified. Key parameters include: +The filter is driven entirely by its parameters (described in the auto-generated table below), which dictate whether a new plugin is created or an existing one is modified. -- `Use Existing Plugin`: A flag indicating whether to modify an existing plugin. -- `Name of Plugin`: The name of the plugin. -- `Human Name of Plugin`: A human-readable name for the plugin. -- `Existing Plugin Location`: The directory where the existing plugin is located (for updates). -- `Plugin Output Directory`: The directory where the new plugin will be stored. -- `Filter Names`: A list of filter names to be included in the plugin, separated by commas. +## Usage ### Generating a New Plugin @@ -44,9 +39,11 @@ If your plugin was not generated using the provided filter but was instead creat - In the `__init__.py` file, add to the `all` method. - In the `Plugin.py` file, add to the `get_filters` method. -## Example Pipelines +### Required Input Sources + +None -- this **Filter** generates source files on disk and does not consume any **DataStructure** objects. -None +% Auto generated parameter table will be inserted here ## License & Copyright diff --git a/src/Plugins/SimplnxCore/docs/CropEdgeGeometryFilter.md b/src/Plugins/SimplnxCore/docs/CropEdgeGeometryFilter.md index d1d76bc5e4..98398f34c2 100644 --- a/src/Plugins/SimplnxCore/docs/CropEdgeGeometryFilter.md +++ b/src/Plugins/SimplnxCore/docs/CropEdgeGeometryFilter.md @@ -1,11 +1,17 @@ # Crop Geometry (Edge) +## Group (Subgroup) + +Core (Conversion) + ## Description -The **Crop Geometry (Edge) Filter** allows users to crop a region of interest (ROI) from an **Edge Geometry**. This filter is essential for isolating specific portions of edge-based data structures. +The **Crop Geometry (Edge) Filter** allows users to crop a region of interest (ROI) from an **Edge Geometry**. This filter is essential for isolating specific portions of edge-based data structures. For cropping voxel-based data instead, see [Crop Geometry (Image)](CropImageGeometryFilter.md). Users can selectively crop specific dimensions of the **Edge Geometry** by toggling **Crop X Dimension**, **Crop Y Dimension**, and **Crop Z Dimension** ON or OFF. Only dimensions that are turned ON will be cropped. +The **Min Coordinate** and **Max Coordinate** values define the ROI bounds and are specified in the **Edge Geometry's** physical coordinate units (the same units as the vertex positions), *not* as cell or vertex indices. + ### Boundary Intersection Behavior The *Boundary Intersection Behavior* parameter provides the following choices: @@ -89,8 +95,6 @@ As you can see, the edges that intersect the ROI boundary have been interpolated % Auto generated parameter table will be inserted here -## Example Pipelines - ## License & Copyright Please see the description file distributed with this **Plugin** diff --git a/src/Plugins/SimplnxCore/docs/CropImageGeometryFilter.md b/src/Plugins/SimplnxCore/docs/CropImageGeometryFilter.md index 06955dbc50..78bc0cffeb 100644 --- a/src/Plugins/SimplnxCore/docs/CropImageGeometryFilter.md +++ b/src/Plugins/SimplnxCore/docs/CropImageGeometryFilter.md @@ -1,80 +1,86 @@ # Crop Geometry (Image) +## Group (Subgroup) + +Core (Spatial) + ## Description -This **Filter** allows the user to crop a region of interest (ROI) from an **Image Geometry**. The input parameters are in units of voxels or physical coordinates. +This **Filter** extracts a region of interest (ROI) from an **Image Geometry**, producing a new geometry that contains only the selected cells. Bounds can be specified either in cell indices (voxels) or in physical coordinates. Individual dimensions (X, Y, Z) can be cropped independently. -It is possible to also crop specific dimensions of the **Image Geometry** by toggling **Crop X Dimension**, **Crop Y Dimension**, and **Crop Z Dimension** ON and OFF. +This is the inverse of [Pad Image Geometry](PadImageGeometryFilter.md). Common uses are isolating a sample from its overscan border, focusing analysis on a single feature, or reducing data size for testing. -## WARNING: NeighborList Removal +### Bounds Mode + +The *Use Physical Bounds* parameter selects how the crop bounds are interpreted: + +- **Use Physical Bounds = false**: bounds are integer **cell indices** (0-based, **inclusive** on both ends). Xmin=50, Xmax=99 keeps cells 50 through 99 (the last 50 cells of a 100-cell volume). +- **Use Physical Bounds = true**: bounds are **physical coordinates** in the geometry's units. The filter computes which cells fall inside the box defined by those coordinates, taking the geometry's origin and spacing into account. + +If any bound exceeds the geometry's extent on that axis, the filter clamps to the geometry's actual extent. The filter fails in preflight only when **all** of the requested bounds fall outside the geometry. -If the option to "Renumber Features" is turn ON and the Cell Feature AttributeMatrix contains any *NeighborList* data arrays, those arrays will be **REMOVED** because those lists are now invalid. Re-run the *Find Neighbors* filter to re-create the lists. +### Per-Axis Cropping +The *Crop X Dimension*, *Crop Y Dimension*, and *Crop Z Dimension* booleans toggle whether each axis is cropped at all. An axis with its flag OFF retains all of its cells regardless of the bounds setting. -## Examples +### Examples -In the following examples, the following image is being used. +In the following examples, the source image has: -- Origin: [0.0, 0.0, 0.0] -- Spacing: {0.5, 0.5, 1.0} -- Dimensions: {100, 100, 1} +- Origin: (0.0, 0.0, 0.0) +- Spacing: (0.5, 0.5, 1.0) +- Dimensions: (100, 100, 1) -So the bounds of the image is (0-50 micron, 0-50 micron, 0-1 micron) +So the physical bounds are (0-50 microns, 0-50 microns, 0-1 micron). ![Base image for examples](Images/CropImageGeometry_1.png) -### Example 1 +#### Example 1 -- Crop to the last 50 cells in X and Y -If the user wanted to crop the last 50 voxels in the X and Y axis then the user would use the following values: + Xmin = 50, Xmax = 99 + Ymin = 50, Ymax = 99 + Zmin = 0, Zmax = 0 + Use Physical Bounds = false - Xmin = 50, - Xmax = 99, - Ymin = 50, - Ymax = 99, - Zmin = 0, - Zmax = 0 +Result: ![Cropped image using voxels as the bounds](Images/CropImageGeometry_2.png) -**Note:** the units in the above image is in microns. +#### Example 2 -- Crop to the middle 50 cells -**Note:** The input parameters are *inclusive* and begin at *0*, so in the above example *50-99* will include the last 50 voxels. + Xmin = 25, Xmax = 74 + Ymin = 25, Ymax = 74 + Zmin = 0, Zmax = 0 + Use Physical Bounds = false -### Example 2 +Result: -If the user would like to crop out the `middle` 50 voxels from the image, these are the inputs: +![Cropped image using voxels as the bounds](Images/CropImageGeometry_3.png) - Xmin = 25, - Xmax = 74, - Ymin = 25, - Ymax = 74, - Zmin = 0, - Zmax = 0 +#### Example 3 -- Crop using physical coordinates, with one bound exceeding the volume -![Cropped image using voxels as the bounds](Images/CropImageGeometry_3.png) + Xmin = 30 microns, Xmax = 65 microns + Ymin = 30 microns, Ymax = 65 microns + Zmin = 0 microns, Zmax = 65 microns + Use Physical Bounds = true -### Example 3 +The Zmax of 65 microns exceeds the geometry's 1-micron Z extent and is silently clamped. The crop still succeeds because at least part of the requested box lies inside the geometry. -In this example the user is going to define the crop using physical coordinates and also selecting an upper bound that exceeds the actual bounds of the image. In this case, the filter will instead use the maximum bounds from that axis. +![Cropped image using voxels as the bounds](Images/CropImageGeometry_4.png) - Xmin = 30 microns, - Xmax = 65 microns, - Ymin = 30 microns, - Ymax = 65 microns, - Zmin = 0 microns, - Zmax = 65 microns +### Renumber Features -**Note:** This will work because at least some portion of the cropped image is within the original image. If **ALL** cropped values fall out side of the image bounds then the filter will error out in preflight. +Cropping can fully remove some **Features** from the volume, which leaves their Feature IDs unused and produces gaps. If *Renumber Features* is enabled, the Cell Feature Attribute Matrix is resized to drop empty features and remaining Features are renumbered to be contiguous starting from 1. Leave this off if you intend to compare the cropped output against the original larger volume by Feature ID. -![Cropped image using voxels as the bounds](Images/CropImageGeometry_4.png) +The user can save the cropped volume as a new **Data Container** or overwrite the current volume in place. -User may note that the way the bounds are determined are affected by the origin and spacing, so be sure to take these into account when supplying coordinate bounds for the crop. +## WARNING: NeighborList Removal -## Renumber Features +When *Renumber Features* is enabled and the Cell Feature Attribute Matrix contains any *NeighborList* arrays, those arrays are **removed** because they refer to the old Feature IDs. Re-run [Compute Feature Neighbors](ComputeFeatureNeighborsFilter.md) afterward to rebuild them. -It is possible with this **Filter** to fully remove **Features** from the volume, possibly resulting in consistency errors if more **Filters** process the data in the pipeline. If the user selects to *Renumber Features* then the *Feature Ids* array will be adjusted so that all **Features** are continuously numbered starting from 1. The user should decide if they would like their **Features** renumbered or left alone (in the case where the cropped output is being compared to some larger volume). +### Required Input Sources -The user has the option to save the cropped volume as a new **Data Container** or overwrite the current volume. +- **Input Image Geometry** -- the geometry to crop. Typically produced by [Create Image Geometry](CreateImageGeometryFilter.md), [ITK Import Image Stack](../ITKImageProcessing/ITKImportImageStackFilter.md), or an EBSD reader. % Auto generated parameter table will be inserted here diff --git a/src/Plugins/SimplnxCore/docs/CropVertexGeometryFilter.md b/src/Plugins/SimplnxCore/docs/CropVertexGeometryFilter.md index 4e4bd5ca8a..aeedb254f1 100644 --- a/src/Plugins/SimplnxCore/docs/CropVertexGeometryFilter.md +++ b/src/Plugins/SimplnxCore/docs/CropVertexGeometryFilter.md @@ -2,18 +2,33 @@ ## Group (Subgroup) -DREAM3D Review (Cropping/Cutting) +Geometry (Cropping/Cutting) ## Description -This **Filter** crops a **Vertex Geometry** by the given bounding box. Unlike the cropping of an Image, it is unknown until run time how the **Geometry** will be changed by the cropping operation. Therefore, this **Filter** requires that a new **Geometry** be created to contain the cropped **Vertex Geometry**. The user-selected **Vertex** data arrays will be copied, with tuples *removed* for any **Vertices** outside the bounding box. The user must supply a name for the cropped **Geometry**, but all other copied objects will retain the same names as the original source. +This **Filter** crops a **Vertex Geometry** (a point cloud) down to the points that lie inside a user-defined, axis-aligned bounding box. The box is specified by a *Min Pos* corner and a *Max Pos* corner. Both corners are given in **physical coordinate units** (the same length units as the vertex coordinates, e.g. microns), *not* in cell or index units. -*Note:* Since it cannot be known before run time how many **Vertices** will be removed during cropping, the new **Vertex Geometry** and all associated **Vertex** data to be copied will be initialized to have size 0. +A vertex is kept when its X, Y, and Z coordinates all fall within the box. The test is **inclusive** on every face of the box: a vertex is retained when its coordinate is greater than or equal to the corresponding *Min Pos* value and less than or equal to the corresponding *Max Pos* value. Vertices on the boundary planes are therefore kept, and vertices outside any face of the box are discarded. -% Auto generated parameter table will be inserted here +Unlike cropping an **Image Geometry**, it is not known until run time how many vertices will survive the crop. Therefore this **Filter** creates a new **Vertex Geometry** to hold the cropped result rather than modifying the input in place. The user-selected vertex data arrays are copied into the new geometry with the tuples for any discarded vertices removed. The user must supply a name for the cropped geometry; all other copied objects keep the same names as in the original source. + +*Note:* Because the number of surviving vertices cannot be known before run time, the new **Vertex Geometry** and all associated vertex data to be copied are initialized to size 0 and then grown to the final size during execution. + +### Related Filters + +- [Crop Geometry (Edge)](CropEdgeGeometryFilter.md) -- crops an **Edge Geometry** to a bounding box. +- [Crop Geometry (Image)](CropImageGeometryFilter.md) -- crops an **Image Geometry** by cell index ranges. + +### Required Input Sources -## Example Pipelines +- **Vertex Geometry to Crop** -- a **Vertex Geometry** (point cloud) to be cropped. + +% Auto generated parameter table will be inserted here ## License & Copyright -Please see the description file distributed with this plugin. +Please see the description file distributed with this **Plugin** + +## DREAM3D-NX Help + +If you need help, need to file a bug report or want to request a new feature, please head over to the [DREAM3DNX-Issues](https://github.com/BlueQuartzSoftware/DREAM3DNX-Issues/discussions) GitHub site where the community of DREAM3D-NX users can help answer your questions. diff --git a/src/Plugins/SimplnxCore/docs/DBSCANFilter.md b/src/Plugins/SimplnxCore/docs/DBSCANFilter.md index 968178fe47..2de5adfdd2 100644 --- a/src/Plugins/SimplnxCore/docs/DBSCANFilter.md +++ b/src/Plugins/SimplnxCore/docs/DBSCANFilter.md @@ -28,7 +28,11 @@ Points that are in sparse regions of the data space are considered "outliers"; t The user may select from a number of options to use as the distance metric. -An advantage of DBSCAN over other clustering approaches (e.g., k-means) is that the number of clusters is not defined *a priori*. Additionally, DBSCAN is capable of finding arbitrarily shaped, nonlinear clusters, and is robust to noise. +An advantage of DBSCAN over other clustering approaches (e.g., [Compute K Means](ComputeKMeansFilter.md)) is that the number of clusters is not defined *a priori*. Additionally, DBSCAN is capable of finding arbitrarily shaped, nonlinear clusters, and is robust to noise. + +### Required Input Sources + +- **Input Data Array** -- any 2D or 3D scalar/multi-component array (other than `bool`) to be clustered. This may already exist in your **DataStructure**, or be assembled from coordinate components using [Combine Attribute Arrays](CombineAttributeArraysFilter.md) (see the **Visualization Tips** section). ### Examples @@ -67,19 +71,19 @@ This filter is designed to be applicable to any 2D or 3D array (other than bool Take note of the name of your input array referred to as `input_array` from here on, and the cluster ids array name referred to as `cluster_array` from here on. **Step 2 (2D only): Create a 1 component array of 0s named `Z`** -This can be done with the *Create Data Array* filter. **It's important to ensure the created array has the same length and type as `input_array`** +This can be done with the [Create Data Array](CreateDataArrayFilter.md) filter. **It's important to ensure the created array has the same length and type as `input_array`** **Step 3 (2D only): Merge `input_array` and `Z` array** -This can be done with the *Combine Attribute Arrays* filter. Make sure **`input_array` is above the `Z` array** in the "Attribute Arrays to Combine" parameter. **The output array will now be the new `input_array` for the following steps**, so it's recommended to enable the "Move Data" parameter to avoid confusion and keep data structure tree clean. +This can be done with the [Combine Attribute Arrays](CombineAttributeArraysFilter.md) filter. Make sure **`input_array` is above the `Z` array** in the "Attribute Arrays to Combine" parameter. **The output array will now be the new `input_array` for the following steps**, so it's recommended to enable the "Move Data" parameter to avoid confusion and keep data structure tree clean. **Step 4: Convert `input_array` to `float32` (skip step if not applicable)** -This can be done with the "Convert AttributeArray DataType" filter. Be sure to set "Scalar Type" parameter to `float32`. +This can be done with the [Convert AttributeArray DataType](ConvertDataFilter.md) filter. Be sure to set "Scalar Type" parameter to `float32`. **Step 5: Create Vertex Geometry** -This can be done with the "Create Geometry" filter. Be sure to set "Geometry Type" to `Vertex`. Your `input_array` is going to be the "Shared Vertex List", so place it in the corresponding parameter with the same name. Take note of the created "Vertex Data" *AttributeMatrix* this will be referred to as `vertex_data` in following steps. +This can be done with the [Create Geometry](CreateGeometryFilter.md) filter. Be sure to set "Geometry Type" to `Vertex`. Your `input_array` is going to be the "Shared Vertex List", so place it in the corresponding parameter with the same name. Take note of the created "Vertex Data" *AttributeMatrix* this will be referred to as `vertex_data` in following steps. **Step 6: Move the `cluster_array` into `vertex_data` *AttributeMatrix*** -This can be done with the "Move Data" filter. Place the `cluster_data` array in the "Data to Move" parameter, and place `vertex_data` in the "New Parent" parameter. +This can be done with the [Move Data](MoveDataFilter.md) filter. Place the `cluster_data` array in the "Data to Move" parameter, and place `vertex_data` in the "New Parent" parameter. **Step 7: Run the pipeline** This concludes the post-processing. @@ -98,7 +102,7 @@ This implementation of DBSCAN uses a grid approach to greatly increase the speed #### Understanding the Grid -The most important part to understand for the function to click into place is the Grid. The Grid is a regular grid that contains all the points in the input array. It serves as a way to spatially partition the dataset for processing. The voxel cells all have a side length of `Epsilon / sqaure_root(Dimensions)` where `Epsilon` is the user supplied hyperparameter and `Dimensions` is the number of components in the input array. This means that if your input array has 2 components the regular grid can be visualized as a square and 3 components can be visualized as a cube. +The most important part to understand for the function to click into place is the Grid. The Grid is a regular grid that contains all the points in the input array. It serves as a way to spatially partition the dataset for processing. The voxel cells all have a side length of `Epsilon / square_root(Dimensions)` where `Epsilon` is the user supplied hyperparameter and `Dimensions` is the number of components in the input array. This means that if your input array has 2 components the regular grid can be visualized as a square and 3 components can be visualized as a cube. #### Minimum Points @@ -108,7 +112,7 @@ This hyperparameter has outsized effects on how many cluster expansion/merge ite #### Epsilon -This hyperparameter is the basis for the entire algorithm. It actually has two separate use cases in this implementation. The first was laid out already in the **Understanding the Grid** section, as it effects the size of the voxels in the regular grid. The second is the maximum distance allowed between any two points in the input array for them to be considered density connected. As you may have perceived, these two use cases are connected, in that the voxels side length ensures all points within the same voxel satisfy the density connected requirement inherently. When preforming merge checks between voxels, every point in a grid is compared against every point in the other grid to see if there are any points that have a distance *less than* `Epsilon`. +This hyperparameter is the basis for the entire algorithm. It actually has two separate use cases in this implementation. The first was laid out already in the **Understanding the Grid** section, as it effects the size of the voxels in the regular grid. The second is the maximum distance allowed between any two points in the input array for them to be considered density connected. As you may have perceived, these two use cases are connected, in that the voxels side length ensures all points within the same voxel satisfy the density connected requirement inherently. When performing merge checks between voxels, every point in a grid is compared against every point in the other grid to see if there are any points that have a distance *less than* `Epsilon`. This hyperparameter has outsized effects on how accurate cluster result is to ground truth and what value is appropriate for `Minimum Points`. Detailed further in the **Optimization** section below. @@ -116,11 +120,11 @@ This hyperparameter has outsized effects on how accurate cluster result is to gr For `Epsilon`, ideally you want a little *a priori* knowledge on what the average distance between points in the dataset is, and start with slightly above that. However, this can be supplemented by visualizing the dataset, selecting a couple of areas you would consider clusters, finding the distance between some of the points on the edges of each of the clusters, and setting an `Epsilon` slightly above that. -For `Minimum Points`, previous recommendations suggested 1 above the dimensions of input data (for 2D - 3 and for 3D - 4). However, the density of points heavily effects this. If you have several packed regions and the rest sparse higher values are reasonable (5-9), and vise versa. **Avoid supplying a 1 as this will result in 0 unlabeled points always, unless that is knowingly the intention.** +For `Minimum Points`, previous recommendations suggested 1 above the dimensions of input data (for 2D - 3 and for 3D - 4). However, the density of points heavily effects this. If you have several packed regions and the rest sparse higher values are reasonable (5-9), and vice versa. **Avoid supplying a 1 as this will result in 0 unlabeled points always, unless that is knowingly the intention.** #### Optimization -Before any optimization, you should always try cleaning up your data. **Standardizing your data with a scaler**, such as [StandardScaler `fit_transform()` from Sci-Kit](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.StandardScaler.html), **will make it much easier to tune the `Epsilon` parameter**. Similarly, **subtle changes in output can be caused by duplicate points in input array**. Duplicate points can be identified and removed with filters like "Identify Duplicate Vertices" and "Remove Flagged Vertices". These require your data to be in a `SharedVertexList` which is type-locked to `float32`, if typecasting is safe this can be done with steps similar to the ones laid out in the **Visualization** section. Otherwise, you may need to clean the data before import to `simplnx`. +Before any optimization, you should always try cleaning up your data. **Standardizing your data with a scaler**, such as [StandardScaler `fit_transform()` from Sci-Kit](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.StandardScaler.html), **will make it much easier to tune the `Epsilon` parameter**. Similarly, **subtle changes in output can be caused by duplicate points in input array**. Duplicate points can be identified and removed with filters like [Identify Duplicate Vertices](IdentifyDuplicateVerticesFilter.md) and [Remove Flagged Vertices](RemoveFlaggedVerticesFilter.md). These require your data to be in a `SharedVertexList` which is type-locked to `float32`, if typecasting is safe this can be done with steps similar to the ones laid out in the **Visualization** section. Otherwise, you may need to clean the data before import to `simplnx`. Optimization is going to rely on extensive *a priori* knowledge of the data no matter what. However, this knowledge can be obtained through sequential runs of the filter and some visualization of the output. That said here is how to interpret results to optimize the speed and/or increase accuracy of output: @@ -147,7 +151,7 @@ Additionally, oddities such as duplicates in the dataset or non-standardized dat This can obviously be caused by large datasets, but it can be mitigated with some changes. Firstly, the "Parse Order" parameter can result in immediate speedups of 60% or more on a majority of datasets by switching to `Low Density First`. The idea being that lower density regions are cheaper for merge checks, so other denser core grids can be picked off early if they are close to sparser core grids, meaning that the expensive grids have less of a chance of running against one another. Another change is tightening the voxels grids by lowering the `Epsilon` and reducing the `Minimum Points` slightly. For ideal performance, in the vast majority of cases, you want to reach the lowest value for both of these that still produces expected clustering. This is because the most costly part is the distance check most of the time. Logically, grids with fewer points run less distance checks. **If your algorithm spends more time in "cluster expansion pass:" than "Identifying Qualifying Independent Clusters".** See output window. -There are many datasets that this is normal in such as `No Structure` from **Examples**. This typically happens when `Minimum Points` is too high. This results in too few Core grids being identified. Since few clusters are able to be formed, most of the time is spent in iterative loops expanding the clusters rather than just preforming the early merges in the Core grid step. +There are many datasets that this is normal in such as `No Structure` from **Examples**. This typically happens when `Minimum Points` is too high. This results in too few Core grids being identified. Since few clusters are able to be formed, most of the time is spent in iterative loops expanding the clusters rather than just performing the early merges in the Core grid step. ### Parse Order diff --git a/src/Plugins/SimplnxCore/docs/DeleteDataFilter.md b/src/Plugins/SimplnxCore/docs/DeleteDataFilter.md index 0abc965f22..8b50708bda 100644 --- a/src/Plugins/SimplnxCore/docs/DeleteDataFilter.md +++ b/src/Plugins/SimplnxCore/docs/DeleteDataFilter.md @@ -6,7 +6,28 @@ Core (Memory/Management) ## Description -This **Filter** allows the user to remove specified objects from the existing structure. This can be helpful if the user has operations that need as much memory as possible and there are extra objects that are not needed residing in memory. Alternatively, this **Filter** allows the user to remove objects that may share a name with another object further in the **Pipeline** that another **Filter** tries to create, since DREAM3D-NX generally does not allows objects at the same hierarchy to share the same name. +This **Filter** removes one or more **Data Objects** from the **Data Structure**. Common use cases: + +- **Free memory.** When subsequent filters need as much RAM as possible and some arrays are no longer needed. +- **Avoid name collisions.** DREAM3DNX does not allow two objects at the same hierarchy level to share the same name. If a downstream filter will create an object with the same name as an existing one, delete the existing one first. +- **Clean up after extraction.** When *Move* or *Extract* options on other filters left behind unused parent containers. + +### Cascade Behavior + +Deletion is recursive on containers. Deleting a: + +- **Geometry** also deletes its child Attribute Matrices and all arrays inside them. +- **Attribute Matrix** also deletes all child arrays. +- **DataGroup** also deletes all of its children, including nested DataGroups, recursively. +- **Data Array** removes only that array. + +## WARNING: Downstream Preflight Will Fail + +Any filter later in the pipeline that references a deleted object by path will fail preflight when re-run. Delete only objects you are certain are not used downstream, or be prepared to update downstream filter parameters. + +### Required Input Sources + +- **Data Objects to Delete** -- a list of paths to existing **DataObjects** in the Data Structure. % Auto generated parameter table will be inserted here diff --git a/src/Plugins/SimplnxCore/docs/ErodeDilateBadDataFilter.md b/src/Plugins/SimplnxCore/docs/ErodeDilateBadDataFilter.md index 4e1c68abef..34a18aeae9 100644 --- a/src/Plugins/SimplnxCore/docs/ErodeDilateBadDataFilter.md +++ b/src/Plugins/SimplnxCore/docs/ErodeDilateBadDataFilter.md @@ -6,14 +6,11 @@ Processing (Cleanup) ## Description -Bad data refers to a **Cell** that has a *Feature Id* of *0*, which means the **Cell** has failed some sort of test and -been marked as a *bad* **Cell**. +This **Filter** grows or shrinks regions of *bad data* (cells with *Feature Id = 0*) by one cell-layer per iteration, using standard image-morphology operations. It is a building block for cleaning up isolated noise or for compensating for boundaries that were systematically under- or over-measured by the experiment. ### Dilation -If the **bad** data is *dilated*, the Filter grows the *bad* data by one **Cell** in -an iterative sequence for a user defined number of iterations. During the *dilate* process the *Feature Id* of any -Cell neighboring a *bad* **Cell** will be changed to *0*. +*Dilate* grows the bad-data region outward. Each iteration changes any cell adjacent to a bad cell into a bad cell, adding a one-cell-thick layer. | Before Dilation | After Dilation | |--------------------------------------|--------------------------------------| @@ -21,42 +18,31 @@ Cell neighboring a *bad* **Cell** will be changed to *0*. ### Erosion -If the *bad* data is *eroded*, the Filter shrinks the -bad data by one **Cell** in an iterative sequence for a user defined number of iterations. During the *erode* process -the *Feature Id* of the *bad* **Cell** is changed from *0* to the *Feature Id* of the majority of its neighbors. If -there is a tie between two *Feature Ids*, then one of the *Feature Ids*, chosen randomly, will be assigned to the *bad* -**Cell**. +*Erode* shrinks the bad-data region. Each iteration converts each bad cell into the *Feature Id* held by the majority of its neighbors. Ties are broken randomly. Single-cell bad regions disappear in one iteration; thicker regions take more. | Before Erosion | After Erosion | |--------------------------------------|--------------------------------------| | ![](Images/ErodeDilateBadData_1.png) | ![](Images/ErodeDilateBadData_3.png) | -` +### When to Use This Filter -Goals a user might be trying to accomplish with this Filter include: +- **Erode** to remove small or thin regions of bad data — single-cell EBSD dropouts, salt-and-pepper noise. +- **Dilate** to grow under-measured features. For example, EBSD scans tend to under-estimate pore size because the beam picks up signal from material *below* the pore when it sits at the pore edge; dilating the *Feature Id = 0* region restores the true pore boundary. +- **Erode followed by Dilate** (a morphological *opening*) is the classic pattern for removing isolated noise without affecting larger regions. A single erode-dilate pair will erase isolated single-cell bad regions but return larger pores to almost their original size. +- **Dilate followed by Erode** (a morphological *closing*) fills small holes inside bad-data regions while preserving their outer boundary. -- Remove small or thin regions of bad data by running a single (or two) iteration *erode* operation. -- Increase the size of a *bad* data region by running an *dilate* operation. This might be useful if the experimental - technique tends to underestimates the size of certain objects. For example, when running EBSD, the pores (which show - up as *bad* data) are generally smaller in the scans than in the specimen, because the beam, when it is just inside - the pore, still can pick up signal from the material just beneath the pore. +### Iterations and Direction -Running the *erode-dilate* operations in pairs can often change the size of some objects without affecting others. For -example, if there were a number of big pores and a number of single *bad* **Cells**, running a single *erode* operation -would remove the single **Cells** and reduce the pores by one **Cell**. If this is followed immediately by a *dilate* -operation, then the pores would grow by one **Cell** and return to near their original size, while the single **Cells** -would remain removed and not "grow back". +- *Number of Iterations* is in **cell-layers**. An iteration count of 3 grows or shrinks the bad-data region by 3 cells. +- *X Direction*, *Y Direction*, and *Z Direction* toggle whether the morphology is applied along that axis. Disable an axis to perform anisotropic erosion/dilation -- useful when serial-sectioning resolution is anisotropic (typically Z is coarser than X and Y) and you want to limit smoothing along the fine axes. -### Operation - -The *Operation* parameter selects which morphological operation to apply: +## WARNING: Feature Data Will Become Invalid -- **Dilate [0]**: Grows bad data regions by one **Cell** per iteration. Any **Cell** neighboring a bad **Cell** has its *Feature Id* changed to 0. -- **Erode [1]**: Shrinks bad data regions by one **Cell** per iteration. Each bad **Cell** is assigned the *Feature Id* of the majority of its neighbors. +By modifying cell-level data, any feature-level data that was previously computed will most likely be invalid after this filter runs. Re-run any downstream feature-level computation filters to ensure accurate results. -## WARNING: Feature Data Will Become Invalid +### Required Input Sources -By modifying the cell level data, any feature data that was previously computed will most likely be invalid at this point. Filters that compute feature level data should be rerun to ensure accurate final results from your pipeline. +- **Cell Feature Ids** -- produced by a segmentation filter such as [Segment Features (Misorientation)](../OrientationAnalysis/EBSDSegmentFeaturesFilter.md) or [Segment Features (Scalar)](ScalarSegmentFeaturesFilter.md). Cells with Feature Id = 0 are treated as bad. % Auto generated parameter table will be inserted here diff --git a/src/Plugins/SimplnxCore/docs/ErodeDilateCoordinationNumberFilter.md b/src/Plugins/SimplnxCore/docs/ErodeDilateCoordinationNumberFilter.md index 2e11f06787..90f36280c3 100644 --- a/src/Plugins/SimplnxCore/docs/ErodeDilateCoordinationNumberFilter.md +++ b/src/Plugins/SimplnxCore/docs/ErodeDilateCoordinationNumberFilter.md @@ -6,23 +6,37 @@ Processing (Cleanup) ## Description -This **Filter** will smooth the interface between *good* and *bad* data. The user can specify a *coordination number*, -which is the number of neighboring **Cells** of opposite type (i.e., *good* or *bad*) compared to a given **Cell** that -is acceptable. For example, a single *bad* **Cell** surrounded by *good* **Cells** would have a *coordination number* of -*6*. The number entered by the user is actually the maximum tolerated *coordination number*. If the user entered a value -of *4*, then all *good* **Cells** with 5 or more *bad* neighbors and *bad* **Cells** with 5 or more *good* neighbors -would be removed. After **Cells** with unacceptable *coordination number* are removed, then the neighboring **Cells** -are *coarsened* to fill the removed **Cells**. - -By default, the **Filter** will only perform a single iteration and will not concern itself with the possibility that -after one iteration, **Cells** that were acceptable may become unacceptable by the original *coordination number* -criteria due to the small changes to the structure during the *coarsening*. The user can opt to enable the *Loop Until -Gone* parameter, which will continue to run until no **Cells** fail the original criteria. - -| Before Filter | After Filter | -|--------------------------------------|--------------------------------------| +This **Filter** smooths the interface between *good* and *bad* cells (or, more generally, between any two adjacent feature regions) by removing cells whose neighborhood is mostly the opposite class. It targets isolated voxels and small protrusions that are surrounded by cells of a different feature, then fills them in with their neighbors' data via isotropic coarsening. + +The *coordination number* is the count of a cell's face-sharing neighbors that belong to a different class. With 6 face neighbors, the coordination number ranges from **0 to 6**: + +- **CN = 0** -- all 6 neighbors agree with the cell. Solidly inside a region. +- **CN = 1-2** -- on a flat or gently curved feature boundary. +- **CN = 4-5** -- a thin protrusion or finger of one feature sticking into another. +- **CN = 6** -- a single isolated cell completely surrounded by another feature. + +| Before Filter | After Filter | +|------------------------------------------------------|-----------------------------------------------------| | ![](Images/ErodeDilateCoordinationNumber_Before.png) | ![](Images/ErodeDilateCoordinationNumber_After.png) | +### How This Filter Works + +The user specifies the *maximum tolerated coordination number*. Any cell whose coordination number is **strictly greater** than this threshold is removed. After the offending cells are identified, neighboring features grow outward (isotropic coarsening) to fill the resulting gaps. See [Remove Minimum Size Features](RequireMinimumSizeFeaturesFilter.md) for the shared definition of isotropic coarsening. + +For example, a threshold of *4* removes any cell with 5 or 6 differing neighbors (i.e., isolated voxels and thin protrusions). A threshold of *2* is much more aggressive and will erase any cell that is more than half surrounded by a different feature. + +### Loop Until Gone + +By default the filter performs **one** pass. After one pass, the coarsening can leave new cells whose coordination number now exceeds the threshold (because their neighbors changed). Enabling *Loop Until Gone* repeats the algorithm until no remaining cell exceeds the original criterion. Use this for full smoothing; use the single-pass mode when you want a controlled, gentle cleanup. + +### When to Use This Filter + +This is the right tool for "salt-and-pepper" cleanup -- isolated single-voxel grains, thin two-cell protrusions, and other small geometric anomalies that segmentation produced but are likely noise. It is more morphologically aware than the size-based filters because it considers neighborhood shape, not just cell count. + +### Required Input Sources + +- **Cell Feature Ids** -- produced by a segmentation filter such as [Segment Features (Misorientation)](../OrientationAnalysis/EBSDSegmentFeaturesFilter.md) or [Segment Features (Scalar)](ScalarSegmentFeaturesFilter.md). + % Auto generated parameter table will be inserted here ## Example Pipelines diff --git a/src/Plugins/SimplnxCore/docs/ErodeDilateMaskFilter.md b/src/Plugins/SimplnxCore/docs/ErodeDilateMaskFilter.md index 8f81cd62e1..8dd618b526 100644 --- a/src/Plugins/SimplnxCore/docs/ErodeDilateMaskFilter.md +++ b/src/Plugins/SimplnxCore/docs/ErodeDilateMaskFilter.md @@ -6,31 +6,33 @@ Processing (Cleanup) ## Description -If the mask is _dilated_, the **Filter** grows the _true_ regions by one **Cell** in an iterative sequence for a user -defined number of iterations. During the _dilate_ process, the classification of any **Cell** neighboring a _false_ * -*Cell** will be changed to _true_. If the mask is _eroded_, the **Filter** shrinks the _true_ regions by one **Cell** in -an iterative sequence for a user defined number of iterations. During the _erode_ process, _true_ **Cells** that have -at least one _false_ neighbor are changed to _false_. The **Filter** also offers the option(s) to -turn on/off the erosion or dilation in specific directions (X, Y or Z). +This **Filter** grows or shrinks the *true* region of a boolean *mask* array by one cell-layer per iteration, using standard image-morphology operations. The mask is a cell-level boolean array (typically produced by a threshold operation such as [Multi-Threshold Objects](MultiThresholdObjectsFilter.md)) where *true* marks cells of interest and *false* marks excluded cells. -This filter will ONLY change the _Mask_ data array and not any of the other data arrays in the same attribute matrix. +Only the **Mask** array is modified; no other cell data is changed. -The example images below were generated **AFTER** the execution of the filter and essentially any black pixel is where the **Mask** was false and any other color is where the **Mask** is true. (The colors are the typical IPF Colors using a <001> reference direction) +The example images below show the IPF-colored data after the filter has run. Black pixels are cells where the mask is *false*; colored pixels are where the mask is *true*. -| Before Dilatation | After Dilation | -|--------------------------------------|--------------------------------------| +| Before Dilation | After Dilation | +|----------------------------------------|----------------------------------------| | ![](Images/ErodeDilateMask_Before.png) | ![](Images/ErodeDilateMask_Dilate.png) | -| Before Erosion | After Erosion | -|--------------------------------------|--------------------------------------| -| ![](Images/ErodeDilateMask_Before.png) | ![](Images/ErodeDilateMask_Erode.png) | +| Before Erosion | After Erosion | +|----------------------------------------|----------------------------------------| +| ![](Images/ErodeDilateMask_Before.png) | ![](Images/ErodeDilateMask_Erode.png) | -### Operation +### When to Use This Filter -The *Operation* parameter selects which morphological operation to apply to the mask: +- **Erode** the mask to discard the boundary layer of valid cells. Useful before computing feature-level statistics from EBSD data, since cells right at the sample edge are often unreliable even after passing a quality threshold. +- **Dilate** the mask to recover cells that were marked invalid by an over-aggressive threshold but lie immediately adjacent to valid data. -- **Dilate [0]**: Expands the masked (true) regions by one **Cell** per iteration. Any **Cell** neighboring a false **Cell** is changed to true. -- **Erode [1]**: Shrinks the masked (true) regions by one **Cell** per iteration. True **Cells** that have at least one false neighbor are changed to false. +### Iterations and Direction + +- *Number of Iterations* is in **cell-layers**. An iteration count of 3 grows or shrinks the *true* region by 3 cells. +- *X Direction*, *Y Direction*, and *Z Direction* toggle whether the morphology is applied along that axis. Disable an axis to perform anisotropic morphology -- useful when serial-sectioning resolution is anisotropic (typically Z is coarser than X and Y) and you want to limit growth or shrinking along the fine axes. + +### Required Input Sources + +- **Mask Array** -- a boolean cell-level array, typically produced by [Multi-Threshold Objects](MultiThresholdObjectsFilter.md) applied to an EBSD confidence index, image quality, or similar scalar. % Auto generated parameter table will be inserted here diff --git a/src/Plugins/SimplnxCore/docs/ExecuteProcessFilter.md b/src/Plugins/SimplnxCore/docs/ExecuteProcessFilter.md index feaeda0d5e..7f1f992b43 100644 --- a/src/Plugins/SimplnxCore/docs/ExecuteProcessFilter.md +++ b/src/Plugins/SimplnxCore/docs/ExecuteProcessFilter.md @@ -22,6 +22,17 @@ For a command with spaces in the path > "C:/Program Files/DREAM3D-6.6.332/nxrunner.exe" "C:/Program Files/DREAM3D-6.6.332/PrebuiltPipelines/Workshop/EBSD Reconstruction/(01) SmallIN100 Archive.json" +The path to the executable should be given as an **absolute path**; relative paths and shell built-ins that are resolved by a particular shell are not reliable across platforms. + +### Blocking and Timeout + +- **Should Block**: When enabled, the **Filter** waits for the launched process to finish (or to start, on platforms where that distinction applies) before the pipeline continues. When disabled, the process is launched and the pipeline moves on without waiting. +- **Timeout (ms)**: Only applies when *Should Block* is enabled. It is the maximum time, in milliseconds, that the **Filter** will wait for the command before giving up. + +### Required Input Sources + +None -- this **Filter** launches an external program and does not consume any **DataStructure** objects. + % Auto generated parameter table will be inserted here ## Example Pipelines diff --git a/src/Plugins/SimplnxCore/docs/ExtractComponentAsArrayFilter.md b/src/Plugins/SimplnxCore/docs/ExtractComponentAsArrayFilter.md index 30df3ed16f..b286df21aa 100644 --- a/src/Plugins/SimplnxCore/docs/ExtractComponentAsArrayFilter.md +++ b/src/Plugins/SimplnxCore/docs/ExtractComponentAsArrayFilter.md @@ -6,11 +6,23 @@ Core (Memory/Management) ## Description -This **Filter** will do one of the following to one component of a multicomponent **Attribute Array**: +This **Filter** operates on a single component of a multicomponent **Attribute Array**, supporting three modes of behavior: -- Remove 1 component from multicomponent **Attribute Array** completely [This is done implicitly so long as **Move Extracted Components To New Array** is false] -- Extract 1 component from multicomponent **Attribute Array** and store it in a new **DataArray** without removing from original -- Extract 1 component from multicomponent **Attribute Array** and store it in a new **DataArray** and remove that component from the original +- **Remove only** (default): the selected component is deleted from the source array; no new array is created. +- **Extract only** (*Move Extracted Components To New Array* = true, *Remove from Original* = false): the selected component is copied into a new scalar **DataArray**; the source array is unchanged. +- **Extract and remove** (*Move Extracted Components To New Array* = true, *Remove from Original* = true): the selected component is moved into a new scalar **DataArray** and removed from the source. + +### Component Indexing + +The component selector is **0-based**. For a 3-component array, valid component indices are 0, 1, and 2. + +### When to Use This Filter + +Use to pull a single channel out of a color image (e.g., extract R from an RGB array), strip a known-bad component from a tensor, or split one specific component while leaving the rest intact. For splitting *all* components into separate arrays at once, use [Split Data Array (By Component)](SplitDataArrayByComponentFilter.md) instead. + +### Required Input Sources + +- **Source Multi-Component Array** -- any **Attribute Array** with two or more components. % Auto generated parameter table will be inserted here diff --git a/src/Plugins/SimplnxCore/docs/ExtractFeatureBoundaries2DFilter.md b/src/Plugins/SimplnxCore/docs/ExtractFeatureBoundaries2DFilter.md index dec668a45e..3b8dd4d2dc 100644 --- a/src/Plugins/SimplnxCore/docs/ExtractFeatureBoundaries2DFilter.md +++ b/src/Plugins/SimplnxCore/docs/ExtractFeatureBoundaries2DFilter.md @@ -2,49 +2,56 @@ ## Group (Subgroup) -SimplnxCore (Geometry) +Surface Meshing (Generation) ## Description -This **Filter** extracts 2D feature boundaries from an Image Geometry and creates an Edge Geometry representing the outlines of features defined by a Feature IDs array. The filter operates only in the XY plane and requires the input Image Geometry to have a Z dimension of 1. +This **Filter** extracts the 2D boundaries between **Features** in an **Image Geometry** and builds an **Edge Geometry** that traces the outlines of those features. An **Image Geometry** is a regular grid of rectangular cells (pixels in 2D). A **Feature** is a connected region of cells that share the same identifier, recorded in a **Feature IDs** array (one integer label per cell). An **Edge Geometry** is a node-based geometry made of straight line segments (edges); here each edge lies on the interface between two cells that belong to different features. -**NOTE**: The "FeatureIds" array can be any integer type, not just `signed int32` as is the typical featureIds arrays. This means that it can work immediately on scalar images that have not been segmented already. The user could use a basic threshold to create a unsigned int 8 mask value, then use that mask value as the input into this filter. This could be used, for example, to outline just the sample border if there is overscan or just outline specific regions of a 2D Image Geometry. +The filter operates only in the XY plane and requires the input **Image Geometry** to have a Z dimension of 1 (a single slice). -The algorithm scans the Feature IDs array and identifies boundaries where adjacent cells have different feature IDs. For each boundary, an edge (line segment) is created at the cell interface. The resulting Edge Geometry contains: +**NOTE**: The Feature IDs array can be any integer type, not just the *signed int32* type used by typical feature-id arrays. This means it can operate directly on scalar images that have not been segmented. For example, the user could run a simple threshold to create a *uint8* mask (a boolean per-cell flag stored as 0/1) and feed that mask in as the Feature IDs input. This is useful for outlining just the sample border when there is **overscan** — extra collected area surrounding the actual sample — or for outlining specific regions of a 2D **Image Geometry**. + +The algorithm scans the Feature IDs array and identifies boundaries where adjacent cells have different feature IDs. For each such boundary, an edge (line segment) is created along the shared cell interface. The resulting **Edge Geometry** contains: - **Shared Vertex List**: 3D coordinates of all unique vertices at feature boundaries -- **Shared Edge List**: Connectivity pairs defining line segments between vertices +- **Shared Edge List**: connectivity pairs defining the line segments between those vertices ### Z Value Source The *Z Value Source* parameter provides the following choices: -- **Use min z value from Image geometry [0]**: Uses the origin Z value of the input Image Geometry as the Z coordinate for all generated vertices. -- **Use max z value from Image geometry [1]**: Uses the origin Z plus the spacing times the Z dimension as the Z coordinate for all generated vertices. -- **Use Custom z Offset [2]**: Allows the user to specify an arbitrary Z coordinate value for all generated vertices. +- *Use min z value from Image geometry [0]*: Uses the origin Z value of the input **Image Geometry** as the Z coordinate for all generated vertices. +- *Use max z value from Image geometry [1]*: Uses the origin Z plus the spacing times the Z dimension as the Z coordinate for all generated vertices. +- *Use Custom z Offset [2]*: Lets the user specify an arbitrary Z coordinate value for all generated vertices. ### Algorithm Details The algorithm uses a two-pass approach for efficiency: -1. **Count Pass**: Scan to count the total number of boundary edges (both vertical and horizontal) -2. **Populate Pass**: Creation of vertices and edge connectivity +1. **Count Pass**: Scans to count the total number of boundary edges (both vertical and horizontal). +2. **Populate Pass**: Creates the vertices and edge connectivity. After edge creation, duplicate vertices are eliminated to ensure a clean, connected edge network. ## Example Output -![Images/ExtractFeatureBoundaries2D_1.png](Images/ExtractFeatureBoundaries2D_1.png) +![Example feature boundaries extracted as an Edge Geometry.](Images/ExtractFeatureBoundaries2D_1.png) + +### Required Input Sources + +- **Image Geometry** -- a 2D **Image Geometry** (Z dimension of 1) holding the Feature IDs. +- **Feature IDs** -- a per-cell integer array. It may be a true segmentation produced by [Segment Features (Scalar)](ScalarSegmentFeaturesFilter.md), or any per-cell integer/mask array produced by a thresholding filter such as [Multi-Threshold Objects](MultiThresholdObjectsFilter.md). % Auto generated parameter table will be inserted here ## Example Pipelines -- ExtractFeatureBoundaries2D.d3dpipline +- ExtractFeatureBoundaries2D.d3dpipeline ## License & Copyright -Please see the description file distributed with this plugin. +Please see the description file distributed with this **Plugin** ## DREAM3D-NX Help diff --git a/src/Plugins/SimplnxCore/docs/ExtractInternalSurfacesFromTriangleGeometryFilter.md b/src/Plugins/SimplnxCore/docs/ExtractInternalSurfacesFromTriangleGeometryFilter.md index 90fd3d3b71..edee05406d 100644 --- a/src/Plugins/SimplnxCore/docs/ExtractInternalSurfacesFromTriangleGeometryFilter.md +++ b/src/Plugins/SimplnxCore/docs/ExtractInternalSurfacesFromTriangleGeometryFilter.md @@ -6,13 +6,15 @@ Geometry ## Description -This **Filter** extracts any **Triangles** from the supplied **Triangle Geometry** that contain any *internal nodes*, then uses these extracted **Triangles** to create a new **Data Container** with the reduced **Triangle Geometry**. This operation is the same as removing all **Triangles** that only lie of the outer surface of the supplied **Triangle Geometry**. The user must supply a "Node Type" **Vertex Attribute Array** that defines the type for each node of the **Triangle Geometry**. Node types may take the following values: +This **Filter** extracts the **Triangles** from a **Triangle Geometry** that contain *internal nodes*, and uses those extracted **Triangles** to create a new **Triangle Geometry** in a new data group. This is equivalent to removing every **Triangle** that lies only on the outer surface of the supplied **Triangle Geometry**. + +The user must supply a "Node Type" **Vertex Attribute Array** that classifies each node of the **Triangle Geometry**. This node-type array is normally created when the original surface mesh is generated by [Create Surface Mesh (Surface Nets)](SurfaceNetsFilter.md) or [Create Surface Mesh (QuickMesh)](QuickSurfaceMeshFilter.md). The node types may take the following values: ### Quick Surface Mesh | Id Value | Node Type | |----------|-----------| -| 2 | Normal **Vertex | +| 2 | Normal **Vertex** | | 3 | Triple Line | | 4 | Quadruple Point | | 12 | Normal **Vertex** on the outer surface | @@ -23,21 +25,28 @@ This **Filter** extracts any **Triangles** from the supplied **Triangle Geometry | Id Value | Node Type | |----------|-----------| -| 0 | Normal **Vertex | +| 0 | Normal **Vertex** | | 3 | Triple Line | | 4-8 | Quadruple Point | | 13 | Normal **Vertex** on the outer surface | | 14 | Triple Line on the outer surface | | 15-18 | Quadruple Point on the outer surface | -This **Filter** has the effect of removing any **Triangles** that only contain **Vertices** whose node Id values fall outside of the min and max that the user sets. In general, this *node type* array is created when the original surface mesh is created. +This **Filter** removes any **Triangle** that contains only **Vertices** whose node Id values fall outside the minimum and maximum that the user sets. It is unknown until runtime how the **Geometry** will be changed by removing certain **Vertices** and **Triangles**. -% Auto generated parameter table will be inserted here +### Required Input Sources + +- **Triangle Geometry** -- the surface mesh to process, typically produced by [Create Surface Mesh (Surface Nets)](SurfaceNetsFilter.md) or [Create Surface Mesh (QuickMesh)](QuickSurfaceMeshFilter.md). +- **Node Types** -- the per-vertex node classification array, produced by the same surface-meshing filter that created the geometry. -## Example Pipelines +% Auto generated parameter table will be inserted here ## License & Copyright -Please see the description file distributed with this plugin. +Please see the description file distributed with this **Plugin** + +## DREAM3D-NX Help + +If you need help, need to file a bug report or want to request a new feature, please head over to the [DREAM3DNX-Issues](https://github.com/BlueQuartzSoftware/DREAM3DNX-Issues/discussions) GitHub site where the community of DREAM3D-NX users can help answer your questions. diff --git a/src/Plugins/SimplnxCore/docs/ExtractPipelineToFileFilter.md b/src/Plugins/SimplnxCore/docs/ExtractPipelineToFileFilter.md index 5c9dce5bb0..ed034916f1 100644 --- a/src/Plugins/SimplnxCore/docs/ExtractPipelineToFileFilter.md +++ b/src/Plugins/SimplnxCore/docs/ExtractPipelineToFileFilter.md @@ -1,9 +1,19 @@ # Extract DREAM3D-NX Pipeline To File +## Group (Subgroup) + +IO (Output) + ## Description This **Filter** reads the pipeline from an hdf5 file with the .dream3d extension and writes it back out to a json formatted pipeline file with the appropriate extension based on whether the pipeline is a DREAM3D-NX version 6 (.json) or DREAM3D-NX version 7 (.d3dpipeline) formatted pipeline. +A `.dream3d` file *may* contain an embedded copy of the pipeline that produced it, but this is not guaranteed (for example, files written by external tools, or written with pipeline embedding disabled, will not have one). If the selected `.dream3d` file does not contain an embedded pipeline, this **Filter** has nothing to extract and will report an error rather than write an empty file. + +### Required Input Sources + +None -- the input is a `.dream3d` file selected by file path, not a **DataStructure** object created by an upstream filter. + % Auto generated parameter table will be inserted here ## Example Pipelines @@ -12,4 +22,8 @@ ExtractPipelineToFile ## License & Copyright -Please see the description file distributed with this plugin. +Please see the description file distributed with this **Plugin** + +## DREAM3D-NX Help + +If you need help, need to file a bug report or want to request a new feature, please head over to the [DREAM3DNX-Issues](https://github.com/BlueQuartzSoftware/DREAM3DNX-Issues/discussions) GitHub site where the community of DREAM3D-NX users can help answer your questions. diff --git a/src/Plugins/SimplnxCore/docs/ExtractVertexGeometryFilter.md b/src/Plugins/SimplnxCore/docs/ExtractVertexGeometryFilter.md index 2e03705bae..a4acf93c72 100644 --- a/src/Plugins/SimplnxCore/docs/ExtractVertexGeometryFilter.md +++ b/src/Plugins/SimplnxCore/docs/ExtractVertexGeometryFilter.md @@ -6,13 +6,17 @@ Core Filters (Geometry) ## Description -This filter will extract all the voxel centers of an Image Geometry or a RectilinearGrid geometry -into a new Vertex Geometry. The user is given the option to copy or move cell arrays over to the -newly created VertexGeometry. The user can also supply a mask array which has the effect of only +This filter will extract all the voxel centers of an **Image Geometry** or a **Rectilinear Grid Geometry** +into a new **Vertex Geometry**. The user is given the option to copy or move cell arrays over to the +newly created **Vertex Geometry**. The user can also supply a mask array which has the effect of only creating a vertex if the mask value = TRUE. ![Example showing the use of a Mask array to only generate specific points.](Images/ExtractVertexGeometry_1.png) +### Required Input Sources + +- **Image Geometry** or **Rectilinear Grid Geometry** -- the grid whose voxel/cell centers will be extracted as vertices. + ### Array Handling The *Array Handling* parameter controls how the selected cell arrays are transferred to the new **Vertex Geometry**: diff --git a/src/Plugins/SimplnxCore/docs/FeatureFaceCurvatureFilter.md b/src/Plugins/SimplnxCore/docs/FeatureFaceCurvatureFilter.md index dde27f2b8c..b74f8388b6 100644 --- a/src/Plugins/SimplnxCore/docs/FeatureFaceCurvatureFilter.md +++ b/src/Plugins/SimplnxCore/docs/FeatureFaceCurvatureFilter.md @@ -6,28 +6,33 @@ Surface Meshing (Curvature) ## Description -This **Filter** calculates *principal direction vectors* and the *principal curvatures*, and optionally the *mean* and *Gaussian* curvature, for each **Triangle** in a **Triangle Geometry** using the technique in [1]. The groups of **Triangles** over which to compute the curvatures is determines by the **Features** they are associated, denoted by their **Face Labels**. The curvature information will be stored in a **Face Attribute Matrix**. +This filter calculates *principal direction vectors* and the *principal curvatures*, and optionally the *mean* and *Gaussian* curvature, for each **Triangle** in a **Triangle Geometry** (a surface mesh built from triangles) using the technique in [1]. The groups of **Triangles** over which to compute the curvatures are determined by the **Features** they belong to, as denoted by their **Face Labels** (the pair of **Feature** Ids on either side of each triangle). The curvature information is stored in a **Face Attribute Matrix**. -Principal Curvatures 1 and 2 are the κ 1 and κ 2 from [1] and are the eigenvalues from the Wiengarten matrix. The Principal Directions 1 and 2 are the eigenvectors from the solution to the least squares fit algorithm. The Mean Curvature is (κ 1 + κ 2 ) / 2, while the Gaussian curvature is (κ 1 * -κ 2 ). +**Curvature** measures how sharply the surface bends at a point: a flat region has zero curvature, while a tightly rounded region has high curvature. The *principal curvatures* are the maximum and minimum bending values at a point, and the *principal directions* are the (unit) directions along the surface in which those extreme bends occur. -The values of the principal directions can have their signs flipped. They are calculated using eigenvectors which are unique up to a sign. +Principal Curvatures 1 and 2 are the κ1 and κ2 from [1] and are the eigenvalues of the Weingarten matrix. The Principal Directions 1 and 2 are the eigenvectors from the solution to the least-squares fit. The Mean Curvature is (κ1 + κ2) / 2, while the Gaussian curvature is (κ1 * κ2). + +The principal directions can have their signs flipped: they come from eigenvectors, which are unique only up to a sign. *Note*: Computing the Weingarten matrix values is an experimental feature, and there is no guarantee at this time that the values are correct. +### Units + +Principal curvatures and mean curvature are reported in **1/length** (the reciprocal of the geometry length units; the radius of the best-fit circle is its reciprocal). Gaussian curvature, being a product of two curvatures, is reported in **1/length^2**. Principal directions are **dimensionless** unit 3-vectors. + ![Curvature Coloring](Images/FeatureFaceCurvatureFilter_3.png) -@image latex FeatureFaceCurvatureFilter.png "Curvature Coloring of a Feature" width = 6in ## Ring Neighbor Schematic ![Ring Neighbor Schematic](Images/FeatureFaceCurvatureFilter_1.png) -## Parameter Notes: - -- The "Feature Face Ids" input data can be computed from the "Compute Triangle Face Ids" filter -- The "Face Normals" input data can be computed from the "Compute Triangle Normals" filter -- The "Face Centroids" input data can be computed from the "Compute Triangle Centroids" filter +### Required Input Sources +- **Triangle Geometry** -- a surface mesh, typically produced by a surface-meshing filter such as [Create Surface Mesh (Surface Nets)](SurfaceNetsFilter.md) or [Create Surface Mesh (QuickMesh)](QuickSurfaceMeshFilter.md). +- **Face Labels** -- the per-triangle pair of **Feature** Ids, produced alongside the mesh by the surface-meshing filter above. +- **Feature Face Ids** -- computed by [Compute Triangle Face Ids](SharedFeatureFaceFilter.md). +- **Face Normals** -- computed by [Compute Triangle Normals](TriangleNormalFilter.md). +- **Face Centroids** -- computed by [Compute Triangle Centroids](TriangleCentroidFilter.md). % Auto generated parameter table will be inserted here @@ -37,13 +42,13 @@ The values of the principal directions can have their signs flipped. They are ca ## Example Pipelines -- Pipelines -> SimplnxCore -> Compute_Feature_Face_Curvature -- Pipelines -> SimplnxCore -> Compute_Feature_Face_Curvature_2 +- Compute_Feature_Face_Curvature +- Compute_Feature_Face_Curvature_2 ## License & Copyright -Please see the description file distributed with this**Plugin** +Please see the description file distributed with this **Plugin** -## DREAM3D-NX Mailing Lists +## DREAM3D-NX Help -If you need more help with a**Filter**, please consider asking your question on the [DREAM3D-NX Users Google group!](https://groups.google.com/forum/?hl=en#!forum/dream3d-users) +If you need help, need to file a bug report or want to request a new feature, please head over to the [DREAM3DNX-Issues](https://github.com/BlueQuartzSoftware/DREAM3DNX-Issues/discussions) GitHub site where the community of DREAM3D-NX users can help answer your questions. diff --git a/src/Plugins/SimplnxCore/docs/FillBadDataFilter.md b/src/Plugins/SimplnxCore/docs/FillBadDataFilter.md index ac1f800efc..2eb2d2cb2a 100644 --- a/src/Plugins/SimplnxCore/docs/FillBadDataFilter.md +++ b/src/Plugins/SimplnxCore/docs/FillBadDataFilter.md @@ -6,45 +6,47 @@ Processing (Cleanup) ## Description -This **Filter** removes small *noise* in the data but keeps larger regions that are possibly **Features**, e.g., pores or defects. This **Filter** identifies *bad* **Cells** (*Feature Id = 0*) and fills small defects by copying data from neighboring good cells, while preserving large defect regions that meet or exceed the minimum allowed defect size specified by the user. +This **Filter** distinguishes small *bad-data noise* from large *real defects* in a segmented dataset and fills only the noise. **Cells** with *Feature Id = 0* are considered *bad*; the filter groups them into connected components, classifies each component by its size, and fills components below the user threshold by copying the most common neighbor's data into them. Components at or above the threshold are left intact, since they likely represent real features (pores, cracks, voids). | Small IN100 Before | Small IN100 After | |--------------------------------------|-------------------------------------| | ![](Images/fill_bad_data_before.png) | ![](Images/fill_bad_data_after.png) | -The above images show the before and after results of running this filter with a minimum defect size of 1000 voxels. Note that because the minimum defect size was set to 1000 voxels that the over scan area was not modified (the area in all black around the sample). +The above images show the before and after results of running this filter with a minimum defect size of 1000 voxels. The all-black overscan area around the sample exceeds the 1000-voxel threshold, so it is correctly preserved. -## Algorithm Overview +### How This Filter Works -The filter uses a four-phase algorithm optimized for both in-memory and out-of-core data processing: +1. **Connected components.** All bad cells (*Feature Id = 0*) are grouped into connected regions using face neighbors. +2. **Classify by size.** + - Components with fewer than *Minimum Allowed Defect Size* cells are flagged as *small noise* and filled. + - Components with at least *Minimum Allowed Defect Size* cells are kept as bad data, or optionally moved to a new phase if *Store Defects as New Phase* is enabled. +3. **Iterative fill.** Each cell flagged for filling examines its 6 face neighbors and copies all cell-level array data from whichever neighbor's *Feature Id* is most common. The pass repeats until every flagged cell has been filled. -### Phase 1: Connected Component Labeling (CCL) -The algorithm first identifies all connected regions of bad data (voxels with Feature Id = 0) using a chunk-sequential scanline algorithm. Each connected component is assigned a unique provisional label, and equivalences between components that span chunk boundaries are tracked using a Union-Find data structure. +### Minimum Defect Size Units -### Phase 2: Global Resolution -All provisional labels are resolved to their root representatives, and the total size (voxel count) of each connected component is computed by aggregating counts across all chunks. +The *Minimum Allowed Defect Size* is in **cells** (integer voxel count), not physical units. To convert a physical-volume threshold into a cell count, divide by the cell volume (dx * dy * dz). -### Phase 3: Classification and Relabeling -Each connected component is classified based on its size: -- **Small defects** (size < minimum allowed defect size): Marked with Feature Id = -1 for filling -- **Large defects** (size ≥ minimum allowed defect size): Retained as Feature Id = 0 (or assigned to a new phase if requested) +Choose the threshold based on what you want to keep: -### Phase 4: Iterative Morphological Fill -Small defects are filled using an iterative erosion process: -1. For each voxel marked for filling (Feature Id = -1), examine its 6 face-connected neighbors -2. Determine the most common positive Feature Id among the neighbors -3. Copy all cell array data from that neighbor to the current voxel -4. Repeat until all small defects are filled +- For removing single-cell or small-cluster EBSD scan noise, **5-50 cells** is typical. +- For preserving real pores while cleaning small noise (as in the example above), thresholds of **500-5000 cells** depend on pore size. -The algorithm processes data in a chunk-sequential manner, making it efficient for large datasets stored using out-of-core data structures. +### Store Defects as New Phase -## Performance Characteristics +When this option is enabled, any connected component that meets or exceeds the size threshold has its cells reassigned to a new phase index rather than being left as Feature Id 0. This makes large defects available to downstream filters as a distinct phase (e.g., for separate statistics or visualization). -This implementation is optimized for out-of-core processing where data may reside on disk rather than in memory. The chunk-sequential access pattern minimizes disk I/O operations compared to random-access algorithms, providing significant performance improvements for large datasets (10-100x faster for typical use cases with out-of-core storage). +### Performance Note + +The implementation is chunk-sequential and optimized for out-of-core data. For large datasets stored on disk, expect 10-100x speedups over random-access algorithms. ## WARNING: Feature Data Will Become Invalid -By modifying the cell level data, any feature data that was previously computed will most likely be invalid at this point. Filters that compute feature level data should be rerun to ensure accurate final results from your pipeline. +By modifying cell-level data, any feature-level data that was previously computed (sizes, centroids, average orientations, etc.) will most likely be invalid after this filter runs. Re-run any downstream feature-level computation filters to ensure accurate results. + +### Required Input Sources + +- **Cell Feature Ids** -- produced by a segmentation filter such as [Segment Features (Misorientation)](../OrientationAnalysis/EBSDSegmentFeaturesFilter.md) or [Segment Features (Scalar)](ScalarSegmentFeaturesFilter.md). Cells with Feature Id = 0 are treated as bad. +- **Cell Phases** -- typically read from EBSD data; only required when *Store Defects as New Phase* is enabled. % Auto generated parameter table will be inserted here diff --git a/src/Plugins/SimplnxCore/docs/FlyingEdges3DFilter.md b/src/Plugins/SimplnxCore/docs/FlyingEdges3DFilter.md index 2afbb9becc..540f4a38e9 100644 --- a/src/Plugins/SimplnxCore/docs/FlyingEdges3DFilter.md +++ b/src/Plugins/SimplnxCore/docs/FlyingEdges3DFilter.md @@ -6,11 +6,29 @@ Visual Analysis ## Description -This filter will draw a 3 dimensional contouring surface through an Image Geometry based on an input value. +This filter generates a 3D **isosurface** (a contour surface) through the scalar values stored on an **Image Geometry**, and saves it as a **Triangle Geometry**. -Here's what the results look like: +### What is an Isosurface? -![3D-Contouring](Images/FlyingEdges3D_1.png) +An **isosurface** is the 3D equivalent of a contour line on a topographic map. Given a scalar value at every **Cell** of a volume (for example density from a CT scan, or a distance field), the isosurface is the connected surface that passes through every point where the scalar equals a chosen threshold — the *Contour Value* (also called the isovalue). Cells with values above the threshold fall on one side of the surface; cells below fall on the other. + +"Flying Edges" is a fast, parallel variant of the classic marching-cubes algorithm. It produces the same triangulated surface but scans the volume more efficiently. + +### When to Use This Filter + +Use this filter to extract a smooth surface from continuous scalar data (CT density, a level-set/distance field, simulation output). If the goal is instead to build a surface mesh around labeled regions (**Feature** Ids from a segmentation), use [Surface Nets](SurfaceNetsFilter.md) or [Quick Surface Mesh](QuickSurfaceMeshFilter.md), which contour an integer label map rather than a continuous field. + +### Parameter Guidance + +- **Contour Value** — the scalar threshold the surface is drawn at. Its units are the same as the selected **Data Array** (for CT data, density units; for a distance field, length units). The surface only appears where the data actually crosses this value, so the value must lie within the array's range. +- **Data Array to Contour** — the per-Cell scalar field the contour is computed from. + +### Required Input Sources + +- **Image Geometry** -- the volume to contour, typically from an image/volume reader such as [Read Image](ReadImageFilter.md) or an upstream processing filter. +- **Data Array to Contour** -- any single-component scalar **Cell Data** array on that geometry. + +![A 3D contour surface extracted from an Image Geometry at the chosen Contour Value.](Images/FlyingEdges3D_1.png) % Auto generated parameter table will be inserted here @@ -18,6 +36,6 @@ Here's what the results look like: Please see the description file distributed with this **Plugin** -## DREAM3D-NX Interaction +## DREAM3D-NX Help -If you need more help with a **Filter**, please consider asking your question on the [DREAM3D-NX Help Forum!](https://github.com/BlueQuartzSoftware/DREAM3DNX-Issues/discussions) +If you need help, need to file a bug report or want to request a new feature, please head over to the [DREAM3DNX-Issues](https://github.com/BlueQuartzSoftware/DREAM3DNX-Issues/discussions) GitHub site where the community of DREAM3D-NX users can help answer your questions. diff --git a/src/Plugins/SimplnxCore/docs/HierarchicalSmoothFilter.md b/src/Plugins/SimplnxCore/docs/HierarchicalSmoothFilter.md index a0538686fc..64aa6d22e5 100644 --- a/src/Plugins/SimplnxCore/docs/HierarchicalSmoothFilter.md +++ b/src/Plugins/SimplnxCore/docs/HierarchicalSmoothFilter.md @@ -97,15 +97,7 @@ This safety mechanism prevents the smoothing from producing mesh artifacts in re ![](Images/HierarchicalSmooth_error_threshold.png) -## Parameters - -| Name | Type | Description | Default | -|------|------|-------------|---------| -| Max Bisection Iterations | Int32 | Maximum number of bisection iterations for smoothing parameter optimization (see above) | 53 | -| Error Threshold | Float64 | Displacement rejection threshold as a multiple of the reference edge length (see above) | 2.0 | -| Triangle Geometry | Geometry Selection | The triangle geometry to smooth | - | -| Node Type | Array Selection (Int8, 1-comp) | Array specifying node type (2=interior, 3=triple, 4=quad; +10 for surface) | - | -| Face Labels | Array Selection (Int32, 2-comp) | Array specifying grain IDs on either side of each face | - | +In addition to the two numeric parameters described above, the filter requires the **Triangle Geometry** to smooth, a per-vertex **Node Type** array (Int8, single-component: 2 = interior, 3 = triple line, 4 = quad point; add 10 for the outer-surface variants), and a per-face **Face Labels** array (Int32, 2-component) giving the grain IDs on either side of each face. These three inputs are normally produced together by a surface-meshing filter. Unlike simple [Laplacian Smoothing](LaplacianSmoothingFilter.md), this filter uses the **Node Type** and **Face Labels** information to respect the topological hierarchy of the boundary network. ## Notes @@ -115,6 +107,10 @@ This safety mechanism prevents the smoothing from producing mesh artifacts in re - The conjugate gradient solver handles its own internal convergence; the max iterations parameter controls only the bisection search for the optimal smoothing parameter, not the CG solver iterations. - If the filter reports rejected nodes, consider increasing the Error Threshold or inspecting the input mesh for degenerate triangles near the rejected vertices. +## Required Input Sources + +- **Triangle Geometry**, **Node Type**, and **Face Labels** -- a polycrystalline surface mesh and its node-type and face-label arrays, produced together by a surface-meshing filter such as [Quick Surface Mesh](QuickSurfaceMeshFilter.md). + % Auto generated parameter table will be inserted here ## Reference @@ -122,12 +118,10 @@ This safety mechanism prevents the smoothing from producing mesh artifacts in re - S. Maddali, "HierarchicalSmooth" - Topology-aware smoothing for polycrystalline grain boundary networks. Carnegie Mellon University, 2016-2018. - S. Maddali, S. Ta'asan, R. M. Suter, Topology-faithful nonparametric estimation and tracking of bulk interface networks, Computational Materials Science 125, 328-340 (2016). -## Example Pipelines - ## License & Copyright -Please see the description file distributed with this plugin. +Please see the description file distributed with this **Plugin** -## DREAM3D Mailing Lists +## DREAM3D-NX Help If you need help, need to file a bug report or want to request a new feature, please head over to the [DREAM3DNX-Issues](https://github.com/BlueQuartzSoftware/DREAM3DNX-Issues/discussions) GitHub site where the community of DREAM3D-NX users can help answer your questions. diff --git a/src/Plugins/SimplnxCore/docs/IdentifyDuplicateVerticesFilter.md b/src/Plugins/SimplnxCore/docs/IdentifyDuplicateVerticesFilter.md index c93944fc51..52eeb1d9c7 100644 --- a/src/Plugins/SimplnxCore/docs/IdentifyDuplicateVerticesFilter.md +++ b/src/Plugins/SimplnxCore/docs/IdentifyDuplicateVerticesFilter.md @@ -6,7 +6,9 @@ Meshing (Cleanup) ## Description -This filter takes a geometry with a **SharedVertexList** and produces a `uint8` mask that contains `1` in positions where a duplicate of an existing vertex exists. It should be noted that this filter utilizes quicksort to speed up checks, quick sort is not a stable sort meaning the vertex point deemed "unique" (ie not labeled as a duplicate) is not guaranteed to be the first instance of the vertex point. See example section below for a visual explanation. The intention is for this filters output to be used as the input for *RemoveFlaggedVertices*. +This filter takes a geometry with a **SharedVertexList** and produces a `uint8` mask that contains `1` at the position of each vertex that duplicates an earlier vertex, and `0` otherwise. Two vertices are considered **duplicates** when their X, Y, and Z coordinates are all equal (the comparison treats coordinate differences smaller than machine epsilon as equal, so this is effectively exact coordinate equality); no user-supplied tolerance is applied. + +It should be noted that this filter utilizes quicksort to speed up checks. Quicksort is not a stable sort, meaning the vertex deemed "unique" (i.e., not labeled as a duplicate) is not guaranteed to be the first instance of that coordinate in the original list. See the example below, which uses small text arrays to illustrate this behavior. The intention is for this filter's output to be used as the input for [Remove Flagged Vertices](RemoveFlaggedVerticesFilter.md). ## Example diff --git a/src/Plugins/SimplnxCore/docs/IdentifySampleFilter.md b/src/Plugins/SimplnxCore/docs/IdentifySampleFilter.md index 333175f841..dfa14deb64 100644 --- a/src/Plugins/SimplnxCore/docs/IdentifySampleFilter.md +++ b/src/Plugins/SimplnxCore/docs/IdentifySampleFilter.md @@ -6,21 +6,21 @@ Processing (Cleanup) ## Description -Often when performing a serial sectioning experiment (especially in the FIB-SEM), the sample is *over scanned* resulting -in a border of *bad* data around the sample. This **Filter** attempts to *identify* the sample within the over scanned -volume. The **Filter** makes the assumption that there is only one contiguous set of **Cells** that belong to the sample. -The **Filter** requires that the user has already *thresheld* the data to determine which **Cells** are *good* and which -are *bad*. The algorithm for the identification of the sample is then as follows: +Serial-sectioning experiments -- especially FIB-SEM -- typically *over-scan* the sample area, producing a border of *bad* data around the actual sample. This **Filter** identifies the sample within that over-scanned volume by finding the single largest contiguous region of *good* cells. -1. Search for the largest contiguous set of *good* **Cells**. (This is assumed to be the sample) -2. Change all other *good* **Cells** to be *bad* **Cells**. (This removes the "speckling" of what was *threshold* as *good* data in the outer border region) +The filter assumes that the sample is one connected set of cells, and it requires that the user has already produced a boolean mask marking which cells are *good* and which are *bad* -- typically via [Multi-Threshold Objects](MultiThresholdObjectsFilter.md) applied to a confidence or quality array. -If *Fill Holes* is set to *true* additional steps are taken: +The algorithm is: -1. Search for the largest contiguous set of *bad* **Cells**. (This is assumed to be the outer border region) -2. Change all other *bad* **Cells** to be *good* **Cells**. (This removes the "speckling" of what was *threshold* as *bad* data inside the sample). +1. Search for the largest contiguous set of *good* cells. This is assumed to be the sample. +2. Change all other *good* cells to *bad*. (This removes the "speckling" of *good* cells in the outer border region.) -*Note:* if there are in fact "holes" in the sample, then this **Filter** will "close" them (if *Fill Holes* is set to true) by calling all the **Cells** "inside" the sample *good*. If the user wants to reidentify those holes, then reuse the threshold **Filter** with the criteria of *GoodVoxels = 1* and whatever original criteria identified the "holes" as this will limit applying those original criteria to within the sample and not the outer border region. +If *Fill Holes* is enabled, two additional steps are run: + +1. Search for the largest contiguous set of *bad* cells. This is assumed to be the outer border region. +2. Change all other *bad* cells to *good*. (This removes the "speckling" of *bad* cells inside the sample.) + +*Note:* If the sample contains real holes, enabling *Fill Holes* will close them by calling all cells "inside" the sample *good*. To reidentify those holes afterward, re-run the threshold filter with the criteria *GoodVoxels = 1* AND whatever original criterion identified the holes. This limits the original hole-finding criteria to within the sample and not the outer border region. ## Slice-By-Slice Option @@ -46,6 +46,10 @@ When *Process Data Slice-By-Slice* is enabled, the *Slice-By-Slice Plane* parame - **XZ [1]**: Processes the volume slice by slice along the Y axis, scanning each XZ plane independently. - **YZ [2]**: Processes the volume slice by slice along the X axis, scanning each YZ plane independently. +### Required Input Sources + +- **Good Voxels Mask** -- a boolean array marking cells as *good* or *bad*, typically produced by [Multi-Threshold Objects](MultiThresholdObjectsFilter.md) applied to EBSD confidence index, image quality, or a similar scalar. + % Auto generated parameter table will be inserted here ## Example Pipelines diff --git a/src/Plugins/SimplnxCore/docs/InitializeDataFilter.md b/src/Plugins/SimplnxCore/docs/InitializeDataFilter.md index 09ab8dbb0f..847a117a04 100644 --- a/src/Plugins/SimplnxCore/docs/InitializeDataFilter.md +++ b/src/Plugins/SimplnxCore/docs/InitializeDataFilter.md @@ -6,73 +6,80 @@ Processing (Cleanup) ## Description -This **Filter** allows the user to define the data set in a _DataArray_. +This **Filter** overwrites every tuple in a **Data Array** with a value chosen by one of four initialization modes. Multi-component arrays can be initialized either uniformly (one value applied to every component) or per-component (a semicolon-separated list). ### Initialization Type -The *Initialization Type* parameter provides the following choices: +The *Initialization Type* parameter provides four modes: -- **Fill Value [0]**: Copies a user-supplied constant value (or per-component values) into every tuple in the array. -- **Incremental [1]**: Fills the array starting from a user-supplied value and applying a fixed step (increment or decrement) to each successive tuple. -- **Random [2]**: Generates random values across the full scalar type range. An optional fixed seed can be supplied for reproducibility. -- **Random With Range [3]**: Generates random values within a user-specified minimum/maximum range per component. +- **Fill Value [0]** -- every tuple is set to a user-supplied constant value (or per-component values). +- **Incremental [1]** -- the array is filled starting from a user-supplied starting value, applying a fixed step (increment or decrement) to each successive tuple. +- **Random [2]** -- every tuple is set to a uniformly-random value drawn from the **full range** of the array's data type. An optional fixed seed can be supplied for reproducibility. +- **Random With Range [3]** -- every tuple is set to a uniformly-random value drawn from a user-specified [min, max] interval per component. + +#### Fill Value + +Provide a single value or, for multi-component arrays, a semicolon-separated list. The same value is copied into every tuple. + +#### Incremental + +Provide a starting value, a *Step Operation* (Addition or Subtraction), and a step value. Each successive tuple's value is the previous tuple's value plus (or minus) the step. A step value of 0 leaves that component unchanged across all tuples. + +Example -- a 3-component array filled with 3-D rotations in radians, stepping X and Y but not Z: + +- Starting value: `0` +- Step Operation: Addition +- Step Values: `3.141592;6.283185;0` + +#### Random and Random With Range + +Both modes draw uniformly. *Random* uses the full data-type range; *Random With Range* honors a per-component lower and upper bound. Both modes use the same random seed plumbing: + +- *Use Seed for Random Generation* + *Seed Value* -- supply a fixed integer seed for reproducibility. +- With the option disabled, a time-based seed is generated; the actual seed used is saved to the *Stored Seed Value Array* so the run can be reproduced later. + +*Standardize Seed* (Random mode only) controls whether all components in a tuple share the same random draw: + +- ON: a single value is drawn per tuple and broadcast to all components: `| 3;3;3 | 9;9;9 | 4;4;4 | ...` +- OFF: each component is drawn independently: `| 3;9;4 | 7;2;8 | 5;9;6 | ...` + +For *Random With Range* on a multi-component array, the lower and upper bounds are semicolon-separated per component. A trick for fixing one component while randomizing the others: set the lower and upper bound to the same value for the fixed component. Example -- 3-component array where the middle component is always 6 and the others vary: + +- Lower bound: `0;6;0` +- Upper bound: `90;6;252` ### Step Operation -The *Step Operation* parameter (used with **Incremental** initialization) provides the following choices: - -- **Addition [0]**: Adds the step value to the previous tuple's value at each successive tuple. -- **Subtraction [1]**: Subtracts the step value from the previous tuple's value at each successive tuple. - -This **Filter** provides several ways to do this: - -- Fill Value: - - This type is fairly straight forward you provide a value, or set of values for a multi-component array, and it gets copied into every tuple in the array. - - Nuances to note: - - None for this type aside from aforementioned boolean nuances -- Incremental: - - This allows the user to supply a start value, define the type (increment or decrement), and set a step value to for the operation. Providing 0 will ensure that that component remains unchanged. - - Example: Say you have a 3 component array where you want to define 3-D rotations in radians for different components, but you only want to operate on the x and y and not the z; You could define your starting value as '0' (ignoring the apostrophe marks), select addition as the operation, then define the step values like so: '3.141592;6.283185;0' - - Boolean Nuances: - - For the _Step Values_ please enter uint8 values, preferably a 0 or 1 only. - - Addition: - - Any step value that is greater than 0 will cause all values to be 'true' after the first tuple, 'true' values will remain unchanged. - - If your start value is 'false' and step value > 0, the array will initialize to | false | true | true | ... | - - If your start value is 'true' and step value > 0, the array will initialize to | true | true | true | ... | - - Subtraction: - - Any step value that is greater than 0 will cause all values to be 'false' after the first tuple, 'false' values will remain unchanged. - - If your start value is 'true' and step value > 0, the array will initialize to | true | false | false | ... | - - If your start value is 'false' and step value > 0, the array will initialize to | false | false | false | ... | -- Random: - - This allows the user to randomly generate values from the actual scalar type min to the scalar type max. If you choose to define the seed for the array the seed in the _Seed Value_ box will be used, otherwise a random seed will be generated. Either way the seed will be saved to the _Stored Seed Value Array_. - - **Standardizing Seed:** - - This value allows the user to be able to generate the same sequence of values for every component in the tuple throughout the array when set to true - - Example: - - When true it will look like | 3;3;3 | 9;9;9 | 4;4;4 | ... | - - When false it will look like | 3;9;4 | 7;2;8 | 5;9;6 | ... | -- Random with Range: - - This is beholden to the same rules as random with some additional considerations in relation to the range. - - If you require an array that has one stable component and other variable components you can define the lower and upper bounds of the range to be the same and the variable will never change. - - Example: Say you have a 3 component array where you want the middle component to be always be 6 and the other component to be randomized above six. When defining a range supply '6' (ignoring the apostrophe marks) for the lower bound and '90;6;252' for the upper bound - -The filter provides two ways to define the values in a multi-component array: - -- Define a single value that will be used for every component in the tuple -- Defining each component's value seperated by the semicolon ';' character - -Example: Say you have a 3 component array that you want to range that starts from zero and has unique end values for each component. In the starting value box just supply '0' (ignoring the apostrophe marks) and then define your end values in a list like this: '4;0;7' - -**Boolean Entry Notes:** - -The **ONLY** two ways to specify a 'false' boolean value are as follows: - -- boolean value string types as follows ignoring apostrophe marks: 'False', 'FALSE', 'false' -- all well-formed integers and well-formed floating point definitions of 0 - -**ANY OTHER** string or number **WILL BE** 'true', although it is good practice to define true values as follows: - -- boolean value string types as follows ignoring apostrophe marks: 'True', 'TRUE', 'true' -- all well-formed integers and well-formed floating point definitions of 1 +Used only with *Incremental*: + +- **Addition [0]** -- adds the step value to the previous tuple's value. +- **Subtraction [1]** -- subtracts the step value from the previous tuple's value. + +### Boolean Array Notes + +For boolean arrays, the only values that produce `false` are: + +- The strings `False`, `FALSE`, `false`. +- Any well-formed numeric `0` (integer or floating-point). + +**Any other** string or number is interpreted as `true`. Conventional `true` values are the strings `True`, `TRUE`, `true`, or the numeric `1`. + +For boolean arrays under *Incremental* mode, the *Step Operation* behaves as follows: + +- **Addition** with step value > 0: starting `false` produces `false, true, true, ...`; starting `true` produces all `true`. +- **Subtraction** with step value > 0: starting `true` produces `true, false, false, ...`; starting `false` produces all `false`. + +### Multi-Component Value Format + +Single value: applied to all components. Example: `2.5` initializes every component of every tuple to 2.5. + +Per-component values: semicolons separate components. Example for a 2-component array: `0;1` sets component 0 to 0 and component 1 to 1. + +Semicolons (rather than commas) are used to avoid international locale ambiguity (commas are decimal points in some locales). + +### Required Input Sources + +- **Input Data Array** -- the array to overwrite. Typically a previously created or imported array. % Auto generated parameter table will be inserted here diff --git a/src/Plugins/SimplnxCore/docs/InitializeImageGeomCellDataFilter.md b/src/Plugins/SimplnxCore/docs/InitializeImageGeomCellDataFilter.md index f61cc5d327..27a0dcb4aa 100644 --- a/src/Plugins/SimplnxCore/docs/InitializeImageGeomCellDataFilter.md +++ b/src/Plugins/SimplnxCore/docs/InitializeImageGeomCellDataFilter.md @@ -6,15 +6,36 @@ Processing (Cleanup) ## Description -This **Filter** allows the user to define a subvolume of the data set in which the **Filter** will reset all data for every **Cell** within the subvolume. The user can choose from three initialization modes: *Manual* (initialize to a user-specified value), *Random* (initialize with random values across the full range of the data type), or *Random With Range* (initialize with random values within a user-specified range). +This **Filter** overwrites every cell within a user-defined *subvolume* of an **Image Geometry** with either a constant value or random values. Use this to reset a region of interest, mask out an area for testing, or stub in synthetic data for development. + +### Subvolume Specification + +The subvolume is specified by minimum and maximum **cell indices** along each axis (X, Y, Z). Indices are **0-based, inclusive** -- a min of 5 and a max of 9 includes cells 5, 6, 7, 8, and 9 (5 cells). The min must be less than or equal to the max along each axis. The min must be at least 0 and the max must be less than the geometry's dimension along that axis. + +The subvolume operates **only on cells inside this index range**; cells outside are unaffected. ### Initialization Type -The *Initialization Type* parameter provides the following choices: +The *Initialization Type* parameter provides three modes: + +- **Manual [0]**: every cell in the subvolume is set to a single user-specified constant value. The value is reinterpreted into each array's data type (e.g., 1.5 → 1 for an int array, 1.5 → 1.5 for a float array, anything non-zero → true for a bool array). +- **Random [1]**: every cell is set to an independent random value drawn from the **full range of the array's data type**. For uint8, this means 0-255. For float32, this means the full IEEE-754 range (which produces extreme values rarely useful for visualization). +- **Random With Range [2]**: every cell is set to an independent random value drawn from the user-specified [min, max] interval. The min/max are interpreted in the array's data type. + +Multiple cell arrays can be initialized in one filter pass; each gets independently-drawn random values when in Random mode. + +### Random Seed + +The random modes use a configurable seed for reproducibility. Enable *Use Seed for Random Generation* and supply an integer to make results deterministic across pipeline runs. With the option disabled, a time-based seed is used (results vary per run). + +### Behavior on Boolean Arrays + +For boolean arrays in random modes, each cell is set to a uniformly-chosen true/false. Range parameters are ignored for boolean arrays. + +### Required Input Sources -- **Manual [0]**: Initializes every cell in the subvolume to a user-specified constant value. -- **Random [1]**: Initializes every cell in the subvolume with random values drawn from the full range of the data type. -- **Random With Range [2]**: Initializes every cell in the subvolume with random values drawn from a user-specified minimum/maximum range. +- **Input Image Geometry** -- the geometry whose cell data will be modified in-place. Typically produced by [Create Image Geometry](CreateImageGeometryFilter.md), [ITK Import Image Stack](../ITKImageProcessing/ITKImportImageStackFilter.md), or an EBSD reader. +- **Cell Attribute Arrays to Initialize** -- one or more cell-level arrays already attached to the geometry's Cell Attribute Matrix. % Auto generated parameter table will be inserted here diff --git a/src/Plugins/SimplnxCore/docs/InterpolatePointCloudToRegularGridFilter.md b/src/Plugins/SimplnxCore/docs/InterpolatePointCloudToRegularGridFilter.md index 98d61e0105..d0c16f39e9 100644 --- a/src/Plugins/SimplnxCore/docs/InterpolatePointCloudToRegularGridFilter.md +++ b/src/Plugins/SimplnxCore/docs/InterpolatePointCloudToRegularGridFilter.md @@ -69,6 +69,10 @@ Statistics are computed on the *weighted* values (`kernel_weight * source_value` Median is not supported because it requires storing every vertex's contribution, which would negate the memory savings of the flat accumulation approach. +### Required Input Sources + +- **Vertex Geometry** -- the point cloud whose arrays will be interpolated, produced by a filter that creates a **Vertex Geometry** such as [Extract Vertex Geometry](ExtractVertexGeometryFilter.md) or [Create Geometry](CreateGeometryFilter.md). + ### Mask An optional boolean or uint8 mask array may be provided. Vertices where the mask value is *false* or *0* are skipped entirely during interpolation – they do not contribute to any voxel's accumulated value or statistics. @@ -79,7 +83,7 @@ This filter uses flat arrays rather than variable-length lists, so memory usage ### Voxel Index Computation -The destination voxel for each vertex is computed on-the-fly from the vertex coordinates and the **Image Geometry**'s origin, spacing, and dimensions. There is no need to pre-compute a voxel indices array (e.g., via the *Map Point Cloud to Regular Grid* filter). Vertices whose coordinates fall outside the **Image Geometry** bounds are silently skipped. +The destination voxel for each vertex is computed on-the-fly from the vertex coordinates and the **Image Geometry**'s origin, spacing, and dimensions. There is no need to pre-compute a voxel indices array (e.g., via the [Map Point Cloud to Regular Grid](MapPointCloudToRegularGridFilter.md) filter). Vertices whose coordinates fall outside the **Image Geometry** bounds are silently skipped. % Auto generated parameter table will be inserted here diff --git a/src/Plugins/SimplnxCore/docs/IterativeClosestPointFilter.md b/src/Plugins/SimplnxCore/docs/IterativeClosestPointFilter.md index 34221c35b7..bff5cee45f 100644 --- a/src/Plugins/SimplnxCore/docs/IterativeClosestPointFilter.md +++ b/src/Plugins/SimplnxCore/docs/IterativeClosestPointFilter.md @@ -16,50 +16,61 @@ which we can describe in terms of "moving geometry" and "target geometry." The b 1. Initial State: We start with two sets of points or geometries. The "moving geometry" is the one we aim to align with the "target geometry." Initially, the moving geometry may be in any orientation or position relative to the target geometry. -1. Identify Correspondences: For each point in the moving geometry, we find the closest point in the target geometry. These +2. Identify Correspondences: For each point in the moving geometry, we find the closest point in the target geometry. These pairs of points are considered correspondences, based on the assumption that they represent the same point in space after the moving geometry is properly aligned. -1. Estimate Transformation: With the correspondences identified, the algorithm calculates the optimal rigid body +3. Estimate Transformation: With the correspondences identified, the algorithm calculates the optimal rigid body transformation (which includes translation and rotation) that best aligns the moving geometry to the target geometry. This step often involves minimizing a metric, such as the sum of squared distances between corresponding points, to find the best fit. -1. Apply Transformation: The calculated transformation is applied to the moving geometry, aligning it closer to the +4. Apply Transformation: The calculated transformation is applied to the moving geometry, aligning it closer to the target geometry. -1. Iterate: Steps 2 through 4 are repeated iteratively. With each iteration, the moving geometry is brought into closer +5. Iterate: Steps 2 through 4 are repeated iteratively. With each iteration, the moving geometry is brought into closer alignment with the target geometry. The iterations continue until a stopping criterion is met, which could be a predefined number of iterations, a minimum improvement threshold between iterations, or when the change in the error metric falls below a certain threshold. -Final Alignment: Once the iterations stop, the algorithm concludes with the moving geometry optimally aligned to the target +6. Final Alignment: Once the iterations stop, the algorithm concludes with the moving geometry optimally aligned to the target geometry, based on the criteria set for minimizing the differences between them. ICP has a number of advantages, such as robustness to noise and no requirement that the two sets of points to be the same size. However, performance may suffer if the two sets of points are of significantly different size. -## Saving the Output Transformation Matrix. +## Saving the Output Transformation Matrix -The format of the output DataArray is a flattened array 16 elements in size that represents a 4x4 matrix. -The elements are encoded in a ROW MAJOR array, i.e., +The filter always reports the computed rigid body transformation as an output **DataArray**. By default the moving geometry itself is left unchanged. If the *Apply Transformation to Moving Geometry* parameter is enabled, the filter also applies the transformation to the moving geometry's vertices in place, so that it is aligned to the target geometry. + +The output **DataArray** is a flattened array 16 elements in size that represents a 4x4 transformation matrix. +The elements are encoded in ROW MAJOR order, i.e., 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 -represents the following 4x4 Matrix +represents the following 4x4 matrix 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 +The upper-left 3x3 block holds the rotation, and the first three entries of the rightmost column (elements 4, 8, 12) hold the translation, expressed in the coordinate units of the input geometries. + +The reported matrix can be supplied to [Apply Transformation to Geometry](ApplyTransformationToGeometryFilter.md) to transform this or another geometry as a separate step. + +### Required Input Sources + +- **Moving Vertex Geometry** -- the **Vertex Geometry** to be aligned to the target. +- **Target Vertex Geometry** -- the fixed reference **Vertex Geometry**. The two geometries need not have the same number of points. + % Auto generated parameter table will be inserted here ## Example Pipelines ## License & Copyright -Please see the description file distributed with this plugin. +Please see the description file distributed with this **Plugin** ## DREAM3D-NX Help diff --git a/src/Plugins/SimplnxCore/docs/LabelTriangleGeometryFilter.md b/src/Plugins/SimplnxCore/docs/LabelTriangleGeometryFilter.md index 0150c0e50e..7ddbb33bc0 100644 --- a/src/Plugins/SimplnxCore/docs/LabelTriangleGeometryFilter.md +++ b/src/Plugins/SimplnxCore/docs/LabelTriangleGeometryFilter.md @@ -24,6 +24,10 @@ The image below shows a single STL file that contains 12 different geometries. T ![Filter Output](Images/LabelTriangleGeometry_1.png) +### Required Input Sources + +- **Triangle Geometry** -- the surface mesh whose triangles will be labeled, typically read from a CAD mesh via [Read STL File](ReadStlFileFilter.md). STL is a common CAD mesh file format that stores a surface as a collection of triangles. + % Auto generated parameter table will be inserted here ## License & Copyright @@ -32,4 +36,4 @@ Please see the description file distributed with this plugin. ## DREAM3D-NX Help -If you need help, need to file a bug report or want to request a new feature, please head over to the [DREAM3DNX-Issues](https://github.com/BlueQuartzSoftware/DREAM3DNX-Issues) GitHub site where the community of DREAM3D-NX users can help answer your questions. +If you need help, need to file a bug report or want to request a new feature, please head over to the [DREAM3DNX-Issues](https://github.com/BlueQuartzSoftware/DREAM3DNX-Issues/discussions) GitHub site where the community of DREAM3D-NX users can help answer your questions. diff --git a/src/Plugins/SimplnxCore/docs/LaplacianSmoothingFilter.md b/src/Plugins/SimplnxCore/docs/LaplacianSmoothingFilter.md index fc52a99704..78d7c298d0 100644 --- a/src/Plugins/SimplnxCore/docs/LaplacianSmoothingFilter.md +++ b/src/Plugins/SimplnxCore/docs/LaplacianSmoothingFilter.md @@ -6,26 +6,26 @@ Surface Meshing (Smoothing) ## Description -This **Filter** applies Laplacian smoothing to any node based geometry except for **vertex**. A. Belyaev [2] has a concise explanation of the Laplacian Smoothing as follows: +This **Filter** applies **Laplacian smoothing** to any node-based geometry except for a **Vertex Geometry**. Laplacian smoothing repeatedly moves each node toward the average position of its connected neighbors, which reduces high-frequency surface noise and tends to flatten the surface. A. Belyaev [1] gives a concise explanation: --------------------------- Let us consider a triangulated surface and for any vertex P let us define the so-called umbrella-operator -![](Images/Laplacian_Fig1.png) +![Definition of the umbrella-operator as a weighted sum over the neighbors of vertex P.](Images/Laplacian_Fig1.png) where summation is taken over all neighbors of P and wi are positive weights. See Fig. 1 for the geometric idea behind the umbrella-operator. -![](Images/Laplacian_Fig2.png) +![Geometric illustration of the umbrella-operator centered on vertex P and its neighbor ring.](Images/Laplacian_Fig2.png) -The weights, can be defined, for example, as the inverse distances between P and its neighbors. The simplest umbrella-operator is obtained if *w* i = 1 and the umbrella-operator has the form +The weights can be defined, for example, as the inverse distances between P and its neighbors. The simplest umbrella-operator is obtained if *w* i = 1 and the umbrella-operator has the form -![](Images/Laplacian_Eq1.png) +![Simplified umbrella-operator where every neighbor weight equals one, divided by the number of neighbors.](Images/Laplacian_Eq1.png) where n is the number of neighbors. The local update rule -![](Images/Laplacian_Eq2.png) +![Local update rule that moves vertex P by lambda times the umbrella-operator.](Images/Laplacian_Eq2.png) applied to every point of the triangulated surface is called Laplacian smoothing of the surface. Typically the factor λ is a small positive number, and the process (2) is executed repeatedly. The Laplacian smoothing algorithm reduces the high frequency surface information and tends to flatten the surface. See Fig. 2 where Laplacian smoothing is applied to a triangulated model of a Noh mask. @@ -33,17 +33,21 @@ If λ is too small, one needs more iterations for smoothing and the smooth --------------------------- -In the Laplacian algorithm the λ term has a range of 0 ≤ λ ≤ 1 and defines a relative distance that a node can move relative to the positions of the nodes neighbors. A λ = 0 value will effectively stop those node types from any movement during the algorithm thus by allowing the user to set this value for specific types of nodes the user can arrest the shrinkage of the surface mesh during the smoothing process. +In the Laplacian algorithm the λ term is dimensionless with a range of 0 ≤ λ ≤ 1 and defines the relative distance that a node can move toward the average position of its neighbors. A value of *λ = 0* effectively stops those node types from any movement during the algorithm. By setting this value for specific types of nodes, the user can arrest the shrinkage of the surface mesh during smoothing. ### Taubin's Lambda-Mu Smoothing Algorithm -One of the options for the filter allows the user to apply Taubin's Lambda-Mu variation on Laplacian smoothing. This variation removes the shrinkage typically found with Laplacian smoothing by adding an additional step within each iteration where the negative of the (Lambda value \* Mu Factor) which effectively moves the points in the **opposite** direction from the initial movement. Because of this negative movement the number of iterations to achieve the same level of smoothing is greatly increased, on the order of 10x to 20x. +One of the filter options applies **Taubin's Lambda-Mu** variation on Laplacian smoothing. This variation removes the shrinkage typically found with Laplacian smoothing by adding a second step within each iteration: it moves the points back by the negative of (*Lambda* * *Mu Factor*), effectively pushing them in the **opposite** direction from the initial movement. The *Mu Factor* is a dimensionless multiplier. Because of this negative movement, the number of iterations needed to achieve the same level of smoothing increases greatly, on the order of 10x to 20x. + +If you instead need a smoothing method that strictly preserves the mesh topology (triple lines, quadruple points, and feature boundaries), consider [Hierarchical Smoothing](HierarchicalSmoothFilter.md). ### Algorithm Usage and Memory Requirements -Currently, if you lock the *Default Lambda* value to zero (0), the triple lines and quadruple points will not be able to move because none of their neighbors can move. The user may want to consider allowing a small value of λ for the default nodes which will allow some movement of the triple lines and/or quadruple Points. +Currently, if you lock the *Default Lambda* value to zero (0), the **triple lines** (edges where three features meet) and quadruple points will not be able to move because none of their neighbors can move. The user may want to consider allowing a small value of λ for the default nodes, which will allow some movement of the triple lines and/or quadruple points. + +The *Iteration Steps* parameter is a dimensionless count of smoothing passes; more steps produce more smoothing. -This **Filter** will create additional internal arrays in order to facilitate the calculations. These arrays are +This **Filter** creates additional internal arrays to facilitate the calculations: - Float - lambda values (same size as nodes array) - 64 bit integer - unique edges array @@ -51,14 +55,11 @@ This **Filter** will create additional internal arrays in order to facilitate th - Integer for number of connections for each node (same size as nodes array) - 64 bit float for delta values (3x size of nodes array) -Due to these array allocations this **Filter** can consume large amounts of memory if the starting mesh has a large number of nodes. - -At the conclusion of the filter these extra internal arrays will be reclaimed by the system. - +Because of these array allocations, this **Filter** can consume large amounts of memory if the starting mesh has a large number of nodes. At the conclusion of the filter these extra internal arrays are reclaimed by the system. ### Node Type Values -The values for the *Node Type* array can take one of the following values. +The values for the *Node Type* array can take one of the following values: namespace SurfaceMesh { namespace NodeType { @@ -72,17 +73,20 @@ The values for the *Node Type* array can take one of the following values. } } -If your surface mesh is lacking a `Node Type` array, you can simply create a DataArray inside the Vertex Data Attribute Matrix. The type should be "int8" and have an initialization value of 3. This will allow **all** nodes to move. +If your surface mesh is lacking a `Node Type` array, you can create a DataArray inside the Vertex Data Attribute Matrix. The type should be "int8" with an initialization value of 3. This will allow **all** nodes to move. + +### Required Input Sources -For more information on surface meshing, visit the tutorial. +- **Triangle Geometry** -- the surface mesh to smooth, typically produced by a surface-meshing filter such as [Create Surface Mesh (Surface Nets)](SurfaceNetsFilter.md) or [Create Surface Mesh (QuickMesh)](QuickSurfaceMeshFilter.md). +- **Node Type** -- the per-vertex node classification array, produced by the same surface-meshing filter that created the geometry. % Auto generated parameter table will be inserted here ## References -[1] D. A. Feature, (1988) Laplacian smoothing and Delaunay triangulations. Commun. appl. numer. methods, 4: 709 712. doi: 10.1002/cnm.1630040603 +[1] A. Belyaev, *Mesh smoothing and enhancing curvature estimation*, lecture notes, Max-Planck-Institut fur Informatik. [http://www.mpi-inf.mpg.de/~ag4-gm/handouts/06gm_surf3.pdf](http://www.mpi-inf.mpg.de/~ag4-gm/handouts/06gm_surf3.pdf) -[2] A. Belyaev, Mesh smoothing and enhancing curvature estimation, [http://www.mpi-inf.mpg.de/ ag4-gm/handouts/06gm_surf3.pdf]( ag4-gm/handouts/06gm_surf3.pdf). +[2] Field, D. A. (1988). *Laplacian smoothing and Delaunay triangulations*. Communications in Applied Numerical Methods, 4(6): 709-712. doi:10.1002/cnm.1630040603 ## Example Pipelines diff --git a/src/Plugins/SimplnxCore/docs/MapPointCloudToRegularGridFilter.md b/src/Plugins/SimplnxCore/docs/MapPointCloudToRegularGridFilter.md index 28620ddf87..c2c4d6c02d 100644 --- a/src/Plugins/SimplnxCore/docs/MapPointCloudToRegularGridFilter.md +++ b/src/Plugins/SimplnxCore/docs/MapPointCloudToRegularGridFilter.md @@ -8,13 +8,15 @@ Sampling (Mapping) This **Filter** determines, for a user-defined grid, in which voxel each point in a **Vertex Geometry** lies. The user can either construct a sampling grid by specifying the dimensions, or select a pre-existing **Image Geometry** to use as the sampling grid. The voxel indices that each point lies in are stored on the vertices. -Additionally, the user may opt to use a mask; points for which the mask are false are ignored when computing voxel indices (instead, they are initialized to voxel 0). +Additionally, the user may opt to use a mask; points for which the mask is false are ignored when computing voxel indices (instead, they are initialized to voxel 0). + +The per-vertex voxel indices produced by this filter are commonly used as the input to [Interpolate Point Cloud to Regular Grid](InterpolatePointCloudToRegularGridFilter.md), which transfers point-cloud attribute values onto the regular grid. ### Sampling Grid Type The *Sampling Grid Type* parameter controls how the target grid is defined: -- **Manual [0]**: The user specifies the grid dimensions directly. The filter creates a new **Image Geometry** with those dimensions to use as the sampling grid. +- **Manual [0]**: The user specifies the grid dimensions directly as voxel counts along X, Y, and Z (dimensionless counts). The filter creates a new **Image Geometry** with those dimensions to use as the sampling grid. - **Use Existing Image Geometry [1]**: The user selects a pre-existing **Image Geometry** from the data structure to use as the sampling grid. ### Out of Bounds Handling @@ -35,16 +37,20 @@ The default selection is `Silent`, but it is mostly provided as a way to preserv - User may intend to create a workflow that will be distributed in which the end user may not have control over the parameter, but should be monitoring for anomalies in output - User may want to watch for unexpected behavior - `Error at First Instance` option - - User may to trace down where a anomaly first occurred + - User may want to trace down where an anomaly first occurred - User may be creating a pipeline in a known problem space with a well defined outcome where any data anomalies must be caught early to prevent downstream problems -Continuing along the Out-of-Bounds discussion, the Out-of-Bounds value allows the user to specify a specific `uint64` (0 - 18,446,744,073,709,551,616) value to use for every value from the vertex geometry that falls outside the image geometry. The default value is just the max `unsigned long long int` in an effort to make sure that it doesn't intersect with existing indexed values. This is identical to previous functionality. However, consider the situation where a user has a geometry that contains 1000 voxels, in this case the actual index values are 0-999, so a user could select 1000 and it wouldn't overlap any existing voxel index. Doing this may reduce skew of coloring or other statistic-based analysis. Advanced users may intentionally select a value that overlaps an existing voxel index they wish to remove in a later filter or to later downcast the datasize without overflow, but this is considered an edge case that is functional, but not recommended. +Continuing along the Out-of-Bounds discussion, the Out-of-Bounds value allows the user to specify a specific `uint64` (0 - 18,446,744,073,709,551,615) value to use for every value from the vertex geometry that falls outside the image geometry. The default value is just the max `unsigned long long int` in an effort to make sure that it doesn't intersect with existing indexed values. This is identical to previous functionality. However, consider the situation where a user has a geometry that contains 1000 voxels, in this case the actual index values are 0-999, so a user could select 1000 and it wouldn't overlap any existing voxel index. Doing this may reduce skew of coloring or other statistic-based analysis. Advanced users may intentionally select a value that overlaps an existing voxel index they wish to remove in a later filter or to later downcast the datasize without overflow, but this is considered an edge case that is functional, but not recommended. + +### Required Input Sources + +- **Vertex Geometry** -- the input point cloud whose points are mapped to grid voxels, typically created by an import step or a filter that produces a **Vertex Geometry**. % Auto generated parameter table will be inserted here ## License & Copyright -Please see the description file distributed with this plugin. +Please see the description file distributed with this **Plugin** ## DREAM3D-NX Help diff --git a/src/Plugins/SimplnxCore/docs/MoveDataFilter.md b/src/Plugins/SimplnxCore/docs/MoveDataFilter.md index 814595d1b3..e445cf7f56 100644 --- a/src/Plugins/SimplnxCore/docs/MoveDataFilter.md +++ b/src/Plugins/SimplnxCore/docs/MoveDataFilter.md @@ -6,7 +6,24 @@ Core (Memory/Management) ## Description -This **Filter** allows the user to move one or more **Data Objects** to a new parent **Group**. When moving a **Data Array** into an **Attribute Matrix**, the destination must be compatible, meaning the *number of tuples* must be equal (though the actual *tuple dimensions* need not match). +This **Filter** moves one or more **Data Objects** to a new parent **Group** (a **DataGroup**, **Attribute Matrix**, or **Geometry**). The objects retain their names; only their parent changes. + +### Tuple Compatibility When Moving Arrays + +When moving a **Data Array** *into* an **Attribute Matrix**, the destination must be tuple-compatible: the **number of tuples** of the array must equal the number of tuples implied by the destination matrix's tuple dimensions. The *shape* of the tuple dimensions does not need to match -- moving a 1-D array of 60 tuples into a (3, 4, 5) Attribute Matrix is allowed, because both equal 60 total tuples. Moving the same array into a (10, 10) matrix would fail (only 100 total tuples). + +When moving between non-Attribute-Matrix parents (e.g., between two DataGroups), tuple matching is not enforced because DataGroups have no tuple-dimension contract. + +### When to Use This Filter + +- Reorganize pipeline output so related arrays end up in one matrix. +- Move a computed array (e.g., output of a custom filter that landed in a temporary group) into the proper Cell/Feature/Ensemble matrix where downstream filters expect to find it. +- Move a Geometry under a DataGroup to organize multiple geometries. + +### Required Input Sources + +- **Objects to Move** -- a list of paths to existing **DataObjects**. +- **New Parent Path** -- an existing **DataGroup**, **Attribute Matrix**, or **Geometry**. % Auto generated parameter table will be inserted here diff --git a/src/Plugins/SimplnxCore/docs/MultiThresholdObjectsFilter.md b/src/Plugins/SimplnxCore/docs/MultiThresholdObjectsFilter.md index 2e07d2da61..4df65b0d3e 100644 --- a/src/Plugins/SimplnxCore/docs/MultiThresholdObjectsFilter.md +++ b/src/Plugins/SimplnxCore/docs/MultiThresholdObjectsFilter.md @@ -8,7 +8,9 @@ Processing (Threshold) This **Filter** allows the user to input single or multiple criteria for thresholding **Attribute Arrays** in an **Attribute Matrix**. Internally, the algorithm creates the output boolean arrays for each comparison that the user creates. Comparisons can be either a value and boolean operator (*Less Than*, *Greater Than*, *Equal To*, *Not Equal To*) or a collective set of comparisons. Then all the output arrays are compared with their given comparison operator ( *And* / *Or* ) with the value of a set being the result of its own comparisons calculated from top to bottom. -An example of this **Filter's** use would be after EBSD data is read into DREAM3D-NX and the user wants to have DREAM3D-NX consider **Cells** that the user considers *good*. The user would insert this **Filter** and select the criteria that makes a **Cell** *good*. All arrays **must** come from the same **Attribute Matrix** in order for the **Filter** to execute. +An example of this **Filter's** use would be after EBSD (Electron Backscatter Diffraction) data is read into DREAM3D-NX and the user wants to have DREAM3D-NX consider **Cells** that the user considers *good*. The user would insert this **Filter** and select the criteria that makes a **Cell** *good*. All arrays **must** come from the same **Attribute Matrix** in order for the **Filter** to execute. + +A **Cell** is a single element (voxel) of a gridded geometry such as an **Image Geometry**, and an **Attribute Matrix** is the container that groups together all of the per-**Cell** **Attribute Arrays** (e.g., Confidence Index, Image Quality, Phases) so that they share the same number of tuples. Because the threshold is evaluated tuple-by-tuple across the selected arrays, every array used in a comparison must live in that same **Attribute Matrix**. For example, an integer array contains the values 1, 2, 3, 4, 5. For a comparison value of 3 and the comparison operator greater than, the boolean threshold array produced will contain *false*, *false*, *false*, *true*, *true*. For the comparison set { *Greater Than* 2 AND *Less Than* 5} OR *Equals* 1, the boolean threshold array produced will contain *true*, *false*, *true*, *true*, *false*. @@ -16,9 +18,11 @@ It is possible to set custom values for both the TRUE and FALSE values that will **NOTE**: If custom TRUE/FALSE values are chosen, then using the resulting mask array in any other filters that require a mask array will break those other filters. This is because most other filters that require a mask array make the assumption that the true/false values are 1/0. -% Auto generated parameter table will be inserted here +### Required Input Sources -## Example Pipelines +- The **Attribute Arrays** being thresholded -- any per-element scalar arrays that already exist in a single **Attribute Matrix**. Common producers are EBSD readers such as [Read H5EBSD](../OrientationAnalysis/ReadH5EbsdFilter.md), [Read CTF Data](../OrientationAnalysis/ReadCtfDataFilter.md), or [Read ANG Data](../OrientationAnalysis/ReadAngDataFilter.md) (which supply Confidence Index, Image Quality, Phases, etc.), but any filter that creates scalar **Cell** or **Feature** arrays can supply the inputs. + +% Auto generated parameter table will be inserted here ## License & Copyright diff --git a/src/Plugins/SimplnxCore/docs/NearestPointFuseRegularGridsFilter.md b/src/Plugins/SimplnxCore/docs/NearestPointFuseRegularGridsFilter.md index e62adf49ba..83b4566bb7 100644 --- a/src/Plugins/SimplnxCore/docs/NearestPointFuseRegularGridsFilter.md +++ b/src/Plugins/SimplnxCore/docs/NearestPointFuseRegularGridsFilter.md @@ -6,9 +6,26 @@ Sampling (Resolution) ## Description -This **Filter** fuses two **Image Geometry** data sets together. The grid of **Cells** in the *Reference* **Data Container** is overlaid on the grid of **Cells** in the *Sampling* **Data Container**. Each **Cell** in the *Reference* **Data Container** is associated with the nearest point in the *Sampling* **Data Container** (i.e., no *interpolation* is performed). All the attributes of the **Cell** in the *Sampling* **Data Container** are then assigned to the **Cell** in the *Reference* **Data Container**. +This filter copies the **Cell** data from one **Image Geometry** onto another by matching each cell to the spatially nearest cell in the other grid. It is used to bring the attribute arrays of two separately-sampled volumes into a single grid so they can be analyzed together. -*Note:* The *Sampling* **Data Container** remains identical after this **Filter**, but the *Reference* **Data Container**, while "geometrically identical", gains all the attribute arrays from the *Sampling* **Data Container**. +### Reference vs. Sampling Geometry + +The filter works with two **Image Geometries**: + +- The **Reference** geometry is the grid that is kept. Its cells are the destination. +- The **Sampling** geometry is the grid that is read from. Its cells are the source of the copied data. + +For each cell in the *Reference* geometry, the filter finds the cell in the *Sampling* geometry whose center is physically closest (using the two grids' origins and spacings), and copies all of that sampling cell's attribute arrays onto the reference cell. **No interpolation is performed** — the nearest sampling value is taken as-is. Because the match is by physical position, the two grids may have different spacings, dimensions, or extents; only their overlap in space is meaningful. + +The *Sampling* geometry is left unchanged. The *Reference* geometry keeps its own geometry but gains a copy of the sampling geometry's attribute arrays. + +### Parameter Guidance + +- **Use Custom Fill Value** — controls what happens to reference cells that fall outside the sampling grid (no nearby sampling cell). When off, copied arrays are filled with *0* there; when on, the user supplies the fill value. + +### Required Input Sources + +- **Reference Image Geometry** and **Sampling Image Geometry** -- two **Image Geometries** (each with a **Cell Attribute Matrix**), typically created by separate import or resampling steps. % Auto generated parameter table will be inserted here diff --git a/src/Plugins/SimplnxCore/docs/PadImageGeometryFilter.md b/src/Plugins/SimplnxCore/docs/PadImageGeometryFilter.md index 37b3e73bcf..8b7eb85866 100644 --- a/src/Plugins/SimplnxCore/docs/PadImageGeometryFilter.md +++ b/src/Plugins/SimplnxCore/docs/PadImageGeometryFilter.md @@ -1,39 +1,57 @@ # Pad Image Geometry - -## Group (Subgroup) ## +## Group (Subgroup) Generic (Generic) -## Description ## +## Description -This **Filter** pads an image geometry by the given min/max voxels for each dimension in X, Y, and Z, using the default padding value. -It is also possible to optionally update the origin of the image geometry, which prevents the original data from shifting in space. +This **Filter** extends an **Image Geometry** outward by adding cells around the edges. Each added cell is initialized to a user-specified default value. Optionally, the geometry's origin can be updated so that the original data stays in the same physical location after padding. -For example given the original input geometry in Figure 1: +Padding is the inverse operation of [Crop Geometry (Image)](CropImageGeometryFilter.md). Common use cases are creating a margin around a sample before applying a transformation, or extending a small ROI to a standard size for batch processing. -### Figure 1 +### Example -![](Images/PadImageGeometry_0.png) +Given the input geometry in Figure 1: +#### Figure 1 + +![](Images/PadImageGeometry_0.png) -Padding the Image Geometry with X Min=0, X Max=10, Y Min=0, Y Max=10 will give the output as shown in Figure 2 +Padding with X Min=0, X Max=10, Y Min=0, Y Max=10 produces: -### Figure 2 +#### Figure 2 ![](Images/PadImageGeometry_1.png) +### Pad Amounts and Units + +The pad amounts (*X Min*, *X Max*, *Y Min*, *Y Max*, *Z Min*, *Z Max*) are integers in **cells/voxels**. A value of 10 adds 10 cells to that face. Setting a pad amount to 0 means no padding on that face. + +### Default Value + +Each padded cell is initialized to the *Default Value* for every cell-level **Attribute Array** in the target Attribute Matrix. The default value is interpreted in the same data type as each array (e.g., for a uint8 array, the value is cast to uint8; for a float32 array, to float32). Pick a value that is sentinel-like in every array (commonly 0). + +### Update Origin + +If *Update Origin* is **OFF** (the default), the geometry's origin stays at its current location. New cells appear at coordinates less than the original origin, so the original data effectively shifts to "the middle" of the new bounds. + +If *Update Origin* is **ON**, the geometry's origin is shifted so that the original data stays in its original physical coordinates. New cells extend to coordinates below the original origin. + +### Required Input Sources + +- **Input Image Geometry** -- the geometry to extend. Typically produced by [Create Image Geometry](CreateImageGeometryFilter.md), [ITK Import Image Stack](../ITKImageProcessing/ITKImportImageStackFilter.md), or an EBSD reader. + % Auto generated parameter table will be inserted here -## Example Pipelines ## +## Example Pipelines 'pad_image_geometry.d3dpipline' -## License & Copyright ## +## License & Copyright Please see the description file distributed with this plugin. -## DREAM3D Mailing Lists ## +## DREAM3D-NX Help -If you need more help with a filter, please consider asking your question on the DREAM3D Users mailing list: -https://groups.google.com/forum/?hl=en#!forum/dream3d-users +If you need help, need to file a bug report or want to request a new feature, please head over to the [DREAM3DNX-Issues](https://github.com/BlueQuartzSoftware/DREAM3DNX-Issues/discussions) GitHub site where the community of DREAM3D-NX users can help answer your questions. diff --git a/src/Plugins/SimplnxCore/docs/PartitionGeometryFilter.md b/src/Plugins/SimplnxCore/docs/PartitionGeometryFilter.md index b18da7c2ad..224a8643b3 100644 --- a/src/Plugins/SimplnxCore/docs/PartitionGeometryFilter.md +++ b/src/Plugins/SimplnxCore/docs/PartitionGeometryFilter.md @@ -6,7 +6,7 @@ Reconstruction (Reconstruction) ## Description -This **Filter** generates a partition grid and assigns partition IDs for every voxel/node of a given geometry. +This **Filter** overlays a coarse **partition grid** onto an existing geometry and tags every cell or vertex of that geometry with the **partition ID** of the partition cell it falls into. The output is a per-cell or per-vertex integer label plus an Image Geometry representing the partition grid itself. Use this filter to prepare for sub-volume statistics, spatially-binned analysis, parallel decomposition, or any workflow that needs to group elements by spatial region. If the **Filter** determines that any voxel/node of the original geometry is out-of-bounds compared to the generated partition grid, the **Out-Of-Bounds Cell ID** will be used as the partition ID in the output partition IDs array. @@ -113,6 +113,12 @@ On all partitioning modes, a vertex mask can be used with a vertex-based input g |:---:|:---:| | ![](Images/PartitionGeometry/UseVertexMask_1a.png) | ![](Images/PartitionGeometry/UseVertexMask_1b.png) | +### Required Input Sources + +- **Input Geometry** -- any supported geometry (Image, RectGrid, Vertex, Edge, Triangle, Quad, Tet, Hex). Typically produced by [Create Geometry](CreateGeometryFilter.md), [Create Image Geometry](CreateImageGeometryFilter.md), or an upstream reader. +- **Partition Grid Geometry** (only when *Partitioning Mode* is *Existing Partition Grid*) -- an Image Geometry produced by a prior run of this filter. +- **Vertex Mask** (optional, for vertex-based input geometries) -- a boolean cell-level array on the input geometry's vertices. + % Auto generated parameter table will be inserted here ## Example Pipelines diff --git a/src/Plugins/SimplnxCore/docs/PointSampleEdgeGeometryFilter.md b/src/Plugins/SimplnxCore/docs/PointSampleEdgeGeometryFilter.md index 19286760e2..3829e1c0bc 100644 --- a/src/Plugins/SimplnxCore/docs/PointSampleEdgeGeometryFilter.md +++ b/src/Plugins/SimplnxCore/docs/PointSampleEdgeGeometryFilter.md @@ -1,20 +1,37 @@ # Point Sample Edge Geometry +## Group (Subgroup) + +Sampling (Geometry) + ## Description -This **Filter** will take an Edge geometry and sample each edge at a fixed spatial resolution to generate a new Vertex geometry of sample points. For each interpolated point it will: +This filter walks along each edge of an **Edge Geometry** and places new sample points at a fixed spacing, building a new **Vertex Geometry** (a point cloud) of those samples. + +An **Edge Geometry** is a set of straight line segments connecting pairs of vertices. In additive-manufacturing workflows each such segment is a **scan vector** — the path the energy source (e.g. a laser) travels in one pass. This filter converts those continuous segments into evenly spaced discrete points, which is useful for simulating or analyzing the path at a controlled resolution. + +For every sample point the filter: + +- Copies the **edge ID** of the segment the point lies on, so each point knows which original edge it came from. +- Optionally records the **cumulative sample distance** — the straight-line distance from the start of that edge (scan vector) to the sample point. + +Any additional **Edge Data Arrays** the user selects are also copied onto the matching points of the new Vertex Geometry. + +### Parameter Guidance + +- **Sampling Spacing (mm)** — the distance between successive sample points along each edge, in **millimeters**. A smaller value yields more, more closely spaced points (finer resolution) and a larger output. +- **Calculate Cumulative Sample Distance** — when enabled, stores the start-of-edge distance described above for each sample point. -- Copy over the edge ID from the original edge. -- Record the linear distance from the beginning of its scan vector. +### Required Input Sources -The user can select additional Edge Data Arrays to also be copied onto the newly constructed Vertex geometry +- **Input Edge Geometry** -- an **Edge Geometry**, typically produced by [Slice Triangle Geometry](SliceTriangleGeometryFilter.md) or [Create AM Scan Paths](CreateAMScanPathsFilter.md). % Auto generated parameter table will be inserted here ## License & Copyright -Please see the description file distributed with this plugin. +Please see the description file distributed with this **Plugin** ## DREAM3D-NX Help -If you need help, need to file a bug report or want to request a new feature, please head over to the [DREAM3DNX-Issues](https://github.com/BlueQuartzSoftware/DREAM3DNX-Issues/discussions) GitHub site where the community of DREAM3D-NX users can help answer your questions. \ No newline at end of file +If you need help, need to file a bug report or want to request a new feature, please head over to the [DREAM3DNX-Issues](https://github.com/BlueQuartzSoftware/DREAM3DNX-Issues/discussions) GitHub site where the community of DREAM3D-NX users can help answer your questions. diff --git a/src/Plugins/SimplnxCore/docs/PointSampleTriangleGeometryFilter.md b/src/Plugins/SimplnxCore/docs/PointSampleTriangleGeometryFilter.md index e10fa4b96f..71b2799245 100644 --- a/src/Plugins/SimplnxCore/docs/PointSampleTriangleGeometryFilter.md +++ b/src/Plugins/SimplnxCore/docs/PointSampleTriangleGeometryFilter.md @@ -2,37 +2,39 @@ ## Group (Subgroup) -DREAM3D Review (Geometry) +Sampling (Geometry) ## Description -This **Filter** randomly samples point locations on **Triangles** in a **Triangle Geometry**. The sampled point locations are then used to construct a **Vertex Geometry**. The number of point samples may either be specified manually or by inferring from another **Geometry**: +This **Filter** randomly samples point locations on the triangles of a **Triangle Geometry** (a node-based surface mesh of triangular faces) and uses those sampled locations to construct a new **Vertex Geometry** (a point cloud). The total number of sample points is supplied directly through the *Number of Sample Points* parameter. -| Geometry | Source for Number of Samples | -|----------|-----------| -| Image | Number of cells | -| Rectilinear Grid | Number of cells | -| Vertex | Number of vertices | -| Edge | Number of vertices | -| Triangle | Number of vertices | -| Quadrilateral | Number of vertices | -| Tetrahedral | Number of vertices | +To ensure an even sampling across the whole surface area of the **Triangle Geometry**, the average number of points placed on each triangle is made proportional to that triangle's area. Larger triangles therefore receive proportionally more samples than smaller ones, which produces a spatially uniform point density rather than an even count per triangle. -In order to ensure an even sampling of the total surface are of the **Triangle Geometry**, the average number of points sampled per triangle is made proportional to the area of the triangle. Within a given **Triangle**, a point is chosen using the following approach: +Within a given triangle, each point is chosen with the following formula: -![Equation 1](Images/PointSampleTriangleGeometry_Eqn1.png) +![Equation: the sampled point P equals (1 minus the square root of r1) times A, plus the square root of r1 times (1 minus r2) times B, plus the square root of r1 times r2 times C.](Images/PointSampleTriangleGeometry_Eqn1.png) -where ![](Images/PSTG_2.png) are the coordinates of the sampled point; ![](Images/PSTG_3.png), ![](Images/PSTG_4.png), and ![](Images/PSTG_5.png) are the coordinates of the vertices beloning to the **Triangle**; and ![](Images/PSTG_6.png) and ![](Images/PSTG_7.png) are random real numbers on the interval ![](Images/PSTG_8.png). This approach has the benefit of uniform sampling within the **Triangle** area, and functions correctly regardless of the dimensionality of the space embedding (i.e., whether the **Triangle** is in the plane or embedded in 3D). +where ![the sampled point coordinates P](Images/PSTG_2.png) are the coordinates of the sampled point; ![vertex A](Images/PSTG_3.png), ![vertex B](Images/PSTG_4.png), and ![vertex C](Images/PSTG_5.png) are the coordinates of the vertices belonging to the triangle; and ![random number r1](Images/PSTG_6.png) and ![random number r2](Images/PSTG_7.png) are random real numbers on the interval ![the interval from zero to one](Images/PSTG_8.png). This approach gives uniform sampling within the triangle area and works correctly regardless of the dimensionality of the embedding space (whether the triangle lies in a plane or is embedded in 3D). -The user may opt to use a mask to prevent certain **Triangles** from being sampled; where the mask is _false_, the **Triangle** will not be sampled. Additionally, the user may choose any number of **Face Attribute Arrays** to transfer to the created **Vertex Geometry**. The vertices in the new **Vertex Geometry** will gain the values of the **Faces** from which they were sampled. +### Random Sampling and Reproducibility -% Auto generated parameter table will be inserted here +The point placement is **random**: both the distribution of samples across triangles and the location of each point within its triangle are drawn from a pseudo-random number generator. By default a new seed is used each run, so the output point cloud differs from run to run. To obtain repeatable results, enable *Use Seed for Random Generation* and supply a fixed *Seed Value*; the seed actually used is also stored in an output array so a run can be reproduced later. + +### Masking and Transferred Data + +The user may opt to use a **mask** (a boolean per-face flag) to prevent certain triangles from being sampled; where the mask is *false*, the triangle is not sampled. Additionally, the user may choose any number of **Face Attribute Arrays** to transfer to the created **Vertex Geometry**. Each vertex in the new geometry inherits the values of the face from which it was sampled. -## Example Pipelines +### Required Input Sources + +- **Triangle Geometry to Sample** -- a **Triangle Geometry** (surface mesh), typically produced by [Create Surface Mesh (QuickMesh)](QuickSurfaceMeshFilter.md). +- **Face Areas** -- a single-component per-face area array, produced by [Compute Triangle Areas](ComputeTriangleAreasFilter.md). +- **Mask** (optional) -- a boolean per-face array, typically produced by a thresholding filter such as [Multi-Threshold Objects](MultiThresholdObjectsFilter.md). + +% Auto generated parameter table will be inserted here ## License & Copyright -Please see the description file distributed with this plugin. +Please see the description file distributed with this **Plugin** ## DREAM3D-NX Help diff --git a/src/Plugins/SimplnxCore/docs/QuickSurfaceMeshFilter.md b/src/Plugins/SimplnxCore/docs/QuickSurfaceMeshFilter.md index 1eca069532..92b676b541 100644 --- a/src/Plugins/SimplnxCore/docs/QuickSurfaceMeshFilter.md +++ b/src/Plugins/SimplnxCore/docs/QuickSurfaceMeshFilter.md @@ -4,81 +4,67 @@ Surface Meshing (Generation) -## Deprecation Notice +## ⚠ Deprecation Notice -The "SurfaceNets" filter should be used instead. Search the filter list for "Surface Nets". +**This filter is deprecated.** Use the [Surface Nets](SurfaceNetsFilter.md) filter instead. Surface Nets produces a smoother mesh (no stair-stepping), runs faster, and includes smoothing in a single pass. This filter is retained for compatibility with legacy pipelines. ## Description -This **Filter** generates a **Triangle Geometry** from a grid **Geometry** (either an **Image Geometry** or a **RectGrid Geometry**) that represents a surface mesh of the present **Features**. The algorithm proceeds by creating a pair of **Triangles** for each face of the **Cell** where the neighboring **Cells** have a different **Feature** Id value. The meshing operation is extremely quick but can result in a surface mesh that is very "stair stepped". The user is encouraged to use a smoothing operation to reduce this "blockiness". +This **Filter** generates a **Triangle Geometry** surface mesh from a grid **Geometry** (Image or Rectilinear Grid). For every cell face shared between two different **Features** (i.e., a Feature boundary), the filter emits two triangles, producing the *stair-stepped* surface that defines the boundary of each Feature. -The user may choose any number of **Cell Attribute Arrays** to transfer to the created **Triangle Geometry**. The **Faces** will gain the values of the **Cells** from which they were created. Currently, the **Filter** disallows the transferring of data that has a *multi-dimensional* component dimensions vector. For example, scalar values and vector values are allowed to be transferred, but N x M matrices cannot currently be transferred. +The resulting mesh is "blocky" because each triangle aligns with a voxel face. To smooth it, apply [Laplacian Smoothing](LaplacianSmoothingFilter.md) afterward -- or, preferably, use [Surface Nets](SurfaceNetsFilter.md), which combines meshing and smoothing in one step. -This filter will ensure that the smaller of the 2 **FaceLabel** values will always be in the first component (component[0]). This will allow assumptions made in downstream filters to continue to work correctly. +![Example Quick Mesh Output](Images/QuickSurface_Output.png) -This filter attempts to repair the windings for a mesh. This may not be possible due to the nature of how meshes are stored in the software. See Verify Traingle Winding documentation for detailed breakdown of nuance. +*Quick Surface Mesh output without smoothing.* -For more information on surface meshing, visit the tutorial. +![Example Quick Mesh Output](Images/QuickSurface_Smooth_Output.png) ---------------- +*Quick Surface Mesh output with Laplacian Smoothing applied.* -![Example Quick Mesh Output](Images/QuickSurface_Output.png) +### Cell Data Transfer -Quick Surface Mesh output **without** any extra smoothing applied +The user may select any number of **Cell Attribute Arrays** to transfer onto the new **Triangle Geometry**. Each output **Face** inherits the values of the **Cell** it came from. Only scalar and vector arrays can be transferred; multi-dimensional component shapes (e.g., N×M matrices) are not supported. ---------------- +### Face Labels Convention -![Example Quick Mesh Output](Images/QuickSurface_Smooth_Output.png) +Each triangle gets a 2-component *Face Labels* attribute storing the two Feature IDs on either side of the boundary. The filter guarantees the smaller Feature ID is in component 0, so downstream filters can rely on a consistent ordering. -Quick Surface Mesh output **with** Laplacian Smoothing filter applied. +If a triangle borders the outer volume rather than a real Feature (i.e., the cell on one side is outside the geometry), one of its Face Labels is set to **-1**. ---------------- +### Node Types -![NodeType = 2](Images/QuickMesh_NodeType_2.png) +A *Node Type* vertex array is produced classifying each vertex by its mesh role: + +| Value | Description | +|-------|-------------| +| 2 | Vertex on the interior of a grain face | +| 3 | Vertex on a triple line (3 grains meet) | +| 4 | Vertex on a quadruple point (4 grains meet) | +| 12 | Vertex on the exterior of the mesh, on a grain face | +| 13 | Vertex on the exterior of the mesh, on a triple line | +| 14 | Vertex on the exterior of the mesh, on a quadruple point | -NodeType = 2 +![NodeType = 2](Images/QuickMesh_NodeType_2.png) ---------------- +*Node Type 2 -- interior face vertex.* ![NodeType = 3](Images/QuickMesh_NodeType_3.png) -NodeType = 3 - ---------------- +*Node Type 3 -- triple line vertex.* ![NodeType = 4](Images/QuickMesh_NodeType_4.png) -NodeType = 4 +*Node Type 4 -- quadruple point vertex.* ---------------- +### Winding -### Node Types +The filter attempts to repair mesh windings so that triangle normals point outward consistently. This may not always succeed -- see [Verify Triangle Winding](VerifyTriangleWindingFilter.md) for cases where the mesh storage scheme prevents fully consistent windings. -One of the arrays to come out of the algorithm is the "Node Type" vertex array. This array uses a value to label each vertex as to what kind of node it was determined to be during the meshing process. +### Required Input Sources -| Value | Description | -|-------|-------------| -| 2 | Node within the interior of the grain face. | -| 3 | Node along a triple line | -| 4 | Node that is a Quadruple point | -| 12 | Node that is on the exterior of the mesh | -| 13 | Node that is on the exterior of the mesh and is a triple line | -| 14 | Node that is on the exterior of the mesh and is a quadruple point | - -### Exterior or Boundary Triangles - -Each triangle that is created will have an 2 component attribute called `Face Labels` that represent the Feature ID on either -side of the triangle. If one of the triangles represents the border of the virtual box then one of the FaceLables will -have a value of -1. - -## Notes - -The Quick Mesh algorithm is very crude and naive in its implementation. This filter -along with the Laplacian Smoothing filter can give you reasonable results. The -newer filter that should replace both the Quick Mesh and the Laplacian Smoothing -filter is the "Surface Nets" surface meshing algorithm. This will create the surface -mesh and smooth in a single filter and give subjectively better results and perform -much faster at both. +- **Cell Feature Ids** -- produced by a segmentation filter such as [Segment Features (Misorientation)](../OrientationAnalysis/EBSDSegmentFeaturesFilter.md) or [Segment Features (Scalar)](ScalarSegmentFeaturesFilter.md). +- **Image Geometry** -- typically produced by [Create Image Geometry](CreateImageGeometryFilter.md), [ITK Import Image Stack](../ITKImageProcessing/ITKImportImageStackFilter.md), or an EBSD reader. % Auto generated parameter table will be inserted here diff --git a/src/Plugins/SimplnxCore/docs/RandomizeFeatureIdsFilter.md b/src/Plugins/SimplnxCore/docs/RandomizeFeatureIdsFilter.md index f26616aacc..c45c6a50d5 100644 --- a/src/Plugins/SimplnxCore/docs/RandomizeFeatureIdsFilter.md +++ b/src/Plugins/SimplnxCore/docs/RandomizeFeatureIdsFilter.md @@ -8,13 +8,21 @@ Core (Filters) ***WARNING:** This filter can throw a pipeline terminating error (at runtime) if the number of tuples in the supplied Feature `Attribute Matrix` is less than the max value in the Feature Ids `DataArray`* -This filter will randomize a user selected "Feature Ids" array and update every container (`DataArray`, `NeighborList`, and `StringArray`) in the feature `Attribute Matrix`. This does not generate random data but instead uses the existing values and swaps the positions of the values in the array. The intended use case is primarily for visualization, so feature data does not appear as a smooth gradient. +This filter will randomize a user selected **Feature Ids** array and update every container (`DataArray`, `NeighborList`, and `StringArray`) in the Feature **Attribute Matrix**. This does not generate random data but instead uses the existing values and swaps the positions of the values in the array. The intended use case is primarily for visualization, so feature data does not appear as a smooth gradient. + +**Feature Ids** are per-cell integer labels that assign each element (voxel) of a geometry to a *Feature* (for example, a grain). The Feature **Attribute Matrix** is the container holding one tuple per Feature; its per-Feature **Attribute Arrays** (such as sizes, phases, or average orientations) and any `NeighborList` (a variable-length list of each Feature's neighbors) are re-ordered consistently with the new Feature Id assignment so the data stays internally coherent. + +This filter does not expose a random-seed parameter, so the shuffle is **not reproducible** from run to run. If you need a deterministic visualization, apply the randomization once and persist the result rather than re-running it. + +### Required Input Sources + +- A **Feature Ids** array, typically produced by a feature-segmentation filter such as [Segment Features (Scalar)](ScalarSegmentFeaturesFilter.md), and the matching Feature **Attribute Matrix** that array indexes into. % Auto generated parameter table will be inserted here ## License & Copyright -Please see the description file distributed with this plugin. +Please see the description file distributed with this **Plugin** ## DREAM3D-NX Help diff --git a/src/Plugins/SimplnxCore/docs/ReadBinaryCTNorthstarFilter.md b/src/Plugins/SimplnxCore/docs/ReadBinaryCTNorthstarFilter.md index 327b8b3aba..2096bd7e7f 100644 --- a/src/Plugins/SimplnxCore/docs/ReadBinaryCTNorthstarFilter.md +++ b/src/Plugins/SimplnxCore/docs/ReadBinaryCTNorthstarFilter.md @@ -2,13 +2,13 @@ ## Group (Subgroup) -IOFilters (Input) +IO (Input) ## Description -This **Filter** will import a NorthStar Imaging data set consisting of a single .nsihdr and one or more .nsidat files. The data is read into an Image Geometry. The user can import a subvolume instead of reading the entire data set into memory. +This **Filter** will import a NorthStar Imaging computed tomography (CT) data set consisting of a single .nsihdr and one or more .nsidat files. The data is read into an **Image Geometry**. The scan intensities are stored in a single-component `float32` array (default name *Density*) inside a **Cell Attribute Matrix** (default name *CT Scan Data*). -The user should note that when using the subvolume feature that the ending voxels are **inclusive**. +The user can import a subvolume instead of reading the entire data set into memory. The subvolume start and end values are specified in **voxels** (zero-based), and both the starting and ending voxels are **inclusive**. The .nsihdr file will be read during preflight and the .nsidat file(s) will be extracted from there. The expectation is that the .nsidat files are in the same directory as the .nsihdr files. @@ -18,6 +18,10 @@ The *Length Unit* parameter sets the physical units associated with the **Image Yoctometer, Zeptometer, Attometer, Femtometer, Picometer, Nanometer, Micrometer, Millimeter, Centimeter, Decimeter, Meter, Decameter, Hectometer, Kilometer, Megameter, Gigameter, Terameter, Petameter, Exameter, Zettameter, Yottameter, Angstrom, Mil, Inch, Foot, Mile, Fathom, Unspecified, Unknown. +## Required Input Sources + +None — this filter reads directly from a `.nsihdr`/`.nsidat` file set on disk. + % Auto generated parameter table will be inserted here ## License & Copyright diff --git a/src/Plugins/SimplnxCore/docs/ReadCSVFileFilter.md b/src/Plugins/SimplnxCore/docs/ReadCSVFileFilter.md index 064a248e34..d23da621dd 100644 --- a/src/Plugins/SimplnxCore/docs/ReadCSVFileFilter.md +++ b/src/Plugins/SimplnxCore/docs/ReadCSVFileFilter.md @@ -8,51 +8,55 @@ IO (Input) This **Filter** reads text data from any text-based file and imports the data into DREAM3D-NX-style arrays. The user specifies which file to import, how the data is formatted, what to call each array, and what type each array should be. -*Note:* This **Filter** is intended to read data that is column-oriented, such that each created DREAM3D-NX array corresponds to a column of data in the text file. Therefore, this **Filter** will only import scalar arrays. If multiple columns are in fact different components of the same array, then the columns may be imported as separate arrays and then combined in the correct order using the Combine Attribute Arrays **Filter**. +*Note:* This **Filter** is intended to read data that is column-oriented, such that each created DREAM3D-NX array corresponds to a column of data in the text file. Therefore, this **Filter** will only import scalar arrays. If multiple columns are in fact different components of the same array, then the columns may be imported as separate arrays and then combined in the correct order using the [Combine Attribute Arrays](CombineAttributeArraysFilter.md) filter. ### Filling Out The Inputs The user first selects the **Input Text File** path, which then enables the rest of the interface. -![Input Text File Field](Images/Read_CSV_1.png) +![Selecting the input text file path](Images/Read_CSV_1.png) If the chosen **Input Text File** already has headers inside the file, the user can select the **Input File Has Headers** checkbox. This enables the **Headers Line Number** spin box where the user can select which line of the file contains the headers. *NOTE*: The interface only allows importing data starting at the line after the chosen **Headers Line Number**. So, in the example below, the **Headers Line Number** is set to 1, so **Start Import Line Number** defaults to 2 and has a range of 2-297 (this particular input file has 297 total lines). The max range of **Headers Line Number** is, of course, set to 296 so that at least 1 line can be imported. -![Input Text File Field](Images/Read_CSV_2.png) +![Setting the headers line number and start import line number](Images/Read_CSV_2.png) The user can choose how the data is delimited: comma (,), tab, semicolon (;) or space ( ). The user may also elect to ignore consecutive delimiters, which treats consecutive delimiters as one delimiter. -![Input Text File Field](Images/Read_CSV_3.png) +![Choosing the column delimiter](Images/Read_CSV_3.png) The user can select the number of preview lines available by changing the **Number of Preview Lines** spin box. The range in the example is set to 1-296 because the import is currently starting at row 2 (from **Start Import Line Number** spin box). -![Input Text File Field](Images/Read_CSV_4.png) +![Adjusting the number of preview lines](Images/Read_CSV_4.png) The user can then set the data format for each column. Selecting one or more columns will enable the **Column Data Type** combo box, where you can choose a data type or decide to skip importing specific columns as well. -![Input Text File Field](Images/Read_CSV_5.png) -![Input Text File Field](Images/Read_CSV_6.png) +![Selecting columns to set the column data type](Images/Read_CSV_5.png) +![Choosing a data type for the selected columns](Images/Read_CSV_6.png) If the **Input File Has Headers** checkbox is OFF, then it is also possible to double-click the headers in the Preview Table to edit them. These values will be used as the name of the **Data Array** in DREAM3D-NX. *NOTE:* Editing table headers is only available when the **Input File Has Headers** checkbox is OFF. If the **Input File Has Headers** checkbox is ON, then the headers will be read from the **Headers Line Number** in the data file, and the table headers will not be editable. -![Input Text File Field](Images/Read_CSV_7.png) +![Editing column header names in the preview table](Images/Read_CSV_7.png) The user can select the tuple dimensions that will be applied to the imported arrays. -![Input Text File Field](Images/Read_CSV_8.png) +![Setting the tuple dimensions for the imported arrays](Images/Read_CSV_8.png) The imported arrays can be stored in an existing attribute matrix or data group, or a new attribute matrix can be created. -![Input Text File Field](Images/Read_CSV_9.png) +![Choosing the destination attribute matrix or data group](Images/Read_CSV_9.png) Afterwards, you end up with a data structure that looks like this: -![Input Text File Field](Images/Read_CSV_10.png) +![Resulting data structure after import](Images/Read_CSV_10.png) + +## Required Input Sources + +None — this filter reads directly from a text/CSV file on disk. % Auto generated parameter table will be inserted here diff --git a/src/Plugins/SimplnxCore/docs/ReadDREAM3DFilter.md b/src/Plugins/SimplnxCore/docs/ReadDREAM3DFilter.md index fceb2b32e7..4ad0f9161f 100644 --- a/src/Plugins/SimplnxCore/docs/ReadDREAM3DFilter.md +++ b/src/Plugins/SimplnxCore/docs/ReadDREAM3DFilter.md @@ -1,8 +1,28 @@ # Read DREAM3D-NX File +## Group (Subgroup) + +IO (Input) + ## Description -This **Filter** reads the data structure from an hdf5 file with the .dream3d extension. This filter is capable of reading from legacy .dream3d files also. +This filter reads data from a `.dream3d` file into the pipeline. A `.dream3d` file is an HDF5-based file (HDF5 is a portable, self-describing container format for large scientific datasets) that stores a complete DREAM3D-NX **DataStructure** — its geometries, **Attribute Matrix** groups, and **Data Array**s. + +### Selective (Partial) Import + +The filter does not have to read the entire file. Through the *Import File Path* parameter, the user can browse the structure of the selected `.dream3d` file and choose exactly which data objects to import. Selecting only the objects that are needed avoids loading large arrays that the rest of the pipeline does not use, which saves memory and time. To import everything, simply select all objects. + +### How Imported Objects Are Added + +The selected objects are added into the pipeline's current **DataStructure** at the same paths they had in the file. If an object being imported has the same path as an object already present in the current **DataStructure**, the existing object is replaced (overwritten) by the imported one, so take care when reading into a non-empty **DataStructure**. Any pipeline metadata stored in the file may also be read when the file is opened. + +### Legacy Files + +This filter can also read **legacy** `.dream3d` files — those written by the older DREAM3D 6.x / SIMPL-era applications. Such files use an earlier internal layout, and this filter converts them to the current **DataStructure** format on import. + +### Required Input Sources + +None — this filter reads directly from a `.dream3d` file on disk. % Auto generated parameter table will be inserted here @@ -12,4 +32,8 @@ ALL ## License & Copyright -Please see the description file distributed with this plugin. +Please see the description file distributed with this **Plugin** + +## DREAM3D-NX Help + +If you need help, need to file a bug report or want to request a new feature, please head over to the [DREAM3DNX-Issues](https://github.com/BlueQuartzSoftware/DREAM3DNX-Issues/discussions) GitHub site where the community of DREAM3D-NX users can help answer your questions. diff --git a/src/Plugins/SimplnxCore/docs/ReadDeformKeyFileV12Filter.md b/src/Plugins/SimplnxCore/docs/ReadDeformKeyFileV12Filter.md index 925989129e..4c1e1cb721 100644 --- a/src/Plugins/SimplnxCore/docs/ReadDeformKeyFileV12Filter.md +++ b/src/Plugins/SimplnxCore/docs/ReadDeformKeyFileV12Filter.md @@ -6,9 +6,43 @@ SimulationIO (SimulationIO) ## Description -This **Filter** reads DEFORM v12 key files and saves the data in a newly created **Data Container**. +This filter reads a **DEFORM** version 12 "key file" and imports its mesh and field data into a newly created **Quad Geometry**. **DEFORM** is a commercial finite-element simulation package for metal-forming processes (such as forging, extrusion, and rolling). A DEFORM *key file* is the text results file the software exports; it contains the simulation mesh together with the values of physical variables computed at each node and element. -It reads the quadrilateral mesh data (nodal coordinates and connectivity), and the value of variables such as stress, strain, ndtmp, etc at cells and nodes. +### What the Filter Creates + +The filter builds a **Quad Geometry** — a surface mesh made of four-sided (quadrilateral) elements — from the key file. The **Quad Geometry** holds: + +- **Node coordinates**: the positions of the mesh nodes (vertices). +- **Connectivity**: which four nodes form each quadrilateral element. + +Alongside the geometry, the filter creates two attribute groups for the field variables stored in the key file: + +- **Vertex (node) data**: variables defined at each node, such as `ndtmp` (nodal temperature). +- **Cell (element) data**: variables defined at each element, such as stress and strain. + +The units of each imported variable are whatever DEFORM exported them in (for example temperature in degrees Celsius, or stress in MPa); the filter does not convert units. + +### Example Input Structure + +A DEFORM v12 key file is a keyword-driven text file. Each block begins with a keyword followed by the data for that block — for example, a node-coordinate block, an element-connectivity block, and one block per nodal or element variable: + +```text +RZ + 1 0.000000 0.000000 + 2 0.500000 0.000000 + .. +ELMCON + 1 1 2 5 4 + .. +NDTMP + 1 20.000000 + 2 20.000000 + .. +``` + +### Required Input Sources + +None — this filter reads directly from a DEFORM v12 key file on disk. % Auto generated parameter table will be inserted here diff --git a/src/Plugins/SimplnxCore/docs/ReadHDF5DatasetFilter.md b/src/Plugins/SimplnxCore/docs/ReadHDF5DatasetFilter.md index 6247254de6..e851cde6a2 100644 --- a/src/Plugins/SimplnxCore/docs/ReadHDF5DatasetFilter.md +++ b/src/Plugins/SimplnxCore/docs/ReadHDF5DatasetFilter.md @@ -6,37 +6,57 @@ Core (IO/Read) ## Description -This **Filter** allows the user to import datasets from an HDF5 file and store them as attribute arrays in DREAM3D-NX. This filter supports importing datasets with any number of dimensions, as long as the created attribute array's total number of components and the tuple count of the destination attribute matrix multiply together to match the HDF5 dataset's total number of elements. +This filter imports one or more datasets from an HDF5 file and stores each one as a **Data Array** in DREAM3D-NX. HDF5 (Hierarchical Data Format version 5) is a binary file format that organizes named datasets inside a tree of groups, much like files inside folders on a disk. -The component dimensions are input as a comma-delimited list of dimensional values. For example: +When the filter is configured, the user browses the structure of the selected HDF5 file and checks one or more datasets to import. Multiple datasets can be selected and imported in a single pass; each checked dataset becomes its own Data Array. For every checked dataset the user supplies how that dataset's elements should be split into **tuple dimensions** and **component dimensions**: -1. 3, 4 = 3x4 -2. 5, 2, 1 = 5x2x1 -3. 6 = 6 +- **Tuple dimensions** describe how many elements (tuples) the array holds — for example, the number of voxels or rows of data. +- **Component dimensions** describe how many values belong to each tuple — for example, a 3-component vector stores 3 values per tuple. -### Examples +The filter places the imported array either at the top level of the **Data Structure** or, if the user selects an existing **Data Group** or **Attribute Matrix** as the parent, inside that container. When an Attribute Matrix is chosen as the parent, the tuple dimensions are taken automatically from that Attribute Matrix and do not need to be entered. -1. Suppose we have a 1D dataset in an HDF5 file with dimension **12,000**. - We can input component dimensions of **5, 2, 2** and set the destination attribute matrix tuple dimensions to **35 x 5 x 2 x 2** +### How It Works -+ The total number of elements for the HDF5 dataset is 12,000. -+ The total number of tuples in the destination attribute matrix is 35\*5\*2\*2 = 700. -+ The total number of components for the created attribute array is 5\*2\*2 = 20. -+ The total number of elements for the created attribute array will be 700\*20 = 14,000. +The import only succeeds when the math is consistent: the total number of elements actually stored in the HDF5 dataset must equal the number of tuples multiplied by the number of components per tuple. -14,000 does not equal 12,000, so this will result in a preflight error. +``` +HDF5 dataset element count == (product of tuple dimensions) x (product of component dimensions) +``` -2. Suppose we have a 3D dataset in an HDF5 file with dimensions **1 x 16 x 1001 x 1001**. -We can input component dimensions of **2** and set our destination attribute matrix tuple dimensions to **134 x 67**. +If these two totals do not match, the filter reports a preflight error and nothing is imported. -+ The total number of elements for the HDF5 dataset is 1\*16\*1001\*1001 = 16,032,016. -+ The total number of tuples in the destination attribute matrix is 8\*1001\*1001 = 8,016,008. -+ The total number of components for the created attribute array is 2. -+ The total number of elements for the created attribute array will be 8,016,008\*2 = 16,032,016. -+ The total number of elements of the created attribute array (16,032,016) equals the total number of elements of the HDF5 dataset (16,032,016), so we can import this dataset without errors (see below). +The component dimensions are entered as a comma-separated list. For example: + +1. `3, 4` means 3 x 4 = 12 components per tuple +2. `5, 2, 1` means 5 x 2 x 1 = 10 components per tuple +3. `6` means 6 components per tuple + +### Worked Examples + +**Example 1 (valid):** Suppose an HDF5 file contains a 1D dataset with **12,000** elements. + +- The user enters component dimensions of `2` (so 2 components per tuple). +- The user enters tuple dimensions of `6000` (so 6,000 tuples). +- Check: 6,000 tuples x 2 components = 12,000 elements, which equals the HDF5 dataset element count of 12,000. The dataset imports successfully. + +**Example 2 (invalid):** Suppose an HDF5 file contains a 1D dataset with **12,000** elements. + +- The user enters component dimensions of `5, 2, 2` (so 5 x 2 x 2 = 20 components per tuple). +- The user enters tuple dimensions of `35, 5, 2, 2` (so 35 x 5 x 2 x 2 = 700 tuples). +- Check: 700 tuples x 20 components = 14,000 elements, which does not equal the HDF5 dataset element count of 12,000. The filter reports a preflight error. + +**Example 3 (valid, multi-dimensional dataset):** Suppose an HDF5 file contains a dataset whose stored dimensions are **16 x 1001 x 1001**, for a total of 16 x 1001 x 1001 = 16,032,016 elements. + +- The user enters component dimensions of `2` (so 2 components per tuple). This means there must be 16,032,016 / 2 = 8,016,008 tuples. +- The user enters tuple dimensions of `8, 1001, 1001` (so 8 x 1001 x 1001 = 8,016,008 tuples). +- Check: 8,016,008 tuples x 2 components = 16,032,016 elements, which equals the HDF5 dataset element count of 16,032,016. The dataset imports successfully. ![Example Image](Images/ImportHDF5Dataset_ui.png) +## Required Input Sources + +None — this filter reads directly from an external `.h5`/`.hdf5` file on disk. The imported array may optionally be placed into an existing **Data Group** or **Attribute Matrix** if one is selected as the parent. + % Auto generated parameter table will be inserted here ## Example Pipelines diff --git a/src/Plugins/SimplnxCore/docs/ReadImageFilter.md b/src/Plugins/SimplnxCore/docs/ReadImageFilter.md index 8684f93a39..b73401e0de 100644 --- a/src/Plugins/SimplnxCore/docs/ReadImageFilter.md +++ b/src/Plugins/SimplnxCore/docs/ReadImageFilter.md @@ -6,7 +6,9 @@ IO (Input) ## Description -Reads a single 2D image file into a newly created Image Geometry. This filter does not depend on ITK. It uses stb_image for PNG/JPEG/BMP files and libtiff for TIFF files. +Reads a single 2D image file into a newly created **Image Geometry**. To read a numbered sequence of slices into a 3D volume instead, use [Read Images [3D Stack]](ReadImageStackFilter.md). + +This filter does not depend on ITK. It uses stb_image for PNG/JPEG/BMP files and libtiff for TIFF files. The following image types are supported: @@ -17,7 +19,7 @@ The following image types are supported: ### Origin & Spacing Caveats -The user can optionally override the origin and spacing (length units per pixel) for the imported image. The default values from the input file will be used unless the user explicitly enables the "Set Origin" and/or "Set Spacing" options. +The user can optionally override the origin and spacing for the imported image. *Spacing* is the physical size of each pixel and *Origin* is the coordinate of the lower-left corner of the geometry; both are expressed in the same physical length units (for example microns). The default values from the input file will be used unless the user explicitly enables the "Set Origin" and/or "Set Spacing" options. When setting a custom origin, the user can choose whether to place the origin at the corner of the geometry (default) or at the center of the geometry by enabling the "Put Input Origin at the Center of Geometry" option. @@ -50,6 +52,10 @@ The user can crop the incoming 2D image using the Cropping Options section. The Both subvolume cropping types have checkboxes to turn on/off cropping in the X and Y dimensions. For example, if **Physical Subvolume** is selected and only **Crop Y Dimension** is enabled, the image will be cropped in the Y dimension only using physical coordinate bounds. +## Required Input Sources + +None — this filter reads directly from a single image file on disk. + % Auto generated parameter table will be inserted here ## Example Pipelines diff --git a/src/Plugins/SimplnxCore/docs/ReadImageStackFilter.md b/src/Plugins/SimplnxCore/docs/ReadImageStackFilter.md index 8bfdb21328..f58c87e044 100644 --- a/src/Plugins/SimplnxCore/docs/ReadImageStackFilter.md +++ b/src/Plugins/SimplnxCore/docs/ReadImageStackFilter.md @@ -1,4 +1,4 @@ -# Read Image Stack +# Read Images [3D Stack] ## Group (Subgroup) @@ -6,7 +6,7 @@ IO (Input) ## Description -Reads a numbered sequence of 2D image files and stacks them into a 3D volume. This filter does not depend on ITK; it uses stb_image for PNG/JPEG/BMP files and libtiff for TIFF files. The per-slice read is delegated to the **Read Image** filter, so any option available there (data type conversion, origin/spacing overrides, 2D cropping) is also available per-slice here. +Reads a numbered sequence of 2D image files and stacks them into a 3D volume. This filter does not depend on ITK; it uses stb_image for PNG/JPEG/BMP files and libtiff for TIFF files. The per-slice read is delegated to the [Read Image](ReadImageFilter.md) filter, so any option available there (data type conversion, origin/spacing overrides, 2D cropping) is also available per-slice here. Supported image types: @@ -15,6 +15,10 @@ Supported image types: - BMP (via stb) - TIFF / TIF (via libtiff) +### File List and Slice Ordering + +The stack is defined by a file list rather than a single file. The user supplies an input directory plus a numeric naming pattern (a file prefix, suffix, file extension, and the start/end index with a padding digit count). The filter expands that pattern into an ordered list of files, where each file becomes one Z-slice of the resulting 3D volume. The first file in the list becomes Z = 0, the next file Z = 1, and so on, so the numeric ordering of the file names directly determines the slice order along the Z axis. The total number of files becomes the Z dimension of the created **Image Geometry**. + ### Processing Order Image operations are applied in the following order: @@ -27,7 +31,7 @@ Image operations are applied in the following order: ### Origin & Spacing Caveats -The filter will create a new Image Geometry. The user can optionally override the origin and spacing for the created geometry. The default values from the input files will be used unless the user explicitly enables the "Set Origin" and/or "Set Spacing" options. +The filter will create a new **Image Geometry**. The user can optionally override the origin and spacing for the created geometry. *Spacing* is the physical size of each voxel and *Origin* is the coordinate of the lower-left-back corner of the volume; both are expressed in the same physical length units (for example microns). The default values from the input files will be used unless the user explicitly enables the "Set Origin" and/or "Set Spacing" options. ### Origin & Spacing Processing @@ -64,7 +68,7 @@ The user can optionally resample each image as it is read in. The *Resample Imag ### Grayscale Conversion -When *Convert To GrayScale* is enabled, RGB image data is converted to a scalar grayscale array using the luminosity algorithm with the supplied *Color Weighting* values. Only uint8 input data is supported for grayscale conversion. +When *Convert To GrayScale* is enabled, RGB image data is converted to a scalar grayscale array using the luminosity algorithm. The luminosity algorithm computes each gray value as a weighted sum of the red, green, and blue channels (gray = wR·R + wG·G + wB·B), where the weights come from the supplied *Color Weighting* values (dimensionless). This produces a perceptually weighted brightness rather than a simple channel average. Only uint8 input data is supported for grayscale conversion. ### Output Data Type @@ -88,6 +92,10 @@ Both subvolume cropping types have checkboxes to turn on/off cropping in each of The user can select to flip the images about the X or Y axis during import. +## Required Input Sources + +None — this filter reads from a file list of image files on disk. + % Auto generated parameter table will be inserted here ## Example Pipelines diff --git a/src/Plugins/SimplnxCore/docs/ReadNIfTIFileFilter.md b/src/Plugins/SimplnxCore/docs/ReadNIfTIFileFilter.md index 983a12d4cb..eabf585ffb 100644 --- a/src/Plugins/SimplnxCore/docs/ReadNIfTIFileFilter.md +++ b/src/Plugins/SimplnxCore/docs/ReadNIfTIFileFilter.md @@ -15,10 +15,10 @@ The filter transparently handles both uncompressed (`.nii`) and gzipped comparing `sizeof_hdr` against the expected value of 348. NIfTI-1 allows a variable-length extension block between the 348-byte -header and the voxel data. The filter honors `vox_offset` and seeks -past the extension block before reading voxels — any custom extension -metadata (DICOM attributes, AFNI XML, etc.) is **skipped, not -preserved**. +header and the voxel data. The filter honors `vox_offset` (the byte offset +in the file where the voxel data begins) and seeks past the extension +block before reading voxels — any custom extension metadata (DICOM +attributes, AFNI XML, etc.) is **skipped, not preserved**. ### Supported voxel datatypes @@ -41,10 +41,19 @@ Complex and 128-bit float types are not currently supported. ### Orientation -When *Use Stored Affine Transform* is enabled (the default), the filter uses +NIfTI stores up to two affine transforms that map voxel indices to physical +space: the `sform` ("standard" transform, a general affine matrix) and the +`qform` ("quaternion" transform, a rigid rotation plus translation). When +*Use Stored Affine Transform* is enabled (the default), the filter uses the NIfTI `sform` transform (if `sform_code > 0`) or `qform` transform (if `qform_code > 0`) to set the **Image Geometry** origin and spacing. If neither -is set, the filter falls back to `pixdim[1..3]` for spacing and a zero origin. +is set, the filter falls back to `pixdim[1..3]` (the per-axis voxel size +stored in the header) for spacing and a zero origin. + +The spacing units are whatever the source file recorded (most commonly +millimeters for medical NIfTI data) and are **not** converted by this +filter. Treat the resulting **Image Geometry** spacing as being in the +file's native physical units. simplnx Image Geometries are axis-aligned; if the stored transform contains a non-trivial rotation, only the spacing (column magnitudes) and origin are @@ -53,8 +62,10 @@ native storage order. ### Data scaling -When *Apply Scaling Transform* is enabled and the header specifies a -non-trivial scaling (`scl_slope != 0` and (`scl_slope != 1` or +NIfTI can store a linear intensity rescaling defined by two header fields: +`scl_slope` (the multiplicative slope) and `scl_inter` (the additive +intercept). When *Apply Scaling Transform* is enabled and the header +specifies a non-trivial scaling (`scl_slope != 0` and (`scl_slope != 1` or `scl_inter != 0`)), the filter computes `y = scl_slope * x + scl_inter` at read time and promotes the output array to `float32`. Per the NIfTI-1 specification, scaling is never applied to `RGB24` or `RGBA32` data and a @@ -129,18 +140,6 @@ version: In short: use cropping to keep the output DataArray small, not to make large compressed files read faster. -## Parameters - -| Parameter | Type | Default | Description | -|---|---|---|---| -| Input NIfTI File | File path | — | Path to the `.nii` or `.nii.gz` file to read. | -| Use Stored Affine Transform | Bool | `true` | Use `sform`/`qform` to set origin + spacing when present. | -| Apply Scaling Transform | Bool | `true` | Apply `y = slope*x + inter` at read time; promotes to float32. | -| Cropping Options | CropGeometry | `NoCropping` | Optional voxel-index or physical-coordinate sub-volume. Only the selected region is retained in the output DataArray; data outside the region is read but never stored. | -| Image Geometry | Data Path | `NIfTI Image` | Path to the created Image Geometry. | -| Cell Attribute Matrix Name | String | `Cell Data` | Name of the attribute matrix holding voxel values. | -| Image Data Array Name | String | `ImageData` | Name of the array receiving voxel values. | - ## Caveats * Only the single-file NIfTI-1 format (magic `n+1`) is supported. The @@ -163,7 +162,11 @@ large compressed files read faster. * `start <= end` is required on each cropped axis; reversed ranges are rejected at parameter-validation time. -% Auto generated parameter table will be inserted here +## Required Input Sources + +None — this filter reads directly from a `.nii` or `.nii.gz` file on disk. + +% Auto generated parameter table will be inserted here ## Reference diff --git a/src/Plugins/SimplnxCore/docs/ReadRawBinaryFilter.md b/src/Plugins/SimplnxCore/docs/ReadRawBinaryFilter.md index 108db506ba..da7fc63087 100644 --- a/src/Plugins/SimplnxCore/docs/ReadRawBinaryFilter.md +++ b/src/Plugins/SimplnxCore/docs/ReadRawBinaryFilter.md @@ -75,6 +75,10 @@ The output array can be placed in two ways: 2. **Standalone**: Select an output path that is not inside an Attribute Matrix (e.g., `MyArray`). The user must provide explicit tuple dimensions via the *Set Tuple Dimensions* checkbox and table. +### Required Input Sources + +None — this filter reads directly from a raw binary file on disk. + % Auto generated parameter table will be inserted here ## Example Pipelines diff --git a/src/Plugins/SimplnxCore/docs/ReadStlFileFilter.md b/src/Plugins/SimplnxCore/docs/ReadStlFileFilter.md index 0e5de47d6e..a6a0c961d4 100644 --- a/src/Plugins/SimplnxCore/docs/ReadStlFileFilter.md +++ b/src/Plugins/SimplnxCore/docs/ReadStlFileFilter.md @@ -6,40 +6,44 @@ IO (Input) ## Description -This **Filter** will read a binary STL File and create a **Triangle Geometry** object in memory. The STL reader is very strict to the STL specification. An explanation of the STL file format can be found on [Wikipedia](https://en.wikipedia.org/wiki/STL). The structure of the file is as follows: +An STL file describes a 3D surface as a list of triangles. This filter reads a **binary** STL file from disk and creates a **Triangle Geometry** (a surface mesh made of triangular faces) in memory, along with a *Face Normals* array (one 3-component normal vector per triangle) and, optionally, a *Face Labels* array. + +The vertex coordinates in an STL file are plain numbers with no embedded unit. They are in whatever length unit the file's author intended (often millimeters or inches), so the reader treats them as dimensionless and copies them through unchanged. + +**Only binary STL files are supported. ASCII STL files are not read by this filter; the filter will report an error if given one.** An ASCII STL file can be converted to binary using a separate 3D mesh tool before reading. + +An explanation of the STL file format can be found on [Wikipedia](https://en.wikipedia.org/wiki/STL_(file_format)). The binary structure is: UINT8[80] Header - UINT32 Number of triangles + UINT32 Number of triangles foreach triangle REAL32[3] Normal vector REAL32[3] Vertex 1 REAL32[3] Vertex 2 REAL32[3] Vertex 3 - UINT16 Attribute byte count + UINT16 Attribute byte count end -The filter will look for specific header information to try and determine the vendor of the STL file. Certain vendors do not write STL files that adhere to the file spec. +The filter inspects the header to try to determine the vendor of the STL file, because some vendors do not write files that strictly follow the specification. -## IMPORANT NOTES: +## IMPORTANT NOTES -**It is very important that the "Attribute byte Count" is correct as DREAM3D-NX follows the specification strictly.** If you are writing an STL file be sure that the value for the "Attribute byte count" is *zero* (0). If you chose to encode additional data into a section after each triangle then be sure that the "Attribute byte count" is set correctly. DREAM3D-NX will obey the value located in the "Attribute byte count". +The reader follows the STL specification strictly and obeys the "Attribute byte count" value written after each triangle. If you are writing an STL file, set the "Attribute byte count" to *zero* (0) unless you are deliberately encoding extra data after each triangle, in which case the count must exactly match the number of extra bytes. An incorrect "Attribute byte count" is the most common cause of read failures, because the reader will skip the number of bytes the file claims are present. -## Known Vendors who Write out of spec STL Files +## Known Vendors Who Write Out-of-Spec STL Files - Materialise Magics [https://www.materialise.com/en/industrial/software/magics-data-build-preparation](https://www.materialise.com/en/industrial/software/magics-data-build-preparation) - The filter looks in the header for "COLOR=" and "MATERIAL=" strings in the header. + The filter looks in the header for "COLOR=" and "MATERIAL=" strings. - Creaform VXelements [https://www.creaform3d.com/en/metrology-solutions/3d-applications-software-platforms](https://www.creaform3d.com/en/metrology-solutions/3d-applications-software-platforms) - + The filter looks for "VXelements" in the header. -## Code to convert +## Code to Convert -If you find yourself in a situation where the STL File is non-conforming and is not made by one of the vendors above, this bit of Python -code can clean up the file. This makes the absolute assumption that the **ONLY** thing wrong with the STL file is that the trailing UINT16 value for -each triangle needs to be set to ZERO. +If you have a non-conforming STL file that was not made by one of the vendors above, the Python snippet below can clean it up. It assumes the **ONLY** problem with the file is that the trailing UINT16 "Attribute byte count" value for each triangle needs to be set to zero. import struct @@ -48,24 +52,24 @@ each triangle needs to be set to ZERO. # Read and copy header header = input_file.read(80) output_file.write(header) - + # Read number of triangles num_triangles = struct.unpack(' [Greater Than] [1]**: Targets **Cells** whose value is greater than the threshold. The replacement neighbor is the one with the lowest value among neighbors that fall below the threshold. +1. For every cell, compare its value of the *Selected Array* to the *Threshold Value* using the *Comparison Operator* (less-than or greater-than). +2. For each cell that passes the comparison (i.e., is flagged for replacement), examine its 6 face-neighbors. +3. Among the neighbors that do **not** pass the comparison, find the one with the maximum (when operator is `<`) or minimum (when operator is `>`) value of the same scalar. This is the "best" neighbor. +4. Copy **all** cell-level arrays in the same attribute matrix from that best neighbor into the flagged cell. -*Note:* By default, the **Filter** will run only one iteration of the cleanup. If the user selects the *Loop Until Gone* -option, then the **Filter** will run iteratively until no **Cells** exist that meet the users criteria. So, if a **Cell** -meets the threshold and so are all of its neighbors, then that **Cell** will not be changed during that iteration and -will remain unchanged until one of its neighbors gets changed by a **Cell** further away. +If a flagged cell has only flagged neighbors (i.e., none of its neighbors pass the threshold), it is left unchanged in this pass. -## Examples +### Comparison Operator -### TSL Data (.ang) File +- **< [Less Than] [0]**: Targets cells whose scalar is **less than** the threshold. Replacement neighbor is the one with the **highest** scalar value among neighbors that exceed the threshold. Use this for measures where higher = better (Confidence Index, Image Quality). +- **> [Greater Than] [1]**: Targets cells whose scalar is **greater than** the threshold. Replacement neighbor is the one with the **lowest** scalar value among neighbors that fall below the threshold. Use this for measures where lower = better (Mean Angular Deviation, scan error metrics). -When attempting to "clean up" EBSD data generated by EDAX/TSL the Attribute Array "Confidence Index" can be used. -Confidence Index is a measure of how confident in the indexing results given by the OIM Analysis software and ranges -from 0.0 (No confidence) to 1.0 (Absolute confidence). More information about the Confidence Index can be found in the -OIM analysis user manual. Typical inputs for TSL (.ang) Data might be the following. +### Loop Until Gone -| Filter Parameter | Value | -|------------------|-----------------------------------------------| -| Threshold Value | 0.1 | -| Operator | < | -| Selected Array | [DataContainer] / CellData / Confidence Index | -| Loop Until Gone | User dependent | +By default, the filter runs a **single pass**. If a flagged cell's neighbors are all flagged in that pass, the cell is left alone. Enabling *Loop Until Gone* repeats the algorithm until every flagged cell has been replaced (typically because flag-replacements propagate inward across multiple passes). + +### Caution: Flood Fill Behavior + +If the threshold is set too aggressively or the dataset has large contiguous regions of low-quality cells, *Loop Until Gone* can act like a flood-fill, propagating one neighbor's data across an entire region. The end result may bear little resemblance to the true microstructure. Always inspect the output and, if grain morphology has shifted dramatically, lower the *Threshold Value* or run a single pass. + +| Original Data | Threshold CI < 0.1 | After Running Filter | True Data | +|---------------------------------------------------------|--------------------------------------------------------------------------------------------------------|---------------------------------------------------|----------------------------------------------| +| ![Original Data](Images/NeighborReplace_No_Cleanup.png) | ![Original Data. Black pixels have Confidence Index < 0.1](Images/NeighborReplace_No_Cleanup_Mask.png) | ![Text](Images/NeighborReplace_After_Cleanup.png) | ![Text](Images/NeighborReplace_Exemplar.bmp) | -Using these values says that for every cell that has a confidence index < 0.1 it's neighbor cells will be considered. If -the neighbor cell has a confidence > 0.1 AND is greater than the other neighbors then this cell's data will be copied -into the original cell data location. +The example above shows what happens when too much of the data is below threshold: most fine grains and twins do **not** match the true microstructure. -### Example EDAX Results +## Example Use Cases -**Reasonable Use of the Filter** +### Reasonable Use of the Filter | Original Data | | After Running Filter | True Data | |-----------------------------------------------------------|-----|-----------------------------------------------------|----------------------------------------------| | ![Original Data](Images/NeighborReplace_No_Cleanup_2.png) | | ![Text](Images/NeighborReplace_After_Cleanup_2.png) | ![Text](Images/NeighborReplace_Exemplar.bmp) | -**Example of Too Much Replacement** +### TSL Data (.ang) -- Using Confidence Index -| Original Data | Threshold CI < 0.1 | After Running Filter | True Data | -|---------------------------------------------------------|--------------------------------------------------------------------------------------------------------|---------------------------------------------------|----------------------------------------------| -| ![Original Data](Images/NeighborReplace_No_Cleanup.png) | ![Original Data. Black pixels have Confidence Index < 0.1](Images/NeighborReplace_No_Cleanup_Mask.png) | ![Text](Images/NeighborReplace_After_Cleanup.png) | ![Text](Images/NeighborReplace_Exemplar.bmp) | +EDAX/TSL ANG files include a *Confidence Index* (CI) array that ranges from 0.0 (no confidence) to 1.0 (absolute confidence). To clean up cells with poor indexing, use: -Note how in the above use of the filter the grain morphology is substantially changed from the exemplar data. Except for -very large grains being similar most of the fine grains and twins are **NOT** reproduced from the original. +| Filter Parameter | Value | +|------------------|-----------------------------------------------| +| Threshold Value | 0.1 | +| Operator | < | +| Selected Array | [DataContainer] / CellData / Confidence Index | +| Loop Until Gone | User dependent | + +This says: for every cell with CI < 0.1, find the neighbor with the highest CI among those above 0.1, and copy that neighbor's data into the cell. -### Oxford/Bruker (.ctf) File +### Oxford/Bruker (.ctf) -- Using Error -Oxford Instruments and Bruker CTF data files do not include a "Confidence Index" measure. There are several measures -such as *Mean Angular Deviation (MAD)* or *Bands* but these values are not filled in or are defaulted to 0 (Zero) if the -scan point was not indexed. By using the *Error* value from the data file we can get the same effect as the EDAX -*Confidence Index*. The user would use the following input values: +CTF files do not include a Confidence Index, but they do have an *Error* value that defaults to 0 for indexed points and is non-zero for non-indexed points. This is the inverse direction from CI: | Filter Parameter | Value | |------------------|------------------------------------| @@ -74,14 +70,15 @@ scan point was not indexed. By using the *Error* value from the data file we can | Selected Array | [DataContainer] / CellData / Error | | Loop Until Gone | User dependent | -### Example Oxford/Bruker Results - | Original Data | After Running Filter | |---------------------------------------------------------|-------------------------------------------| | ![Original Data](Images/NeighborReplace_CTF_Before.png) | ![](Images/NeighborReplace_CTF_After.png) | -Note the large areas of unindexed pixels in the original image (black pixels) and how they are all filled in. The filter -can act much like a generic "flood fill" image processing algorithm if used improperly. +The black pixels in the original are unindexed cells (Error > 0) and are filled in by the filter. + +### Required Input Sources + +- **Selected Scalar Array** -- any single-component cell-level scalar suitable for thresholding. Common sources: confidence/quality arrays from [Read H5EBSD](../OrientationAnalysis/ReadH5EbsdFilter.md), [Read CTF Data](../OrientationAnalysis/ReadCtfDataFilter.md), or [Read ANG Data](../OrientationAnalysis/ReadAngDataFilter.md), or any computed per-cell scalar. % Auto generated parameter table will be inserted here diff --git a/src/Plugins/SimplnxCore/docs/RequireMinNumNeighborsFilter.md b/src/Plugins/SimplnxCore/docs/RequireMinNumNeighborsFilter.md index 5596f74021..887351a8c8 100644 --- a/src/Plugins/SimplnxCore/docs/RequireMinNumNeighborsFilter.md +++ b/src/Plugins/SimplnxCore/docs/RequireMinNumNeighborsFilter.md @@ -6,17 +6,27 @@ Processing (Cleanup) ## Description -This **Filter** sets the minimum number of contiguous neighboring **Features** a **Feature** must have to remain in the structure. Entering zero results in nothing changing. Entering a number larger than the maximum number of neighbors of any **Feature** generates an *error* (since all **Features** would be removed). The user needs to proceed conservatively here when choosing the value for the minimum to avoid accidentally exceeding the maximum. After **Features** are removed for not having enough neighbors, the remaining **Features** are *coarsened* iteratively, one **Cell** per iteration, until the gaps left by the removed **Features** are filled. Effectively, this is an isotropic **Feature** growth in the regions around removed **Features**. +This **Filter** removes **Features** that have fewer than the user-specified number of contiguous neighbors. The most common use case is cleaning up isolated single-feature islands left over from segmentation -- features whose surroundings turned out to be too sparsely connected to support a meaningful grain. After flagged features are removed, the remaining features grow outward via [isotropic coarsening](RequireMinimumSizeFeaturesFilter.md) until every cell is reassigned. -The **Filter** can be run in a mode where the minimum number of neighbors is applied to a single **Ensemble**. The user can select to apply the minimum to one specific **Ensemble**. +The threshold is a **count of contiguous neighbors** (a non-negative integer). Setting the threshold to 0 removes nothing. Setting it larger than the maximum number of neighbors any feature has produces an error (since all features would be removed). Inspect the *Number of Neighbors* output of [Compute Feature Neighbors](ComputeFeatureNeighborsFilter.md) before choosing a threshold. + +### Apply to Single Phase + +When *Apply to Single Phase* is enabled, the threshold is applied only to features of the specified phase. Features of other phases are untouched regardless of how many neighbors they have. This is useful when isolated features are noise in one phase but meaningful in another. ## WARNING: Feature Data Will Become Invalid -By modifying the cell level data, any feature data that was previously computed will most likely be invalid at this point. Filters that compute feature level data should be rerun to ensure accurate final results from your pipeline. +By modifying cell-level data, any feature-level data that was previously computed will most likely be invalid after this filter runs. Re-run any downstream feature-level computation filters to ensure accurate results. ## WARNING: NeighborList Removal -If the Cell Feature AttributeMatrix contains any *NeighborList* data arrays, those arrays will be **REMOVED** because those lists are now invalid. Re-run the *Find Neighbors* filter to re-create the lists. +If the Cell Feature **Attribute Matrix** contains any *NeighborList* arrays, they will be **removed** because the neighbor relationships have changed. Re-run [Compute Feature Neighbors](ComputeFeatureNeighborsFilter.md) afterward to rebuild them. + +### Required Input Sources + +- **Cell Feature Ids** -- produced by a segmentation filter such as [Segment Features (Misorientation)](../OrientationAnalysis/EBSDSegmentFeaturesFilter.md) or [Segment Features (Scalar)](ScalarSegmentFeaturesFilter.md). +- **Number of Neighbors** -- produced by [Compute Feature Neighbors](ComputeFeatureNeighborsFilter.md). +- **Feature Phases** (only when *Apply to Single Phase* is enabled) -- produced by [Compute Feature Phases](ComputeFeaturePhasesFilter.md). % Auto generated parameter table will be inserted here @@ -24,7 +34,6 @@ If the Cell Feature AttributeMatrix contains any *NeighborList* data arrays, tho + (02) Small IN100 Full Reconstruction - ## License & Copyright Please see the description file distributed with this **Plugin** diff --git a/src/Plugins/SimplnxCore/docs/RequireMinimumSizeFeaturesFilter.md b/src/Plugins/SimplnxCore/docs/RequireMinimumSizeFeaturesFilter.md index d3a1c185b3..f106557a1f 100644 --- a/src/Plugins/SimplnxCore/docs/RequireMinimumSizeFeaturesFilter.md +++ b/src/Plugins/SimplnxCore/docs/RequireMinimumSizeFeaturesFilter.md @@ -6,17 +6,43 @@ Processing (Cleanup) ## Description -This **Filter** removes **Features** that have a total number of **Cells** below the minimum threshold defined by the user. Entering a number larger than the largest **Feature** generates an *error* (since all **Features** would be removed). Hence, a choice of threshold should be carefully chosen if it is not known how many **Cells** are in the largest **Features**. After removing all the small **Features**, the remaining **Features** are isotropically coarsened to fill the gaps left by the small **Features**. +This **Filter** removes small **Features** from a segmented dataset and fills in the space they leave behind by expanding their neighbors. Features whose cell count is below the user-specified *Minimum Allowed Features Size* are erased; the remaining features grow outward into the erased cells until every cell is reassigned to a surviving feature. -The **Filter** can be run in a mode where the minimum number of neighbors is applied to a single **Ensemble**. The user can select to apply the minimum to one specific **Ensemble**. +This is typically used immediately after segmentation ([Segment Features (Misorientation)](../OrientationAnalysis/EBSDSegmentFeaturesFilter.md) or similar) to discard spurious single-cell or few-cell "grains" that are almost always noise rather than real features. + +### How This Filter Works + +1. For each **Feature**, look up its cell count from the input *Feature Num. Cells* array. +2. If the feature's count is below the threshold, mark it for removal. All of its cells are temporarily set to Feature Id 0 ("unassigned"). +3. After all small features are removed, the remaining features are *isotropically coarsened* to fill the gaps. + +### What is Isotropic Coarsening? + +"Isotropic coarsening" is an iterative dilation that grows each surviving feature outward by one cell layer at a time, uniformly in all directions. On each pass, an unassigned cell is given the Feature Id of whichever neighbor feature touches it; if multiple features touch it, one is picked. The process repeats until no unassigned cells remain. The result is that every removed cell is absorbed into the closest surviving feature, with no preferred direction. + +### Minimum Size Units + +The *Minimum Allowed Features Size* is in **cells** (integer voxel count), not physical units. A threshold of 10 means "remove any feature with fewer than 10 cells," regardless of the image's spacing. To convert a physical-volume threshold into a cell count, divide by the product of the cell spacing (dx * dy * dz). + +Entering a number larger than the size of the largest feature produces an error, since every feature would be removed. If the size distribution is unknown, compute feature sizes first with [Compute Feature Sizes](ComputeFeatureSizesFilter.md) and inspect the range. + +### Apply to Single Phase + +When *Apply to Single Phase* is enabled, the size threshold is applied only to features of the specified phase. Features of other phases are untouched regardless of their size. This is useful when small features are noise in one phase but meaningful in another (e.g., small precipitates in a matrix). ## WARNING: Feature Data Will Become Invalid -By modifying the cell level data, any feature data that was previously computed will most likely be invalid at this point. Filters that compute feature level data should be rerun to ensure accurate final results from your pipeline. +By modifying the cell-level Feature Ids, any feature-level data that was previously computed (sizes, centroids, average orientations, etc.) will almost certainly be invalid after this filter runs. Re-run any feature-level computation filters downstream of this one to ensure accurate results. ## WARNING: NeighborList Removal -If the Cell Feature AttributeMatrix contains any *NeighborList* data arrays, those arrays will be **REMOVED** because those lists are now invalid. Re-run the *Find Neighbors* filter to re-create the lists. +If the Cell Feature **Attribute Matrix** contains any *NeighborList* arrays, they will be **removed** because the list of neighbors for each surviving feature has changed. Re-run [Compute Feature Neighbors](ComputeFeatureNeighborsFilter.md) afterward to rebuild the neighbor relationships. + +### Required Input Sources + +- **Cell Feature Ids** -- produced by a segmentation filter such as [Segment Features (Misorientation)](../OrientationAnalysis/EBSDSegmentFeaturesFilter.md) or [Segment Features (Scalar)](ScalarSegmentFeaturesFilter.md). +- **Feature Num. Cells** -- the cell count per feature, produced by [Compute Feature Sizes](ComputeFeatureSizesFilter.md). +- **Feature Phases** (only when *Apply to Single Phase* is enabled) -- produced by [Compute Feature Phases](ComputeFeaturePhasesFilter.md). % Auto generated parameter table will be inserted here @@ -24,7 +50,6 @@ If the Cell Feature AttributeMatrix contains any *NeighborList* data arrays, tho + (02) Small IN100 Full Reconstruction - ## License & Copyright Please see the description file distributed with this **Plugin** diff --git a/src/Plugins/SimplnxCore/docs/ResampleImageGeomFilter.md b/src/Plugins/SimplnxCore/docs/ResampleImageGeomFilter.md index cbaf8036ba..4ebecb5b26 100644 --- a/src/Plugins/SimplnxCore/docs/ResampleImageGeomFilter.md +++ b/src/Plugins/SimplnxCore/docs/ResampleImageGeomFilter.md @@ -6,75 +6,54 @@ Sampling (Resample) ## Description -This **Filter** changes the **Cell** spacing/resolution based on inputs from the user. There are several resampling modes: +This **Filter** changes the cell resolution of an **Image Geometry** by overlaying a new regular grid on the existing data and copying the *closest-cell* value from the old grid to each new cell. No interpolation is performed. -### Resampling Mode - -The *Resampling Mode* parameter provides the following choices: - -- **Spacing (0) [0]**: The entered values are the desired new spacings (not multiples of the current resolution). The number of cells in the volume will change accordingly. -- **Scaling (1) [1]**: The entered values are the desired scaling factor for each dimension, expressed as percentages. -- **Exact Dimensions (2) [2]**: The entered values are the desired cell dimensions of the resampled geometry. - -## WARNING: NeighborList Removal - -If the option to "Renumber Features" is turn ON and the Cell Feature AttributeMatrix contains any *NeighborList* data arrays, those arrays will be **REMOVED** because those lists are now invalid. Re-run the *Find Neighbors* filter to re-create the lists. - -### Spacing - -The values entered are the desired new spacings (not multiples of the current resolution). The number of **Cells** in the volume will change when the spacing values are changed and thus the user should be cautious of generating "too many" **Cells** by entering very small values (i.e., very high resolution). +The overall **bounds** of the volume do not change -- only the spacing and the number of cells. To scale the physical extent of a geometry, apply a scaling transformation with [Apply Transformation To Geometry](ApplyTransformationToGeometryFilter.md) instead. -**Example 1**: - -Image Geometry with cell dimensions (524, 390, 164) and spacing (1, 1, 1). - -If the new spacing value is (2, 2, 2), then the geometry will have cell dimensions (262, 195, 82) and spacing (2, 2, 2). - -**Example 2**: - -Image Geometry with cell dimensions (524, 390, 164) and spacing (1, 1, 1). - -If the new spacing value is (0.25, 0.7, 2.3), then the geometry will have cell dimensions (2096, 557, 71) and spacing (0.25, 0.7, 2.3). - -### Scale Factor +### Resampling Mode -The values entered are the desired scaling factor for each dimension, in percentages. +The *Resampling Mode* parameter provides three ways to specify the new grid: -**Example 1**: +- **Spacing [0]**: Set the new spacing directly (in physical units; same as the input geometry's spacing). The cell count adjusts accordingly. Use small spacings cautiously -- they can produce very large cell counts. +- **Scaling [1]**: Scale spacing by a percentage per axis. A scaling factor of 30% reduces cell count to roughly 30% of the original (and increases spacing by ~3.33x). +- **Exact Dimensions [2]**: Set the exact new cell counts per axis (integer). Spacing is computed automatically to span the original bounds. -Image Geometry with cell dimensions (524, 390, 164) and spacing (1, 1, 1). +#### Spacing Examples -If the new scaling value is (30%, 30%, 30%), then the geometry will have cell dimensions (157, 117, 49) and spacing (3.3333, 3.3333, 3.3333). +Image with cell dimensions (524, 390, 164) and spacing (1, 1, 1) (units in microns/voxel). -**Example 2**: +- New spacing (2, 2, 2) → cell dimensions (262, 195, 82), spacing (2, 2, 2) microns/voxel. +- New spacing (0.25, 0.7, 2.3) → cell dimensions (2096, 557, 71), spacing (0.25, 0.7, 2.3). -Image Geometry with cell dimensions (524, 390, 164) and spacing (1, 1, 1). +#### Scaling Examples -If the new scaling value is (120.4%, 50.74%, 68.12%), then the geometry will have cell dimensions (630, 197, 111) and spacing (0.830565, 1.97083, 1.468). +Same starting image. -### Exact Dimensions +- Scaling (30%, 30%, 30%) → cell dimensions (157, 117, 49), spacing (3.333, 3.333, 3.333). +- Scaling (120.4%, 50.74%, 68.12%) → cell dimensions (630, 197, 111), spacing (0.831, 1.971, 1.468). -The values entered are the desired cell dimensions of the resampled geometry. (100, 100, 100) would resample the geometry so that there are 100 cells in each dimension. +#### Exact Dimensions Examples -**Example 1**: +Same starting image. -Image Geometry with cell dimensions (524, 390, 164) and spacing (1, 1, 1). +- Exact dimensions (100, 100, 100) → cell dimensions (100, 100, 100), spacing (5.24, 3.9, 1.64). +- Exact dimensions (100, 500, 20) → cell dimensions (100, 500, 20), spacing (5.24, 0.78, 8.2). -If the new exact dimensions are (100, 100, 100), then the geometry will have cell dimensions (100, 100, 100) and spacing (5.24, 3.9, 1.64). +### Resampling Algorithm -**Example 2**: +A new regular grid is overlaid on the old one. For each new cell, the filter finds the old cell whose center is closest and copies that old cell's attributes (Feature Ids, phases, orientations, etc.) into the new cell. There is **no interpolation** -- this is the right behavior for label data (Feature Ids), but it does mean that small features can disappear during downsampling. -Image Geometry with cell dimensions (524, 390, 164) and spacing (1, 1, 1). +### Renumber Features -If the new exact dimensions are (100, 500, 20), then the geometry will have cell dimensions (100, 500, 20) and spacing (5.24, 0.78, 8.2). +When downsampling produces a result in which some Features no longer have any cells, those Features become invalid. Enable *Renumber Features* to detect this case, resize the Cell Feature Attribute Matrix to drop the empty features, and renumber the remaining features so that Feature IDs remain contiguous starting at 1. ---- +## WARNING: NeighborList Removal -A new grid of **Cells** is created and "overlaid" on the existing grid of **Cells**. There is currently no *interpolation* performed, rather the attributes of the old **Cell** that is closest to each new **Cell's** is assigned to that new **Cell**. +When *Renumber Features* is enabled and the Cell Feature Attribute Matrix contains any *NeighborList* arrays, those arrays are **removed** because they refer to the old (pre-renumber) Feature IDs. Re-run [Compute Feature Neighbors](ComputeFeatureNeighborsFilter.md) afterward to rebuild them. -*Note:* Present **Features** may disappear when down-sampling to coarse resolutions. If *Renumber Features* is checked, the **Filter** will check if this is the case and resize the corresponding **Feature Attribute Matrix** to comply with any changes. Additionally, the **Filter** will renumber **Features** such that they remain contiguous. +### Required Input Sources -*Note:* This filter does NOT change the overall bounds of the volume, just the spacing and number of cells in the volume. To change the overall bounds of the volume, apply a scaling transformation with the [Apply Transformation To Geometry](./ApplyTransformationToGeometryFilter.md) filter. +- **Input Image Geometry** -- the geometry to be resampled. Typically produced by [Create Image Geometry](CreateImageGeometryFilter.md), [ITK Import Image Stack](../ITKImageProcessing/ITKImportImageStackFilter.md), or an EBSD reader. % Auto generated parameter table will be inserted here diff --git a/src/Plugins/SimplnxCore/docs/ResampleRectGridToImageGeomFilter.md b/src/Plugins/SimplnxCore/docs/ResampleRectGridToImageGeomFilter.md index bbc146e6ed..6ef84c23b2 100644 --- a/src/Plugins/SimplnxCore/docs/ResampleRectGridToImageGeomFilter.md +++ b/src/Plugins/SimplnxCore/docs/ResampleRectGridToImageGeomFilter.md @@ -6,13 +6,30 @@ Sampling (Sampling) ## Description -This **Filter** will resample an existing RectilinearGrid onto a regular grid (Image Geometry) and copy cell data into the newly created Image Geometry Data Container during the process. +This **Filter** converts a **Rectilinear Grid Geometry** (which has variable spacing along each axis) into an **Image Geometry** (which has uniform spacing along each axis). Selected cell-level arrays from the rectilinear grid are copied onto the new uniform grid using a *last-one-wins* rule. -The sampling algorithm is a simple "last one wins" algorithm due to the likely hood that interpolating data is probably not the correct algorithm to bring in data to the new Image Geometry. +### When to Use This Filter -The algorithm logic is thus: If the ImageGeometry cell would contain multiple RectilinearGrid cells, then we select from the covered cells the cell with the largest X, Y and Z index and copy that data into the Image Geometry Cell Attribute Matrix. +Many downstream filters and most external visualization tools expect uniform-grid data. This filter is the right choice when: -The user can select which cell attribute matrix data arrays will be copied into the newly created Image Geometry Cell Attribute Matrix. +- You have data on a variable-spacing rectilinear grid (e.g., imported from a simulation or instrument that uses non-uniform sampling). +- You need uniform Image Geometry data for downstream processing. +- The data being resampled is *categorical* (Feature Ids, phase labels) and interpolation would produce nonsensical intermediate values. + +For interpolatable scalar data (intensity, density), prefer a true resampling filter with interpolation rather than this filter. + +### Algorithm + +If a single Image Geometry cell covers multiple Rectilinear Grid cells, the filter selects the rectilinear cell with the **largest X, Y, and Z index** among the covered cells and copies that one's data. This is a deterministic "last one wins" rule chosen because interpolating across categorical data would be incorrect. + +The user selects: + +- The target Image Geometry's dimensions, origin, and spacing. +- Which cell-level Attribute Arrays from the rectilinear grid should be copied onto the new geometry. + +### Required Input Sources + +- **Rectilinear Grid Geometry** -- the source geometry. Typically produced by [Create Geometry](CreateGeometryFilter.md) with type Rectilinear Grid, or imported from an external simulation. % Auto generated parameter table will be inserted here diff --git a/src/Plugins/SimplnxCore/docs/ReshapeDataArrayFilter.md b/src/Plugins/SimplnxCore/docs/ReshapeDataArrayFilter.md index cf73edcd11..60211190f7 100644 --- a/src/Plugins/SimplnxCore/docs/ReshapeDataArrayFilter.md +++ b/src/Plugins/SimplnxCore/docs/ReshapeDataArrayFilter.md @@ -6,17 +6,33 @@ Core (Generation) ## Description -This **Filter** is used to modify the tuple shape of Data Arrays, Neighbor Lists, and String Arrays within a data structure. It validates the new tuple dimensions to ensure they are positive and differ from the current shape, preventing unnecessary or invalid reshapes. +This **Filter** updates the **tuple dimensions** (the *shape* metadata) of an existing **Data Array**, **Neighbor List**, or **String Array** in place. The total number of tuples is unchanged; only how the shape is described is changed. -**THIS FILTER DOES NOT MOVE ANY THE VALUES IN MEMORY. IT SIMPLY UPDATES THE TUPLE DIMENSIONS. This means that if the data does not -have the proper stride for the new dimensions this could result in incorrect results.** +## ⚠ CRITICAL WARNING: Values Are Not Reordered -For example if a data set is read in from an HDF5 file with a tuple dimension of 3 x 45 this means that there are 45 columns -and 3 rows. If this data is supposed to be interpreted as 3D points, using this data within DREAM3D-NX would not -work because DREAM3D-NX is "C" ordered and the dimensions should be 3 columns x 45 rows. Using this filter will -**NOT** result the correct ordering of the data because the filter will not move any data in memory. +**This filter does NOT move any data in memory.** It only updates the tuple-dimensions metadata. If the data's existing memory layout does not match the new shape's expected layout, **the filter will silently produce incorrectly-shaped data** that downstream filters will misinterpret. -**NOTE:** If the input array is a Neighbor List or String Array, the filter will throw a warning if the new tuple dimensions are multi-dimensional. This is because these array types do not support multi-dimensional tuple dimensions and the filter will default to reshaping the data to an equivalent 1-dimensional number of tuples. +### When This Is Safe vs Dangerous + +DREAM3DNX uses **C-order (row-major)** layout: the last dimension varies fastest in memory. So `(3, 45)` is stored as 3 rows × 45 columns -- 3 contiguous chunks of 45 values each. + +- **Safe**: changing `(135)` → `(3, 45)` simply tells the system "treat this 135-tuple array as a 3×45 array". The bytes in memory are the same; only the shape interpretation changes. +- **Safe**: changing `(3, 45)` → `(135)` flattens to 1D. Memory is identical. +- **DANGEROUS**: reading an array from an HDF5 file that was stored 3 rows × 45 columns and trying to use it as 3-component 45-vertex data. In DREAM3DNX, 3-vertex data is stored as `(N, 3)` with 3 contiguous values per tuple. Calling Reshape from `(3, 45)` to `(45, 3)` **does not transpose** -- it just relabels the shape, and the bytes are now in the wrong order for the new shape. + +To actually transpose or reorder data, use external preprocessing (e.g., reshape the HDF5 dataset before reading) or use an array-arithmetic filter to manually rebuild the array with the desired ordering. + +### Validation + +The filter validates that the new tuple dimensions are positive and that the total tuple count matches the array's existing total. A shape change that would alter the total tuple count fails preflight. + +### Neighbor Lists and String Arrays + +Neighbor Lists and String Arrays do not support multi-dimensional tuple shapes. If you specify a multi-dimensional new shape for one of these array types, the filter emits a warning and falls back to an equivalent 1-D tuple count. + +### Required Input Sources + +- **Array to Reshape** -- any **Data Array**, **Neighbor List**, or **String Array** in the Data Structure. % Auto generated parameter table will be inserted here diff --git a/src/Plugins/SimplnxCore/docs/ReverseTriangleWindingFilter.md b/src/Plugins/SimplnxCore/docs/ReverseTriangleWindingFilter.md index d6b97553aa..fbf92d32aa 100644 --- a/src/Plugins/SimplnxCore/docs/ReverseTriangleWindingFilter.md +++ b/src/Plugins/SimplnxCore/docs/ReverseTriangleWindingFilter.md @@ -6,11 +6,15 @@ Surface Meshing (Connectivity/Arrangement) ## Description -This **Filter** reverses the *winding* for each **Triangle** in a **Triangle Geometry**. This will *reverse* the direction of calculated **Triangle** normals. Some analysis routines require the normals to be pointing "away" from the center of a **Feature**. This **Filter** allows for manipulation of this construct. +This **Filter** reverses the **winding** of every **Triangle** in a **Triangle Geometry**. The *winding* is the order in which a triangle's three vertices are listed; that order determines which way the triangle's normal points. Reversing the winding therefore *flips* the direction of the triangle normals so they point the opposite way. -% Auto generated parameter table will be inserted here +Some analysis routines require the normals to point "away" from the center of a **Feature**. This **Filter** lets you flip the winding so the normals point in the required direction. After reversing the winding, recompute normals with [Compute Triangle Normals](TriangleNormalFilter.md) so they reflect the new vertex order. To check whether a mesh has consistent winding before or after this operation, use [Verify Triangle Winding](VerifyTriangleWindingFilter.md). + +### Required Input Sources -## Example Pipelines +- **Triangle Geometry** -- the surface mesh whose triangle winding will be reversed. + +% Auto generated parameter table will be inserted here ## License & Copyright diff --git a/src/Plugins/SimplnxCore/docs/RobustAutomaticThresholdFilter.md b/src/Plugins/SimplnxCore/docs/RobustAutomaticThresholdFilter.md index 3042e596e9..146d27799b 100644 --- a/src/Plugins/SimplnxCore/docs/RobustAutomaticThresholdFilter.md +++ b/src/Plugins/SimplnxCore/docs/RobustAutomaticThresholdFilter.md @@ -2,15 +2,19 @@ ## Group (Subgroup) -DREAM3D Review (Threshold) +Threshold ## Description -This **Filter** automatically computes a threshold value for a scalar **Attribute Array** based on the array's gradient magnitude, producing a boolean array that is *false* where the input array is less than the threshold value and *true* otherwise. The threshold value is computed using the following equation: +This filter is *automatic* because it computes the threshold value itself, and *robust* because it derives that value from where the data changes most sharply rather than from a fixed cutoff. The user does not have to choose a threshold value manually; the filter selects one that tends to separate the input array along its sharpest boundaries. It produces a boolean **Mask** array that is *false* where the input array is less than the computed threshold and *true* otherwise. -![\f[ T = \sum_{i = 1}^{n} \frac{a_{i} g_{i}}{g_{i}} \f]](Images/latex24.png) +The threshold is computed as a gradient-magnitude-weighted average of the input array. Each value of the input array is weighted by its corresponding gradient magnitude, so **Cells** that sit on strong boundaries (high gradient magnitude) contribute most to the chosen threshold, while flat interior regions (low gradient magnitude) contribute little. The result is a single threshold value `T` that generally partitions the input array where its gradient is highest. -where \f$ a \f$ is the input array, \f$ g \f$ is the gradient magnitude array, \f$ n \f$ is the length of the input array, and \f$ T \f$ is the computed threshold value. Computing a threshold in this manner will generally partition the input array where its gradient is highest. Gradients may be computed using the Find Derivatives **Filter**. The gradient magnitude may then be found by computing the 2-norm of the gradient. +The *gradient magnitude* measures how quickly the input field changes from one location to the next: it is large at edges or boundaries and near zero in smooth regions. It is obtained by computing the *2-norm* (the square root of the sum of the squares of the per-axis derivative components) of the gradient vector at each **Cell**, which collapses the multi-component gradient into a single non-negative scalar value per **Cell**. The required gradient magnitude array can be produced with the [ITK Gradient Magnitude Image Filter](../ITKImageProcessing/ITKGradientMagnitudeImageFilter.md). + +### Required Input Sources + +- **Gradient Magnitude Data** -- a single-component 32-bit float array giving the gradient magnitude of the input array, produced by [ITK Gradient Magnitude Image Filter](../ITKImageProcessing/ITKGradientMagnitudeImageFilter.md). % Auto generated parameter table will be inserted here diff --git a/src/Plugins/SimplnxCore/docs/RotateSampleRefFrameFilter.md b/src/Plugins/SimplnxCore/docs/RotateSampleRefFrameFilter.md index 1f2ab9d99e..6827f2c18d 100644 --- a/src/Plugins/SimplnxCore/docs/RotateSampleRefFrameFilter.md +++ b/src/Plugins/SimplnxCore/docs/RotateSampleRefFrameFilter.md @@ -6,18 +6,19 @@ Sampling (Rotating/Transforming) ## Description -**NOTE: As of July 2023, this filter is only verified to work with a rotation angle of 90 or 180 degrees, a rotation axis of (010) || (100) || (001) The origin must also be (0, 0, 0).** +This **Filter** rotates the *sample reference frame* -- the coordinate system axes of the sample -- around a user-defined axis by a user-defined angle. The cell data is relocated so that each **Cell** sits in the correct position under the new axes. -This **Filter** will rotate the *spatial reference frame* around a user defined axis, by a user defined angle. The **Filter** will modify the (X, Y, Z) positions of each **Cell** to correctly represent where the **Cell** sits in the newly defined reference frame. For example, if a user selected a *rotation angle* of 90o and a *rotation axis* of (001), then a **Cell** sitting at (10, 0, 0) would be transformed to (0, -10, 0), since the new *reference frame* would have x'=y and y'=-x. +This is a *reference frame* rotation, not a geometric rotation of the data. The physical microstructure stays where it was; only the coordinate system used to describe it changes. Use this filter when correcting a known sample-orientation mismatch between an instrument's output and DREAM3DNX's convention (e.g., the typical EDAX-to-DREAM3DNX 180-degree rotation around <010>). For a true geometric rotation of the data (rotate the microstructure to a new orientation), use [Apply Transformation to Geometry](ApplyTransformationToGeometryFilter.md) instead. -### Rotation Representation +### ⚠ Limited Verification -The *Rotation Representation* parameter selects how the rotation is specified: +**This filter is currently verified only for rotation angles of 90 or 180 degrees about axis-aligned axes (`<100>`, `<010>`, or `<001>`), with origin (0, 0, 0).** Off-axis or non-orthogonal rotations may produce incorrect results. If your workflow requires an arbitrary-angle rotation, use [Apply Transformation to Geometry](ApplyTransformationToGeometryFilter.md). + +### Example -- **Axis Angle [0]**: The rotation is defined by a unit axis vector (x, y, z) and an angle in degrees. This is the most common representation for single-axis rotations. -- **Rotation Matrix [1]**: The rotation is defined as a 3x3 rotation matrix entered directly by the user. +If you select a rotation angle of 90 degrees and a rotation axis of (001), a **Cell** sitting at (10, 0, 0) is mapped to (0, -10, 0). The new reference frame is defined by `x' = y` and `y' = -x`. -The equivalent rotation matrix for the above rotation would be the following: +The equivalent rotation matrix is: | | | | | - | - | - | @@ -25,16 +26,24 @@ The equivalent rotation matrix for the above rotation would be the following: | 1 | 0 | 0 | | 0 | 0 | 1 | -## Example +When importing EBSD data from EDAX, the typical correction is a rotation about the `<010>` (Y) axis. The example below shows the result. Note that the input origin (0, 0) microns becomes (-189, 0) microns after rotation. To reset the origin afterward, run [Set Origin & Spacing (Image Geom)](SetImageGeomOriginScalingFilter.md). -When importing EBSD data from EDAX typically the user will need to rotate the sample reference frame about the <010> (Y) axis. This results in the image comparison below. Note that in the original image the origin of the data is at (0, 0) microns but after rotation the origin now becomes (-189, 0) microns. If you need to reset the origin back to (0,0) then the filter "Set Origin & Spacing" can be run. +![Imported EBSD Data Rotated about the <010> axis](Images/RotateSampleRefFrame_1.png) -## Notes +### Rotation Representation -The transformation will most likely create an origin that is different from the input geometry's origin. If you wish to still keep the input geometry's origin -then there is an option to allow you to do that. By default, the option is OFF so that the origin generated from the transformation is used. +The *Rotation Representation* parameter selects how the rotation is specified: -![Imported EBSD Data Rotated about the <010> axis](Images/RotateSampleRefFrame_1.png) +- **Axis Angle [0]**: A unit axis vector (x, y, z) plus an angle in **degrees**. The most common form for single-axis rotations. +- **Rotation Matrix [1]**: A 3x3 rotation matrix entered directly. + +### Notes on the Output Origin + +The rotated geometry will most likely have an origin that differs from the input geometry's origin (see EDAX example above). If you wish to keep the input origin, enable the *Keep Input Geometry's Origin* option. By default, the option is OFF, so the transformation-derived origin is used. + +### Required Input Sources + +- **Image Geometry** -- the input image whose reference frame is being rotated. Typically produced by an EBSD reader such as [Read H5EBSD](../OrientationAnalysis/ReadH5EbsdFilter.md), [Read CTF Data](../OrientationAnalysis/ReadCtfDataFilter.md), or [Read ANG Data](../OrientationAnalysis/ReadAngDataFilter.md). % Auto generated parameter table will be inserted here diff --git a/src/Plugins/SimplnxCore/docs/ScalarSegmentFeaturesFilter.md b/src/Plugins/SimplnxCore/docs/ScalarSegmentFeaturesFilter.md index ab536a2667..ae88e5651d 100644 --- a/src/Plugins/SimplnxCore/docs/ScalarSegmentFeaturesFilter.md +++ b/src/Plugins/SimplnxCore/docs/ScalarSegmentFeaturesFilter.md @@ -6,19 +6,33 @@ Reconstruction (Segmentation) ## Description -This **Filter** segments the **Features** by grouping neighboring **Cells** that satisfy the *scalar tolerance*, i.e., have a scalar difference less than the value set by the user. The process by which the **Features** are identified is given below and is a standard *burn algorithm*. +This **Filter** groups neighboring **Cells** (voxels) that have similar scalar values into **Features** (connected regions). The output is a *FeatureIds* array that assigns every cell in the input **Image Geometry** to a numbered feature, so that downstream analyses can operate on features instead of individual cells. -1. Randomly select a **Cell**, add it to an empty list and set its *FeatureId* to the current **Feature** -2. Compare the **Cell** to each of its six (6) face-sharing neighbors (i.e., calculate the scalar difference with each neighbor) -3. Add each neighbor **Cell** that has a scalar difference below the user defined tolerance to the list created in 1) and set the *FeatureId* of the neighbor **Cell** to the current **Feature** -4. Remove the current **Cell** from the list and move to the next **Cell** and repeat 2. and 3.; continue until no **Cells** are left in the list -5. Increment the current **Feature** counter and repeat steps 1. through 4.; continue until no **Cells** remain unassigned in the dataset +Use this filter whenever your segmentation criterion is a single scalar value per cell -- for example, image quality, confidence index, a phase label, or a computed property. For orientation-based segmentation of EBSD data, see [Segment Features (Misorientation)](../OrientationAnalysis/EBSDSegmentFeaturesFilter.md) or [Segment Features (C-Axis Misalignment)](../OrientationAnalysis/CAxisSegmentFeaturesFilter.md). -The user has the option to *Use Mask Array*, which allows the user to set a boolean array for the **Cells** that remove **Cells** with a value of *false* from consideration in the above algorithm. This option is useful if the user has an array that either specifies the domain of the "sample" in the "image" or specifies if the orientation on the **Cell** is trusted/correct. +### What is Feature Segmentation? -After all the **Features** have been identified, an **Attribute Matrix** is created for the **Features** and each **Feature** is flagged as *Active* in a boolean array in the matrix. +Segmentation groups cells that "belong together" into discrete regions. Each region receives a unique positive integer *Feature Id*; cells that are excluded (for example, by a mask) are assigned Feature Id 0. After segmentation, a new **Feature Attribute Matrix** is created so that per-feature statistics (sizes, centroids, phases, etc.) can be computed and stored. -If the data is specified as **Periodic**, the segmentation will check if features wrap around geometry bounds in a tileable fashion. If any such features are detected, the filter will throw a warning that centroid data may be incorrect. +### How This Filter Works + +This filter uses a standard *burn algorithm* to grow each feature outward from a seed cell: + +1. Randomly pick an unassigned **Cell** and give it a new *Feature Id*. +2. Compare the cell's scalar value to each of its neighboring cells (see **Neighbor Scheme** below). +3. Any neighbor whose scalar value differs from the seed by less than the user-specified *Scalar Tolerance* is added to the current feature and gets the same *Feature Id*. +4. Repeat step 2-3 from each newly added cell, growing the feature outward until no more neighbors qualify. +5. Increment the feature counter and pick a new unassigned seed cell. Continue until every eligible cell has been assigned. + +### Tolerance and Units + +The *Scalar Tolerance* is in **the same units as the input scalar array**. There are no universal "good" values; the right tolerance depends entirely on what array you are segmenting: + +- For an integer phase map, a tolerance of 0 (or less than 1) groups only cells with exactly the same phase. +- For a floating-point image-quality array with values 0-1, tolerances around 0.05-0.1 are typical. +- For a raw grayscale image with values 0-255, tolerances of 5-20 are typical. + +Start conservative (smaller tolerance -> more, smaller features), inspect the result, and loosen the tolerance if features are being over-split. ### Neighbor Scheme @@ -27,11 +41,7 @@ The *Neighbor Scheme* parameter provides the following choices: - **Face Neighbors [0]**: Only the 6 face-sharing neighbors of a voxel are considered during segmentation. - **All Connected Neighbors [1]**: All 26 neighbors connected by a face, edge, or vertex are considered during segmentation. -## Note on Neighbor Scheme - -Historically DREAM.3D version 6.x has used *only* the 6 face neighbors of a voxel. This release introduces the option -of using all 26 neighboring voxels that are connected by a face, edge or vertex. The default for the filter -is to still use the 6 face neighbors ("Face Only") in order to stay consistent with the output from DREAM.3D version 6.x. +DREAM.3D version 6.x only used face neighbors. The default here is still *Face Only* for backward compatibility; switch to *All Connected* when diagonal connectivity should merge a feature that would otherwise be split. | Neighbor Scheme = "Face Only" | Neighbor Scheme = "All Connected" | |:--:|:--:| @@ -49,6 +59,19 @@ is to still use the 6 face neighbors ("Face Only") in order to stay consistent w |:--:|:--:| | ![Shared Edges & Points With Disconnected Region - "Face Only"](Images/SegmentFeatures/combination_face_only.png) | ![Shared Edges & Points With Disconnected Region - "All Connected"](Images/SegmentFeatures/combination_all_connected.png) | +### Mask Array + +If *Use Mask Array* is enabled, cells flagged *false* in the mask are excluded from segmentation and left with a Feature Id of 0. Masks are commonly used to restrict segmentation to valid sample regions -- for example, a quality threshold on an EBSD confidence index (see [Multi-Threshold Objects](MultiThresholdObjectsFilter.md)). + +### Periodic Option + +If the input data represents a **periodic** structure (i.e., features are allowed to wrap across opposite faces of the volume), enable *Is Periodic*. The filter will detect features that tile across the geometry bounds and emit a warning that centroid and other spatial statistics may be incorrect for those features. + +### Required Input Sources + +- **Input Scalar Array** -- any single-component cell-level scalar array suitable for thresholding. Common sources include image readers such as [ITK Import Image Stack](../ITKImageProcessing/ITKImportImageStackFilter.md), phase or quality arrays from EBSD readers such as [Read H5EBSD](../OrientationAnalysis/ReadH5EbsdFilter.md), or any computed per-cell scalar from an earlier filter in the pipeline. +- **Mask Array** (optional) -- a boolean array marking valid cells, typically produced by [Multi-Threshold Objects](MultiThresholdObjectsFilter.md). + % Auto generated parameter table will be inserted here ## Example Pipelines diff --git a/src/Plugins/SimplnxCore/docs/SetImageGeomOriginScalingFilter.md b/src/Plugins/SimplnxCore/docs/SetImageGeomOriginScalingFilter.md index d4ed868025..71d782d25b 100644 --- a/src/Plugins/SimplnxCore/docs/SetImageGeomOriginScalingFilter.md +++ b/src/Plugins/SimplnxCore/docs/SetImageGeomOriginScalingFilter.md @@ -6,13 +6,33 @@ Core (Spatial) ## Description -This **Filter** changes the origin and/or the spacing of an **Image Geometry**. For example, if the current origin is at (0, 0, 0) and the user would like the origin to be (10, 4, 8), then the user should enter the following input values: +This **Filter** updates the origin and/or spacing of an existing **Image Geometry**. The grid dimensions (number of cells per axis) are unchanged; only the physical placement and physical size of the cells are modified. Use this filter to: -+ X Origin: 10 -+ Y Origin: 4 -+ Z Origin: 8 +- Correct an incorrect origin after import (e.g., reset to (0, 0, 0) after a sample-frame rotation). +- Convert the geometry's spacing to a different physical unit (e.g., millimeters → microns). +- Recenter a geometry so the user-specified point lands at the volume's geometric center. -When setting the origin, the user may also enable the *Put Input Origin at the Center of Geometry* option, which adjusts the geometry so that the specified origin is placed at the geometric center rather than the corner. +### Origin + +The *Origin* parameter sets the new physical location of the bottom-left corner of the geometry. For example, to change the origin from (0, 0, 0) to (10, 4, 8): + +- X Origin: 10 +- Y Origin: 4 +- Z Origin: 8 + +Origin coordinates are in the geometry's physical units (microns, millimeters, etc.). + +### Spacing + +The *Spacing* parameter sets the new physical distance between grid planes along each axis. Spacing values must be positive and non-zero. Updating spacing rescales the entire physical extent of the geometry (since the number of cells is unchanged) but leaves cell data values untouched. + +### Put Input Origin at the Center of Geometry + +If *Put Input Origin at the Center of Geometry* is enabled, the user-supplied origin value is treated as the **geometric center** of the volume rather than the bottom-left corner. The filter computes the corresponding bottom-left origin so that the user-supplied point lands at the center. This is convenient for centering a geometry on a meaningful reference point (sample center, beam axis, etc.) without computing the corner offset by hand. + +### Required Input Sources + +- **Input Image Geometry** -- the geometry to modify in place. Typically produced by [Create Image Geometry](CreateImageGeometryFilter.md), [ITK Import Image Stack](../ITKImageProcessing/ITKImportImageStackFilter.md), or an EBSD reader. % Auto generated parameter table will be inserted here diff --git a/src/Plugins/SimplnxCore/docs/SharedFeatureFaceFilter.md b/src/Plugins/SimplnxCore/docs/SharedFeatureFaceFilter.md index 4f0c21a6ba..eb99998c96 100644 --- a/src/Plugins/SimplnxCore/docs/SharedFeatureFaceFilter.md +++ b/src/Plugins/SimplnxCore/docs/SharedFeatureFaceFilter.md @@ -4,21 +4,24 @@ Surface Meshing (Connectivity/Arrangement) +(Note: this filter's human name is *Compute Triangle Face Ids*, even though its source file is named `SharedFeatureFace`.) + ## Description -This **Filter** assigns a unique Id to each **Triangle** in a **Triangle Geometry** that represents the _unique boundary_ -on which that **Triangle** resides. For example, if there were only two **Features** that shared one boundary, -then the **Triangles** on that boundary would be labeled with a single unique Id. This procedure creates _unique groups_ -of **Triangles**, which themselves are a set of **Features**. Thus, this **Filter** also creates a **Feature Attribute -Matrix** for this new set of **Features**, and creates **Attribute Arrays** for their Ids and number of **Triangles**. This -process can be considered a **segmentation** where each unique id is the shared boundary between two features. +This filter assigns a unique Id to each **Triangle** in a **Triangle Geometry** (a surface mesh built from triangles) that identifies the *unique boundary* on which that triangle resides. A **Feature** is a region of material; the **Face Labels** of a triangle are the pair of **Feature** Ids on either side of it. All triangles sharing the same pair of **Face Labels** form one shared boundary and receive the same unique Id. + +For example, if only two **Features** shared a single boundary, every triangle on that boundary would be labeled with one unique Id. This procedure groups the triangles into unique boundaries, which are themselves treated as a new set of **Features** (one per shared boundary). + +The filter therefore also creates a **Feature Attribute Matrix** (a table holding one row of data per shared-boundary feature) and places two **Attribute Arrays** into it: -Because the algorithm is essentially segmenting the triangles based on the unique combination of face labels, the filter will -also generate a Feature level Attribute Matrix and place two additional _DataArrays_ into that feature attribute matrix -that store the following information: +1. The number of triangles in each unique boundary. +2. The pair of **Face Labels** values that made up each unique boundary. -1. The number of triangles in each unique boundary -2. The pair of Face Label values that made up the unique boundary. +This process can be viewed as a **segmentation** in which each unique Id is the shared boundary between two features. + +### Randomize Face IDs + +The *Randomize Face IDs* parameter shuffles the assigned boundary Id values. The grouping of triangles is unchanged; only the numeric Id labels are permuted. This is purely a visualization aid: with sequential Ids, neighboring boundaries can map to similar colors and blend together, whereas randomized Ids spread adjacent boundaries across the color map so they are easier to tell apart. The two figures below illustrate the difference. ### Generated Feature Boundaries _with_ Randomization @@ -28,13 +31,16 @@ that store the following information: ![Example Surface Mesh Coloring By Feature Face Id](Images/SharedFeaturFace_2.png) ---------------- +### Required Input Sources + +- **Triangle Geometry** -- a surface mesh, typically produced by a surface-meshing filter such as [Create Surface Mesh (Surface Nets)](SurfaceNetsFilter.md) or [Create Surface Mesh (QuickMesh)](QuickSurfaceMeshFilter.md). +- **Face Labels** -- the per-triangle pair of **Feature** Ids, produced alongside the mesh by the surface-meshing filter above. % Auto generated parameter table will be inserted here ## Example Pipelines -"(03) Small IN100 Mesh Statistics.d3dpipeline" ++ (03) Small IN100 Mesh Statistics ## License & Copyright diff --git a/src/Plugins/SimplnxCore/docs/SilhouetteFilter.md b/src/Plugins/SimplnxCore/docs/SilhouetteFilter.md index 43f31ca03f..09bd6a2d6b 100644 --- a/src/Plugins/SimplnxCore/docs/SilhouetteFilter.md +++ b/src/Plugins/SimplnxCore/docs/SilhouetteFilter.md @@ -6,13 +6,15 @@ DREAM3D Review (Clustering) ## Description -This **Filter** computes the silhouette for a clustered **Attribute Array**. The user must select both the original array that has been clustered and the array of cluster Ids. The silhouette represents a measure for the quality of a clustering. Specifically, the silhouette provides a measure for how strongly a given point belongs to its own cluster compared to all other clusters. The silhouette is computed as follows: +This **Filter** computes the silhouette for a clustered **Attribute Array**. The user must select both the original array that has been clustered and the array of cluster Ids. The silhouette is a dimensionless measure of the quality of a clustering. Specifically, the silhouette provides a measure of how strongly a given point belongs to its own cluster compared to all other clusters. The silhouette is computed as follows: -\f[ s_{i} = \frac{b_{i} - a_{i}}{\max\{a_{i},b_{i}\}} \f] +$$ s_{i} = \frac{b_{i} - a_{i}}{\max\{a_{i},b_{i}\}} $$ -where \f$ a \f$ is the average distance between point \f$ i \f$ and all other points in the cluster point \f$ i \f$ belongs to, \f$ b \f$ is the *next closest* average distance among all other clusters, and \f$ s \f$ is the silhouette value. Using this definition, \f$ s \f$ exists on the interval \f$ [-1, 1] \f$, where 1 indicates that the point strongly belongs to its current cluster and -1 indicates that the point does not belong well to its current cluster. The user may select from a variety of options to use as the distance metric. Additionally, the user may opt to use a mask array to ignore points in the silhouette; these points will contain a silhouette value of 0. +where $a$ is the average distance between point $i$ and all other points in the cluster point $i$ belongs to, $b$ is the *next closest* average distance among all other clusters, and $s$ is the silhouette value. Using this definition, $s$ exists on the interval $[-1, 1]$ (dimensionless), where 1 indicates that the point strongly belongs to its current cluster and -1 indicates that the point does not belong well to its current cluster. The user may select from a variety of options to use as the distance metric. Additionally, the user may opt to use a mask array to ignore points in the silhouette; these points will contain a silhouette value of 0. -The silhouette can be used to determine how well a particular clustering has performed, such as k means or k medoids. +The filter writes one float silhouette value per input point into the created silhouette array, located alongside the input array. Each value lies in the range $[-1, 1]$ (dimensionless). + +The silhouette can be used to determine how well a particular clustering has performed, such as a clustering produced by [Compute K Means](ComputeKMeansFilter.md) or [Compute K Medoids](ComputeKMedoidsFilter.md). ### Distance Metric @@ -25,13 +27,18 @@ The *Distance Metric* parameter controls how the distance between two points is - **Pearson [4]**: Correlation-based distance derived from the Pearson correlation coefficient. - **Squared Pearson [5]**: Square of the Pearson distance. +### Required Input Sources + +- **Cluster Ids** -- the per-point cluster label array, produced by [Compute K Means](ComputeKMeansFilter.md) or [Compute K Medoids](ComputeKMedoidsFilter.md). +- **Clustered Attribute Array** -- the original **Attribute Array** that was clustered (the same array passed to the clustering filter). + % Auto generated parameter table will be inserted here ## Example Pipelines ## License & Copyright -Please see the description file distributed with this plugin. +Please see the description file distributed with this **Plugin** ## DREAM3D-NX Help diff --git a/src/Plugins/SimplnxCore/docs/SliceTriangleGeometryFilter.md b/src/Plugins/SimplnxCore/docs/SliceTriangleGeometryFilter.md index 445a39d67a..36017f7b1b 100644 --- a/src/Plugins/SimplnxCore/docs/SliceTriangleGeometryFilter.md +++ b/src/Plugins/SimplnxCore/docs/SliceTriangleGeometryFilter.md @@ -6,7 +6,9 @@ Sampling (Geometry) ## Description -This **Filter** slices an input **Triangle Geometry**, producing an **Edge Geometry**. The user can control the range over which to slice (either the entire range of the geoemtry or a specified subregion), and the spacing bewteen slices. Currently this filter only supports slicing along the direction of the z axis. The total area and perimieter of each slice is also computed and stored as an attribute on each created slice. +This **Filter** slices an input **Triangle Geometry**, producing an **Edge Geometry**. The user can control the range over which to slice (either the entire range of the geometry or a specified subregion), and the spacing between slices. Currently this filter only supports slicing along the direction of the z axis. The total area and perimeter of each slice is also computed and stored as an attribute on each created slice. + +Both the *Slice Spacing* and the *User Defined Range* values are specified in the same physical units as the input **Triangle Geometry** coordinates (for example, microns if the mesh is in microns). The computed slice area and perimeter are likewise reported in those physical units (squared, for area). Additionally, if the input **Triangle Geometry** is labeled with an identifier array (such as different regions or features), the user may select this array and the resulting edges will inherit these identifiers. @@ -26,7 +28,11 @@ Example Surface Mesh being sliced with a 2.0 slice spacing. The *Slice Range* parameter controls which portion of the geometry is sliced: - **Full Range [0]**: Slices across the entire extent of the geometry along the slicing direction. -- **User Defined Range [1]**: Allows specifying custom start and end values for the slicing range, restricting slices to a subregion of the geometry. +- **User Defined Range [1]**: Allows specifying custom start and end values (in the geometry's physical units) for the slicing range, restricting slices to a subregion of the geometry. + +### Required Input Sources + +- **Triangle Geometry** -- an existing surface mesh. Typically produced by [Create Surface Mesh (QuickMesh)](QuickSurfaceMeshFilter.md), read from disk via [Read STL File](ReadStlFileFilter.md), or assembled from multiple files by [Combine STL Files](CombineStlFilesFilter.md). % Auto generated parameter table will be inserted here diff --git a/src/Plugins/SimplnxCore/docs/SplitDataArrayByComponentFilter.md b/src/Plugins/SimplnxCore/docs/SplitDataArrayByComponentFilter.md index 6afce43553..f558c0bb31 100644 --- a/src/Plugins/SimplnxCore/docs/SplitDataArrayByComponentFilter.md +++ b/src/Plugins/SimplnxCore/docs/SplitDataArrayByComponentFilter.md @@ -18,14 +18,18 @@ This **Filter** will produce three new scalar unsigned 8-bit arrays: The user must specify a postfix string to add to the newly created arrays. For example, if the original multicomponent **Attribute Array** is named "Foo" and the postfix is set to "Component", this **Filter** will produce three new arrays named "FooComponent0", "FooComponent1", and "FooComponent2". The numbering will always be present regardless of how the postfix is set. -There is an alternative option which allows the user to select a subset of components to extract instead of extracting all the components by entering the components to be extracted. The components should be specified starting with the first componet as 0. So if the original array has 3 components and the user wanted the first and second components, the unput to the component table should be 0 and 1 respectively. +An alternative *Select Components* option lets the user extract a subset of components rather than all of them. Components are **0-based** -- for a 3-component array, entering 0 and 1 extracts only the first two components. -This **Filter** is the opposite operation of the Combine Attribute Arrays **Filter**, and the generalized version of the Extract Component as Attribute Array **Filter**. +This **Filter** is the inverse of [Combine Attribute Arrays](CombineAttributeArraysFilter.md), and a generalized version of [Extract/Remove Components](ExtractComponentAsArrayFilter.md). **Looking to split by *tuples* instead?** See the *[Split Data Array (By Tuple)](SplitDataArrayByTupleFilter.md)* filter that separates a data array into several smaller data arrays based on the tuple layout. +### Required Input Sources + +- **Multi-Component Input Array** -- any multi-component **Attribute Array**. + % Auto generated parameter table will be inserted here ## Example Pipelines diff --git a/src/Plugins/SimplnxCore/docs/SplitDataArrayByTupleFilter.md b/src/Plugins/SimplnxCore/docs/SplitDataArrayByTupleFilter.md index bddb3f935b..d80710aedf 100644 --- a/src/Plugins/SimplnxCore/docs/SplitDataArrayByTupleFilter.md +++ b/src/Plugins/SimplnxCore/docs/SplitDataArrayByTupleFilter.md @@ -50,6 +50,14 @@ An optional flag allows you to delete the original input array after splitting. See the *[Split Data Array (By Component)](SplitDataArrayByComponentFilter.md)* filter that separates each component into its own scalar array. +### Tuple Counts + +The per-output *tuple counts* are integers. The sum of all requested output counts along the split dimension must equal the input's tuple count along that dimension. + +### Required Input Sources + +- **Input Data Array** -- the array to split. + % Auto generated parameter table will be inserted here ## Example Pipelines diff --git a/src/Plugins/SimplnxCore/docs/SurfaceNetsFilter.md b/src/Plugins/SimplnxCore/docs/SurfaceNetsFilter.md index 658ca935b9..2cdb6348b9 100644 --- a/src/Plugins/SimplnxCore/docs/SurfaceNetsFilter.md +++ b/src/Plugins/SimplnxCore/docs/SurfaceNetsFilter.md @@ -6,22 +6,25 @@ Surface Meshing (Generation) ## Description -This filter uses the algorithm from {1} to produce a triangle surface mesh. The code is directly based on the sample code from the paper but has been modified to -work with the simplnx library classes. This filter uses a different algorithm that aims to produce a mush that keeps sharp edges -while still producing a mesh superior to marching cubes or QuickMesh. +This filter generates a **Triangle Geometry** (a surface mesh) that wraps the boundaries between labeled regions in a volume. It uses the **Surface Nets** algorithm from {1}. The code is based directly on the sample code from that paper, modified to work with the simplnx library classes. + +Unlike **marching cubes** (a classic algorithm that builds an isosurface by placing triangles inside each cube of eight neighboring **Cells**), Surface Nets keeps sharp edges between materials while still producing a mesh that is generally smoother and higher quality than either marching cubes or the older [Create Surface Mesh (QuickMesh)](QuickSurfaceMeshFilter.md) approach. + +An **isosurface** is the surface that separates regions above a threshold from regions below it; for a labeled volume the "threshold" is simply the boundary between one **Feature** label and a different one. From the abstract of the paper: - We extend 3D SurfaceNets to generate surfaces of segmented 3D medical images composed - of multiple materials represented as indexed labels. Our extension generates smooth, high- - quality triangle meshes suitable for rendering and tetrahedralization, preserves topology and - sharp boundaries between materials, guarantees a user-specified accuracy, and is fast enough - that users can interactively explore the trade-off between accuracy and surface smoothness. +> We extend 3D SurfaceNets to generate surfaces of segmented 3D medical images composed +> of multiple materials represented as indexed labels. Our extension generates smooth, high- +> quality triangle meshes suitable for rendering and tetrahedralization, preserves topology and +> sharp boundaries between materials, guarantees a user-specified accuracy, and is fast enough +> that users can interactively explore the trade-off between accuracy and surface smoothness. + +The filter writes a **Face Labels** array on each triangle: a 2-component value holding the **Feature** Id on either side of the triangle. The filter guarantees the smaller of the two Face Labels values is always stored in the first component (component 0), so that assumptions made in downstream filters continue to work correctly. -This filter will ensure that the smallest of the 2 **FaceLabel** values will always be in the first component (component[0]). This will allow assumptions made in -downstream filters to continue to work correctly. +The filter also attempts to repair the triangle **winding** (the order in which a triangle's three vertices are listed, which determines the direction its normal points). A fully consistent winding may not be achievable because of how meshes are stored in the software; see [Verify Triangle Winding](VerifyTriangleWindingFilter.md) for a detailed breakdown of the nuances. -This filter attempts to repair the windings for a mesh. This may not be possible due to the nature of how meshes are stored in the software. See Verify Traingle Winding documentation for detailed breakdown of nuance. +The *Relaxation Iterations* parameter is a dimensionless count of smoothing passes, and *Max Distance from Voxel Center* is a physical length (same units as the Image Geometry spacing) limiting how far a node may move from its originating voxel center. --------------- @@ -39,12 +42,11 @@ SurfaceNets output **with** the built-in smoothing operation applied. ## Node Types -During the meshing process, each vertex, or node, will get a "Node Type" value assigned to it. These will range from 0 to 6. The value is an internal representation from the SurfaceNets algorithm. They are roughly equivelent to the Node Types from the Quick Surface Mesh algorithm but not strictly the same. - -- Node Type = 0: This is a node that ONLY has 2 features connected to the node. -- Node Type = 2: This is a node that has 3 features connected to the node, such as a triple line -- Node Type = 3-6: These nodes have 4 or more features connected to the node. +During the meshing process, each vertex (node) is assigned a "Node Type" value ranging from 0 to 6. The value is an internal representation from the Surface Nets algorithm. The values are roughly equivalent to the Node Types from the [Create Surface Mesh (QuickMesh)](QuickSurfaceMeshFilter.md) algorithm but are not strictly the same. +- Node Type = 0: A node that has ONLY 2 features connected to it. +- Node Type = 2: A node that has 3 features connected to it, such as a **triple line** (the edge where exactly three features meet). +- Node Type = 3-6: Nodes that have 4 or more features connected to them. | Node Type | Example Image | |-----------|----------------------------------------------| @@ -56,38 +58,39 @@ During the meshing process, each vertex, or node, will get a "Node Type" value a ### Exterior or Boundary Nodes -Nodes that appear on the exterior of a volume have Node Type values starting at 10 and going up from there. For instance, a triple line that is also on the exterior of the volume should have a value of 12. +Nodes that appear on the exterior of a volume have Node Type values starting at 10 and going up from there. For instance, a triple line that is also on the exterior of the volume has a value of 12. ![Exterior Node Types](Images/SurfaceNets_NodeType_Exterior.png) ### Exterior or Boundary Triangles -Each triangle that is created will have an 2 component attribute called `Face Labels` that represent the Feature ID on either -side of the triangle. If one of the triangles represents the border of the virtual box then one of the FaceLables will -have a value of -1. +Each triangle has a 2-component **Face Labels** array that holds the Feature Id on either side of the triangle. If a triangle lies on the border of the virtual bounding box, one of its Face Labels values is -1. ## Notes -This filter should be used in place of the "QuickMesh Surface Filter". +This filter should be used in place of the [Create Surface Mesh (QuickMesh)](QuickSurfaceMeshFilter.md) filter. + +### Required Input Sources +- **Image Geometry** -- the labeled volume to mesh, from an image/volume reader or an upstream processing filter. +- **Cell Feature Ids** -- the per-Cell integer label array that defines the regions to wrap, typically produced by a segmentation filter such as [Segment Features (Scalar)](ScalarSegmentFeaturesFilter.md). % Auto generated parameter table will be inserted here ## Example Pipelines - Pipelines/SimplnxCore/SurfaceNets_Demo.d3dpipeline +Pipelines/SimplnxCore/SurfaceNets_Demo.d3dpipeline ## Citations -{1}[SurfaceNets for Multi-Label Segmentations with Preservation of Sharp Boundaries](https://jcgt.org/published/0011/01/03/paper.pdf) +{1} [SurfaceNets for Multi-Label Segmentations with Preservation of Sharp Boundaries](https://jcgt.org/published/0011/01/03/paper.pdf) + +Sarah F. Frisken, *SurfaceNets for Multi-Label Segmentations with Preservation of Sharp Boundaries*, Journal of Computer Graphics Techniques (JCGT), vol. 11, no. 1, 34-54, 2022. [http://jcgt.org/published/0011/01/03](http://jcgt.org/published/0011/01/03) ## License & Copyright -`Sarah F. Frisken, SurfaceNets for Multi-Label Segmentations with Preservation of Sharp -Boundaries, Journal of Computer Graphics Techniques (JCGT), vol. 11, no. 1, 34–54, 2022` -[http://jcgt.org/published/0011/01/03](http://jcgt.org/published/0011/01/03) +Please see the description file distributed with this **Plugin** -## DREAM3D-NX Mailing Lists +## DREAM3D-NX Help -If you need more help with a **Filter**, please consider asking your question on -the [DREAM3D-NX Users Google group!](https://groups.google.com/forum/?hl=en#!forum/dream3d-users) +If you need help, need to file a bug report or want to request a new feature, please head over to the [DREAM3DNX-Issues](https://github.com/BlueQuartzSoftware/DREAM3DNX-Issues/discussions) GitHub site where the community of DREAM3D-NX users can help answer your questions. diff --git a/src/Plugins/SimplnxCore/docs/TriangleCentroidFilter.md b/src/Plugins/SimplnxCore/docs/TriangleCentroidFilter.md index 545dcfb1f6..0e2fb65c15 100644 --- a/src/Plugins/SimplnxCore/docs/TriangleCentroidFilter.md +++ b/src/Plugins/SimplnxCore/docs/TriangleCentroidFilter.md @@ -6,7 +6,21 @@ Surface Meshing (Misc) ## Description -This **Filter** computes the centroid of each **Triangle** in a **Triangle Geometry** by calculating the average position of all 3 **Vertices** that make up the **Triangle**. +This filter computes the centroid of each **Triangle** in a **Triangle Geometry** (a surface mesh built from triangles) by averaging the positions of the 3 **vertices** (nodes) that make up the triangle, and stores the result as a per-triangle **Face Data** array. + +### When to Use This Filter + +A per-triangle centroid gives a single representative point for each triangle. It is commonly used as a position reference when fitting a local neighborhood of triangles (for example, by [Compute Feature Face Curvature](FeatureFaceCurvatureFilter.md)) and when visualizing or sampling per-face quantities at a point rather than across the whole triangle. + +Note: this filter produces one centroid **per triangle**. To instead compute one centroid **per Feature** (averaged over all the nodes that bound a feature), use [Compute Feature Centroids from Triangle Geometry](ComputeTriangleGeomCentroidsFilter.md). + +### Units + +Centroid coordinates are reported in the **geometry length units** of the **Triangle Geometry** vertices (for example, micrometers if the mesh coordinates are stored in micrometers). + +### Required Input Sources + +- **Triangle Geometry** -- a surface mesh, typically produced by a surface-meshing filter such as [Create Surface Mesh (Surface Nets)](SurfaceNetsFilter.md) or [Create Surface Mesh (QuickMesh)](QuickSurfaceMeshFilter.md). % Auto generated parameter table will be inserted here diff --git a/src/Plugins/SimplnxCore/docs/TriangleDihedralAngleFilter.md b/src/Plugins/SimplnxCore/docs/TriangleDihedralAngleFilter.md index ea6e6ac6a9..5922f99334 100644 --- a/src/Plugins/SimplnxCore/docs/TriangleDihedralAngleFilter.md +++ b/src/Plugins/SimplnxCore/docs/TriangleDihedralAngleFilter.md @@ -6,7 +6,24 @@ Surface Meshing (Misc) ## Description -This **Filter** computes the minimum dihedral angle of each **Triangle** in a **Triangle Geometry** by utilizing matrix mathematics +This filter computes, for every **Triangle** in a **Triangle Geometry**, the smallest of its three interior corner angles, and stores that value as a per-triangle **Face Data** array. + +### What This Measures and Why + +Each triangle has three interior angles. This filter records the **minimum** of those three angles. (For a single flat triangle this minimum interior angle is what is referred to here as the "dihedral angle".) It is a standard **mesh-quality** metric: + +- A well-shaped, near-equilateral triangle has a minimum angle close to 60°. +- A long, thin "sliver" triangle has a very small minimum angle (close to 0°). Slivers are numerically poorly conditioned and degrade downstream calculations (curvature, smoothing, finite-element meshing). + +Coloring a surface mesh by this value is a quick way to locate sliver triangles that may need remeshing or smoothing. + +### Units + +The output angle is reported in **degrees** (0° to 60°; a value of 60° corresponds to a perfectly equilateral triangle). + +### Required Input Sources + +- **Triangle Geometry** -- a surface mesh, typically produced by a surface-meshing filter such as [Surface Nets](SurfaceNetsFilter.md) or [Quick Surface Mesh](QuickSurfaceMeshFilter.md). % Auto generated parameter table will be inserted here diff --git a/src/Plugins/SimplnxCore/docs/TriangleNormalFilter.md b/src/Plugins/SimplnxCore/docs/TriangleNormalFilter.md index c2a4f5ac9c..d722e1478d 100644 --- a/src/Plugins/SimplnxCore/docs/TriangleNormalFilter.md +++ b/src/Plugins/SimplnxCore/docs/TriangleNormalFilter.md @@ -6,14 +6,30 @@ Surface Meshing (Misc) ## Description -This **Filter** computes the normal of each **Triangle** in a **Triangle Geometry** by utilizing matrix subtraction, cross product, and normalization to implement the following theory: - For a triangle with point1, point2, point3, if the vector U = point2 - point1 and the vector V = point3 - point1 +This filter computes the **normal** of each **Triangle** in a **Triangle Geometry** (a surface mesh built from triangles) and stores the result as a per-triangle **Face Data** array. A normal is the direction that points straight out of the flat triangle surface. - Nx = UyVz - UzVy - Ny = UzVx - UxVz - Nz = UxVy - UyVx +### How It Is Computed - Where "point#" represents a 3x1 Matrix of coordinates x, y, and z belonging to one of a Triangles vertexes and N represents the normal of the corresponding axis value +For a triangle with corner **vertices** *point1*, *point2*, and *point3*, the filter forms two edge vectors + + U = point2 - point1 + V = point3 - point1 + +and computes their **cross product** (a vector perpendicular to both edges, and therefore perpendicular to the triangle): + + Nx = Uy*Vz - Uz*Vy + Ny = Uz*Vx - Ux*Vz + Nz = Ux*Vy - Uy*Vx + +The result is then normalized to unit length. + +### Output and Direction + +The output is a 3-component **unit vector** (length 1) and is therefore **dimensionless**. Its sense (which of the two opposite directions it points along) is set by the **winding order** -- the order in which the triangle's three vertices are listed. Reversing the vertex order flips the normal to point the opposite way. Consistent winding across the mesh is what makes all normals point consistently inward or outward. + +### Required Input Sources + +- **Triangle Geometry** -- a surface mesh, typically produced by a surface-meshing filter such as [Create Surface Mesh (Surface Nets)](SurfaceNetsFilter.md) or [Create Surface Mesh (QuickMesh)](QuickSurfaceMeshFilter.md). % Auto generated parameter table will be inserted here diff --git a/src/Plugins/SimplnxCore/docs/UncertainRegularGridSampleSurfaceMeshFilter.md b/src/Plugins/SimplnxCore/docs/UncertainRegularGridSampleSurfaceMeshFilter.md index ddaf37c656..38091602b9 100644 --- a/src/Plugins/SimplnxCore/docs/UncertainRegularGridSampleSurfaceMeshFilter.md +++ b/src/Plugins/SimplnxCore/docs/UncertainRegularGridSampleSurfaceMeshFilter.md @@ -6,15 +6,24 @@ Sampling (Resolution) ## Description -This **Filter** "samples" a triangulated surface mesh on a rectilinear grid, but with "uncertainty" in the absolute position of the **Cells**. The "uncertainty" is meant to simulate the possible positioning error in a sampling probe. The user can specify the number of **Cells** along the X, Y, and Z directions in addition to the resolution in each direction and origin to define a rectilinear grid. The sampling, with "uncertainty", is then performed by the following steps: +This **Filter** "samples" a triangulated surface mesh onto a **rectilinear grid** (a regular grid of box-shaped **Cells**), but with "uncertainty" in the absolute position of each Cell. The uncertainty simulates the possible positioning error of a sampling probe. A **Cell** is a single volume element of the output grid, and a **Feature** is one labeled region of the surface mesh. -1. Determine the bounding box and **Triangle** list of each **Feature** by scanning all **Triangles** and noting the **Features** on either side of the **Triangle** -2. For each **Cell** in the rectilinear grid, perturb the location of the **Cell** by generating a three random numbers between [-1, 1] and multiplying them by the three uncertainty values (one for each direction) -3. For each perturbed **Cell** in the rectilinear grid, determine which bounding box(es) they fall in (*Note:* the bounding box of multiple **Features** can overlap) -4. For each bounding box a **Cell** falls in, check against that **Feature's** **Triangle** list to determine if the **Cell** falls within that n-sided polyhedra. (*Note:* if the surface mesh is conformal, then each **Cell** will only belong to one **Feature**, but if not, the last **Feature** the **Cell** is found to fall inside of will *own* the **Cell**) -5. Assign the **Feature** number that the **Cell** falls within to the *Feature Ids* array in the new rectilinear grid geometry +The user specifies the number of **Cells** along the X, Y, and Z directions, plus the resolution (spacing) and origin that define the grid. The grid resolution and origin are given in the same physical length units as the input surface mesh (typically microns). The three uncertainty values are also physical lengths in those same units. The sampling, with uncertainty, is performed by the following steps: -**Note that the unperturbed grid is where the *Feature Ids* actually live, but the perturbed locations are where the Cells are sampled from. Essentially, the *Feature Ids* are stored where the user *thinks* the sampling took place, not where it actually took place!** +1. Determine the bounding box and **Triangle** list of each **Feature** by scanning all **Triangles** and noting the **Features** on either side of each **Triangle**. +2. For each **Cell** in the rectilinear grid, perturb its location by generating three random numbers in the range [-1, 1] and multiplying them by the three uncertainty values (one for each direction). +3. For each perturbed **Cell**, determine which bounding box(es) it falls in (*Note:* the bounding boxes of multiple **Features** can overlap). +4. For each bounding box a **Cell** falls in, test it against that **Feature's** **Triangle** list to determine whether the **Cell** lies within that n-sided polyhedron. (*Note:* if the surface mesh is **conformal** -- meaning adjacent features share exactly one common surface with no gaps or overlaps -- each **Cell** belongs to only one **Feature**; if not, the last **Feature** the **Cell** is found inside of *owns* the **Cell**.) +5. Assign the **Feature** number that the **Cell** falls within to the *Feature Ids* array in the new rectilinear grid geometry. + +**Note that the unperturbed grid is where the *Feature Ids* actually live, but the perturbed locations are where the Cells are sampled from. Essentially, the *Feature Ids* are stored where the user *thinks* the sampling took place, not where it actually took place.** + +For the variant that samples onto a regular grid without positional uncertainty, see the sibling filter [Sample Triangle Geometry on Regular Grid](RegularGridSampleSurfaceMeshFilter.md), which shares the same grid (dimensions, origin, spacing) parameters. + +### Required Input Sources + +- **Triangle Geometry** -- the surface mesh to sample, typically produced by a surface-meshing filter such as [Create Surface Mesh (Surface Nets)](SurfaceNetsFilter.md) or [Create Surface Mesh (QuickMesh)](QuickSurfaceMeshFilter.md). +- **Face Labels** -- the per-face 2-component array identifying the **Features** on either side of each triangle, produced by the same surface-meshing filter. % Auto generated parameter table will be inserted here diff --git a/src/Plugins/SimplnxCore/docs/VerifyTriangleWindingFilter.md b/src/Plugins/SimplnxCore/docs/VerifyTriangleWindingFilter.md index d0a5c95f23..b19ee9fb86 100644 --- a/src/Plugins/SimplnxCore/docs/VerifyTriangleWindingFilter.md +++ b/src/Plugins/SimplnxCore/docs/VerifyTriangleWindingFilter.md @@ -2,35 +2,35 @@ ## Group (Subgroup) -Meshing (Cleanup) +Surface Meshing (Connectivity/Arrangement) ## Description -***WARNING***: *If your mesh contains multiple disconnected objects in it, you should run **Label Triangle Geometry** beforehand, and convert the output (region ids) into face labels. Recommended procedure for such is described below in **Multi-Object Meshes**.* +***WARNING***: *If your mesh contains multiple disconnected objects, you should run [Label CAD Geometry](LabelTriangleGeometryFilter.md) beforehand and convert the output (region ids) into face labels. The recommended procedure is described below in **Multi-Object Meshes**.* -This filter attempts to repair the windings for a mesh. This may not be possible due to the nature of how meshes are stored in the software. +This filter attempts to repair the **winding** of a mesh so that it is consistent across the surface. The *winding* is the order in which a triangle's three vertices are listed; that order determines which way the triangle's normal points (the triangle's "front" versus "back" face). Consistent winding means every triangle of a closed surface has its normal pointing the same way relative to the enclosed volume. Achieving fully consistent winding may not be possible because of how meshes are stored in the software. ### Key Nuances -While this filter doesn't modify anything more than the *Shared Faces List*, it has wider downstream implications for the mesh so it is recommended that it is executed as close to the start of the pipeline as possible. This ensures you don't have to recalculate extensive amounts of face data. This is especially pertinent in **Multi-Object Meshes**, where there are prerequisites to be satisfied as well. +While this filter modifies nothing more than the *Shared Faces List*, it has wider downstream implications for the mesh, so it is recommended to run it as close to the start of the pipeline as possible. This avoids recalculating extensive amounts of face data later. This is especially important for **Multi-Object Meshes**, which have additional prerequisites. -The meshes treat both sides of each triangle as valid, the upside to this is that the amount of space needed to store meshes is reduced, but it means that giving every feature the proper winding is impossible. The order of execution is based on feature label numbering, so randomizing order may lead to more visual distinction. +The meshes treat both sides of each triangle as valid. The upside is that less space is needed to store meshes, but it means giving every feature the proper winding is impossible. The order of execution is based on feature label numbering, so randomizing that order may lead to more visual distinction. -This filter requires that vertices are unique, well formed meshes should not have an issue with this. The filter will check this at runtime, returning an error if duplicates are found. If this happens, run *Identify Duplicate Vertices* followed by *Remove flagged Vertices* prior to this. +This filter requires that vertices are unique; well-formed meshes should not have an issue with this. The filter checks this at runtime and returns an error if duplicates are found. If this happens, run [Identify Duplicate Vertices](IdentifyDuplicateVerticesFilter.md) followed by [Remove Flagged Vertices](RemoveFlaggedVerticesFilter.md) prior to this filter. -This filter offers recalculating triangle normals as an option, however it is just a convience option. It simply calls Calculate Triangle Normals at the end. +This filter offers recalculating triangle normals as an option; this is a convenience that simply calls [Compute Triangle Normals](TriangleNormalFilter.md) at the end. -Both *Surface Nets* and *Quick Mesh* (the only synthetic mesh generating currently) already utilize this algorithm at the end of their execution. Thus this filter will be redundant to run on meshes generated from the software's integrated algorithms. +Both [Create Surface Mesh (Surface Nets)](SurfaceNetsFilter.md) and [Create Surface Mesh (QuickMesh)](QuickSurfaceMeshFilter.md) (the only synthetic mesh generators currently available) already apply this algorithm at the end of their execution. This filter is therefore redundant when run on meshes generated by the software's integrated algorithms. -This filter detemines candidates for winding reversal feature by feature based on the volume of the feature. This means its possible you may input a mesh that contains a feature with negative volume (that is untounched during winding repair) that gets all of it's windings reversed as a result. However, to our knowledge there does not exist a case where the feature would not be "inside-out" prior to execution. Essentially, this filter will addtionally preform winding reversal for you if it contains invalid features. +This filter determines candidates for winding reversal feature by feature, based on the **volume** of each feature. A feature whose triangle windings are "inside-out" computes a **negative volume** (the signed volume comes out negative because the surface normals point inward instead of outward). It is possible to input a mesh containing a feature with negative volume that is left untouched during winding repair but then gets all of its windings reversed as a result. To our knowledge there is no case where such a feature would not already be "inside-out" prior to execution. Essentially, this filter will additionally perform winding reversal for you when the mesh contains invalid (inside-out) features. ### Multi-Object Meshes -If your mesh has more than one disconnected object in it, *Label Traingle Geometry* should be run beforehand. This can be confusing because the output of the filter is not a face labels array. To convert the output to face labels, you need to merge this array with another array of zeros (created with *Create Data Array*) using *Combine Attribute Arrays*. The order is not strictly enforced but the internal paradigm is to place the zeros array above the *region ids* array (Option A below). The difference n output is as follows: +If your mesh has more than one disconnected object, run [Label CAD Geometry](LabelTriangleGeometryFilter.md) beforehand. This can be confusing because the output of that filter is a region ids array, not a face labels array. To convert the output to face labels, merge that array with an array of zeros (created with [Create Data Array](CreateDataArrayFilter.md)) using [Combine Attribute Arrays](CombineAttributeArraysFilter.md). The order is not strictly enforced, but the internal convention is to place the zeros array above the *region ids* array (Option A below). The difference in output is as follows: **Option A**: -- Zero's array first +- Zeros array first - Region Ids array second ```console @@ -42,23 +42,28 @@ OR **Option B**: - Region Ids array first -- Zero's array second +- Zeros array second ```console {{1,0}, {1,0}, {1,0}, ...} ``` -The output of this combination will become your face labels for the mesh. +The output of this combination becomes the face labels for the mesh. -The relative pipeline for multiobject meshes should look something like this: +The pipeline for multi-object meshes should look something like this: -1. Identify Duplicate Vertices (optional) -2. Remove Flagged Vertices (optional) -3. Label CAD Geometry (LabelTriangleGeometry) -4. Create Data Array (fill with 0's) -5. Combine Attribute Arrays (make face labels [Zero Array + Region Ids]) +1. [Identify Duplicate Vertices](IdentifyDuplicateVerticesFilter.md) (optional) +2. [Remove Flagged Vertices](RemoveFlaggedVerticesFilter.md) (optional) +3. [Label CAD Geometry](LabelTriangleGeometryFilter.md) +4. [Create Data Array](CreateDataArrayFilter.md) (fill with 0's) +5. [Combine Attribute Arrays](CombineAttributeArraysFilter.md) (make face labels [Zeros Array + Region Ids]) 6. Verify Triangle Winding +### Required Input Sources + +- **Triangle Geometry** -- the surface mesh whose winding will be verified and repaired. +- **Face Labels (or Region Ids)** -- the per-face array identifying the **Features** on either side of each triangle, produced by a surface-meshing filter such as [Create Surface Mesh (Surface Nets)](SurfaceNetsFilter.md) or [Create Surface Mesh (QuickMesh)](QuickSurfaceMeshFilter.md), or assembled from region ids via [Label CAD Geometry](LabelTriangleGeometryFilter.md) as described above. + % Auto generated parameter table will be inserted here ## License & Copyright diff --git a/src/Plugins/SimplnxCore/docs/WriteASCIIDataFilter.md b/src/Plugins/SimplnxCore/docs/WriteASCIIDataFilter.md index f8a0aa968a..5a8fdcf1b0 100644 --- a/src/Plugins/SimplnxCore/docs/WriteASCIIDataFilter.md +++ b/src/Plugins/SimplnxCore/docs/WriteASCIIDataFilter.md @@ -2,15 +2,19 @@ ## Group (Subgroup) -IO (Output) (Write) (Export) (Text) (CSV) (ASCII) +IO (Output) ## Description -This filter will write the selected DataArrays to either individual files or as a single CSV style of file. +This filter will write the selected **Data Array**s to either individual files or as a single CSV style of file. The inputs are any existing **Data Array**s (numeric or string) that the user selects to export. + +### Maximum Tuples Per Line + +When writing to multiple files, the *Maximum Tuples Per Line* parameter controls how many tuples are printed on each row of an output file (units: tuples per row). For example, with a value of *1* each tuple is written on its own line; with a value of *10* up to ten tuples are written per line before a new line begins. This makes it possible to reshape long single-column output into a more compact block. The parameter does not apply to string arrays. ## String Data Array Caveats -- The "Maximum Tuples per Line" will not have any effect for that specific array. +- The "Maximum Tuples Per Line" will not have any effect for that specific array. - If the output is for a single file, then each String value will be enclosed in a set of Single Quotes (') characters. ### Multiple Files diff --git a/src/Plugins/SimplnxCore/docs/WriteAbaqusHexahedronFilter.md b/src/Plugins/SimplnxCore/docs/WriteAbaqusHexahedronFilter.md index 0ce78f3152..c5b467ea15 100644 --- a/src/Plugins/SimplnxCore/docs/WriteAbaqusHexahedronFilter.md +++ b/src/Plugins/SimplnxCore/docs/WriteAbaqusHexahedronFilter.md @@ -6,117 +6,98 @@ IO (Output) ## Description -***WARNING**: If you are not using this filter for stress - strain curves, be sure to disable `Write Dummy Node` or it may mess up mesh connectivity.* +This filter converts a voxel grid (an **Image Geometry**) into a hexahedral element mesh and writes it to a set of Abaqus input (`.inp`) files. **Abaqus** is a commercial *finite-element-analysis* (FEA) software package; FEA is a numerical technique that divides a body into many small, simple elements and solves for quantities such as stress and strain across them. By exporting the microstructure as an Abaqus mesh, the filter lets users run mechanical (stress/strain) simulations on a digital microstructure. -This **Filter** produces the basic five Abaqus .inp files for input into the Abaqus analysis tool. The files created are: xxx.inp (the master file), xxx_nodes.inp, xxx_elems.inp, xxx_elset.inp and xxx_sects.inp. This **Filter** is based on a Python script developed by Matthew W. Priddy (Ga. Tech., early 2015). +Each **Cell** (voxel) in the **Image Geometry** becomes one hexahedral (brick-shaped) element with 8 corner nodes. Nodes shared between neighboring voxels are written only once so the mesh is fully connected. The element type written is `C3D8`, Abaqus's standard 8-node linear brick element. Every element is assigned to an element set named after the **Feature** (grain) it belongs to, using the *Cell Feature Ids* array, so each grain can be given its own material in the simulation. + +### Output Files + +The filter writes five plain-text files. The first is a master file that pulls in the other four using Abaqus's `*Include` directive, so the simulation is launched from the master file alone: + +- `.inp` — the master file. It `*Include`s the four files below. +- `_nodes.inp` — the node coordinates. +- `_elems.inp` — the element connectivity (which 8 nodes make up each element). +- `_elset.inp` — the element sets (one set per grain). +- `_sects.inp` — the section definitions assigning a material to each grain set. + +Node coordinates are written in the physical units of the **Image Geometry** (for example microns, if the geometry's spacing is in microns). Each node coordinate is the voxel-grid position scaled by the geometry spacing and offset by its origin. + +### Write Dummy Node + +When the *Write Dummy Node* parameter is enabled, the filter appends one extra "dummy" node at the end of the `_nodes.inp` file. This node is not attached to any element; it exists only as a reference point that some Abaqus stress/strain workflows require (for example, to apply or read periodic boundary conditions). If the export is not being used for stress/strain curves, this parameter should be disabled, because the unused node can interfere with mesh connectivity tools that expect every node to belong to an element. + +### Hourglass Stiffness + +The `_sects.inp` file includes an `*Hourglass Stiffness` value for each grain section. "Hourglass" modes are spurious, zero-energy deformation patterns that reduced-integration brick elements can exhibit; a small artificial stiffness suppresses them. The *Hourglass Stiffness Value* parameter sets this number (default *250*, a dimensionless solver-control value). + +### Required Input Sources + +- **Image Geometry** -- the voxel grid to export. +- **Cell Feature Ids** -- produced by a segmentation filter such as [Segment Features (Scalar)](ScalarSegmentFeaturesFilter.md). One element set is written per Feature Id. ### Example Output +The headers in the snippets below read `DREAM3DLib Version 5.1.566`; these version strings are illustrative and will reflect the actual version that wrote the file. The filter is based on a Python script developed by Matthew W. Priddy (Georgia Tech, early 2015). + The master file: ```text - *Heading - Job 101 - ** Job name : Job 101 - ** Generated by : DREAM3DLib Version 5.1.566.e1e7b7f - *Preprint, echo = NO, model = NO, history = NO, contact = NO - ** - ** ----------------------------Geometry---------------------------- - ** - *Include, Input = 32x32x32_nodes.inp - *Include, Input = 32x32x32_elems.inp - *Include, Input = 32x32x32_elset.inp - *Include, Input = 32x32x32_sects.inp - ** - ** ---------------------------------------------------------------- - ** +*Heading +Job 101 +** Job name : Job 101 +** Generated by : DREAM3DLib Version 5.1.566 +*Preprint, echo = NO, model = NO, history = NO, contact = NO +** +** ----------------------------Geometry---------------------------- +** +*Include, Input = 32x32x32_nodes.inp +*Include, Input = 32x32x32_elems.inp +*Include, Input = 32x32x32_elset.inp +*Include, Input = 32x32x32_sects.inp ``` -The _nodes.inp file: +The `_nodes.inp` file (node ID followed by x, y, z in geometry units): ```text - ** Generated by : DREAM3DLib Version 5.1.566.e1e7b7f - ** ---------------------------------------------------------------- - ** - *Node - 1, 0.000000, 0.000000, 0.000000 - 2, 0.500000, 0.000000, 0.000000 - 3, 1.000000, 0.000000, 0.000000 - 4, 1.500000, 0.000000, 0.000000 - .. +*Node +1, 0.000000, 0.000000, 0.000000 +2, 0.500000, 0.000000, 0.000000 +3, 1.000000, 0.000000, 0.000000 + .. ``` -The _elset.inp file: +The `_elems.inp` file (element ID followed by its 8 node IDs): ```text - ** Generated by : DREAM3DLib Version 5.1.566.e1e7b7f - ** ---------------------------------------------------------------- - ** - ** The element sets - *Elset, elset=cube, generate - 1, 32768, 1 - ** - ** Each Grain is made up of multiple elements - ** - *Elset, elset=Grain1_set - 24126, 24127, 24128, 24159, 24160, 24191, 24192, 25085, 25086, 25087, 25117, 25118, 25119, 25120, 25149, 25150, - 25151, 25152, 25181, 25182, 25183, 25184, 25214, 25215, 25216, 25247, 25248, 26077, 26078, 26079, 26080, 26108, - 26109, 26110, 26111, 26112, 26140, 26141, 26142, 26143, 26144, 26172, 26173, 26174, 26175, 26176, 26204, 26205, - 26206, 26207, 26208, 26237, 26238, 26239, 26240, 26270, 26271, 26272, 26303, 26304, 27069, 27070, 27071, 27072, - 27100, 27101, 27102, 27103, 27104, 27131, 27132, 27133, 27134, 27135, 27136, 27163, 27164, 27165, 27166, 27167, - 27168, 27195, 27196, 27197, 27198, 27199, 27200, 27228, 27229, 27230, 27231, 27232, 27260, 27261, 27262, 27263, - 27264, 27294, 27295, 27296, 27326, 27327, 27328, 27359, 27360, 28093, 28094, 28095, 28096, 28123, 28124, 28125, - 28126, 28127, 28128, 28155, 28156, 28157, 28158, 28159, 28160, 28187, 28188, 28189, 28190, 28191, 28192, 28219, - 28220, 28221, 28222, 28223, 28224, 28252, 28253, 28254, 28255, 28256, 28284, 28285, 28286, 28287, 28288, 28317, - 28318, 28319, 28320, 28350, 28351, 28352, 28383, 28384, 28416, 29116, 29117, 29118, 29119, 29120, 29147, 29148, - 29149, 29150, 29151, 29152, 29179, 29180, 29181, 29182, 29183, 29184, 29211, 29212, 29213, 29214, 29215, 29216, - 29243, 29244, 29245, 29246, 29247, 29248, 29276, 29277, 29278, 29279, 29280, 29308, 29309, 29310, 29311, 29312, - 29341, 29342, 29343, 29344, 29374, 29375, 29376, 29407, 29408, 29440, 30140, 30141, 30142, 30143, 30144, 30171, - 30172, 30173, 30174, 30175, 30176, 30203, 30204, 30205, 30206, 30207, 30208, 30235, 30236, 30237, 30238, 30239, - 30240, 30267, 30268, 30269, 30270, 30271, 30272, 30300, 30301, 30302, 30303, 30304, 30332, 30333, 30334, 30335, - 30336, 30365, 30366, 30367, 30368, 30398, 30399, 30400, 30431, 30432, 31164, 31165, 31166, 31167, 31168, 31195, - 31196, 31197, 31198, 31199, 31200, 31227, 31228, 31229, 31230, 31231, 31232, 31259, 31260, 31261, 31262, 31263, - 31264, 31292, 31293, 31294, 31295, 31296, 31324, 31325, 31326, 31327, 31328, 31357, 31358, 31359, 31360, 31389, - 31390, 31391, 31392, 31422, 31423, 31424, 31455, 31456, 32188, 32189, 32190, 32191, 32192, 32220, 32221, 32222, - 32223, 32224, 32251, 32252, 32253, 32254, 32255, 32256, 32284, 32285, 32286, 32287, 32288, 32316, 32317, 32318, - 32319, 32320, 32348, 32349, 32350, 32351, 32352, 32381, 32382, 32383, 32384, 32413, 32414, 32415, 32416, 32447, - 32448 - *Elset, elset=Grain2_set - .. +*Element, type=C3D8 +1, 1091, 2, 1, 1090, 1124, 35, 34, 1123 +2, 1092, 3, 2, 1091, 1125, 36, 35, 1124 + .. ``` -The _elems.inp file: +The `_elset.inp` file (a "cube" set spanning all elements, then one set per grain — the full grain sets contain many element IDs and are abbreviated here): ```text - ** Generated by : DREAM3DLib Version 5.1.566.e1e7b7f - ** ---------------------------------------------------------------- - ** - *Element, type=C3D8 - 1, 1091, 2, 1, 1090, 1124, 35, 34, 1123 - 2, 1092, 3, 2, 1091, 1125, 36, 35, 1124 - 3, 1093, 4, 3, 1092, 1126, 37, 36, 1125 - 4, 1094, 5, 4, 1093, 1127, 38, 37, 1126 - 5, 1095, 6, 5, 1094, 1128, 39, 38, 1127 - 6, 1096, 7, 6, 1095, 1129, 40, 39, 1128 - .. +** The element sets +*Elset, elset=cube, generate +1, 32768, 1 +** +*Elset, elset=Grain1_set +24126, 24127, 24128, 24159, 24160, 24191, 24192, 25085, 25086, .. +*Elset, elset=Grain2_set + .. ``` -The _sects.inp file: +The `_sects.inp` file (one section per grain, each with its hourglass stiffness): ```text - ** Generated by : DREAM3DLib Version 5.1.566.e1e7b7f - ** ---------------------------------------------------------------- - ** - ** Each section is a separate grain - ** Section: Grain1 - *Solid Section, elset=Grain1_set, material=Grain_Mat1 - *Hourglass Stiffness - 250 - ** -------------------------------------- - ** Section: Grain2 - *Solid Section, elset=Grain2_set, material=Grain_Mat2 - - .. +** Section: Grain1 +*Solid Section, elset=Grain1_set, material=Grain_Mat1 +*Hourglass Stiffness +250 +** Section: Grain2 +*Solid Section, elset=Grain2_set, material=Grain_Mat2 + .. ``` % Auto generated parameter table will be inserted here diff --git a/src/Plugins/SimplnxCore/docs/WriteAvizoRectilinearCoordinateFilter.md b/src/Plugins/SimplnxCore/docs/WriteAvizoRectilinearCoordinateFilter.md index 1280f50da4..8590261f7b 100644 --- a/src/Plugins/SimplnxCore/docs/WriteAvizoRectilinearCoordinateFilter.md +++ b/src/Plugins/SimplnxCore/docs/WriteAvizoRectilinearCoordinateFilter.md @@ -6,9 +6,17 @@ IO (Output) ## Description -This filter writes out a native Avizo Rectilinear Coordinate data file. Values should be present from segmentation of experimental data or synthetic generation and cannot be determined by this filter. Not having these values will result in the filter to fail/not execute. +This filter writes an **Image Geometry** and its **Cell** *FeatureIds* array to a file that can be read by **Avizo**. Avizo is a commercial 3D visualization and analysis package. Its native data format is **AmiraMesh**, a header-plus-data file (commonly given an `.am` extension). -### Example Output +The filter requires two inputs: an **Image Geometry**, and an Int32 *FeatureIds* **Cell** **Data Array** that labels which **Feature** (for example, which grain) each cell belongs to. The *FeatureIds* values are produced earlier in the pipeline by a segmentation filter such as [Segment Features (Scalar)](ScalarSegmentFeaturesFilter.md); this filter does not compute them. If no valid *FeatureIds* array is supplied, the filter will not execute. + +The data is written in the **rectilinear-coordinate** form: the file stores explicit per-axis coordinate arrays (the X, Y, and Z positions of the grid lines). This is the counterpart to the [Write Avizo Uniform Coordinate](WriteAvizoUniformCoordinateFilter.md) filter, which instead records a single uniform spacing and bounding box. Use the rectilinear variant when the per-axis coordinate values must be written out explicitly. + +The *Write Binary File* parameter selects the on-disk encoding: *false* (the default) writes the data section as ASCII text, while *true* writes it in little-endian binary, producing smaller files. + +**Units caveat:** the AmiraMesh header always records the coordinate units as `microns`, regardless of the actual units stored on the input **Image Geometry**. If the geometry uses different units, adjust them in Avizo after import. + +### Example AmiraMesh Header # AmiraMesh BINARY-LITTLE-ENDIAN 2.1 # Dimensions in x-, y-, and z-direction @@ -17,18 +25,21 @@ This filter writes out a native Avizo Rectilinear Coordinate data file. Values s Parameters { DREAM3DParams { Author "DREAM3D", - DateTime " . M o n J u n 1 1 0 : 0 1 : 1 4 2 0 1 5 " + DateTime "Mon Jun 1 10:01:14 2015" } Units { - Coordinates "microns" + Coordinates "microns" } - CoordType "rectilinear" + CoordType "rectilinear" } - Lattice { int FeatureIds } = @1 Coordinates { float xyz } = @2 # Data section follows - .. + +### Required Input Sources + +- **Image Geometry** -- the geometry whose dimensions and coordinates are written. +- **Cell Feature Ids** -- an Int32 per-cell label array, produced by a segmentation filter such as [Segment Features (Scalar)](ScalarSegmentFeaturesFilter.md). % Auto generated parameter table will be inserted here diff --git a/src/Plugins/SimplnxCore/docs/WriteAvizoUniformCoordinateFilter.md b/src/Plugins/SimplnxCore/docs/WriteAvizoUniformCoordinateFilter.md index 42d9da60a1..1301d5a552 100644 --- a/src/Plugins/SimplnxCore/docs/WriteAvizoUniformCoordinateFilter.md +++ b/src/Plugins/SimplnxCore/docs/WriteAvizoUniformCoordinateFilter.md @@ -6,9 +6,17 @@ IO (Output) ## Description -This filter writes out a native Avizo Uniform Coordinate data file. Values should be present from segmentation of experimental data or synthetic generation and cannot be determined by this filter. Not having these values will result in the filter to fail/not execute. +This filter writes an **Image Geometry** and its **Cell** *FeatureIds* array to a file that can be read by **Avizo**. Avizo is a commercial 3D visualization and analysis package. Its native data format is **AmiraMesh**, a header-plus-data file (commonly given an `.am` extension). -### Example Output +The filter requires two inputs: an **Image Geometry**, and an Int32 *FeatureIds* **Cell** **Data Array** that labels which **Feature** (for example, which grain) each cell belongs to. The *FeatureIds* values are produced earlier in the pipeline by a segmentation filter such as [Segment Features (Scalar)](ScalarSegmentFeaturesFilter.md); this filter does not compute them. If no valid *FeatureIds* array is supplied, the filter will not execute. + +The data is written in the **uniform-coordinate** form: the file records a single uniform spacing together with the grid's bounding box (minimum and maximum X, Y, and Z), rather than listing per-axis coordinate values. This is the compact counterpart to the [Write Avizo Rectilinear Coordinate](WriteAvizoRectilinearCoordinateFilter.md) filter, which writes explicit per-axis coordinate arrays. Use the uniform variant when the grid has uniform spacing (the usual case for an **Image Geometry**). + +The *Write Binary File* parameter selects the on-disk encoding: *false* (the default) writes the data section as ASCII text, while *true* writes it in little-endian binary, producing smaller files. + +**Units caveat:** the AmiraMesh header always records the coordinate units as `microns`, regardless of the actual units stored on the input **Image Geometry**. If the geometry uses different units, adjust them in Avizo after import. + +### Example AmiraMesh Header # AmiraMesh BINARY-LITTLE-ENDIAN 2.1 # Dimensions in x-, y-, and z-direction @@ -17,19 +25,23 @@ This filter writes out a native Avizo Uniform Coordinate data file. Values shoul Parameters { DREAM3DParams { Author "DREAM3D", - DateTime + DateTime "Mon Jun 1 10:01:14 2015" } Units { - Coordinates "microns" + Coordinates "microns" } - Content " int, uniform coordinates", - # Bounding Box is xmin xmax ymin ymax zmin zmax - BoundingBox , - CoordType "uniform" + Content "int, uniform coordinates", + # Bounding Box is xmin xmax ymin ymax zmin zmax + BoundingBox 0 64 0 64 0 64, + CoordType "uniform" } Lattice { int FeatureIds } = @1 # Data section follows - .. + +### Required Input Sources + +- **Image Geometry** -- the geometry whose dimensions and bounding box are written. +- **Cell Feature Ids** -- an Int32 per-cell label array, produced by a segmentation filter such as [Segment Features (Scalar)](ScalarSegmentFeaturesFilter.md). % Auto generated parameter table will be inserted here diff --git a/src/Plugins/SimplnxCore/docs/WriteBinaryDataFilter.md b/src/Plugins/SimplnxCore/docs/WriteBinaryDataFilter.md index d422016ea4..574404f110 100644 --- a/src/Plugins/SimplnxCore/docs/WriteBinaryDataFilter.md +++ b/src/Plugins/SimplnxCore/docs/WriteBinaryDataFilter.md @@ -6,17 +6,37 @@ IO (Output) (Write) (Export) (Binary) ## Description -This **Filter** accepts DataArray(s) as input, extracts the data, and writes each array to a separate binary file in the specified output directory +This filter writes each selected **Data Array** to its own raw binary file in the chosen output directory. One file is written per selected array. + +### How It Works + +For each array, the filter writes the array's numeric values straight to disk as raw bytes. **No header is written** — the file contains only the array values with no metadata describing the data type, dimensions, byte order, or component layout. Because of this, the user must independently record the data type (for example *float32*, *int32*, *uint8*), the tuple and component dimensions, and the endianness chosen below. That information is required later to read the file back correctly. + +The values are written in the same order they are stored in memory: tuple by tuple, with the components of each tuple written together (interleaved). For example, a 3-component array is written as `t0c0, t0c1, t0c2, t1c0, t1c1, t1c2, ...`. + +### File Naming + +Each output file is named after the array it contains, followed by the value of the *File Extension* parameter, and is placed in the *Output Path* directory. For example, an array named `Confidence Index` written with the default extension `.bin` produces a file named `Confidence Index.bin` in the output directory. + +### Reading the Files Back + +These raw binary files can be read back into DREAM3D-NX with the [Read Raw Binary](ReadRawBinaryFilter.md) filter. Because no header was written, the user must supply the data type, dimensions, and endianness to that filter manually — they must match the values used when the file was written. ### Endianess The *Endianess* parameter controls the byte order used when writing numeric values to the binary file: -- **Little Endian [0]**: The least significant byte is stored first. This is the native byte order for x86 and ARM processors and is the most common choice for files consumed on modern desktop systems. -- **Big Endian [1]**: The most significant byte is stored first. This byte order is used by some network protocols and legacy systems. +- *Little Endian*: The least significant byte is stored first. This is the native byte order for x86 and ARM processors and is the most common choice for files consumed on modern desktop systems. +- *Big Endian*: The most significant byte is stored first. This byte order is used by some network protocols and legacy systems. + +## Required Input Sources + +The arrays to export are user-selected **Data Arrays** from anywhere in the **Data Structure**; there is no specific upstream producer filter required. % Auto generated parameter table will be inserted here +## Example Pipelines + ## License & Copyright Please see the description file distributed with this **Plugin** diff --git a/src/Plugins/SimplnxCore/docs/WriteDREAM3DFilter.md b/src/Plugins/SimplnxCore/docs/WriteDREAM3DFilter.md index 24e258f4d9..7ce5d70186 100644 --- a/src/Plugins/SimplnxCore/docs/WriteDREAM3DFilter.md +++ b/src/Plugins/SimplnxCore/docs/WriteDREAM3DFilter.md @@ -1,5 +1,9 @@ # Write DREAM3D-NX File +## Group (Subgroup) + +IO (Output) + ## Description This **Filter** writes the current `DataStructure` to disk as an HDF5 file with the `.dream3d` extension. The file contains every `DataArray`, geometry, attribute matrix, and group in the pipeline, along with the pipeline itself so the work can be re-run or inspected later. @@ -34,6 +38,10 @@ The `.xdmf` file does not contain a copy of the data — it is a metadata wrappe Enabling XDMF costs almost nothing (the file is small and fast to write) and is the recommended setting whenever visualization outside DREAM3D-NX is a possibility. It can safely be left off for intermediate pipeline outputs that will only be re-read by DREAM3D-NX itself. +### Required Input Sources + +None — this filter writes whatever currently exists in the **DataStructure** to the output file. If the file already exists it is overwritten. + % Auto generated parameter table will be inserted here ## Example Pipelines diff --git a/src/Plugins/SimplnxCore/docs/WriteFeatureDataCSVFilter.md b/src/Plugins/SimplnxCore/docs/WriteFeatureDataCSVFilter.md index a1ff8e7b8d..39c80d7ce1 100644 --- a/src/Plugins/SimplnxCore/docs/WriteFeatureDataCSVFilter.md +++ b/src/Plugins/SimplnxCore/docs/WriteFeatureDataCSVFilter.md @@ -6,10 +6,12 @@ IO (Output) ## Description -This **Filter** writes the data associated with each **Feature** to a file name specified by the user in *CSV* format. Every array in the **Feature** map is written as a column of data in the *CSV* file. The user can choose to also write the neighbor data. Neighbor data are data arrays that are associated with the neighbors of a **Feature**, such as: list of neighbors, list of misorientations, list of shared surface areas, etc. These blocks of info are written after the scalar data arrays. Since the number of neighbors is variable for each **Feature**, the data is written as follows (for each **Feature**): Id, number of neighbors, value1, value2,...valueN. +A **Feature** is a grouped region of the data, such as a grain. This **Filter** writes the data associated with each **Feature** to a file name specified by the user in *CSV* format. Every array in the **Feature** map is written as a column of data in the *CSV* file. The user can choose to also write the neighbor data. Neighbor data are data arrays that are associated with the neighbors of a **Feature**, such as: list of neighbors, list of misorientations, list of shared surface areas, etc. These blocks of info are written after the scalar data arrays. Since the number of neighbors is variable for each **Feature**, the data is written as follows (for each **Feature**): Id, number of neighbors, value1, value2,...valueN. ### Example Output +In the examples below, the very first line of the output (here `5414`) is the total **Feature** count — the number of Features whose data follows. + The *CSV* file: 5414 @@ -49,6 +51,14 @@ The *Delimiter* parameter selects the character used to separate values within e - **Colon [3]**: Values are separated by a colon (`:`). - **Tab [4]**: Values are separated by a tab character. +## Required Input Sources + +The per-feature columns come from any feature-level **Data Array**s present in the selected Feature **Attribute Matrix** (for example feature phases, sizes, or average orientations). When *Write Neighbor Data* is enabled, the additional neighbor blocks require: + +- **Number of Neighbors** and the contiguous **Neighbor List** -- produced by [Compute Feature Neighbors](ComputeFeatureNeighborsFilter.md). +- **Shared Surface Area List** -- produced by [Compute Feature Neighbors](ComputeFeatureNeighborsFilter.md). +- **Neighbor Misorientation List** -- produced by [Compute Feature Neighbor Misorientations](../OrientationAnalysis/ComputeFeatureNeighborMisorientationsFilter.md). + % Auto generated parameter table will be inserted here ## Example Pipelines diff --git a/src/Plugins/SimplnxCore/docs/WriteImageFilter.md b/src/Plugins/SimplnxCore/docs/WriteImageFilter.md index cdab858ea9..2ec302ba15 100644 --- a/src/Plugins/SimplnxCore/docs/WriteImageFilter.md +++ b/src/Plugins/SimplnxCore/docs/WriteImageFilter.md @@ -31,6 +31,10 @@ The *Plane* parameter controls which orthogonal plane is used when writing a 3D The *Total Number of Index Digits* and *Fill Character* parameters control the numeric suffix applied to each slice filename. For example, 3 total digits with a fill character of `0` produces `slice_000.tif`, `slice_001.tif`, etc. +### Required Input Sources + +- **Image Data** -- a `uint8` (or `uint16`/`float32` for TIFF) **Cell Data** array on an **Image Geometry**, produced by an image reader such as [Read Image](ReadImageFilter.md) / [Read Images [3D Stack]](ReadImageStackFilter.md), or by any upstream image-processing filter. + % Auto generated parameter table will be inserted here ## Example Pipelines diff --git a/src/Plugins/SimplnxCore/docs/WriteLAMMPSFileFilter.md b/src/Plugins/SimplnxCore/docs/WriteLAMMPSFileFilter.md index 1447639280..f7ec695b39 100644 --- a/src/Plugins/SimplnxCore/docs/WriteLAMMPSFileFilter.md +++ b/src/Plugins/SimplnxCore/docs/WriteLAMMPSFileFilter.md @@ -6,13 +6,40 @@ IO (Output) ## Description -This **Filter** is used to create an atomistic representation of microstructure from image data. The data file produced by this **filter** can be used for initializing the atomic coordinates in LAMMPS package. +This filter writes atom coordinates from a **Vertex Geometry** (a point cloud, where each point is one atom) into an input file for **LAMMPS**. LAMMPS (Large-scale Atomic/Molecular Massively Parallel Simulator) is an open-source molecular-dynamics code from Sandia National Laboratories that simulates the motion of atoms and molecules. -This **filter** should be used in conjunction with another **filter** named "Insert Atoms". Given a microstructure, the "Insert Atoms" filter follows the orientation of different features to insert atoms in them and saves the configuration of atoms in a **Vertex Data Container**. The "Export LAMMPS Filter" uses this **Vertex Data Container** to create an input file for LAMMPS. +The typical workflow first builds an atomistic representation of a microstructure with the *Insert Atoms* filter. Given a microstructure, *Insert Atoms* follows the crystallographic orientation of each **Feature** (grain) to place atoms inside it and stores the resulting atom positions in a **Vertex Geometry**. This **Write LAMMPS File** filter then reads that **Vertex Geometry** and writes a LAMMPS data file that LAMMPS can use to initialize the atom coordinates of a simulation. -% Auto generated parameter table will be inserted here +Atom coordinates are written in the physical units of the **Vertex Geometry** (the same units as the vertex positions, typically Angstroms or nanometers for atomistic data). The *Atom Feature Labels* array assigns each atom an atom type, so atoms belonging to different grains can be distinguished in the simulation. + +### Example Output + +A LAMMPS data file begins with header lines giving the atom and type counts and the simulation box bounds, followed by an `Atoms` section listing, for each atom, its ID, type, and x/y/z coordinates: + +```text +Number of Atoms + +8000 atoms +25 atom types + +0.0 100.0 xlo xhi +0.0 100.0 ylo yhi +0.0 100.0 zlo zhi -## Example Pipelines +Atoms + +1 1 0.000000 0.000000 0.000000 +2 1 1.500000 0.000000 0.000000 +3 2 3.000000 0.000000 0.000000 + .. +``` + +### Required Input Sources + +- **Vertex Geometry** -- the atom positions to export, typically produced by the *Insert Atoms* filter. +- **Atom Feature Labels** -- a per-atom integer array (one value per vertex) giving each atom's type, also produced by *Insert Atoms*. + +% Auto generated parameter table will be inserted here ## License & Copyright diff --git a/src/Plugins/SimplnxCore/docs/WriteLosAlamosFFTFilter.md b/src/Plugins/SimplnxCore/docs/WriteLosAlamosFFTFilter.md index 2b40aa11b1..e62a7fe75b 100644 --- a/src/Plugins/SimplnxCore/docs/WriteLosAlamosFFTFilter.md +++ b/src/Plugins/SimplnxCore/docs/WriteLosAlamosFFTFilter.md @@ -6,40 +6,36 @@ IO (Output) ## Description -This **Filter** will create the directories along the path to the file if possible. +This filter writes per-**Cell** data from an **Image Geometry** to a plain-text file formatted for Ricardo Lebensohn's FFT-based simulation codes[1]. That code is a full-field micromechanical *crystal-plasticity* simulation: it predicts how a polycrystalline microstructure deforms by solving the mechanical equations on the voxel grid using a Fast Fourier Transform (FFT) method, with one material point per voxel. -This **Filter** writes out **CellData** from an **Image Geometry** to a file that is appropriate to use as an input into Ricardo Lebensohn's FFT 3D simulation codes[1]. +Each line of the output describes a single **Cell** and combines its crystallographic orientation, its grid location, and its **Feature** (grain) and phase membership. The orientation is given as three **Euler angles** — three angles (in the Bunge Z-X-Z convention) that together specify how a crystal is rotated relative to the sample reference frame. -The format of the file is an ASCII text file with the following space delimited information: +If possible, the filter creates any missing directories along the path to the output file. + +The format of the file is an ASCII text file with the following space-delimited information: Phi1 Phi Phi2 X Y Z Feature_ID Phase_ID The Euler angles are in degrees. X, Y, Z are integer indices into the **Image** geometry. Feature ID & Phase ID are the integer values for the feature and phase **Starting at One (1)**. +### Required Input Sources + +- **Image Geometry** -- the voxel grid to export. +- **Cell Euler Angles** -- a 3-component, per-cell orientation array (Bunge Z-X-Z, in degrees), typically read from EBSD data via [Read EDAX EBSD Data (.ang)](../OrientationAnalysis/ReadAngDataFilter.md), [Read Oxford Instr. EBSD Data (.ctf)](../OrientationAnalysis/ReadCtfDataFilter.md), or [Read H5EBSD File](../OrientationAnalysis/ReadH5EbsdFilter.md). +- **Cell Feature Ids** -- produced by a segmentation filter such as [Segment Features (Scalar)](ScalarSegmentFeaturesFilter.md). +- **Cell Phases** -- a per-cell phase index, read alongside the Euler angles from the EBSD readers above. + ### Example Output -The output file: +The output file (columns: Phi1, Phi, Phi2, X, Y, Z, Feature_ID, Phase_ID): 90.000 0.000 0.000 1 1 1 0 1 - 90.000 0.000 0.000 2 1 1 0 1 - 90.000 0.000 0.000 3 1 1 0 1 + 90.000 0.000 0.000 2 1 1 0 1 + 90.000 0.000 0.000 3 1 1 0 1 90.000 0.000 0.000 4 1 1 0 1 - 90.000 0.000 0.000 5 1 1 0 1 - 90.000 0.000 0.000 6 1 1 0 1 - 90.000 0.000 0.000 7 1 1 0 1 - 90.000 0.000 0.000 8 1 1 0 1 - 90.000 0.000 0.000 9 1 1 0 1 - 90.000 0.000 0.000 10 1 1 0 1 - 90.000 0.000 0.000 11 1 1 0 1 - 90.000 0.000 0.000 12 1 1 0 1 - 90.000 0.000 0.000 13 1 1 0 1 - 90.000 0.000 0.000 14 1 1 0 1 - 90.000 0.000 0.000 15 1 1 0 1 - 90.000 0.000 0.000 16 1 1 0 1 - 90.000 0.000 0.000 17 1 1 0 1 - 135.009 55.304 295.274 18 1 1 1742 1 - 90.000 0.000 0.000 19 1 1 0 1 - .. + 135.009 55.304 295.274 18 1 1 1742 1 + 90.000 0.000 0.000 19 1 1 0 1 + .. % Auto generated parameter table will be inserted here @@ -47,8 +43,6 @@ The output file: [1] R.A. Lebensohn, 2001. N-site modeling of a 3D viscoplastic polycrystal using Fast Fourier Transform. Acta mater. 49, 2723-2737. -## Example Pipelines - ## License & Copyright Please see the description file distributed with this **Plugin** diff --git a/src/Plugins/SimplnxCore/docs/WriteNodesAndElementsFilesFilter.md b/src/Plugins/SimplnxCore/docs/WriteNodesAndElementsFilesFilter.md index 280fda67ba..1c6d4b9f91 100644 --- a/src/Plugins/SimplnxCore/docs/WriteNodesAndElementsFilesFilter.md +++ b/src/Plugins/SimplnxCore/docs/WriteNodesAndElementsFilesFilter.md @@ -8,7 +8,7 @@ IO (Output) This **Filter** exports node based geometries into structured text files. It allows users to save the following: -1. Node Data (Vertices): Export the coordinates of points that define the geometry. +1. Node Data (Vertices): Export the coordinates of points that define the geometry. The coordinates are written in the geometry's physical units (the same units as the geometry's vertex coordinates). 2. Element Data (Connectivity): Export the node indices that make up the edges, faces, or volumes of the geometry. The filter gives the user the option to export a node file, element file, or both. It also allows the user to decide whether or not to number the nodes and elements and whether or not to include headers for the node and element files. @@ -40,7 +40,7 @@ In this example output, the following filter parameter options have been selecte The output is listed below where column 1 is controlled by the `Number Elements/Cells` parameter and line #2 is controlled by the `Include Element/Cell File Header` parameter. -Some explanation as to the columns is requried for this output. +Some explanation as to the columns is required for this output. - Column #1 is just the index of the element - Column #2 is the number of vertices in this element. in this output, 3 since this was exported from a Triangle Geometry @@ -73,6 +73,10 @@ ELEMENT_NUM NUM_VERTS_IN_ELEMENT V0_Index V1_Index V2_Index | Hexahedral | 8 | +## Required Input Sources + +- **Node-based Geometry** -- any node-based geometry (**Vertex**, **Edge**, **Triangle**, **Quadrilateral**, **Tetrahedral**, or **Hexahedral Geometry**), produced by a surface-meshing filter such as [Create Surface Mesh (QuickMesh)](QuickSurfaceMeshFilter.md) or a geometry-creation filter such as [Create Geometry](CreateGeometryFilter.md). + % Auto generated parameter table will be inserted here ## License & Copyright diff --git a/src/Plugins/SimplnxCore/docs/WriteSPParksSitesFilter.md b/src/Plugins/SimplnxCore/docs/WriteSPParksSitesFilter.md index 443adeba36..7cc8629520 100644 --- a/src/Plugins/SimplnxCore/docs/WriteSPParksSitesFilter.md +++ b/src/Plugins/SimplnxCore/docs/WriteSPParksSitesFilter.md @@ -4,39 +4,50 @@ IO (Output) -## Description ## - -This **Filter** writes to a data file in a format used by [SPPARKS Kinetic Monte Carlo Simulator](http://spparks.sandia.gov/). - -+ The "Values" section is a pair of numbers where the first number is the site ID and the second number is the actual value of the **Feature** Id at that site. -+ LINE 4 evidently must be what is shown in the example file. -+ LINE 3 is the total number of **Cells**. -+ LINES 5, 6 and 7 are the dimensions of the volume. - -More information can be found at the [SPParks web site.](http://spparks.sandia.gov/doc/read_sites.html) or [http://spparks.sandia.gov/doc/dump.html](http://spparks.sandia.gov/doc/dump.html) - -**This filter will write an SPParks _Sites_ file format** - -## Example Output ## - - [LINE 1] - - [LINE 2] 3 dimension - [LINE 3] 8000000 sites - [LINE 4] 26 max neighbors - [LINE 5] 0 200 xlo xhi - [LINE 6] 0 200 ylo yhi - [LINE 7] 0 200 zlo zhi - [LINE 8] - [LINE 9] Values - [LINE 10] - 1 944 - 2 944 - 3 944 - 4 944 - 5 509 - 6 509 - 7 509 - .. +## Description + +This filter writes a data file in the format used by [SPPARKS](http://spparks.sandia.gov/). **SPPARKS** (Stochastic Parallel PARticle Kinetic Simulator) is an open-source Kinetic Monte Carlo code from Sandia National Laboratories used to simulate microstructure evolution, such as grain growth. + +SPPARKS represents the microstructure as a set of **sites**. In this export each site corresponds to one **Cell** (voxel) of the input **Image Geometry**, and the value stored at each site is that cell's **Feature** Id (the grain it belongs to). The `Values` section of the file is therefore a list of pairs: the first number in each pair is the site ID (running from *1*), and the second number is the Feature Id at that site. + +The header lines describe the lattice the sites live on: + +- **LINE 1** is intentionally left blank (a separator). +- **LINE 2** records the spatial dimension (always `3 dimension` for a 3D **Image Geometry**). +- **LINE 3** is the total number of **Cells** (sites). +- **LINE 4** is the maximum number of neighbors per site. For a 3D cubic lattice this is `26 max neighbors` (the 26 surrounding cells), and SPPARKS expects exactly this value for this lattice type. +- **LINES 5, 6, and 7** give the box extents along x, y, and z. These pairs (for example `0 200`) are **cell-index** extents — dimensionless counts of cells along each axis — not physical lengths in microns. +- **LINE 8** is a blank separator before the `Values` keyword. + +More information can be found in the SPPARKS documentation for [read_sites](http://spparks.sandia.gov/doc/read_sites.html) and [dump](http://spparks.sandia.gov/doc/dump.html). + +### Required Input Sources + +- **Image Geometry** -- the voxel grid whose cells become SPPARKS sites. +- **Cell Feature Ids** -- produced by a segmentation filter such as [Segment Features (Scalar)](ScalarSegmentFeaturesFilter.md). The Feature Id at each cell becomes that site's value. + +### Example Output + +```text +[LINE 1] +[LINE 2] 3 dimension +[LINE 3] 8000000 sites +[LINE 4] 26 max neighbors +[LINE 5] 0 200 xlo xhi +[LINE 6] 0 200 ylo yhi +[LINE 7] 0 200 zlo zhi +[LINE 8] +[LINE 9] Values +[LINE 10] +1 944 +2 944 +3 944 +4 944 +5 509 +6 509 +7 509 + .. +``` % Auto generated parameter table will be inserted here diff --git a/src/Plugins/SimplnxCore/docs/WriteStlFileFilter.md b/src/Plugins/SimplnxCore/docs/WriteStlFileFilter.md index 302c9dfa18..9e41cff946 100644 --- a/src/Plugins/SimplnxCore/docs/WriteStlFileFilter.md +++ b/src/Plugins/SimplnxCore/docs/WriteStlFileFilter.md @@ -6,21 +6,26 @@ IO (Output) ## Description -***WARNING:*** The filter now provides implict overflow capabilities for very large datasets, but **this will lead to many duplicated vertices being produced**. Be sure to run a cleaning algorithm when importing these files into DREAM3DNX or other software. For more info see below. +***WARNING:*** The filter now provides implicit overflow capabilities for very large datasets, but **this will lead to many duplicated vertices being produced**. Be sure to run a cleaning algorithm when importing these files into DREAM3DNX or other software. For more info see below. -This **Filter** can generate a single or multiple binary STL (StereoLithography) files for a given Triangle Geometry. +This **Filter** can generate a single or multiple binary STL (StereoLithography) files for a given **Triangle Geometry**. The vertex coordinates written to each STL file are in the **Triangle Geometry**'s physical units. ### File Grouping Type The *File Grouping Type* parameter provides the following choices: -- **Features [0]**: The user must supply a 2-component Int32 array where the values are the 2 features that each triangle belongs to. One STL file is written per feature. +- **Features [0]**: The user must supply a 2-component Int32 array (a **FaceLabels**-style array) where the two values for each triangle are the **Feature** IDs on either side of that triangle. One STL file is written per feature. - **Phases and Features [1]**: The same 2-component array as Features, plus a single-component array representing a higher-order grouping such as a phase or part number. - **Single File [2]**: The entire Triangle Geometry is saved as a single STL file. - **Part Index [3]**: The user must supply a single-component Int32 array at the triangle level that indicates which part each triangle belongs to. This filter supports overflow capabilities for all of the "File Grouping Type"(s) (including single file). This means if you have over the maximum number of triangles for a single STL file (2,147,483,647), the remaining triangles will be written to "overflow files" which will follow the following syntax `{filename}_overflow_{count}`. *Warnings will be emitted during preflight if it is known or a possibility this will occur.* Due to the nature of STL files containing all the vertices relative to the triangles in the file, **duplicate vertices will be written between the files**. For single file overflow, the files will be written in parallel with the number of additional tasks being equivalent to `({number of triangles in Geometry} / 2,147,483,647) + 1`. For multiple files, the existing tasks handling the grouping write out are also responsible for creating/writing any overflow files. +## Required Input Sources + +- **Triangle Geometry** -- a surface mesh produced by a surface-meshing filter such as [Create Surface Mesh (QuickMesh)](QuickSurfaceMeshFilter.md). +- **Face Labels** (only when grouping by feature) -- a 2-component array, on the triangle/face data, holding the two **Feature** IDs on either side of each triangle. This is produced by the same surface-meshing step, for example [Create Surface Mesh (QuickMesh)](QuickSurfaceMeshFilter.md). + % Auto generated parameter table will be inserted here ## License & Copyright diff --git a/src/Plugins/SimplnxCore/docs/WriteVtkRectilinearGridFilter.md b/src/Plugins/SimplnxCore/docs/WriteVtkRectilinearGridFilter.md index 1a275277be..39612f039c 100644 --- a/src/Plugins/SimplnxCore/docs/WriteVtkRectilinearGridFilter.md +++ b/src/Plugins/SimplnxCore/docs/WriteVtkRectilinearGridFilter.md @@ -6,7 +6,20 @@ I/O Filters ## Description -This Filter writes a VTK legacy file with a Dataset type of `RECTILINEAR_GRID`. The user can select which arrays from the Image Geometry will be written to the file. +This filter writes the selected data to a **VTK legacy file**. A VTK legacy file is the older, human-readable file format used by the Visualization Toolkit (VTK); it can be opened directly by common scientific visualization tools such as **ParaView** and **VisIt**. + +The file is written with a dataset type of `RECTILINEAR_GRID`. A rectilinear grid stores three explicit per-axis coordinate arrays (one list of X positions, one of Y positions, and one of Z positions). The grid lines are axis-aligned but the spacing along each axis may vary. + +Although the input to this filter is an **Image Geometry** (which has a single uniform spacing along each axis), the output is written in the rectilinear-grid form: the filter expands the image's uniform spacing into the explicit per-axis coordinate arrays that the `RECTILINEAR_GRID` format requires. If the output only needs uniform spacing, the smaller [Write Vtk Structured Points](WriteVtkStructuredPointsFilter.md) format may be preferable. + +The user selects which **Cell** **Data Array**s from the **Image Geometry** are written into the file. Each selected array becomes a cell-data field in the VTK file. + +The *Write Binary File* parameter controls the on-disk encoding. When *false* (the default), the data is written as plain ASCII text, which is portable and easy to inspect but larger and slower to read. When *true*, the data is written in VTK's binary form, producing smaller files that load faster. + +### Required Input Sources + +- **Image Geometry** -- the geometry whose dimensions and spacing define the grid. +- **Cell Data Array(s) to write** -- any per-cell arrays on the **Image Geometry**. A common choice is a *FeatureIds* array produced by [Segment Features (Scalar)](ScalarSegmentFeaturesFilter.md). % Auto generated parameter table will be inserted here diff --git a/src/Plugins/SimplnxCore/docs/WriteVtkStructuredPointsFilter.md b/src/Plugins/SimplnxCore/docs/WriteVtkStructuredPointsFilter.md index 5c7808dcb6..3ad3e1e31c 100644 --- a/src/Plugins/SimplnxCore/docs/WriteVtkStructuredPointsFilter.md +++ b/src/Plugins/SimplnxCore/docs/WriteVtkStructuredPointsFilter.md @@ -6,9 +6,24 @@ I/O Filters ## Description -This Filter writes a VTK legacy file with a Dataset type of `STRUCTURED_POINTS`. The user can select which arrays from the Image Geometry will be written to the file. +This filter writes the selected data to a **VTK legacy file**. A VTK legacy file is the older, human-readable file format used by the Visualization Toolkit (VTK); it can be opened directly by common scientific visualization tools such as **ParaView** and **VisIt**. -Note: This filter only writes cell data to the VTK file. +The file is written with a dataset type of `STRUCTURED_POINTS`. A structured-points dataset describes a regular grid with uniform spacing along each axis: the grid is fully defined by its origin, its per-axis spacing, and its dimensions, so no explicit coordinate arrays are stored. This makes it the most compact VTK form for image data. + +The user selects which **Cell** **Data Array**s from the **Image Geometry** are written into the file. + +**Note:** This filter only writes cell data to the VTK file. + +### When to use this filter vs Write Vtk Rectilinear Grid + +Use **Write Vtk Structured Points** when the **Image Geometry** has uniform spacing (the usual case) and a compact file is desired. Use [Write Vtk Rectilinear Grid](WriteVtkRectilinearGridFilter.md) when the output must store explicit per-axis coordinate arrays (for example, to interoperate with a tool that expects a `RECTILINEAR_GRID` dataset). + +The *Write Binary File* parameter controls the on-disk encoding. When *false* (the default), the data is written as plain ASCII text, which is portable and easy to inspect but larger and slower to read. When *true*, the data is written in VTK's binary form, producing smaller files that load faster. + +### Required Input Sources + +- **Image Geometry** -- the geometry whose origin, spacing, and dimensions define the grid. +- **Cell Data Array(s) to write** -- any per-cell arrays on the **Image Geometry**. A common choice is a *FeatureIds* array produced by [Segment Features (Scalar)](ScalarSegmentFeaturesFilter.md). % Auto generated parameter table will be inserted here