upxo.pxtal.mcgs2_temporal_slice module

Temporal-slice grain-structure operations for MCGS outputs.

This module defines the core per-time-slice data model used after Monte-Carlo grain-growth simulation and provides utilities for grain detection, characterization, neighborhood analysis, species partitioning, and grain merging workflows.

Imports

from upxo.pxtal.mcgs2_temporal_slice import mcgs2_grain_structure

Primary Classes

  • labeled_feature_image_2d

  • mcgs2_grain_structure

Classes of Operations

  • Grid and state setup:

    initialization of LFI/state containers, state-to-grain mappings, and per-slice bookkeeping.

  • Feature/grain detection:

    connected-component based detection, relabeling, and feature extraction from labelled images.

  • Morphological characterization:

    computation of grain/feature properties (area, axes, perimeter, moments, compactness, aspect ratio, etc.).

  • Neighborhood analysis:

    O(1)/higher-order neighbor extraction, fast neighbor approximations, and neighbor-driven querying.

  • Boundary and topology utilities:

    grain-boundary segment extraction, boundary/junction-point identification, and graph-ready grain-pair construction.

  • Species partitioning:

    state-combination and per-instance feature decomposition workflows.

  • Merge and threshold workflows:

    property-threshold based merge selection, merge execution, and post-merge renumbering/recount operations.

  • Property access and filtering:

    targeted property computation, retrieval, validation, and bounds-based grain-ID selection.

Definitions

  • LFI: Labelled Feature Image

  • gid/fid: Grain/Feature ID (1-based in most public APIs)

  • tslice: Monte-Carlo temporal slice

Metadata

  • Module: upxo.pxtal.mcgs2_temporal_slice

  • Package: upxo

  • Author: Dr. Sunil Anandatheertha

  • Email: vaasu.anandatheertha@ukaea.uk

  • Status: Active development

  • Last updated: 2026-03-12

upxo.pxtal.mcgs2_temporal_slice.get_neighbor_mask(arr, gid)

Mark pixels adjacent to a given grain ID.

Parameters:
  • arr (numpy.ndarray) – Integer array that is updated in place.

  • gid (int) – Grain ID to trace.

Returns:

The updated array, with non-gid 4-neighbours marked as -1 and all other non-marked values cleared to 0.

Return type:

numpy.ndarray

class upxo.pxtal.mcgs2_temporal_slice.labeled_feature_image_2d(lfi=None, ftypes=None, nfeatures=None, props_df=None)[source]

Bases: object

lfi
ftypes
nfeatures
props_df
class upxo.pxtal.mcgs2_temporal_slice.mcgs2_grain_structure(dim=2, m=None, uidata=None, S_total=None, px_size=None, xgr=None, ygr=None, zgr=None, uigrid=None, uimesh=None, EAPGLB=None, assign_ori_stack=False, assign_ori_slice=True, oripert_tc=True, oripert_gr=True)[source]

Bases: object

EPS = 1e-12
valid_skprop_names = ['area', 'area_bbox', 'area_convex', 'area_filled', 'axis_major_length', 'axis_minor_length', 'bbox', 'centroid', 'centroid_local', 'centroid_weighted', 'centroid_weighted_local', 'coords', 'coords_scaled', 'eccentricity', 'equivalent_diameter_area', 'euler_number', 'extent', 'feret_diameter_max', 'image', 'image_convex', 'image_filled', 'image_intensity', 'inertia_tensor', 'inertia_tensor_eigvals', 'intensity_max', 'intensity_mean', 'intensity_min', 'intensity_std', 'label', 'moments', 'moments_central', 'moments_hu', 'moments_normalized', 'moments_weighted', 'moments_weighted_central', 'moments_weighted_hu', 'moments_weighted_normalized', 'num_pixels', 'orientation', 'perimeter', 'perimeter_crofton', 'slice', 'solidity']
valid_morpho_props = ['area', 'area_bbox', 'area_convex', 'area_filled', 'axis_major_length', 'axis_minor_length', 'bbox', 'centroid', 'centroid_local', 'centroid_weighted', 'centroid_weighted_local', 'coords', 'coords_scaled', 'eccentricity', 'equivalent_diameter_area', 'euler_number', 'extent', 'feret_diameter_max', 'image', 'image_convex', 'image_filled', 'image_intensity', 'inertia_tensor', 'inertia_tensor_eigvals', 'intensity_max', 'intensity_mean', 'intensity_min', 'intensity_std', 'label', 'moments', 'moments_central', 'moments_hu', 'moments_normalized', 'moments_weighted', 'moments_weighted_central', 'moments_weighted_hu', 'moments_weighted_normalized', 'num_pixels', 'orientation', 'perimeter', 'perimeter_crofton', 'slice', 'solidity']
valid_topo_props = ['euler_characteristic', 'avg_nneigh', 'nneigh', 'n_vertices', 'n_boundaries', 'ntjp', 'nqp', 'nneigh_dist_P_n', 'aboav_weaire_params']
uinputs
val
dim
m
S
px_size
uigrid
uimesh
xgr
ygr
g
gb
info
EAPGLB
EASGLB
mp
scaled
scaled_gs
are_properties_available
display_messages
xomap
neigh_gid
species
valid_mprops
pxtal
set_grain_coords_dtype(dtype)[source]

Set the dtype used to store grain coordinates.

classmethod from_image(fdb=numpy.random.random, xmin=0, ymin=0, xinc=1, yinc=1, xmax=50, ymax=50)[source]

Create a structure instance from a 2D image and grid bounds.

Parameters:
  • fdb (numpy.ndarray, optional) – Image data used to build the grid.

  • xmin (int or float, optional) – Grid bounds and increments.

  • ymin (int or float, optional) – Grid bounds and increments.

  • xinc (int or float, optional) – Grid bounds and increments.

  • yinc (int or float, optional) – Grid bounds and increments.

  • xmax (int or float, optional) – Grid bounds and increments.

  • ymax (int or float, optional) – Grid bounds and increments.

Returns:

A new instance initialised from the supplied image data.

Return type:

mcgs2_grain_structure

property get_px_size

Return the configured pixel size.

set__s_n(S_total)[source]

Initialise the per-state grain-count list.

set__s_gid(S_total)[source]

Initialise the state-to-grain-ID mapping dictionary.

set__gid_s()[source]

Reset the grain-to-state mapping list.

set__spart_flag(S_total)[source]

Initialise per-state partitioning flags to False.

property lfi

Return the labelled feature image alias used by this class.

calc_num_grains(throw=False)[source]

Compute the number of grains from the current labelled image.

Parameters:

throw (bool, optional) – If True, return the computed grain count.

Returns:

The grain count when throw is True, otherwise None.

Return type:

int or None

get_property_bounded_grains(pnames=None, mprops=None, pvalue_thresholds=None)[source]

Return grain IDs whose property values lie outside the supplied bounds.

Parameters:
  • pnames (list) – Property names to evaluate.

  • mprops (dict) – Mapping of property names to per-grain value arrays.

  • pvalue_thresholds (dict) – Mapping of property names to [lower_threshold, upper_threshold].

Returns:

Grain IDs selected for each requested property.

Return type:

dict

Examples

pnames=['area', 'aspect_ratio', 'perimeter', 'solidity']
mprops = gsan.gsstack[gsid].get_mprops(pnames, set_missing_mprop=True)
pvalue_thresholds = {'area': [10, None], 'aspect_ratio': [2.0, None],
                    'perimeter': [15, None], 'solidity': [0.8, None]}
props_gids = self.get_propery_bounded_grains(mprops, pnames, pvalue_thresholds)
extract_neigh_props(gids, mprop)[source]

Extract neighbor grain IDs and property values for each requested grain.

Parameters:
  • gids (list or array-like) – Grain IDs to query.

  • mprop (dict or array-like) – Property values indexed by grain ID.

Returns:

Nested dictionaries keyed by input grain ID for neighbour IDs and their property values.

Return type:

dict

find_neigh(include_central_grain=False, print_msg=True, user_defined_bbox_ex_bounds=False, bbox_ex_bounds=None, update_grain_object=True, use_numba=False)[source]

Populate self.neigh_gid with neighbour IDs for every grain.

Parameters:
  • include_central_grain (bool, optional) – Include the central grain in each neighbour list.

  • print_msg (bool, optional) – Print progress information while computing neighbours.

  • user_defined_bbox_ex_bounds (bool, optional) – Use caller-supplied extended bounding boxes.

  • bbox_ex_bounds (dict, optional) – Extended bounding-box limits keyed by grain ID.

  • update_grain_object (bool, optional) – Update grain objects with neighbour information.

  • use_numba (bool, optional) – Use the numba-accelerated path when available.

Return type:

None

Examples

from upxo.ggrowth.mcgs import mcgs
pxtal = mcgs(study='independent', input_dashboard='input_dashboard_for_testing_50x50_alg202.xls')
pxtal.simulate()
pxtal.detect_grains()
tslice = 10
pxtal.gs[tslice].char_morph_2d(char_gb=True)

pxtal.gs[tslice].find_neigh(include_central_grain=True)
pxtal.gs[tslice].neigh_gid[10]

pxtal.gs[tslice].find_neigh(include_central_grain=False)
pxtal.gs[tslice].neigh_gid[10]
find_neigh_v2(p=1.0, include_central_grain=False, throw_numba_dict=False, verbosity_nfids=1000)[source]

Populate self.neigh_gid using the O(1) neighbour finder.

Parameters:
  • p (float, optional) – Neighbourhood expansion parameter passed to the backend helper.

  • include_central_grain (bool, optional) – Include the central grain in each neighbour list.

  • throw_numba_dict (bool, optional) – Return the raw numba dictionary when supported.

  • verbosity_nfids (int, optional) – Progress reporting frequency used by the backend helper.

Return type:

None

find_neigh_gid(fid, include_central_grain=False, update_grain_object=True, user_defined_bbox_ex_bounds=False, bbox_ex_bounds_fid=None, use_numba=False, get_gbsegs=False, save_gbsegs=False, throw_gbsegs=False, throw=False)[source]

Backward-compatible wrapper for neighOps.find_neigh_fid.

Parameters:
  • fid (int) – Feature or grain ID to query.

  • include_central_grain (bool, optional) – Include the queried grain in the returned neighbour list.

  • update_grain_object (bool, optional) – Update the underlying grain object.

  • user_defined_bbox_ex_bounds (bool, optional) – Use a caller-supplied extended bounding box.

  • bbox_ex_bounds_fid (object, optional) – Extended bounding-box limits for the queried feature.

  • use_numba (bool, optional) – Use the numba-accelerated implementation when available.

  • get_gbsegs (bool, optional) – Control grain-boundary segment handling and return behaviour.

  • save_gbsegs (bool, optional) – Control grain-boundary segment handling and return behaviour.

  • throw_gbsegs (bool, optional) – Control grain-boundary segment handling and return behaviour.

  • throw (bool, optional) – Control grain-boundary segment handling and return behaviour.

Returns:

Neighbour IDs when throw is True, otherwise None.

Return type:

list or None

From upxo.connops.neighbour_ops.find_neigh_fid: Find the neighbour IDs of a single grain and optionally its boundary segments.

Extracts the extended bounding-box sub-array for fid, constructs a neighbour mask (via Numba or pure Python depending on nfeatures), and returns the unique IDs of all directly touching grains. Grain-boundary segment maps can be generated and stored in the grain object’s sparse format.

Parameters:
  • gdict (dict) – Grain-object dictionary keyed by grain ID. Each value is either a grain object directly (_char_fx_version_=2) or a dict with a 'grain' key (_char_fx_version_=1).

  • lfi (numpy.ndarray of int, shape (R, C)) – Full labelled feature image for the grain structure.

  • fid (int) – Grain ID for which neighbours are to be found.

  • nfeatures (int) – Total number of grains in the structure. Governs the Numba/pure-Python branch threshold (Numba is used when nfeatures > 2000 or use_numba is True).

  • include_central_grain (bool, default False) – Include fid itself in the returned neighbour array.

  • update_grain_object (bool, default True) – Write the neighbour ID array into the grain object as grain.neigh.

  • user_defined_bbox_ex_bounds (bool, default False) – Use bbox_ex_bounds_fid instead of the bounding-box stored in the grain object.

  • bbox_ex_bounds_fid (tuple of int or None, default None) – (rmin, rmax, cmin, cmax) bounding-box extents to use when user_defined_bbox_ex_bounds is True.

  • use_numba (bool, default False) – Force use of NMB_get_neighbor_mask() regardless of nfeatures.

  • _char_fx_version_ ({1, 2}, default 2) – Selects how grain objects are accessed from gdict. Version 2 accesses grain attributes directly; version 1 assumes a nested dict with a 'grain' key.

  • get_gbsegs (bool, default True) – Compute the grain-boundary segment map (a 2D array where each non-zero pixel contains the neighbour grain’s ID at that boundary location).

  • save_gbsegs (bool, default False) – Serialise the boundary segment map into the grain object in sparse format (shape, NZI, NZV, dtype keys).

  • dtype_gbseg (numpy dtype, default numpy.int32) – Data type recorded in the sparse dtype field when saving segments.

  • throw (bool, default False) – Return neighbour_ids (or a tuple) instead of None.

  • throw_gbsegs (bool, default False) – When both get_gbsegs and throw_gbsegs are True, return (neighbour_ids, gbsegs) instead of neighbour_ids alone.

Returns:

  • None – When throw is False.

  • neighbour_ids (numpy.ndarray of int) – Unique IDs of all grains directly touching fid. Returned when throw is True and throw_gbsegs is False.

  • (neighbour_ids, gbsegs) (tuple) – Tuple of the neighbour ID array and the 2D boundary segment map. Returned when both throw and throw_gbsegs are True.

Notes

Grain-boundary segments are always stored in the grain object in sparse format (non-zero indices and values). To reconstruct the dense array use the lfi_gbsegs property of the grain object, or rebuild manually from the shape, NZI, and NZV fields.

Examples

Typical usage through the grain-structure object (which calls this function internally):

from upxo.ggrowth.mcgs import mcgs
pxtal = mcgs(input_dashboard='input_dashboard.xls')
pxtal.simulate()
pxtal.detect_grains()
tslice = 10
pxtal.gs[tslice].char_morph_2d(char_gb=True)
pxtal.gs[tslice].find_neigh(include_central_grain=False)
print(pxtal.gs[tslice].neigh_gid[10])

