Grain Tutorial edit page

This tutorial starts with an EBSD map and turns its measurements into grains. It then compares pixel and grain orientations, selects grains by their properties, and previews the boundaries between two phases.

Read the EBSD tutorial first if phase maps, orientation maps, or MTEX selections are new to you. General Concepts explains how one MTEX object holds a vectorized list of measurements or grains.

The specimen is the mylonite used by Bachmann, Hielscher and Schaeben in Grain detection from 2d and 3d EBSD data. The data are courtesy of Daniel Rutte and Bret Hacker, Stanford University.

plottingConvention.default('y↑→x');

% load the example map and display its summary
mtexdata mylonite

% plot the phases
plot(ebsd)
ebsd = EBSD (y↑→x)
 
 Phase  Orientations     Mineral         Color  Symmetry  Crystal reference frame
     1    3444 (28%)    Andesina  LightSkyBlue        -1              X||a*, Z||c
     2    3893 (31%)      Quartz  DarkSeaGreen      -3m1        X||a*, Y||b, Z||c
     3    368 (2.9%)     Biotite     Goldenrod     2/m11        X||a, Y||b*, Z||c
     4    4781 (38%)  Orthoclase    LightCoral     12/m1        X||a*, Y||b, Z||c
 
 Scan unit : um
 X × Y × Z : [15000 → 24000] × [1020 → 3990] × [0 → 0]
 Normal vector: (0,0,1)

The displayed EBSD summary reports four indexed phases and the scan extent. The phase map shows quartz ribbons between mixed feldspar layers, with smaller biotite regions.

The full map is too large for the details below. We continue with a rectangle written as [xmin, ymin, width, height].

region = [19000 1500 4000 1500];

% mark the selected region on the phase map
rectangle('Position',region,'EdgeColor','black','LineWidth',2)

inpolygon selects the measurements inside the rectangle. Its displayed summary confirms the new extent and phase counts.

ebsdRegion = ebsd(inpolygon(ebsd,region))
ebsdRegion = EBSD (y↑→x)
 
 Phase  Orientations     Mineral         Color  Symmetry  Crystal reference frame
     1     578 (20%)    Andesina  LightSkyBlue        -1              X||a*, Z||c
     2    1144 (40%)      Quartz  DarkSeaGreen      -3m1        X||a*, Y||b, Z||c
     3       58 (2%)     Biotite     Goldenrod     2/m11        X||a, Y||b*, Z||c
     4    1066 (37%)  Orthoclase    LightCoral     12/m1        X||a*, Y||b, Z||c
 
 Scan unit : um
 X × Y × Z : [19020 → 22980] × [1500 → 3000] × [0 → 0]
 Normal vector: (0,0,1)

Grain reconstruction

A grain is a phase-homogeneous, spatially connected region of EBSD pixels produced by segmentation. A phase change between neighbouring pixels is always a grain boundary.

MTEX gives each measurement a spatial cell and links neighbouring cells that meet the segmentation criterion. Grain outlines follow the cell interfaces left between different linked groups.

For neighbours of the same phase, calcGrains draws a boundary when their minimum symmetry-equivalent misorientation reaches the chosen angle. The test is local between neighbours. Consequently, a gradual orientation gradient can connect two ends of one grain even when those ends differ by more than the threshold.

The 15 degree value below is an example parameter, not a universal grain definition. Grain Reconstruction explains how 'angle', 'minPixel', and 'alpha' change the result.

% reconstruct grains and return the map with a grainId property
[grains,ebsdRegion] = calcGrains(ebsdRegion,'angle',15*degree);

% display the grain summary
grains

% plot the phase map of the selected region
plot(ebsdRegion)

