Newer
Older
Nicola Vigano
committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
function [grain, gv] = gtDefSyntheticGrainCreate(fedpars, grain, parameters, dmvol, intvol)
% [grain, gv] = gtDefSyntheticGrainCreate(fedpars, grain, parameters, dmvol, intvol)
%
% Sets up the framework, variables, random strain distribution for simulated data.
% In the grain volume everything is defined in voxels, no dimensioning with pixel size.
% In the projections and diff. blobs, everything is defined in detector pixels
% (here comes the pixel size and setup geometry into play).
% Thus the dimensioning/scaling happens in the forward projection
% functions and their derivative functions, since they relate the
% grain voxels to the detector pixels.
%
% INPUT
% fedpars - FED parameters
% Some important ones:
% grainsize - no. of voxels in grain
% grainenv = grainsize
% ngv = grainsize
% gvsize = [1 1 1]
% loadbl - blobs ID-s in grain.allblobs to be generated
% dcomps - for rotations only use [1 1 1 0 0 0 0 0 0]
% blobsizeadd - blob volume padding
% vox000sam - (X, Y, Z) coordinates of voxel (0, 0, 0) in the Sample reference frame
% grain - grain data as output from Indexter
% parameters - parameters as in DCT paramaters file
% dmvol - all deformation components per voxel for the entire volume
% (nx, ny, nz, ndef); if empty, random distribution is applied
% with max limits as in fedpars.dapplim and max gradients
% as in fedpars.dappgradlim
% intvol - Volume instensities
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Load and update geometry parameters
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
fprintf('Setting voxels up..')
c = tic();
labgeo = parameters.labgeo;
labgeo.omstep = gtGetOmegaStepDeg(parameters);
% Rotation matrix components:
labgeo.rotcomp = gtMathsRotationMatrixComp(labgeo.rotdir', 'col');
samgeo = parameters.samgeo;
recgeo = parameters.recgeo;
if (~isfield(parameters, 'detgeo') || isempty(parameters.detgeo))
[parameters.detgeo, labgeo] = gtGeoConvertLegacyLabgeo2Detgeo(labgeo);
end
detgeo = parameters.detgeo;
% Update labgeo
parameters.labgeo = labgeo;
if (~isfield(parameters.fsim, 'oversizeVol') ...
|| isempty(parameters.fsim.oversizeVol))
parameters.fsim.oversizeVol = 1.2;
end
Nicola Vigano
committed
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Load grain parameters
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if (~exist('dmvol', 'var') || isempty(dmvol))
Nicola Vigano
committed
gr_size = fedpars.grainsize; % x, y, z number of voxels in grain
Nicola Vigano
committed
gr_size = [size(dmvol, 1), size(dmvol, 2), size(dmvol, 3)];
Nicola Vigano
committed
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Volume sampling and volume elements
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
fprintf('\b\b: Done in %g seconds.\nAllocating memory for elements..', toc(c))
c = tic();
% total number of vol elements
Nicola Vigano
committed
nv = gr_size(1) * gr_size(2) * gr_size(3);
nv_ones = ones(nv, 1);
Nicola Vigano
committed
nd = sum(fedpars.dcomps);
% Element XYZ index
Nicola Vigano
committed
[gv.ind(:, 1), gv.ind(:, 2), gv.ind(:, 3)] = ind2sub(gr_size, 1:nv);
Nicola Vigano
committed
gv.ind = gv.ind';
% Element diffracting power
if (~exist('intvol', 'var') || isempty(intvol))
intvol = ones(gr_size, fedpars.gvtype);
end
if (numel(intvol) ~= nv)
error('gtFedTestLoadData_v2:wrong_argument', ...
'The volume of voxel intensities should have the same size as dmvol''s first 3 coordinates')
end
gv.pow = reshape(intvol, 1, []);
if (strcmp(fedpars.gvtype, 'single'))
gv.pow = single(gv.pow);
Nicola Vigano
committed
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
end
gv.used_ind = find(gv.pow > 0);
% Element actual strain state
gv.d = zeros(nd, nv, fedpars.gvtype);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Apply strain distribution to grain
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
fprintf('\b\b: Done in %g seconds.\n', toc(c))
disp('Active deformation components:')
disp(fedpars.dcomps)
disp('Applying random deformation..')
c = tic();
% Measured (true, real) strain distribution:
if (~exist('dmvol', 'var') || isempty(dmvol))
[gvdm, dmvol, gradok] = gtFedTestGenerateRandomDef(fedpars, nd);
else
[gvdm, dmvol_size] = gtDefDmvol2Gvdm(dmvol);
if (strcmpi(fedpars.defmethod, 'small'))
if (dmvol_size(4) == 3)
mean_gvdm = mean(gvdm, 2);
fprintf('Recentering GVDM and DMVOL to the mean orientation: (%f, %f, %f), from: (%f, %f, %f).\n', ...
grain.R_vector, mean_gvdm)
Nicola Vigano
committed
% gvdm_shift = grain.R_vector' - mean_gvdm;
gvdm_shift = 0 - mean_gvdm;
Nicola Vigano
committed
gvdm = gvdm + gvdm_shift(:, ones(size(gvdm, 2), 1));
dmvol = gtDefGvdm2Dmvol(gvdm, dmvol_size);
end
end
gradok = [];
end
gv.dm = gvdm;
Nicola Vigano
committed
fprintf('\b\b: Done in %g seconds.\nComputing voxel centers..', toc(c))
c = tic();
phantom_voxsize = recgeo(1).voxsize';
vox000sam = grain.center' - (gr_size' / 2) .* phantom_voxsize;
% Elements' positions in the sample volume in mm!
gv.cs = vox000sam(:, nv_ones) + (gv.ind - 0.5) .* phantom_voxsize(:, nv_ones);
% Producing centers and deformation components for projection
if (isfield(fedpars, 'volume_super_sampling') ...
&& (fedpars.volume_super_sampling > 1))
[gv.pcs, gv.d] = compute_oversampling_voxels(gv, dmvol, fedpars, phantom_voxsize);
else
gv.pcs = gv.cs;
gv.d = gv.dm;
end
Nicola Vigano
committed
if (strcmp(fedpars.gvtype, 'single'))
fprintf('\b\b: Done in %g seconds.\nConverting type to single..', toc(c))
c = tic();
fn = fieldnames(gv);
for ii = 1:length(fn)
gv.(fn{ii}) = single(gv.(fn{ii}));
end
end
fprintf('\b\b: Done in %g seconds.\n', toc(c))
if (~all(gradok))
disp('Gradients are higher than the limits for components:')
Nicola Vigano
committed
disp(find(~gradok)')
end
disp('Largest deformation component:')
disp(max(dmvol(:)))
disp('Smallest deformation component:')
disp(min(dmvol(:)))
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Computing allblobs info
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Cleaning grain struct
if (isfield(grain, 'id'))
Nicola Vigano
committed
end
grain = struct('id', grain.id, 'phaseid', grain.phaseid, ...
'center', grain.center, 'R_vector', grain.R_vector);
Nicola Vigano
committed
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
grain = gtCalculateGrain(grain, parameters);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Iinitial blob parameters
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
num_dets = numel(detgeo);
grain.proj(1:num_dets) = struct( ...
'stack', [], 'num_cols', [], 'num_rows', [], 'bl', [], ...
'vol_size_x', [], 'vol_size_y', [], 'vol_size_z', [], 'shift', [], ...
'ondet', [], 'included', [], 'selected', [], 'centerpix', []);
for n = 1:num_dets
% Checking if we should just project all of them, or wether the user
% has something to say abou it.
if (isfield(fedpars, 'detector') && isfield(fedpars.detector(n), 'ondet'))
ondet = fedpars.detector(n).ondet;
included = fedpars.detector(n).included;
selected = fedpars.detector(n).selected;
else
ondet = find(grain.allblobs.detector(n).ondet);
included = (1:numel(ondet))';
selected = true(size(included));
end
ref_inc = ondet(included);
nbl = numel(ref_inc);
is_nearfield = norm(detgeo(n).detrefpos) < 90;
% If it is farfield, we should adjust the voxel size to be 1/4 of the
% pixel size
% if (~is_nearfield)
% voxsize = mean([detgeo(n).pixelsizeu, detgeo(n).pixelsizev]) / 4;
% recgeo(n).voxsize = voxsize([1 1 1]);
% parameters.recgeo(n) = recgeo(n);
% end
fprintf( ['Generating blob data (for detector: %d, blobs on the' ...
' detector: %d):\n'], n, nbl);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Simulate "measured" diffraction patterns
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
fprintf(' - Simulating true ("measured") blob intensities..')
c = tic();
bl = gtDefFwdProjGvdm2UVW(grain, ref_inc, gv, fedpars, parameters, n);
Nicola Vigano
committed
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Assembling the final proj structure
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
fprintf('\b\b (%f seconds)\n - Producing data-structure..\n', toc(c))
c = tic();
stack = arrayfun(@(x){sum(x.intm, 3)}, bl);
stack = cat(3, stack{:});
Nicola Vigano
committed
vol_size = gtGeoSam2Sam(gr_size, recgeo(1), recgeo(n), 1);
vol_size = ceil(vol_size * parameters.fsim.oversizeVol);
if (is_nearfield && size(intvol, 3) == 2) % This handles the 2D case
Nicola Vigano
committed
vol_size(3) = max(vol_size(3), 8);
end
proj = gtFwdSimProjDefinition();
proj.stack = permute(stack, [1 3 2]);
proj.num_cols = size(proj.stack, 3);
proj.num_rows = size(proj.stack, 1);
proj.bl = bl;
proj.vol_size_x = vol_size(2);
proj.vol_size_y = vol_size(1);
proj.vol_size_z = vol_size(3);
proj.centerpix = gtGeoSam2Sam(grain.center, samgeo, recgeo(n), 0);
proj.shift = gtFwdSimComputeVolumeShifts(grain.proj(n), parameters, vol_size);
proj.ondet = ondet;
proj.included = included;
proj.selected = selected;
grain.proj(n) = proj;
Nicola Vigano
committed
fprintf('\b\b(%f seconds)\n - True blob dimensions:\n', toc(c))
fprintf(' %3d) %4d %4d %4d\n', [(1:nbl)', vertcat(bl(:).mbbsize)]')
end
Nicola Vigano
committed
function [gvpcs, gvd] = compute_oversampling_voxels(gv, dmvol, fedpars, voxsize)
nv = size(gv.ind, 2);
nv_ones = ones(nv, 1);
Nicola Vigano
committed
vssampling = fedpars.volume_super_sampling;
Nicola Vigano
committed
Nicola Vigano
committed
num_subvoxels = vssampling ^ 3;
gvpcs = zeros(3, nv, num_subvoxels, fedpars.gvtype);
gvd = zeros(3, nv, num_subvoxels, fedpars.gvtype);
Nicola Vigano
committed
Nicola Vigano
committed
dmvol_size = [size(dmvol, 1), size(dmvol, 2), size(dmvol, 3)]';
dmvol_size = dmvol_size(:, nv_ones);
Nicola Vigano
committed
orig_gvdm = gv.dm;
Nicola Vigano
committed
Nicola Vigano
committed
counter = 0;
corner = (1 - (1 / vssampling)) / 2 .* voxsize;
Nicola Vigano
committed
Nicola Vigano
committed
fprintf('\b\b: ')
Nicola Vigano
committed
Nicola Vigano
committed
for ss_z = linspace(-corner(3), corner(3), vssampling)
for ss_y = linspace(-corner(2), corner(2), vssampling)
for ss_x = linspace(-corner(1), corner(1), vssampling)
Nicola Vigano
committed
Nicola Vigano
committed
num_chars = fprintf('%03d/%03d', counter, num_subvoxels);
Nicola Vigano
committed
Nicola Vigano
committed
offset_subvoxel = [ss_x; ss_y; ss_z];
Nicola Vigano
committed
Nicola Vigano
committed
gvpcs(:, :, counter) = gv.cs + offset_subvoxel(:, nv_ones);
Nicola Vigano
committed
Nicola Vigano
committed
offset_pos = offset_subvoxel ./ voxsize;
offset_pos = gv.ind + offset_pos(:, nv_ones);
Nicola Vigano
committed
Nicola Vigano
committed
res_r_vecs = zeros(3, nv);
res_ints = zeros(3, nv);
Nicola Vigano
committed
Nicola Vigano
committed
for z_r = 0:1
for y_r = 0:1
for x_r = 0:1
rounding = [x_r, y_r, z_r]';
pos = floor(offset_pos) + rounding(:, nv_ones);
int_coeff = 1 - abs(offset_pos - pos);
Nicola Vigano
committed
Nicola Vigano
committed
valid = all(int_coeff > 0, 1) ...
& all(pos > 0, 1) ...
& all(pos <= dmvol_size, 1);
Nicola Vigano
committed
Nicola Vigano
committed
valid_x = pos(1, valid);
valid_y = pos(2, valid);
valid_z = pos(3, valid);
Nicola Vigano
committed
Nicola Vigano
committed
ind_valid_pos = valid_x ...
+ (valid_y - 1) * size(dmvol, 1) ...
+ (valid_z - 1) * size(dmvol, 1) * size(dmvol, 2);
Nicola Vigano
committed
Nicola Vigano
committed
% Filtering the positions that have no
% intensity
valid(valid) = valid(valid) & (gv.pow(ind_valid_pos) > 0);
Nicola Vigano
committed
Nicola Vigano
committed
valid_x = pos(1, valid);
valid_y = pos(2, valid);
valid_z = pos(3, valid);
Nicola Vigano
committed
Nicola Vigano
committed
ind_valid_pos = valid_x ...
+ (valid_y - 1) * size(dmvol, 1) ...
+ (valid_z - 1) * size(dmvol, 1) * size(dmvol, 2);
Nicola Vigano
committed
Nicola Vigano
committed
res_ints(:, valid) = res_ints(:, valid) + int_coeff(:, valid);
Nicola Vigano
committed
Nicola Vigano
committed
res_r_vecs(:, valid) = res_r_vecs(:, valid) ...
+ int_coeff(:, valid) .* orig_gvdm(:, ind_valid_pos);
Nicola Vigano
committed
end
end
Nicola Vigano
committed
end
Nicola Vigano
committed
Nicola Vigano
committed
renorm_res_ints = res_ints + (res_ints == 0);
gvd(:, :, counter) = res_r_vecs ./ renorm_res_ints;
Nicola Vigano
committed
Nicola Vigano
committed
counter = counter + 1;
Nicola Vigano
committed
Nicola Vigano
committed
fprintf(repmat('\b', [1 num_chars]));
Nicola Vigano
committed
end
end
end
end