For direct use at module level:

import upxo.connops.neighbour_ops as neighOps
neigh_ids = neighOps.find_neigh_fid(
    gdict, lfi, fid=5, nfeatures=200,
    throw=True, throw_gbsegs=False)
find_neigh_fid(fid, include_central_grain=False, update_grain_object=True, user_defined_bbox_ex_bounds=False, bbox_ex_bounds_fid=None, use_numba=False, get_gbsegs=False, save_gbsegs=False, throw_gbsegs=False, throw=False)[source]

Delegate neighbour lookup to neighOps.find_neigh_fid.

Parameters:
  • fid (int) – Feature or grain ID to query.

  • include_central_grain (bool, optional) – Include the queried grain in the returned neighbour list.

  • update_grain_object (bool, optional) – Update the underlying grain object.

  • user_defined_bbox_ex_bounds (bool, optional) – Use a caller-supplied extended bounding box.

  • bbox_ex_bounds_fid (object, optional) – Extended bounding-box limits for the queried feature.

  • use_numba (bool, optional) – Use the numba-accelerated implementation when available.

  • get_gbsegs (bool, optional) – Control grain-boundary segment handling and return behaviour.

  • save_gbsegs (bool, optional) – Control grain-boundary segment handling and return behaviour.

  • throw_gbsegs (bool, optional) – Control grain-boundary segment handling and return behaviour.

  • throw (bool, optional) – Control grain-boundary segment handling and return behaviour.

Returns:

Neighbour IDs when throw is True, otherwise None.

Return type:

list or None

From upxo.connops.neighbour_ops.find_neigh_fid: Find the neighbour IDs of a single grain and optionally its boundary segments.

Extracts the extended bounding-box sub-array for fid, constructs a neighbour mask (via Numba or pure Python depending on nfeatures), and returns the unique IDs of all directly touching grains. Grain-boundary segment maps can be generated and stored in the grain object’s sparse format.

Parameters:
  • gdict (dict) – Grain-object dictionary keyed by grain ID. Each value is either a grain object directly (_char_fx_version_=2) or a dict with a 'grain' key (_char_fx_version_=1).

  • lfi (numpy.ndarray of int, shape (R, C)) – Full labelled feature image for the grain structure.

  • fid (int) – Grain ID for which neighbours are to be found.

  • nfeatures (int) – Total number of grains in the structure. Governs the Numba/pure-Python branch threshold (Numba is used when nfeatures > 2000 or use_numba is True).

  • include_central_grain (bool, default False) – Include fid itself in the returned neighbour array.

  • update_grain_object (bool, default True) – Write the neighbour ID array into the grain object as grain.neigh.

  • user_defined_bbox_ex_bounds (bool, default False) – Use bbox_ex_bounds_fid instead of the bounding-box stored in the grain object.

  • bbox_ex_bounds_fid (tuple of int or None, default None) – (rmin, rmax, cmin, cmax) bounding-box extents to use when user_defined_bbox_ex_bounds is True.

  • use_numba (bool, default False) – Force use of NMB_get_neighbor_mask() regardless of nfeatures.

  • _char_fx_version_ ({1, 2}, default 2) – Selects how grain objects are accessed from gdict. Version 2 accesses grain attributes directly; version 1 assumes a nested dict with a 'grain' key.

  • get_gbsegs (bool, default True) – Compute the grain-boundary segment map (a 2D array where each non-zero pixel contains the neighbour grain’s ID at that boundary location).

  • save_gbsegs (bool, default False) – Serialise the boundary segment map into the grain object in sparse format (shape, NZI, NZV, dtype keys).

  • dtype_gbseg (numpy dtype, default numpy.int32) – Data type recorded in the sparse dtype field when saving segments.

  • throw (bool, default False) – Return neighbour_ids (or a tuple) instead of None.

  • throw_gbsegs (bool, default False) – When both get_gbsegs and throw_gbsegs are True, return (neighbour_ids, gbsegs) instead of neighbour_ids alone.

Returns:

  • None – When throw is False.

  • neighbour_ids (numpy.ndarray of int) – Unique IDs of all grains directly touching fid. Returned when throw is True and throw_gbsegs is False.

  • (neighbour_ids, gbsegs) (tuple) – Tuple of the neighbour ID array and the 2D boundary segment map. Returned when both throw and throw_gbsegs are True.

Notes

Grain-boundary segments are always stored in the grain object in sparse format (non-zero indices and values). To reconstruct the dense array use the lfi_gbsegs property of the grain object, or rebuild manually from the shape, NZI, and NZV fields.

Examples

Typical usage through the grain-structure object (which calls this function internally):

from upxo.ggrowth.mcgs import mcgs
pxtal = mcgs(input_dashboard='input_dashboard.xls')
pxtal.simulate()
pxtal.detect_grains()
tslice = 10
pxtal.gs[tslice].char_morph_2d(char_gb=True)
pxtal.gs[tslice].find_neigh(include_central_grain=False)
print(pxtal.gs[tslice].neigh_gid[10])

For direct use at module level:

import upxo.connops.neighbour_ops as neighOps
neigh_ids = neighOps.find_neigh_fid(
    gdict, lfi, fid=5, nfeatures=200,
    throw=True, throw_gbsegs=False)
property neigh_fid

Return the neighbour-ID dictionary used for backward compatibility.

find_extended_bounding_box(fid, make_binary=False)[source]

Return the extended bounding box for a single feature ID.

This delegates to upxo.pxtalops.grid_ops.find_feature_extended_bbox_pix().

Returns:

Extended bounding-box mask for the requested feature.

Return type:

numpy.ndarray

find_extended_bounding_box_all_grains(make_binary=False)[source]

Return extended bounding boxes for all grains.

Returns:

Extended bounding-box masks for every grain ID.

Return type:

numpy.ndarray

find_extended_bounding_box_fids(fids=None, make_binary=False)[source]

Return extended bounding boxes for the requested grain IDs.

Returns:

Extended bounding-box masks for the requested grain IDs.

Return type:

numpy.ndarray

assign_species(method='mc state partitioned global combined', ignore_vf=True, vf={}, spid=1, combineids=[], ninstances=10, detect_features=True, bso=1, characterise_features=True, make_feature_skprops=True, extract_feature_coords=True, throw_feature_bounding_box=True)[source]

Assign species based on state partitioning methods. :param method: Method for state partitioning. Default is ‘mc state partitioned global combined’. :type method: str, optional :param ignore_vf: Whether to ignore volume fractions. Default is True. :type ignore_vf: bool, optional :param vf: Volume fractions for each state. Default is an empty dict. :type vf: dict, optional :param spid: Species ID. Default is 1. :type spid: int, optional :param combineids: List of state combinations for partitioning. Default is an empty list. :type combineids: list of list of int, optional :param ninstances: Number of instances to create. Default is 10. :type ninstances: int, optional :param detect_features: Whether to detect features in the image. Default is True. :type detect_features: bool, optional :param bso: Binary structure order for feature detection. Default is 1. :type bso: int, optional :param characterise_features: Whether to characterise detected features. Default is True. :type characterise_features: bool, optional :param make_feature_skprops: Whether to create scikit-image regionprops for features. Default is True. :type make_feature_skprops: bool, optional :param extract_feature_coords: Whether to extract feature coordinates. Default is True. :type extract_feature_coords: bool, optional :param throw_feature_bounding_box: Whether to throw bounding box for features. Default is True. :type throw_feature_bounding_box: bool, optional

Return type:

None

Examples

from upxo.ggrowth.mcgs import mcgs
pxtal = mcgs(study='independent',
             input_dashboard='input_dashboard_for_testing_50x50_alg202.xls')
pxtal.simulate()
pxtal.detect_grains()
tslice = 10
pxtal.gs[tslice].assign_species(method='mc state partitioned global combined',
                                ignore_vf=True, vf={}, spid=1,
                                combineids=[[1,2],[3,4]], ninstances=5,
                                detect_features=True, bso=1, characterise_features=True,
                                make_feature_skprops=True, extract_feature_coords=True,
                                throw_feature_bounding_box=True)
extract_feature_properties(skprops={}, area=True, eq_diameter=False, feret_diameter=False, perimeter=False, perimeter_crofton=False, npixels_gb=False, gb_length_px=False, major_axis_length=True, minor_axis_length=True, aspect_ratio=False, compactness=False, solidity=False, morph_ori=False, circularity=False, eccentricity=False, euler_number=True, moments_hu=True)[source]

Extract feature properties from skprops.

Parameters:
  • skprops (dict) – Dictionary with feature IDs as keys and their scikit-image regionprops as values.

  • area (bool, optional) – Whether to extract area property. Default is True.

  • eq_diameter (bool, optional) – Whether to extract equivalent diameter property. Default is False.

  • feret_diameter (bool, optional) – Whether to extract feret diameter property. Default is False.

  • perimeter (bool, optional) – Whether to extract perimeter property. Default is False.

  • perimeter_crofton (bool, optional) – Whether to extract perimeter crofton property. Default is False.

  • npixels_gb (bool, optional) – Whether to extract number of pixels in grain boundary property. Default is False.

  • gb_length_px (bool, optional) – Whether to extract grain boundary length in pixels property. Default is False.

  • major_axis_length (bool, optional) – Whether to extract major axis length property. Default is True.

  • minor_axis_length (bool, optional) – Whether to extract minor axis length property. Default is True.

  • aspect_ratio (bool, optional) – Whether to extract aspect ratio property. Default is False.

  • compactness (bool, optional) – Whether to extract compactness property. Default is False.

  • solidity (bool, optional) – Whether to extract solidity property. Default is False.

  • morph_ori (bool, optional) – Whether to extract morphological orientation property. Default is False.

  • circularity (bool, optional) – Whether to extract circularity property. Default is False.

  • eccentricity (bool, optional) – Whether to extract eccentricity property. Default is False.

  • euler_number (bool, optional) – Whether to extract euler number property. Default is True.

  • moments_hu (bool, optional) – Whether to extract Hu moments property. Default is True.

Returns:

mprops – Dictionary with property names as keys and their corresponding values as numpy arrays.

Return type:

dict

Examples

skprops, bbox_limits_ex, bboxes_ex, coords_dict = mcharOps.characterise_features_in_image_2d(labelled_image, Xgrid, Ygrid,
                               make_skprops=True, extract_coords=True,
                               throw_bounding_box=True
                               )
mprops = self.extract_feature_properties(skprops=skprops, area=True, eq_diameter=False,
                           feret_diameter=False, perimeter=False,  perimeter_crofton=False,
                           npixels_gb=False, gb_length_px=False, major_axis_length=True,
                           minor_axis_length=True, aspect_ratio=False, compactness=False,
                           solidity=False,  morph_ori=False, circularity=False,
                           eccentricity=False, euler_number=True, moments_hu=True,)
find_neigh_gid_fast(gid, include_parent=False, return_type='tuple')[source]

Find neighbouring grains of a given gid.

Parameters:
  • gid (int) – Grain ID for which to find neighbours.

  • include_parent (bool, optional) – Whether to include the parent gid in the neighbours list. Default is False.

  • return_type (str, optional) – Type of return value: ‘tuple’ or ‘list’. Default is ‘tuple’.

Returns:

Neighbouring grain IDs.

Return type:

tuple or list

Examples

from upxo.ggrowth.mcgs import mcgs
pxtal = mcgs(study='independent',
             input_dashboard='input_dashboard_for_testing_50x50_alg202.xls')
pxtal.simulate()
pxtal.detect_grains()
np.unique(pxtal.gs[16].find_extended_bounding_box(10))
pxtal.gs[10].find_neigh_gid_fast(10)
find_neigh_gid_fast_all_grains(include_parent=False, saa=True, throw=False)[source]

Find neighbouring grains for all gids.

Parameters:
  • include_parent (bool, optional) – Whether to include the parent gid in the neighbours list. Default is False.

  • saa (bool, optional) – Whether to store the result as an attribute. Default is True.

  • throw (bool, optional) – Whether to return the result. Default is False.

Returns:

Dictionary with grain IDs as keys and their neighbouring grain IDs as values.

Return type:

dict

Examples

from upxo.ggrowth.mcgs import mcgs
pxtal = mcgs(study='independent',
             input_dashboard='input_dashboard_for_testing_50x50_alg202.xls')
pxtal.simulate()
pxtal.detect_grains()
np.unique(pxtal.gs[16].find_extended_bounding_box(10))
pxtal.gs[10].find_neigh_gid_fast_all_grains(include_parent=False)
pxtal.gs[10].neigh_gid
get_upto_nth_order_neighbors(grain_id, neigh_order, fast_estimate=False, recalculate=False, include_parent=True, output_type='list')[source]

Calculates the nth order neighbours for a given gid.

Parameters:
  • grain_id (int) – The ID of the grain for which to find neighbors.

  • neigh_order (int) – The order of neighbors to calculate (1st order, 2nd order, etc.).

  • fast_estimate (bool, optional) – Whether to use a fast estimation method. Default is False.

  • recalculate (bool, optional) – Whether to recalculate neighbors even if they are already computed. Default is False.

  • include_parent (bool, optional) – Whether to include the parent grain ID in the neighbors list. Default is True.

  • output_type (str, optional) – The type of output: ‘list’, ‘nparray’, or ‘set’. Default is ‘list’.

Returns:

Neighbors of the specified order.

Return type:

list, np.ndarray, or set

Examples

from upxo.ggrowth.mcgs import mcgs
# pxtal = mcgs(study='independent', input_dashboard='input_dashboard_for_testing_50x50_alg202.xls')
pxtal = mcgs(study='independent', input_dashboard='input_dashboard.xls')
pxtal.simulate()
pxtal.detect_grains()
tslice = 18
pxtal.gs[tslice].char_morph_2d(char_gb=True)
neigh_order = 3
gid = 6
neighbours = pxtal.gs[tslice].get_upto_nth_order_neighbors(gid, neigh_order,
                                              fast_estimate=False,
                                              recalculate=True,
                                              include_parent=True,
                                              output_type='list')
pxtal.gs[tslice].neigh_gid[gid]

