-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathmulticoil_cov.m
More file actions
104 lines (96 loc) · 3.38 KB
/
multicoil_cov.m
File metadata and controls
104 lines (96 loc) · 3.38 KB
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
101
102
103
104
function [C,A] = multicoil_cov(rho, x, s, gpu)
% Maximum likelihood covariance given a set of observed coil images,
% log-sensitivity profiles and a mean image.
%
% FORMAT [C,A] = multicoil_cov(rho, x, s, (gpu))
%
% rho - (File)Array [Nx Ny Nz 1 (2)] - Complex mean image
% x - (File)Array [Nx Ny Nz Nc (2)] - Complex coil images
% s - (File)Array [Nx Ny Nz Nc (2)] - Complex log-sensitivity profiles
% gpu - If 'gpu', compute on GPU
%
% C - Array [Nc Nc] - Noise covariance matrix
% A - Array [Nc Nc] - Noise precision matrix
%
% >> C = sum((b*rho-x)*(b*rho-x)')/(2J) [where ' = conjugate transpose]
%
% Nc = number of coils
% Images can either be complex or have two real components that are then
% assumed to be the real and imaginary parts.
% An output FileArray can be provided by using `rho` as an input. If not
% provided, the output volume will have the same format as the input coil
% volume.
%__________________________________________________________________________
% Copyright (C) 2018 Wellcome Centre for Human Neuroimaging
if nargin < 4
gpu = '';
end
% -------------------------------------------------------------------------
% Allocate output array
C = zeros(size(x,4), 'double');
if strcmpi(gpu, 'gpu')
C = gpuArray(C);
end
% -------------------------------------------------------------------------
% Process slice-wise to save memory
for z=1:size(rho, 3)
% ---------------------------------------------------------------------
% Load one slice of the complete coil dataset
if size(x, 5) == 2
% Two real components
x1 = reshape(single(x(:,:,z,:,:)), [], size(x,4), 2);
x1 = x1(:,:,1) + 1i*x1(:,:,2);
else
% One complex volume
x1 = reshape(single(x(:,:,z,:)), [], size(x,4));
end
if isa(C, 'gpuArray')
x1 = gpuArray(x1);
end
% ---------------------------------------------------------------------
% Load one slice of the mean
if size(rho, 5) == 2
% Two real components
rho1 = reshape(single(rho(:,:,z,:,:)), [], 1, 2);
rho1 = rho1(:,:,1) + 1i*rho1(:,:,2);
else
% One complex volume
rho1 = reshape(single(rho(:,:,z,:,:)), [], 1);
end
if isa(C, 'gpuArray')
rho1 = gpuArray(rho1);
end
% ---------------------------------------------------------------------
% Load one slice of the complete sensitivity dataset + correct
if size(s, 5) == 2
% Two real components
s1 = reshape(double(s(:,:,z,:,:)), [], size(x,4), 2);
s1 = single(exp(s1(:,:,1) + 1i*s1(:,:,2)));
else
% One complex volume
s1 = reshape(single(exp(double(s(:,:,z,:,:)))), [], size(x,4));
end
if isa(C, 'gpuArray')
s1 = gpuArray(s1);
end
rho1 = bsxfun(@times, rho1, s1);
clear s1
% ---------------------------------------------------------------------
% Compute and sum residuals
rho1 = rho1 - x1;
clear x1
for n=1:size(x,4)
C(n,n) = C(n,n) + sum(double(real( rho1(:,n) .* conj(rho1(:,n)) )));
for m=n+1:size(x,4)
tmp = sum(double(real( rho1(:,n) .* conj(rho1(:,m)) )));
C(n,m) = C(n,m) + tmp;
C(m,n) = C(m,n) + tmp;
clear tmp
end
end
clear rho1
end
C = C/(2*size(x,1)*size(x,2)*size(x,3));
A = spm_matcomp('inv', C);
C = single(C);
A = single(A);