Skip to content
Snippets Groups Projects
gtDefShapeFunctionsFwdProjUVW.m 6.93 KiB
Newer Older
function shape_funcs = gtDefShapeFunctionsFwdProjUVW(sampler, factor, dtype, recenter_sf)

    if (~exist('dtype', 'var') || isempty(dtype))
        dtype = 'single';
    end

    if (~exist('recenter_sf', 'var') || isempty(recenter_sf))
        recenter_sf = true;
    end

    interpolated_voxel = false;

    det_ind = sampler.detector_index;

    labgeo = sampler.parameters.labgeo;
%     samgeo = sampler.parameters.samgeo;
%     recgeo = sampler.parameters.recgeo(det_ind);
%     detgeo = sampler.parameters.detgeo(det_ind);

    labgeo.rotcomp = gtMathsRotationMatrixComp(labgeo.rotdir', 'col');
    sampler.parameters.labgeo = labgeo;

    fed_pars_detector = struct(...
        'blobsizeadd', [0 0 0], 'psf', [], 'apply_uv_shift', recenter_sf);
    fedpars = struct( ...
        'dcomps', [1 1 1 0 0 0 0 0 0] == 1, ...
        'defmethod', 'rod_rightstretch', ...
        'detector', repmat( fed_pars_detector, [numel(sampler.parameters.detgeo), 1]));

    voxel_factor = factor([1 1 1]);
    num_sub_voxels = prod(voxel_factor);
    ones_nsv = ones(num_sub_voxels, 1);

    gv = struct('cs', [], 'ind', [], 'dm', [], 'pow', []);

    [gv.ind(:, 1), gv.ind(:, 2), gv.ind(:, 3)] = ind2sub(voxel_factor, 1:num_sub_voxels);
    gv.ind = gv.ind';

    ref_gr = sampler.get_reference_grain();
    gv.cs = ref_gr.center(ones_nsv, :)';

    % computing the subsampling, used to deterine the shape functions
    voxel_size = sampler.stats.sampling.gaps;
    if (interpolated_voxel)
        half_voxel_size = voxel_size; % Enlarging to neighbours
        steps = voxel_size ./ voxel_factor * 2;
    else
        half_voxel_size = voxel_size ./ 2;
        steps = voxel_size ./ voxel_factor;
    end
    half_steps = steps ./ 2;
    beg_pos = - half_voxel_size + half_steps;
    end_pos = + half_voxel_size - half_steps;

    x_steps = beg_pos(1):steps(1):end_pos(1);
    y_steps = beg_pos(2):steps(2):end_pos(2);
    z_steps = beg_pos(3):steps(3):end_pos(3);

    num_steps = [numel(x_steps), numel(y_steps), numel(z_steps)];
    ones_x_steps = ones(1, num_steps(1));

    gv.d = zeros(3, prod(num_steps));

    pos = 0;
    for ii_z = z_steps
        for ii_y = y_steps
            gv.d(:, (pos+1):(pos+num_steps(1))) ...
                = [ x_steps; ones_x_steps * ii_y; ones_x_steps * ii_z];

            pos = pos + num_steps(1);
        end
    end

    if (interpolated_voxel)
        gv.pow = prod(1 - abs(gv.d ./ half_voxel_size(ones_nsv, :)'), 1);
    else
        gv.pow = ones(1, num_sub_voxels, dtype);
    end
    gv.pow = gv.pow / sum(gv.pow);

    gv.used_ind = find(gv.pow > 0);
    nuv = numel(gv.used_ind);
    ones_nuv = ones(1, nuv);

    sel_bls = find(sampler.selected);
    inc_bls = sampler.ondet(sampler.included(sampler.selected));

    % computing the size of the blobs
    shape_funcs_size(:, 3) = ceil(2 * atand(sampler.stats.sampling.gaps(3)) ...
        / labgeo.omstep .* ref_gr.allblobs.lorentzfac(inc_bls)) + 1;
    shape_funcs_size(:, 1) = sampler.stats.proj.max_pixel_dist_u;
    shape_funcs_size(:, 2) = sampler.stats.proj.max_pixel_dist_v;
    if (interpolated_voxel)
        shape_funcs_size = shape_funcs_size * 2;
    end
    shape_funcs_size = 2 * ceil(shape_funcs_size) + 1; % Imposing odd shape! -> for centering
    half_sf_size = floor(shape_funcs_size / 2);

    % Only one lattice allowed for the moment!
    num_ors = numel(sampler.lattice(1).gr);
    shape_funcs = cell(num_ors, 1);

    nbl = numel(sel_bls);

    fprintf('Computing UVW shape functions: ')
    c = tic();
    for ii_g = 1:num_ors
        num_chars = fprintf('%03d/%03d', ii_g, num_ors);

        or = sampler.lattice(1).gr{ii_g};

        bl = repmat(gtFedBlobDefinition(), nbl, 1);

        or_uvw = or.allblobs.detector(det_ind).uvw(sel_bls, :);

        for ii_b = 1:nbl
            % Load diffraction paramaters of blobs

            % Initial strained non-signed plane normal in SAMPLE reference
            bl(ii_b).plorig = or.allblobs.plorig(sel_bls(ii_b), :);
            bl(ii_b).sinth0 = or.allblobs.sintheta(sel_bls(ii_b));  % initial sin(theta)
            bl(ii_b).omega0 = or.allblobs.omega(sel_bls(ii_b));     % initial omega
            bl(ii_b).omind  = or.allblobs.omind(sel_bls(ii_b));     % initial omega index (1..4)

            % Initial centroid in image
            bl(ii_b).u0im = or_uvw(ii_b, :);

            % Projection information!!
            bl(ii_b).bbuim = round(or_uvw(ii_b, 1) + [-half_sf_size(ii_b, 1), half_sf_size(ii_b, 1)]);
            bl(ii_b).bbvim = round(or_uvw(ii_b, 2) + [-half_sf_size(ii_b, 2), half_sf_size(ii_b, 2)]);
            bl(ii_b).bbwim = round(or_uvw(ii_b, 3) + [-half_sf_size(ii_b, 3), half_sf_size(ii_b, 3)]);
            bl(ii_b).bbsize = [ ...
                (bl(ii_b).bbuim(2) - bl(ii_b).bbuim(1) + 1), ...
                (bl(ii_b).bbvim(2) - bl(ii_b).bbvim(1) + 1), ...
                (bl(ii_b).bbwim(2) - bl(ii_b).bbwim(1) + 1) ];

            % Blob origin and center [u, v, w]:
            bl(ii_b).bbor   = [bl(ii_b).bbuim(1)-1, bl(ii_b).bbvim(1)-1, bl(ii_b).bbwim(1)-1];

            bl(ii_b).bbcent = [ ...
                round( (bl(ii_b).bbuim(1) + bl(ii_b).bbuim(2) ) / 2 ), ...
                round( (bl(ii_b).bbvim(1) + bl(ii_b).bbvim(2) ) / 2 ), ...
                round( (bl(ii_b).bbwim(1) + bl(ii_b).bbwim(2) ) / 2 ) ];

            % u in blob = u in image minus u at blob origin
            bl(ii_b).u0bl = bl(ii_b).u0im - bl(ii_b).bbor;
            bl(ii_b).uv_shift = bl(ii_b).u0im(1:2) - bl(ii_b).bbcent(1:2);

            bl(ii_b).int = zeros(bl(ii_b).bbsize, dtype);
            bl(ii_b).intm = [];
        end

        for ii_b = nbl:-1:1
            gvb(ii_b).uc      = zeros(3, nuv, dtype);
            gvb(ii_b).ucd     = zeros(3, nuv, dtype);
            gvb(ii_b).ucblmod = zeros(3, nuv, dtype);
            gvb(ii_b).ucbl8   = zeros(1, nuv*8, dtype);
            gvb(ii_b).ucbl8ini= zeros(1, nuv*8, dtype);
            gvb(ii_b).ucbl8ok = 0;

            % Initial u of gv centre relative to blob origin
            gvb(ii_b).uc0bl = cast(bl(ii_b).u0im - bl(ii_b).bbor, dtype)';
            gvb(ii_b).uc0bl = gvb(ii_b).uc0bl(:, ones_nuv);
        end

        [gvb, bl] = gtFedFwdProjExact(gv, gvb, bl, fedpars, sampler.parameters, det_ind, false);

        % Cutting borders
        for ii_b = 1:nbl
            diff_inds_w = [...
                find(sum(sum(bl(ii_b).int, 1), 2), 1, 'first') - 1, ...
                find(sum(sum(bl(ii_b).int, 1), 2), 1, 'last') - bl(ii_b).bbsize(3); ...
                ];
            bl(ii_b).bbwim = bl(ii_b).bbwim + diff_inds_w;

            bl(ii_b).mbbu = bl(ii_b).bbuim;
            bl(ii_b).mbbv = bl(ii_b).bbvim;
            bl(ii_b).mbbw = bl(ii_b).bbwim;

            inds_w = [1, bl(ii_b).bbsize(3)] + diff_inds_w;

            bl(ii_b).intm = bl(ii_b).int(:, :, inds_w(1):inds_w(2));
            bl(ii_b).int = [];

            bl(ii_b).bbsize(3) = size(bl(ii_b).intm, 3);
        end

        shape_funcs{ii_g} = bl;

        fprintf(repmat('\b', [1, num_chars]));
    end

    fprintf('Done in %g seconds.\n', toc(c))
end