pxtal.gs[tslice].plot_grains_gids(pxtal.gs[tslice].gid, gclr='color', title='')
pxtal.gs[tslice].plot_grains_gids([gid], gclr='color', title='parent gid: '+str(gid))
pxtal.gs[tslice].plot_grains_gids(neighbours, gclr='color', cmap_name='nipy_spectral')
get_nth_order_neighbors(grain_id, neigh_order, fast_estimate=False, recalculate=False, include_parent=True)[source]

Calculates the 1st till nth order neighbours for a given gid.

Parameters:
  • grain_id (int) – The ID of the grain for which to find neighbors.

  • neigh_order (int) – The order of neighbors to calculate (1st order, 2nd order, etc.).

  • fast_estimate (bool, optional) – Whether to use a fast estimation method. Default is False.

  • recalculate (bool, optional) – Whether to recalculate neighbors even if they are already computed. Default is False.

  • include_parent (bool, optional) – Whether to include the parent grain ID in the neighbors list. Default is True.

Returns:

A list containing the nth order neighbors.

Return type:

list

Examples

from upxo.ggrowth.mcgs import mcgs pxtal = mcgs(study=’independent’, input_dashboard=’input_dashboard.xls’) pxtal.simulate() pxtal.detect_grains() gid = 10 tslice = 16 neigh_order = 6 neighbours = pxtal.gs[tslice].get_nth_order_neighbors(gid, neigh_order,

fast_estimate=False, recalculate=True, include_parent=True)

pxtal.gs[tslice].plot_grains_gids(neighbours, gclr=’color’)

get_upto_nth_order_neighbors_all_grains(neigh_order, recalculate=False, fast_estimate=False, include_parent=True, output_type='list')[source]

Calculates 1st to nth order neighbors of all gids.

Parameters:
  • neigh_order (int) – The order of neighbors to calculate (1st order, 2nd order, etc.).

  • recalculate (bool, optional) – Whether to recalculate neighbors even if they are already computed. Default is False.

  • fast_estimate (bool, optional) – Whether to use a fast estimation method. Default is False.

  • include_parent (bool, optional) – Whether to include the parent grain ID in the neighbors list. Default is True.

  • output_type (str, optional) – The type of output: ‘list’, ‘nparray’, or ‘set’. Default is ‘list’.

Returns:

Dictionary with grain IDs as keys and their neighbors of specified order as values.

Return type:

dict

Examples

from upxo.ggrowth.mcgs import mcgs
pxtal = mcgs(study='independent',
             input_dashboard='input_dashboard_for_testing_50x50_alg202.xls')
pxtal.simulate()
pxtal.detect_grains()
neigh_order = 1
pxtal.gs[16].get_upto_nth_order_neighbors_all_grains(neigh_order,
                                                     recalculate=False,
                                                     include_parent=True,
                                                     output_type='list')
get_nth_order_neighbors_all_grains(neigh_order, fast_estimate=False, recalculate=False, include_parent=True)[source]

Calculates the nth order neighbours of all gids.

Parameters:
  • neigh_order (int) – The order of neighbors to calculate (1st order, 2nd order, etc.).

  • fast_estimate (bool, optional) – Whether to use a fast estimation method. Default is False.

  • recalculate (bool, optional) – Whether to recalculate neighbors even if they are already computed. Default is False.

  • include_parent (bool, optional) – Whether to include the parent grain ID in the neighbors list. Default is True.

Returns:

Dictionary with grain IDs as keys and their neighbors of specified order as values.

Return type:

dict

Examples

from upxo.ggrowth.mcgs import mcgs pxtal = mcgs(study=’independent’, input_dashboard=’input_dashboard.xls’) pxtal.simulate() pxtal.detect_grains() tslice = 99 pxtal.gs[tslice].char_morph_2d(char_gb=True)

no_clr = [‘k’, ‘b’, ‘r’, ‘g’] no_mrk = [‘o’, ‘s’, ‘x’, ‘+’] no_msz = [8, 8, 8, 8] gb_clr = [‘k’, ‘b’, ‘r’, ‘g’]

cg = 1 NO = [2] ANO = [None, None, None] plt.figure(figsize=(5, 5), dpi=100) for no in NO:

A = pxtal.gs[tslice].get_nth_order_neighbors_all_grains(no,

fast_estimate=False, recalculate=False, include_parent=True,)

for gid in A[cg]:
plt.plot(*np.roll(pxtal.gs[tslice].g[gid][‘grain’].gbloc, 1, axis=1).T,

gb_clr[no]+’.’, markersize=2)

gidcentroid = pxtal.gs[tslice].g[gid][‘grain’].centroid plt.plot(*gidcentroid, no_clr[no]+no_mrk[no],

markersize=no_msz[no])

plt.plot(*np.roll(pxtal.gs[tslice].g[cg][‘grain’].gbloc, 1, axis=1).T,

‘c.’, markersize=4)

cgcentroid = pxtal.gs[tslice].g[cg][‘grain’].centroid plt.plot(*cgcentroid, no_clr[0]+no_mrk[0],

markersize=no_msz[0])

plt.gca().set_aspect(‘equal’)

cg = 10 # central_grain neigh_order = 1 A = pxtal.gs[tslice].get_upto_nth_order_neighbors_all_grains(neigh_order,

recalculate=False, include_parent=True, output_type=’list’)

A = pxtal.gs[tslice].get_nth_order_neighbors_all_grains(neigh_order,

recalculate=False, include_parent=True,)

pxtal.gs[tslice].plot_grains_gids(A[cg], gclr=’color’, title=”user grains”,

cmap_name=’CMRmap_r’, )

neigh_order = 2 A = pxtal.gs[tslice].get_upto_nth_order_neighbors_all_grains(neigh_order,

recalculate=False, include_parent=True, output_type=’list’)

A = pxtal.gs[tslice].get_nth_order_neighbors_all_grains(neigh_order,

recalculate=False, include_parent=True,)

pxtal.gs[tslice].plot_grains_gids(A[cg], gclr=’color’, title=”user grains”,

cmap_name=’CMRmap_r’, )

neigh_order = 3 A = pxtal.gs[tslice].get_upto_nth_order_neighbors_all_grains(neigh_order,

recalculate=False, include_parent=True, output_type=’list’)

A = pxtal.gs[tslice].get_nth_order_neighbors_all_grains(neigh_order,

recalculate=False, include_parent=True,)

pxtal.gs[tslice].plot_grains_gids(A[cg], gclr=’color’, title=”user grains”,

cmap_name=’CMRmap_r’, )

# —————————————– no_clr = [‘k’, ‘b’, ‘k’, ‘k’] no_mrk = [‘o’, ‘s’, ‘x’, ‘+’] no_msz = [8, 8, 8, 8]

plt.figure(figsize=(5, 5), dpi=100) for gid in A[cg]:

plt.plot(*np.roll(pxtal.gs[tslice].g[gid][‘grain’].gbloc, 1, axis=1).T,

‘k.’, markersize=3)

gidcentroid = pxtal.gs[tslice].g[gid][‘grain’].centroid plt.plot(*gidcentroid, no_clr[neigh_order]+no_mrk[neigh_order],

markersize=no_msz[neigh_order])

plt.plot(*np.roll(pxtal.gs[tslice].g[cg][‘grain’].gbloc, 1, axis=1).T,

‘r.’, markersize=4)

cgcentroid = pxtal.gs[tslice].g[cg][‘grain’].centroid plt.plot(*cgcentroid, no_clr[0]+no_mrk[0],

markersize=no_msz[0])

plt.gca().set_aspect(‘equal’) # ================================================================= all_neighs = pxtal.gs[tslice].neigh_gid neigh_order = 1 cg = 17 plt.figure(figsize=(5, 5), dpi=100) for gid in all_neighs[cg]:

plt.plot(*np.roll(pxtal.gs[tslice].g[gid][‘grain’].gbloc, 1, axis=1).T,

‘k.’, markersize=3)

gidcentroid = pxtal.gs[tslice].g[gid][‘grain’].centroid plt.plot(*gidcentroid, no_clr[neigh_order]+no_mrk[neigh_order],

markersize=no_msz[neigh_order])

plt.plot(*np.roll(pxtal.gs[tslice].g[cg][‘grain’].gbloc, 1, axis=1).T,

‘r.’, markersize=4)

cgcentroid = pxtal.gs[tslice].g[cg][‘grain’].centroid plt.plot(*cgcentroid, no_clr[0]+no_mrk[0],

markersize=no_msz[0])

plt.gca().set_aspect(‘equal’)

get_upto_nth_order_neighbors_all_grains_prob(neigh_order, recalculate=False, include_parent=False, print_msg=False, _int_approx_=0.05)[source]

Calculates 1st to nth order neighbors of all gids. Allows float values for neigh_order for probabilistic selection.

Parameters:
  • neigh_order (int or float) – The order of neighbors to calculate (1st order, 2nd order, etc.). If float, probabilistic selection is done between floor and ceil values.

  • recalculate (bool, optional) – Whether to recalculate neighbors even if they are already computed. Default is False.

  • include_parent (bool, optional) – Whether to include the parent grain ID in the neighbors list. Default is False.

  • print_msg (bool, optional) – Whether to print messages during execution. Default is False.

  • _int_approx_ (float, optional) – Threshold to consider a float as an integer. Default is 0.05.

Returns:

Dictionary with grain IDs as keys and their neighbors of specified order as values.

Return type:

dict

Examples

from upxo.ggrowth.mcgs import mcgs
pxt = mcgs()
pxt.simulate()
pxt.detect_grains()
tslice = 10
def_neigh = pxt.gs[tslice].get_upto_nth_order_neighbors_all_grains_prob

neigh0 = def_neigh(1, recalculate=False, include_parent=True)
neigh1 = def_neigh(1.06, recalculate=False, include_parent=True)
neigh2 = def_neigh(1.5, recalculate=False, include_parent=True)
neigh0[22]   # list of neighbours of grain 22 at order 1
neigh1[22]   # probabilistic blend for grain 22 (order ~1.06)
neigh2[22]   # probabilistic blend for grain 22 (order ~1.5)
char_morph_2d(use_characterization_settings=False, use_version=1, bso=1, def_feat_name='grain', bbox=True, bbox_ex=True, npixels=False, npixels_gb=False, identify_pixel_locations=True, area=False, eq_diameter=False, perimeter=False, perimeter_crofton=False, compactness=False, gb_length_px=False, aspect_ratio=False, solidity=False, morph_ori=False, circularity=False, eccentricity=False, feret_diameter=False, major_axis_length=False, minor_axis_length=False, euler_number=False, moments_hu=True, append=False, saa=True, throw=False, char_grain_positions=False, find_neigh=False, char_gb=False, make_skim_prop=False, get_grain_coords=True)[source]

Characterize the 2D grain structure and populate grain properties.

This is the main morphology-characterisation entry point and delegates to the versioned implementation selected by use_version.

char_morph_2d_v1(use_characterization_settings=False, bbox=True, bbox_ex=True, npixels=False, npixels_gb=False, identify_pixel_locations=True, area=False, eq_diameter=False, perimeter=False, perimeter_crofton=False, compactness=False, gb_length_px=False, aspect_ratio=False, solidity=False, morph_ori=False, circularity=False, eccentricity=False, feret_diameter=False, major_axis_length=False, minor_axis_length=False, euler_number=False, moments_hu=True, append=False, saa=True, throw=False, char_grain_positions=False, find_neigh=False, char_gb=False, make_skim_prop=False, get_grain_coords=True, make_pd=True)[source]

This method allows user to calculate morphological parameters of a given grain structure slice.

Parameters:
  • use_characterization_settings (bool, optional) – Whether to use pre-defined characterization settings. Default is False.

  • bbox (bool, optional) – Whether to extract bounding box property. Default is True.

  • bbox_ex (bool, optional) – Whether to extract extended bounding box property. Default is True.

  • npixels (bool, optional) – Whether to extract number of pixels property. Default is False.

  • npixels_gb (bool, optional) – Whether to extract number of grain boundary pixels property. Default is False.

  • area (bool, optional) – Whether to extract area property. Default is False.

  • eq_diameter (bool, optional) – Whether to extract equivalent diameter property. Default is False.

  • perimeter (bool, optional) – Whether to extract perimeter property. Default is False.

  • perimeter_crofton (bool, optional) – Whether to extract perimeter (Crofton) property. Default is False.

  • compactness (bool, optional) – Whether to extract compactness property. Default is False.

  • gb_length_px (bool, optional) – Whether to extract grain boundary length in pixels property. Default is False.

  • aspect_ratio (bool, optional) – Whether to extract aspect ratio property. Default is False.

  • solidity (bool, optional) – Whether to extract solidity property. Default is False.

  • morph_ori (bool, optional) – Whether to extract morphological orientation property. Default is False.

  • circularity (bool, optional) – Whether to extract circularity property. Default is False.

  • eccentricity (bool, optional) – Whether to extract eccentricity property. Default is False.

  • feret_diameter (bool, optional) – Whether to extract feret diameter property. Default is False.

  • major_axis_length (bool, optional) – Whether to extract major axis length property. Default is False.

  • minor_axis_length (bool, optional) – Whether to extract minor axis length property. Default is False.

  • euler_number (bool, optional) – Whether to extract euler number property. Default is False.

  • moments_hu (bool, optional) – Whether to extract Hu moments property. Default is True.

  • append (bool, optional) – Whether to append to existing properties. Default is False.

  • saa (bool, optional) – Whether to store as attribute. Default is True.

  • throw (bool, optional) – Whether to return the properties. Default is False.

  • char_grain_positions (bool, optional) – Whether to characterize grain positions. Default is False.

  • find_neigh (bool, optional) – Whether to find neighboring grains. Default is False.

  • char_gb (bool, optional) – Whether to characterize grain boundaries. Default is False.

  • make_skim_prop (bool, optional) – Whether to make skim properties. Default is False.

  • get_grain_coords (bool, optional) – Whether to get grain coordinates. Default is True.

