From a0af4c2e10bce17484005c2600113ff8cb81dc8d Mon Sep 17 00:00:00 2001 From: Nicola Vigano <nicola.vigano@esrf.fr> Date: Thu, 17 Mar 2016 14:55:28 +0100 Subject: [PATCH] Grain-ODF: added another solver that also can use the uvw shape functions Signed-off-by: Nicola Vigano <nicola.vigano@esrf.fr> --- zUtil_Deformation/GtGrainODFuvwPatchSolver.m | 140 ++++++--------- zUtil_Deformation/GtGrainODFuvwSfSolver.m | 174 +++++++++++++++++++ zUtil_Deformation/GtGrainODFwSolver.m | 2 +- 3 files changed, 232 insertions(+), 84 deletions(-) create mode 100644 zUtil_Deformation/GtGrainODFuvwSfSolver.m diff --git a/zUtil_Deformation/GtGrainODFuvwPatchSolver.m b/zUtil_Deformation/GtGrainODFuvwPatchSolver.m index 9c09bedd..2e762749 100644 --- a/zUtil_Deformation/GtGrainODFuvwPatchSolver.m +++ b/zUtil_Deformation/GtGrainODFuvwPatchSolver.m @@ -1,10 +1,11 @@ -classdef GtGrainODFuvwPatchSolver < GtGrainODFuvwSolver +classdef GtGrainODFuvwPatchSolver < GtGrainODFuvwSfSolver properties + shape_functions_extracted = {}; end methods (Access = public) function self = GtGrainODFuvwPatchSolver(parameters, varargin) - self = self@GtGrainODFuvwSolver(parameters, varargin{:}); + self = self@GtGrainODFuvwSfSolver(parameters, varargin{:}); end end @@ -16,35 +17,49 @@ classdef GtGrainODFuvwPatchSolver < GtGrainODFuvwSolver end function build_orientation_sampling(self, ref_gr, det_index, oversize, oversampling, shape_functions) - self.build_orientation_sampling@GtGrainODFuvwSolver(ref_gr, det_index, oversize, oversampling, shape_functions); - - shape_functions_name = sprintf('tmp_shape_functions_uvw_%d_%d', ... - size(self.voxel_centers, 1), self.sampler.get_total_num_orientations()); - - if (evalin('base', ['exist(''' shape_functions_name ''', ''var'')'])) - fprintf('Loading shape functions..') - c = tic(); - self.shape_functions = evalin('base', shape_functions_name); - fprintf('\b\b: Done in %g seconds\n', toc(c)); - elseif (~exist([shape_functions_name '.mat'], 'file')) - switch (self.shape_functions_type) - case 'uvw' - for ii_v = 1:size(self.voxel_centers, 1); - disp_sampler = self.sampler.regenerate_displaced(self.voxel_centers(ii_v, :)); - - self.shape_functions{ii_v} = gtDefCreateShapeFuncs(disp_sampler, 15, [], false); - end + self.build_orientation_sampling@GtGrainODFuvwSfSolver(ref_gr, det_index, oversize, oversampling, shape_functions); + + for ii_o = 1:self.sampler.get_total_num_orientations() + for ii_v = 1:size(self.voxel_centers, 1); + self.shape_functions_extracted{ii_o, ii_v} = {self.shape_functions{ii_v}{ii_o}(:).intm}; end - sfs = self.shape_functions; - save([shape_functions_name '.mat'], 'sfs', '-v7.3') - assignin('base', shape_functions_name, sfs); - else - fprintf('Loading shape functions..') - c = tic(); - sfs_file = load([shape_functions_name '.mat']); - self.shape_functions = sfs_file.sfs; - assignin('base', shape_functions_name, sfs_file.sfs); - fprintf('\b\b: Done in %g seconds\n', toc(c)); + end + end + + function build_projection_matrices_sf_uvw(self) + ref_sel = self.sampler.selected; + + grid_gr = self.sampler.get_orientations(); + num_orients = numel(grid_gr); + + num_voxels = size(self.voxel_centers, 1); + self.S = cell(num_voxels, 1); + self.St = cell(num_voxels, 1); + + bls = self.sampler.bl(ref_sel); + bls_uvw_orig = cat(1, bls(:).bbuim, bls(:).bbvim, bls(:).bbwim); + bls_uvw_orig = reshape(bls_uvw_orig, [], 3, 2); + bls_uvw_orig = bls_uvw_orig(:, :, 1); + bls_uvw_orig(:, 3) = bls_uvw_orig(:, 3) - self.pre_paddings + 1; + + for ii_v = 1:num_voxels + num_chars = fprintf('%03d/%03d', ii_v, num_voxels); + + sf_uvw_shift = cell(num_orients, 1); + for ii_o = 1:num_orients + sf_uvw_shift{ii_o} = cat(1, ... + self.shape_functions{ii_v}{ii_o}(:).bbuim, ... + self.shape_functions{ii_v}{ii_o}(:).bbvim, ... + self.shape_functions{ii_v}{ii_o}(:).bbwim ... + ); + sf_uvw_shift{ii_o} = reshape(sf_uvw_shift{ii_o}, [], 3, 2); + sf_uvw_shift{ii_o} = sf_uvw_shift{ii_o}(:, :, 1) - bls_uvw_orig; + end + sf_uvw_shift = cat(3, sf_uvw_shift{:}); + + self.S{ii_v} = sf_uvw_shift; + + fprintf(repmat('\b', [1 num_chars])); end end @@ -121,59 +136,22 @@ classdef GtGrainODFuvwPatchSolver < GtGrainODFuvwSolver % fprintf(repmat('\b', [1 num_chars])); % end % end - - function build_projection_matrices_sf_uvw(self) - ref_sel = self.sampler.selected; - - grid_gr = self.sampler.get_orientations(); - num_orients = numel(grid_gr); - - num_voxels = size(self.voxel_centers, 1); - self.S = cell(num_voxels, 1); - self.St = cell(num_voxels, 1); - - bls = self.sampler.bl(ref_sel); - bls_uvw_orig = cat(1, bls(:).bbuim, bls(:).bbvim, bls(:).bbwim); - bls_uvw_orig = reshape(bls_uvw_orig, [], 3, 2); - bls_uvw_orig = bls_uvw_orig(:, :, 1); - bls_uvw_orig(:, 3) = bls_uvw_orig(:, 3) - self.pre_paddings + 1; - - for ii_v = 1:num_voxels - num_chars = fprintf('%03d/%03d', ii_v, num_voxels); - - sf_uvw_shift = cell(num_orients, 1); - for ii_o = 1:num_orients - sf_uvw_shift{ii_o} = cat(1, ... - self.shape_functions{ii_v}{ii_o}(:).bbuim, ... - self.shape_functions{ii_v}{ii_o}(:).bbvim, ... - self.shape_functions{ii_v}{ii_o}(:).bbwim ... - ); - sf_uvw_shift{ii_o} = reshape(sf_uvw_shift{ii_o}, [], 3, 2); - sf_uvw_shift{ii_o} = sf_uvw_shift{ii_o}(:, :, 1) - bls_uvw_orig; - end - sf_uvw_shift = cat(3, sf_uvw_shift{:}); - - self.S{ii_v} = sf_uvw_shift; - - fprintf(repmat('\b', [1 num_chars])); - end - end end methods (Access = protected) function y = fp(self, x) num_blobs = self.get_num_blobs(); + num_orients = size(self.shape_functions_extracted, 1); + num_voxels = size(self.shape_functions_extracted, 2); y = gtMathsGetSameSizeZeros(self.sino, self.data_type); - for ii_v = 1:numel(self.S) - vsfs = self.shape_functions{ii_v}; - + for ii_v = 1:num_voxels uvw_shifts = self.S{ii_v}; - for ii_o = 1:numel(vsfs) - sfs = vsfs{ii_o}; - bls = {sfs(:).intm}; + for ii_o = 1:num_orients + bls = self.shape_functions_extracted{ii_o, ii_v}; + for ii_b = 1:num_blobs bls{ii_b} = bls{ii_b} .* x(ii_o, ii_v); end @@ -184,27 +162,23 @@ classdef GtGrainODFuvwPatchSolver < GtGrainODFuvwSolver function y = bp(self, x) num_blobs = self.get_num_blobs(); + num_orients = size(self.shape_functions_extracted, 1); + num_voxels = size(self.shape_functions_extracted, 2); - num_orients = numel(self.shape_functions{1}); - num_voxels = numel(self.S); - - y = zeros([num_orients, numel(self.S)], self.data_type); + y = zeros([num_orients, num_voxels], self.data_type); for ii_v = 1:num_voxels - vsfs = self.shape_functions{ii_v}; - uvw_shifts = self.S{ii_v}; for ii_o = 1:num_orients - sfs = vsfs{ii_o}; - bls = {sfs(:).intm}; + bls = self.shape_functions_extracted{ii_o, ii_v}; - mask_sino = gtMathsGetSameSizeZeros(self.sino); + mask_sino = zeros(self.size_sino, self.data_type); mask_sino = gtPlaceSubVolumes(mask_sino, bls, [uvw_shifts(:, :, ii_o), (0:num_blobs-1)']); mask_sino = mask_sino .* x; - y(ii_o, ii_v) = sum(sum(sum(sum(mask_sino, 1), 2), 3), 4); + y(ii_o, ii_v) = gtMathsSumNDVol(mask_sino); end end end diff --git a/zUtil_Deformation/GtGrainODFuvwSfSolver.m b/zUtil_Deformation/GtGrainODFuvwSfSolver.m new file mode 100644 index 00000000..43f1a6c4 --- /dev/null +++ b/zUtil_Deformation/GtGrainODFuvwSfSolver.m @@ -0,0 +1,174 @@ +classdef GtGrainODFuvwSfSolver < GtGrainODFuvwSolver + properties + end + + methods (Access = public) + function self = GtGrainODFuvwSfSolver(parameters, varargin) + self = self@GtGrainODFuvwSolver(parameters, varargin{:}); + end + end + + methods (Access = public) + function build_orientation_sampling(self, ref_gr, det_index, oversize, oversampling, shape_functions) + self.build_orientation_sampling@GtGrainODFuvwSolver(ref_gr, det_index, oversize, oversampling, shape_functions); + + shape_functions_name = sprintf('tmp_shape_functions_uvw_%d_%d', ... + size(self.voxel_centers, 1), self.sampler.get_total_num_orientations()); + + if (evalin('base', ['exist(''' shape_functions_name ''', ''var'')'])) + fprintf('Loading shape functions..') + c = tic(); + self.shape_functions = evalin('base', shape_functions_name); + fprintf('\b\b: Done in %g seconds\n', toc(c)); + elseif (~exist([shape_functions_name '.mat'], 'file')) + switch (self.shape_functions_type) + case 'uvw' + for ii_v = 1:size(self.voxel_centers, 1); + disp_sampler = self.sampler.regenerate_displaced(self.voxel_centers(ii_v, :)); + + self.shape_functions{ii_v} = gtDefCreateShapeFuncs(disp_sampler, 15, [], false); + end + end + sfs = self.shape_functions; + save([shape_functions_name '.mat'], 'sfs', '-v7.3') + assignin('base', shape_functions_name, sfs); + else + fprintf('Loading shape functions..') + c = tic(); + sfs_file = load([shape_functions_name '.mat']); + self.shape_functions = sfs_file.sfs; + assignin('base', shape_functions_name, sfs_file.sfs); + fprintf('\b\b: Done in %g seconds\n', toc(c)); + end + end + + function build_projection_matrices_sf_uvw_nooo(self) + ref_sel = self.sampler.selected; + + grid_gr = self.sampler.get_orientations(); + num_orients = numel(grid_gr); + + num_voxels = size(self.voxel_centers, 1); + self.S = cell(num_voxels, 1); + self.St = cell(num_voxels, 1); + + bls = self.sampler.bl(ref_sel); + bls_uvw_orig = cat(1, bls(:).bbuim, bls(:).bbvim, bls(:).bbwim); + bls_uvw_orig = reshape(bls_uvw_orig, [], 3, 2); + bls_uvw_orig = bls_uvw_orig(:, :, 1); + bls_uvw_orig(:, 3) = bls_uvw_orig(:, 3) - self.pre_paddings + 1; + + for ii_v = 1:num_voxels + num_chars = fprintf('%03d/%03d', ii_v, num_voxels); + + sf_uvw_shift = cell(num_orients, 1); + for ii_o = 1:num_orients + sf_uvw_shift{ii_o} = cat(1, ... + self.shape_functions{ii_v}{ii_o}(:).bbuim, ... + self.shape_functions{ii_v}{ii_o}(:).bbvim, ... + self.shape_functions{ii_v}{ii_o}(:).bbwim ... + ); + sf_uvw_shift{ii_o} = reshape(sf_uvw_shift{ii_o}, [], 3, 2); + sf_uvw_shift{ii_o} = sf_uvw_shift{ii_o}(:, :, 1) - bls_uvw_orig; + end + sf_uvw_shift = cat(3, sf_uvw_shift{:}); + + self.S{ii_v} = sf_uvw_shift; + + fprintf(repmat('\b', [1 num_chars])); + end + end + + function build_projection_matrices_sf_uvw(self) + ref_sel = self.sampler.selected; + + bls = self.sampler.bl(ref_sel); + num_blobs = self.get_num_blobs(); + + num_ws = self.get_num_ws(); + bls_bbws = cat(1, bls(:).bbwim); + min_w_conds = bls_bbws(:, 1) - self.pre_paddings + 1; + max_w_conds = min_w_conds + num_ws - 1; + + bls_bbus = cat(1, bls(:).bbuim); + bls_bbvs = cat(1, bls(:).bbvim); + + grid_gr = self.sampler.get_orientations(); + num_orients = numel(grid_gr); + + num_voxels = size(self.voxel_centers, 1); + self.S = cell(num_voxels, 1); + self.St = cell(num_voxels, 1); + + bls_uvw_orig = cat(1, bls(:).bbuim, bls(:).bbvim, bls(:).bbwim); + bls_uvw_orig = reshape(bls_uvw_orig, [], 3, 2); + bls_uvw_orig = bls_uvw_orig(:, :, 1); + bls_uvw_orig(:, 3) = bls_uvw_orig(:, 3) - self.pre_paddings + 1; + + for ii_v = 1:num_voxels + b_us = []; + b_vs = []; + b_ws = []; + b_cs = []; + b_is = []; + b_os = []; + + num_chars = fprintf('%03d/%03d', ii_v, num_voxels); + + for ii_o = 1:num_orients + sf = self.shape_functions{ii_v}{ii_o}; + sf_uvw_shift = cat(1, sf(:).bbuim, sf(:).bbvim, sf(:).bbwim); + sf_uvw_shift = reshape(sf_uvw_shift, [], 3, 2); + sf_uvw_shift = sf_uvw_shift(:, :, 1) - bls_uvw_orig; + + uvw_cs = cell(num_blobs, 1); + bl_is = cell(num_blobs, 1); + bl_shifts = cell(num_blobs, 1); + + for ii_b = 1:num_blobs + inds = find(sf(ii_b).intm); + uvw_cs{ii_b} = sf(ii_b).intm(inds); + +% [inds_u, inds_v, inds_w] = ind2sub(sf(ii_b).bbsize, inds); + inds_u = mod(inds, sf(ii_b).bbsize(1)); + inds_v = mod(floor(inds / sf(ii_b).bbsize(1)) + 1, sf(ii_b).bbsize(2)); + inds_w = floor(inds / prod(sf(ii_b).bbsize(1:2))) + 1; + + bl_is{ii_b} = ii_b(ones(numel(inds), 1)); + bl_shifts{ii_b} = [inds_u, inds_v, inds_w] + sf_uvw_shift(bl_is{ii_b}, :); + end + + uvw_cs = cat(1, uvw_cs{:}); + bl_is = cat(1, bl_is{:}); + bl_shifts = cat(1, bl_shifts{:}); + + b_us = [b_us; bl_shifts(:, 1)]; + b_vs = [b_vs; bl_shifts(:, 2)]; + b_ws = [b_ws; bl_shifts(:, 3)]; + + b_cs = [b_cs; uvw_cs]; + + b_is = [b_is; bl_is]; + b_os = [b_os; ii_o(ones(numel(bl_is), 1))]; + end + +% sino_indx = sub2ind(self.size_sino, b_us, b_vs, b_ws, b_is); + sino_indx = b_us ... + + self.size_sino(1) * (b_vs - 1 ... + + self.size_sino(2) * (b_ws - 1 ... + + self.size_sino(3) * (b_is - 1))); + + self.S{ii_v} = sparse( ... + sino_indx, b_os, double(b_cs), ... + numel(self.sino), num_orients); + + self.St{ii_v} = self.S{ii_v}'; + + fprintf(repmat('\b', [1 num_chars])); + end + end + end + + methods (Access = protected) + end +end \ No newline at end of file diff --git a/zUtil_Deformation/GtGrainODFwSolver.m b/zUtil_Deformation/GtGrainODFwSolver.m index 71138aa0..42379bdd 100644 --- a/zUtil_Deformation/GtGrainODFwSolver.m +++ b/zUtil_Deformation/GtGrainODFwSolver.m @@ -24,7 +24,7 @@ classdef GtGrainODFwSolver < handle verbose = false; - data_type = 'single'; + data_type = 'double'; end methods (Access = public) -- GitLab