Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 62 additions & 28 deletions Examples/Basics/Basics.m
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,19 @@
% Shows the simplest method for reconstructing the Austenite phase
% from an EBSD scan of Martensite
% ======================================================================= %

% Create "AF96.ang" file from provided sample data if not already made
if size(dir('Af96.ang'),1) == 0
data = h5read("../../Resources/EBSD/EBSD.hdf5","/AF96_small/AF001");
header = h5readatt("../../Resources/EBSD/EBSD.hdf5","/AF96_small",'header');
f = fopen('AF96.txt','w');
fprintf(f,header);
fclose(f);
writematrix(data','AF96.txt','delimiter',' ','WriteMode','append')
movefile AF96.txt AF96.ang
end
tic

% load some metadata about folder locations and do a flight check
Mart2Aust_Parent_folder = "C:\Users\agerlt\workspace\Mart2Aust";
Mart2Aust_Parent_folder = "C:\Users\ALEBRUS\Desktop\Software\Matlab\Mart2Aust-main";
meta.Data_folder = Mart2Aust_Parent_folder + filesep +'Resources'+...
filesep + 'EBSD'+ filesep +'AF96_small';
meta.MTEX_folder = Mart2Aust_Parent_folder + filesep + 'MTEX';
meta.MTEX_folder = Mart2Aust_Parent_folder + filesep + 'Mart2Aust' + filesep + 'MTEX';
meta.Functions_folder = Mart2Aust_Parent_folder + filesep + 'Mart2Aust';
meta.current_folder = string(pwd);
meta.MTEX_Version = "mtex-5.7.0";
addpath(genpath(meta.Functions_folder));

check_AusRecon_loaded;
% check_AusRecon_loaded;
try
disp(['Compatable MTEX version ', check_MTEX_version(meta.MTEX_Version), ' detected'])
catch
Expand All @@ -34,6 +24,8 @@
addpath(meta.MTEX_folder + filesep + meta.MTEX_Version);
startup_mtex
end
setMTEXpref('xAxisDirection','east')
setMTEXpref('zAxisDirection','outOfPlane')
clear Aus_Recon_Parent_folders split_loc f data header Mart2Aust_Parent_folder


Expand All @@ -45,40 +37,82 @@

% Load default reconstruction options and file location
options = load_options("default");
fname = dir('AF96.ang');
% Use these two choices to generate some other location information
name = split(string(fname.name),'.');
name = name(end-1);
location = [fname.folder, filesep, fname.name];
pname = 'C:\Users\ALEBRUS\Documents\Microstructure_Work\Exxon_2022\Data';
fname = '55-HR_EBSD1.ang';
tname = fullfile(pname,fname);

% Load a Martensite/Austenite Orientation Relationship and MDF halfwidth
% that was previously measured on this scan (remove this line to recalculate
% the values. See some of the other examples for more details on defining
% and calculating the orientation relationship)
options.OR_ksi = [2.9057 7.7265 8.2255];
options.OR_noise = 0.0281;
%% Alter Default Options
% options.OR_ksi = [2.7 9.2 9.4];
% % options.OR_ksi = [2.4284 8.6749 8.8738];
% % options.OR_ksi = [3.89,8.84,9.17];
% options.OR_noise = 0.029;
% options.RGC_in_plane_m = 6;
% options.RGC_in_plane_b = 12;
% options.RGC_post_pre_m = 1.75e-1;
% options.RGC_post_pre_b = 0.6;
% options.OR_sampling_size = 2000;

% load the ebsd
original_ebsd = EBSD.load(location, ...
options.OR_plot_PAG_Mart_Guess = 1;
options.OR_plot_ODF_of_PAG_OR_guess = 1;

%% Load EBSD and Format for Reconstruction
% Load original ebsd
original_ebsd = EBSD.load(tname, ...
'convertEuler2SpatialReferenceFrame','setting 2');

% Truncate ebsd if flagged
truncate = 1;
if truncate
ebsd = truncate_ebsd(original_ebsd,10,125,7,107);
else
ebsd = original_ebsd;
end

% Not all scans list phases in the same order: this command fixes that
ebsd = prep_for_Recon(original_ebsd,options);
clear original_ebsd
ebsd = prep_for_Recon(ebsd,options);

% clear original_ebsd
% at this point, we have identical scans with the following phase IDs:
% 0 : Unindexed
% 1 : Untransformed Parent (High temperature, or HT)
% 2 : Transformed Child (Low Temperature, or LR)
% 3 : Reconstructed Parent (starts empty) (Reconstructed, or R)

%% Auto OR Computation

% Determine the Orientation Relationship, if not already given
CS_HT =ebsd.CSList{1};
CS_LT =ebsd.CSList{2};
CS_HT = ebsd.CSList{1};
CS_LT = ebsd.CSList{2};
[ebsd.opt.OR,ebsd.opt.HW,~] = AutoOR_estimation(ebsd,options);

%% Calculate Misorientation Distribution Function

% Determine the Misorientation Distribution function for the LT phase
[ebsd.opt.LT_MDF,ebsd.opt.psi] = calc_LT_MDF(CS_HT, CS_LT, ebsd.opt.HW, ebsd.opt.OR);

%% Perform Reconstruction
tic

[Recon_ebsd, Recon_Likelihood] = Call_Reconstruction_Austin(ebsd,options);

[a,AusGrns,E2627,E112_13] = CalcGrainSize(Recon_ebsd,3,1);

Recon_Time = toc/60;
%%
tic
options.RGC_in_plane_m = 5;
options.RGC_in_plane_b = 3;
options.RGC_post_pre_m = 1.75e-1;
options.RGC_post_pre_b = 2;

% Perform the actual Reconstruction
Recon_ebsd = Call_Reconstruction(ebsd,options);
[Recon_ebsdOrig, Recon_LikelihoodOrig] = Call_Reconstruction(ebsd,options);
Recon_TimeOrig = toc/60;
%% Segment Variants

% Segment the variants using the low temp and high temp maps
variant_int_map = variants(ebsd, Recon_ebsd,options);
6 changes: 3 additions & 3 deletions Mart2Aust/Core/AutoOR_estimation.m
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@

%% search the low temp phase (Phase 2) for acceptably close PAG
% for first iteration, make the entire scan searchable
searchable_ebsd = ebsd(ebsd.phaseId == 2);
searchable_ebsd = ebsd;
for iteration = 1:10
% NOTE TO FUTURE USERS: The first step in this code is to use the MTEX
% calcgrain tool to find likely martensite grains, then merge grains
Expand Down Expand Up @@ -66,7 +66,7 @@
%to the leftovers-only search, JIC. Feel free to try either way.
%% Method 1: Search all unused areas
% find indices of a possible grain
[Aus_Grain_Ids,~,AusOr] = HT_grain_guess(searchable_ebsd);
[Aus_Grain_Ids,~,AusOr] = HT_grain_guess_Alex(searchable_ebsd);
% extract the expected grain and leave the remainder for future searches
grain_ebsd = searchable_ebsd(Aus_Grain_Ids);
searchable_ebsd(Aus_Grain_Ids) = [];
Expand All @@ -89,6 +89,7 @@
martensite=martensite(keep(1:options.OR_sampling_size));
else
end

% plot the martensite pole figure and grain if desired
if options.OR_plot_PAG_Mart_Guess == 1
figure();
Expand Down Expand Up @@ -142,7 +143,6 @@
%leftover can ignore
austenite_prior_odf=uniformODF(CS_HT,SS);


prior_pars=struct;
prior_pars.ksi_prior_mu=ksi_prior_mu;
prior_pars.ksi_prior_sigma=ksi_prior_sigma;
Expand Down
33 changes: 25 additions & 8 deletions Mart2Aust/Core/Call_Reconstruction.m
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
function HT_ebsd = Call_Reconstruction(orig_ebsd,options,LT_MDF)
function [HT_ebsd, GlobOP_wts] = Call_Reconstruction(orig_ebsd,options,LT_MDF)
% Do the actual reconstruction from the low temp to the high temp phase

% Pre-flight stuff:
Expand All @@ -23,7 +23,7 @@

% Now do the actual reconstruction as a seperate function (helps avoid
% accidental overwrites and removes pre-flight parameters)
recon_ebsd = Reconstruct_HT_grains(LT_ebsd,...
[recon_ebsd, RecOP_wts] = Reconstruct_HT_grains(LT_ebsd,...
neigh_list,...
IP_wts,...
options);
Expand All @@ -34,10 +34,15 @@
HT_ebsd = orig_ebsd;
HT_ebsd(orig_ebsd.phaseId == 2).orientations = temp_ebsd.orientations;
HT_ebsd(orig_ebsd.phaseId == 2).phaseId = recon_ebsd.phaseId;

% Set likelihood for entire ebsd data set, regardless of the phase. Those
% specific likelihood values can be later extracted using ebsd('phase').id
GlobOP_wts = zeros(length(orig_ebsd),1);
GlobOP_wts(orig_ebsd.isIndexed) = RecOP_wts;
end


function LT_ebsd = Reconstruct_HT_grains(LT_ebsd,neigh_list,IP_wts,options)
function [LT_ebsd,RecOP_wts] = Reconstruct_HT_grains(LT_ebsd,neigh_list,IP_wts,options)
%Reconstruct_HT_grains perform the actual reconstruction
% performs a 'while ' loop that progressively cuts out possible grains
% until eithr there is nothing left to cut, or the algorithm starts
Expand All @@ -51,6 +56,9 @@
%%figure()
%%plot(Active_Ebsd,Active_Ebsd.orientations)

% Alex add on: Global Likelihood
RecOP_wts = zeros(length(LT_ebsd),1);

while continue_recon == 1
% checks to break out of while loop
if iterations > options.max_recon_attempts || bad_cut_counter > 10
Expand All @@ -61,7 +69,7 @@
disp('=========================================\n')
continue
end
if sum(LT_ebsd.phaseId == 2) == 0
if sum(LT_ebsd.phaseId == 2) < 4
continue_recon = false;
disp('\n=========================================')
disp('reconstruction completed successfully!')
Expand All @@ -71,7 +79,12 @@

%% ======== Step 1 ======== %%
% Find a likely high temp grain orientation to attempt to cut out.
Guess_ID = randsample(1:length(Active_Ebsd),1,true,Active_Ebsd.ci);
try
Guess_ID = randsample(1:length(Active_Ebsd),1,true,Active_Ebsd.ci);
catch
Guess_ID = randsample(1:length(Active_Ebsd),1,true);
end

HT_guess_ori = Active_Ebsd(Guess_ID).orientations;

% Using that guess, make a rough cut to find a likely HT grain.If the
Expand Down Expand Up @@ -102,7 +115,7 @@
% if the grain made it this far, reset the counters and do 5 graph
% cuts (1 for the parent, 4 for the twins) to find the parent/twin areas
bad_cut_counter = 0;
[PT_ID_stack] = Seperate_Twins(proposed_grain, neigh_list, IP_wts, PT_oris,options);
[PT_ID_stack,LocOP_wts] = Seperate_Twins(proposed_grain, neigh_list, IP_wts, PT_oris,options);
% Use this data to overwrite the orientation and phase data in LT_ebsd
for i = 1:size(PT_oris,1)
mask = PT_ID_stack(i,1:end);
Expand All @@ -113,6 +126,7 @@
IDs_to_assign = proposed_grain(mask).id;
LT_ebsd(ismember(LT_ebsd.id, IDs_to_assign)).orientations = PT_oris(i);
LT_ebsd(ismember(LT_ebsd.id, IDs_to_assign)).phase = 3;
RecOP_wts(ismember(LT_ebsd.id, IDs_to_assign)) = LocOP_wts(mask);
end

% Prune out any orphaned pixels
Expand Down Expand Up @@ -292,6 +306,7 @@
[~,~,cs,~]=maxflow(FP_digraph,N+1,N+2);
cs(cs>length(Rough_Guess)) = [];
proposed_grain = Rough_Guess(cs);

% Code for debugging to show the cut out area. NOTE: this is not a grain,
% Its just a region of the scan that likely has at least one complete grain
% in it
Expand All @@ -307,7 +322,7 @@
end


function [Parent_and_Twin_IDs] = Seperate_Twins(proposed_grain, neigh_list, IP_wts, PT_oris,options)
function [Parent_and_Twin_IDs,LocOP_wts] = Seperate_Twins(proposed_grain, neigh_list, IP_wts, PT_oris,options)
% Given we have a for sure parent grain, check to see if parts would make
% more sense as a twin or as part of the parent.

Expand Down Expand Up @@ -338,6 +353,7 @@
mx = (bg_likelyhoods*options.RGC_post_pre_m);
b = options.RGC_post_pre_b;
OP_Parent_wts = mx + b;
LocOP_wts = OP_Parent_wts;
clear Parent_variants Parent_odf bg_likelyhoods mx b

for i = 2:size(PT_oris,1)
Expand Down Expand Up @@ -375,6 +391,8 @@
% save out the mask of the cut
% yes_mask = [1:N].*ismember([1:N],cs);
Parent_and_Twin_IDs(i,1:end) = ismember((1:N),cs);
% Establish OP weights for completed parent and twins
LocOP_wts(ismember((1:N),cs)) = OP_twin_wts(cs);
% find the already assigned orientations, set their in-plane weights to
% zero so they won't get pulled out again.
assigned =(1:N).*(sum(Parent_and_Twin_IDs,1)>0);
Expand Down Expand Up @@ -503,4 +521,3 @@
% neighborhood) change options.degree_of_connections_for_neighborhood
% from 2 to 1.


Loading