char_morph_2d_v2(bso=1, def_feat_name='grain', bbox=True, bbox_ex=True, npixels=False, npixels_gb=False, identify_pixel_locations=True, area=False, eq_diameter=False, perimeter=False, perimeter_crofton=False, compactness=False, gb_length_px=False, aspect_ratio=False, solidity=False, morph_ori=False, circularity=False, eccentricity=False, feret_diameter=False, major_axis_length=False, minor_axis_length=False, euler_number=False, moments_hu=True, char_gb=False, char_grain_positions=False, find_neigh=True, make_skim_prop=False, get_grain_coords=True, append=False, saa=True, throw=False, make_pd=True, _redo_lgi_=False, make_grain_object=True)[source]

Characterize the 2D grain structure using the version-2 workflow.

This implementation detects features, builds grain objects, and optionally computes morphology, neighbourhoods, and grain positions.

build_grain_pairs(neigh_gid)[source]

Build unique grain pairs from the neighbour list.

pad_lfi()[source]

Return the labelled feature image padded for boundary operations.

find_gb(gsimage, plot_gb=False, figsize=(6, 6), dpi=100, cmap='nipy_spectral')[source]

Return grain-boundary pixels for gsimage using the grid helper.

segment_gb(gsimage, gbimage, neigh_fid, connectivity=8)[source]

Segment grain-boundary pixels for the specified neighbouring grain IDs.

make_gbsegImage(gbMask, segments, nsegments, neigh_fid)[source]

Build and return a grain-boundary segment image.

see_all_gbsegs(gbsegImage)[source]

Visualise all grain-boundary segments in gbsegImage.

see_gbsegs_fid(gbsegImage, fid)[source]

Visualise the grain-boundary segments for a specific grain ID.

findJP(segments)[source]

Return grain-boundary junction points for the given segments.

separate_junctions_by_order(segments)[source]

Group junction points by their order.

see_gbsegs_jp_by_jpo(gbsegs, jps_by_order, style_by_order=None, default_style=None, figsize=(5, 5), dpi=80, legend_anchor=(1.02, 1.0), ms2=4, ms3=4, ms4=4, ms5=4, legend_loc='upper left', legend_title='Junction point data', legend_frameon=True, hide_axis=True, cmap='rainbow')[source]

Visualise grain-boundary segments together with junctions by order.

make_graph(neigh_gid)[source]

Create a graph representation from the neighbor list.

Parameters:

neigh_gid (dict) – Dictionary where key is grain ID and value is list of neighbor grain IDs.

Returns:

Graph representation of the grain neighbors.

Return type:

graph

identify_grain_boundary_pixels(grain_pairs)[source]

Identify grain boundary pixels for the specified grain pairs.

plot_boundaries_standalone(gb_dict)[source]

Plot grain boundaries from the provided dictionary of boundary coordinates.

Parameters:

gb_dict (dict) – Dictionary where: - Key: tuple (grain_id1, grain_id2) as standard Python ints (sorted) - Value: Nx2 NumPy array of coordinates (float64)

find_grain_boundary_junction_points(xorimap=False, IN=None)[source]

Identify grain boundary junction points in the microstructure. :param xorimap: If True, the junction points will be calculated for the

instance number IN in the pxtal dictionary. If False, junction points will be calculated for the current instance. Default is False.

Parameters:

IN (int, optional) – Instance number in the pxtal dictionary for which junction points are to be calculated if xorimap is True. Default is None.

do_single_pixel_grains_exist()[source]

Return True when any single-pixel grains are present.

do_straightline_grains_exist()[source]

Check if any straight-line grains exist in the grain structure.

Straight-line grains are grains that are only one pixel wide in at least one dimension, excluding single-pixel grains. These are identified by having a minor axis length of zero when trying to fit an ellipse.

Returns:

True if straight-line grains exist, False otherwise.

Return type:

bool

Notes

This method uses the straight_line_grains property which identifies grains where skimage cannot fit an ellipse due to unit pixel width. Single pixel grains are excluded from this check.

Examples

from upxo.ggrowth.mcgs import mcgs
pxt = mcgs(study='independent', input_dashboard='input_dashboard.xls')
pxt.simulate()
pxt.detect_grains()
tslice = 10
pxt.gs[tslice].char_morph_2d(make_skim_prop=True)
has_straight = pxt.gs[tslice].do_straightline_grains_exist()
print(f"Straight-line grains present: {has_straight}")

See also

straight_line_grains

Property that returns the IDs of straight-line grains

do_single_pixel_grains_exist

Check for single-pixel grains

single_pixel_grains

Property that returns the IDs of single-pixel grains

check_for_neigh(parent_gid, other_gid)[source]

Check if other_gid is indeed a O(1) neighbour of parent_gid.

Parameters:
  • parent_gid – Grain ID of the parent.

  • other_gid – Grain ID of the other grain being checked for O(1) neighbourhood with parent_gid.

Return type:

True if other_gid is a valid O(1) neighbour of parent_gid, else False.

get_two_rand_o1_neighs()[source]

Calculate at random, two neighbouring O(1) grains.

Examples

from upxo.ggrowth.mcgs import mcgs
mcgs = mcgs(study='independent', input_dashboard='input_dashboard.xls')
mcgs.simulate()
mcgs.detect_grains()
mcgs.gs[35].char_morph_2d()
mcgs.gs[35].find_neigh()
mcgs.gs[35].neigh_gid
mcgs.gs[35].get_two_rand_o1_neighs()
mcgs.gs[35].plot_two_rand_neighs(return_gids=True)
plot_two_rand_neighs(return_gids=True)[source]

Plot two random neighbouring grains.

Parameters:

return_gids (bool) – Flag to return the random neigh gid numbers. Defaults to True.

Returns:

rand_neigh_gids – random neigh gid numbers. Will be gids if return_gids is True. Else, will be [None, None].

Return type:

list

Examples

Please refer to use in the example provided for the definition,
get_two_rand_o1_neighs()
find_gids_by_mprop(mprop='area', method='at', distr_loc='mean', bounds=[(0, 2), (10, 15)], ineq_spec_lb='>=', ineq_spec_ub='<=', validate_ui=True, recalculate_area=False)[source]

Find grain IDs based on morphological property criteria.

Parameters:
  • mprop (str) – Morphological property to filter grains by.

  • method (str) – Method to use for filtering. Options are ‘at’ or ‘bounded’.

  • distr_loc (str) – Location statistic to use when method is ‘at’. Options are ‘mean’, ‘median’, ‘min’, ‘max’, or quantiles like ‘q1’, ‘q2’, ‘q3’.

  • ineq_spec_lb (str) – Inequality specification for lower bound when method is ‘bounded’. Options are ‘>’ or ‘>=’.

  • ineq_spec_ub (str) – Inequality specification for upper bound when method is ‘bounded’. Options are ‘<’ or ‘<=’.

  • bounds (list of tuples) – List of (lower_bound, upper_bound) tuples to use when method is ‘bounded’.

Returns:

Dictionary containing: - ‘mprop’: The morphological property used for filtering. - ‘method’: The method used for filtering. - ‘gids’: Numpy array of grain IDs that meet the specified criteria.

Return type:

dict

Examples

from upxo.ggrowth.mcgs import mcgs
pxt = mcgs(study='independent', input_dashboard='input_dashboard.xls')
pxt.simulate()
pxt.detect_grains()
tslice = 10
pxt.gs[tslice].char_morph_2d()
# Find grains with area close to mean area
mean_area_gids = pxt.gs[tslice].find_gids_by_mprop(mprop='area',
                                                   method='at',
                                                   distr_loc='mean')
print("Grain IDs with area close to mean area:", mean_area_gids)
# Find grains with area within specified bounds
bounded_area_gids = pxt.gs[tslice].find_gids_by_mprop(mprop='area',
                                                      method='bounded',
                                                      bounds=[(50, 100), (200, 300)])
print("Grain IDs with area within specified bounds:", bounded_area_gids)
thresholding(prop_type='mprop', threshold_type='lower', method='merge', bso=2, recalculate_neigh='all', update_grain_object=False, validate_ui=True, recursive_search_and_merge=True, niter=10, kwargs_lower_mprop_threshold={'ineq_spec_ub': '<=', 'pname': 'area', 'recalculate_mprop': True, 'sink_metric': 'mean', 'sink_select_uncertainty': [-5, 5], 'threshold': 1.0})[source]

Apply repeated threshold-based merge or erosion operations.

lower_mprop_thresholding(threshold=1.0, sink_metric='mean', method='merge', pname='area', bso=2, recalculate_mprop=True, ineq_spec_ub='<=', recalculate_neigh='all', update_grain_object=False, validate_ui=True, sink_select_uncertainty=[-5, 5], post_merge_ops_frequency=1, recursive_search_and_merge=True)[source]

Apply lower-threshold morphology-driven grain merging or erosion.

The operation selects grains whose property values fall below threshold and then uses neighbouring grains to choose merge sinks or perform erosion, depending on method.

merge_two_neigh_grains(parent_gid, other_gid, check_for_neigh=True, simple_merge=True)[source]

Merge other_gid grain to the parent_gid grain.

Parameters:
  • parent_gid – Grain ID of the parent.

  • other_gid – Grain ID of the other grain being merged into the parent.

  • check_for_neigh (bool.) – If True, other_gid will be checked if it can be merged to the parent grain. Defaults to True.

Returns:

merge_success – True, if successfully merged, else False.

Return type:

bool

perform_post_grain_merge_ops(merge_success, merged_gid)[source]

Run post-merge bookkeeping after a successful grain merge.

renumber_gid_post_grain_merge(merged_gid)[source]

Renumber grain IDs after a merge removed merged_gid.

recalculate_ngrains_post_grain_merge()[source]

Recompute the grain count after a merge.

renumber_lgi_post_grain_merge(merged_gid)[source]

Renumber the labelled grain image after a merge.

validate_propnames(mpnames, return_type='dict')[source]

Validate that each requested property name is supported.

Parameters:
  • mpnames (iterable) – Property names to validate.

  • return_type (str, optional) – Return a dictionary or a tuple of validation flags.

Returns:

Validation results for each property name.

Return type:

dict or tuple

Examples

self.validate_propnames(['area', 'perimeter', 'solidity'])
check_mpnamevals_exists(mpnames, return_type='dict')[source]

Check whether each requested property has already been computed.

Parameters:
  • mpnames (iterable) – Property names to check.

  • return_type (str, optional) – Return a dictionary or a sequence of boolean flags.

Returns:

Existence flags for each property name.

Return type:

dict or list or tuple

set_mprops(mpnames, char_grain_positions=True, char_gb=False, set_grain_coords=True, saa=True, throw=False)[source]

Compute and cache the requested morphology properties.

Parameters:
  • mpnames (iterable) – Property names to calculate.

  • char_grain_positions (bool, optional) – Update grain position classification.

  • char_gb (bool, optional) – Recompute grain-boundary geometry.

  • set_grain_coords (bool, optional) – Update stored grain coordinates.

  • saa (bool, optional) – Store computed properties on the instance.

  • throw (bool, optional) – Return computed property arrays.

Returns:

Requested property values when throw is True, otherwise None placeholders.

Return type:

dict

Examples

self.set_mprops(mpnames, recharacterize=True)
get_mprops(mpnames, set_missing_mprop=False)[source]

Return morphology-property arrays, computing missing ones if needed.

Parameters:
  • mpnames (iterable) – Property names to return.

  • set_missing_mprop (bool, optional) – Compute missing properties before returning values.

Returns:

Mapping of property name to numpy array or None.

Return type:

dict

Examples

from upxo.ggrowth.mcgs import mcgs
mcgs = mcgs(study='independent', input_dashboard='input_dashboard.xls')
mcgs.simulate()
mcgs.detect_grains()
mcgs.gs[mcgs.m[-1]].char_morph_2d(bbox=True, bbox_ex=True,
                             area=True,aspect_ratio=True,
                             make_skim_prop=True,)

mpnames=['area', 'aspect_ratio', 'perimeter', 'solidity']
mcgs.gs[mcgs.m[-1]].prop
mprop_values = mcgs.gs[mcgs.m[-1]].get_mprops(mpnames,
                                              set_missing_mprop=True)
mprop_values
validata_gids(gids)[source]

Return True when all requested grain IDs exist in self.gid.

get_gids_in_params_bounds(search_gid_source='all', search_gids=None, mpnames=['area', 'aspect_ratio', 'perimeter', 'solidity'], fx_stats=[numpy.mean, numpy.mean, numpy.mean, numpy.mean], pdslh=[[50, 50], [50, 50], [50, 50], [50, 50]], param_priority=[1, 2, 3, 2], plot_mprop=True)[source]

Get gids of grains whose morphological property values lie within user specified bounds.

Parameters:
  • search_gid_source (str) – Source of gids to be searched. Valid choices: ‘all’ : All gids in self.gid will be searched. ‘user’: Only user provided gids in search_gids will be searched.

  • search_gids (Iterable of ints) – User provided gids to be searched. Only valid if search_gid_source is ‘user’.

  • mpnames (dth.dt.ITERABLES) – List of user specified names of morphological properties.

  • fx_stats (dth.dt.ITERABLES) – List of functions to compute the statistic of the morphological property. The length of fx_stats must be same as length of mpnames. Valid functions include numpy functions like np.mean, np.median, np.std, etc.

  • pdslh (dth.dt.ITERABLES) – List of lists containing percentages of distance from stat to minimum and stat to maximum. The length of pdslh must be same as length of mpnames. Each element of pdslh must be a list of two numbers. The first number is percentage of distance from stat to minimum and the second number is percentage of distance from stat to maximum.

  • param_priority (dth.dt.ITERABLES) – List of integers specifying the priority of each morphological property. The length of param_priority must be same as length of mpnames. Higher the number, higher the priority.

  • plot_mprop (bool) – If True, plots the morphological property maps with bounds indicated in the title.

Returns:

  • GIDs (dict) – Dictionary containing the following keys: ‘intersection’: List of gids that lie within the bounds of all

    morphological properties.

    ’union’: List of gids that lie within the bounds of at least one

    morphological property.

    ’presence’: Dictionary with gids as keys and number of

    morphological properties that the gid lies within bounds as values.

    ’mpmapped’: Dictionary with morphological property names as keys

    and list of gids that lie within the bounds of the morphological property as values.

  • VALIND (dict) – Dictionary containing the following keys: ‘stat’: Dictionary with morphological property names as keys and

    their corresponding statistic values as values.

    ’statmap’: List of functions used to compute the statistic of

    each morphological property.

    ’bounds’: Dictionary with morphological property names as keys

    and their corresponding bounds as values.

    ’indices’: Dictionary with morphological property names as keys

    and list of indices of grains that lie within the bounds of the morphological property as values.

