Volume Data and Slices edit page

An EBSD3 object stores one measurement per voxel: its position, phase, orientation, and whatever properties the file provides. It is the volume counterpart of a two-dimensional EBSD map, and the representation to use while the question still concerns individual measurements rather than whole-grain geometry.

This page imports such a volume, displays it, and cuts planar slices out of it. A slice is an ordinary two-dimensional EBSD map, so everything written for planar data applies to it unchanged. The polyhedral grain3d representation is the subject of Three-Dimensional Grains.

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

Import a volume

EBSD3.load detects the file format automatically. The sample data set is a simulated nine-phase volume written in the Xnovo GrainMapper3D format,

  ebsd = EBSD3.load(fullfile(mtexDataPath,'EBSD3','SimulatedMultiPhase.h5'))

which mtexdata resolves by name.

ebsd = mtexdata('xnovo')
ebsd = EBSD3square (y↑→x)
 
 Phase  Orientations     Mineral          Color  Symmetry  Crystal reference frame
     0   27950 (22%)  notIndexed           none                                   
     1  11046 (8.8%)     Silicon        SkyBlue      m-3m                         
     2  11876 (9.5%)     Diamond  PaleVioletRed      m-3m                         
     3  10436 (8.3%)   Magnesium            Red     6/mmm        X||a, Y||b*, Z||c
     4  10231 (8.2%)      Rutile            Red     4/mmm                         
     5   9060 (7.2%)    Corundum    YellowGreen      -3m1        X||a, Y||b*, Z||c
     6  11521 (9.2%)      Quartz    DeepSkyBlue      -3m1        X||a, Y||b*, Z||c
     7  10961 (8.8%)    Pyroxene     SandyBrown       mmm                         
     8  10578 (8.5%)  Hornblende         Orchid     12/m1        X||a, Y||b, Z||c*
     9  11341 (9.1%)  Microcline           Gold        -1              X||a, Z||c*
 
 Properties: Completeness, grainId
 Scan unit : mm
 X × Y × Z : [-0.24 0.24] × [-0.24 0.24] × [-0.24 0.24]
 Grid size (square): 50 × 50 × 50

The summary reports a 50 x 50 x 50 array rather than a list, i.e. the measurements are held in an EBSD3square whose entries are addressed as ebsd(i,j,k). The three array dimensions carry \(x\), \(y\) and \(z\). Each of the nine phases occupies roughly a twelfth of the voxels and the remaining fifth is not indexed.

The voxel is 10 micron on a side and the volume spans about half a millimetre in each direction.

[ebsd.dx, ebsd.dy, ebsd.dz]
ebsd.extent
ans =
    0.0100    0.0100    0.0100
ans =
   -0.2450    0.2450   -0.2450    0.2450   -0.2450    0.2450

Select voxels

A phase or a condition selects voxels the way it selects the pixels of a map. The result is a list of the selected voxels, shorter than the volume, that still carries the unit cell of the grid it came from.

ebsdQuartz = ebsd('Quartz')
ebsdQuartz = EBSD3 (y↑→x)
 
 Phase  Orientations  Mineral        Color  Symmetry  Crystal reference frame
     6  11521 (100%)   Quartz  DeepSkyBlue      -3m1        X||a, Y||b*, Z||c
 
 Properties: Completeness, grainId
 Scan unit : mm
 X × Y × Z : [-0.23 0.24] × [-0.23 0.24] × [-0.24 0.24]

Whatever needs the grid rebuilds it in place: calcGrains, plot and slice put the list back onto its lattice, with the cells nobody occupies not indexed, and gridify does so explicitly. A block of subscripts, ebsd(10:20,10:20,10:20), keeps the grid and crops it.

Display the volume

plot hands the volume to the MATLAB volume viewer, which cuts three slice planes through the data and renders them on the graphics card. The planes are dragged with the mouse, and the volume is rotated, clipped and cropped interactively, so this is a live window rather than a figure:

  plot(ebsd)                          % colour by phase
  plot(ebsd,ebsd.prop.grainId)        % colour by a property

Voxel colours are never interpolated, so a boundary stays where the measurement puts it, and voxels that are not indexed are painted in the background colour.

Interaction is what that window is for. Anything that has to end up in a figure, a publication, or a further calculation goes through a slice.

Cut a slice

slice resamples the volume onto a regular grid inside a plane3d and returns a two-dimensional EBSD map. The plane is given by its normal and one point on it.

ebsdZ = slice(ebsd,plane3d(vector3d.Z,vector3d(0,0,0)))
ebsdZ = EBSDsquare (y↑→x, col←row↓)
 
 Phase  Orientations     Mineral          Color  Symmetry  Crystal reference frame
     0     763 (28%)  notIndexed           none                                   
     1     376 (14%)     Silicon        SkyBlue      m-3m                         
     2    122 (4.5%)     Diamond  PaleVioletRed      m-3m                         
     3    179 (6.6%)   Magnesium            Red     6/mmm        X||a, Y||b*, Z||c
     4    128 (4.7%)      Rutile            Red     4/mmm                         
     5    193 (7.1%)    Corundum    YellowGreen      -3m1        X||a, Y||b*, Z||c
     6     76 (2.8%)      Quartz    DeepSkyBlue      -3m1        X||a, Y||b*, Z||c
     7    256 (9.5%)    Pyroxene     SandyBrown       mmm                         
     8    236 (8.7%)  Hornblende         Orchid     12/m1        X||a, Y||b, Z||c*
     9     375 (14%)  Microcline           Gold        -1              X||a, Z||c*
 
 Properties: Completeness, grainId
 Scan unit : mm
 X × Y × Z : [-0.26 → 0.26] × [-0.26 → 0.26] × [0 → 0]
 Normal vector: (0,0,1)
 Square grid  :52 × 52

