Skip to content

Commit

Permalink
Add area method and clean tests using deg2rad(1) (#42)
Browse files Browse the repository at this point in the history
* area1

* area scale

* |Diff|

* volume1

* deg2rad

* cover

* clean todo
  • Loading branch information
JeffFessler authored Aug 4, 2022
1 parent ecffa88 commit bbac39c
Show file tree
Hide file tree
Showing 27 changed files with 65 additions and 59 deletions.
2 changes: 1 addition & 1 deletion docs/lit/examples/02-ellipse.jl
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ p3 = jim(axesf(ig), sp.(spectrum_fft), "log10|DFT|"; clim, xlabel, ylabel)
err = maximum(abs, spectrum_exact - spectrum_fft) / maximum(abs, spectrum_exact)
@assert err < 2e-2
p4 = jim(axesf(ig), 1e3*abs.(spectrum_fft - spectrum_exact),
"Difference × 10³"; xlabel, ylabel)
"|Difference| × 10³"; xlabel, ylabel)
jim(p1, p4, p2, p3)


Expand Down
4 changes: 2 additions & 2 deletions docs/lit/examples/03-rect.jl
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ p3 = jim(axesf(ig), sp.(spectrum_fft), "log10|DFT|"; clim, xlabel, ylabel)
err = maximum(abs, spectrum_exact - spectrum_fft) / maximum(abs, spectrum_exact)
@assert err < 2e-2
p4 = jim(axesf(ig), 1e3*abs.(spectrum_fft - spectrum_exact),
"Difference × 10³"; xlabel, ylabel)
"|Difference| × 10³"; xlabel, ylabel)
jim(p1, p4, p2, p3)