Example

get_gid_mprop_map(mpropname, querry_gids)[source]

Map a morphology property onto the requested grain IDs.

Parameters:
  • mpropname (str) – Property name to extract.

  • querry_gids (iterable) – Grain IDs to map.

Returns:

Grain-ID to property-value mapping.

Return type:

dict

map_scalar_to_lgi(scalars_dict, default_scalar=-1, plot=True, throw_axis=True, plot_centroid=True, plot_gid_number=True, title='title', centroid_kwargs={'marker': 'o', 'mec': 'black', 'mfc': 'yellow', 'ms': 2.5}, gid_text_kwargs={'fontsize': 10}, title_kwargs={'fontsize': 10}, label_kwargs={'fontsize': 10})[source]

Map to LGI, the gid keyed values in scalars_dict.

Parameters:
  • scalars_dict (dict) – Dictionary with gids as keys and scalar values as values.

  • default_scalar (float) – Default scalar value to be assigned to gids not in scalars_dict. Defaults to -1.

  • plot (bool) – If True, plot the mapped LGI. Defaults to True.

  • throw_axis (bool) – If True, returns the axis object along with the mapped LGI. Defaults to True.

  • plot_centroid (bool) – If True, plots the centroids of the grains. Defaults to True.

  • plot_gid_number (bool) – If True, plots the gid number at the centroid of the grains. Defaults to True.

  • title (str) – Title of the plot. Defaults to ‘title’.

  • centroid_kwargs (dict) – Keyword arguments for plotting centroids. Defaults to {‘marker’: ‘o’, ‘mfc’: ‘yellow’, ‘mec’: ‘black’, ‘ms’: 2.5}.

  • gid_text_kwargs (dict) – Keyword arguments for plotting gid numbers. Defaults to {‘fontsize’: 10}.

  • title_kwargs (dict) – Keyword arguments for the plot title. Defaults to {‘fontsize’: 10}.

  • label_kwargs (dict) – Keyword arguments for the plot labels. Defaults to {‘fontsize’: 10}.

Returns:

result – Dictionary with the following keys: ‘lgi’: Mapped LGI as a numpy array. ‘ax’: Axis object if throw_axis is True, else None.

Return type:

dict

Examples

from upxo.ggrowth.mcgs import mcgs
pxt = mcgs()
pxt.simulate()
pxt.detect_grains()
tslice = 10
def_neigh = pxt.gs[tslice].get_upto_nth_order_neighbors_all_grains_prob

neigh1 = def_neigh(1.38, recalculate=False, include_parent=True)

sf_no = pxt.gs[tslice]

from upxo.growth.mcgs import mcgs
mcgs = mcgs(study='independent', input_dashboard='input_dashboard.xls')
mcgs.simulate()
mcgs.detect_grains()
mcgs.gs[35].char_morph_2d(bbox=True, bbox_ex=True, area=True,
                          aspect_ratio=True,
                          make_skim_prop=True,)
GIDs, VALIND = mcgs.gs[35].get_gids_in_params_bounds(mpnames=['aspect_ratio', 'area'],
                                      fx_stats=[np.mean, np.mean],
                                      pdslh=[[50, 30], [50, 30]], plot_mprop=False
                                      )
mcgs.gs[35].map_scalar_to_lgi(GIDs['presence'], default_scalar=-1,
                      plot=True, throw_axis=True)

gid_mprop_map = mcgs.gs[35].get_gid_mprop_map('aspect_ratio',
                                              GIDs['mpmapped']['aspect_ratio'])
MPLGIAX = mcgs.gs[35].map_scalar_to_lgi(gid_mprop_map, default_scalar=-1,
                      plot=True, throw_axis=True)
merge_two_neigh_grains_simple(method_id='1', method_params_parent_sel=['area'], method_params_other_sel=['area'], method_params_merging=['area'], parent_gid=[], return_gids=True, plot_gs_bf=True, plot_gs_af=True, plot_area_kde_diff=True, bandwidth=1.0)[source]

Find two random neighbouring grains and merge them.

Parameters:
  • method_id (int) –

    0: parenmt_gid will be selected at random and other_gid will also

    be selected at random.

    1: parent_gid should be provided by user and othet_gid should also

    be provided by user.

    2: parent_gid sahould be provide by user and other_gid will be

    selected at random.

    NOTE: other_grain will allways be O(1) neighbour of parent_grain.

  • method_params_parent_sel (str) – Morphological parameter of choice for parent grain selection.

  • method_params_other_sel (str) – Morphological parameter of choice for other grain selection.

  • method_params_merging (str) – Morphological parameter of choice for merging decision makjing.

  • plot_bf (bool) – Plot grain structure before merging. Defaults to True.

  • plot_af (bool) – Plot grain structure after merging. Defaults to True.

Returns:

gids – [parent_gid, other_gid]. Other_gid merged into parent_gid.

Return type:

list

merge_neigh_grains(gid_pairs, check_for_neigh=True, simple_merge=True)[source]

Merge multiple pairs of neighbouring grains.

Parameters:
  • gid_pairs (dth.dt.ITERABLES) – Iterable of tuples containing pairs of grain IDs to be merged. Each tuple should be in the form (parent_gid, other_gid).

  • check_for_neigh (bool) – If True, each pair will be checked for neighbourhood before merging. Defaults to True.

  • simple_merge (bool) – If True, simple merging will be performed. Defaults to True.

Return type:

None

set_twingen(vf=0.2, tspec='absolute', trel='minil', tdis='user', t=[0.2, 0.5, 0.6, 0.7], tw=[1, 1, 1, 1], tmin=0.2, tmean=0.5, tmax=1.0, nmax_pg=1, placement='centroid', factor_min=0.0, factor_max=1.0)[source]

Set twin generation parameters.

Parameters:
  • vf (float) – Twin volume fraction.

  • tspec (str) –

    Twin thickness specification. Valid choices: ‘absolute’: Absolute thickness values will be used. ‘relative’: Relative thickness values will be used. ‘minil’: Thickness values will be specified as multiples of

    minimum inter-lattice distance.

  • trel (str) –

    Twin thickness relation. Valid choices: ‘minil’: Thickness values will be specified as multiples of

    minimum inter-lattice distance.

    ’grain_size’: Thickness values will be specified as multiples of

    grain size.

  • tdis (str) – Twin thickness distribution. Valid choices: ‘user’: User provided thickness values will be used. ‘normal’: Normal distribution will be used. ‘lognormal’: Log-normal distribution will be used. ‘uniform’: Uniform distribution will be used.

  • t (dth.dt.ITERABLES) – List of twin thickness values. Only valid if tdis is ‘user’.

  • tw (dth.dt.ITERABLES) – List of twin weights corresponding to the twin thickness values. Only valid if tdis is ‘user’.

  • tmin (float) – Minimum twin thickness. Only valid if tdis is not ‘user’.

  • tmean (float) – Mean twin thickness. Only valid if tdis is not ‘user’.

  • tmax (float) – Maximum twin thickness. Only valid if tdis is not ‘user’.

  • nmax_pg (int) – Maximum number of twins per grain.

  • placement (str) –

    Twin placement method. Valid choices: ‘centroid’: Twins will be placed at the centroid of the grain. ‘random’: Twins will be placed at random locations within the

    grain.

  • factor_min (float) – Minimum factor for twin placement. Only valid if placement is ‘random’.

  • factor_max (float) – Maximum factor for twin placement. Only valid if placement is ‘random’.

Return type:

None

introduce_single_twins(GIDs=[1], full_twin=True, throw_lgi=True, LFAL_kwargs={'angle_max': 360, 'angle_min': 0, 'factor': 0.5, 'length': 50}, twdis_kwargs={'distribution': 'normal', 'max_count_per_grain': 1, 'max_thickness': 4.5, 'mean_thickness': 4.5, 'min_thickness': 4.5, 'variance': 1.0}, plotgs_original=True, plotgs_twinned=True, save_to_features=True)[source]

Introduce twinned grain features into self.lgi.

This method creates twin lamellae within specified grains by defining slip lines supports visualization of grain structures before and after twin introduction, and can optionally store the twin features for later analysis.

Parameters:
  • GIDs (list of int, optional) – List of grain IDs to be twinned. Default is [1].

  • full_twin (bool, optional) – will be introduced. Default is True.

  • throw_lgi (bool, optional) – Default is True.

  • LFAL_kwargs (dict, optional) –

    Keyword arguments for the slip line 2D class method by_LFAL. Default is {‘factor’: 0.5, ‘angle_min’: 0, ‘angle_max’: 360, ‘length’: 50}. - factor : float

    Scale factor for line generation

    • angle_minfloat

      Minimum angle in degrees

    • angle_maxfloat

      Maximum angle in degrees

    • lengthint

      Length of the generated line

  • twdis_kwargs (dict, optional) –

    Keyword arguments for twin thickness distribution. Default parameters: - max_count_per_grain : int

    Maximum number of twin lamellae per grain

    • min_thicknessfloat

      Minimum thickness of twin lamellae in micrometers

    • mean_thicknessfloat

      Mean thickness of twin lamellae in micrometers

    • max_thicknessfloat

      Maximum thickness of twin lamellae in micrometers

    • distributionstr

      Type of distribution (‘normal’, etc.)

    • variancefloat

      Variance of the distribution

  • plotgs_original (bool, optional) – If True, plots the original grain structure before twin introduction. Default is True.

  • plotgs_twinned (bool, optional) – Default is True.

  • save_to_features (bool, optional) – Default is True.

  • numpy.ndarray (None or) – Returns None by default. If throw_lgi is True, returns the modified Local Grain Index (LGI) array as a numpy array with twin regions marked as -1.

Examples

from upxo.ggrowth.mcgs import mcgs
mcgs = mcgs(study='independent', input_dashboard='input_dashboard.xls')
mcgs.simulate()
mcgs.detect_grains()
mcgs.gs[35].char_morph_2d(bbox=True, bbox_ex=True, area=True,
                          aspect_ratio=True, perimeter=True, solidity=True,
                          make_skim_prop=True,)
mcgs.gs[35].prop.columns
mcgs.gs[35].find_neigh()
mcgs.gs[35].g[12]['grain'].coords
mcgs.gs[35].g[12]['grain'].centroid
GIDs, VALIND = mcgs.gs[35].get_gids_in_params_bounds(mpnames=['area'],
                                      fx_stats=[np.mean],
                                      pdslh=[[50, 50]],
                                      plot_mprop=False
                                      )
gids = GIDs['mpmapped']['area']
mcgs.gs[35].introduce_single_twins(GIDs=gids, full_twin=True,
                                   throw_lgi=True, plotgs_original=False,
                                   plotgs_twinned=True)

Notes

  • Twin regions are identified perpendicular to generated slip lines

  • Twin indices are marked with value -1 in the output LGI array

  • The method modifies self.lgi_1 to track twinned regions across multiple grains

  • Visualization uses the plotgs method with custom colormap and grain ID labels

add_pxtal()[source]

Add a new polycrystal orientation map instance to the grain structure.

Return type:

None

set_pxtal(instance_no=1, path_filename_noext=None, map_type='ebsd', apply_kuwahara=False, kuwahara_misori=5, gb_misori=10, min_grain_size=1, print_closs=True)[source]

Crystal Orientation Map. EBSD dataswt is one which can be loadsed.

Parameters:
  • instance_no (int) – Instance number of the polycrystal orientation map to be set up. Defaults to 1.

  • path_filename_noext (str) – Path and filename without extension of the orientation map file. For example, if the file is ‘D:/data/map.ctf’, then the path_filename_noext should be ‘D:/data/map’.

  • map_type (str) – Type of orientation map file. Valid choices: ‘ebsd’: EBSD orientation map file.

  • apply_kuwahara (bool) – If True, applies Kuwahara filter to the orientation map. Defaults to False.

  • kuwahara_misori (float) – Misorientation threshold for Kuwahara filter in degrees. Defaults to 5 degrees.

  • gb_misori (float) – Grain boundary misorientation threshold in degrees. Defaults to 10 degrees.

  • min_grain_size (int) – Minimum grain size in number of pixels. Defaults to 1.

  • print_closs (bool) – If True, prints the conversion loss after setting up the polycrystal orientation map. Defaults to True.

Return type:

None

Examples

from upxo.ggrowth.mcgs import mcgs
pxt = mcgs()
pxt.simulate()
pxt.detect_grains()
tslice = 20  # Temporal slice number
pxt.char_morph_2d(tslice)
pxt.gs[tslice].export_ctf(r'D:/export_folder', 'sunil')
path_filename_noext = r'D:/export_folder/sunil'
pxt.gs[tslice].set_pxtal(path_filename_noext=path_filename_noext)
pxt.gs[tslice].pxtal.map
make_linear_grid(sf=1)[source]

Make linear grid for interpolation.

Parameters:

sf (float) – Scale factor for grid spacing.

Returns:

  • x (np.ndarray) – 1D array of x-coordinates.

  • y (np.ndarray) – 1D array of y-coordinates.

  • xinc (float) – Increment in x-coordinates.

  • yinc (float) – Increment in y-coordinates.

scale(sf)[source]

Apply a scale factor to the current grain structure temporal slice.

Parameters:

sf (float) – Scale factor to apply.

Return type:

None

coarser(Grid_Data, ParentStateMatrix, Factor, InterpMethod)[source]

Create a coarser grid from parent grid and parent state matrix.

Parameters:
  • Grid_Data (dict) – Dictionary containing grid parameters of the parent grid.

  • ParentStateMatrix (np.ndarray) – 2D array representing the state matrix of the parent grid.

  • Factor (int) – Factor by which to decrease the resolution.

  • InterpMethod (str) – Interpolation method to use. Valid choices: ‘nearest’, ‘linear’, ‘cubic’.

Returns:

  • cogrid_NG (tuple of np.ndarray) – Tuple containing the new coordinate grid arrays (X, Y).

  • OSM_NG (np.ndarray) – 2D array representing the new orientation state matrix.

char_grain_positions_2d()[source]

Characterize and categorize the spatial positions of grains in a 2D grain structure.

