upxo.pxtal.geometrification module

Geometrification module for converting raster grain structures to polygon representations.

class upxo.pxtal.geometrification.polygonised_grain_structure(lgi, gids, neigh_gid_pxtal)[source]

Bases: object

Polygonised grain structure for geometrification of raster-format grain structures.

EPS_coord_coincide = 1e-08
lgi
gid
neigh_gid_pxtal
n
GBSEG
polygons
polygons_raw_exteriors
polygons_raw_holes
gsmp
smoothed
geometrify(verbose=True)[source]

Geometrify.

polygonize(user_lgi=False, lgi=None, user_gids=False, gids=None, verbose=True)[source]

Polygonize grains in self.lgi.

setup_gsmp_datastructure()[source]

Setup gsmp datastructure.

make_gsmp(verbose=True)[source]

Build and return gsmp.

make_polygonal_grains_raw(verbose=True, perform_xtal_dict_check=True)[source]

Build and return polygonal grains raw.

property expol

Expol.

property hlpol

Hlpol.

property holes_exist

Holes exist.

property allpol

Allpol.

set_polygons(verbose=True)[source]

Set self.polygons to the list of external grain polygons.

find_neighbors(verbose=True)[source]

Calculate neighbouring polygon IDs for all polygons in the grain structure.

Parameters:

polygons (list) – A list of Shapely Polygon objects.

Returns:

Keys are polygon IDs (1-based) and values are lists of neighbouring polygon IDs.

Return type:

dict

val_neigh_gid(pixl_gs_neigh_gid)[source]
Parameters:

pixl_gs_neigh_gid (dict) – neigh_gid dict of the pixellated grain structure (i.e. mcgs).

Returns:

True if validation passes, else False.

Return type:

bool, bool

make_neighpols()[source]

Build and return neighpols.

extract_gbsegments_raw()[source]

Extract gbsegments raw.

extract_gbsegments_mls_raw()[source]

Extract gbsegments mls raw.

get_polygon_touch_lines(poly1, poly2)[source]

Calculate the lines or points where two Shapely polygons touch.

Parameters:
  • poly1 (shapely.geometry.Polygon) – The two polygon objects to test.

  • poly2 (shapely.geometry.Polygon) – The two polygon objects to test.

Returns:

List of Shapely LineString objects if the polygons share edges, or Shapely Point objects if they touch at a single point.

Return type:

list

get_multilinestring_touch_points(mls2)[source]

Calculate the point(s) where two Shapely MultiLineStrings touch.

Parameters:
  • mls1 (shapely.geometry.MultiLineString) – The two MultiLineString objects to test.

  • mls2 (shapely.geometry.MultiLineString) – The two MultiLineString objects to test.

Returns:

List of Shapely Point objects at touch points, or empty list if none.

Return type:

list

area_gid(gid, gsrepr='raw')[source]

Return area of gid grain. Valid values for gsrepr are self.gsmp.keys(). In any case, the returned area will be geometric and not pixellated.

Examples

self.area_gid(1, gsrepr='raw')
plot_linestrings(ax=None, color='blue', linewidth=1, **kwargs)[source]

Plot a list of Shapely LineStrings and return the axis.

Parameters:
  • linestrings (list) – A list of LineString or MultiLineString objects.

  • ax (matplotlib.axes.Axes, optional) – Axes object to plot on. If None, a new figure and axis are created.

  • color (str, optional) – Line colour. Default is 'blue'.

  • linewidth (float, optional) – Line width. Default is 1.

  • **kwargs – Additional keyword arguments passed to plt.plot().

Returns:

The Axes object on which the lines were plotted.

Return type:

matplotlib.axes.Axes

plot_gsmp(raw=True, overlay_on_lgi=False, xoffset=0.5, yoffset=0.5, ax=None)[source]

Plot multi-polygon form of the grain structure.

Parameters:
  • raw (bool, optional) – If True, plot the raw gsmp. Default is True.

  • overlay_on_lgi (bool, optional) – If True, overlay the polygons on the lgi image. Default is False.

  • xoffset (float, optional) – Coordinate offsets applied before plotting. Default is 0.5.

  • yoffset (float, optional) – Coordinate offsets applied before plotting. Default is 0.5.

  • ax (matplotlib.axes.Axes, optional) – Axes object to plot on. If None, a new figure and axis are created.

Return type:

matplotlib.axes.Axes

plot_grains_gids(gids, add_points=True, points=None, gclr='color', title='user grains', cmap_name='viridis', plot_centroids=True, add_gid_text=True, plot_gbseg=False, bjp_kwargs={'marker': 'o', 'mec': 'black', 'mfc': 'yellow', 'ms': 2.5}, addpoints_kwargs={'marker': 'x', 'mec': 'black', 'mfc': 'black', 'ms': 5})[source]
Parameters:
  • gids (int or list) – Either a single grain index number or a list of them.

  • title (str, optional) – Plot title. Default is "user grains".

  • gclr (str, optional) – Colour mode. Options: 'color', 'binary', 'grayscale'.

