File: simple_gridder.m

package info (click to toggle)
ismrmrd 1.15.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,576 kB
  • sloc: cpp: 6,439; ansic: 2,276; xml: 1,025; sh: 242; python: 72; makefile: 42
file content (100 lines) | stat: -rw-r--r-- 3,759 bytes parent folder | download | duplicates (5)
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
function img = simple_gridder(co,data,weight,matrix_size)
%
%   img = simple_gridder(co,data,weight,matrix_size)
%
%   A very simple gridder written purely in Matlab. 
%   Only tested for 2D
%
%   Input arguments:
%     - co [N,2], k-space coordinates in the range [-0.5:0.5]
%     - data, vector of N complex data points
%     - weight, vector of N data weights (density compensation)
%     - matrix_size, 2-element vector, e.g. [128 128]
%
%   Michael S. Hansen (michael.hansen@nih.gov), 2012
%
%

over_sampling = 2.0;
kernel_width = 8;
kernel_samples = 100000;
kernel_beta = 18.5547;
matrix_size_oversampled = matrix_size*over_sampling;

kernel_table = 1.0-(2.0*[-bitshift(kernel_samples,-1):(bitshift(kernel_samples,-1)-1)]/kernel_samples).^2;

kernel_table(kernel_table<0) = 0;
kernel_table=sqrt(kernel_table);
kernel_table = bessi0(kernel_beta .* kernel_table);
knorm = sum(kernel_table(:))/numel(kernel_table);
kernel_table = kernel_table ./ knorm;

grid_cells = ceil(co .* repmat(matrix_size_oversampled,size(co,1),1)-(kernel_width/2));
kernel_idx = grid_cells-(co .* repmat(matrix_size_oversampled,size(co,1),1));
grid_cells = uint32(grid_cells+repmat(bitshift(matrix_size_oversampled+kernel_width,-1),size(co,1),1));
kernel_idx = uint32(floor(((kernel_idx + kernel_width/2)/kernel_width)*kernel_samples));
kernel_step = uint32(floor(kernel_samples/kernel_width));

%Calculate deapodization
kern = -bitshift(kernel_width,-1):(-bitshift(kernel_width,-1)+kernel_width-1);
kern = 1.0-(2.0*kern/kernel_width).^2;
kern = bessi0(kernel_beta .* kern);
kern = repmat(kern,kernel_width,1) .* repmat(kern',1,kernel_width);
deapodization = zeros(matrix_size_oversampled);
deapodization((1:kernel_width) + bitshift(matrix_size_oversampled(1)-kernel_width,-1), ...
              (1:kernel_width) + bitshift(matrix_size_oversampled(2)-kernel_width,-1)) = kern;  
deapodization = fftshift(ifftn(ifftshift(deapodization))) ./ sqrt(numel(deapodization));

%Do convolution
oversampled_grid_padded = zeros(matrix_size_oversampled+kernel_width);
for y=1:(kernel_width),
    for x=1:(kernel_width),       
        oversampled_grid_padded = oversampled_grid_padded + ...
            accumarray([grid_cells(:,1)+(x-1),grid_cells(:,2)+(y-1)], ...
            weight(:).*data(:).*(kernel_table(kernel_idx(:,1)+(x-1)*kernel_step+1).*kernel_table(kernel_idx(:,2)+(y-1).*kernel_step+1))', ...
            matrix_size_oversampled+kernel_width);
    end
end

osps = size(oversampled_grid_padded);
oss = matrix_size_oversampled;

%Let's just get rid of the padding, it should really be folded in
oversampled_grid = oversampled_grid_padded(bitshift(osps(1)-oss(1),-1):bitshift(osps(1)-oss(1),-1)+matrix_size_oversampled(1)-1, ...
                                           bitshift(osps(2)-oss(2),-1):bitshift(osps(1)-oss(2),-1)+matrix_size_oversampled(2)-1); 

%FFT to image space                                       
img = fftshift(ifftn(ifftshift(oversampled_grid))) ./ sqrt(numel(oversampled_grid));

%Deapodization
img = img ./ deapodization;

%Remove oversampling
img = img((1:matrix_size(1))+bitshift(matrix_size_oversampled(1)-matrix_size(1),-1), ...
          (1:matrix_size(2))+bitshift(matrix_size_oversampled(2)-matrix_size(2),-1));

%TODO
% - fold padding back in

return

function ans = bessi0(x)

ax = abs(x);
ans = zeros(size(x));

% ax<3.75
k = find(ax<3.75);
y=x(k)./3.75;
y=y.^2;
ans(k)=1.0+y.*(3.5156229+y.*(3.0899424+y.*(1.2067492 ...
    +y.*(0.2659732+y.*(0.360768e-1+y.*0.45813e-2)))));

% ax>=3.75
k = find(ax>=3.75);
y=3.75./ax(k);
ans(k)=(exp(ax(k))./sqrt(ax(k))).*(0.39894228+y.*(0.1328592e-1 ...
    +y.*(0.225319e-2+y.*(-0.157565e-2+y.*(0.916281e-2 ...
    +y.*(-0.2057706e-1+y.*(0.2635537e-1+y.*(-0.1647633e-1 ...
    +y.*0.392377e-2))))))));
return