This method analyzes each grain’s pixel locations to determine whether the grain is positioned at the boundary, corner, or interior of the microstructure domain. Grains are classified based on which edges of the image domain they touch.

Position Categories

Corner Positions:
  • ‘top_left’: Grain touches both top and left boundaries

  • ‘top_right’: Grain touches both top and right boundaries

  • ‘bottom_left’: Grain touches both bottom and left boundaries

  • ‘bottom_right’: Grain touches both bottom and right boundaries

Edge Positions (not at corners):
  • ‘pure_top’: Grain touches only the top boundary

  • ‘pure_bottom’: Grain touches only the bottom boundary

  • ‘pure_left’: Grain touches only the left boundary

  • ‘pure_right’: Grain touches only the right boundary

Aggregate Positions:
  • ‘top’: All grains touching top boundary (corner + pure_top)

  • ‘bottom’: All grains touching bottom boundary (corner + pure_bottom)

  • ‘left’: All grains touching left boundary (corner + pure_left)

  • ‘right’: All grains touching right boundary (corner + pure_right)

  • ‘boundary’: All grains touching any boundary

  • ‘corner’: All grains at corners only

  • ‘internal’: Grains not touching any boundary

Attributes Modified

For each grain in self.g:
grain.positionlist

[x_centroid, y_centroid, position_category_string]

self.positionsdict

Dictionary with position categories as keys and lists of grain IDs as values: - Keys: ‘top_left’, ‘bottom_left’, ‘bottom_right’, ‘top_right’,

‘pure_right’, ‘pure_bottom’, ‘pure_left’, ‘pure_top’, ‘left’, ‘bottom’, ‘right’, ‘top’, ‘boundary’, ‘corner’, ‘internal’

  • Values: List of grain IDs (gids) belonging to each category

returns:

Results are stored in grain.position attributes and self.positions dictionary

rtype:

None

Notes

  • Legacy codes. To be updated with better implementation using defs in gid_ops module.

  • A grain can belong to multiple aggregate categories simultaneously

  • Internal grains are those with no pixels on any boundary

  • Position determination is based on pixel-level analysis, not centroids

  • Domain boundaries are defined by image array indices (0, row_max, col_max)

Examples

from upxo.ggrowth.mcgs import mcgs
pxt = mcgs(study='independent', input_dashboard='input_dashboard.xls')
pxt.simulate()
pxt.detect_grains()
pxt.gs[10].char_grain_positions_2d()

# Access corner grains
corner_grains = pxt.gs[10].positions['corner']

# Access internal grains
internal_grains = pxt.gs[10].positions['internal']

# Get position of a specific grain
grain_5_position = pxt.gs[10].g[5]['grain'].position
print(f"Grain 5 centroid: ({grain_5_position[0]:.2f}, {grain_5_position[1]:.2f})")
print(f"Grain 5 category: {grain_5_position[2]}")

See also

plot_grains_at_position

Visualize grains at specific positions

find_border_internal_grains_fast

Fast alternative for border/internal classification

char_grain_positions_2d_v1()[source]

Characterize and categorize the spatial positions of grains in a 2D grain structure.

This method analyzes each grain’s pixel locations to determine whether the grain is positioned at the boundary, corner, or interior of the microstructure domain. Grains are classified based on which edges of the image domain they touch.

Position Categories

Corner Positions:
  • ‘top_left’: Grain touches both top and left boundaries

  • ‘top_right’: Grain touches both top and right boundaries

  • ‘bottom_left’: Grain touches both bottom and left boundaries

  • ‘bottom_right’: Grain touches both bottom and right boundaries

Edge Positions (not at corners):
  • ‘pure_top’: Grain touches only the top boundary

  • ‘pure_bottom’: Grain touches only the bottom boundary

  • ‘pure_left’: Grain touches only the left boundary

  • ‘pure_right’: Grain touches only the right boundary

Aggregate Positions:
  • ‘top’: All grains touching top boundary (corner + pure_top)

  • ‘bottom’: All grains touching bottom boundary (corner + pure_bottom)

  • ‘left’: All grains touching left boundary (corner + pure_left)

  • ‘right’: All grains touching right boundary (corner + pure_right)

  • ‘boundary’: All grains touching any boundary

  • ‘corner’: All grains at corners only

  • ‘internal’: Grains not touching any boundary

Algorithm

For each grain:
  1. Extract all pixel locations belonging to the grain

  2. Check if any pixels lie on domain boundaries (row=0, row=max, col=0, col=max)

  3. Classify based on which boundaries are touched

  4. Store classification in grain.position attribute (list format: [x_centroid, y_centroid, position_string])

Attributes Modified

For each grain in self.g:
grain.positionlist

[x_centroid, y_centroid, position_category_string]

self.positionsdict

Dictionary with position categories as keys and lists of grain IDs as values: - Keys: ‘top_left’, ‘bottom_left’, ‘bottom_right’, ‘top_right’,

‘pure_right’, ‘pure_bottom’, ‘pure_left’, ‘pure_top’, ‘left’, ‘bottom’, ‘right’, ‘top’, ‘boundary’, ‘corner’, ‘internal’

  • Values: List of grain IDs (gids) belonging to each category

returns:

Results are stored in grain.position attributes and self.positions dictionary

rtype:

None

Notes

  • A grain can belong to multiple aggregate categories simultaneously

  • Internal grains are those with no pixels on any boundary

  • Position determination is based on pixel-level analysis, not centroids

  • Domain boundaries are defined by image array indices (0, row_max, col_max)

Examples

from upxo.ggrowth.mcgs import mcgs
pxt = mcgs(study='independent', input_dashboard='input_dashboard.xls')
pxt.simulate()
pxt.detect_grains()
pxt.gs[10].char_grain_positions_2d()

# Access corner grains
corner_grains = pxt.gs[10].positions['corner']

# Access internal grains
internal_grains = pxt.gs[10].positions['internal']

# Get position of a specific grain
grain_5_position = pxt.gs[10].g[5]['grain'].position
print(f"Grain 5 category: {grain_5_position}[2]}")
print(f"Grain 5 category: {grain_5_position[2]}")

See also

plot_grains_at_position

Visualize grains at specific positions

find_border_internal_grains_fast

Fast alternative for border/internal classification

find_border_internal_grains_fast()[source]

Identify border and internal grains. Quickly find border and internal grains without doing anything else. :returns: * border_gids (Numpy array of border grain IDs.)

  • internal_gids (Numpy array of internal grain IDs.)

  • lgi_border (Numpy array of Local Grain Index (LGI) with only border) – grains.

  • lgi_internal (Numpy array of Local Grain Index (LGI) with only internal) – grains.

Examples

border_gids, internal_gids, lgi_border, lgi_internal = find_border_internal_grains_fast()

plt.figure()
plt.imshow(lgi_border)

plt.figure()
plt.imshow(lgi_internal)
find_grain_size_fast(metric='npixels', recalculate_gid=False)[source]

Quickly find the grain sizes without doing anything else.

Notes

Order of grain_sizes is that of pxtal.gs[m].gid

Parameters:

metric (Specify which ares metric is needed. Options include:) –

  • ‘npixels’: Number of pixels

  • ’pxarea’: Pixel wise calculated area

  • ’eq_dia’: Equivalent diameter

Returns:

grain_sizes

Return type:

Numpy array of grain areas.

Examples

from upxo.ggrowth.mcgs import mcgs
pxtal = mcgs(study='independent', input_dashboard='input_dashboard.xls')
pxtal.simulate()
pxtal.detect_grains()
grain_areas_all_grains = pxtal.gs[2].find_grain_size_fast(metric='npixels')
find_npixels_border_grains_fast(metric='npixels')[source]

Find the number of pixels in each of the border grains.

Parameters:

metric (Specify which ares metric is needed. Options include:) –

  • ‘npixels’: Number of pixels

  • ’pxarea’: Pixel wise calculated area

  • ’eq_dia’: Equivalent diameter

Returns:

border_grain_npixels – grain.

Return type:

Numpy array of number of pixels in each border

Examples

from upxo.growth.mcgs import mcgs
pxtal = mcgs(study='independent',input_dashboard='input_dashboard.xls')
pxtal.simulate()
pxtal.detect_grains()
grain_areas_border_grains = pxtal.gs[2].find_npixels_border_grains_fast(metric='npixels')
find_npixels_internal_grains_fast(metric='npixels')[source]

Find the number of pixels in each of the internal grains.

Parameters:

metric (Specify which ares metric is needed. Options include:) –

  • ‘npixels’: Number of pixels

  • ’pxarea’: Pixel wise calculated area

  • ’eq_dia’: Equivalent diameter

Returns:

internal_grain_npixels – internal grain.

Return type:

Numpy array of number of pixels in each

Examples

from upxo.ggrowth.mcgs import mcgs
pxtal = mcgs(study='independent',input_dashboard='input_dashboard.xls')
pxtal.simulate()
pxtal.detect_grains()
grain_areas_internal_grains = pxtal.gs[2].find_npixels_internal_grains_fast(metric='npixels')
find_ags(grains_to_include='all', gids=None, method='npixels')[source]

Find average grain size of the grain structure.

Parameters:
  • grains_to_include (str) – Specify which grains to include in the average grain size calculation. Options include: * ‘all’: Include all grains. * ‘border’: Include only border grains. * ‘internal’: Include only internal grains. * ‘gid’ or ‘gids’: Include only grains with specified GIDs.

  • gids (list or np.ndarray, optional) – List or array of grain IDs to include if grains_to_include is ‘gid’ or ‘gids’. Defaults to None.

  • method (str) – Specify which area metric to use for average grain size calculation. Options include: * ‘npixels’: Number of pixels. * ‘pxarea’: Pixel wise calculated area. * ‘eq_dia’: Equivalent diameter.

Returns:

ags – Average grain size based on the specified criteria.

Return type:

float

Examples

from upxo.ggrowth.mcgs import mcgs
pxtal = mcgs(study='independent',input_dashboard='input_dashboard.xls')
pxtal.simulate()
pxtal.detect_grains()
ags_all = pxtal.gs[2].find_ags(grains_to_include='all', method='npixels')
ags_border = pxtal.gs[2].find_ags(grains_to_include='border', method='npixels')
ags_internal = pxtal.gs[2].find_ags(grains_to_include='internal', method='npixels')
ags_specific = pxtal.gs[2].find_ags(grains_to_include='gids', gids=[1,2,3], method='npixels')
find_prop_npixels()[source]

Get grain NUMBER OF PIXELS into pandas dataframe :rtype: None

find_prop_npixels_gb()[source]

Get grain GRAIN BOUNDARY LENGTH (NO. PIXELS) into pandas dataframe :rtype: None

find_prop_gb_length_px()[source]

Get grain GRAIN BOUNDARY LENGTH (NO. PIXELS) into pandas dataframe :rtype: None

find_prop_area()[source]

Get grain AREA into pandas dataframe :rtype: None

find_prop_eq_diameter()[source]

Get grain EQUIVALENT DIAMETER into pandas dataframe :rtype: None

find_prop_perimeter()[source]

Get grain PERIMETER into pandas dataframe :rtype: None

find_prop_perimeter_crofton()[source]

Get grain CROFTON PERIMETER into pandas dataframe :rtype: None

find_prop_compactness()[source]

Get grain COMPACTNESS into pandas dataframe :rtype: None

find_prop_aspect_ratio()[source]

Get grain ASPECT RATIO into pandas dataframe :rtype: None

find_prop_solidity()[source]

Get grain SOLIDITY into pandas dataframe :rtype: None

find_prop_circularity()[source]

Get grain CIRCULARITY into pandas dataframe :rtype: None

find_prop_major_axis_length()[source]

Get grain MAJOR AXIS LENGTH into pandas dataframe :rtype: None

find_prop_minor_axis_length()[source]

Get grain MINOR AXIS LENGTH into pandas dataframe :rtype: None

find_prop_morph_ori()[source]

Get grain MORPHOLOGICAL ORIENTATION into pandas dataframe :rtype: None

find_prop_feret_diameter()[source]

Get grain FERET DIAMETER into pandas dataframe :rtype: None

find_prop_euler_number()[source]

Get grain EULER NUMBER into pandas dataframe :rtype: None

find_prop_eccentricity()[source]

Get grain ECCENTRICITY into pandas dataframe :rtype: None

build_prop(correct_aspect_ratio=False)[source]

Build the grain structure properties as requested by user in the ‘prop_flag’ attribute.

Return type:

None

get_stat(PROP_NAME, saa=True, throw=False)[source]

Calculates ths statistics of a property in the ‘prop’ attribute.

Notes

Input data is not sanitised before calculating the statistics. Will results in an error if invalid entries are found.

Parameters:
  • PROP_NAME (str) –

    Name of the property, whos statistics is to be calculated. They could be from the following list:

    1. npixels

    2. npixels_gb

    3. area

    4. eq_diameter

    5. perimeter

    6. perimeter_crofton

    7. compactness

    8. gb_length_px

    9. aspect_ratio

    10. solidity

    11. morph_ori

    12. circularity

    13. eccentricity

    14. feret_diameter

    15. major_axis_length

    16. minor_axis_length

    17. euler_number

  • saa (bool, optional) – Flag to save the statistics as attribute. The default is True.

  • throw (bool, optional) – Flag to return the computed statistics. The default is False.

Returns:

metrics – DESCRIPTION.

Return type:

TYPE

Notes

Following statistical metrics will be calculated:

count: Data count value mean: Mean of the data std: Standard deviation of the data min: Minimum value of the data 25%: First quartile of the data 50%: Second quartile of the data 75%: Third quartile of the data max: Maximum value of the data median: Median value of the data mode: List of modes of the data var: Variance of the data skew: Skewness of the data kurt: Kurtosis of the data nunique: Number of unique values in the data sem: Standard error of the mean of the data

Examples

PXGS.gs[4].extract_statistics_prop('area')
make_valid_prop(PROP_NAME='aspect_ratio', rem_nan=True, rem_inf=True, PROP_df_column=None)[source]

Remove invalid entries from a column in a Pandas dataframe and returns sanitized pandas column with the PROP_NAME as column name

Parameters:
  • PROP_NAME (str, optional) – Property to be cleansed. The default is ‘aspect_ratio’.

  • rem_nan (TYPE, optional) – Boolean flag to remove np.nan. The default is True.

  • rem_inf (TYPE, optional) – Boolean flag to remove np.inf. Both negative and positive inf will be removed. The default is True.

