Skip to content
Snippets Groups Projects
gtGrainComputeBeamAttenuation.m 4.86 KiB
Newer Older
function atts = gtGrainComputeBeamAttenuation(gr, p, det_index, abs_vol, sampling_factor)

    if (~exist('sampling_factor', 'var') || isempty(sampling_factor))
        sampling_factor = 1;
    end

    if (isfield(gr.proj, 'ondet'))
        gr_included = gr.proj.ondet(gr.proj.included);
    else
        gr_included = gr.ondet(gr.included);
    end

    if (~exist('det_index', 'var') || isempty(det_index))
        det_index = 1;
    end

    rot_l2s = gr.allblobs.srot(:, :, gr_included);
    % They are reversed because we also use them to find the intersaction
    % with the volume border
    beam_dirs_in = - p.labgeo.beamdir * reshape(rot_l2s, 3, []);
    beam_dirs_in = permute(reshape(beam_dirs_in, 1, 3, []), [3 2 1]);

    beam_dirs_out = gr.allblobs.dvecsam(gr_included, :);

    gr_center = gr.proj(det_index).centerpix + size(abs_vol) / 2 + 1;

    % ray tracing
    dists_borders = cat(3, [1 1 1], size(abs_vol)) - gr_center(1, :, [1 1]);

    dists_renorm_in = compute_renormalized_distances(dists_borders, beam_dirs_in);
    dists_renorm_out = compute_renormalized_distances(dists_borders, beam_dirs_out);

    num_refl = numel(gr_included);
    atts = zeros(num_refl, 2);

    for ii = 1:num_refl
%         dist_in = dists_borders(d_inds_in_dir(d_inds_in_pm(ii)));
%         samp_points_in = linspace(0, dists_renorm_in(ii), ceil(abs(dist_in) * sampling_factor) );

        samp_factor_in = ceil(dists_renorm_in(ii) * sampling_factor);

        samp_points_in = linspace(0, dists_renorm_in(ii), samp_factor_in);
        samp_points_in = bsxfun(@times, beam_dirs_in(ii, :), samp_points_in');
        samp_points_in = bsxfun(@plus, samp_points_in, gr_center);

%         dist_out = dists_borders(d_inds_out_dir(d_inds_out_pm(ii)));
%         samp_points_out = linspace(0, dists_renorm_out(ii), ceil(abs(dist_out) * sampling_factor) );

        samp_factor_out = ceil(dists_renorm_out(ii) * sampling_factor);

        samp_points_out = linspace(0, dists_renorm_out(ii), samp_factor_out);
        samp_points_out = bsxfun(@times, beam_dirs_out(ii, :), samp_points_out');
        samp_points_out = bsxfun(@plus, samp_points_out, gr_center);

        [inds_in, ints_in] = gtMathsGetInterpolationIndices(samp_points_in);
        valid_in = ints_in > eps('single');
        inds_in = inds_in(valid_in, :);
        ints_in = ints_in(valid_in);

        [inds_out, ints_out] = gtMathsGetInterpolationIndices(samp_points_out);
        valid_out = ints_out > eps('single');
        inds_out = inds_out(valid_out, :);
        ints_out = ints_out(valid_out);

        inds_in = sub2ind(size(abs_vol), inds_in(:, 1), inds_in(:, 2), inds_in(:, 3));
        vals_in = abs_vol(inds_in) .* ints_in;

        inds_out = sub2ind(size(abs_vol), inds_out(:, 1), inds_out(:, 2), inds_out(:, 3));
        vals_out = abs_vol(inds_out) .* ints_out;

        abs_in = sum(vals_in) / samp_factor_in * dists_renorm_in(ii);
        abs_out = sum(vals_out) / samp_factor_out * dists_renorm_out(ii);

        atts(ii, :) = [abs_in, abs_out];

%         f = figure();
%         ax = axes('parent', f);
%         hold(ax, 'on')
%         scatter3(ax, samp_points_in(:, 1), samp_points_in(:, 2), samp_points_in(:, 3));
%         scatter3(ax, samp_points_out(:, 1), samp_points_out(:, 2), samp_points_out(:, 3));
%         show_bbox(ax, cat(1, [1 1 1], size(abs_vol)))
%         hold(ax, 'off')
%         pause
    end

    atts = exp(-atts);

%     figure, semilogy(ints)
%     figure, semilogy(prod(ints, 2))
end

function [dists_renorm, d_inds_pm, d_inds_dir] = compute_renormalized_distances(dists_borders, beam_dirs)
    dists_renorm = bsxfun(@times, dists_borders, 1 ./ beam_dirs);
    [dists_renorm, d_inds_pm] = max(dists_renorm, [], 3); % Takes negative out
    [dists_renorm, d_inds_dir] = min(dists_renorm, [], 2); % Takes shortest, and removes last remaining nans
end

function show_bbox(ax, borders)
    min_sampled_R_vecs = min(borders, [], 1);
    max_sampled_R_vecs = max(borders, [], 1);
    bbox_R_vecs = [ ...
        min_sampled_R_vecs(1), min_sampled_R_vecs(2), min_sampled_R_vecs(3); ...
        min_sampled_R_vecs(1), min_sampled_R_vecs(2), max_sampled_R_vecs(3); ...
        min_sampled_R_vecs(1), max_sampled_R_vecs(2), min_sampled_R_vecs(3); ...
        min_sampled_R_vecs(1), max_sampled_R_vecs(2), max_sampled_R_vecs(3); ...

        max_sampled_R_vecs(1), min_sampled_R_vecs(2), min_sampled_R_vecs(3); ...
        max_sampled_R_vecs(1), min_sampled_R_vecs(2), max_sampled_R_vecs(3); ...
        max_sampled_R_vecs(1), max_sampled_R_vecs(2), min_sampled_R_vecs(3); ...
        max_sampled_R_vecs(1), max_sampled_R_vecs(2), max_sampled_R_vecs(3); ...
        ];
    faces = [ ...
        1 5; 2 6; 3 7; 4 8; ...
        1 3; 2 4; 5 7; 6 8; ...
        1 2; 3 4; 5 6; 7 8; ...
        ];

    scatter3(ax, bbox_R_vecs(:, 1), bbox_R_vecs(:, 2), bbox_R_vecs(:, 3), 30, 'y', 'filled');
    patch('parent', ax, 'Faces', faces, 'Vertices', bbox_R_vecs, 'FaceColor', 'w');
end