Return type:

matplotlib.axes.Axes

Examples

# After acquiring gids for aspect_ratio between ranks 80 and 100,
# visualize those grains.
gid, _, __ = PXGS.gs[8].get_gid_prop_range(PROP_NAME='aspect_ratio',
                                            range_type='rank',
                                            rank_range=[80, 100])
PXGS.gs[8].plot_grains_gids(gid, cmap_name='CMRmap_r')
set_minimum_nnodes_per_gbseg()[source]

Set or update minimum nnodes per gbseg.

subdivide_gbsegments(method=1)[source]

Subdivide grain boundary segments by inserting additional nodes.

smooth_moving_avg(n=3)[source]

Smooth moving avg.

smooth_polynomial()[source]

Smooth polynomial.

extract_gids_for_smoothing(verbose=True)[source]

Extract gids for smoothing.

heal_edges(verbose=True)[source]

Heal edges.

plot_gbseg(gid, segid=[])[source]

Visualise gbseg using Matplotlib or PyVista.

Link polygons.

heal_polygons()[source]

Heal polygons.

write_abq_script_data()[source]

Export or convert to the ABQ script data format.

set_mesh_properties()[source]

Set or update mesh properties.

mesh()[source]

Mesh.

assess_mesh_quality()[source]

Assess mesh quality.

export_mesh()[source]

Export the mesh data.

set_grain_centroids_raw(verbose=True)[source]

Set raw grain centroids computed from lgi pixel locations.

set_grain_centroids(verbose=True)[source]

Set grain centroids from polygon coordinates.

set_polygonization_xyoffset(xyoffset, verbose=True)[source]

Set or update polygonization xyoffset.

pix_to_geom(polygonisation_offset=0.5, verbose=True, perform_xtal_dict_check=True)[source]

Pix to geom.

get_bounds_from_grain_boundary_points()[source]

Get x and y bounds from grain boundary points.

Notes

Works on grain boundary points obtained from polygonization of the raster image. self.xyoffset is subtracted from polygonization end coordinates to align with MCGS 2D results.

Examples

xmin, xmax, ymin, ymax = self.get_bounds_from_grain_boundary_points()
set_grain_loc_ids(verbose=True)[source]

Identify the location of grains and place their IDs in self.grain_loc_ids dictionary.

get_junction_points_from_grain_intersections(verbose=True)[source]

Return the junction points from grain intersections.

extract_GBP(verbose=True)[source]

Extract grain boundary points data from polygonization coordinate results.

set_up_quality_measures(verbose=True)[source]

Initiate the quality dictionary to hold results on operation quality.

get_bounds_from_GBP()[source]

Calculate the bounds of the polygonized grain structure.

find_GBP_at_boundary(verbose=True)[source]

Identify grain boundary points lying on the grain structure boundary.

update_JNP_from_GBP_at_boundary(verbose=True)[source]

Update junction points with the grain boundary points which are on the boundaries of the poly-xtal.

build_jnp_objects(verbose=True)[source]

Build coordinates, UPXO Point2d objects and shapely point objects of all junction points.

build_all_gbp_objects(verbose=True)[source]

Build coordinates of all grain boundary points. Global.

get_gbp_grain_wise_coords(verbose=True)[source]

Build coordinates of all grain boundary points, grain-wise.

build_jnp_grain_wise_indices(verbose=True)[source]

Build indices of jnp for every grain. Indices will be from jnp_all_coords. These indices relate to:

  • jnp_all_coords, jnp_all_upxo, jnp_all_shapely

  • jnp_all_upxo_mp.points, jnp_all_upxo_mp.coords

Examples

# Data access:
jnp_all_coords[jnp_grain_wise_indices[gid]]
jnp_all_upxo[jnp_grain_wise_indices[gid]]
jnp_all_upxo_mp.points[jnp_grain_wise_indices[gid]]

# Verification:
gid = 10
plt.imshow(geom.lgi)
coord = jnp_all_coords[jnp_grain_wise_indices[gid]]
plt.plot(coord[:, 0], coord[:, 1], 'ko')

Notes

jnp_all_upxo and jnp_all_upxo_mp.points share the same objects: id(jnp_all_upxo[i]) == id(jnp_all_upxo_mp.points[i])

build_gbp_grain_wise_indices_geometric(verbose=True)[source]

This is to correct inconsistencies in build_jnp_grain_wise_indices method. There are cases which lead to mulline constityutent lines intersecting each other. This step is crucial to avoid it.

build_gbp_grain_wise_indices_coordbased(verbose=True)[source]