Returns:

  • subset (pd.data_frame) – A single column pandas dataframe with cleansed values.#

  • ratio (float) – Ratio of total number of values removed to the size of the property column in the self.prop dataframe

s_prop(s=1, PROP_NAME='area')[source]

Extract state wise partitioned property. Property name has to be specified by the user.

Parameters:
  • s (int, optional) – Value of the The default is 1.

  • PROP_NAME (TYPE, optional) – DESCRIPTION. The default is ‘area’.

Returns:

  • TYPE – DESCRIPTION.

  • # TODO – 1: add validity checking layers for s and PROP_NAME 2: if s = 0, then any of the available be selected at random and

    returned

    3: if s = -1, then the state with the minimum number of grains

    will be returned

    4: if s = -2, then the state with the maximum number of grains

    will be returned

get_gid_prop_range(PROP_NAME='area', reminf=True, remnan=True, range_type='percentage', value_range=[1, 2], percentage_range=[0, 20], rank_range=[60, 90], pivot=None)[source]

Get GIDs of grains whose property values fall within a specified range.

Parameters:
  • PROP_NAME (str, optional) – Name of the property to filter grains by. The default is ‘area’.

  • reminf (bool, optional) – Flag to remove infinite values from the property data. The default is True.

  • remnan (bool, optional) – Flag to remove NaN values from the property data. The default is True.

  • range_type (str, optional) – Type of range to use for filtering. Options are ‘percentage’, ‘value’, or ‘rank’. The default is ‘percentage’.

  • value_range (list, optional) – List of two values specifying the min and max property values for filtering when range_type is ‘value’. The default is [1, 2].

  • percentage_range (list, optional) – List of two values specifying the min and max percentage for filtering when range_type is ‘percentage’. The default is [0, 20].

  • rank_range (list, optional) – List of two values specifying the min and max rank percentiles for filtering when range_type is ‘rank’. The default is [60, 90].

  • pivot (TYPE, optional) – DESCRIPTION. The default is None.

Returns:

  • gids (np.ndarray) – Numpy array of grain IDs (GIDs) that fall within the specified property range.

  • A_B_values (np.ndarray) – Numpy array of property values corresponding to the selected GIDs.

  • A_B_indices (pd.Index) – Pandas Index of the selected GIDs.

Notes

To understand how the sub-selection is done, consider the following illustration of the property distribution:

PROP_min–inf——–A—–nan——B—nan—-inf——PROP_max
  1. clean data for inf and nans

  2. Then subselect from A to PROP_max

  3. Then subselect from A to B, which is what we need

Examples

gid, value, df_loc = PXGS.gs[8].get_gid_prop_range(PROP_NAME='aspect_ratio',
                            range_type='rank', value_range=[80, 100])
gid, value, df_loc = PXGS.gs[8].get_gid_prop_range(PROP_NAME='area',
                            range_type='percentage', value_range=[80, 100])
gid, value, df_loc = PXGS.gs[8].get_gid_prop_range(PROP_NAME='aspect_ratio',
                            range_type='value', value_range=[2, 2.5])
plot_largest_grain()[source]

Plot the largest grain in a temporal slice of a grain structure

Returns:

  • None.

  • # TODO (WRAP THIS INSIDE A FIND_LARGEST_GRAIN AND HAVE IT TRHOW)

  • THE GID TO THE USER

plot_longest_grain()[source]

A humble method to just plot the longest grain in a temporal slice of a grain structure

Returns:

  • None.

  • # TODO (WRAP THIS INSIDE A FIND_LONGEST_GRAIN AND HAVE IT TRHOW)

  • THE GID TO THE USER

mask_lgi_with_gids(gids, masker=-10)[source]

Mask the lgi (PXGS.gs[n] specific lgi array: lattice of grain IDs) against user input grain indices, with a default UPXO-reserved place-holder value of -10.

Parameters:
  • gids (int/list) – Either a single grain index number or list of them

  • kwargs

    masker:

    An int value, preferably -10, but compulsorily less than -5.

Returns:

  • s_masked (np.ndarray(dtype=int)) – lgi masked against gid values

  • Internal calls (@dev)

  • ———————

  • None

mask_s_with_gids(gids, masker=-10, force_masker=False)[source]

Mask the s (PXGS.gs[n] specific s array) against user input grain indices

Parameters:
  • gids (int/list) – Either a single grain index number or list of them

  • kwargs

    masker:

    An int value, preferably -10.

    force_masker:

    This is here to satisfy the tussle of future development needs and user-readiness!! Please go with it for now.

    If True, user value for masker will be forced to masker variable, else the defaultr value of -10 will be used.

Returns:

  • lgi_masked (np.ndarray(dtype=int)) – lgi masked against gid values

  • Internal calls (@dev)

  • ———————

  • self.mask_lgi_with_gids()

plotgs(figsize=(6, 6), dpi=120, custom_lgi=None, cmap='coolwarm', plot_cbar=True, title='Title', plot_centroid=False, plot_gid_number=False, centroid_kwargs={'marker': 'o', 'mec': 'black', 'mfc': 'yellow', 'ms': 2.5}, gid_text_kwargs={'fontsize': 10}, title_kwargs={'fontsize': 10}, label_kwargs={'fontsize': 10})[source]

Method to plot the grain structure of a temporal slice

Parameters:
  • figsize (tuple, optional) – Figure size in inches. The default is (6, 6).

  • dpi (int, optional) – Dots per inch. The default is 120.

  • custom_lgi (np.ndarray, optional) – Custom lgi to be plotted instead of the internal one. The default is None.

  • cmap (str, optional) – Colormap name. The default is ‘coolwarm’.

  • plot_cbar (bool, optional) – Flag to plot colorbar. The default is True.

  • title (str, optional) – Plot title. The default is ‘Title’.

  • plot_centroid (bool, optional) – Flag to plot centroids of grains. The default is False.

  • plot_gid_number (bool, optional) – Flag to plot gid numbers at centroids. The default is False.

  • centroid_kwargs (dict, optional) – Keyword arguments for centroid plotting. The default is {‘marker’: ‘o’, ‘mfc’: ‘yellow’, ‘mec’: ‘black’, ‘ms’: 2.5}.

  • gid_text_kwargs (dict, optional) – Keyword arguments for gid text plotting. The default is {‘fontsize’: 10}.

  • title_kwargs (dict, optional) – Keyword arguments for title. The default is {‘fontsize’: 10}.

  • label_kwargs (dict, optional) – Keyword arguments for axis labels. The default is {‘fontsize’: 10}.

Return type:

None.

Examples

from upxo.ggrowth.mcgs import mcgs
mcgs = mcgs(study='independent', input_dashboard='input_dashboard.xls')
mcgs.simulate()
mcgs.detect_grains()
mcgs.gs[35].plotgs(figsize=(6, 6), dpi=120, cmap='coolwarm',
                   plot_centroid=True,
                   centroid_kwargs={'marker':'o','mfc':'yellow',
                                    'mec':'black','ms':2.5},
                   plot_gid_number=True)
plot_grains_gids(gids, gclr='color', title='user grains', cmap_name='CMRmap_r')[source]

Method to plot grains specified by user input grain indices

Parameters:
  • gids (int/list) – Either a single grain index number or list of them

  • title (TYPE, optional) – DESCRIPTION. The default is “user grains”.

  • gclr (str, optional) – Color scheme for plotting. The default is ‘color’.

  • cmap_name (str, optional) – Colormap name. The default is ‘CMRmap_r’.

Return type:

None.

Examples

After acquiring gids for aspect_ratio between ranks 80 and 100, we will visualize those grains. As we are only interested in gid, we will not use the other two values returned by PXGS.gs[n].get_gid_prop_range() method:

gid, _, __ = PXGS.gs[8].get_gid_prop_range(PROP_NAME='aspect_ratio',
                                            range_type='rank',
                                            rank_range=[80, 100]
                                            )
# Now, pass gid as input for the PXGS.gs[n].plot_grains_gids(),
# which will then plot the grain strucure with only these values:
PXGS.gs[8].plot_grains_gids(gid, cmap_name='CMRmap_r')
plot_neigh_grains_of_gid(neigh_gid_subset)[source]

Method to plot neighbouring grains of user specified grain indices

Parameters:

neigh_gid_subset (dict) – A dictionary with key as gid and value as list of neighbouring gids.

Return type:

None.

plot_grains_prop_range(PROP_NAME='area', range_type='percentage', value_range=[1, 2], percentage_range=[0, 20], rank_range=[60, 90], pivot=None, gclr='color', title=None, cmap_name='CMRmap_r')[source]

Method to plot grains having properties within the domain defined by the range description specified by the user.

Parameters:
  • PROP_NAME (str, optional) – Name of the grain structure property. The default is ‘area’.

  • range_type (str, optional) – Range description type. The default is ‘percentage’.

  • value_range (iterable, optional) – Range of the actual PROP_NAME values. The default is [1, 2].

  • percentage_range (iterable, optional) – Percentage range defining the PROP_NAME values. The default is [0, 20].

  • rank_range (iterable, optional) – Ranks defining the range of PROP_NAME values. If rank_range=[6, 10] and there are 20 grains, then those grains having 12th to 20th largest PROP_NAME values will be selected. The default is [60, 90].

  • pivot (str, optional) –

    Describes the range location. Options: (‘ends’, ‘mean’, ‘primary_mode’):

    • If ‘ends’ and percentage_range=[5, 8], then this means that

    PROP_NAME vaklues between 5% and 8% of vaklues will be used to select the grains. - If ‘mean’ and percentage_range=[5, 8], then this means that PROP_NAME values between 0.95*mean and 1.08*mean will be used to select the grains. - If ‘primary_mode’ and percentage_range=[5, 8], then this means that PROP_NAME values between 0.95*primary_mode and 1.08*primary_mode will be used to select the grains.

    The default is None.

  • gclr (str, optional) – Specify whether grains are to have colours or grayscale. Choose ‘binary’ or ‘grayscale’ for grayscale The default is ‘color’.

  • title (str, optional) – DESCRIPTION. The default is None.

  • cmap_name (str, optional) – DESCRIPTION. The default is ‘CMRmap_r’.

Return type:

None.

plot_large_grains(extent=5)[source]

Method to plot large grains based on area percentage extent.

Parameters:

extent (int, optional) – Percentage extent to consider for large grains. The default is 5.

Return type:

None.

plot_neigh_grains(gids=[None], throw=True, gclr='color', title='Neigh grains', cmap_name='CMRmap_r')[source]

Method to plot neighbouring grains of user specified grain indices

Parameters:
  • gids (int/list, optional) – Either a single grain index number or list of them. The default is [None].

  • throw (bool, optional) – Flag to return the list of neighbouring gids. The default is True.

  • gclr (str, optional) – Color scheme for plotting. The default is ‘color’.

  • title (str, optional) – Plot title. The default is “Neigh grains”.

  • cmap_name (str, optional) – Colormap name. The default is ‘CMRmap_r’.

Returns:

neighbours – List of neighbouring grain IDs.

Return type:

list

plot(PROP_NAME=None, title='auto', cmap='CMRmap_r', vmin=1, vmax=5)[source]

Plot the grain structure based on user input property name

Parameters:
  • PROP_NAME (str, optional) – Name of the property to plot the grain structure by. The default is None.

  • title (str, optional) – Plot title. The default is ‘auto’.

  • cmap (str, optional) – Colormap name. The default is ‘CMRmap_r’.

Return type:

None.

Notes

  1. if no kwargs: plot the entire greain structure: just use plotgs()

plot_grain(gid, neigh=False, neigh_hops=1, save_png=False, filename='auto', field_variable=None, throw=False)[source]

Plots the nth grain.

Parameters:
  • Ng (int) – The grain number to plot. Grain number is global and not state specific.

  • neigh (bool) – Flag to decide plotting of grains neighbouring to Ng

  • neigh_hops (1) –

    Non-locality of neighbours. If 1, only neighbours of Ng will be plotted along with Ng grain If 2, neighbours of neighbours of Ng will be plotted along with Ng grain NOTE: maximum number of hops permitted = 2

    If a number greater than 2 is provided, then hops will be restricted to 2.

  • save_png (bool) – Flag to consider saving .png image to disk

  • filename (str) –

    Use this filename for the .png imaage. If ‘auto’, then filename will be generated containing:

    • Grain structure temporal slice number

    • Global grain number

    If None or an invalid, image will not be saved to disk.

  • field_variable (str) – Global field variable This is @ future development when SDVs can be re-mapped from CPFE simulation to UPXO.mcgs2d

Returns:

grain_plot – matplotlib.plt.imshow object

Return type:

bool

Examples