% overlay the grain boundaries
hold on
plot(grains.boundary,'LineColor','black','LineWidth',1.5)
hold off
grains = grain2d (y↑→x)
 
 Phase  Grains  Pixels     Mineral  Symmetry         Color
     1     371     578    Andesina        -1  LightSkyBlue
     2     189    1144      Quartz      -3m1  DarkSeaGreen
     3      55      58     Biotite     2/m11     Goldenrod
     4     381    1066  Orthoclase     12/m1    LightCoral
 
 boundary segments: 4527 (155309 µm)
 inner boundary segments: 1 (45 µm)
 triple points: 1294
 
 Properties: meanRotation, GOS

The grain summary reports a count for each phase and the number of boundary segments. In the figure, every outline follows interfaces between measurement cells rather than a hand-drawn curve. Each segment lies between neighbouring pixels assigned to different grains.

Notice the many tiny polygons. Their size makes segmentation choices and spatial resolution important before any grain-size result is reported.

Pixel orientations and grain mean orientations

A phase map says where quartz was indexed, but not how its lattice is oriented. We first colour every quartz measurement with an inverse pole figure key and draw the other phases pale.

quartzEbsd = ebsdRegion('Quartz');
quartzGrains = grains('Quartz');
ipfKey = ipfColorKey(quartzEbsd);

% plot the non-quartz grains as context
plot(grains({'Andesina','Biotite','Orthoclase'}),'FaceAlpha',0.4)

% add the quartz measurements using one explicit colour key
hold on
plot(quartzEbsd,ipfKey.orientation2color(quartzEbsd.orientations))
plot(grains.boundary,'LineColor','black')
legend off
hold off

Many boundaries coincide with abrupt colour changes. Colour variation also remains inside some grains, where it may represent orientation noise or a real lattice gradient.

An IPF colour records where one specimen direction lies in the crystal. It is not a complete orientation-distance scale, so colour alone cannot validate a reconstruction. IPF Maps explains the key.

% display the colour key used for both orientation maps
close all
plot(ipfKey)

The key identifies the crystal direction represented by each colour. The same key can now colour one mean orientation per quartz grain.

% plot the non-quartz grains as context
plot(grains({'Andesina','Biotite','Orthoclase'}),'FaceAlpha',0.4)

% colour each quartz grain by its mean orientation
hold on
plot(quartzGrains,ipfKey.orientation2color(quartzGrains.meanOrientation))
legend off
hold off

Compared with the pixel map, each quartz grain now has one flat colour. The mean suppresses intragranular variation rather than proving that the variation was noise. Orientation Parameters measures that variation explicitly.

Selecting and measuring grains

Grain properties are arrays with one value per grain. Here numPixel records the number of measurements assigned to a grain, while area measures its sectional area in the scan unit.

The next selection keeps quartz grains with at least ten measurements and removes grains cut by the edge of the map. The value ten only illustrates a logical selection; it is not a recommended quality criterion.

selectedQuartz = grains('Quartz',...
  grains.numPixel >= 10 & ~grains.isBoundary)
selectedQuartz = grain2d (y↑→x)
 
 Phase  Grains  Pixels  Mineral  Symmetry         Color
     2      13     451   Quartz      -3m1  DarkSeaGreen
 
 boundary segments: 634 (20086 µm)
 inner boundary segments: 0 (0 µm)
 triple points: 133
 
  Id   Phase   Pixels      meanRotation      GOS
  78       2       23    (3°,121°,115°)    0.038
 180       2       12      (3°,148°,3°)    0.029
 188       2       51    (171°,32°,65°)    0.055
 235       2       11     (1°,152°,53°)     0.05
 293       2       37    (1°,121°,113°)    0.025
 473       2       12    (153°,117°,8°)    0.057
 533       2       10    (1°,121°,114°)    0.012
 657       2       17    (2°,121°,117°)    0.016
 860       2       10   (161°,118°,27°)    0.012
 886       2       22   (161°,117°,87°)     0.01
 895       2      203   (165°,112°,44°)    0.018
 945       2       33   (161°,117°,88°)   0.0093
 958       2       10     (176°,60°,2°)    0.018

