Exporting an orientation distribution function (ODF) means choosing what the receiving program needs. MTEX supports four common representations:
- a pickle file containing the MTEX object, which preserves it as a Python object;
- an MTEX ASCII file describing supported ODF components in readable text;
- a generic table of ODF values on an orientation grid;
- a VPSC table of discrete orientations and their volume fractions.
The last two are finite approximations to the continuous ODF introduced in ODF Theory. Record the Euler-angle convention, angle units, grid resolution or number of orientations, crystal symmetry and specimen symmetry whenever the result must be reproducible.
import os
import pickle
import tempfile
import numpy as np
from mtex import *
Define a Model ODF
The examples use one mixture of uniform, fibre and unimodal components. Keeping the ODF fixed makes the differences between the file formats visible.
cs = crystalFrame('cubic')
mod1 = orientation.byAxisAngle(xvector, 45 * degree, cs)
mod2 = orientation.byAxisAngle(yvector, 65 * degree, cs)
model_odf = (0.5 * uniformODF(cs)
+ 0.05 * fibreODF(Miller(1, 0, 0, cs), xvector, halfwidth=10 * degree)
+ 0.05 * fibreODF(Miller(0, 1, 0, cs), yvector, halfwidth=10 * degree)
+ 0.05 * fibreODF(Miller(0, 0, 1, cs), zvector, halfwidth=10 * degree)
+ 0.05 * unimodalODF(mod1, halfwidth=15 * degree)
+ 0.3 * unimodalODF(mod2, halfwidth=25 * degree))
plot(model_odf, sections=6, verbose=False)

The six sections show a smooth density with localized maxima and fibre ridges on a uniform background. The grid and VPSC exports below replace this continuous function by finitely many rows.
Save a Python Object
Use Python’s pickle when the next step also runs in Python with MTEX. Unlike a table
export, this stores model_odf itself. MATLAB’s counterpart is save into a .mat
file.
tempdir = tempfile.mkdtemp()
pickleName = os.path.join(tempdir, 'odf.pkl')
with open(pickleName, 'wb') as f:
pickle.dump(model_odf, f)
Loading the file returns the stored ODF object rather than reconstructing one from sampled values. The assertion makes that round trip executable.
with open(pickleName, 'rb') as f:
saved = pickle.load(f)
assert np.allclose(saved.eval(cat(mod1, mod2)), model_odf.eval(cat(mod1, mod2)))
Export Values on a Generic Grid
By default, export writes four columns. The first three are Bunge Euler angles on a regular \(5^\circ\) grid, in degrees, and the fourth is the ODF value at that orientation. These values are density values in multiples of a uniform distribution, not volume fractions.
Sampling does not preserve the internal ODF representation. A grid that is too coarse can miss a narrow component, so choose the resolution from the smallest feature that the receiving calculation must resolve. Here we request \(10^\circ\) to keep the example file compact.
genericName = os.path.join(tempdir, 'odf-generic.txt')
export(model_odf, genericName, 'Bunge', resolution=10 * degree)
The header records the symmetries and names the four columns. The first data rows then contain angles and the sampled ODF value.
print('Beginning of the generic grid file:')
with open(genericName) as f:
for k in range(6):
print(f.readline().rstrip())
Beginning of the generic grid file:
% MTEX ODF
% crystal symmetry: "m3̅m"
% specimen symmetry: "specimen"
% phi1 Phi phi2 value
0.00000 0.00000 0.00000 3.46659
10.00000 0.00000 0.00000 2.63068
Pass a Grid Directly
Other Euler-angle conventions and resolutions are available as options to export.
For complete control, construct an orientation grid and pass it directly. This example
uses an equispaced grid with a nominal resolution of \(10^\circ\).
S3G = equispacedSO3Grid(cs, resolution=10 * degree)
gridName = os.path.join(tempdir, 'odf-equispaced.txt')
export(model_odf, gridName, S3G, 'Bunge', 'generic')
Export an MTEX Component Description
The 'mtex' interface writes a human-readable description of the ODF components. It
records the components themselves instead of replacing them by grid samples, and it is
not a general interchange format.
The current source tree has no matching reader: SO3Fun.load offers
loaders for generic and VPSC ODF files only, so this format is write-only. Use pickle
when an exact round trip matters. Not every representation is supported either, and
the exporter records that harmonic components cannot be written in this format.
mtexName = os.path.join(tempdir, 'odf.mtex')
export(model_odf, mtexName, 'Bunge', interface='mtex')
The beginning of the file identifies the symmetries and the uniform component. Later blocks describe the fibre and radial components.
print('Beginning of the MTEX component file:')
with open(mtexName) as f:
for k in range(8):
print(f.readline().rstrip())
Beginning of the MTEX component file:
% MTEX ODF
% crystal symmetry: "m3̅m"
% specimen symmetry: "specimen"
%
%% uniform component
% weight: 0.50000
%
%% fibre component
Export a Synthetic Polycrystal for VPSC
The VPSC code and other crystal plasticity
programs operate on discrete crystal orientations rather than directly on an ODF. The
'VPSC' interface therefore draws orientations from the ODF and writes their Bunge
Euler angles and volume fractions.
vpscName = os.path.join(tempdir, 'odf-vpsc.txt')
export(model_odf, vpscName, 'VPSC', points=5000)
A VPSC block has four header lines. Its fourth line gives the Euler-angle convention
and orientation count: B means Bunge. Each following row contains three Euler angles
in degrees and one volume fraction.
print('Beginning of the VPSC file:')
with open(vpscName) as f:
for k in range(6):
print(f.readline().rstrip())
Beginning of the VPSC file:
texture exported by MTEX
B 5000
191.51 58.01 161.33 0.0002000
133.24 142.42 21.10 0.0002000
The points option controls the number of orientations and defaults to 10000. More
orientations usually represent the continuous density more finely, but they also make
the receiving calculation larger. A VPSC file carries no crystal symmetry, so pass that
information separately when it is read. Import from VPSC shows the
return path.
Clean Up
All examples wrote to a temporary directory. Remove every file now that the previews and round-trip check are complete.
os.remove(pickleName)
os.remove(genericName)
os.remove(gridName)
os.remove(mtexName)
os.remove(vpscName)
Choosing a Format
Use pickle while continuing an analysis in Python and MTEX. Use MTEX ASCII when a
readable description of supported components is useful. Use a generic grid when the
receiving program expects function values, and use VPSC when it expects a synthetic
polycrystal.
Grid spacing and sample size are accuracy parameters, not merely file-format options. Random Sampling explains why a random statistical sample and an optimized numerical representation are not interchangeable. ODF Import explains how MTEX interprets tabulated values and weights when files are read back. Orientation Export is the corresponding page when the starting data are already individual orientations rather than an ODF.
References
- H.-J. Bunge, Texture Analysis in Materials Science: Mathematical Methods, Butterworths, 1982. This is the standard reference for ODFs and the Bunge Euler-angle convention.
- R. A. Lebensohn and C. N. Tomé, A self-consistent anisotropic approach for the simulation of plastic deformation and texture development of polycrystals, Acta Metallurgica et Materialia 41 (1993), 2611–2624. This paper introduces the VPSC formulation used by the discrete-orientation export.
Technical Details
MATLAB’s .mat working copy is Python’s pickle; a pickled frame comes back as the
session’s own handle, so the loaded function lives in the same frames as the original.
The three writers, 'generic', 'mtex' and 'VPSC', are in mtex/io/exportodf.py,
chosen by the flag or the interface keyword. The VPSC sample
is a random draw, so its rows differ from MATLAB’s.
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/ODFExport_py.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.