Parent Beta Phase Reconstruction in Titanium Alloys edit page

This page reconstructs the former beta-grain map of a titanium alloy from a nearly complete alpha-phase EBSD map. It continues the Burgers-variant example in Parent and Child Variants and uses the reconstruction ideas prepared by Martensite Variants.

mtexdata alphaBetaTitanium

% Plot the measured alpha phase with inverse pole figure colours.
plot(ebsd('Ti (alpha)'),ebsd('Ti (alpha)').orientations,...
  'figSize','large')
ebsd = EBSDsquare (y↓→x, row↓→col)
 
 Phase  Orientations     Mineral         Color  Symmetry  Crystal reference frame
     0  10449 (5.3%)  notIndexed          none                                   
     1   437 (0.22%)   Ti (BETA)  LightSkyBlue       432                         
     2  185722 (94%)  Ti (alpha)  DarkSeaGreen       622        X||a*, Y||b, Z||c
 
 Properties: bands, bc, bs, error, mad, reliabilityindex, oldId
 Scan unit : um
 X × Y × Z : [0 → 1568] × [0 → 1175] × [0 → 0]
 Normal vector: (0,0,1)
 Square grid  :384 × 512

The map contains 99.8% alpha titanium and 0.2% beta titanium among its indexed measurements. The goal is to recover the original beta phase.

phaseFraction = 100 .* ...
  [length(ebsd('Ti (alpha)')),length(ebsd('Ti (beta)'))] ./ ...
  length(ebsd('indexed'))
phaseFraction =
   99.7653    0.2347

The former beta-grain structure is almost visible by eye. Groups of alpha regions with related colours form larger blocks, but colour alone does not decide which regions came from the same beta grain.

Set the parent-to-child relationship

We use the Burgers OR introduced on the first page. It aligns a beta \((110)\) plane with an alpha \((0001)\) plane and a beta \([1\bar{1}1]\) direction with an alpha \([\bar{2}110]\) direction.

beta2alpha = orientation.Burgers(...
  ebsd('Ti (beta)').CS,ebsd('Ti (alpha)').CS)
beta2alpha = misorientation (Ti (BETA) → Ti (alpha))
 
 (110) || (0001)   [11̅1] || [2̅110]

Every parent grain reconstruction method expects the OR in the parent-to-child direction. Passing its inverse would make all candidate parent orientations wrong even though their number still looked plausible.

Segment the child grains

A grain is a phase-homogeneous, spatially connected region of EBSD pixels produced by segmentation. A small angular threshold keeps alpha regions from different beta grains separate at this stage.

[grains,ebsd] = calcGrains(ebsd,'threshold',1.5*degree,...
  'removeQuadruplePoints');

The 1.5-degree threshold is deliberately small. If two alpha orientations from different beta grains were merged now, reconstruction could not separate them later.

Set up the reconstruction job

A parentGrainReconstructor stores the input, the current reconstruction, and the relation between them. Assigning p2c tells it which phase is the parent and which phase is the child.

job = parentGrainReconstructor(ebsd,grains);
job.p2c = beta2alpha
job = parentGrainReconstructor
 
 phase   mineral     symmetry  grains  area   reconstructed
 parent  Ti (BETA)   432       428     0.23%  0%           
 child   Ti (alpha)  622       45802   100%                
 
 OR: (110) || (0001)   [11̅1] || [2̅110]
   p2c fit: 0.82°, 1.2°, 1.6°, 3.1° (quintiles)
   c2c fit: 0.71°, 0.99°, 1.3°, 1.8° (quintiles)

The displayed job summary reports the current parent and child grain counts, areas, and reconstructed fraction. The most useful properties are grouped below.

  • job.grainsPrior and job.ebsdPrior preserve the input grains and EBSD data.
  • job.grains and job.ebsd expose the current grains and reconstructed EBSD data.
  • job.mergeId maps each input grain job.grainsPrior(ind) to the current grain job.grains(job.mergeId(ind)).
  • job.numChilds counts the input grains represented by each current grain.
  • job.parentGrains and job.childGrains select the current parent and child grains.
  • job.isTransformed marks input child grains assigned a parent orientation.
  • job.isMerged marks input grains that have been combined into a current grain.
  • job.transformedGrains selects the input child grains with a computed parent orientation.

The class also provides several reconstruction routes and cleanup operations.

These operations can be repeated while refining a reconstruction. They are not arbitrary in order: graph clustering needs a graph, and vote-based transformation needs votes.

Build the variant graph

A variant graph has one node for every combination of child grain and candidate parent variant. Its edges connect compatible candidate variants of neighbouring grains.

