upxo.repgen.repgen2dmcgs module
2D representative MC grain-structure generation and temporal-slice ranking.
Class repgen2d filters and ranks MCGS2D time slices against an EBSD or
other reference (grain count, morphological properties, Wasserstein /
energy-distance style metrics). Supports host-orientation and twin-geometry
hooks used in FCC twinning workflows.
Import:
from upxo.repgen.repgen2dmcgs import repgen2d
- class upxo.repgen.repgen2dmcgs.repgen2d(tdist=None, tstat=None, tgs=None, sgs=None, tdim=2, iroute='tgs.sgs', sgstype='upxo.mc2d', tgstype='upxo.mc2d')[source]
Bases:
object2D representative MC grain-structure ranking against a reference.
Filters and ranks MCGS2D temporal slices (sample
sgs) against an EBSD or other target (tgs/ distributions / statistics) using grain count, morphological properties, and distribution-distance metrics. Also holds host-orientation and twin-geometry fields used in FCC twinning workflows.Valid
iroutevalues (VALiroutes)'tdist.sgs'— target distributions vs sample GS'tstat.sgs'— target statistics vs sample GS'tgs.sgs'— target and sample grain structures directly
- tdist, tstat
Target distribution / statistics collections when used.
- tgs, sgs
Target and sample grain-structure objects.
- rm0tests, rm0
r0-test selection and results.
- ebsd_file, ebsd_step, lfi_ebsd, euler_ebsd, quat_ebsd, prop_ebsd, …
EBSD reference import and derived fields when loaded.
- repr_rank_ng, grain_count_rank_ng
Ranking outputs over temporal slices / candidates.
- mc_host_orientations, mc_twin_geom, mc_smooth_geom, …
Host / twin / smooth geometry workspaces for twinning pipelines.
- VALiroutes = ('tdist.sgs', 'tstat.sgs', 'tgs.sgs')
- VALgs = ('upxo.mc2d', 'upxo.mc3d', 'upxo.pv2d', 'upxo.vv3d', 'upxo.v2d', 'upxo.v3d', 'image2d', 'image3d', 'ebsd2d')
- tdist
- tstat
- tgs
- sgs
- tdim
- iroute
- sgstype
- tgstype
- classmethod from_tdist_sgs(tdist=None, sgs=None, tdim=2, sgstype='upxo.mc2d')[source]
Alternative constructor for creating a RepGen2DMCGS instance using distribution data of target grain structure and sample grain structure.
The sample grain structure can be of the following types: - see description of sgstype parameter
- Parameters:
tdist (upxo distribution collection object, optional) – Distribution data of the target grain structure. Defaults to None.
sgs (grain structure data object, optional) – The sample grain structure. Defaults to None.
tdim (int, optional) – Dimensionality of the target grain structure data used for tdist. Defaults to 2.
sgstype (str) – Type of the sample grain structure. Must be one of:
'upxo.mc2d','upxo.mc3d','upxo.pv2d','upxo.vv3d','upxo.v2d','upxo.v3d','image2d','image3d','ebsd2d'.
- Returns:
A new RepGen2DMCGS instance.
- Return type:
RepGen2DMCGS
- classmethod from_tstat_sgs(tstat=None, sgs=None, tdim=2, sgstype='upxo.mc2d')[source]
Alternative constructor for creating a RepGen2DMCGS instance using statistics data of target grain structure and sample grain structure.
The sample grain structure can be of the following types: - see description of sgstype parameter
- Parameters:
tstat (upxo statistics collection object, optional) – Statistics data of the target grain structure. Defaults to None.
sgs (grain structure data object, optional) – The sample grain structure. Defaults to None.
tdim (int, optional) – Dimensionality of the target grain structure data used for tstat. Defaults to 2.
sgstype (str) – Type of the sample grain structure. Must be one of:
'upxo.mc2d','upxo.mc3d','upxo.pv2d','upxo.vv3d','upxo.v2d','upxo.v3d','image2d','image3d','ebsd2d'.
- Returns:
A new RepGen2DMCGS instance.
- Return type:
RepGen2DMCGS
- classmethod from_tgs_sgs(tgs=None, sgs=None, tgstype='upxo.mc2d', sgstype='upxo.mc2d')[source]
Alternative constructor for creating a RepGen2DMCGS instance using actual target and sample grain structures.
The sample grain structure can be of the following types: - see description of sgstype parameter
- Parameters:
tgs (grain structure data object, optional) – The target grain structure. Defaults to None.
sgs (grain structure data object, optional) – The sample grain structure. Defaults to None.
tgstype (str, optional) – Type of the target grain structure. Must be one of:
'upxo.mc2d','upxo.mc3d','upxo.pv2d','upxo.vv3d','upxo.v2d','upxo.v3d','image2d','image3d','ebsd2d'. Defaults to'upxo.mc2d'.sgstype (str) – Type of the sample grain structure. Must be one of:
'upxo.mc2d','upxo.mc3d','upxo.pv2d','upxo.vv3d','upxo.v2d','upxo.v3d','image2d','image3d','ebsd2d'.
- Returns:
A new RepGen2DMCGS instance.
- Return type:
RepGen2DMCGS
- classmethod from_tgs(tgs=None, tgstype='upxo.mc2d', ebsd_file=None)[source]
Alternative constructor for creating a RepGen2DMCGS instance using only a target grain structure. A sample grain structure will be generated internally during the representativeness workflow.
- Parameters:
tgs (grain structure data object, optional) – The target grain structure. Defaults to None.
tgstype (str, optional) – Type of the target grain structure. Must be one of:
'upxo.mc2d','upxo.mc3d','upxo.pv2d','upxo.vv3d','upxo.v2d','upxo.v3d','image2d','image3d','ebsd2d'. Defaults to'upxo.mc2d'.ebsd_file (str or None, optional) – Path to an EBSD file (.ctf, .ang, .h5oina, etc.) associated with the target grain structure. Stored for future use only; no parsing is performed at construction time. Defaults to None.
- Returns:
A new RepGen2DMCGS instance with sgs=None.
- Return type:
RepGen2DMCGS
Notes
self.tgsholds the target grain structure;self.sgsis None until a sample is generated and assigned.self.ebsd_filestores the EBSD file path (not yet processed).
- set_px_size(px_size)[source]
Set the physical pixel size to use for area and length calculations. This value will overwrite the px_size stored inside every grain structure object before characterisation runs.
- Parameters:
px_size (float) – Physical size of one pixel (same units as the simulation domain).
Notes
Stored in
self.px_size.
- set_ebsd_step(step)[source]
Set the step size to use for EBSD-derived grain structures when calculating the ENSD metric. This value will be used to determine the neighborhood size for ENSD calculations.
- Parameters:
step (float) – Step size (in physical units) to use for EBSD-derived grain structures.
Notes
Stored in
self.ebsd_step.
- set_mpflags(area=True, aspect_ratio=True, perimeter=False, perimeter_crofton=False, eq_diameter=False, feret_diameter=False, compactness=False, solidity=False, circularity=False, eccentricity=False, euler_number=False, moments_hu=False, morph_ori=False, npixels=False, npixels_gb=False, gb_length_px=False, major_axis_length=False, minor_axis_length=False, bbox=True, bbox_ex=True, char_gb=False, char_grain_positions=False, get_grain_coords=True, identify_pixel_locations=True, make_skim_prop=True, saa=True, use_version=2)[source]
Set flags controlling which 2D morphological properties are computed during characterisation.
- Parameters:
area (bool) – Grain area (in px_size² units). Default True.
aspect_ratio (bool) – Aspect ratio (major / minor axis). Default True. Automatically enables major_axis_length and minor_axis_length.
perimeter (bool) – Grain perimeter. Default False.
perimeter_crofton (bool) – Crofton perimeter estimate. Default False.
eq_diameter (bool) – Equivalent circular diameter. Default False.
feret_diameter (bool) – Feret (maximum caliper) diameter. Default False.
compactness (bool) – Compactness (4π·area / perimeter²). Default False.
solidity (bool) – Solidity (area / convex hull area). Default False.
circularity (bool) – Circularity. Default False.
eccentricity (bool) – Eccentricity of best-fit ellipse. Default False.
euler_number (bool) – Euler number (topology). Default False.
moments_hu (bool) – Hu moments (7 invariants). Default False.
morph_ori (bool) – Morphological orientation angle. Default False.
npixels (bool) – Number of pixels per grain. Default False.
npixels_gb (bool) – Number of grain-boundary pixels. Default False.
gb_length_px (bool) – Grain boundary length in pixels. Default False.
major_axis_length (bool) – Major axis length of best-fit ellipse. Default False.
minor_axis_length (bool) – Minor axis length of best-fit ellipse. Default False.
bbox (bool) – Axis-aligned bounding box. Default True.
bbox_ex (bool) – Extended bounding box. Default True.
char_gb (bool) – Characterise grain boundaries. Default False.
char_grain_positions (bool) – Characterise grain centroid positions. Default False.
get_grain_coords (bool) – Store pixel coordinates per grain. Default True.
identify_pixel_locations (bool) – Identify pixel locations. Default True.
make_skim_prop (bool) – Store scikit-image region properties. Default True.
saa (bool) – Store skimage attribute access helper. Default True.
use_version (int) – Characterisation version (1 or 2). Default 2.
Notes
Stored in
self.mpflagsas a flat dict of flag name → bool/int.
- char_gs()[source]
Characterise the morphological properties of the available grain structure objects according to the current iroute:
‘tdist.sgs’ / ‘tstat.sgs’: only the sample grain structure (sgs) is characterised (tgs is not an UPXO object in these routes).
‘tgs.sgs’: both tgs and sgs are characterised, provided their type is in the UPXO image family (‘upxo.mc2d’, ‘upxo.pv2d’, ‘image2d’).
- Raises:
RuntimeError – If px_size has not been set via set_px_size().
RuntimeError – If mpflags have not been set via set_mpflags().
Notes
Results are stored directly on the grain structure objects:
sgs.prop(DataFrame),sgs.prop_flag,sgs.g[gid].skprop. Same fortgswhen iroute=’tgs.sgs’.
- find_neighbours(p=1.0, include_central_grain=False, throw_numba_dict=False, verbosity_nfids=1000)[source]
Find first-order grain neighbours for all characterised grain structure objects using find_neigh_v2().
Populates gs_obj.neigh_gid on each object.
- Parameters:
p (float) – Dilation probability for neighbour detection. Default 1.0.
include_central_grain (bool) – Include the grain itself in its neighbour list. Default False.
throw_numba_dict (bool) – Return a numba-typed dict instead of a plain Python dict. Default False.
verbosity_nfids (int) – Print progress every N grains. Default 1000.
Notes
Results stored in
sgs.neigh_gid(andtgs.neigh_gidwhen iroute=’tgs.sgs’) as dicts mapping grain ID → list of neighbour IDs.
- char_network(gsids=None, k_char_level='basic', recalculate_neighbours=False, include_central_grain=False)[source]
Build and characterise the grain network (graph) for the available grain structure objects using the UPXO gsan2d / kmodel pipeline.
Results are stored in self.gsan_sgs and (if iroute=’tgs.sgs’) self.gsan_tgs as gsan2d objects whose .K dict contains the kmodel.
- Parameters:
gsids (list or None) – List of grain structure IDs to pass to initiate_kmodel(). Defaults to [1].
k_char_level (str) – Level of graph characterisation: ‘none’, ‘basic’, ‘simple’, ‘full’, or ‘advanced’. Default ‘basic’.
recalculate_neighbours (bool) – Re-run find_neigh() inside initiate_kmodel(). Default False (assumes find_neighbours() has already been called).
include_central_grain (bool) – Include central grain when recalculating neighbours. Default False.
Notes
Graph objects stored in
self.gsan_sgsandself.gsan_tgs(gsan2dinstances). The NetworkX graph and metrics are accessible viaself.gsan_sgs.K[gsid](akmodelobject).
- compute_ebsd_stats()[source]
Compute per-property descriptive statistics across all grains in
prop_ebsdand store the result instat_ebsd.Statistics computed for every scalar property in
prop_ebsd: mean, std, min, max, median, 25th percentile (q25), 75th percentile (q75), and count (number of grains).Non-scalar properties (
centroid,bbox) are skipped.- Raises:
RuntimeError – If
prop_ebsdhas not been populated yet (callrechar()first).
Notes
Stored in
self.stat_ebsdas a dict: ``{property_name: {‘mean’: …, ‘std’: …, ‘min’: …,‘max’: …, ‘median’: …, ‘q25’: …, ‘q75’: …, ‘count’: …}}``
- see_distr(prop='area', source='ebsd', nbins=40, vis='hist', show_kde=True, show_stats=True, color='steelblue', figsize=(7, 4), log_scale=False, step_size=None)[source]
Visualise the distribution of a grain morphological property.
- Parameters:
prop (str) – Grain property name, e.g.
'area','perimeter','aspect_ratio','eq_diameter','solidity','eccentricity','major_axis_length','minor_axis_length','npixels'.source (str) –
Which grain structure to draw data from:
'ebsd'—self.prop_ebsd(EBSD target, dict of dicts). Requiresrechar()orcharacterise()to have been called.'sgs'—self.sgs.prop(simulated sample grain structure, pandas DataFrame). Requireschar_gs()to have been called.'tgs'—self.tgs.prop(non-EBSD target grain structure, pandas DataFrame). Requireschar_gs()to have been called.nbins (int) – Number of histogram bins. Default 40.
vis (str) – Plot style:
'hist','kde', or'hist_kde'. Default'hist'.show_kde (bool) – Overlay KDE on the histogram (
vis='hist'only). Default True.show_stats (bool) – Annotate mean and median lines. Default True.
color (str) – Histogram / KDE fill colour. Default
'steelblue'.figsize (tuple) – Figure (width, height) in inches. Default
(7, 4).log_scale (bool) – Log x-axis. Default False.
step_size (float or None) – Physical pixel size (µm) for x-label annotation. When
Noneandsource='ebsd', the value is not shown in the label (it is already embedded in the physical-unit values stored inprop_ebsd). Default None.
- Returns:
fig, ax
- Return type:
matplotlib Figure and Axes
- Raises:
RuntimeError – If the requested source has not been populated yet.
KeyError – If prop is not present in the property data.
ValueError – If source or vis is not one of the accepted values.
Examples
>>> fig, ax = rg.see_distr(prop='area', source='ebsd', nbins=40) >>> plt.show() >>> fig, ax = rg.see_distr(prop='aspect_ratio', source='sgs', ... vis='hist_kde') >>> plt.show()
- build_merged_ebsd_lfi(parent_info: dict, plot: bool = True) None[source]
Merge twin grains into their parents in a deepcopy of
lfi_ebsd, re-characterise, store results, and display a side-by-side comparison.Twin chains (A→B→C) are resolved so every twin maps to its ultimate root parent before the remapping is applied.
- Parameters:
parent_info (dict) – Output of
identify_parent_grains(). Keyed by CSL label; each value must have a'pairs_labeled'key containing a list of(parent_gid, twin_gid)tuples.plot (bool) – Render the automatic side-by-side original-vs-merged comparison figure. Default
True; the GUI’s compute step calls this withFalse(matching its compute/plot separation convention elsewhere on the same page) and shows the comparison from a separate plot action instead.Populates
---------
lfi_ebsd_merged (np.ndarray) – Copy of
lfi_ebsdwith twin pixels relabelled to their parent grain ID and then relabelled sequentially to 1…N.prop_ebsd_merged (dict) – Per-grain morphological property dict for the merged structure.
prop_ebsd_merged_df (pd.DataFrame) – DataFrame version of
prop_ebsd_merged(centroid and bbox excluded). Index name:'grain_id'.
- clean_and_rechar_from_rdr(rdr, connectivity=4, min_grain_size=0, verbose=True)[source]
Clean and re-characterise the EBSD target grain structure from an already-loaded (and optionally cropped)
EBSDReader, then assign all results to the correspondingrg.*_ebsdslots.Internally calls
rdr.characterise(connectivity, min_grain_size)which performs:Pixel filling — non-indexed / boundary pixels (values ≤ 0) are assigned to the spatially largest neighbouring grain and their orientations are updated (cleaning step).
Morphological characterisation — per-grain area, perimeter, aspect ratio, etc. via
skimage.measure.regionprops. Grains smaller thanmin_grain_sizepixels are excluded fromprop_ebsd.Neighbourhood graph — first-order grain adjacency via cc3d.
This is the preferred path when
rdrhas been built and cropped outsiderechar()— it avoids reloading the file from disk.- Parameters:
rdr (EBSDReader) – A populated (and optionally cropped)
EBSDReaderinstance.connectivity (int) – Pixel connectivity for cleaning and neighbour detection. 4 (edge-only) or 8 (edge + corner). Default 4.
min_grain_size (int, optional) – Minimum grain size in pixels. Grains with fewer pixels are excluded from
prop_ebsdafter characterisation. Default 0 (all grains included).verbose (bool) – Print a timing and grain-count summary on completion. Default True.
Notes
Populated slots after return:
lfi_ebsd,euler_ebsd,quat_ebsd,neigh_gid_ebsd,prop_ebsd.
- rechar(target='tgs', connectivity=4, k_char_level='basic', gsids=None, min_grain_size=10, misori_tol=10)[source]
Quickly re-detect grains, re-compute first-order neighbourhood, and build the grain network model.
For standard UPXO grain structure types (
'upxo.mc2d','upxo.pv2d','image2d') this delegates to cc3d: -upxo.gsdataops.grid_ops.detect_grains_cc3d— grain labelling -upxo.gsdataops.gid_ops.find_neighs2d— neighbourhood -upxo.analysis.analysis2d.gsan2d+initiate_kmodel— networkFor
'ebsd2d'(whentgstype='ebsd2d'andtargetincludes'tgs') the EBSD file stored inself.ebsd_fileis loaded viaEBSDReader.from_file(). The extracted arrays are stored onselfand the neighbourhood is computed fromlfi_ebsd. Fullgsan2dnetwork characterisation is not yet supported for the'ebsd2d'route.- Parameters:
target (str) – Which grain structure(s) to re-characterise:
'sgs','tgs', or'both'. Default'tgs'.connectivity (int) – cc3d connectivity. Valid 2D values: 4 (edge-only) or 8 (edge+corner). Default 4.
k_char_level (str) – Level of graph characterisation passed to
initiate_kmodel:'none','basic','simple','full', or'advanced'. Default'basic'.gsids (list or None) – Grain structure IDs passed to
initiate_kmodel. Default [1].min_grain_size (int, optional) – Minimum grain size in pixels for EBSD grain detection. Passed to
EBSDReader.from_file(). Default 10.misori_tol (float, optional) – Misorientation tolerance in degrees for EBSD grain boundary detection. Passed to
EBSDReader.from_file(). Default 10.
- Raises:
ValueError – If
targetis not one of the accepted values.ValueError – If
connectivityis not 4 or 8.RuntimeError – If
tgstype='ebsd2d'butself.ebsd_fileis not set.
Notes
Standard route — results written onto each grain structure object:
gs_obj.lgi,gs_obj.n_grains,gs_obj.neigh_gid. Network models inself.gsan_sgs/self.gsan_tgs.EBSD route — arrays stored on
self:self.lfi_ebsd(int32, ny×nx),self.euler_ebsd(float64, ny×nx×3, radians),self.quat_ebsd(float64, ny×nx×4),self.neigh_gid_ebsd(dict grain_id → list of neighbour IDs).
- compute_mdf_ebsd(n_bins=65, angle_range=(0.0, 65.0), prominence=0.002, distance=3, csl=None, csl_tol=2.0, bw_method='scott', n_kde=500, plot=True)[source]
Compute the misorientation distribution function (MDF) from the EBSD dataset attached to this repgen2d instance and display it.
Prerequisites
clean_and_rechar_from_rdr(orrechar) must have been called withtgstype='ebsd2d'beforehand so thatself.lfi_ebsd,self.quat_ebsd, andself.neigh_gid_ebsdare populated.- param n_bins:
Forwarded to
compute_mdf_from_quats. Default 65.- type n_bins:
int
- param angle_range:
Forwarded to
compute_mdf_from_quats. Default (0.0, 65.0).- type angle_range:
tuple(float, float)
- param prominence:
Forwarded to
detect_mdf_peaks. Default 0.002.- type prominence:
float
- param distance:
Forwarded to
detect_mdf_peaks. Default 3.- type distance:
int
- param csl:
Forwarded to
detect_mdf_peaks. Default None (built-inCUBIC_CSLtable).- type csl:
dict or None
- param csl_tol:
Forwarded to
detect_mdf_peaks. Default 2.0.- type csl_tol:
float
- param bw_method:
Forwarded to
detect_mdf_peaks. Default ‘scott’.- type bw_method:
str or float
- param n_kde:
Forwarded to
detect_mdf_peaks. Default 500.- type n_kde:
int
- param plot:
If True (default, matching prior unconditional behaviour), render the MDF histogram via
ebsdviz.plot_mdf+plt.show(). Callers that re-run this repeatedly while tuning parameters (e.g. an interactive GUI) should passplot=Falseto avoid a popup window on every call.- type plot:
bool
- returns:
mdf (np.ndarray) – 1-D array of grain-boundary misorientation angles (degrees) for every unique neighbour pair found in the EBSD map.
peaks (dict) – Peak-detection results with keys
'peak_indices','peak_labels', and'peak_angles'. Pass directly tonbWidgets.mdf_peak_selectorfor interactive peak selection.Side Effects
————
When
plot=True, callsebsdviz.plot_mdfandplt.show(),rendering the MDF histogram with detected peaks in the current
matplotlib backend.
- segregate_csl_pairs(mdf, selected_peaks, csl, csl_tol)[source]
Segregate grain-boundary pairs by coincidence site lattice (CSL) type.
Classifies every unique grain-boundary pair in the EBSD dataset into its nearest CSL relationship based on the peaks the user retained via the interactive widget. Delegates to
crystal_orientation.segregate_csl_pairsand prints a summary table.- Parameters:
mdf (dict) – Output of
compute_mdf_ebsd()(or directly fromcrystal_orientation.compute_mdf_from_quats()). Must contain'pairs'(N, 2) and'miso_deg'(N,).selected_peaks (dict) – Output of
select_mdf_peaks()after the user has confirmed their selection. Keys:'angles'(list of float) and'indices'(list of int).csl (dict or None) –
{label: reference_angle_degrees}mapping. Enterpeaks['csl'](the CSL dict used during MDF peak detection). PassNoneto fall back to the built-inCUBIC_CSLtable.csl_tol (float) – Tolerance in degrees; pairs within this distance of a CSL reference angle are included in that category. Input
peaks['csl_tol']from the peak-detection step.
- Returns:
csl_grains (dict) – A dict keyed by CSL label (e.g.
'Σ3'); each value is a dict with:csl_angle: float — reference misorientation angle (degrees)pairs: ndarray (M, 2) — grain-ID pairs at this boundary typemiso_deg: ndarray (M,) — disorientation of those pairs (degrees)grains_A: ndarray — unique grain IDs on one side of the boundarygrains_B: ndarray — unique grain IDs on the other sidegrains_all: ndarray — all unique grain IDs touching this boundary type
Side Effects
————
Prints a summary table with columns
CSL type,ref °,pairs, andgrainsfor every CSL category found.
- select_mdf_peaks(peaks)[source]
Launch the interactive ipywidgets checklist for selecting MDF peaks.
Wraps
nbWidgets.mdf_peak_selector(re-exported viaebsdviz) to display a checkbox panel in Jupyter so the user can choose which detected MDF peaks to retain for downstream CSL segregation.- Parameters:
peaks (dict) – Output of
compute_mdf_ebsd()(or directly fromcrystal_orientation.detect_mdf_peaks()). Must contain'peak_indices','peak_labels', and'peak_angles'.- Returns:
selected_peaks – Live state dict with keys
'angles'(list of float) and'indices'(list of int), pre-populated with all peaks and updated in-place when the user clicks Confirm selection. Pass this dict tosegregate_csl_pairs()orself.segregate_csl_pairs().- Return type:
Notes
Must be called inside a Jupyter cell. The returned dict is updated asynchronously on button click; read it in a subsequent cell after confirming the selection.
- plot_mdf_selected(mdf, peaks, selected_peaks)[source]
Replot the MDF histogram and KDE highlighting only the user-selected peaks; unselected histogram bins are greyed out.
Wraps
ebsdviz.plot_mdf_selected, passing themdfandpeaksdicts that must exist in the calling notebook scope (produced bycompute_mdf_ebsd()).- Parameters:
mdf (ndarray) – The MDF histogram data.
peaks (dict) – Output of
compute_mdf_ebsd()(or directly fromcrystal_orientation.detect_mdf_peaks()). Must contain'peak_indices','peak_labels', and'peak_angles'.selected_peaks (dict) – Output of
select_mdf_peaks()after the user has confirmed their selection via the widget. Keys:'angles'(list of float) and'indices'(list of int).
- Returns:
The figure is rendered via
plt.show(). Selected peak angles are printed to stdout.- Return type:
None
Notes
mdfandpeaksmust be defined in the calling scope (typically the notebook cell that calledcompute_mdf_ebsd()).
- see_csl_grain_map(csl_grains, **kwargs)[source]
Render a colour-coded grain map showing CSL boundary participation for the EBSD target grain structure.
Each CSL type present in csl_grains is assigned a distinct colour. Grains touching boundaries of more than one CSL type are shown with blended colours; non-CSL grains are displayed in semi-transparent light grey. Wraps
ebsdviz.plot_csl_grain_mapusingself.lfi_ebsdas the grain label field.- Parameters:
csl_grains (dict) – Output of
segregate_csl_pairs(). Keys are CSL labels (e.g.'Σ3'); each value must contain'grains_all','n_pairs', and'n_grains'.- Returns:
None – The figure is rendered via
plt.show().Prerequisites
————-
clean_and_rechar_from_rdr()must have been called so thatself.lfi_ebsdis populated, andsegregate_csl_pairs()must have been called to produce *csl_grains.*
- compute_csl_volume_fractions(csl_grains)[source]
Compute and display the area fraction of the EBSD map occupied by grains participating in each CSL boundary type.
A grain is counted for a CSL category if it appears in at least one boundary of that type (i.e. it is in
csl_grains[label]['grains_all']). Grains can contribute to multiple categories, so fractions need not sum to 1. Delegates tocrystal_orientation.csl_volume_fractions, then prints a summary table and renders a bar chart of volume fractions.- Parameters:
csl_grains (dict) – Output of
segregate_csl_pairs(). Keys are CSL labels (e.g.'Σ3'); each value must contain'grains_all','csl_angle','n_grains', and'n_pairs'.- Returns:
None – Results are printed as a table and displayed as a bar chart via
plt.show(). Thevfdict (keyed by CSL label) contains per-label dicts with:n_pixels: int — pixels occupied by CSL grainsvf_indexed: float — fraction of indexed pixelsvf_total: float — fraction of all pixels (incl. unindexed)csl_angle: float — reference CSL angle (degrees)n_grains: int — number of grains in this CSL type
Prerequisites
————-
clean_and_rechar_from_rdr()must have been called so thatself.lfi_ebsdis populated, andsegregate_csl_pairs()must have been called to produce *csl_grains.*
- identify_parent_grains(csl_grains, **kwargs)[source]
Identify parent, twin, and intermediate grains for each CSL boundary type in the EBSD target and display a summary.
Uses grain area (from
self.prop_ebsd) to label each pair in csl_grains as parent (larger grain) vs twin/child (smaller grain). A grain’s net role is determined across all pairs it participates in:pure_parents — larger grain in every one of their pairs
pure_twins — smaller grain in every one of their pairs
intermediates — parent in some pairs, twin in others (twin chains)
Delegates computation to
crystal_orientation.identify_parent_grains, then callsebsdviz.print_parent_grain_summaryandebsdviz.plot_parent_grain_summary. Optionally overlays a spatial parent/twin map onself.lfi_ebsd.- Parameters:
csl_grains (dict) – Output of
segregate_csl_pairs(). Keys are CSL labels; each value must contain'pairs'and'csl_angle'.**kwargs –
Optional display controls:
figsize: tuple — figure size for the summary bar chart (default(8, 4))dpi: int — DPI for the summary chart (default120)title: str — title for the summary chartplot_parent_twin_map: bool — ifTrue, also render a spatial grain map coloured by role (defaultFalse)map_figsize: tuple — figure size for the spatial map (default(6, 6))map_dpi: int — DPI for the spatial map (default140)map_suptitle: str — super-title for the spatial map
- Returns:
parent_info (dict) – Keyed by CSL label; each value is a dict with:
pairs_labeled: list of(parent_gid, twin_gid)tuplesall_parents: ndarray — grains that are parent in ≥1 pairall_twins: ndarray — grains that are twin in ≥1 pairpure_parents: ndarray — grains that are only ever a parentpure_twins: ndarray — grains that are only ever a twinintermediates: ndarray — grains in both roles (twin chains)n_pure_parents: intn_pure_twins: intn_intermediates: intcsl_angle: float — reference CSL angle (degrees)
Prerequisites
————-
clean_and_rechar_from_rdr()must have been called so thatself.prop_ebsd(grain area data) andself.lfi_ebsd(if
plot_parent_twin_map=True) are populated.
- compute_ebsd_tvf(parent_info: dict, csl_label: str | None = None) dict[source]
Compute EBSD twin area fraction broken down by grain role.
Uses
classify_grain_roles_extended()to splitpure_twinsinto primary twins (1st generation) and secondary twins (2nd generation / twins-of-twins).- Parameters:
parent_info (dict) – Output of
identify_parent_grains().csl_label (str or None) – CSL type to analyse (e.g.
'Σ3'). WhenNone(default), the first key inparent_infois used automatically. Passlist(parent_info.keys())to see available labels.
- Returns:
'csl_label'— the CSL label actually used'total_area'— sum of all grain areas inprop_ebsd'pure_parent_frac'— area fraction of pure-parent grains'primary_twin_frac'— area fraction of 1st-gen twin grains'secondary_twin_frac'— area fraction of 2nd-gen twin grains'intermediate_frac'— area fraction of intermediate grains'overall_twin_frac'— total twin area fraction(primary + secondary + intermediates)
'extended_info'— full output ofclassify_grain_roles_extended
- Return type:
- compute_ebsd_texture_stages(parent_info: dict, csl_label: str | None = None) dict[source]
Compute per-grain mean orientations for the five EBSD-only pole-figure visualization stages (see admin/twinnedFccGui/texIntegration/scoping.md §6.1 in the UPXO repo for the full rationale): Full EBSD, EBSD parents (twins merged back into their host), EBSD Primary twins, EBSD Secondary twins (undifferentiated), and All EBSD twins.
Uses
grain_avg_quats()to collapse the per-pixelself.quat_ebsdarray down to one representative orientation per grain, andclassify_grain_roles_extended()(the same functioncompute_ebsd_tvf()uses) to split twins into primary/secondary generations.- Parameters:
parent_info (dict) – Output of
identify_parent_grains().csl_label (str or None) – CSL type to analyse (e.g.
'S3 (twin)'). WhenNone(default), the first key inparent_infois used automatically.
- Returns:
'csl_label'— the CSL label actually used'full'—{'gids': ndarray, 'quats': ndarray}for every grain in
self.lfi_ebsd'parents'— same shape, for the twin-mergedparent-state structure (
self.lfi_ebsd_merged, built on demand if not already present)'primary_twins'— same shape, restricted tofirst-generation twin grain IDs
'secondary_twins'— same shape, restricted tosecond-generation+ twin grain IDs
'all_twins'—primary_twinsandsecondary_twinscombined
Every stage’s
(gids, quats)pair is ready to pass directly intoPoleFigure(quats, gids=gids, convention='quaternion').- Return type:
- allocate_mc_twin_hosts(cntr, mc_slices: list, target_fraction: float | None = None, size_criterion: str = 'area', min_host_px: int = 0) dict[source]
Designate which MC grains will host twin regions, matching the EBSD twin-hosting fraction.
The target fraction is taken from
self.merge_info['twin_hosting_fraction'](computed automatically bybuild_merged_ebsd_lfi()) unless overridden bytarget_fraction.Grains are ranked by
size_criterionin descending order — the largest grains are designated hosts first, reflecting that larger grains are more likely to nucleate and retain twins.- Parameters:
cntr (MC_GS_Container2d)
mc_slices (list) – MC time-slice keys to allocate.
target_fraction (float or None) – Fraction of MC grains to designate as twin hosts. Defaults to
self.merge_info['twin_hosting_fraction'].size_criterion (str) – Column in
cntr.gsset[k].propused to rank grains. Default'area'.min_host_px (int) – Grains with fewer pixels than this are excluded from host consideration before the ranking/selection step. Default 0 (no filtering, backward-compatible).
- Returns:
- ``{slice_key: {
’host_gids’: np.ndarray, ‘non_host_gids’: np.ndarray, ‘n_total’: int, ‘n_hosts’: int, ‘actual_fraction’: float, ‘target_fraction’: float,
}}``
- Return type:
- plot_mc_host_properties(cntr, mc_twin_hosts: dict, parent_info: dict, props: list | None = None, csl_label: str | None = None, ncols_spatial: int = 2, figsize_spatial: tuple = (10, 4), figsize_prop: tuple = (10, 4), dpi: int = 100, fontsize: float = 9.0) None[source]
Visualise MC host grains and compare their morphological property distributions against EBSD pure-parent grain properties.
Produces two figures:
Spatial maps — one subplot per selected MC slice; host grains in steel-blue, non-host grains in light-grey, background white.
Property distributions — one subplot per property; KDE of MC host grain values (one coloured line per slice) overlaid on the EBSD pure-parent KDE (dashed black line).
- Parameters:
cntr (MC_GS_Container2d) – Container with
.gssetdict (same object passed tosgs_mcgs2Gen()).mc_twin_hosts (dict) – Output of
allocate_mc_twin_hosts().parent_info (dict) – Output of
identify_parent_grains().props (list of str or None) – Properties to compare. Defaults to
['area', 'aspect_ratio', 'eq_diameter'].csl_label (str or None) – Which CSL key to use when extracting EBSD pure parents. Auto-selects first key when None.
ncols_spatial (int) – Columns in the spatial-map figure.
figsize_spatial (tuple) – Figure sizes in inches.
figsize_prop (tuple) – Figure sizes in inches.
dpi (int)
fontsize (float)
- assign_mc_parent_orientations(cntr, mc_twin_hosts: dict, parent_info: dict, csl_label: str | None = None, mdf: dict | None = None, csl_grains: dict | None = None, s5_tol_deg: float = 1.0, ang_scatter_gaussian_deg: float = 2.0, rng_seed=None) dict[source]
Assign EBSD pure-parent quaternions to the MC host grains identified by
allocate_mc_twin_hosts().Uses a neighbour-conflict-free sampling strategy: no two adjacent host grains receive the same quaternion (which would give zero misorientation — physically impossible for a grain boundary). If the EBSD parent pool is smaller than required, additional FCC-texture orientations are generated via
tops.synth_fcc_quatsas a fallback.When mdf is supplied, a post-assignment S5 seeding pass seeds Σ5 (36.87° /<100>) relationships between a fraction of adjacent host-grain pairs matching the EBSD S5 boundary fraction. The replacement quaternions are synthetic (derived analytically from the pair partner’s orientation, not sampled from the EBSD pool); the extent of this approximation is printed to the console.
- Parameters:
cntr (MC_GS_Container2d) – Container with
.gssetdict.mc_twin_hosts (dict) – Output of
allocate_mc_twin_hosts().parent_info (dict) – Output of
identify_parent_grains().csl_label (str or None) – CSL key to select pure parents from parent_info. Auto-selects first key when None.
mdf (dict or None) – EBSD MDF dict from
compute_mdf_ebsd(). When provided, enables S5 boundary seeding.csl_grains (dict or None) – Output of
segregate_csl_pairs()(§9). When provided, the EBSD Σ5 fraction is taken directly from the genuine Σ5 boundary count incsl_grains, which is far more accurate than the histogram background-subtraction fallback.s5_tol_deg (float) – Half-width (°) of the S5 peak window used only when csl_grains is
None(histogram fallback, default 1°).ang_scatter_gaussian_deg (float) – Gaussian σ (°) of the small random rotation added to each seeded S5 quaternion to reproduce the angular spread seen in EBSD (default 2.0°). Set to 0 for exact 36.87° misorientations.
rng_seed (int or None) – Seed for reproducibility.
- Returns:
Keyed by MC time-slice. Each value is the dict returned by
assign_parent_orientations: ``{‘host_quats’: {gid: ndarray(4,)}, ‘pool_size’: int,’n_hosts’: int, ‘n_fallback’: int}``.
Also stored in
mc_host_orientations.- Return type:
- plot_mc_parent_mdf(cntr, mc_host_orientations: dict, mdf: dict, slice_key=None, n_bins: int = 65, angle_range: tuple = (0.0, 65.0), figsize: tuple = (6, 4), dpi: int = 100, fontsize: float = 9.0) dict[source]
Compare the neighbour-misorientation distribution of the assigned MC host-grain orientations against the reference EBSD MDF.
- Parameters:
cntr (MC_GS_Container2d) – Container with
.gssetdict.mc_host_orientations (dict) – Output of
assign_mc_parent_orientations().mdf (dict) – EBSD MDF dict returned by
compute_mdf_ebsd()(§5).slice_key (int, list, or None) –
None→ all keys in mc_host_orientations;int→ that one slice;list→ those slices (accepts the output ofbest_match_mcgs_key()directly).n_bins (int) – Histogram bins for each MC MDF.
figsize (plot parameters.)
dpi (plot parameters.)
fontsize (plot parameters.)
- Returns:
{slice_key: mc_mdf_dict, ...}— one entry per plotted slice.- Return type:
- compute_mc_twin_thickness(parent_info: dict, abrupt_threshold: float = 0.8, linear_intercept_axes: list | None = None, linear_intercept_n_lines: int | dict = 20) dict[source]
Compute EBSD twin lamella thickness and intercept-length statistics.
Calls
compute_twin_thickness_stats()(with abrupt-twin detection) and pools per-grain intercept lengths across all EBSD twin grains to derive Q1/Q2/Q3 quantiles (viacompute_grain_intercept_lengths(), measured perpendicular to each grain’s OWN major axis).Additionally (additive, not a replacement) computes the classical (ASTM E112-style) linear-intercept method via
compute_linear_intercepts_2d(): fixed lab-frame test lines (independent of each grain’s own shape), along whichever of X (horizontal lines)/Y (vertical lines)/Z (diagonal lines) axes are requested.- Parameters:
parent_info (dict) – Output of
identify_parent_grains().abrupt_threshold (float) – Twin extent / parent extent ratio below which a twin is counted as abruptly-ending. Default 0.8.
linear_intercept_axes (list of str or None) – Subset of
['x', 'y', 'z']– which lab-frame directions to cast linear-intercept test lines along. Defaults to all three.linear_intercept_n_lines (int or dict) – Number of test lines per axis. Either one int applied uniformly to every axis in
linear_intercept_axes, or a{'x': int, 'y': int, 'z': int}dict for a different count per axis.
- Returns:
Combined thickness + intercept stats dict. Keys include
'thick_px','intercept_px','intercept_q1','intercept_q2','intercept_q3'(per-grain major-axis method),'linear_intercept_by_axis'(dict {axis: ndarray}),'linear_intercept_px'(pooled across enabled axes),'linear_intercept_q1/q2/q3'(from the pooled array),'n_abrupt_ebsd','abrupt_frac_ebsd', and all keys fromcompute_twin_thickness_stats().- Return type:
- introduce_mc_twin_lamellae(cntr, mc_twin_hosts: dict, mc_host_orientations: dict, twin_thickness: dict, tvf: dict, csl_label: str = 'S3 (twin)', n_twins_per_parent: int = 1, ang_scatter_gaussian_deg: float = 3.0, twin_orient_scatter_deg: float = 1.5, rng_seed=None) dict[source]
Introduce S3 twin lamellae into MC host grains.
For each slice in mc_twin_hosts:
Primary twins are introduced into each host grain using a lamella angle derived from the host’s crystal orientation (projection of the active {111} trace onto XY) and a half-width sampled from the EBSD twin-thickness distribution.
A fraction
twin_thickness['abrupt_frac_ebsd']of lamellae are truncated to end abruptly inside the host grain.Secondary twins are introduced into a subset of primary-twin grains when
tvf['secondary_twin_frac'] > 0.
- Returns:
- ``{sk: {‘twin_result_agg’: …, ‘sec_twin_result_agg’: …,
’all_quats’: …, ‘n_abrupt_mc’: int, ‘abrupt_frac_mc’: float}}``
- Return type:
dict (also stored in
self.mc_twin_geom)
- plot_mc_twin_mdf(cntr, mc_twin_geom: dict, mc_twin_hosts: dict, mdf: dict, tvf: dict, n_bins: int = 65, angle_range: tuple = (0.0, 65.0), figsize: tuple = (6, 4), dpi: int = 100, fontsize: float = 9.0, kde: bool = False, kde_bw: str | float = 0.1, kde_n_points: int = 500, show_peaks: bool = False, peak_prominence: float = 0.002) dict[source]
MDF of all oriented grain-boundary pairs in the post-twin MC structure overlaid on the reference EBSD MDF. Volume fractions are annotated in the legend so the user can gauge twin-area accuracy at a glance.
- Parameters:
kde (bool) – If True, plot smooth KDE curves instead of histogram density. When enabled only KDE curves are drawn (no histogram).
kde_bw (str or float) – KDE bandwidth passed to
scipy.stats.gaussian_kde.0.1(default, ≈1.5° effective bandwidth),'scott','silverman', or any scalar factor.kde_n_points (int) – Number of evaluation points for the KDE grid.
show_peaks (bool) – When
kde=True, annotate detected peaks. EBSD peaks are marked with vertical dotted lines; MC peaks similarly as thin coloured dotted vertical lines.peak_prominence (float) – Minimum prominence for
scipy.signal.find_peaks.
- Return type:
dict
{sk: mc_mdf_dict}
- visualize_mc_twin_lamellae(cntr, mc_twin_geom: dict, mc_twin_hosts: dict, parent_info: dict, tvf: dict, figsize_per_slice: tuple = (5, 4), dpi: int = 100, ncols: int = None, show_ebsd: bool = True) None[source]
Spatial maps of introduced twin lamellae: EBSD reference + one MC slice per subplot.
Pixel colours (all subplots): - grey
#b0b0b0— non-participating grains - blue#4682b4— host / pure-parent grains - orange#ff8c00— primary twin grains - red#cc2222— secondary twin grainsSubplot titles carry pixel-based volume fractions. The first subplot is the EBSD reference; subsequent subplots are the MC slices.
- Parameters:
parent_info (dict) – Output of
identify_parent_grains— used to colour EBSD grains.tvf (dict) – Output of
compute_ebsd_tvf— suppliescsl_label,extended_info, and EBSD volume fractions.ncols (int, optional) – Subplot grid columns. Default = all in a single row.
show_ebsd (bool) – Include the EBSD reference panel. Default
True. Set toFalseto plot only the MC slice panels.
- compare_twin_intercepts(cntr, mc_twin_geom: dict, twin_thickness: dict, figsize: tuple = (6, 4), dpi: int = 100, fontsize: float = 9.0) dict[source]
Overlay EBSD vs MC twin intercept-length distributions.
For each MC slice the intercept lengths of introduced twin grains are pooled and plotted as a KDE curve against the EBSD reference pool (already stored in
twin_thickness['intercept_px']).- Return type:
dict
{sk: intercept_px_array}
- plot_ipf_maps(cntr, mc_twin_geom: dict, sample_direction: tuple = (0.0, 0.0, 1.0), figsize_per_panel: tuple = (4, 3), dpi: int = 100, fontsize: float = 9.0, ncols: int | None = None, show_ebsd: bool = True) None[source]
IPF orientation maps for the EBSD reference and every MC post-twin slice in mc_twin_geom, arranged in a grid.
Colours encode the crystal direction parallel to sample_direction using the standard
|R(q).T @ sd|formula (same ascrystal_orientation.ipf_color). Pixels whose grain has no assigned orientation are rendered grey.- Parameters:
cntr (MC_GS_Container2d) – Container with
.gssetdict.mc_twin_geom (dict) – Output of
introduce_mc_twin_lamellae(); each value must contain'all_quats'{gid: ndarray(4,)}.sample_direction (tuple of 3 floats) – Reference direction (crystal direction to project onto).
(0,0,1)= ND (normal direction, default),(1,0,0)= RD (rolling direction).figsize_per_panel ((float, float)) – Width × height (inches) of each subplot.
dpi (plot parameters.)
fontsize (plot parameters.)
ncols (int or None) – Number of columns in the subplot grid.
None(default) puts all panels in a single row.show_ebsd (bool) – Include the EBSD reference panel. Default
True. Set toFalseto plot only the MC slice panels.
- assign_mc_nonhost_orientations(cntr, mc_twin_geom: dict, rng_seed=None) None[source]
Assign orientations to all MC grains not already in mc_twin_geom
'all_quats'by sampling from the EBSD grain-average quaternion pool.Mutates mc_twin_geom in place. Host and twin grains already present in
'all_quats'are not overwritten.- Parameters:
cntr (MC_GS_Container2d) – Container with
.gssetdict.mc_twin_geom (dict) – Output of
introduce_mc_twin_lamellae();'all_quats'is extended for each slice.rng_seed (int or None) – Seed for the random number generator.
- smooth_mc_slices(cntr, slice_keys: list | None = None, area_threshold: int = 1, smooth_iter: int = 10, smooth_lambda: float = 0.5, smooth_mu: float = -0.53, trim_bounds=(5, 5, 95, 95), coord_decimals: int = 6, verbose: bool = True, method: str = 'taubin', ma_window: int = 3, corner_angle_deg: float = 30.0, upscale_factor: int = 1, thin_grain_px: float = 0.0, fix_diagonal: bool = True, merge_enclosed: bool = True, close_staircase: bool = True, **seed_kwargs) dict[source]
Smooth the grain geometry for one or more MC slices and store the result in
self.mc_smooth_geom.Each slice is processed by
upxo.pxtalops.gssmooth2d.smooth_gs_slice()(small-grain merge → tessellation → Taubin smooth → trim → neighbour graph → GID renumbering → validation → interface extraction → junction extraction).- Parameters:
cntr (MC_GS_Container2d) – Container with
.gsset {sk: gs}.slice_keys (list or None) – Keys to process.
Noneprocesses all keys incntr.gsset.area_threshold (int) – Grains with <= this many pixels are merged before tessellation.
smooth_iter (int) – Taubin smoothing iterations.
smooth_lambda (float) – Taubin forward-pass weight.
smooth_mu (float) – Taubin backward-pass weight (negative).
trim_bounds (tuple or dict) –
(xmin%, ymin%, xmax%, ymax%)as percentages (0–100) of each slice’s LFI dimensions, applied uniformly, or{sk: (xmin%, ymin%, xmax%, ymax%)}for per-slice values. Converted to pixel coordinates internally usinggs.lgi.shape.coord_decimals (int) – Decimal places for junction-point coordinate rounding.
verbose (bool) – Print per-slice progress.
**seed_kwargs – Forwarded to
generate_constrained_hybrid_seedswhen seeds are generated internally (e.g.target_spacing,bulk_spacing).
- Returns:
{sk: smooth_gs_slice_result_dict}— also stored inself.mc_smooth_geom.- Return type:
- smooth_parent_and_twin_geometric(cntr, mc_host_orientations: dict, twin_thickness: dict, tvf: dict, slice_keys: list | None = None, area_threshold: int = 1, smooth_iter: int = 10, smooth_lambda: float = 0.5, smooth_mu: float = -0.53, trim_bounds=(5, 5, 95, 95), coord_decimals: int = 6, method: str = 'taubin', ma_window: int = 3, corner_angle_deg: float = 30.0, upscale_factor: int = 1, thin_grain_px: float = 0.0, fix_diagonal: bool = True, merge_enclosed: bool = True, close_staircase: bool = True, n_twins_per_parent: int = 1, twin_orient_scatter_deg: float = 1.5, verbose: bool = True, rng_seed: int | None = None, **seed_kwargs) dict[source]
Route 2 pipeline — geometric twin introduction in Shapely polygon space.
Steps
- A Smooth the PARENT-ONLY MC grain structure (
gs.lgibefore twin introduction via
introduce_mc_twin_lamellae).- B Map parent quaternions from
mc_host_orientationsonto smooth polygon GIDs using a
cKDTreeof pixel centres.- C Introduce S3 twin lamellae geometrically: each host polygon is
intersected with an oriented Shapely rectangle whose angle comes from
compute_s3_lamella_angle_2dand whose half-width is sampled fromtwin_thickness['thick_px'].- D Rebuild topology (GID renumbering, neighbour graph, interfaces,
junction points) using the same Steps 5–11 logic as
smooth_gs_slice.
The result is stored in
self.mc_smooth_geom_r2.Important
This method must be called BEFORE
introduce_mc_twin_lamellae(§32 in the demo notebook), because that method overwritesgs.lgiin-place. After §32, the parent-only LFI is gone.- param cntr:
Container with
.gsset {sk: gs}.- type cntr:
MC_GS_Container2d
- param mc_host_orientations:
{sk: {'all_quats': {orig_gid: quaternion}}}— output ofassign_mc_parent_orientations.- type mc_host_orientations:
dict
- param twin_thickness:
Output of
compute_mc_twin_thickness. Must contain key'thick_px'(1-D array of half-widths in px) and optionally'abrupt_frac_ebsd'.- type twin_thickness:
dict
- param tvf:
Twin volume fraction dict.
tvf.get('secondary_twin_frac', 0.0)controls secondary twinning (currently reserved).- type tvf:
dict
- param slice_keys:
Keys to process.
Noneprocesses all keys incntr.gsset.- type slice_keys:
list or None
- param area_threshold:
- param smooth_iter:
- param smooth_lambda:
- param smooth_mu:
- param trim_bounds:
:param : :param coord_decimals: :param method: :param ma_window: :param corner_angle_deg: :param upscale_factor: :param : :param thin_grain_px: Forwarded to
smooth_gs_slice(same semantics assmooth_mc_slices).- param fix_diagonal:
Forwarded to
smooth_gs_slice(same semantics assmooth_mc_slices).- param merge_enclosed:
Forwarded to
smooth_gs_slice(same semantics assmooth_mc_slices).- param close_staircase:
Forwarded to
smooth_gs_slice(same semantics assmooth_mc_slices).- param n_twins_per_parent:
Number of twin strips to cut per host grain.
- type n_twins_per_parent:
int
- param twin_orient_scatter_deg:
Gaussian angular scatter on twin quaternion (degrees).
- type twin_orient_scatter_deg:
float
- param verbose:
Print per-slice progress.
- type verbose:
bool
- param rng_seed:
Seed for the random generator used in twin placement.
- type rng_seed:
int or None
- param **seed_kwargs:
Forwarded to
generate_constrained_hybrid_seeds.- returns:
{sk: result_dict}— also stored inself.mc_smooth_geom_r2. Each result dict contains:cells,polygon_neighbors,validity_report,cell_pairs_list,cell_pair_interfaces,junction_points,jp_dict,old_to_new_gid,n_grains,n_invalid,smooth_quats,twin_gids_map.- rtype:
dict
- A Smooth the PARENT-ONLY MC grain structure (
- assign_smooth_orientations(cntr, mc_twin_geom: dict, slice_keys: list | None = None) dict[source]
Map crystallographic orientations from the pixellated twinned MC grain structure onto the smoothed polygon grain structure stored in
self.mc_smooth_geom.For each smoothed polygon, Shapely’s
representative_point()(guaranteed strictly inside the polygon) is queried against acKDTreeof pixel centres built from the original pixellated LFI. The grain ID at the nearest pixel is looked up inmc_twin_geom[sk]['all_quats'].This approach is robust to three failure modes that break centroid- or
old_to_new_gid-based mapping: (1)cc3dGID relabeling inside_merge_small_grains; (2)trim_to_rveclipping of boundary polygons; (3) thin twin lamellae fragmenting into multiple globular polygons.Result stored in
self.mc_smooth_quats = {sk: {new_gid: quaternion}}.- Parameters:
cntr (MC_GS_Container2d) – Container with
.gsset {sk: gs};gs.lgiis the pixellated LFI.mc_twin_geom (dict) – Output of
introduce_mc_twin_lamellae()— provides'all_quats' {orig_gid: np.ndarray(4,)}per slice.slice_keys (list or None) – Slices to process.
Noneprocesses all keys inself.mc_smooth_geom.
- Returns:
{sk: {new_gid: np.ndarray(4,)}}— also stored inself.mc_smooth_quats.- Return type:
- plot_smooth_ipf_comparison(cntr, mc_twin_geom: dict, slice_keys: list | None = None, sample_direction: tuple = (0.0, 0.0, 1.0), show_pixellated: bool = True, ncols: int | None = None, figsize_per_panel: tuple = (4, 4), dpi: int = 150, fontsize: float = 9.0, lw_poly: float = 0.3, ec_poly: str = 'k') None[source]
IPF map comparison: pixellated grain structure vs smoothed polygon grain structure, one row per MC slice.
- Parameters:
cntr (MC_GS_Container2d)
mc_twin_geom (dict) – Output of
introduce_mc_twin_lamellae()— provides'all_quats'orientation dict per slice.slice_keys (list or None) – Slices to plot. Defaults to all keys in
self.mc_smooth_geom.sample_direction (tuple of 3 floats) – IPF projection direction (ND = (0,0,1)).
show_pixellated (bool) –
True— two-column layout: pixellated (left) | smoothed (right).False— smoothed only;ncolscontrols the grid.ncols (int or None) – Column count when
show_pixellated=False.None→ one row.figsize_per_panel ((float, float)) – Width × height (inches) of each panel.
dpi – Appearance parameters.
fontsize – Appearance parameters.
lw_poly – Appearance parameters.
ec_poly – Appearance parameters.
- plot_ebsd_tvf(tvf_result: dict, figsize: tuple = (7, 4), dpi: int = 100, fontsize: float = 9.0, title: str = 'EBSD grain-role area fractions') None[source]
Horizontal bar chart of EBSD grain-role area fractions.
- Parameters:
tvf_result (dict) – Output of
compute_ebsd_tvf().figsize – Forwarded to the core vizDistr function.
dpi – Forwarded to the core vizDistr function.
fontsize – Forwarded to the core vizDistr function.
title – Forwarded to the core vizDistr function.
- plot_parent_twin_map(parent_info, **kwargs)[source]
Render a per-CSL spatial grain map coloured by parent / twin / intermediate role on the EBSD label field.
One subplot is produced per CSL type found in parent_info. Within each subplot grains are coloured as: pure parents (blue), pure twins (coral), intermediates (green), non-role grains (semi-transparent grey). Wraps
ebsdviz.plot_parent_twin_mapusingself.lfi_ebsd.- Parameters:
parent_info (dict) – Output of
identify_parent_grains(). Keys are CSL labels; each value must contain'pure_parents','pure_twins','intermediates','n_pure_parents','n_pure_twins', and'n_intermediates'.**kwargs –
map_figsize: tuple — figure size (default(6, 6))map_dpi: int — DPI (default140)map_suptitle: str — super-title for the figure
- Returns:
The figure is rendered via
plt.show().- Return type:
None
- plot_combined_parent_twin_map(parent_info, **kwargs)[source]
Render a single spatial grain map with pure-parent, pure-twin, intermediate, and/or non-participating grains aggregated across all CSL types in parent_info, depending on
highlight.Unlike
plot_parent_twin_mapwhich produces one subplot per CSL type, this produces a single combined map. Priority when a grain appears in multiple roles: intermediate > parent > twin. Wrapsebsdviz.plot_combined_parent_twin_mapusingself.lfi_ebsd.- Parameters:
parent_info (dict) – Output of
identify_parent_grains(). Keys are CSL labels; each value must contain'pure_parents','pure_twins', and'intermediates'.**kwargs –
highlight: {‘combined’, ‘parent’, ‘non_participating’} — which role(s) to highlight vs. dim (default'combined', i.e. every role coloured)combmap_figsize: tuple — figure size (default(6, 6))combmap_dpi: int — DPI (default140)combmap_alpha_bg: float — opacity of dimmed grains (default0.08)combmap_suptitle: str — super-title for the figure (defaultNone, i.e. auto-generated fromhighlight)
- Returns:
The figure is rendered via
plt.show().- Return type:
None
- selectProps_twinGS()[source]
Launch the ipywidgets control panel for selecting grain-role property plots.
Thin wrapper around
nbWidgets.selectProps_twinGS. Displays checkboxes for morphological properties and grain groups, plus sliders for subplot columns and font size. Must be called inside a Jupyter cell.- Returns:
Widget state dict with keys
'prop_checkboxes','group_checkboxes','ncols_slider', and'fontsize_slider'. Pass toreadProps_twinGSto extract current values before plotting.- Return type:
- readProps_twinGS(_widgets)[source]
Read the current widget values from the panel returned by
selectProps_twinGS.Thin wrapper around
nbWidgets.readProps_twinGS. Prints the selected properties and groups to stdout and returns them as a plain dict.
- selectProps_reprComp(props=None)[source]
Launch the property-selection checklist for MC–EBSD comparison.
Thin wrapper around
nbWidgets.selectProps_reprComp. Displays only morphological property checkboxes (no grain-group controls or layout sliders). Must be called inside a Jupyter cell.
- readProps_reprComp(_widgets)[source]
Read selected property names from the panel returned by
selectProps_reprComp.Thin wrapper around
nbWidgets.readProps_reprComp.
- see_grain_role_property_stats(parent_info, twinProps, **kwargs)[source]
Plot morphological and topological property distributions split by grain role (pure parents, pure twins, intermediates, non-role) for the EBSD target.
Delegates to
ebsdviz.plot_grain_role_property_statsusingself.lfi_ebsd,self.prop_ebsd, andself.neigh_gid_ebsd.- Parameters:
parent_info (dict) – Output of
identify_parent_grains(). Keys are CSL labels; values contain'pure_parents','pure_twins', and'intermediates'grain-ID arrays.twinProps (dict) – Output of
readProps_twinGS(). Must contain'selected_props','selected_groups','ncols', and'fontsize'.**kwargs –
Optional overrides forwarded to
plot_grain_role_property_stats:nbins: int — histogram bins (default 40)bw_method: str — KDE bandwidth (default'scott')peak_prominence: float — peak detection threshold (default 0.02)figsize_per: tuple — per-subplot figure size (default(6, 4))dpi: int — figure DPI (default 100)suptitle: str — figure super-title
- Returns:
The figure is rendered inline via matplotlib.
- Return type:
None
Examples
Typical Jupyter notebook workflow (one cell per step):
# Cell 1 — build the widget panel and confirm selection _widgets = rgen.selectProps_twinGS() # Cell 2 — read widget values after confirming twinProps = rgen.readProps_twinGS(_widgets) # Cell 3 — plot with defaults rgen.see_grain_role_property_stats(parent_info, twinProps) # Cell 4 — override specific display options rgen.see_grain_role_property_stats( parent_info, twinProps, nbins=60, figsize_per=(7, 4), dpi=130, suptitle='Cu OFHC — grain role distributions', )
- sgs_mcgs2Gen(INPUT_DASHBOARD, MC_TIME_START=2, MC_TIME_END=-1, MC_TIME_STEP=2, show_stats_table=False, figsize=(5, 4), dpi=110, **kwargs)[source]
Generate a sample Monte-Carlo grain structure set, characterise it across temporal slices, and plot the temporal property distributions.
- Parameters:
INPUT_DASHBOARD (str or path) – Path to the UPXO MC simulation input dashboard.
MC_TIME_START (int, optional) – First MC time slice index to characterise. Default 2.
MC_TIME_END (int, optional) – Last MC time slice index (exclusive,
-1= all). Default -1.MC_TIME_STEP (int, optional) – Step between characterised time slices. Default 2.
show_stats_table (bool, optional) – If
True, print the per-property statistics table after the figure. DefaultFalse— suppresses the table while still storing it incntr.stats_table.figsize_per (tuple of (float, float), optional) –
(width, height)in inches for each subplot panel. Default(5, 4). Forwarded toMC_GS_Container2d.plot_temporal_distributions().dpi (int, optional) – Figure resolution in dots-per-inch. Default
110. Forwarded toMC_GS_Container2d.plot_temporal_distributions().**kwargs – Additional keyword arguments forwarded to
MC_GS_Container2d.plot_temporal_distributions(). Accepted keys includeprops,ncols,bins,bw_method,peak_prominence,fontsize,suptitle,cmap. Any key supplied here overrides the corresponding default set inside this method.
- Returns:
cntr – Populated container with
gssetandstats_table.- Return type:
- rank_mcgs_by_n(cntr, P: float = 10.0)[source]
Rank all MC grain structures in
cntr.gssetby grain count relative to the de-twinned EBSD map.Requires
build_merged_ebsd_lfi()to have been called first.- Parameters:
cntr (MC_GS_Container2d) – Container with
gssetdict.P (float, optional) – Tolerance in % below the de-twinned EBSD grain count used to determine eligibility. A slice is ineligible (0) when
n_mc < (1 - P/100) * n_ebsd_merged; eligible (1) otherwise. Default 10.
- Returns:
Indexed by
'mc_time_slice', columns:n_mc— grain count of the MC slicen_ebsd_merged— grain count of the de-twinned EBSD (constant)ratio—n_mc / n_ebsd_merged; >1 = more grainsthan EBSD; <1 = fewer grains
eligible— 1 ifratio >= 1 - P/100, else 0nPixQ1SimGS— Q1 (25th percentile) of the per-grain pixelcount distribution across all grains in the MC slice. A grain with
npixelsat or below this value is among the smallest 25 % of grains in that slice.Relevance to twin introduction
Twin lamellae are introduced into individual parent grains. The smallest grains (lower quartile) are the hardest cases: a grain with very few pixels can only accommodate a 1–2 pixel-wide twin regardless of the intended physical thickness, collapsing the twin to a featureless stripe with no resolvable area, aspect ratio, or boundary orientation.
nPixQ1SimGScaptures this worst-case pixel budget. Higher values mean even the smallest quartile of grains is pixel-rich, so twin lamellae can span several pixels in their thickness dimension — yielding realistic aspect ratios, well-defined boundaries, and volume fractions that faithfully reflect the intended twin thickness parameter. In short, higher values make twin introduction more accurate by reducing discretisation error in the twin geometry.Note: this is a purely discretisation argument. Physical accuracy also depends on the pixel step size; both should be considered together when choosing a representative MC time slice.
Sorted ascending by
ratiodeviation from 1. Also stored ingrain_count_rank_ng.- Return type:
pd.DataFrame
- selectSlices_reprComp()[source]
Show an ipywidgets checklist of MC time slices from
grain_count_rank_ngfor the user to select which slices to carry forward into property-distribution comparison.Requires
rank_mcgs_by_n()to have been called first.- Returns:
{'slice_checkboxes': dict}— pass toreadSlices_reprComp().- Return type:
- readSlices_reprComp(_widgets)[source]
Read selected MC time-slice keys from the panel returned by
selectSlices_reprComp().
- find_repr_mcgs_props(cntr, mc_slices: list, props=None)[source]
Score user-selected MC grain structures against
prop_ebsd_merged_dfusing three distribution-similarity metrics.Call
rank_mcgs_by_n()first, inspect the table, select slices viaselectSlices_reprComp()/readSlices_reprComp(), then pass the result here.- Parameters:
cntr (MC_GS_Container2d) – Container with
gssetdict.mc_slices (list) – Explicit list of
mc_time_slicekeys (fromgrain_count_rank_ng.index) chosen by the user.props (list of str or None) – Properties to compare. If None, the intersection of float columns shared between
prop_ebsd_merged_dfand the first candidate’spropDataFrame is used automatically. Supply the list fromreadProps_reprComp()to use a user-selected subset.
- Returns:
Keys
'ratio','wasserstein','energy'— each a DataFrame of per-property scores sorted ascending by'aggregate'(best match first). Also stored inrepr_rank_ng.- Return type:
- show_repr_rank_ng(metric: str = 'wasserstein', n_top=None)[source]
Display the MC–EBSD ranking table for the given metric.
Prints the available metric options (with the active one bracketed), a note on how the aggregate is computed and what each cell value means for the chosen metric, then IPython-displays the DataFrame.
- plot_repr_rank(figsize=None, dpi: int = 100, fontsize_annot: float = 8.0, fontsize_tick: float = 9.0, fontsize_title: float = 9.0, fontsize_suptitle: float = 11.0) None[source]
Three vertically stacked heatmaps of per-property rankings for all compared MC slices.
Green = best-ranked within a column, red = worst. Cell text shows the raw score. Call after
find_repr_mcgs_props()has populatedrepr_rank_ng. Delegates toupxo.viz.vizDistr.plot_repr_rank().- Parameters:
figsize (tuple or None)
dpi (int)
fontsize_annot (float) – Font size for the numeric value in each cell.
fontsize_tick (float) – Font size for tick labels (slice keys and column names).
fontsize_title (float) – Font size for each panel title.
fontsize_suptitle (float) – Font size for the overall figure title.
- plot_normalized_prop_distributions(cntr, mc_slices: list, props=None, annotate_scores: bool = True, bins: int = 40, bw_method='scott', figsize_per: tuple = (5, 4), dpi: int = 100, ncols=None, fontsize: float = 9.0, show_hist: bool = True, show_peaks: bool = True, legend_loc: str = 'upper right', legend_ncol: int = 1, legend_fontsize: float | None = None) None[source]
Overlaid normalised property distributions for EBSD (merged) vs MC slices.
Each property distribution is divided by its own mean before plotting, matching the normalisation used in
find_repr_mcgs_props(), so all curves are centred near 1.0 and are directly shape-comparable.- Parameters:
cntr (MC_GS_Container2d)
mc_slices (list) – MC time-slice keys to plot (subset of
cntr.gssetkeys).props (list of str or None) – Properties to plot. Auto-detected from shared float columns when None.
annotate_scores (bool) – If True and
repr_rank_ngis populated, annotate each MC curve with its Wasserstein and energy distance for that property.bins – Forwarded to the core vizDistr function.
bw_method – Forwarded to the core vizDistr function.
figsize_per – Forwarded to the core vizDistr function.
dpi – Forwarded to the core vizDistr function.
ncols – Forwarded to the core vizDistr function.
fontsize – Forwarded to the core vizDistr function.
show_hist – Forwarded to the core vizDistr function.
show_peaks – Forwarded to the core vizDistr function.
legend_loc (str) – Legend location. Default
'upper right'.legend_ncol (int) – Number of legend columns. Use
2or more to split entries side-by-side and reduce legend height. Default1.legend_fontsize (float or None) – Legend text size. Reducing this is the most direct way to shrink the legend box. Defaults to
fontsize - 2when None.
- plot_qq(cntr, mc_slices: list, props=None, figsize_per: tuple = (4, 4), dpi: int = 100, ncols=None, fontsize: float = 9.0) None[source]
Quantile–Quantile plots of EBSD (merged) vs MC slices per property.
Both distributions are normalised by their own mean so both axes share a dimensionless scale centred near 1.0. Points on the diagonal indicate identical shapes at that quantile; deviations reveal where and how the distributions differ. See
upxo.viz.vizDistr.plot_qq_comparison()for full interpretation guidance.- Parameters:
cntr (MC_GS_Container2d)
mc_slices (list) – MC time-slice keys to compare.
props (list of str or None) – Properties to plot. Auto-detected when None.
figsize_per – Forwarded to the core vizDistr function.
dpi – Forwarded to the core vizDistr function.
ncols – Forwarded to the core vizDistr function.
fontsize – Forwarded to the core vizDistr function.
- best_match_mcgs_key(metric: str = 'wasserstein', n: int = 1, by: str = 'aggregate')[source]
Return the best-matching MC time-slice key(s) ranked by a chosen column.
- Parameters:
metric (str, optional) – Which metric’s table to consult. One of
'ratio','wasserstein','energy'. Default'wasserstein'.n (int, optional) –
Number of top matches to return. -
n=1(default) — returns a single key (scalar). -n>1— returns a list of the top-nkeys,ordered best-to-worst.
by (str, optional) –
Column to rank by. Any property name present in
repr_rank_ng[metric].columns, or'aggregate'(default).Ranking direction is metric-aware:
wasserstein / energy — sort
bycolumn ascending; lower distance = better match regardless of which column is chosen.ratio with a property column — sort by
|value − 1|ascending; closest to 1.0 (perfect mean match) = best.ratio with
by='aggregate'— sort ascending; the aggregate column already storesmean(|ratio − 1|), so lower = better.
- Returns:
MC time-slice key(s) from
repr_rank_ng[metric].index.- Return type:
key or list of keys
- Raises:
ValueError – If
byis not a column inrepr_rank_ng[metric].
Examples
>>> rg.best_match_mcgs_key() # top-1, Wasserstein aggregate >>> rg.best_match_mcgs_key('energy', n=3) # top-3 by energy aggregate >>> rg.best_match_mcgs_key('wasserstein', by='area') # top-1 by area shape distance >>> rg.best_match_mcgs_key('ratio', by='area') # top-1 by area mean offset
- mesh_smooth_slices(slice_keys: list | None = None, mesh_size_gb: float = 0.75, mesh_size_bulk: float = 4.5, mesh_order: int = 1, mesh_algo: int = 8, recombine_to_quads: bool = True, dist_min: float = 0.5, dist_max: float = 5.0, out_dir: str | None = None, basename: str = 'repgen_gs_mesh', formats: list | None = None, verbose: bool = True) dict[source]
Generate conformal FE meshes for smoothed grain structure slices.
Reads smoothed polygon geometry from
self.mc_smooth_geomand callsupxo.meshing.gsmesh2d.mesh_gs()for each slice.Result stored in
self.mc_smooth_mesh = {sk: mesh_result_dict}.- Parameters:
slice_keys (Slice keys to process. Defaults to all keys in) –
self.mc_smooth_geom.mesh_size_gb (Target element size on grain boundaries.)
mesh_size_bulk (Target element size in grain interiors.)
mesh_order (Element order (1=linear, 2=quadratic).)
mesh_algo (Gmsh algorithm ID (8=Frontal-Delaunay quads, 6=Frontal).)
recombine_to_quads (Recombine triangles into quads.)
dist_min (Distance field DistMin.)
dist_max (Distance field DistMax.)
out_dir (Directory for exported mesh files.)
basename (Filename stem (per-slice suffix
_sk<sk>appended).)formats (List of format extensions, e.g.
['msh', 'inp'].)verbose (Print per-slice progress.)
- Returns:
dict {sk
- Return type:
mesh_result_dict} — also stored in
self.mc_smooth_mesh.
- visualize_smooth_meshes(slice_keys: list | None = None, figsize: tuple = (12, 9), dpi: int = 150, **kwargs) dict[source]
Visualize FE meshes for smoothed slices stored in
self.mc_smooth_mesh.- Parameters:
slice_keys (Slice keys to visualize. Defaults to all keys in) –
self.mc_smooth_mesh.figsize (Figure size in inches.)
dpi (Figure DPI.)
**kwargs (Forwarded to
upxo.meshing.gsmesh2d.visualize_gs_mesh().)
- Returns:
dict {sk
- Return type:
(fig, ax)}
- compute_ebsd_twin_vf_partition(parent_info: dict, tvf: dict = None) dict[source]
Classify EBSD pure twin grains as Type 2a (outward, boundary-sharing) or Type 2b (inward, fully submerged) by geometric analysis of
self.lfi_ebsd.- Type 2a – pure twin that shares at least one pixel boundary with a
pure-parent grain. In the synthetic structure these are carved from the parent grain at the primary-twin boundary (outward secondary twins).
- Type 2b – pure twin whose every adjacent grain is an intermediate
(not a pure parent). In the synthetic structure these are carved from within the primary twin lamella (inward / submerged secondary twins).
- Parameters:
parent_info (dict) – Output of
identify_parent_grains().tvf (dict or None) – Output of
compute_ebsd_tvf(). Used to readcsl_label. If None, the first key of parent_info is used.
- Returns:
vf_2a– area fraction of Type-2a outward twins.vf_2b– area fraction of Type-2b inward twins.tvf_stage1– primary-twin carving target for the SGC:intermediate_frac + vf_2b (the full region to carve from the parent grain, including space later subdivided by 2b secondaries).
n_2a– count of Type-2a pure twin grains.n_2b– count of Type-2b pure twin grains.prob_secondary_outward– vf_2a / (vf_2a + vf_2b); use thisas
prob_secondary_outward_twinNucleationinTwinGenerator3D.intermediate_frac– area fraction of intermediate grains(from parent_info pixel counts).
n_intermediates– count of intermediate (primary twin)grains.
- Return type:
dict with keys
- mpflags
- rm0tests
- rm0
- px_size
- sdim
- gsan_sgs
- gsan_tgs
- ebsd_file
- ebsd_step
- lfi_ebsd
- euler_ebsd
- quat_ebsd
- neigh_gid_ebsd
- prop_ebsd
- prop_ebsd_df
- stat_ebsd
- lfi_ebsd_merged
- prop_ebsd_merged
- prop_ebsd_merged_df
- repr_rank_ng
- grain_count_rank_ng
- merge_info
- mc_host_orientations
- mc_twin_geom
- mc_smooth_geom
- mc_smooth_geom_r2
- mc_smooth_quats
- mc_smooth_mesh