graintrace.nf#
NF (near-field) HEDM voxel grid processing subpackage.
NF point-cloud to fixed-grid conversion and VTK export helpers.
- graintrace.nf.convert.layer_number(path, token='layer')[source]#
Extract the layer index that follows
tokenin a filename.
- graintrace.nf.convert.nf_to_pointcloud(folder, dz, layer_token='layer')[source]#
Convert nearfield data (.mic/.csv layers) to a stacked point cloud.
- graintrace.nf.convert.process_layer_pointcloud(df_layer, plane_points, nx, ny)[source]#
Interpolate one point-cloud layer onto a fixed nx x ny grid.
- Returns:
nx x ny x 7 array [phase, Eul1, Eul2, Eul3, X, Y, Z]
- Return type:
np.ndarray
- graintrace.nf.convert.pointcloud_to_fixed_grid(pointcloud, nx, ny)[source]#
Convert a point cloud to an nx x ny x nz x 7 fixed grid.
- graintrace.nf.convert.fixed_grid_to_vtk(fixed_grid, filename, varlabels=['phase', 'Eul1', 'Eul2', 'Eul3', 'X', 'Y', 'Z'])[source]#
Save an nx x ny x nz x 7 fixed grid to a structured-grid VTK file.
Flood-fill grain segmentation and cleanup for NF voxel grids.
- graintrace.nf.segment.flood(angles, phase, misorientation_tol, connectivity=26, batch_norm=10000000, grain_threshold=100, stop_count=100, **kwargs)[source]#
Flood-fill segmentation of connected components in a 3D voxel grid.
- Parameters:
angles (nx,ny,nz,3) – Euler angles, interpreted per metrics.misorientation kwargs
phase (nx,ny,nz) – phase identifiers per voxel (>0 material, 0 void)
misorientation_tol (float) – misorientation tolerance for connectivity
connectivity (int) – 6 or 26
batch_norm (int) – batch size for distance calculation
grain_threshold (int) – minimum segment size to keep
stop_count (int) – stop after discarding this many small segments; must be >= 1
**kwargs – extra arguments for metrics.misorientation()
- Returns:
(nx,ny,nz) array of segmented phases
- Raises:
ValueError – if
stop_countis less than 1
- graintrace.nf.segment.infill_nearest_neighbor(grid, connectivity=6)[source]#
Infill unmarked voxels (phase == -1) from nearest filled neighbors.
- Parameters:
grid (nx,ny,nz,7) – fixed grid, grid[…,0] is the phase index
connectivity (int) – 6 or 26
- Returns:
(nx,ny,nz,7) tensor with all phase == -1 voxels filled
- graintrace.nf.segment.remove_small_segments(grid, min_size, connectivity=6)[source]#
Merge segments smaller than
min_sizeinto their largest-contact neighbor.
SCULPT hex meshing and orientation mapping for NF voxel grids.
- graintrace.nf.mesh.write_spn(data, filename_spn, filename_orientations, angle_convention='bunge', angle_type='radians', symmetry='1')[source]#
Write an spn and per-grain orientation file from fixed grid data.
- Parameters:
data (np.ndarray) – nx x ny x nz x 7 array [phase, Eul1, Eul2, Eul3, X, Y, Z]
filename_spn (str) – output spn filename
filename_orientations (str) – output orientations filename
angle_convention (str) – ‘kocks’, ‘bunge’, or ‘roe’
angle_type (str) – ‘degrees’ or ‘radians’
symmetry (str) – crystal symmetry for the per-grain orientation average (see
graintrace.nf.metrics.average_rotations()). Pass the crystal point group (e.g."432") so voxels of one grain reported in different symmetry variants average correctly.
- Raises:
ValueError – if any voxel still carries a negative (“unsegmented”) phase. Such a voxel is not a grain, and mapping it to void here would silently delete material from the mesh, so the caller decides.
- graintrace.nf.mesh.mesh_sculpt(sculpt_config, sculpt_options, input_spn, data, output_mesh_filename, output_angle_filename, split_output_prefix='output_mesh', angle_convention='bunge', angle_type='radians', symmetry='1')[source]#
Call sculpt (+epu) to generate an Exodus mesh from an spn file.
- Parameters:
sculpt_config (dict) – configuration for the sculpt call
sculpt_options (list) – extra command line options for sculpt
input_spn (str) – path to input spn file
data (np.ndarray) – nx x ny x nz x 7 array [phase, Eul1, Eul2, Eul3, X, Y, Z]
output_mesh_filename (str) – path to output exodus mesh file
output_angle_filename (str) – path to output orientations file
split_output_prefix (str) – prefix for temporary output files
angle_convention (str) – ‘kocks’, ‘bunge’, or ‘roe’
angle_type (str) – ‘degrees’ or ‘radians’
symmetry (str) – crystal symmetry for the per-block orientation average (see
graintrace.nf.metrics.average_rotations()).
- graintrace.nf.mesh.rescale_exodus_mesh(exo_file, data)[source]#
Rescale Exodus mesh coordinates to match those in a fixed grid.
- Parameters:
exo_file (str) – path to Exodus mesh file
data (np.ndarray) – nx x ny x nz x 7 array [phase, Eul1, Eul2, Eul3, X, Y, Z]
- graintrace.nf.mesh.map_orientations(exo_file, data, output_angle_filename, angle_convention='bunge', angle_type='radians', symmetry='1', background_id=0)[source]#
Map orientations from fixed grid data onto an Exodus mesh’s blocks.
Each Exodus element block is one grain, so a block’s elements are looked up against that grain’s own voxels only: void voxels (
background_id, which carry a meaningless Euler (0, 0, 0)) are excluded from the search, and the per-block KD-tree is restricted to voxels of the block’s grain. A single tree over every voxel lets a surface or void-adjacent element take the identity from a void voxel, or a neighbouring grain’s orientation across the boundary.Block-to-grain association uses the Exodus block ids (
eb_prop1) when they are all present in the grid – the SCULPT path, wherewrite_spn()relabels the grid ids to the spn material ids that become the block ids. Otherwise, when the block count matches the grain count, blocks are associated positionally with the sorted non-void grain ids.- Parameters:
exo_file (str) – path to Exodus mesh file
data (np.ndarray) – nx x ny x nz x 7 array [phase, Eul1, Eul2, Eul3, X, Y, Z]
output_angle_filename (str) – path to output orientations file
angle_convention (str) – ‘kocks’, ‘bunge’, or ‘roe’
angle_type (str) – ‘degrees’ or ‘radians’
symmetry (str) – crystal symmetry for the per-block orientation average (see
graintrace.nf.metrics.average_rotations()).background_id (int) – grid id treated as void and excluded from the lookup. Default 0.
- Raises:
ValueError – if the grid has no non-void voxels, or the Exodus blocks cannot be associated with the grid’s grains by id or by position.
- graintrace.nf.mesh.write_voxel_exodus(data, output_mesh_filename, output_angle_filename, angle_convention='bunge', angle_type='radians', background_id=0, symmetry='1')[source]#
Dump a segmented voxel grid directly to an Exodus hex mesh (no SCULPT).
Emits one axis-aligned cube HEX8 per non-background voxel, with nodes shared between adjacent voxels (conformal, including across grain boundaries). Because every element is a perfect cube its scaled Jacobian is exactly 1, so the mesh has no inverted/sliver elements – at the cost of stair-stepped grain boundaries and one hex per filled voxel. This is the robust alternative to mesh_sculpt when conformal smoothing produces bad elements.
- Parameters:
data – (nx, ny, nz, 7) array [grain_id, Eul1, Eul2, Eul3, X, Y, Z] (torch or numpy); coordinates are voxel centers.
output_mesh_filename (str) – output Exodus (.e) path. One element block per grain, block ids relabeled to a contiguous 1..N (matching MOOSE/PUMA).
output_angle_filename (str) – orientation output stem; the per-block MRP file is written to
output_angle_filename + ".csv"(one row per block, same order/convention as map_orientations).angle_convention (str) – ‘kocks’, ‘bunge’, or ‘roe’.
angle_type (str) – ‘degrees’ or ‘radians’.
background_id (int) – voxel id treated as void (skipped). Default 0. Voxels with a negative (“unsegmented”) id are skipped as well, so an orphan left by
remove_small_segmentsdoes not become a block of its own and shift every grain id.symmetry (str) – crystal symmetry for the per-block orientation average (see
graintrace.nf.metrics.average_rotations()).
- Returns:
{‘nodes’, ‘elements’, ‘blocks’} counts.
- Return type:
Orientation-field smoothing for NF voxel grids.
- graintrace.nf.smooth.smooth(data, connectivity=6, symmetry='1', angle_convention='bunge', angle_type='radians')[source]#
Smooth voxel orientations via a neighbor quaternion mean.
Voxel connectivity helpers for NF grid images.
- graintrace.nf.image.get_neighbor_indices(offsets, shape)[source]#
Compute neighbor indices for every voxel given a set of offsets.
- Parameters:
offsets – (n_offsets, 3) tensor of (dx, dy, dz)
shape – (nx, ny, nz) tuple
- Returns:
(n_offsets, nx, ny, nz) clamped neighbor indices valid: (n_offsets, nx, ny, nz) mask of in-bounds neighbors
- Return type:
Xk, Yk, Zk
Orientation averaging and misorientation metrics for NF grids.
- graintrace.nf.metrics.fold_to_reference_variant(R, symmetry)[source]#
Fold rotations onto the symmetry variant closest to the first of the set.
A crystal orientation has one rotation matrix per symmetry operator (24 for cubic
432), and a reconstruction may report neighbouring voxels of one grain in different variants. Averaging across variants is meaningless, so every member is first replaced by the symmetry-equivalent that is closest (largest Frobenius inner product) to the reference memberR[..., 0, :, :].- Parameters:
R –
(..., N, 3, 3)rotation matrices; the set is averaged over axis -3.symmetry (str) – crystal symmetry in orbifold notation;
"1"disables folding and returnsRunchanged.
- Returns:
(..., N, 3, 3)rotation matrices, all in a common symmetry variant.
- graintrace.nf.metrics.average_rotations(e, angle_convention='kocks', angle_type='radians', symmetry='1')[source]#
Average a set of Euler angles via quaternion (eigenvector) mean.
- Parameters:
e – Nx…x3 array of Euler angles
angle_convention (str) – ‘kocks’, ‘bunge’, or ‘roe’
angle_type (str) – ‘degrees’ or ‘radians’
symmetry (str) – crystal symmetry in orbifold notation (e.g.
"432"). Members are folded into a common symmetry variant before averaging, so a grain whose voxels are reported in different variants still yields the correct mean."1"(the default) disables folding and gives the plain quaternion eigenvector (Markley) mean.
- Returns:
averaged orientation as a neml2 v3 MRP (…, 3) and as Euler angles (…, 3) in the given convention.
- Return type:
tuple
(mrp, euler)
- graintrace.nf.metrics.batched_norm(v1, v2, norm, chunk_size, **kwargs)[source]#
Compute
norm(v1, v2)in chunks ofchunk_sizeto save memory.