Skip to content

Commit 3f3c8f1

Browse files
authored
Merge branch 'main' into fractiona_fourier_transform
2 parents bc0359c + 0c2de4f commit 3f3c8f1

22 files changed

+612
-74
lines changed

Project.toml

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "FourierTools"
22
uuid = "b18b359b-aebc-45ac-a139-9c0ccbb2871e"
33
authors = ["Felix Wechsler (roflmaostc) <[email protected]>", "rheintzmann <[email protected]>"]
4-
version = "0.3.2"
4+
version = "0.3.7"
55

66
[deps]
77
ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4"
@@ -11,19 +11,22 @@ LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
1111
NDTools = "98581153-e998-4eef-8d0d-5ec2c052313d"
1212
NFFT = "efe261a4-0d2b-5849-be55-fc731d526b0d"
1313
PaddedViews = "5432bcbf-9aad-5242-b902-cca2824c8663"
14+
Reexport = "189a3867-3050-52da-a836-e630ba90ab69"
1415
ShiftedArrays = "1277b4bf-5013-50f5-be3d-901d8477a67a"
1516

1617
[compat]
17-
ChainRulesCore = "0.9, 0.10, 1.0, 1.1, 1"
18+
19+
ChainRulesCore = "1, 1.0, 1.1"
1820
FFTW = "1.5"
19-
ImageTransformations = "0.8.12"
21+
ImageTransformations = "0.9"
2022
IndexFunArrays = "0.2"
21-
NDTools = "0.4.2"
22-
NFFT = "0.11, 0.12"
23-
PaddedViews = "0.5.8"
24-
ShiftedArrays = "1"
23+
NDTools = "0.5.1"
24+
NFFT = "0.11, 0.12, 0.13"
25+
PaddedViews = "0.5"
26+
Reexport = "1"
27+
ShiftedArrays = "2"
2528
Zygote = "0.6"
26-
julia = "1.6, 1.7"
29+
julia = "1, 1.6, 1.7, 1.8"
2730

2831
[extras]
2932
FractionalTransforms = "e50ca838-b4f0-4a10-ad18-4b920bf1ae5c"