The displayed grain2d summary reports what the selection retained. Because calcGrains returned ebsdRegion with a grainId property, the selection also leads back to its measurements.

selectedMeasurements = ebsdRegion(selectedQuartz)
selectedMeasurements = EBSD (y↑→x)
 
 Phase  Orientations  Mineral         Color  Symmetry  Crystal reference frame
     2    451 (100%)   Quartz  DarkSeaGreen      -3m1        X||a*, Y||b, Z||c
 
 Properties: grainId
 Scan unit : um
 X × Y × Z : [19170 → 22830] × [1770 → 2640] × [0 → 0]
 Normal vector: (0,0,1)

The measurement summary contains only quartz pixels assigned to the selected grains. The grains themselves can be coloured by area.

close all
plot(grains,'FaceColor','lightgray','FaceAlpha',0.3)
hold on
plot(selectedQuartz,selectedQuartz.area)
hold off
legend off
mtexColorbar('title','sectional grain area')

The coloured regions are the selected interior quartz grains, and their colour represents area rather than orientation. Removing edge grains avoids treating a clipped grain as if its full section had been measured.

A two-dimensional section does not directly give three-dimensional grain volume. Step size, segmentation settings, and the treatment of small or notIndexed regions must also be fixed before specimens are compared. notIndexed is the phase for measurements whose diffraction patterns could not be indexed. Shape Parameters develops these measurements.

Boundaries between two phases

A phase boundary is not a separate type of object. It is a grain boundary whose two neighbouring grains differ in phase, selected here by two names.

Every segment between andesina and orthoclase carries a misorientation. Its angle is the minimum over the symmetries of both phases.

close all

% select the boundary segments between two phases and display their summary
aoBoundary = grains.boundary('Andesina','Orthoclase')

% store one angle per boundary segment in radians
boundaryAngle = aoBoundary.misorientation.angle;

% highlight an illustrative part of the angular range
plot(grains,'FaceAlpha',0.4)
hold on
plot(aoBoundary(boundaryAngle > 160*degree),...
  'LineWidth',2,'LineColor','red')
hold off
aoBoundary = grainBoundary (y↑→x)
 
 Segments    length  mineral 1   mineral 2
     1180  40120 µm   Andesina  Orthoclase

The red traces are the segments above the illustrative 160 degree filter. This filter is applied after reconstruction and did not define the grains. A phase change already made every andesina to orthoclase contact a boundary.

One physical interface is represented by many connected segments. A segment count is therefore neither a count of interfaces nor a set of independent observations.

Weighting by segLength gives longer interfaces proportionally more influence. It avoids weighting every tessellation segment equally.

figure

% bin the angles and sum the segment lengths falling into each bin
[~,edges,binId] = histcounts(boundaryAngle./degree);
traceLength = accumarray(binId,aoBoundary.segLength,[numel(edges)-1 1]);

histogram('BinEdges',edges,'BinCounts',traceLength)
xlabel('minimum misorientation angle (degrees)')
ylabel('boundary trace length')
title('Andesina to orthoclase orientation relationships')

Notice how the traced boundary length is distributed across the angular range. This plot is descriptive, not evidence that either phase pair is related more often than chance.

Such a claim needs a stated reference distribution and consistent sampling weights. Continue with the grain boundary tutorial, then Boundary Misorientations and Misorientation Distribution Functions.

Next

Selecting Grains covers selection by position, phase, property, and orientation. Grain Plots and Shape Parameters develop grain measurements.

Grain mean orientations can also be used for pole figures and ODFs. Giving every grain one vote answers a different question from weighting pixels or grain area; ODF Estimation explains the choice.

For your own data, read Reference Frame before interpreting orientation-dependent results. The reconstructed regions continue into the Grains chapter, while their interfaces continue into Grain Boundaries.

Further reading

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/GrainTutorial.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.