Repository navigation
graintrace 0.2.0
This release makes the NF/FF/EBSD experiment path work end to end inside graintrace: state the frame transform between datasets, reconstruct NF with a confidence mask and graph segmentation, mesh it with SCULPT, and match grains across datasets and load steps. It contains API and default changes, so read Breaking and behaviour changes before upgrading.
Highlights
FrameTransform(new,graintrace.frame_transform, #61): a stated sample-frame changex' = Q(s⊙x) + t,g' = g Qᵀ,ε' = Q ε Qᵀthat moves positions, orientations and strain tensors consistently. Tilt is part ofQ;sis a per-axis sign only (no scale). It has adapters for FF grain CSVs, point clouds, voxel grids and the headerlessreconstruction_cpfe_ee.csv, plusinside_voxel_solidfor building overlap masks. Inverse, composition and JSON records are exact. Orientation math goes through neml2.- NF confidence mask (#62):
min_confidence,max_point_distanceandvoxel_size_uminNearFieldMeshBuilder.reconstruct,NFGridConversionand the NF point-cloud gridding, so air and low-confidence points become void instead of being nearest-neighbour filled. The per-voxel confidence is written beside the grid. - Graph (Leiden) segmentation in
NearFieldMeshBuilder(#62):segmentation={"method": "graph", ...}with an optional in-planedownsample. The.micreader also accepts MIDAS per-layer subfolders. - Size-aware split detection (#63):
FragmentationAnalyzer.detect_splitsgainsd_tol_mode="radius"/"radius_sum",assignment="one_to_one"(Hungarian), per-side recall within_overlap_a/bmasks, and a chance-link null (n_null). - Segmentation without a grain-size cap (#64):
FragmentationAnalyzer.segmentno longer caps grain size by default. Small fragments are absorbed only into a neighbour of similar orientation (absorb_max_miso_deg). The adjacency re-merge is agglomerative and checks the merged cluster's spread.cluster_leak_checkdetects orientation leaks.seg_to_grain_table(trim_miso_deg=...)gives a trimmed grain mean. .angconverter (new,graintrace.ang_conversion.AngConverter, #56): converts EDAX/TSL.anglayers to.micforNearFieldMeshBuilder, or to the mergedx, y, z, Eul0..2CSV forVoxelMeshBuilder. Layers are ordered by the parsed layer index.
Breaking and behaviour changes
graintrace.nf.convert.pointcloud_to_fixed_gridnow returns(grid, confidence)instead ofgrid.- Passing
nx/nytogether withvoxel_size_umraisesValueError. - SCULPT
--void_matis now set by graintrace. SCULPT numbers spn values from 1, so the void (spn 0) is material 1. The previously documented--void_mat 0meshed the void as a block.mesh_sculptnow passes--void_mat 1when the grid has void and replaces a user value with a warning. Remove--void_matfrom yoursculpt_options. - SCULPT meshes are mapped from SCULPT's voxel-index coordinates exactly. Earlier meshes were shrunk by one voxel per axis, and masked (void-bordered) grids were stretched over the full scan box.
- SCULPT block ids are renumbered to a contiguous 1..N.
<mesh>_block_map.csvrecords each block's original SCULPT id and grain. Orientation rowkbelongs to blockk+1. - A
phasecolumn is no longer treated as a void marker implicitly. Opt in withvoid_marker_col. - Isolated solid islands left unsegmented after cleanup become void instead of aborting
write_spn. FragmentationAnalyzer.segmentdefaults: no grain-size cap, orientation-gated absorption, and a spread-checked re-merge. Segmentations may keep more small, distinct grains than before.percolation_max_frac=0.03restores the previous behaviour exactly.grain_fragmentsusesgamma=0.25whenseg_kwargsgives none.orientation_helper.matrix_to_eulerwraps φ1/φ2 to [0, 360) (or [0, 2π)) and resolves gimbal lock deterministically. The rotations are unchanged, but stored Euler values can differ numerically.VoronoiMeshBuilder(rotate_angles=...)now rotates orientations on the sample side (g Qᵀ). The old crystal-side update was a no-op for cubic crystals.orientation_active_conventionis deprecated and ignored.FrameTransformrejects non-unit quaternions.detect_splitsraises on negative or NaN tolerances, and treats NaN or negative radii as 0 with a warning.AngConverterdefaults to TSL Bunge radians and raises when angles labelled as radians exceed 4π.
Fixes
VoronoiMeshBuilderauto_rotateno longer raises on about 8% of inputs; the axis signs are aligned before handedness is restored.FrameTransform.mrpreturns the short MRP set; it no longer blows up to NaN near 180° rotations.- The chain-merge in
adjacency_remergewithout a cap is fixed (#64). Labels below 0 and the background label are left untouched consistently across segmentation helpers. - Grain-orientation averaging folds crystal-symmetry variants first (#20).
- An unsegmented voxel no longer corrupts the SCULPT mesh. Discarded flood segments stay rejected (#33). Mesh blocks are matched to their own grain's voxels (#38).
- The flood out-of-domain mask is applied in place. Experiment rotation refuses a row-count mismatch. IPF block colouring defaults to Bunge degrees (#55).
detect_splitskeeps a parent's best candidate when no two children are adjacent (#37).- Graph-affecting and weighting parameters are validated when resuming a segmentation checkpoint (#18, #22). The mutual-kNN neighbour count is clamped to N−1 (#16). DBSCAN summaries are labelled with their columns (#17). Top-k prune ties are resolved consistently, with a faster half-edge grouping (#39, #41).
validate_topologyrefuses a broken tessellation at any verbosity (#42).GrainMatcheroutput files followoutput_prefix(#40). Examples write to their own output folders (#36). Lazy-import errors name the install tier needed (#34).
Documentation
- New API page for
FrameTransform, a.angsection in File formats, and updated configuration, pitfalls and tutorials (NF reconstruction, NF+FF, reorientation/fragmentation, voxel segmentation). - The docs build now lists pandoc as a prerequisite (#35). The maths and tutorial pages are expanded (#54).
Upgrade notes
- Drop
--void_matfromsculpt_options, and re-mesh any masked NF grid: earlier meshes included the air as a block and were stretched. - Unpack
grid, confidence = pointcloud_to_fixed_grid(...). - For NF data, use
min_confidence(about 0.5–0.6) with graph segmentation instead of relying on a grain-size cap. - To move FF data into the NF frame, state the transform with
FrameTransforminstead ofrotate_angleswithorientation_active_convention.