calcVariantGraph converts angular fit into edge probability. Here 1.5 degrees is the misfit at which the default probability model gives an edge weight of one half.

job.calcVariantGraph('threshold',1.5*degree)
ans = parentGrainReconstructor
 
 phase   mineral     symmetry  grains  area   reconstructed
 parent  Ti (BETA)   432       428     0.23%  0%           
 child   Ti (alpha)  622       45802   100%                
 
 OR: (110) || (0001)   [11̅1] || [2̅110]
   p2c fit: 0.82°, 1.2°, 1.6°, 3.1° (quintiles)
   c2c fit: 0.71°, 1°, 1.3°, 1.8° (quintiles)
 
 variant graph: 546622 entries

Cluster candidate variants

clusterVariantGraph propagates compatibility through the graph. Three iterations produce probabilities for the candidate parents of each child grain.

job.clusterVariantGraph('numIter',3)
ans = parentGrainReconstructor
 
 phase   mineral     symmetry  grains  area   reconstructed
 parent  Ti (BETA)   432       428     0.23%  0%           
 child   Ti (alpha)  622       45802   100%                
 
 OR: (110) || (0001)   [11̅1] || [2̅110]
   p2c fit: 0.82°, 1.2°, 1.6°, 3.1° (quintiles)
   c2c fit: 0.71°, 1°, 1.3°, 1.8° (quintiles)
 
 votes: 45802 × 1
   probabilities: 100%, 99%, 98%, 93% (quintiles)

The rows of job.votes.prob contain the candidate probabilities. The matching columns of job.votes.parentId contain their parent-variant IDs. The first column is the highest-ranked candidate for each grain.

Transform child grains to candidate parents

Transform is the first reconstruction step. Each selected child grain is assigned one candidate parent orientation and changes from the child phase to the parent phase.

calcParentFromVote accepts the highest-probability candidate here.

job.calcParentFromVote

reconstructedFraction = 100 * nnz(job.isTransformed) ./ ...
  nnz(job.grainsPrior.phaseId == job.childPhaseId)
ans = parentGrainReconstructor
 
 phase   mineral     symmetry  grains  area  reconstructed
 parent  Ti (BETA)   432       44445   99%   96%          
 child   Ti (alpha)  622       1785    1.1%               
 
 OR: (110) || (0001)   [11̅1] || [2̅110]
   p2c fit: 3.1°, 20°, 35°, 42° (quintiles)
   c2c fit: 2.2°, 4.8°, 12°, 19° (quintiles)
 
 votes: 1785 × 1
   probabilities: 0%, 0%, 0%, 0% (quintiles)
 
reconstructedFraction =
   96.1028

At this stage, 96.10% of the input child grains have parent orientations.

The displayed fraction reaches 99% after the inclusion cleanup below. Neighbouring candidates have not yet all been merged into their shared beta-grain footprints.

% Define a beta-phase IPF colour key.
ipfKey = ipfColorKey(ebsd('Ti (Beta)'));
ipfKey.ipfDirection = vector3d.Y;

% Plot the transformed beta grains.
parentColor = ipfKey.orientation2color(...
  job.parentGrains.meanOrientation);
plot(job.parentGrains,parentColor,'figSize','large')

The map now contains many small regions with almost identical colours. Those regions are compatible parent candidates that still need the merge step.

Merge similar parent grains

Merge is the second reconstruction step. Neighbouring transformed grains with compatible parent orientations are combined into one grain footprint.

mergeSimilar uses an angular threshold. Here neighbours within 5 degrees are treated as one parent grain.

job.mergeSimilar('threshold',5*degree)

parentColor = ipfKey.orientation2color(...
  job.parentGrains.meanOrientation);
plot(job.parentGrains,parentColor,'figSize','large')
ans = parentGrainReconstructor
 
 phase   mineral     symmetry  grains  area  reconstructed
 parent  Ti (BETA)   432       123     99%   96%          
 child   Ti (alpha)  622       1742    1.1%               
 
 OR: (110) || (0001)   [11̅1] || [2̅110]
   p2c fit: 3.2°, 18°, 35°, 41° (quintiles)
   c2c fit: 4.7°, 9.9°, 17°, 23° (quintiles)
 
 votes: 1785 × 1
   probabilities: 0%, 0%, 0%, 0% (quintiles)

The many similarly coloured fragments have coalesced into a small number of large beta grains. Their remaining enclosed specks require a separate topological cleanup.

Merge small inclusions

An inclusion is a grain entirely enclosed by another grain. Some small child grains remain as inclusions because no parent orientation was assigned to them confidently.

