Skip to content

Commit f92c53d

Browse files
authored
Exchangable NFFT backends (#17)
* Move NFFTOp to trigger on AbstractNFFTs instead * Remove fixed precompute plan keyword argument and instead pass in given kwargs * Re-add precompute flag and update keyword args delimter * Remove symmetrize keyword (also had no effect previously)
1 parent 03c63b3 commit f92c53d

File tree

4 files changed

+18
-14
lines changed

4 files changed

+18
-14
lines changed

Project.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,15 @@ julia = "1.9"
2424
GPUArrays = "11"
2525
KernelAbstractions = "0.9"
2626
JLArrays = "0.2"
27-
NFFT = "0.13"
27+
AbstractNFFTs = "0.9"
2828
LinearOperators = "2"
2929
RadonKA = "0.6"
3030
Wavelets = "0.9, 0.10"
3131
Reexport = "1.0"
3232
FFTW = "1.0"
3333

3434
[weakdeps]
35+
AbstractNFFTs = "7f219486-4aa7-41d6-80a7-e08ef20ceed7"
3536
GPUArrays = "0c68f7d7-f131-5f86-a1c3-88cf8149b2d7"
3637
KernelAbstractions = "63c18a36-062a-441e-b654-da1e3ab1ce7c"
3738
NFFT = "efe261a4-0d2b-5849-be55-fc731d526b0d"
@@ -43,7 +44,7 @@ RadonKA = "86de8297-835b-47df-b249-c04e8db91db5"
4344
test = ["Test", "FFTW", "Wavelets", "NFFT", "JLArrays", "RadonKA"]
4445

4546
[extensions]
46-
LinearOperatorNFFTExt = ["NFFT", "FFTW"]
47+
LinearOperatorNFFTExt = ["AbstractNFFTs", "FFTW"]
4748
LinearOperatorFFTWExt = "FFTW"
4849
LinearOperatorWaveletExt = "Wavelets"
4950
LinearOperatorGPUArraysExt = "GPUArrays"

ext/LinearOperatorNFFTExt/LinearOperatorNFFTExt.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module LinearOperatorNFFTExt
22

3-
using LinearOperatorCollection, NFFT, NFFT.AbstractNFFTs, FFTW, FFTW.AbstractFFTs
3+
using LinearOperatorCollection, AbstractNFFTs, FFTW, FFTW.AbstractFFTs
44

55
include("NFFTOp.jl")
66

ext/LinearOperatorNFFTExt/NFFTOp.jl

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,16 @@ generates a `NFFTOpImpl` which evaluates the MRI Fourier signal encoding operato
66
77
# Arguments:
88
* `shape::NTuple{D,Int64}` - size of image to encode/reconstruct
9-
* `tr` - Either a `Trajectory` object, or a `ND x Nsamples` matrix for an ND-dimenensional (e.g. 2D or 3D) NFFT with `Nsamples` k-space samples
10-
* (`nodes=nothing`) - Array containg the trajectory nodes (redundant)
11-
* (`kargs`) - additional keyword arguments
9+
* `nodes=nothing` - Array containg the trajectory nodes
10+
* `toeplitz=false` -
11+
* `oversamplingFactor=1.25`
12+
* `kernelSize=3`
13+
* `precompute = AbstractNFFTs.TENSOR` Precompute flag for the NFFT backend
14+
* (`kargs`) - additional keyword arguments for the NFFT plan,
1215
"""
1316
function LinearOperatorCollection.NFFTOp(::Type{T};
1417
shape::Tuple, nodes::AbstractMatrix{U}, toeplitz=false, oversamplingFactor=1.25,
15-
kernelSize=3, kargs...) where {U <: Number, T <: Number}
18+
kernelSize=3, precompute = AbstractNFFTs.TENSOR, kargs...) where {U <: Number, T <: Number}
1619
return NFFTOpImpl(shape, nodes; toeplitz, oversamplingFactor, kernelSize, kargs... )
1720
end
1821

@@ -38,11 +41,11 @@ end
3841

3942
LinearOperators.storage_type(op::NFFTOpImpl) = typeof(op.Mv5)
4043

41-
function NFFTOpImpl(shape::Tuple, tr::AbstractMatrix{T}; toeplitz=false, oversamplingFactor=1.25, kernelSize=3, S = Vector{Complex{T}}, kargs...) where {T}
44+
function NFFTOpImpl(shape::Tuple, tr::AbstractMatrix{T}; toeplitz, oversamplingFactor, kernelSize, S = Vector{Complex{T}}, kargs...) where {T}
4245

4346
baseArrayType = Base.typename(S).wrapper # https://github.com/JuliaLang/julia/issues/35543
44-
plan = plan_nfft(baseArrayType, tr, shape, m=kernelSize, σ=oversamplingFactor, precompute=NFFT.TENSOR,
45-
fftflags=FFTW.ESTIMATE, blocking=true)
47+
plan = plan_nfft(baseArrayType, tr, shape; m=kernelSize, σ=oversamplingFactor,
48+
fftflags=FFTW.ESTIMATE, blocking=true, kargs...)
4649

4750
return NFFTOpImpl{eltype(S), S, typeof(plan)}(size(tr,2), prod(shape), false, false
4851
, (res,x) -> produ!(res,plan,x)
@@ -143,7 +146,7 @@ function NFFTToeplitzNormalOp(nfft::NFFTOp{T}, W=nothing; kwargs...) where {T}
143146
shape_os = 2 .* shape
144147
baseArrayType = Base.typename(typeof(tmpVec)).wrapper # https://github.com/JuliaLang/julia/issues/35543
145148
p = plan_nfft(baseArrayType, nfft.plan.k, shape_os; m = nfft.plan.params.m, σ = nfft.plan.params.σ,
146-
precompute=NFFT.POLYNOMIAL, fftflags=FFTW.ESTIMATE, blocking=true)
149+
precompute=AbstractNFFTs.POLYNOMIAL, fftflags=FFTW.ESTIMATE, blocking=true)
147150
tmpOnes = similar(tmpVec, size(nfft.plan.k, 2))
148151
tmpOnes .= one(T)
149152

test/testOperators.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ function testNFFT2d(N=16;arrayType = Array)
218218
# Operator
219219
xop = arrayType(vec(x))
220220
nodes = [(idx[d] - N÷2 - 1)./N for d=1:2, idx in vec(CartesianIndices((N,N)))]
221-
F_nfft = NFFTOp(ComplexF64; shape=(N,N), nodes, symmetrize=false, S = typeof(xop))
221+
F_nfft = NFFTOp(ComplexF64; shape=(N,N), nodes, S = typeof(xop))
222222

223223
# test against FourierOperators
224224
y = vec( ifftshift(reshape(F*vec(fftshift(x)),N,N)) )
@@ -249,7 +249,7 @@ function testNFFT2d(N=16;arrayType = Array)
249249
# test type stability;
250250
# TODO: Ensure type stability for Trajectory objects and test here
251251
nodes = Float32.(nodes)
252-
F_nfft = NFFTOp(ComplexF32; shape=(N,N), nodes, symmetrize=false, S = typeof(ComplexF32.(xop)))
252+
F_nfft = NFFTOp(ComplexF32; shape=(N,N), nodes, S = typeof(ComplexF32.(xop)))
253253

254254
y_nfft = F_nfft * ComplexF32.(xop)
255255
y_adj_nfft = adjoint(F_nfft) * ComplexF32.(xop)
@@ -273,7 +273,7 @@ function testNFFT3d(N=12;arrayType = Array)
273273
# Operator
274274
xop = arrayType(vec(x))
275275
nodes = [(idx[d] - N÷2 - 1)./N for d=1:3, idx in vec(CartesianIndices((N,N,N)))]
276-
F_nfft = NFFTOp(ComplexF64; shape=(N,N,N), nodes=nodes, symmetrize=false, S = typeof(xop))
276+
F_nfft = NFFTOp(ComplexF64; shape=(N,N,N), nodes=nodes, S = typeof(xop))
277277

278278
# test agains FourierOperators
279279
y = vec( ifftshift(reshape(F*vec(fftshift(x)),N,N,N)) )

0 commit comments

Comments
 (0)