-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
108 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
# UtilitiesForMRI | ||
|
||
Utilities for MRI | ||
Collection of utilities for 3D MRI, first and foremost comprising a NFFT linear operator which may be perturbed by phase-encoding dependent rigid-body motion. The perturbed operator is differentiable with respect to rigid-body motion parameters (translation and rotations). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
# Motion parameter utilities | ||
|
||
export derivative1d_linop, derivative1d_motionpars_linop, interpolation1d_linop, interpolation1d_motionpars_linop | ||
|
||
function derivative1d_linop(t::AbstractVector{T}, order::Integer) where {T<:Real} | ||
(order != 1) && (order != 2) && error("Order not supported (only 1 or 2)") | ||
nt = length(t) | ||
Δt = t[2:end]-t[1:end-1] | ||
if order == 1 | ||
d_0 = [-T(1)./Δt; T(0)] | ||
d_p1 = T(1)./Δt; | ||
return spdiagm(nt, nt, 0 => d_0, 1 => d_p1) | ||
elseif order == 2 | ||
Δt_m1 = Δt[1:end-1] | ||
Δt_p1 = Δt[2:end] | ||
Δt_mean = (Δt_m1+Δt_p1)/T(2) | ||
d_m1 = T(1)./(Δt_m1.*Δt_mean) | ||
d_p1 = [T(0); T(1)./(Δt_p1.*Δt_mean)] | ||
d_0 = [T(0); -d_m1-d_p1[2:end]] | ||
return spdiagm(nt, nt, -1 => d_m1, 0 => d_0, 1 => d_p1) | ||
end | ||
end | ||
|
||
function derivative1d_motionpars_linop(t::AbstractVector{T}, order::Integer; pars::NTuple{6,Bool}=(true, true, true, true, true, true)) where {T<:Real} | ||
D = derivative1d_linop(t, order) | ||
Id = sparse(I, length(t), length(t)) | ||
A = [] | ||
for i = 1:6 | ||
pars[i] ? push!(A, D) : push!(A, Id) | ||
end | ||
return cat(A...; dims=(1,2)) | ||
end | ||
|
||
function interpolation1d_linop(t::AbstractVector{T}, ti::AbstractVector{T}; interp::Symbol=:linear) where {T<:Real} | ||
(interp != :linear) && error("Only linear interpolation supported") | ||
nt = length(t) | ||
nti = length(ti) | ||
I = repeat(reshape(1:nti, :, 1); outer=(1,2)) | ||
J = Array{Int64,2}(undef, nti, 2) | ||
V = Array{T,2}(undef, nti, 2) | ||
for i = 1:nti | ||
if t[1] == ti[i] | ||
J[i,:] = [1 2] | ||
V[i,:] = [T(1) T(0)] | ||
else | ||
idx = maximum(findall(t.<ti[i])) | ||
J[i,:] = [idx idx+1] | ||
Δt = t[idx+1]-t[idx] | ||
V[i,:] = [(t[idx+1]-ti[i])/Δt (ti[i]-t[idx])/Δt] | ||
end | ||
end | ||
return sparse(vec(I),vec(J),vec(V),nti,nt) | ||
end | ||
|
||
function interpolation1d_motionpars_linop(t::NTuple{6,AbstractVector{T}}, ti::NTuple{6,AbstractVector{T}}; interp::Symbol=:linear) where {T<:Real} | ||
Ip = [] | ||
for i=1:6 | ||
push!(Ip, interpolation1d_linop(t[i], ti[i]; interp=interp)) | ||
end | ||
return cat(Ip...; dims=(1,2)) | ||
end | ||
|
||
interpolation1d_motionpars_linop(t::AbstractVector{T}, ti::NTuple{6,AbstractVector{T}}; interp::Symbol=:linear) where {T<:Real} = interpolation1d_motionpars_linop((t,t,t,t,t,t), ti; interp=interp) | ||
|
||
interpolation1d_motionpars_linop(t::NTuple{6,AbstractVector{T}}, ti::AbstractVector{T}; interp::Symbol=:linear) where {T<:Real} = interpolation1d_motionpars_linop(t, (ti,ti,ti,ti,ti,ti); interp=interp) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
using UtilitiesForMRI, LinearAlgebra, Test, PyPlot | ||
|
||
nt = 256 | ||
t = Float64.(1:nt) | ||
D = derivative1d_motionpars_linop(t, 2; pars=(true,false,true,false,true,true)) | ||
θ = zeros(Float64, nt, 6); θ[129-30:129+30,:] .= 1; θ[1:10,1] .= 1; θ[end-9:end,1] .= 1 | ||
Dθ = reshape(D*vec(θ), :, 6) | ||
|
||
nt = 256+1 | ||
t = Float64.(0:nt-1) | ||
ti = Float64.(0:2:nt-1); nti = length(ti) | ||
Itp = interpolation1d_motionpars_linop((ti,ti,t,ti,ti,t), t) | ||
θ = randn(Float64, 4*nti+2*nt) | ||
Iθ = reshape(Itp*θ, nt, 6) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters