-
preischig authored
A comprehensive fitting package to refine grain positions, orientations, strains, global parameters and sample drifts. Signed-off-by:
preischig <preischig@gmail.com>
preischig authoredA comprehensive fitting package to refine grain positions, orientations, strains, global parameters and sample drifts. Signed-off-by:
preischig <preischig@gmail.com>
gtFitJacobianPattern.m 5.37 KiB
function JacPatt = gtFitJacobianPattern(newvars, spot, gr, par)
% GTFITJACOBIANPATTERN Jacobian matrix structure for fitting.
%
% The JacPatt matrix is sparse and created by collecting all indices which
% will be non-zero.
%
% Jacobian has the following structure (ng = no. of grains; ns = no. of
% spots):
% Each target variable (deviations in u,v,w) represents a row:
% [all du; all dv, all dw], size (3*ng,1)
% Each fitted variable represents a column, ordered this way:
% - global variables (geometry, constant energy, etc.)
% - drift variables:
% - X position
% - Y position
% - Z position
% - X rotation
% - Y rotation
% - Z rotation
% - energy
% - grain centroid positions
% - grain orientation
% - grain strain components
% Grain parameters are ordered by grain.
%
% OUTPUT
% JacPatt - Jacobian pattern (logical sparse matrix)
%
%
% Version 001 18-04-2014 by P.Reischig
%
%%%%%%%%%%%%%%%%%%%%%%
%% Global variables
%%%%%%%%%%%%%%%%%%%%%%
% Matrix size for global parameters: 3*numtarg x numglob.
% First build the matrix only for the spot U corrdinates, then repeat it
% another 2 times.
% No. of target parameters
numspot = sum([gr(:).numspots]);
% Indices of fitted global parameters (numglob: no. of fitted global parameters)
indglob = 1:par.nvarglobal;
% Row indices
ir = (1:numspot)';
ir = ir(:, ones(1,length(indglob)));
ir = reshape(ir, [], 1);
% Column indices
ic = indglob(ones(numspot,1), :);
ic = reshape(ic, [], 1);
% No. of all non-zero components
nonz = length(ir);
%%%%%%%%%%%%%%%%%%%%%%
%% Drift variables
%%%%%%%%%%%%%%%%%%%%%%
switch par.drift.method
case 'linear'
error('Linear interpolation not yet supported.')
case 'pchip'
ird = cell(1,length(par.drift.omega));
nom = length(par.drift.omega);
% ROW INDICES
% Omega range low and high boundaries where the drift variables
% have an effect (in degrees)
omlo(2) = par.drift.omega(1);
omlo(nom-1) = par.drift.omega(nom-3);
omlo(nom) = par.drift.omega(nom-2);
omhi(2) = par.drift.omega(4);
omhi(nom-1) = par.drift.omega(nom);
omhi(nom) = par.drift.omega(nom);
for ii = 3 : (nom-2)
omlo(ii) = par.drift.omega(ii-2);
omhi(ii) = par.drift.omega(ii+2);
end
% Change from degrees to images
omlo = omlo/par.omstep;
omhi = omhi/par.omstep;
% Find spot indices in the omega ranges (based on measured omega);
% ird is indexed according to fitted variables, not to omega ranges
for ii = 1:(nom-1)
ird{ii} = find((omlo(ii+1) < spot.mesw) & (spot.mesw < omhi(ii+1)));
end
% COLUMN INDICES
% Active drift modes
fitv = [par.fit_drift_posX, par.fit_drift_posY, par.fit_drift_posZ, ...
par.fit_drift_rotX, par.fit_drift_rotY, par.fit_drift_rotZ,...
par.fit_drift_energy];
% Last column index
lastcolind = par.nvarglobal;
% Loop through drift modes
for ii = 1:length(fitv)
if ~fitv(ii)
continue
end
% Column indices of current drift variables
icd = (lastcolind + 1) : (lastcolind + nom - 1) ;
% Current maximum column index
lastcolind = icd(end);
% Loop through time point (omega) variables within drift mode
for jj = 1:length(icd)
% Add row indices to list
ir = [ir; ird{jj}];
% Add the same number of column indices to list
icd_jj = icd(jj);
ic = [ic; icd_jj(ones(length(ird{jj}),1),1)];
end
end
otherwise
error('Interpolation method not recognised.')
end
% error
% add drift vars here
% par.drift
%%%%%%%%%%%%%%%%%%%%%%
%% Grain variables
%%%%%%%%%%%%%%%%%%%%%%
% Loop through grains, get corresponding row and column indices of
% Jacobian for each grain:
% - position
% - orientation
% - strain (if any)
% Assemble them in a vector.
if par.fit_grain_position || par.fit_grain_orientation || par.fit_grain_strain
for ii = 1:length(gr)
% Spot index tells which row indices (spots) correspond to grain
irg = gr(ii).indspot';
if isempty(gr(ii).indstrain)
% No strain, only position and orientation
irg = irg(:, ones(1,6)); % repeat 6 times
icg = [gr(ii).indcenter, gr(ii).indRvec];
icg = icg(ones(size(irg,1),1), :);
else
% Position, orientation, strain
irg = irg(:, ones(1,12)); % repeat 12 times
icg = [gr(ii).indcenter, gr(ii).indRvec, gr(ii).indstrain];
icg = icg(ones(size(irg,1),1), :);
end
ir = [ir; reshape(irg, [], 1)];
ic = [ic; reshape(icg, [], 1)];
nonz = nonz + numel(irg);
end
end
% Create sparse matrix from indices and component values
JacPatt0 = sparse(ir, ic, true, numspot, length(newvars)); %, nonz);
% Repeat to extend to V and W:
JacPatt = [JacPatt0; JacPatt0; JacPatt0];
end % function