EbsdLib is primarily used in the DREAM3D family of applications and libraries.
The PDF is courtesy of Dr. Anthony Rollett from Carnegie Mellon University. The original URL is http://pajarito.materials.cmu.edu/lectures/L3-OD_symmetry-21Jan16-slide_50-operators.pdf
EbsdLib v3.0 aligned its hexagonal and trigonal direction conventions to X‖a*, matching
MTEX and Oxford Instruments / HKL acquisition systems. (EDAX/TSL/OIM Analysis use the
other convention, X‖a.) The 30° rotation between the two conventions is what caused
the original (10-10) and (2-1-10) pole-figure mismatches before the v3 changes.
As of 3.1.0 the public default is X‖a (TSL/EDAX), matching legacy DREAM3D and the
rest of EbsdLib. The internal canonical SymOps tables remain X‖a* (MTEX-validated); only
the default selected by the IPF/pole-figure APIs and config structs changed. IPF colors
are convention-invariant — only pole-figure positions and the legend / pole-figure family
labels follow the basis.
Position-space validation across all 11 Laue classes lives in
Data/Pole_Figure_Validation/.
EbsdLib 3.1 is the "discrete pole figures + TSL-by-default" release. It builds
on the 3.0 MTEX-correctness work with a new vector-marker pole-figure renderer
and a switch of the public default hexagonal/trigonal basis back to X‖a
(TSL/EDAX). The two themes:
- Discrete (vector-marker) pole figures. A new renderer draws each pole as a crisp, decimated vector marker instead of rasterizing it as pixels — sharper figures, controllable marker size, and a hard cap on overdraw for million-pole datasets.
X‖a(TSL) is the default convention again. 3.0 shippedX‖a*(MTEX) as the public default; 3.1 returns the default toX‖ato match legacy DREAM3D and the rest of EbsdLib. The internal canonical tables are unchanged (X‖a*); only the default the public APIs/structs select changed.
Detailed API reference: v3_api_reference.md.
The default value of HexConvention flipped from XParallelAStar (3.0) to
XParallelA (3.1) in every public surface that selects it:
LaueOps::generateIPFTriangleLegend(...)— theconvparameter, which was required in 3.0, now defaults toebsdlib::HexConvention::XParallelA.PoleFigureConfiguration_t::hexConvention— now defaults toXParallelA.CompositePoleFigureConfiguration_t::hexConvention— now defaults toXParallelA.InversePoleFigureConfiguration_t::hexConvention— now defaults toXParallelA(affects only the SST label annotation; IPF colors are convention-invariant).
Effect: hexagonal/trigonal pole-figure positions and legend/family labels
render in the TSL basis by default. IPF colors are unaffected (convention-
invariant). Callers that want the 3.0 behavior must now pass
HexConvention::XParallelAStar explicitly (e.g. to compare side-by-side with
MTEX). Cubic / tetragonal / orthorhombic / monoclinic / triclinic are unaffected.
getDefaultPoleFigureNames() now returns plane-family brace notation —
{0001}, {10-10}, {11-20}, {001}, {011}, {111}, etc. — for every
Laue class, and the labels are identical under both conventions. The 3.0
behavior of switching the hexagonal a-family label (<10-10> ↔ <2-1-10>) with
the convention is removed; both conventions now report {11-20} for that family
(the family identity is convention-independent; only the on-figure dot positions
rotate by 30°). Downstream code that parsed the old angle-bracket strings, or
that relied on the per-convention label switch, must update.
Pole figures now render +Y-up by default (flipFinalImage), and discrete
figures use the vector-marker renderer rather than per-pixel stamping. Output is
not byte-identical to 3.0. Any pixel-level exemplars pinned against 3.0 pole
figures must be regenerated.
DiscretePoleFigureCompositorrenders discrete pole figures by stamping opaque marker sprites, with aMarkerOccupancyGridthat decimates overlapping markers (bounded overdraw for >1M-pole inputs).ebsdlib::GeneratePoleFigureComposite(config)is the dispatch entry point: it routesdiscrete && !discreteHeatMapfigures to the vector-marker renderer and everything else to the rasterPoleFigureCompositor. Prefer this over calling a compositor directly.CompositePoleFigureConfiguration_tgained aDiscreteMarkerStyle(markerStyle.radiusFraction) to control marker size.StereographicProjectUpperHemisphere(...)projection helper.- Shared title / axis / info-block chrome extracted into a reusable
PoleFigureChromemodule.
Hexagonal and trigonal IPF triangle legends now print a small
Convention: X||a (TSL) (or X||a* (MTEX/Oxford)) sub-line under the title,
so a legend is self-documenting. Non-hex/trig classes are unchanged.
| App | Status |
|---|---|
generate_ipf_legends |
defaults to X‖a; prints the absolute output directory at start/finish; regenerates the per-class legend + pole-figure matrix as PNG |
render_ebsd |
--convention now defaults to x_a (TSL) |
- Strict IPF-color corners.
LaueOpsTest::IPFColor_SSTCornersasserts the standard-stereographic-triangle corners render as pure primaries for every Laue class: apex ([0001]/[001]) = red, η-min edge = green, η-max edge = blue (exact primaries for cubic and hex 6/mmm; dominant-channel just inside the edge for the wider-wedge classes, which sit on a fold boundary). - Discrete-render performance guard. A hidden test renders a >1M-pole discrete figure to bound decimation cost.
- MTEX positions still validated.
PoleFigurePositionTestcontinues to pass against the MTEX golden (X‖a*).PoleFigureLaueComparisonTestnow routes throughGeneratePoleFigureComposite(vector markers) and pinsX‖a*locally to stay aligned with its MTEX comparison script.
EbsdLib 3.0 is the "MTEX-compatible pole figures and IPF coloring" release. The two themes are:
- Crystallographic correctness for hexagonal / trigonal systems —
direction conventions, basal-plane plane families, and pole-figure
positions now match MTEX out of the box (validated to
< 10⁻⁷against MTEX 6.1.0 across all 11 Laue classes). - Pluggable IPF coloring —
ColorKeyKindenum selects between TSL (DREAM3D-legacy), PUCM (perceptually uniform, Nolze 2016), and Nolze-Hielscher color keys at the call site, with optional grid-snapped ("flat-shaded") variants for MTEX-style legends.
Detailed API reference: v3_api_reference.md.
Source consumers of EbsdLib must touch each of these only if they were calling the affected symbol. The simplnx / DREAM3DNX / DREAM3D_Plugins trees compile clean against v3 without source changes (audited; see the v3 release checklist).
generateSphereCoordsFromEulers(eulers, c1, c2, c3)→generateSphereCoordsFromEulers(eulers, c1, c2, c3, ebsdlib::HexConvention conv). Cubic / tetragonal / orthorhombic / monoclinic / triclinic overrides ignoreconv; passHexConvention::NotApplicable. Hex and trigonal overrides honor it.getDefaultPoleFigureNames()→getDefaultPoleFigureNames(ebsdlib::HexConvention conv). Hex/trig classes return different labels per convention (<10-10>↔<2-1-10>shuffles); cubic/tet/ortho/mono/triclinic return the same labels regardless.generateIPFTriangleLegend(int imageDim, bool generateEntirePlane)→generateIPFTriangleLegend(int imageDim, bool generateEntirePlane, ebsdlib::HexConvention conv, ebsdlib::ColorKeyKind kind = ebsdlib::ColorKeyKind::TSL, bool gridded = false). Thekindandgriddedarguments default;convdoes not, because the legend itself draws different labels under the two bases.generateIPFColor(eulers, refDir, convertDegrees)→generateIPFColor(eulers, refDir, convertDegrees, ebsdlib::ColorKeyKind kind = ebsdlib::ColorKeyKind::TSL). Thekinddefaults to TSL — pre-v3 callers recompile unchanged and get the same colors. Note that IPF coloring is now convention-invariant (it operates on the sample-frame reference direction, which never sees the basal basis); the pre-v3HexConventionparameter some patches briefly added was removed before release.
Code that uses the named values is unaffected. Code that
static_cast<HexConvention>(int) from a UI index needs the cast target
to match the new ordering — confirm by reading the new enum, not by
remembering pre-v3 integer values.
Several low-symmetry Laue classes had their symmetry orbits expanded as
part of the SymOps refactor (PR 2a–2d). Pole figures rendered before/after
v3 will not be byte-identical for these classes — the sym-op count for the
same Laue class changed. Position-space tests pass (< 10⁻⁷ vs MTEX), so
this is a correctness fix, not a regression. If you pin byte-level pixel
exemplars at the simplnx layer (the way the now-deprecated
PoleFigure_Exemplars_v5.tar.gz did), regenerate those baselines against
v3 output.
make_pole_figure,make_ipf,render_ebsd, and the simplnxWritePoleFigureFilter/WriteIPFImageFilterfilters now emit PNG (via STB image) instead of TIFF. Consumers that watched for*.tiffpole-figure output need to watch for*.pnginstead. The pixel content is the same up to PNG-encoder differences from libtiff.
enum class ColorKeyKind : uint8_t {
TSL = 0, // EDAX / DREAM3D-legacy IPF coloring
PUCM = 1, // Perceptually uniform (Nolze 2016)
NolzeHielscher = 2 // Nolze-Hielscher color key
};Each LaueOps subclass owns a per-class singleton for each kind. The
TSL singleton is shared across all classes (it's the standard EDAX
mapping); PUCM is parameterized by rotation point group; Nolze-Hielscher
is parameterized by the fundamental sector. Callers select among them at
the call site by passing the kind enum to generateIPFColor or
generateIPFTriangleLegend — instances stay stateless, no setter API.
Cubic / tetragonal / orthorhombic / monoclinic / triclinic Laue classes
have no X‖a vs X‖a* distinction to make. The NotApplicable value
is the right thing for those classes to pass when one of the new
hex/trig-aware APIs requires the convention parameter. The hex/trig
overrides assert if they receive NotApplicable, and the non-hex/trig
overrides ignore the parameter regardless of its value.
generateIPFTriangleLegend(..., gridded=true) wraps the selected color
key in a GriddedColorKey (~1° eta × chi resolution), producing
MTEX-style flat-shaded cells instead of a smooth continuous gradient.
Useful for visually matching MTEX legend renders side-by-side.
New app at Source/Apps/render_ebsd.cpp. Single-binary entry point for
pole figure, IPF map, and IPF legend rendering against a .ang / .ctf
input — useful for CI smoke tests and reference renders. Rejects missing
output directories and bad positional arguments before doing any work.
The IPF rendering config struct now has a hexConvention field so the
hex/trig-aware code paths (legend labels, basal-plane direction tables)
can be routed through the same configuration object the existing
PoleFigureConfiguration_t uses.
generateIPFTriangleLegend output is now cropped to the SST contents
(plus a small margin). No more wasted whitespace on classes whose
fundamental sector occupies only a fraction of the unit triangle.
| App | Status |
|---|---|
make_pole_figure |
rewritten — STB/PNG output, MTEX-compatible pole positions, HexConvention-aware family labels |
make_ipf |
rewritten — STB/PNG output, ColorKeyKind dispatch |
generate_ipf_legends |
new flags for color key + gridded variant; emits per-class legend matrix |
render_ebsd |
new — single-binary pole-figure / IPF map / IPF legend renderer for .ang / .ctf inputs |
generate_pole_figure |
unchanged surface, but inherits the renderer overhaul |
generate_ipf_from_file |
unchanged surface |
- Position-space test.
PoleFigurePositionTest(Catch2) compares EbsdLib pole figure positions against an MTEX-generated golden CSV across 396 buckets (12 canonical orientations × 11 Laue classes × 3 plane families). Worst max-distance:6.29 × 10⁻⁸at1e-5tolerance. SeeData/Pole_Figure_Validation/ReadMe.md. - Renderer reproducibility.
PoleFigureCompositorTest::All_Laue_Classespins byte-level renderer output across every Laue class. - HexConvention plumbing. simplnx
WritePoleFigureFilterhas two test cases: a mask-effectiveness test (Pole_Figure_Exemplars_v6) and a HexConvention plumbing test that asserts both the intensity array AND the composite RGB image differ when switching X‖a → X‖a* on hex data. - Convention story. The geometric picture is in
x_parallel_a_star_convention.svg; the canonical internal direction tables areX‖a*, matching MTEX.