Expand All @@ -125,7 +125,7 @@ dr = 0.2mm # radial sample spacing
nr = 2^10 # radial sinogram bins
r = (-nr÷2:nr÷2-1) * dr # radial samples
fr = (-nr÷2:nr÷2-1) / nr / dr # corresponding spectral axis
ϕ = deg2rad.(0:180) # * Unitful.rad # todo round unitful Unitful.°
ϕ = deg2rad.(0:180)
sino = radon(ob).(r, ϕ') # sample Radon transform of a single shape object
smax = ob.value * sqrt(sum(abs2, maximum(width)))
p5 = jim(r, rad2deg.(ϕ), sino; title="sinogram",
Expand Down
4 changes: 2 additions & 2 deletions docs/lit/examples/04-gauss.jl
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ p3 = jim(axesf(ig), sp.(spectrum_fft), "log10|DFT|"; clim, xlabel, ylabel)
err = maximum(abs, spectrum_exact - spectrum_fft) / maximum(abs, spectrum_exact)
@assert err < 4e-4
p4 = jim(axesf(ig), 1e3*abs.(spectrum_fft - spectrum_exact),
"Difference × 10³"; xlabel, ylabel)
"|Difference| × 10³"; xlabel, ylabel)
jim(p1, p4, p2, p3)


Expand All @@ -127,7 +127,7 @@ dr = 0.2mm # radial sample spacing
nr = 2^10 # radial sinogram bins
r = (-nr÷2:nr÷2-1) * dr # radial samples
fr = (-nr÷2:nr÷2-1) / nr / dr # corresponding spectral axis
ϕ = deg2rad.(0:180) # * Unitful.rad # todo round unitful Unitful.°
ϕ = deg2rad.(0:180)
sino = radon(ob).(r, ϕ') # sample Radon transform of a single shape object
smax = ob.value * IP.fwhm2spread(50mm)
p5 = jim(r, rad2deg.(ϕ), sino; title="sinogram",
Expand Down
4 changes: 2 additions & 2 deletions docs/lit/examples/05-triangle.jl
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ p3 = jim(axesf(ig), sp.(spectrum_fft), "log10|DFT|"; clim, xlabel, ylabel)
err = maximum(abs, spectrum_exact - spectrum_fft) / maximum(abs, spectrum_exact)
@assert err < 2e-2
p4 = jim(axesf(ig), 1e3*abs.(spectrum_fft - spectrum_exact),
"Difference × 10³"; xlabel, ylabel)
"|Difference| × 10³"; xlabel, ylabel)
jim(p1, p4, p2, p3)


Expand All @@ -130,7 +130,7 @@ dr = 0.2mm # radial sample spacing
nr = 2^10 # radial sinogram bins
r = (-nr÷2:nr÷2-1) * dr # radial samples
fr = (-nr÷2:nr÷2-1) / nr / dr # corresponding spectral axis
ϕ = deg2rad.(0:180) # * Unitful.rad # todo round unitful Unitful.°
ϕ = deg2rad.(0:180)
sino = radon(ob).(r, ϕ') # sample Radon transform of a single shape object
smax = ob.value * sqrt((width[1]/2)^2 + (width[2] * sqrt(3) / 2)^2)
p5 = jim(r, rad2deg.(ϕ), sino; title="sinogram",
Expand Down
4 changes: 2 additions & 2 deletions docs/lit/examples/32-ellipsoid.jl
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ vols = round.(((p -> sum(p)*prod(pg.deltas)).(proj2)..., volume) ./ 1mm^3; digi

# Look at a set of projections as the views orbit around the object.
ϕd = 0:6:360
ϕs = deg2rad.(ϕd) # * Unitful.rad # todo round unitful Unitful.°
ϕs = deg2rad.(ϕd)
θs = :(π/7)
θ = eval(θs)
projs = radon(axes(pg)..., ϕs, [θ], [ob]) # many projection views
Expand Down Expand Up @@ -221,7 +221,7 @@ p8 = jim(axesf(pg), sp.(proj_fft); prompt=false,
err = maximum(abs, spectrum_slice - proj_fft) / maximum(abs, spectrum_slice)
@assert err < 1e-3
p9 = jim(axesf(pg), 1e3*abs.(proj_fft - spectrum_slice);
title="Difference × 10³", xlabel, ylabel, prompt=false)
title="|Difference| × 10³", xlabel, ylabel, prompt=false)
jim(p6, p7, p8, p9)


Expand Down
4 changes: 2 additions & 2 deletions docs/lit/examples/33-cuboid.jl
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ vols = round.(((p -> sum(p)*prod(pg.deltas)).(proj3)..., volume) ./ 1mm^3; digit

# Look at a set of projections as the views orbit around the object.
ϕd = 0:6:360
ϕs = deg2rad.(ϕd) # * Unitful.rad # todo round unitful Unitful.°
ϕs = deg2rad.(ϕd)
θs = :(π/7)
θ = eval(θs)
projs = radon(axes(pg)..., ϕs, [θ], [ob]) # many projection views
Expand Down Expand Up @@ -224,7 +224,7 @@ p8 = jim(axesf(pg), sp.(proj_fft); prompt=false,
err = maximum(abs, spectrum_slice - proj_fft) / maximum(abs, spectrum_slice)
@assert err < 2e-3
p9 = jim(axesf(pg), 1e6*abs.(proj_fft - spectrum_slice);
title="Difference × 10⁶", xlabel, ylabel, prompt=false)
title="|Difference| × 10⁶", xlabel, ylabel, prompt=false)
jim(p6, p7, p8, p9)


Expand Down
6 changes: 3 additions & 3 deletions docs/lit/examples/34-gauss3.jl
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ p3 = jim(axesf(ig), sp.(spectrum_fft), "log10|DFT|"; clim, xlabel, ylabel)
err = maximum(abs, spectrum_exact - spectrum_fft) / maximum(abs, spectrum_exact)
@assert err < 1e-3
p4 = jim(axesf(ig), 1e3*abs.(spectrum_fft - spectrum_exact);
title="Difference × 10³", xlabel, ylabel)
title="|Difference| × 10³", xlabel, ylabel)
jim(p1, p4, p2, p3)


Expand Down Expand Up @@ -167,7 +167,7 @@ vols = round.(((p -> sum(p)*prod(pg.deltas)).(proj2)..., volume) ./ 1mm^3; digit

# Look at a set of projections as the views orbit around the object.
ϕd = 0:6:360
ϕs = deg2rad.(ϕd) # * Unitful.rad # todo round unitful Unitful.°
ϕs = deg2rad.(ϕd)
θs = :(π/7)
θ = eval(θs)
projs = radon(axes(pg)..., ϕs, [θ], [ob]) # many projection views
Expand Down Expand Up @@ -221,7 +221,7 @@ p8 = jim(axesf(pg), sp.(proj_fft); prompt=false,
err = maximum(abs, spectrum_slice - proj_fft) / maximum(abs, spectrum_slice)
@assert err < 1e-5
p9 = jim(axesf(pg), 1e6*abs.(proj_fft - spectrum_slice);
title="Difference × 10⁶", xlabel, ylabel, prompt=false)
title="|Difference| × 10⁶", xlabel, ylabel, prompt=false)
jim(p6, p7, p8, p9)


Expand Down
4 changes: 2 additions & 2 deletions docs/lit/examples/35-cylinder.jl
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ vols = round.(((p -> sum(p)*prod(pg.deltas)).(proj3)..., volume) ./ 1mm^3; digit

# Look at a set of projections as the views orbit around the object.
ϕd = 0:6:360
ϕs = deg2rad.(ϕd) # * Unitful.rad # todo round unitful Unitful.°
ϕs = deg2rad.(ϕd)
θs = :(π/7)
θ = eval(θs)
projs = radon(axes(pg)..., ϕs, [θ], [ob]) # many projection views
Expand Down Expand Up @@ -224,7 +224,7 @@ p8 = jim(axesf(pg), sp.(proj_fft); prompt=false,
err = maximum(abs, spectrum_slice - proj_fft) / maximum(abs, spectrum_slice)
@assert err < 1e-3
p9 = jim(axesf(pg), 1e3*abs.(proj_fft - spectrum_slice);
title="Difference × 10³", xlabel, ylabel, prompt=false)
title="|Difference| × 10³", xlabel, ylabel, prompt=false)
jim(p6, p7, p8, p9)


Expand Down
2 changes: 1 addition & 1 deletion src/cuboid.jl
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ end
# methods


volume(ob::Object3d{Cuboid}) = prod(ob.width)
volume1(::Cuboid) = 1 # volume of unit cube


"""
Expand Down
2 changes: 1 addition & 1 deletion src/cylinder.jl
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ cylinder(args... ; kwargs...) = Object(Cylinder(), args...; kwargs...)
# methods


volume(ob::Object3d{Cylinder}) = π * prod(ob.width[1:2]) * ob.width[3]
volume1(::Cylinder) = π


"""
Expand Down
3 changes: 3 additions & 0 deletions src/ellipse.jl
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ end
# methods


area1(::Ellipse) = π # area of unit circle


"""
phantom1(ob::Object2d{Ellipse}, (x,y))
Evaluate unit circle at `(x,y)`,
Expand Down
2 changes: 1 addition & 1 deletion src/ellipsoid.jl
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ end
# methods


volume(ob::Object3d{Ellipsoid}) = 4/3 * π * prod(ob.width)
volume1(::Ellipsoid) = 4/3 * π # volume of unit sphere


"""
Expand Down
3 changes: 3 additions & 0 deletions src/gauss2.jl
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ Convert FWHM `w` to equivalent Gaussian spread `s` for ``\\exp(-π (x/s)^2)``.
# methods


area1(::Gauss2) = fwhm2spread(1)^2


"""
phantom1(ob::Object2d{Gauss2}, (x,y))
Evaluate unit gauss2 at `(x,y)`,
Expand Down
2 changes: 1 addition & 1 deletion src/gauss3.jl
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ gauss3(args... ; kwargs...) = Object(Gauss3(), args...; kwargs...)
# methods


volume(ob::Object3d{Gauss3}) = fwhm2spread(1)^3 * prod(ob.width)
volume1(::Gauss3) = fwhm2spread(1)^3


"""
Expand Down
3 changes: 3 additions & 0 deletions src/object2.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ Utilities for 2D objects
export phantom, radon, spectrum


area(ob::Object2d{S}) where S = area1(S()) * prod(ob.width)


# rotate

"""
Expand Down
3 changes: 3 additions & 0 deletions src/object3.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ using LazyGrids: ndgrid
export phantom, radon, spectrum


volume(ob::Object3d{S}) where S = volume1(S()) * prod(ob.width)


# rotate

"""
Expand Down
3 changes: 3 additions & 0 deletions src/rect.jl
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ end
# methods


area1(::Rect) = 1 # area of unit square


"""
phantom1(ob::Object2d{Rect}, (x,y))
Evaluate unit square at `(x,y)`,
Expand Down
3 changes: 3 additions & 0 deletions src/triangle.jl
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,9 @@ end
# methods


area1(::Triangle) = sqrt(3)/4 # area of unit base equilateral


"""
phantom1(ob::Object2d{Triangle}, (x,y))
Evaluate unit triangle at `(x,y)`,
Expand Down
3 changes: 2 additions & 1 deletion test/cuboid.jl
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,8 @@ end
v = (-nv÷2:nv÷2-1) * dv
fu = (-nu÷2:nu÷2-1) / nu / du
fv = (-nv÷2:nv÷2-1) / nv / dv
ϕ = deg2rad.(0:6:180) # * Unitful.rad # todo round unitful Unitful.°
# ϕ = (0:6:180) * deg2rad(1)
ϕ = deg2rad.(0:6:180) # helps coverage of "abs(e2) < eps(T)"
θ =/7]
sino = @inferred radon(u, v, ϕ, θ, [ob])

Expand Down
7 changes: 2 additions & 5 deletions test/cylinder.jl
Original file line number Diff line number Diff line change
Expand Up @@ -141,12 +141,9 @@ end
v = (-nv÷2:nv÷2-1) * dv
fu = (-nu÷2:nu÷2-1) / nu / du
fv = (-nv÷2:nv÷2-1) / nv / dv
ϕ = deg2rad.(0:6:180) # * Unitful.rad # todo round unitful Unitful.°
ϕ = (0:30:180) * deg2rad(1)
θ =/7]
sino = @inferred radon(u, v, ϕ, θ, [ob])

#=
todo projection slice
=#

# todo projection slice
end
7 changes: 3 additions & 4 deletions test/ellipse.jl
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ end
for ob in obs
nr, dr = 2^4, 0.02m
r = (-nr÷2:nr÷2-1) * dr .+ ob.center[1]
ϕ = deg2rad.(0:20:360)
ϕ = (0:30:360) * deg2rad(1)
@inferred IP._radon(ob, r[1], ϕ[1])
sino1 = @inferred radon([r[1]], [ϕ[1]], [ob])
sino = @inferred radon(r, ϕ, [ob])
Expand All @@ -118,7 +118,7 @@ end
ob = shape((4m, 3m), radii, π/6, 1.0f0)
img = @inferred phantom(x, y, [ob])

zscale = 1 / π / prod(radii) # normalize spectra by area
zscale = 1 / (ob.value * IP.area(ob)) # normalize spectra by area
fx = (-M÷2:M÷2-1) / M / dx
fy = (-N÷2:N÷2-1) / N / dy
X = myfft(img) * dx * dy * zscale
Expand All @@ -145,8 +145,7 @@ end
nr = 2^10
r = (-nr÷2:nr÷2-1) * dr
fr = (-nr÷2:nr÷2-1) / nr / dr
ϕ = deg2rad.(0:360) # * Unitful.rad # todo round unitful Unitful.°
# ϕ = deg2rad.((0:360)°) # not yet due to Unitful issue
ϕ = (0:30:360) * deg2rad(1)
sino = @inferred radon(r, ϕ, [ob])

ia = argmin(abs.(ϕ .- deg2rad(55)))
Expand Down
2 changes: 1 addition & 1 deletion test/ellipsoid.jl
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ end
v = (-nv÷2:nv÷2-1) * dv
fu = (-nu÷2:nu÷2-1) / nu / du
fv = (-nv÷2:nv÷2-1) / nv / dv
ϕ = deg2rad.(0:6:180) # * Unitful.rad # todo round unitful Unitful.°
ϕ = (0:30:180) * deg2rad(1)
θ =/7]
sino = @inferred radon(u, v, ϕ, θ, [ob])

Expand Down
5 changes: 2 additions & 3 deletions test/gauss2.jl
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ end
ob = shape((2m, 3m), width, π/6, 1.0f0)
img = @inferred phantom(x, y, [ob])

zscale = 1 / IP.fwhm2spread(1)^2 / prod(width) # normalize spectra by area
zscale = 1 / (ob.value * IP.area(ob)) # normalize spectra by area
fx = (-M÷2:M÷2-1) / M / dx
fy = (-N÷2:N÷2-1) / N / dy
X = myfft(img) * dx * dy * zscale
Expand All @@ -135,8 +135,7 @@ end
nr = 2^10
r = (-nr÷2:nr÷2-1) * dr
fr = (-nr÷2:nr÷2-1) / nr / dr
ϕ = deg2rad.(0:360) # * Unitful.rad # todo round unitful Unitful.°
# ϕ = deg2rad.((0:180)°) # not yet due to Unitful issue
ϕ = (0:30:360) * deg2rad(1)
sino = @NOTinferred radon(r, ϕ, [ob])

ia = argmin(abs.(ϕ .- deg2rad(55)))
Expand Down
4 changes: 2 additions & 2 deletions test/gauss3.jl
Original file line number Diff line number Diff line change
Expand Up @@ -138,11 +138,11 @@ end
v = (-nv÷2:nv÷2-1) * dv
fu = (-nu÷2:nu÷2-1) / nu / du
fv = (-nv÷2:nv÷2-1) / nv / dv
ϕ = deg2rad.(0:6:180) # * Unitful.rad # todo round unitful Unitful.°
ϕ = (0:30:180) * deg2rad(1)
θ =/7]
sino = @inferred radon(u, v, ϕ, θ, [ob])
end

#=
todo projection slice
=#
end
5 changes: 2 additions & 3 deletions test/rect.jl
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ end
ob = shape((4m, 3m), width, π/6, 1.0f0)
img = @inferred phantom(x, y, [ob])

zscale = 1 / prod(width) # normalize spectra by area
zscale = 1 / (ob.value * IP.area(ob)) # normalize spectra by area
fx = (-M÷2:M÷2-1) / M / dx
fy = (-N÷2:N÷2-1) / N / dy
X = myfft(img) * dx * dy * zscale
Expand All @@ -125,8 +125,7 @@ end
nr = 2^10
r = (-nr÷2:nr÷2-1) * dr
fr = (-nr÷2:nr÷2-1) / nr / dr
ϕ = deg2rad.(0:360) # * Unitful.rad # todo round unitful Unitful.°
# ϕ = deg2rad.((0:360)°) # not yet due to Unitful issue
ϕ = (0:30:360) * deg2rad(1)
sino = @inferred radon(r, ϕ, [ob])

ia = argmin(abs.(ϕ .- deg2rad(55)))
Expand Down
Loading

2 comments on commit bbac39c

@JeffFessler
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator() register

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request updated: JuliaRegistries/General/65594

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v0.2.0 -m "<description of version>" bbac39ce8dbdaef6085f03ff515094973e5ab54f
git push origin v0.2.0

Please sign in to comment.