PlotIndividualOrientationsInMTex
MTex is a free, GPL, MATLAB toolbox for quantitative texture analysis. It includes many functions for dealing with ODF, plotting pole figures and so on.
We use it to plot 3D-XRD data, for which you have a collection of grains, with their orientation matrix. You want to plot the orientations of the individual grains as dots (or circles) overlayed on a pole figure reconstructed from and ODF.
The grain orientations are provided in VPSC texture file, with Bunge Euler angles.
Pole figure conventions in Mtex
By default, MTex plots pole figures with Z in the center, X to the Nord, and Y to the West. You can check the location of the axes using the following commands
plot(zvector,'Marker','p','MarkerSize',15,'MarkerFaceColor','red','MarkerEdgeColor','black') plot(xvector,'Marker','p','MarkerSize',15,'MarkerFaceColor','red','MarkerEdgeColor','black') plot(yvector,'Marker','p','MarkerSize',15,'MarkerFaceColor','red','MarkerEdgeColor','black')
You can also change this default behavior using
plotx2east plotx2north plotx2west plotx2south.
Prepare Mtex for loading you data
You should define a crystal symmetry (cs for instance), sample symmetry (ss for instance) and the location of the data you want to load
cs = symmetry('tetragonal');
ss = symmetry('-1');
fname = fullfile('/home/data/directory/','','filename.tex');
Crystal symmetry will be something like cubic, hexagonal, tetragonal, etc. In 3D-XRD experiments, sample symmetry is usually not known. It will depend on the grain you indexed, the geometry of your experiment, etc.
Load individual orientations and create a texture
To load the data with individual orientations and generate an ODF, use the following command
halfwidth = 10*degree;
odf = loadODF_generic(fname,'cs',cs,'ss',ss,'bunge','degree','ColumnNames',{'Euler 1' 'Euler 2' 'Euler 3' 'weight'},'header',4,'Columns',[1,2,3,4],'halfwidth',halfwidth);
This will load the VPSC texture file and generate the ODF. In Mtex, this is done by adding a bell shaped model at every measured individual orientation. Some comments:
- The halfwidth of the bell shaped model ODF is crucial for the resulting ODF it is very important to choose it carefully. I typically use 10 degrees.
- This routine assumes a VPSC file format, which has 4 lines of header. If you use another format, with more or less headers, do not forget to adjust the command.
- This routine also assumes that you are using Bunge euler angles, in degrees.
You can the plot a plain pole figure using
plotpdf(odf,Miller(1,0,0),'antipodal','resolution',2*degree) plotpdf(odf,Miller(1,0,0),'contourf', 'antipodal','resolution',2*degree)
Load individual orientations, and keep them as such
To load the data with individual orientations and and keep them as such, you should use
ebsd = loadEBSD_generic(fname,'cs',cs,'ss',ss,'bunge','degree','ColumnNames',{'Euler 1' 'Euler 2' 'Euler 3' 'weight'},'header',4,'Columns',[1,2,3,4]);
o = get(ebsd,'orientations')
and you can plot the individual orientation using
plotpdf(o,Miller(1,0,0),'MarkerSize',3,'MarkerEdgeColor','k','MarkerFaceColor','w')
Some comments:
- This routine assumes a VPSC file format, which has 4 lines of header. If you use another format, with more or less headers, do not forget to adjust the command.
- This routine also assumes that you are using Bunge euler angles, in degrees.
Recently, we noticed an issue while loading orientations for crystals with orthorhombic symmetry. For some reason, the sample symmetry was then forced to orthorhombic as well and there were inconsistencies in pole figures. Therefore, we wrote our own loading routine. You can see it below
test = load_generic(fname,'header',4,'Columns',[1,2,3,4]);
[m,n] = size(test);
clear o;
for j=1:m,
o(j) = orientation('Euler',test(j,1)*degree,test(j,2)*degree,test(j,3)*degree,cs,ss);
end
Rotate the ODF
In some cases, you might want to rotate the ODF before plotting. For instance, if you have a compression direction along Y, and you want to plot pole figures of the compression direction, you should rotate the ODF by 90 (or -90 degrees) around XX. To do so, you should define a rotation and rotate the ODF
rotate = rotation('Euler',0*degree,90*degree,0*degree)
odfRotated = rotate(odf,rotate)
ebsdRotated = rotate(ebsd,rotate)
I am not entirely sure weather you should rotate by +90 or -90 degrees. Please check your data!!
Similarly, if you have a compression direction along X, and you want to plot pole figures of the compression direction, you should rotate the ODF by 90degrees round Z and 90 around XX:
rotate = rotation('Euler',90*degree,90*degree,0*degree)
odfRotated = rotate(odf,rotate)
ebsdRotated = rotate(ebsd,rotate)
Again, please check! There could +90 or -90 degrees rotations. I'm not sure.
Plot the ODF and individual orientations, together, on the same plot
To do this type of plots in color, use something like
plotpdf(odf,Miller(1,0,0),'antipodal','resolution',2*degree) hold all plotpdf(o,Miller(1,0,0),'MarkerSize',5,'MarkerEdgeColor','w') hold off
You can remove the boxes, add spaces between pole figures and so on in the options, once the figure has been plotted. To force all pole figures to use the same color scale, type setcolorrange('equal');. To force any orientation with a probability below 0 to show up in white, type setcolorrange('zero2white');.
Another version, in black and white this time
setMTEXpref('defaultColorMap',white2blackColorMap)
plotpdf(odf, [Miller(1,0,0), Miller(0,1,0), Miller(0,0,1)],'antipodal','resolution',2*degree);
hold all;
plotpdf(o, [Miller(1,0,0), Miller(0,1,0), Miller(0,0,1)],'MarkerSize',10,'MarkerFaceColor','w','MarkerEdgeColor','k');
setcolorrange('equal');
hold off;
A final version, in black and white and with contours
setMTEXpref('defaultColorMap',white2blackColorMap)
plotpdf(odf, [Miller(1,0,0), Miller(0,1,0), Miller(0,0,1)],'contourf','antipodal','resolution',2*degree);
hold all;
plotpdf(o, [Miller(1,0,0), Miller(0,1,0), Miller(0,0,1)],'MarkerSize',10,'MarkerFaceColor','w','MarkerEdgeColor','k');
setcolorrange('equal');
hold off;
Batch processing of multiple files
This routine will load multiple individual orientation files, use the same intensity scale for textures, and save them in jpeg
cs = symmetry('orthorhombic');
ss = symmetry('-1');
minPFrange = 0;
maxPFrange = 3;
markersize = 8;
path = '/home/path/to/data';
texture = {'file1.dat', 'file2.dat', 'file3.dat'};
images = {'file1.jpg', 'file2.jpg', 'file3.jpg'};
[tt,nfiles] = size(texture);
disp(nfiles)
for i=1:nfiles,
fname = fullfile(path,texture{i});
output = fullfile(path,images{i});
test = load_generic(fname,'header',2,'Columns',[1,2,3,4]);
[m,n] = size(test);
clear o;
for j=1:m,
o(j) = orientation('Euler',test(j,1)*degree,test(j,2)*degree,test(j,3)*degree,cs,ss);
end
halfwidth = 10*degree;
odf = loadODF_generic(fname,'cs',cs,'ss',ss,'bunge','degree','ColumnNames',{'Euler 1' 'Euler 2' 'Euler 3' 'weight'},'header',2,'Columns',[1,2,3,4],'halfwidth',halfwidth);
setMTEXpref('defaultColorMap',white2blackColorMap)
plotpdf(odf,[Miller(1,0,0), Miller(0,1,0), Miller(0,0,1)],'antipodal','resolution',2*degree,'colorrange',[minPFrange,maxPFrange])
hold all
plotpdf(o,[Miller(1,0,0), Miller(0,1,0), Miller(0,0,1)],'antipodal','MarkerSize',markersize,'MarkerFaceColor','w','MarkerEdgeColor','k','gray')
hold off
savefigure(output)
end