The result is an EBSDsquare like any imported map, it carries all nine phases, and it plots like one.

plot(ebsdZ)

The section is a disc, so the simulated specimen is round in the \(xy\) plane rather than filling its bounding box. The grains are equiaxed and the nine phases are mixed through the section without any layering.

Slices at several depths

Repeating the cut at different heights shows how the microstructure develops through the volume. Each panel is a full EBSD map.

newMtexFigure('layout',[1,3],'figSize','large');

for z = [-0.15 0 0.15]
  plot(slice(ebsd,plane3d(vector3d.Z,vector3d(0,0,z))),'micronbar','off')
  mtexTitle(['z = ' num2str(z) ' mm'])
  if z < 0.15, nextAxis; end
end

The three discs have the same diameter, so the specimen is a cylinder standing along \(z\). The grain pattern is different in each panel because every section meets a different set of grains.

An arbitrary plane

The normal is unrestricted. The measurements of a section keep their position in the specimen, so a section that does not lie in the \(xy\) plane would be seen edge on from the default viewing direction. slice therefore gives the section a plottingConvention of its own that looks along the plane normal, and the map is drawn face on without moving any data.

newMtexFigure('layout',[1,2],'figSize','large');

plot(slice(ebsd,plane3d(vector3d.X,vector3d(0,0,0))),'micronbar','off')
mtexTitle('normal || x')
nextAxis
plot(slice(ebsd,plane3d(vector3d(1,1,1),vector3d(0,0,0))),'micronbar','off')
mtexTitle('normal || (1,1,1)')

The section normal to \(x\) is rectangular and shows the full height of the cylinder. The oblique section is the larger of the two because that plane crosses more of the specimen; its grid is regular within the plane, not in the specimen axes.

A section normal to \(z\) needs no new convention and keeps the one the volume already carries, so it is drawn exactly as an imported map is.

Several sections at once

A section keeps the position its measurements have in the specimen, so drawing more than one into the same axes assembles them where they belong. Three orthogonal cuts seen from an angle give the picture the volume viewer shows, in a figure that can be published.

plot(slice(ebsd,plane3d(vector3d.Z,vector3d(0,0,0))),'micronbar','off')
hold on
plot(slice(ebsd,plane3d(vector3d.X,vector3d(0,0,0))),'micronbar','off')
plot(slice(ebsd,plane3d(vector3d.Y,vector3d(0,0,0))),'micronbar','off')
hold off

setCamera(plottingConvention.default3D)

The convention a single section carries decides how that section alone is seen. Once several are combined there is one camera for all of them, and plottingConvention.default3D is the oblique view this chapter uses. The three planes meet at the centre of the specimen, so a grain crossed by two of them appears in both.

Colour a slice

A slice carries the orientations, phases and properties of the voxels it passes through, so it is coloured by exactly the same commands as an imported map. Orientation colouring needs a single phase at a time, which for a multi-phase section means one call per phase.

for p = ebsdZ.indexedPhasesId
  ebsdP = ebsdZ(ebsdZ.CSList(p).mineral);
  plot(ebsdP,ebsdP.orientations,'micronbar','off')
  hold on
end
hold off
Warning: The point group "-1" has no topologically correct
color key: its
         fundamental sector cannot be mapped smoothly and
         one to one onto the
         color space, so the colors jump somewhere.
         Colorizing with the point
         group "1" instead removes the jump, but that
         identifies directions
         differently, so symmetrically equivalent
         directions no longer share a
         color.

Each phase is coloured by its own inverse pole figure key, so colours are comparable within a phase but not between phases.

Separate orientation from measurement quality

A dark or abruptly changing orientation colour does not by itself indicate a poor measurement. Compare a stored quality field with orientation on the same plane. Completeness is supplied by this Xnovo file; other importers may provide different quality measures.

newMtexFigure('layout',[1,2],'figSize','large');
plot(ebsdZ,ebsdZ.prop.Completeness,'micronbar','off')
mtexTitle('Completeness')
mtexColorbar
nextAxis
quartz = ebsdZ('Quartz');
ipfKey = ipfColorKey(quartz.CS);
ipfKey.inversePoleFigureDirection = vector3d.Z;
plot(quartz,ipfKey.orientation2color(quartz.orientations),'micronbar','off')
mtexTitle('Quartz: IPF along specimen z')

The IPF reference is a specimen direction. It stays along \(z\) even when the cutting plane or camera changes. Reuse the same key when comparing orientations on several sections. Interpret completeness using the acquisition method; this simulated example does not establish a cutoff for experimental data.

A slice is an ordinary EBSD map

Nothing distinguishes the result of slice from an imported map, so the planar toolchain applies to it directly. Here the section is segmented into grains and the boundaries drawn over the phase map.

grains = calcGrains(ebsdZ('indexed'));

plot(ebsdZ,'micronbar','off')
hold on
plot(grains.boundary,'lineWidth',2)
hold off

These are grains reconstructed independently in two dimensions. A grain connected outside this plane can appear as separate regions here, so this segmentation need not match a slice of the three-dimensional grains. This data set also ships the segmentation of the full volume as the voxel property grainId, which the slice carries along.

Reconstructing grains in the volume as closed polyhedra is described in Three-Dimensional Grains.

Function reference

Function

Purpose

Function

Purpose

load

import volume measurements

plot

open the volume viewer

slice

extract a planar EBSD map

plot

colour a section

calcGrains

segment one section

calcGrains

segment the full volume

References

Next

Continue with Three-Dimensional Grains to turn a volume into polyhedra and to work with their faces and normals.

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