Build and return gbp grain wise indices coordbased.

build_gbp_grain_wise_indices_pointsbased(verbose=True)[source]

Build and return gbp grain wise indices pointsbased.

build_gbmullines_grain_wise(verbose=True)[source]

Build grain boundary multi-linestring objects from grain boundary point data.

arrange_junction_point_coords_new(gbcoords_thisgrain, junction_points_coord)[source]

Arrange junction point coords new.

build_sorted_jnp_objects(plot=False, verbose=True)[source]

Build and return sorted jnp objects.

align_gbmullines_start_to_jnp_start(plot_bf=False, plot_af=False, verbose=True)[source]

Align gbmullines start to jnp start.

splice_grain_boundary_segments_at_junction_points(plot=False, verbose=True)[source]

Splice the grain boundary into grain boundary segments using jnp point data

find_quality_of_grain_boundary_segmentation(verbose=True)[source]

Assess quality of grain boundary segmentation by comparing segment counts per grain.

create_neigh_gid_pair_ids(neigh_gid, verbose=True)[source]

Create a dictionary mapping unique grain pairs to integer IDs.

Parameters:

neigh_gid (dict) – Keys are grain IDs and values are lists of neighbouring grain IDs.

Returns:

Keys are integer pair IDs and values are lists of two grain IDs.

Return type:

dict

get_random_gbpoint_between_jnpoints(gbcoords, jnpcoords)[source]

Return a random grain boundary point located between two junction points.

get_random_gbpoints_between_jnpoints(gid)[source]

Return random grain boundary points between junction points for a given grain.

setup_neigh_connectivity_flags_DS(neigh_sense='lr', field_names=['gbseg', 'nnodes_eq', 'length_eq', 'n', 'areas_raw', 'uniquified'], verbose=True)[source]

Setup neigh connectivity flags ds.

extract_end_coordinates_of_grain_boundary_segments_grain_wise(gid)[source]

Extract end coordinates of grain boundary segments grain wise.

set_neigh_connectivity_flags_DS(centroid_eq_EPS=1e-08, verbose=True)[source]

Set or update neigh connectivity flags DS.

get_unique_object_indices(nnodes, lengths, centroids, tol=1e-08)[source]

Find indices of unique objects based on nnodes, lengths, and centroids.

Parameters:
  • nnodes (np.ndarray) – 1D array of nnode values.

  • lengths (np.ndarray) – 1D array of length values.

  • centroids (np.ndarray) – 2D array of centroid coordinates.

  • tol (float, optional) – Tolerance for centroid coordinate comparison. Default is 1e-8.

Returns:

1D array of indices corresponding to unique objects.

Return type:

np.ndarray

gather_grain_boundary_segments_of_all_pairs(verbose=True)[source]

Gather grain boundary segments of all pairs.

consolidate_gbsegments(squeeze_segment_data_structure=False, verbose=True)[source]

Consolidate grain boundary segments by grain ID.

Parameters:

squeeze_segment_data_structure (bool, optional) – If True, flatten nested segment lists. Default is False.

Returns:

Keys are grain IDs and values are lists of grain boundary segments.

Return type:

dict

get_problematic_grains(plot=False)[source]

Def name must be changed.

find_segs_at_loc(gbsegs, axis='y', location=-0.5)[source]

Find segs at loc.

update_consolidated_segments_with_boundary_grain_gids(plot=False, verbose=True)[source]

Set or update te consolidated segments with boundary grain gids.

plot_consolidated_segments()[source]

Visualise consolidated segments using Matplotlib or PyVista.

check_if_all_gbsegs_can_form_closed_rings(GBSEGS, _print_individual_excoord_order_=True, _print_statement_=True)[source]

Check or validate check if all gbsegs can form closed rings.

flip_segments_to_reorder_GBS(plot_each_grain_details=False, verbose=True)[source]

Flip segments to reorder gbs.

update_segflip_requirements(verbose=True)[source]

Set or update te segflip requirements.

sort_subsets_by_original_order(CA, subsets)[source]

Sort subsets of coordinates based on their original order in the CA array.

Parameters:
  • CA (np.ndarray) – The original 2D coordinate array (N x 2).

  • subsets (list) – A list of np.ndarrays, each representing a subset of coordinates.

Returns:

  • list – Sorted np.ndarrays, each subset ordered according to its position in CA.

  • np.ndarray – 1D array of the original subset indices in sorted order.

sort_gbsegments_by_original_order(verbose=True)[source]

Sort gbsegments by original order.

calculate_grain_boundary_coordinates_after_gbseg_reordering(verbose=True)[source]

Calculate grain boundary coordinates after gbseg reordering.

are_grains_closed_usenodes()[source]

Are grains closed usenodes.

are_grains_closed_usecoords()[source]

Are grains closed usecoords.