PXGS.gs[4].plot_grain(3, filename='t4_ng3.png'
# TODO
  1. Add validity checking layer for gid

2. Add validity check for save_png and filename 2. Generate automatic filename 3. Save image to file 4. Add branching for dimensionality 5. Add validity check for existence of data

plot_grains(gids, hide_non_actors=True, default_cmap='jet', title='user grains', throw_plt_object=False, figsize=(6, 6), dpi=120)[source]

Method to plot grains specified by user input grain indices

Parameters:

gids (iterable) – An iterable containing grain index numbers

Examples

self.plot_grains([1, 2, 3, 4])
plot_grains_prop_bounds_s(s, PROP_NAME=None, prop_min=0, prop_max='')[source]

Placeholder for plotting grains in a state by property bounds.

Parameters:
  • s (int) – State value to inspect.

  • PROP_NAME (str, optional) – Property name used to filter grains.

  • prop_min (float, optional) – Lower property bound.

  • prop_max (float or str, optional) – Upper property bound.

Return type:

None

Notes

This method is not yet implemented.

plot_grains_at_position(position='corner', overlay_centroids=True, markersize=6)[source]

Method to plot grains at specified positions in the grain structure

Parameters:
  • position (str, optional) – Position in the grain structure to plot grains at. Options: ‘corner’, ‘boundary’, ‘triple_point’ The default is ‘corner’.

  • overlay_centroids (bool, optional) – Flag to overlay centroids of the grains on the plot. The default is True.

  • markersize (int, optional) – Size of the markers for centroids. The default is 6.

Return type:

None.

Examples

PXGS.gs[tslice].plot_grains_at_position(position='boundary')
detect_grain_boundaries()[source]

Placeholder for grain-boundary detection logic.

Notes

This method is not yet implemented.

hist(PROP_NAME=None, bins=20, kde=True, bw_adjust=None, stat='density', color='blue', edgecolor='black', alpha=1.0, line_kws={'color': 'k', 'ls': '-', 'lw': 2}, auto_xbounds=True, auto_ybounds=True, xbounds=[0, 50], ybounds=[0, 0.2], peaks=False, height=0, prominance=0.2, __stack_call__=False, __tslice__=None)[source]

Plot histogram of grain property distribution

Parameters:
  • PROP_NAME (str, optional) – Name of the grain property. The default is None.

  • bins (int, optional) – Number of bins for the histogram. The default is 20.

  • kde (bool, optional) – Flag to plot kernel density estimate (KDE). The default is True.

  • bw_adjust (float, optional) – Bandwidth adjustment for KDE. The default is None.

  • stat (str, optional) – Statistic to plot. Options: ‘density’, ‘frequency’, ‘count’. The default is ‘density’.

  • color (str, optional) – Color of the histogram bars. The default is ‘blue’.

  • edgecolor (str, optional) – Edge color of the histogram bars. The default is ‘black’.

  • alpha (float, optional) – Transparency of the histogram bars. The default is 1.0.

  • line_kws (dict, optional) – Keyword arguments for the KDE line. The default is {‘color’: ‘k’, ‘lw’: 2, ‘ls’: ‘-‘}.

  • auto_xbounds (bool, optional) – Flag to automatically set x-axis bounds. The default is True.

  • auto_ybounds (bool, optional) – Flag to automatically set y-axis bounds. The default is True.

  • xbounds (list, optional) – User-defined x-axis bounds if auto_xbounds is False. The default is [0, 50].

  • ybounds (list, optional) – User-defined y-axis bounds if auto_ybounds is False. The default is [0, 0.2].

  • peaks (bool, optional) – Flag to identify and plot peaks in the KDE. The default is False.

  • height (float, optional) – Minimum height of peaks to identify. The default is 0.

  • prominance (float, optional) – Minimum prominence of peaks to identify. The default is 0.2.

  • __stack_call__ (bool, optional) – Internal flag for stack calls. The default is False.

  • __tslice__ (int, optional) – Temporal slice number for stack calls. The default is None.

Return type:

None.

kde(PROP_NAMES, bw_adjust)[source]

Plot kernel density estimate (KDE) of grain property distribution

Parameters:
  • PROP_NAMES (list) – List of grain property names.

  • bw_adjust (float) – Bandwidth adjustment for KDE.

Return type:

None.

see_distr(viz='hist', prop_names=['area', 'perimeter', 'orientation', 'solidity'], props={'area': [], 'orientation': [], 'perimeter': [], 'solidity': []}, prop_units={'area': 'μm²', 'orientation': 'degrees', 'perimeter': 'μm', 'solidity': ''}, probability_density=False, nbins_values={'area': 30, 'orientation': 30, 'perimeter': 30, 'solidity': 30}, bw_adjust_values={'area': None, 'orientation': None, 'perimeter': None, 'solidity': None}, alpha_values={'area': 0.7, 'orientation': 0.7, 'perimeter': 0.7, 'solidity': 0.7}, color_values={'area': 'blue', 'orientation': 'blue', 'perimeter': 'blue', 'solidity': 'blue'}, edgecolor_values={'area': 'black', 'orientation': 'black', 'perimeter': 'black', 'solidity': 'black'}, binsize=30, alpha=0.7, color='blue', edgecolor='black', ncolumns=3, ylabel='count', gsdim=2)[source]

Delegate to the plotting helper that visualises property distributions.

From upxo.viz.dataviz.see_distr:

Plot distributions of multiple grain properties in subplots

Parameters:
  • gsdim (int, optional) – Dimensionality of the grain structure data (2 for 2D, 3 for 3D). Default is 2.

  • vis (str, optional) – Visualization type: ‘hist’ for histogram, ‘kde’ for kernel density estimate, or ‘hist_kde’ for both overlaid. Default is ‘hist’.

  • prop_data_format (str, optional) – Format of the property data source. Options are ‘dataframe’ or ‘dict’. Default is ‘dataframe’.

  • prop_df (pandas.DataFrame, optional) – DataFrame containing grain properties if prop_data_format is ‘dataframe’. Default is None.

  • prop_names (list of str, optional) – List of grain property names to plot distributions for. Default includes ‘area’, ‘perimeter’, ‘orientation’, and ‘solidity’.

  • props (dict, optional) – Dictionary of grain properties if prop_data_format is ‘dict’. Default is empty dict.

  • prop_units (dict, optional) – Dictionary mapping property names to their units for labeling axes. Default units are provided for common properties.

  • probability_density (bool, optional) – If True, normalize distributions to form a probability density. Default is False.

  • nbins_values (dict, optional) – Dictionary specifying number of bins for each property. Default is 30 bins for each.

  • bw_adjust_values (dict, optional) – Dictionary specifying bandwidth adjustment for KDE plots. If None for a property, optimal bandwidth is calculated automatically using Scott’s rule. Default is None for all.

  • alpha_values (dict, optional) – Dictionary specifying transparency (alpha) for each property distribution. Default is 0.7.

  • color_values (dict, optional) – Dictionary specifying fill color for each property distribution. Default is ‘blue’.

  • edgecolor_values (dict, optional) – Dictionary specifying edge color for each property distribution. Default is ‘black’.

  • binsize (int, optional) – Default number of bins to use if not specified in nbins_values. Default is 30

  • alpha (float, optional) – Default transparency (alpha) to use if not specified in alpha_values. Default is 0

  • color (str, optional) – Default fill color to use if not specified in color_values. Default is ‘blue’.

  • edgecolor (str, optional) – Default edge color to use if not specified in edgecolor_values. Default is ‘black’.

  • ncolumns (int, optional) – Number of columns in the subplot grid. Default is 3.

  • ylabel (str, optional) – Label for the y-axis. Default is ‘count’.

Return type:

None

Notes

This function creates distributions for specified grain properties in a grid of subplots. It supports data input as either a pandas DataFrame or a dictionary of properties.

Usage

from upxo.viz.dataviz import see_distr

femesh(saa=True, throw=False)[source]

Set up finite element mesh of the poly-xtal

Parameters:
  • saa (bool, optional) – Flag to set the mesh attribute of the grain structure object. The default is True.

  • throw (bool, optional) – Flag to return the mesh object. The default is False.

Returns:

mesh – Finite element mesh of the grain structure.

Return type:

pxtal.mesh.mesh_mcgs2d object

Notes

Use saa=True to update grain structure mesh atttribute Use saa=True and throw=True to update and return mesh Use saa=False and throw=True to only return mesh

property pxtal_length

Return the physical length of the polycrystal domain.

property pxtal_height

Return the physical height of the polycrystal domain.

property pxtal_area

Return the physical area of the polycrystal domain.

property centroids

Return grain centroids as an (n, 2) array.

property bboxes

Return bounding boxes for all grains.

property bboxes_bounds

Return bounding-box bounds for all grains.

property bboxes_ex

Return extended bounding boxes for all grains.

property bboxes_ex_bounds

Return extended bounding-box bounds for all grains.

property areas

Return grain areas as a numpy array.

property areas_min

Return the minimum grain area.

property areas_mean

Return the mean grain area.

property areas_std

Return the standard deviation of grain areas.

property areas_var

Return the variance of grain areas.

property areas_max

Return the maximum grain area.

property areas_stat

Return basic statistics for grain areas.

property aspect_ratios

Return grain aspect ratios.

property aspect_ratios_min

Return the minimum grain aspect ratio.

property aspect_ratios_mean

Return the mean grain aspect ratio.

property aspect_ratios_std

Return the standard deviation of grain aspect ratios.

property aspect_ratios_var

Return the variance of grain aspect ratios.

property aspect_ratios_max

Return the maximum grain aspect ratio.

property aspect_ratios_stat

Return basic statistics for grain aspect ratios.

property npixels

Return the number of pixels for each grain.

property single_pixel_grains

Return the grain IDs that contain a single pixel.

property plot_single_pixel_grains

Plot the grains that consist of a single pixel.

property straight_line_grains

Return grain IDs that are effectively straight-line grains.

property locations

Return stored grain locations.

property perimeters

Return grain perimeters estimated from pixel counts.

property perimeters_min

Return the minimum grain perimeter.

property perimeters_mean

Return the mean grain perimeter.

property perimeters_std

Return the standard deviation of grain perimeters.

property perimeters_var

Return the variance of grain perimeters.

property perimeters_stat

Return basic statistics for grain perimeters.

property ratio_p_a

Return the perimeter-to-area ratio for each grain.

property AF_bgrains_igrains

Return area fractions for boundary and internal grains.

property grains

Return a generator over the grains in this structure.

make_mulpoint2d_grain_centroids()[source]

Build and store a mulpoint2d object from grain centroids.

plot_mcgs_mpcentroids()[source]

Plot the stored grain-centroid multipoint overlay on the slice image.

Return type:

None

vtgs2d(visualize=True)[source]

Build a 2D Voronoi tessellation from the grain centroids.

Parameters:

visualize (bool, optional) – Plot the tessellation after construction.

Return type:

None

ebsd_write_ctf(folder='upxo_ctf', file='ctf.ctf')[source]

Write a small synthetic CTF file for testing purposes.

Parameters:
  • folder (str) – Folder to write the ctf file to.

  • file (str) – Name of the ctf file.

Return type:

None.

export_vtk2d()[source]

Placeholder for exporting the grain structure to a 2D VTK file.

Return type:

None

export_ctf(folder, fileName, pathFinding='direct', headerFileLocation='C:\\Development\\UPXO\\upxo_library\\src\\upxo\\_writer_data\\_ctf_header_CuCrZr_1.txt', factor=1, method='nearest')[source]

Export the grain structure to a CTF file for downstream EBSD tools.

Parameters:
  • folder (str) – Directory path string where the CTF file will be exported.

  • fileName (str) – Name of the CTF file to be exported.

  • factor (float) – Resolution modification factor. If factor < 1.0, the grid resolution will be decreased by the specified factor using decimation. If factor = 1.0, the grid resolution will remain unchanged. If factor > 1.0, the grid resolution will be increased by the specified factor using nearest neighbor interpolation.

  • method (str) – Method to modify grid resolution. Options include ‘nearest’ and ‘decimate’.

Return type:

None.

Examples

ctf.export_ctf('D:/export_folder', 'sunil')
export_slices(xboundPer=None, yboundPer=None, zboundPer=None, mlist=None, sliceStepSize=None, sliceNormal=None, xoriConsideration=None, resolution_factor=None, exportDir=None, fileFormats=None, overwrite=None)[source]

Exports datafiles of slices through the grain structures.

Parameters:
  • xboundPer (list/tuple) – (min%, max%), min% < max%. min% shows the percentage length from grid’s xmin, where the bound starts and the max% shows the percentage xlength from grid’s xmin, where the bounds ends

  • yboundPer (list/tuple) – (min%, max%), min% < max%. min% shows the percentage length from grid’s ymin, where the bound starts and the max% shows the percentage ylength from grid’s ymin, where the bounds ends

  • zboundPer (list/tuple) – (min%, max%), min% < max%. min% shows the percentage length from grid’s zmin, where the bound starts and the max% shows the percentage ylength from grid’s zmin, where the bounds ends

  • mlist (list/tuple of int values) – List of monte-carlo temporal time values, where slices are needed. For each entry, a seperate folder will be created.

  • sliceStepSize (int) – Pixel-distance (number of pixels) between each individual slice. Minimum should be 1, in which case, the every adjqacent possible slice will be sliced and exported. If 2, slices 0, 2, 4, … will be considered. If 5, slices, 0, 5, 10, … will be considered.

  • sliceNormal (str) – Options include x, y, z

  • xoriConsideration (dict) –

    Xtal orientation consideration Mandatory key: ‘method’. Options include:

    • ’ignore’. Only when crystallographical orientations have

    already been mapped to grains. * ‘random’. Value could be a dummy value. * ‘userValues’. Value to be a numpy array of 3 Bunge’s Euler angles, shaped (nori, 3). * ‘import’.

  • resolution_factor (float)

  • exportDir (str) – Directory path string which would be parent directory for all exports made from this PXGS.export_slices(.). If directory does not exit, it will be created.

  • fileFormats (dict) – Keys include txt, h5d, ctf, vtk. * Include txt or h5d to export for for further work in UPXO * Include ctf for export to MTEX or Dream3D’s h5ebsd reconstruction pipeline * Include vtk2d for export to VTK format of each slice * Include vtk3d for export to VTK of entire grain structure

  • overwrite (bool) – If True, any existing contents in all child directories inside exportDir will be overwritten If False, existing contents will not be altered.

Return type:

None.

Examples

xboundPer = (0, 100)
yboundPer = (0, 100)
zboundPer = (0, 100)
mlist = [0, 10, 20]
sliceStepSize = 1
sliceNormal = 'z'
xoriConsideration = {'method': 'random'}
exportDir = 'FULL PATH'
fileFormats = {'.ctf': {},
               '.vtk3d': {},
               }
overwrite = True
PXGS.export_slices(xboundPer, yboundPer, zboundPer, mlist,
                   sliceStepSize, sliceNormal, exportDir,
                   fileFormats, overwrite)
import_ctf(filePath, fileName, convertUPXOgs=True)[source]

Import a CTF file into the grain-structure workflow.

import_crc(filePath, fileName, convertUPXOgs=True)[source]

Import a CRC file into the grain-structure workflow.

clean_exp_gs(minGrainSize=10)[source]

Clean imported experimental grain-structure data.

zgr
s
fcores
fbz
pixConn
binaryStructure2D
binaryStructure3D
n
lgi
spart_flag
gid
s_gid
gid_s
s_n
positions
vtgs
mesh
prop_flag
prop
prop_stat
print_interval_bool
gbjp
features
twingen
import_dream3d(filePath, fileName, convertUPXOgs=True)[source]

Import a Dream3D file into the grain-structure workflow.