mergeInclusions merges inclusions of at most 10 pixels into their surrounding parent grains.

job.mergeInclusions('maxSize',10)

parentColor = ipfKey.orientation2color(...
  job.parentGrains.meanOrientation);
plot(job.parentGrains,parentColor,'figSize','large')
ans = parentGrainReconstructor
 
 phase   mineral     symmetry  grains  area   reconstructed
 parent  Ti (BETA)   432       42      100%   99%          
 child   Ti (alpha)  622       228     0.21%               
 
 OR: (110) || (0001)   [11̅1] || [2̅110]
   p2c fit: 3.3°, 5.6°, 16°, 31° (quintiles)
   c2c fit: 4.9°, 9.8°, 15°, 20° (quintiles)
 
 votes: 1785 × 1
   probabilities: 0%, 0%, 0%, 0% (quintiles)

The large parent-grain shapes remain, while the small enclosed fragments no longer interrupt them. This operation changes topology rather than choosing another orientation variant.

Reconstruct a parent orientation at every pixel

So far, parent orientations have been stored as grain means. calcParentEBSD transfers the reconstruction to an EBSD variable and assigns a parent orientation to every transformed child pixel.

parentEBSD = job.calcParentEBSD;

parentColor = ipfKey.orientation2color(...
  parentEBSD('Ti (Beta)').orientations);
plot(parentEBSD('Ti (Beta)'),parentColor,'figSize','large')

The pixel map is piecewise consistent with the reconstructed grain map. It can now be analysed with ordinary EBSD tools while retaining the reconstructed beta phase and parent grain IDs.

Check the per-pixel reconstruction fit

parentEBSD.fit is a per-pixel property. It is the angular mismatch between the measured alpha orientation and the child variant predicted from its reconstructed beta-grain orientation.

fitDegree = parentEBSD('Ti (Beta)').fit ./ degree;
fitQuantiles = quantile(fitDegree(~isnan(fitDegree)),[0.5 0.9 0.99])

plot(parentEBSD,parentEBSD.fit ./ degree,'figSize','large')
mtexColorbar
setColorRange([0,5])
mtexColorMap('LaboTeX')

hold on
plot(job.grains.boundary,'lineWidth',2)
hold off
fitQuantiles =
    1.1861
    2.1044
    3.5820

Low values indicate pixels consistent with the assigned Burgers variant. The median is 1.19 degrees, 90% are below 2.10 degrees, and 99% are below 3.58 degrees.

The black outlines show whether larger mismatches collect at reconstructed parent boundaries rather than filling a grain interior.

Compare reconstructed boundaries with the child map

The final plot returns to the measured alpha orientations. White lines show the smoothed reconstructed beta-grain boundaries.

plot(ebsd('Ti (Alpha)'),ebsd('Ti (Alpha)').orientations,...
  'figSize','large')

hold on
parentGrains = smoothBoundary(job.parentGrains,5);
plot(parentGrains.boundary,'lineWidth',3,'lineColor','White')
hold off

The white boundaries enclose the large alpha-variant groups that were only hinted at by colour in the first map. The overlay is the final visual check that graph compatibility recovered the structure visible by eye.

References

Next

Continue with Parent Austenite Reconstruction for a steel workflow that first fits the OR and then combines variant-graph reconstruction with further cleanup strategies.

Citing this page. This page is part of the documentation of MTEX, a free and open source MATLAB toolbox for analyzing and modeling crystallographic textures. It was written by The MTEX Developers and is published at https://mtex-toolbox.github.io/TiBetaReconstruction.html. If you use MTEX, or reuse text or figures from this page, in your research, please cite

F. Bachmann, R. Hielscher, H. Schaeben: Texture Analysis with MTEX - Free and Open Source Software Toolbox, Solid State Phenomena 160 (2010), 63-68. 10.4028/www.scientific.net/SSP.160.63

BibTeX
@article{bachmann2010mtex,
  author  = {F. Bachmann and R. Hielscher and H. Schaeben},
  title   = {Texture Analysis with MTEX - Free and Open Source Software Toolbox},
  journal = {Solid State Phenomena},
  volume  = {160},
  pages   = {63-68},
  year    = {2010},
  doi     = {10.4028/www.scientific.net/SSP.160.63},
  url     = {https://doi.org/10.4028/www.scientific.net/SSP.160.63}
}

Other papers describing specific MTEX methods are listed under Publications — please cite the one that best fits your application. The MTEX source code is licensed under the GNU General Public License v2.0; the text and figures of this documentation are licensed under CC BY 4.0, which permits reuse — including by automated systems — provided The MTEX Developers and this page are credited.