From 7d8ab800ec95a05124fea33f7a2ea2ae06224cec Mon Sep 17 00:00:00 2001 From: Nicola Vigano <nicola.vigano@esrf.fr> Date: Wed, 6 May 2015 17:18:07 +0200 Subject: [PATCH] EBSD: added a few functions for interacting with EBSD data Signed-off-by: Nicola Vigano <nicola.vigano@esrf.fr> --- zUtil_Deformation/gtDefCalibrateEBSDMap.m | 68 ++++++++++++++ zUtil_Deformation/gtReadEBSDMapEulerCSVFile.m | 54 +++++++++++ .../plotting/gt6DRenderEBSDMapIPF.m | 91 +++++++++++++++++++ 3 files changed, 213 insertions(+) create mode 100755 zUtil_Deformation/gtDefCalibrateEBSDMap.m create mode 100755 zUtil_Deformation/gtReadEBSDMapEulerCSVFile.m create mode 100644 zUtil_Deformation/plotting/gt6DRenderEBSDMapIPF.m diff --git a/zUtil_Deformation/gtDefCalibrateEBSDMap.m b/zUtil_Deformation/gtDefCalibrateEBSDMap.m new file mode 100755 index 00000000..191e61fa --- /dev/null +++ b/zUtil_Deformation/gtDefCalibrateEBSDMap.m @@ -0,0 +1,68 @@ +function [rot_angle, rot_axis, rot_tensor] = gtDefCalibrateEBSDMap(EBSD_r_map, points, gr, symm) + + if (~exist('symm', 'var')) + symm = gtCrystGetSymmetryOperators(); + end + + num_points = numel(gr); + for ii = 1:num_points +% ref_e_vec = extract_from_map(EBSD_e_map, points{ii}); +% ref_r_vec = gtMathsEuler2RodInFundZone(ref_e_vec', symm); + ref_r_vec = extract_from_map(EBSD_r_map, points{ii}); + ref_r_vec = gtMathsRod2RodInFundZone(ref_r_vec', symm); + % Sometimes the axes definition is not the same +% ref_r_vec = [-ref_r_vec(2), ref_r_vec(3), -ref_r_vec(1)]; + + gr_r_vec = gr(ii).R_vector; + gr_r_vec = gtMathsRod2RodInFundZone(gr_r_vec', symm); + + [rot_vec(ii, :)] = get_angle_axis(ref_r_vec, gr_r_vec, symm); %#ok<AGROW> +% [rot_angle(ii), rot_axis(ii, :)] = get_angle_axis(ref_r_vec, gr_r_vec, symm); %#ok<AGROW> + end + +% rot_angle = sum(rot_angle) / num_points; +% rot_axis = sum(rot_axis, 1) / num_points; +% rot_axis = rot_axis / norm(rot_axis); + + rot_vec = sum(rot_vec, 1) / num_points; + rot_angle = 2 * atand(norm(rot_vec)); + rot_axis = rot_vec / norm(rot_vec); + + rotcomp = gtMathsRotationMatrixComp(rot_axis', 'col'); + rot_tensor = gtMathsRotationTensor(rot_angle, rotcomp); +end + +function r_vec_3 = get_angle_axis(r_vec_1, r_vec_2, symm) +% function [angle, axis] = get_angle_axis(r_vec_1, r_vec_2, symm) +% [angle, axis] = gtDisorientation(r_vec_1', r_vec_2', symm); + + g1 = gtMathsRod2OriMat(r_vec_1); + g2 = gtMathsRod2OriMat(r_vec_2); + + M = g1' * g2; + + r_vec_3 = gtMathsOriMat2Rod(M); + r_vec_3 = gtMathsRod2RodInFundZone(r_vec_3, symm); +% angle = 2 * atand(norm(r_vec_3)); +% axis = r_vec_3 ./ norm(r_vec_3); +end + +function r_vec = extract_from_map(EBSD_r_map, points) + kernel = 7; + k_dist = (kernel - 1) / 2; + + num_points = size(points, 1); + r_vecs = zeros(num_points, 3); + + for ii = 1:num_points + point = points(ii, :); + + ranges = [point(2)-k_dist, point(2)+k_dist; point(1)-k_dist, point(1)+k_dist]; + + temp_r_vecs = EBSD_r_map(ranges(1, 1):ranges(1, 2), ranges(2, 1):ranges(2, 2), :); + temp_r_vecs = sum(sum(temp_r_vecs, 1), 2) / (size(temp_r_vecs, 1) * size(temp_r_vecs, 2)); + r_vecs(ii, :) = reshape(temp_r_vecs, 1, []); + end + + r_vec = sum(r_vecs, 1) / num_points; +end diff --git a/zUtil_Deformation/gtReadEBSDMapEulerCSVFile.m b/zUtil_Deformation/gtReadEBSDMapEulerCSVFile.m new file mode 100755 index 00000000..1ca09ecb --- /dev/null +++ b/zUtil_Deformation/gtReadEBSDMapEulerCSVFile.m @@ -0,0 +1,54 @@ +function [EBSD_e_map, EBSD_r_map] = gtReadEBSDMapEulerCSVFile(filename, axes_perm) +% function [EBSD_e_map, EBSD_r_map] = gtReadEBSDMapEulerCSVFile(filename, axes_perm) +% Axes permutation allows to easily deal with different reference +% systems, like for instance: +% DCT Axes <-> EBSD Axes ([x y z] <-> [x'y'z']) +% x = -y' +% y = z' +% z = -x' +% Translates to: axes_perm = [-2 3 -1] +% +% NOTE: Only the Rodrigues vector map has the axes changed! +% + + c = tic(); + fprintf('Reading from file: "%s"..', filename); + + fid = fopen(filename); + sizes = fscanf(fid, 'Width,%d\nHeight,%d\nX Position,Y Position,Eul 1,Eul 2,Eul 3\n')'; + input = fscanf(fid, '%d,%d,%f,%f,%f'); + fclose(fid); + + fprintf('\b\b, Done in %f seconds.\n', toc(c)); + c = tic(); + fprintf('Converting to Euler and Rodriguez maps..'); + + xx = input(1:5:end)+1; + yy = input(2:5:end)+1; + ea1 = input(3:5:end); + ea2 = input(4:5:end); + ea3 = input(5:5:end); + + sizes = sizes([2 1]); + EBSD_e_map = zeros([sizes 3], 'single'); + ii = sub2ind([sizes, 3], yy, xx, 1 * ones(size(xx))); + EBSD_e_map(ii) = ea1; + ii = sub2ind([sizes, 3], yy, xx, 2 * ones(size(xx))); + EBSD_e_map(ii) = ea2; + ii = sub2ind([sizes, 3], yy, xx, 3 * ones(size(xx))); + EBSD_e_map(ii) = ea3; + + EBSD_e_map = EBSD_e_map * 180 / pi; + + dmvol_EBSD_e_map = permute(EBSD_e_map, [1 2 4 3]); + [gvdm_EBSD_e_map, size_dmvol_EBSD_map] = gtDefDmvol2Gvdm(dmvol_EBSD_e_map); + gvdm_EBSD_r_map = gtMathsEuler2Rod(gvdm_EBSD_e_map); + dmvol_EBSD_r_map = gtDefGvdm2Dmvol(gvdm_EBSD_r_map, size_dmvol_EBSD_map); + EBSD_r_map = reshape(dmvol_EBSD_r_map, [sizes 3]); + + EBSD_r_map = EBSD_r_map(:, :, abs(axes_perm)); + negative = axes_perm < 0; + EBSD_r_map(:, :, negative) = - EBSD_r_map(:, :, negative); + + fprintf('\b\b, Done in %f seconds.\n', toc(c)); +end diff --git a/zUtil_Deformation/plotting/gt6DRenderEBSDMapIPF.m b/zUtil_Deformation/plotting/gt6DRenderEBSDMapIPF.m new file mode 100644 index 00000000..66ace7d3 --- /dev/null +++ b/zUtil_Deformation/plotting/gt6DRenderEBSDMapIPF.m @@ -0,0 +1,91 @@ +function gt6DRenderEBSDMapIPF(EBSD_r_map, phase_id, varargin) + + conf = struct( ... + 'ipf_plane_normal', [], ... + 'flip_ud', false, ... + 'flip_lr', false, .... + 'clims', [], ... + 'lims_x', [], ... + 'pixel_to_cm', 0.05, ... + 'borders', 'no', ... + 'colorbar', 'no' ); + conf = parse_pv_pairs(conf, varargin); + + if (~isempty(conf.lims_x)) + % Note the inversion between x/y because of matlab's transpose problem + EBSD_r_map = EBSD_r_map(:, conf.lims_x(1):conf.lims_x(2), :); + end + + slice_ids = all(EBSD_r_map ~= 0, 3); + indx = find(slice_ids); + r_vecs = reshape(EBSD_r_map, [], 3); + r_vecs = r_vecs(indx, :); + + cmap = get_cmap(r_vecs, phase_id, conf.ipf_plane_normal); + + slice_R = zeros(size(slice_ids)); + slice_G = zeros(size(slice_ids)); + slice_B = zeros(size(slice_ids)); + + slice_R(indx) = cmap(:, 1); + slice_G(indx) = cmap(:, 2); + slice_B(indx) = cmap(:, 3); + + if (conf.flip_lr) + slice_R = fliplr(slice_R); + slice_G = fliplr(slice_G); + slice_B = fliplr(slice_B); + end + if (conf.flip_ud) + slice_R = flipud(slice_R); + slice_G = flipud(slice_G); + slice_B = flipud(slice_B); + end + + f = figure(); + ax = axes('Parent', f); + im = imagesc(cat(3, slice_R, slice_G, slice_B), 'Parent', ax); + + set(f, 'Units', 'centimeters') + img_size = size(slice_ids) * conf.pixel_to_cm; + img_size = img_size([2 1]); + if (strcmpi(conf.borders, 'no')) + position = [0, 0, img_size]; + set(f, 'Position', position) + set(f, 'Paperposition', position) + + set(ax, 'Units', 'normalized') + set(ax, 'Position', [0, 0, 1, 1]) + else + set(ax, 'Units', 'centimeters') + if (strcmpi(conf.colorbar, 'no')) + position = [0, 0, img_size] + [0, 0, 2, 1.5]; + set(f, 'Position', position) + set(f, 'Paperposition', position) + else + position = [0, 0, img_size] + [0, 0, 3, 2]; + set(f, 'Position', position) + set(f, 'Paperposition', position) + + cb = colorbar('peer', ax, 'location', 'EastOutside'); + set(cb, 'Units', 'centimeters') + position = [img_size(1)+1.35, 1, 0.65, img_size(2)]; + set(cb, 'Position', position) + end + position = [1, 1, img_size]; + set(ax, 'Position', position) + end +end + +function cmap = get_cmap(r_vecs, phase_id, ipf_plane_normal) + p = gtLoadParameters(); + cryst_system = p.cryst(phase_id).crystal_system; + cryst_spacegroup = p.cryst(phase_id).spacegroup; + symm = gtCrystGetSymmetryOperators(cryst_system, cryst_spacegroup); + + [cmap, ~, ~] = gtIPFCmap(phase_id, ipf_plane_normal, ... + 'r_vectors', r_vecs, ... + 'crystal_system', cryst_system, ... + 'background', false, ... + 'symm', symm); +end -- GitLab