Newer
Older
Laura Nervo
committed
function out = gtForwardSimulate_v2(first, last, workingdirectory, phaseID, varargin)
% GTFORWARDSIMULATE_V2 Finds missing diffraction spots and updates grain structure
Nicola Vigano
committed
% out = gtForwardSimulate_v2(first, last, workingdirectory, [phaseID], varargin)
% ------------------------------------------------------------------------------
Nicola Vigano
committed
% first = <int> first grainid
% last = <int> last grainid
% workingdirectory = <string> working directory
% phaseID = <int> phase ID
% varargin = parameters.fsim plus some additional
% options as in gtAppFsimExtraPars():
Nicola Vigano
committed
% OPTIONAL INPUT (p/v pairs):
% updateSample = <logical> true/false to update sample.mat and
% spot2grain.mat {true}
% updateDBtables = <logical> true/false to update DB table with
% 'grainID', 'phaseID', 'flag' {false}
% area_factor = <double> Weight for area criterion {1}
% position_factor = <double> Weight for UV position criterion {1}
% image_factor = <double> Weight for image criterion {1}
% int_factor = <double> Weight for intensity criterion {0}
%
% OPTIONAL INPUT for twin variants calculation (p/v pairs):
% variants = <logical> Use fsim relative to twin variants
% {false}
% plot_variants = <logical> Plot the variants orientation wrt to
% the parent orientation as XYZ crystal
% axes {false}
% num_variant = <double> Variant number to forward simulate
% {[]}
% twin_angle = <double> twin angle {[]}
% twin_axis = <double> twin axis {[]}
% twin_center = <double> alternative center for the twin (mm)
% or the twinID if available from the
% same indexed dataset {[]}
% twin_grain = <struct> twin grain structure for common spot
% properties and full image {[]}
Nicola Vigano
committed
% out = <struct> updated grain structure. Fields:
% .bl = <struct N> stack of normalized difblobs, along with metadata
% .proj.geom = <double> input for grain reconstruction
% / forward projection using ROI
% (hsize, vsize) (Nx12)
% .proj.geom_full = <double> input for grain reconstruction
% / forward projection (full images) (Nx12)
% .proj.geom_abs = <double> input for grain reconstruction
% / forward projection of extinction spots (Nx12)
% .proj.difstack = <double> stack of normalized difspots (XxYxN)
% .ondet = <double> indices of those spots (from the list in allblobs)
% which are expected on the detector
% .uvw = <double> spot positions on the detector (Nx3)
% .hklsp = <double> signed hk(i)l of reflection (Nx3(4))
% .hkl = <double> hk(i)l family for each reflection (Nx3(4))
% .flag = <int> status flag indicating result of forward simulation
% .allblobs = <struct> forward simulation output produced by gtIndexFwdSimGrains
% .used_fam = <double> List of unique HKL families used
% (theoretical)
% .used_famsp = <double> List of all the HKL families used
% (theoretical)
Nicola Vigano
committed
% We will classify spots with a flag [1...6]:
% - 1 : No intensity at expected spot position
% - 2 : Found intensity in FULL images at predicted position
% - 3 : Found segmented difspot at expected position - but position
% / size do not match strict criteria
% - 4 : Found segmented difspot in database matching the strict
% search criteria - we will use theoretically predicted
% angles for reconstruction
% - 5 : Difspot is part of a pair identified by INDEXTER - use
% Friedelpair information for reconstruction
% - 6 : Conflict difspot (if existing)
Nicola Vigano
committed
% Version 010 21-07-2014 by LNervo
% Extracted the ASTRA geometry and the gtFwdSimFindCandidates routines
% Version 009 14-05-2014 by LNervo
% Added check of used hkl families
%
Nicola Vigano
committed
% Version 008 25-04-2014 by LNervo
% Adapted to use twin forward simulation
%
% Version 007 Beginning-2014 by LNervo
% Modulized, simplified, added application parameters to update
% sample.mat and DB difspot table
%
% Version 006 18-12-2013 by LNervo
% Moduling a bit more...
Laura Nervo
committed
%
Nicola Vigano
committed
% Version 005 05/03/2013 by Nicola Vigano (nicola.vigano@esrf.fr)
% Re-structured completely, to be more clear and easy to debug.
Nicola Vigano
committed
%
% Version 004 21/06/2012 by AKing
% Trivial change to make segbb zeros(1, 6)
%
% Version 003 14-06-2012 by LNervo
% Use gtFsimDefaultParameters
Nicola Vigano
committed
if (isdeployed)
Nicola Vigano
committed
global GT_DB %#ok<NUSED,TLEV>
global GT_MATLAB_HOME %#ok<NUSED,TLEV>
load('workspaceGlobal.mat');
end
Laura Nervo
committed
cd(workingdirectory);
gtDBConnect();
Nicola Vigano
committed
parameters = gtLoadParameters();
labgeo = parameters.labgeo;
samgeo = parameters.samgeo;
recgeo = parameters.recgeo;
Nicola Vigano
committed
if (~isfield(parameters.seg, 'writehdf5') || ~parameters.seg.writehdf5)
error('gtForwardSimulate_v2:wrong_parameter', ...
[ 'Segmentation has to write HDF5 blobs in order for ' ...
'ForwardSimulation to work properly. You can now create them ' ...
'using some of the conversion functions like "gtConvertRawImages2Blobs"' ])
end
if (~isfield(parameters.fsim, 'save_grain'))
Nicola Vigano
committed
parameters.fsim.save_grain = true;
end
Nicola Vigano
committed
if (~exist('phaseID', 'var') || isempty(phaseID))
phaseID = 1;
end
Nicola Vigano
committed
if (isdeployed)
Laura Nervo
committed
first = str2double(first);
last = str2double(last);
Nicola Vigano
committed
parameters.fsim.display_figure = false;
Nicola Vigano
committed
elseif (~isempty(varargin))
% in interactive mode we can modify parameters
Nicola Vigano
committed
[parameters.fsim, rej_pars] = parse_pv_pairs(parameters.fsim, varargin);
end
Nicola Vigano
committed
if (~exist('rej_pars', 'var'))
Nicola Vigano
committed
rej_pars = {};
Nicola Vigano
committed
indexgrainModel = fullfile(parameters.acq.dir, '4_grains', 'phase_%02d', 'index.mat');
Wolfgang Ludwig
committed
fprintf('\nLoading indexing results...\n');
grain = [];
Nicola Vigano
committed
load(sprintf(indexgrainModel, phaseID), 'grain');
Nicola Vigano
committed
totGrains = length(grain);
Nicola Vigano
committed
if (last > totGrains)
warning('gtForwardSimulate_v2:wrong_parameter', ...
'Last was bigger than the total number of grains, setting it to max')
last = totGrains;
end
difspotfile = fullfile(parameters.acq.dir, '2_difspot', '00000', 'difspot00001.edf');
Nicola Vigano
committed
if (exist(difspotfile, 'file'))
info = edf_info(difspotfile);
else
info = [];
end
Laura Nervo
committed
%%% this section should be replaced with a function dealing with different
% versions of parameters names: fed, v1, v2...
Nicola Vigano
committed
% !!! using a mean pixel size is uncertain; ideally fwd simulation should
% use mm-s
Nicola Vigano
committed
% detector reference position in pixels
detrefpos_p = gtGeoLab2Sam(labgeo.detrefpos, eye(3), labgeo, recgeo, true);
Nicola Vigano
committed
fprintf('\nLoading reflections from database..');
Nicola Vigano
committed
% Initialization of spot table and info about pairs
segmentedSpots = gtDBLoadTable([parameters.acq.name 'difspot'], 'difspotID');
pairsTable = gtDBLoadTable(parameters.acq.pair_tablename, 'pairID');
Nicola Vigano
committed
fprintf('(Done).\n')
Wolfgang Ludwig
committed
Nicola Vigano
committed
difspot_num = numel(segmentedSpots.difspotID); % number of difspots in database
Wolfgang Ludwig
committed
spot2grain = cell(difspot_num, 1); % cell array linking difspots with grainids
spot2phase = cell(difspot_num, 1);
Nicola Vigano
committed
filetable = [parameters.acq.name '_filetable'];
filename = fullfile(parameters.acq.dir, '4_grains', 'spot2grain.mat');
Wolfgang Ludwig
committed
spotTable = GtMergeTable(filetable, filename, {'spot2grain', 'spot2phase'});
Nicola Vigano
committed
samplefile = fullfile(parameters.acq.dir, '4_grains', 'sample.mat');
sample = GtSample.loadFromLockedFile(filetable, samplefile);
Wolfgang Ludwig
committed
% initialise sample structure
Nicola Vigano
committed
phase = GtPhase(parameters.cryst(phaseID).name, totGrains);
Wolfgang Ludwig
committed
sample.phases{phaseID} = phase;
Nicola Vigano
committed
% initialize output
out = [];
if (parameters.fsim.verbose)
Nicola Vigano
committed
disp('FwdSim parameters:')
Nicola Vigano
committed
print_structure(parameters.fsim, 'parameters.fsim', false, true)
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Wolfgang Ludwig
committed
for n = first : last
Nicola Vigano
committed
fprintf('\nRunning forward simulation for grain %d:\n', n);
fprintf(' - Computing grain properties..');
gr = grain{n}; % output from INDEXTER
Laura Nervo
committed
%%% Predict spot positions
Nicola Vigano
committed
gr = gtCalculateGrain(gr, parameters);
Nicola Vigano
committed
uvw = gr.allblobs.uvw;
Nicola Vigano
committed
%%% Get:
% - average difspot X and Y sizes for the current spots in the grain
% - theshold values used during the database search
% - offset in possible lateral grain orientation
% - diffstack Vertical and Horizontal sizes
Nicola Vigano
committed
spotsCommProps = gtFwdSimGetDiffspotsCommonProperties(gr, detrefpos_p, parameters);
Nicola Vigano
committed
%%% Get the indices of all spots which fully intersect the active
% region of the detector
Nicola Vigano
committed
onDet = gtFwdSimFindSpotsOnDetector(spotsCommProps, uvw, parameters);
fprintf(' (Done).\n - Producing blob masks..')
proj_bls = predict_spot_masks_from_indexed( ...
gr, grain, segmentedSpots, spotsCommProps, onDet, parameters);
fprintf(' (Done).\n - Preallocating structs..')
Nicola Vigano
committed
Nicola Vigano
committed
% number of exspected diffraction spots
numspots = numel(onDet);
Nicola Vigano
committed
flag = ones(numspots, 1); % see above
% stack of zero padded diffraction spots (projections used for 3D reconstruction)
Nicola Vigano
committed
bl(1:numspots) = struct( ...
'intm', [], ... % The normalized blob
'mask', [], ... % The segmentation mask
'bbuim', [], ... % Image BB on U
'bbvim', [], ... % Image BB on V
'bbwim', [], ... % Image BB on W <- Not strictly w
'bbsize', [], ... % Image BoundingBox (includes margins)
Nicola Vigano
committed
'mbbsize', [], ... % Real (Measured) Blob Bounding Box
Nicola Vigano
committed
'intensity', [] ); % Blob original intensity
Nicola Vigano
committed
checkSpots = struct('info', cell(numspots, 1));
Nicola Vigano
committed
bb = zeros(numspots, 4); % difspot BoundingBox from database
Nicola Vigano
committed
cent = zeros(numspots, 1); % centroid distance from database added 06-02-2014 LNervo
Nicola Vigano
committed
spotid = zeros(numspots, 1); % Mysql difspottable difspotID
Nicola Vigano
committed
check = false(numspots, 2);
intensity = zeros(numspots, 1); % Integrated blob intensity
Nicola Vigano
committed
avg_pixel_int = zeros(numspots, 1); % Average pixel intensity in blob
likelihood = zeros(numspots, 1); % Integrated blob intensity
cands = struct(...
'id', cell(numspots, 1), ...
'likelihood_tot', cell(numspots, 1), ...
'likelihood_proj_mask', cell(numspots, 1), ...
'likelihood_dev_uv', cell(numspots, 1), ...
'likelihood_dev_w', cell(numspots, 1) );
Nicola Vigano
committed
% Diffraction vectors directions
diff_beam_dirs = zeros(numspots, 3);
Nicola Vigano
committed
U = zeros(numspots, 1); % CoM u positions of difspots from difspottable
V = zeros(numspots, 1); % CoM v positions of difspots from difspottable
W = zeros(numspots, 1); % CoM w positions of difspots from difspottable
Nicola Vigano
committed
if (parameters.fsim.assemble_figure)
full = zeros(parameters.acq.ydet, parameters.acq.xdet);
else
full = [];
end
Nicola Vigano
committed
tempIsSpotA = false(numspots, 1);
Nicola Vigano
committed
fprintf(' (Done).\n - Matching reflections and spots..');
Nicola Vigano
committed
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Nicola Vigano
committed
%%% Forward simulation:
% We try to match the reflections with the segmented spots, so we
% examine all hklsp and search corresponding spots / intensity on the
% detector..
Nicola Vigano
committed
%%% But also build the diffraction blob stack
Nicola Vigano
committed
for ii = 1:numspots
Nicola Vigano
committed
% Producing predicted spot's properties
spot_props = predict_spot_properties(spotsCommProps, proj_bls(ii), gr.stat, parameters);
Wolfgang Ludwig
committed
% Look for difspots appying loose search criteria - is there any intensity at the predicted spot
% position ? Choose the one which is closest to the expected size
Nicola Vigano
committed
[candidateIDs, spotsCands] = gtFwdSimFindCandidates(spot_props, uvw(onDet(ii), :), segmentedSpots);
Nicola Vigano
committed
if (isempty(candidateIDs))
Nicola Vigano
committed
% NO CANDIDATES FOUND:
% segmentation / overlap / intensity / ... problem ?
Nicola Vigano
committed
if (spotsCands.found_intensity)
% A bigger spot was found in the region.. it may be an
% overlap
flag(ii) = 2;
end
Nicola Vigano
committed
Nicola Vigano
committed
% If requested, we will check into the raw images later.
continue;
Nicola Vigano
committed
end
Nicola Vigano
committed
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
bls = gtFwdSimBuildDifstackBlobs(candidateIDs, [], parameters, ...
spotsCommProps.stackHSize, spotsCommProps.stackVSize);
proj_bl = proj_bls(ii * ones(numel(bls), 1));
% Computing spot area/shape deviation/likelihood
ls_pb = compute_proj_bbs_partial_likelihoods(bls, proj_bl);
refl_indx = onDet(ii) * ones(numel(bls), 1);
% Computing UV deviation/likelihood
th_uv = uvw(refl_indx, 1:2);
blobs_uv = [ spotsCands.CentroidX, spotsCands.CentroidY ];
ls_uv = compute_uv_partial_likelihoods(blobs_uv, th_uv, proj_bl);
% Computing W deviation/likelihood
th_w = gr.allblobs.omega(refl_indx);
blob_w = spotsCands.CentroidImage * gtGetOmegaStepDeg(parameters);
ls_w = compute_w_partial_likelihoods(blob_w, th_w);
% in case there are several candidates, take the one with best
% likelihood in terms of: shape, UV position, and W position.
ls = ls_pb .* ls_uv .* ls_w;
[~, cand_inc_index] = max(ls);
cands(ii).id = candidateIDs';
cands(ii).likelihood_tot = ls';
cands(ii).likelihood_proj_mask = ls_pb';
cands(ii).likelihood_dev_uv = ls_uv';
cands(ii).likelihood_dev_w = ls_w';
spotid(ii) = candidateIDs(cand_inc_index);
bl(ii) = bls(cand_inc_index); %#ok<AGROW>
U(ii) = spotsCands.CentroidX(cand_inc_index);
V(ii) = spotsCands.CentroidY(cand_inc_index);
W(ii) = spotsCands.CentroidImage(cand_inc_index) * gtGetOmegaStepDeg(parameters);
bb(ii, :) = [...
spotsCands.BoundingBoxXorigin(cand_inc_index), ...
spotsCands.BoundingBoxYorigin(cand_inc_index), ...
spotsCands.BoundingBoxXsize(cand_inc_index), ...
spotsCands.BoundingBoxYsize(cand_inc_index) ];
% The following should be beter than the previous, but it seems to
% geneterate problems
Nicola Vigano
committed
% bb(ii, :) = bls(cand_inc_index).mbbsize([1 2 4 5]);
Nicola Vigano
committed
intensity(ii) = bls(cand_inc_index).intensity;
avg_pixel_int(ii) = intensity(ii) / sum(bls(cand_inc_index).mask(:));
likelihood(ii) = ls(cand_inc_index);
% Found a segmented difspot at expected position:
% we will check if it does match strict criteria
Nicola Vigano
committed
uv_ok = cent(ii, :) <= spotsCommProps.Offset;
bb_ok = all( [...
Nicola Vigano
committed
between(bb(ii, 3), spotsCommProps.XsizeMin, spotsCommProps.XsizeMax), ...
between(bb(ii, 4), spotsCommProps.YsizeMin, spotsCommProps.YsizeMax) ] );
Nicola Vigano
committed
check(ii, :) = [uv_ok, bb_ok];
Nicola Vigano
committed
Nicola Vigano
committed
isSpotA = ~isempty(find(gr.difspotidA == spotid(ii), 1));
isSpotB = ~isempty(find(gr.difspotidB == spotid(ii), 1));
Nicola Vigano
committed
if (isSpotA || isSpotB)
% This spot is part of a pair and has been used by INDEXTER
flag(ii) = 5;
tempIsSpotA(ii) = isSpotA;
Nicola Vigano
committed
elseif all(check(ii, :))
Nicola Vigano
committed
flag(ii) = 4;
else
flag(ii) = 3;
end
end
Nicola Vigano
committed
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Nicola Vigano
committed
%%% Re-check flag == 1, to see if there's intensity at the predicted
Nicola Vigano
committed
% position, if requested.
if (parameters.fsim.check_spot)
Nicola Vigano
committed
fprintf(' (Done).\n - Checking spots in Raw images..');
Nicola Vigano
committed
toBeChecked = find(flag == 1);
for ii = reshape(toBeChecked, [1 numel(toBeChecked)]);
Nicola Vigano
committed
[found_intensity, spotInfo] = gtFwdSimCheckSpotInRawImages(...
Nicola Vigano
committed
uvw(onDet(ii), :), spotsCommProps, parameters);
Nicola Vigano
committed
if (found_intensity)
% Found intensity in FULL images at predicted position
flag(ii) = 2;
Nicola Vigano
committed
if (parameters.fsim.assemble_figure)
full = gtPlaceSubImage2(spotInfo.spot, full, spotInfo.bb(1), spotInfo.bb(2), 'summed');
end
Nicola Vigano
committed
checkSpots(ii).info = spotInfo;
Nicola Vigano
committed
end
Nicola Vigano
committed
end
Nicola Vigano
committed
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Nicola Vigano
committed
% Reflections that have been matched to segmented spots
Nicola Vigano
committed
included = find(flag >= 3);
Nicola Vigano
committed
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Nicola Vigano
committed
%%% We now build the diffraction stack
Nicola Vigano
committed
fprintf(' (Done).\n - Building difstack..');
Nicola Vigano
committed
difstack = gtFwdSimBuildDifstackSpots(spotid, included, parameters, ...
Nicola Vigano
committed
spotsCommProps.stackHSize, spotsCommProps.stackVSize, ...
spotsCommProps.Xsize, spotsCommProps.Ysize, ...
bb, info);
Nicola Vigano
committed
if (parameters.fsim.assemble_figure)
% no padded spots
Nicola Vigano
committed
full = sfBuildFull(spotid(reshape(included, 1, [])), ...
parameters, spotsCommProps, bb(reshape(included, 1, []), :));
Nicola Vigano
committed
end
Nicola Vigano
committed
fprintf(' (Done).\n - Building geometry..');
Nicola Vigano
committed
%%% Diffraction geometry
Nicola Vigano
committed
for ii = reshape(included, 1, [])
% we found a segmented spot - can use the theoretically
% predicted direction or apparent direction (based on CoM of
% grain and spot) for backprojection
% theoretically prediceted omega angle
Nicola Vigano
committed
if (flag(ii) == 5)
Nicola Vigano
committed
% If available, we want to use the angles as determined from
% the Friedel pairs - interrogate spotpair table
%
% diff_beam_dirs: direction of diffracted beam used in ASTRA
Nicola Vigano
committed
[diff_beam_dirs(ii, :), W(ii)] = sfGetFriedelPair(pairsTable, spotid(ii), tempIsSpotA(ii));
Nicola Vigano
committed
elseif (parameters.fsim.use_th)
currentReflection = onDet(ii);
% use theoretically predited directions (default)
W(ii) = gr.allblobs.omega(currentReflection);
% theoretically predicted beam direction (in sample
% coordinate system)
diff_beam_dirs(ii, :) = gr.allblobs.dvecsam(currentReflection, :);
Nicola Vigano
committed
else
Nicola Vigano
committed
% use experimentally determined omega angles
W(ii) = segmentedSpots.CentroidImage(spotid(ii)) * gtGetOmegaStepDeg(parameters);
% projection direction as inferred from grain / spot center
% positions
diff_beam_dirs(ii, :) = gtGeoDiffVecInSample([U(ii), V(ii)], W(ii), gr.center, labgeo, samgeo);
Nicola Vigano
committed
end
Nicola Vigano
committed
end
Nicola Vigano
committed
[selected, goodness] = gtFwdSimSelectSpots(likelihood, intensity, ...
avg_pixel_int, flag, included, parameters);
Nicola Vigano
committed
%%% We now Build ASTRA's geometry
proj = gtFwdSimBuildProjGeometry(...
diff_beam_dirs(included, :), gr.center, W(included), ...
bb(included, :), parameters, ...
spotsCommProps.stackHSize, spotsCommProps.stackVSize, ...
selected);
Nicola Vigano
committed
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Laura Nervo
committed
%%% Now fill in the information for the output
Wolfgang Ludwig
committed
% remove reflections for which no segmented spot has been found
out.id = gr.id;
out.phaseid = phaseID;
out.R_vector = gr.R_vector;
out.center = gr.center;
Nicola Vigano
committed
out.selected = selected; % vector of logicals with pre-selected spots active
out.included = included; % This is needed by Orientation Reconstruction
Nicola Vigano
committed
out.ondet = onDet;
Nicola Vigano
committed
Nicola Vigano
committed
out.flag = flag;
out.pairid = gr.pairid;
out.spotid = spotid;
Nicola Vigano
committed
% only included spots info
Nicola Vigano
committed
out.cands = cands(included);
out.likelihood = likelihood(included);
out.difspotID = spotid(included);
Nicola Vigano
committed
out.uv_exp = [U(included), V(included)];
out.om_exp = W(included);
out.bb_exp = bb(included, :);
out.intensity = intensity(included);
Nicola Vigano
committed
Nicola Vigano
committed
% save full image
out.full = full;
Nicola Vigano
committed
Nicola Vigano
committed
% check spot info
out.checkSpots = checkSpots;
% diffraction geometry
out.proj = proj;
% blob/spot stacks
Nicola Vigano
committed
out.proj.bl = bl(included);
Nicola Vigano
committed
out.proj.stack = difstack(:, included, :);
% recontruction and assemble stuff
out.seg = [];
out.vol = [];
out.segbb = zeros(1, 6);
out.threshold = 0;
Nicola Vigano
committed
found_reflections = length(find(flag > 1));
Nicola Vigano
committed
out.completeness = found_reflections / numspots;
Nicola Vigano
committed
out.completeness_incl = length(find(flag > 3)) / numspots;
out.goodness = goodness;
out.goodness_sel = mean(out.likelihood(selected));
out.confidence = out.goodness * out.completeness_incl;
Nicola Vigano
committed
if (parameters.fsim.save_grain)
Nicola Vigano
committed
fprintf(' (Done).\n - Saving ouput..');
Nicola Vigano
committed
grain_file_name = fullfile(parameters.acq.dir, '4_grains', 'phase_%02d', 'grain_%04d.mat');
save(sprintf(grain_file_name, phaseID, gr.id), '-struct', 'out');
Nicola Vigano
committed
end
Nicola Vigano
committed
if (parameters.fsim.display_figure)
fprintf(' (Done).\n - Displaying figure..');
Nicola Vigano
committed
Nicola Vigano
committed
displayShowFsim(phaseID, out, rej_pars{:})
end
Nicola Vigano
committed
fprintf(' (Done).\n\n');
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Now update spotTables and sample
Nicola Vigano
committed
spot2grain(out.difspotID) = {n};
spot2phase(out.difspotID) = {phaseID};
Wolfgang Ludwig
committed
sample.phases{phaseID}.setR_vector(n, gr.R_vector);
Nicola Vigano
committed
sample.phases{phaseID}.setCompleteness(n, out.completeness);
Nicola Vigano
committed
sample.phases{phaseID}.setCenter(n, out.center); % center in pixels
Nicola Vigano
committed
if (isempty(out.selected))
warning('gtForwardSimulate_v2:bad_value', ...
'No spot was selected! This will make reconstruction impossible')
elseif (numel(out.selected) < 10)
warning('gtForwardSimulate_v2:bad_value', ...
'Too few selected spots! This will give a very bad reconstruction')
end
Nicola Vigano
committed
if (out.goodness < 0.25)
warning('gtForwardSimulate_v2:very_low_goodness', ...
[ 'Very low goodness (included %f, selected %f) indicates a' ...
' probably poor quality of grain reconstruction' ], ...
out.goodness, out.goodness_sel)
elseif (out.goodness < 0.5)
warning('gtForwardSimulate_v2:low_goodness', ...
[ 'Low goodness (included %f, selected %f) indicates a' ...
' possibly poor quality of grain reconstruction' ], ...
out.goodness, out.goodness_sel)
end
Nicola Vigano
committed
if (~parameters.fsim.check_spot)
Nicola Vigano
committed
fprintf(['Completeness estimates may be too pessimistic - activate ' ...
'option ''check_spot'' for more reliable results\n'])
end
fprintf('\n Grain number %d:\n', n);
newspots = length(find(flag == 4));
fprintf(['Forward simulation found intensity at %d out of %d expected ' ...
'spot positions \n'], found_reflections, numspots);
fprintf('Completeness estimate: %f\n', out.completeness);
Nicola Vigano
committed
fprintf('Goodness estimate: included %f, selected %f\n', ...
out.goodness, out.goodness_sel);
Nicola Vigano
committed
fprintf('%d spots will be used for reconstruction\n', length(out.selected));
fprintf(['%d new spots have been detected in addition to the %d ' ...
'spotpairs identified by INDEXTER\n'], newspots, gr.nof_pairs);
Nicola Vigano
committed
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Nicola Vigano
committed
if (parameters.fsim.save_grain)
Nicola Vigano
committed
% update difspot table in the DB
% keep list of difspots
Nicola Vigano
committed
spotID = out.spotid;
spotID(out.spotid == 0) = [];
flags = out.flag;
flags(out.spotid == 0) = [];
Nicola Vigano
committed
gtDBFillUpdateColumn([parameters.acq.name 'difspot'], ...
'grainID', 'int', 'integral', 'difspotID', {out.difspotID}, n)
gtDBFillUpdateColumn([parameters.acq.name 'difspot'], ...
'phaseID', 'int', 'integral', 'difspotID', {out.difspotID}, phaseID)
gtDBFillUpdateColumn([parameters.acq.name 'difspot'], ...
Nicola Vigano
committed
'flag', 'int', 'integral', 'difspotID', {spotID}, {flags});
Nicola Vigano
committed
end
Wolfgang Ludwig
committed
end
Nicola Vigano
committed
if (parameters.fsim.save_grain)
% fill spotTables
spotTable.fillTable(spot2grain, 'spot2grain');
spotTable.fillTable(spot2phase, 'spot2phase');
% save sample.mat
sample.mergeToFile(filetable, samplefile, 'sample');
end
Nicola Vigano
committed
end
Nicola Vigano
committed
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% sub-functions
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Nicola Vigano
committed
Nicola Vigano
committed
function full = sfBuildFull(spotid, parameters, spotsCommProps, bb)
% full = sfBuildFull(spotid, parameters, spotsCommProps, bb)
%
% spotid : spotid from grain
% parameters : parameters.mat
% spotsCommProps : spots common properties
% bb : bounding boxes from DB
Nicola Vigano
committed
Nicola Vigano
committed
full = zeros(parameters.acq.ydet, parameters.acq.xdet);
Nicola Vigano
committed
Nicola Vigano
committed
for ii = 1:numel(spotid)
[spot, ~] = gtFwdSimBuildSpot(spotid(ii), parameters, spotsCommProps.Xsize, spotsCommProps.Ysize, bb(ii, :));
Nicola Vigano
committed
Nicola Vigano
committed
full = gtPlaceSubImage2(spot, full, bb(ii, 1), bb(ii, 2), 'summed');
Nicola Vigano
committed
end
end
Nicola Vigano
committed
function [diff_beam_dir, omega] = sfGetFriedelPair(pairsTable, spotID, isSpotA)
% [diff_beam_dirs, omega] = sfGetFriedelPair(pairsTable, spotID, isSpotA)
Nicola Vigano
committed
if (isSpotA)
Nicola Vigano
committed
idx = find(pairsTable.difAID == spotID);
omega = pairsTable.omega(idx);
diff_beam_dir = [pairsTable.ldirX(idx), pairsTable.ldirY(idx), pairsTable.ldirZ(idx)];
Nicola Vigano
committed
else
Nicola Vigano
committed
idx = find(pairsTable.difBID == spotID);
omega = pairsTable.omegaB(idx);
Nicola Vigano
committed
% in this case we have to reverse the line direction
Nicola Vigano
committed
diff_beam_dir = -[pairsTable.ldirX(idx), pairsTable.ldirY(idx), pairsTable.ldirZ(idx)];
Nicola Vigano
committed
end
end
Nicola Vigano
committed
function displayShowFsim(phaseID, grain, varargin)
% displayShowFsim(phaseID, grain, varargin)
Nicola Vigano
committed
Nicola Vigano
committed
if isempty(varargin)
[vars_pars, vars_list] = gtAppFsimDefaultPars();
ind = findValueIntoCell(fieldnames(vars_pars), {'fsimtype', 'f_title'});
vars_list(ind(:, 1), 4) = {2};
Nicola Vigano
committed
Nicola Vigano
committed
vars_pars = gtModifyStructure(vars_pars, vars_list, 1, 'Options for displaying the Forward Sim:');
varargin = struct2pv(vars_pars);
Nicola Vigano
committed
gtShowFsim(grain, phaseID, varargin{:});
Nicola Vigano
committed
end
Nicola Vigano
committed
function proj_bls = predict_spot_masks_from_indexed(gr, grain_INDX, ...
segmentedSpots, spotsCommProps, onDet, parameters)
% First argument: included_INDXTR, might be needed in the future for
% some reason...
[~, difspotID_INDXTR] = gtFwdSimGetIndexterReflections(gr, grain_INDX{gr.id}, segmentedSpots);
% Producing blobs' boundingboxes (as by dilated segmentation info)
bls_INDXTR = gtFwdSimBuildDifstackBlobs(difspotID_INDXTR, [], ...
parameters, spotsCommProps.stackHSize, spotsCommProps.stackVSize);
% INDEXTER Data
Nicola Vigano
committed
BBs = cat(1, bls_INDXTR(:).mbbsize);
Nicola Vigano
committed
BBs = BBs(:, [1 2 4 5]);
Ws = segmentedSpots.CentroidImage(difspotID_INDXTR) .* gtGetOmegaStepDeg(parameters);
proj_bls = gtFwdSimPredictProjectedGrainBBox(gr, BBs, Ws, onDet, parameters);
% Producing original blobs' boundingboxes (as by original segmentation
% info)
BBs = [...
segmentedSpots.BoundingBoxXorigin(difspotID_INDXTR), ...
segmentedSpots.BoundingBoxYorigin(difspotID_INDXTR), ...
segmentedSpots.BoundingBoxXsize(difspotID_INDXTR), ...
segmentedSpots.BoundingBoxYsize(difspotID_INDXTR) ];
proj_bls_original = gtFwdSimPredictProjectedGrainBBox(gr, BBs, Ws, onDet, parameters);
for ii_b = 1:numel(proj_bls)
Nicola Vigano
committed
proj_bls(ii_b).mbbsize = proj_bls_original(ii_b).bbsize;
Nicola Vigano
committed
end
end
function spot_props = predict_spot_properties(spotsCommProps, proj_bl, gr_stats, parameters)
bb_size_factor = parameters.fsim.bbsize_factor;
% Minimums could be wrong by up to 2 pixels (roundings)
Nicola Vigano
committed
spot_props.XsizeMin = max(5, proj_bl.mbbsize(1) - bb_size_factor * gr_stats.bbxsstd - 2);
spot_props.YsizeMin = max(5, proj_bl.mbbsize(2) - bb_size_factor * gr_stats.bbysstd - 2);
Nicola Vigano
committed
% Allowing for matching spots, even if the convex shape of the grain
% computed from indexter's selection had a limited angle view on the
% grain volume
spot_props.XsizeMin = min(spot_props.XsizeMin, spotsCommProps.XsizeMin);
spot_props.YsizeMin = min(spot_props.YsizeMin, spotsCommProps.YsizeMin);
Nicola Vigano
committed
spot_props.XsizeMax = proj_bl.mbbsize(1) + bb_size_factor * gr_stats.bbxsstd;
spot_props.YsizeMax = proj_bl.mbbsize(2) + bb_size_factor * gr_stats.bbysstd;
Nicola Vigano
committed
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
spot_props.thr_max_offset = spotsCommProps.thr_max_offset;
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Likelihood computation
function ls = compute_uv_partial_likelihoods(blob_uv, th_uv, proj_bls)
proj_bbox(:, [1 3]) = cat(1, proj_bls(:).bbuim);
proj_bbox(:, [2 4]) = cat(1, proj_bls(:).bbvim);
blob_expected_sizes = proj_bbox(:, [3 4]) - proj_bbox(:, [1 2]) + 1;
ls = (th_uv - blob_uv) ./ max(blob_expected_sizes ./ 10, 10);
ls = exp(- (ls .^ 2) );
ls = ls(:, 1) .* ls(:, 2);
end
function ls = compute_w_partial_likelihoods(blob_w, th_w)
ls = 2 .* (th_w - blob_w);
ls = exp(- (ls .^ 2));
end
function ls = compute_proj_bbs_partial_likelihoods(bls, proj_bls)
bls_bboxes(:, [1, 3]) = cat(1, bls(:).bbuim);
bls_bboxes(:, [2, 4]) = cat(1, bls(:).bbvim);
proj_bls_bboxes(:, [1, 3]) = cat(1, proj_bls(:).bbuim);
proj_bls_bboxes(:, [2, 4]) = cat(1, proj_bls(:).bbvim);
cont_bbxes = [ ...
min(bls_bboxes(:, 1:2), proj_bls_bboxes(:, 1:2)), ...
max(bls_bboxes(:, 3:4), proj_bls_bboxes(:, 3:4)) ...
];
cont_bbxes = [cont_bbxes(:, 1:2), (cont_bbxes(:, 3:4) - cont_bbxes(:, 1:2) + 1)];
bls_shifts = bls_bboxes(:, 1:2) - cont_bbxes(:, 1:2);
bls_shifts(:, 3) = 0;
proj_bls_shifts = proj_bls_bboxes(:, 1:2) - cont_bbxes(:, 1:2);
proj_bls_shifts(:, 3) = 0;
num_bls = numel(proj_bls);
mismatch_more = zeros(num_bls, 1);
mismatch_less = zeros(num_bls, 1);
proj_count = zeros(num_bls, 1);
for ii = 1:num_bls
cont_size = cont_bbxes(ii, 3:4);
proj_count(ii) = sum(proj_bls(ii).mask(:));
bl_mask = bls(ii).mask;
bl_mask = sum(bl_mask, 3);
bl_mask = bl_mask > 0;
proj_bl_mask = logical(proj_bls(ii).mask);
bl_mask = gtPlaceSubVolume( ...
zeros(cont_size, 'uint8'), bl_mask, bls_shifts(ii, :));
proj_bl_mask = gtPlaceSubVolume( ...
zeros(cont_size, 'uint8'), proj_bl_mask, proj_bls_shifts(ii, :));
overlap = bl_mask & proj_bl_mask;
bl_mask(overlap) = 0;
proj_bl_mask(overlap) = 0;
mismatch_more(ii) = sum(bl_mask(:));
mismatch_less(ii) = sum(proj_bl_mask(:));
end
% 3 and 2 are temporary
ls = (1 .* mismatch_more + 1 .* mismatch_less) ./ proj_count;
ls = exp(- (ls .^ 2));
end