set_pure_gbpoints(verbose=True)[source]

Set or update pure gbpoints.

plot_reordered_GBCoords(gid, force_close=True)[source]

Visualise reordered GBCoords using Matplotlib or PyVista.

plot_user_gbcoords(gbcoords, lw=1.5)[source]

Visualise user gbcoords using Matplotlib or PyVista.

plot_user_gbcoords1(gbcoords, lw=1.5)[source]

Visualise user gbcoords1 using Matplotlib or PyVista.

construct_geometric_xtals_from_gbcoords(coord_loop_dict, dtype='shapely', saa=True, throw=False)[source]

self.construct_geometric_xtals_from_gbcoords(GBCoords).

construct_geometric_polyxtal_from_xtals(self.GRAINS.values(), dtype='shapely')[source]
construct_geometric_polyxtal_from_gbcoords(coord_loop_dict, dtype='shapely', saa=True, throw=False, plot_polyxtal=False, verbose=True)[source]

Construct geometric polyxtal from gbcoords.

AssembleGBSEGS(GB, saa=True, throw=False, verbose=True)[source]

Assemblegbsegs.

get_mids_gbsegs(gid)[source]

Return the mids gbsegs.

get_gbmid_indices_at_gid(gid, all_mids)[source]

Return the gbmid indices at gid.

smooth_gbsegs(GB, npasses=2, max_smooth_levels=[3, 3], plot=True, name='kali')[source]

Smooth gbsegs.

plotgs(gs_geometric, fig=None, ax=None, cmap='tab20', edgecolor='black', alpha=0.7, lw=1, figsize=(10, 10), dpi=100)[source]

Plotgs.

pxtal
neigh_gid
gbsegments_raw
gbsegments_mls
gbseg_smoothed
GBPOINTS
raster_img_polygonisation_results
neigh_pols
centroids_raw
centroids
xyoffset
grain_loc_ids
JNP
GBP
GBP_pure
GBP_at_boundary
jnp_all_coords
quality
sorted_segs
jnp_all_upxo
jnp_all_shapely
gbp_all_coords
gbp_all_upxo
gbp_all_shapely
jnp_grain_wise_indices
gbp_grain_wise_coords
gbp_grain_wise_indices
gbp_grain_wise_points
gbmullines_grain_wise
junction_points_coord
jnp_all_sorted_coords
jnp_all_sorted_upxo
gbsegments
gid_pair_ids
gid_pair_ids_unique_lr
gid_pair_ids_unique_rl
nconn
GBSEGMENTS
consolidated_segments
GB
GBCoords
GRAINS
POLYXTAL
mids_all_gbsegs
sgseg_obj_list
class upxo.pxtal.geometrification.VoronoiMasking(lfi)[source]

Bases: ABC

Abstract base class for Voronoi-based masking of a label field image (LFI).

map_seeds_to_lfi(channel=0)[source]

Samples the LFI at seed coordinates. Correctly handles the conversion from Cartesian (x, y) seeds to array indices (row, col) for sampling.

abstractmethod classmethod by_tessellation(lfi, seeds)[source]

Factory method to create instance via new Voronoi computation.

abstractmethod classmethod load_tessellation(lfi, filepath)[source]

Factory method to create instance from a saved geometry file.

abstractmethod assemble_cells()[source]

Dimension-specific: Shapely UnaryUnion vs PyVista Merge.

class upxo.pxtal.geometrification.GrainManifold2D(lfi)[source]

Bases: VoronoiMasking

2D grain manifold constructed by Voronoi tessellation and label field sampling.

classmethod by_tessellation(lfi, seeds, channel=0)[source]

By tessellation.

assemble_cells(polygons)[source]

Steps 5 & 6: Groups by ID and performs manifold union.

classmethod load_tessellation(lfi, filepath)[source]

Placeholder implementation to satisfy abstract requirement.

smooth_interfaces(iterations=10, lmbda=0.5, mu=-0.53, method='taubin', ma_window=3, corner_angle_deg=30.0, thin_grain_px=0.0)[source]

Smooth interfaces.

gb_smooth(ma_window=3, taubin_iter=10, lmbda=0.5, mu=-0.5, ma_smoother_version=2)[source]

Gb smooth.

apply_taubin_smoothing(iterations=10, lmbda=0.5, mu=-0.53)[source]

Step 8: Smooths interfaces while keeping triple points pinned.

trim_to_rve(bounds=(0, 0, 200, 200))[source]

Trims all grain geometries to the exact RVE bounding box. This ensures perfectly straight, rectangular external faces.

class upxo.pxtal.geometrification.GrainManifold3D(lfi)[source]

Bases: VoronoiMasking

classmethod by_tessellation(lfi, seeds, channel=0)[source]

By tessellation.

assemble_cells(solids)[source]

Assemble cells.