README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,25 @@ The main features are:
2727
* array/image rotation
2828
* array/image shifting (including noteworthy subpixel shifts)
2929
* array/image shearing
30+
* convenient wrappers of [NFFT.jl](https://github.com/JuliaMath/NFFT.jl)
3031
* several tools like `ffts`, `ft`, `fftshift_view` etc. allowing simpler use with Fourier transforms
3132
* Chirp Z-Transform
3233
* Fractional Fourier Transform
34+
* reexports [FFTW.jl](https://github.com/JuliaMath/FFTW.jl)
3335

3436
Have a look in the [examples folder](examples/) for interactive examples. The [documentation](https://bionanoimaging.github.io/FourierTools.jl/dev/) offers a quick overview.
3537

3638
## FFTW Threading
3739
By default we set 4 Threads. Use `FFTW.set_num_threads(N)` to set `N` threads.
3840

3941

42+
43+
## Related Packages
44+
There are numerous packages related to Fourier transforms which offer similar functions or which this package is based on:
45+
* [FFTW.jl](https://github.com/JuliaMath/FFTW.jl) for FFTs
46+
* [NFFT.jl](https://github.com/JuliaMath/NFFT.jl) for non-uniform FFTs
47+
* [FractionalTransforms.jl](https://github.com/SciFracX/FractionalTransforms.jl) offers 1D fractional Fourier transforms
48+
4049
## Cite
4150
If you use this package in an academic work, please cite us!
4251
See on the right side the *Cite this repository*:
@@ -47,6 +56,9 @@ title = {FourierTools.jl - Efficiently Working with Fourier Space},
4756
url = {https://github.com/bionanoimaging/FourierTools.jl}}
4857
```
4958

59+
## Development
60+
Feel free to file an issue regarding problems, suggestions or improvement ideas for this package!
61+
5062

5163
[docs-dev-img]: https://img.shields.io/badge/docs-dev-pink.svg
5264
[docs-dev-url]: https://bionanoimaging.github.io/FourierTools.jl/dev/

docs/make.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,12 @@ makedocs(modules = [FourierTools],
77
pages = Any[
88
"FourierTools.jl" => "index.md",
99
"FFT Helpers" => "helpers.md",
10-
"FFT Based Convolutions" => "convolutions.md",
10+
"FFT Based Convolutions and Cross-Correlation" => "convolutions.md",
1111
"Resampling (sinc Interpolation)" => "resampling.md",
1212
"Shifting with FFTs" => "shifting.md",
1313
"Image Shearing with FFTs" => "shear.md",
1414
"Image Rotation with FFTs" => "rotate.md",
15+
"NFFT" => "nfft.md",
1516
"Utility Functions" => "utils.md",
1617
]
1718
)

docs/src/convolutions.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
## Function References
22
```@docs
33
conv
4+
ccorr
45
conv_psf
56
plan_conv
67
plan_conv_psf

docs/src/helpers.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@ ffts!
55
iffts
66
rffts
77
irffts
8-
fftshift!
9-
ifftshift!
108
FourierTools.fftshift_view
119
FourierTools.ifftshift_view
1210
FourierTools.rfftshift_view

docs/src/nfft.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# NFFT helpers
2+
Based on [NFFT.jl](https://github.com/JuliaMath/NFFT.jl) we provide some convenient helper functions:
3+
4+
```@docs
5+
FourierTools.nfft_nd
6+
FourierTools.plan_nfft_nd
7+
```

docs/src/utils.md

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,4 @@ FourierTools.select_region
66
FourierTools.center_set!
77
FourierTools.get_indices_around_center
88
FourierTools.center_extract
9-
FourierTools.selectsizes
10-
FourierTools.expanddims
11-
FourierTools.slice
12-
FourierTools.slice_indices
139
```

src/FourierTools.jl

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,32 @@
11
module FourierTools
22

3+
4+
using Reexport
35
using PaddedViews, ShiftedArrays
4-
using FFTW
5-
FFTW.set_num_threads(4)
6+
@reexport using FFTW
67
using LinearAlgebra
78
using IndexFunArrays
89
using ChainRulesCore
910
using NDTools
10-
using NFFT
11+
@reexport using NFFT
12+
FFTW.set_num_threads(4)
13+
14+
1115

1216
include("utils.jl")
1317
include("nfft_nd.jl")
1418
include("resampling.jl")
1519
include("custom_fourier_types.jl")
1620
include("fourier_resizing.jl")
1721
include("fourier_shifting.jl")
22+
include("fourier_filtering.jl")
1823
include("fourier_resample_1D_based.jl")
1924
include("fourier_rotate.jl")
2025
include("fourier_shear.jl")
2126
include("fftshift_alternatives.jl")
2227
include("fft_helpers.jl")
2328
include("convolutions.jl")
29+
include("correlations.jl")
2430
include("damping.jl")
2531
include("czt.jl")
2632
include("fractional_fourier_transform.jl")

src/convolutions.jl

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -136,18 +136,23 @@ function plan_conv(u::AbstractArray{T1, N}, v::AbstractArray{T2, M}, dims=ntuple
136136
# FFTW.MEASURE flag might overwrite input! Hence copy!
137137
if (:flags in keys(kwargs) &&
138138
(getindex(kwargs, :flags) == FFTW.MEASURE || getindex(kwargs, :flags) == FFTW.PATIENT))
139-
P = plan(copy(u), dims; kwargs...)
139+
plan(copy(u), dims; kwargs...)
140140
else
141-
P = plan(u, dims; kwargs...)
141+
plan(u, dims; kwargs...)
142142
end
143143
end
144-
P_inv = inv(P)
145144

146145
v_ft = fft_or_rfft(T1)(v, dims)
147146
# construct the efficient conv function
148147
# P and P_inv can be understood like matrices
149148
# but their computation is fast
150-
conv(u, v_ft=v_ft) = p_conv_aux(P, P_inv, u, v_ft)
149+
conv = let P = P,
150+
P_inv = inv(P),
151+
# put a different name here! See https://discourse.julialang.org/t/type-issue-with-captured-variables-let-workaround-failed/85661
152+
v_ft = v_ft
153+
conv(u, v_ft=v_ft) = p_conv_aux(P, P_inv, u, v_ft)
154+
end
155+
151156
return v_ft, conv
152157
end
153158

@@ -211,9 +216,7 @@ function plan_conv_psf(u::AbstractArray{T, N}, psf::AbstractArray{T, M}, dims=nt
211216
end
212217

213218
function p_conv_aux(P, P_inv, u, v_ft)
214-
tmp = (P_inv.p * ((P * u) .* v_ft))
215-
tmp .*= P_inv.scale
216-
return tmp
219+
return (P_inv.p * ((P * u) .* v_ft .* P_inv.scale))
217220
end
218221

219222
function ChainRulesCore.rrule(::typeof(p_conv_aux), P, P_inv, u, v)

src/correlations.jl

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
export ccorr
2+
3+
4+
"""
5+
ccorr(u, v[, dims]; centered=false)
6+
7+
Calculates the cross-correlation between `u` and `v` along `dims`.
8+
`centered=true` moves the output of the cross-correlation to the Fourier center.
9+
10+
If `u` and `v` are both a real valued array we use `rfft` and hence
11+
the output is real as well.
12+
If either `u` or `v` is complex we use `fft` and output is hence complex.
13+
14+
Per default the correlation is performed along `min(ndims(u), ndims(v))`.
15+
16+
17+
```jldoctest
18+
julia> ccorr([1,1,0,0], [1,1,0,0], centered=true)
19+
4-element Vector{Float64}:
20+
0.0
21+
1.0
22+
2.0
23+
1.0
24+
25+
julia> ccorr([1,1,0,0], [1,1,0,0])
26+
4-element Vector{Float64}:
27+
2.0
28+
1.0
29+
0.0
30+
1.0
31+
32+
julia> ccorr([1im,0,0,0], [0,1im,0,0])
33+
4-element Vector{ComplexF64}:
34+
0.0 + 0.0im
35+
0.0 + 0.0im
36+
0.0 + 0.0im
37+
1.0 + 0.0im
38+
39+
julia> ccorr([1im,0,0,0], [0,1im,0,0], centered=true)
40+
4-element Vector{ComplexF64}:
41+
0.0 + 0.0im
42+
1.0 + 0.0im
43+
0.0 + 0.0im
44+
0.0 + 0.0im
45+
```
46+
"""
47+
function ccorr(u::AbstractArray{T, N}, v::AbstractArray{D, M},
48+
dims=ntuple(+, min(N, M));
49+
centered=false) where {T, D, N, M}
50+
out = ifft(fft(u, dims) .* conj.(fft(v, dims)), dims)
51+
52+
if centered
53+
return fftshift(out)
54+
else
55+
return out
56+
end
57+
end
58+
59+
function ccorr(u::AbstractArray{<:Real, N}, v::AbstractArray{<:Real, M},
60+
dims=ntuple(+, min(N, M));
61+
centered=false) where {N, M}
62+
out = irfft(rfft(u, dims) .* conj.(rfft(v, dims)), size(u, dims[1]), dims)
63+
64+
if centered
65+
return fftshift(out)
66+
else
67+
return out
68+
end
69+
end

0 commit comments

Comments
 (0)