Skip to content

Commit ed697de

Browse files
authored
Use helpers instead of getproperty (#47)
* Improve short CBCT demo * Use getfield for show * WIP to remove getproperty * Use helpers * update docs * view weight * Use parker_weight * Coverage * Simply fbp_ramp * Fix ds bug * Test _tau * v0.4.0 * Use _ds * Fix ramp * Move _tau, improve coverage * Refine DocTestSetup for import * Setup view_weights, improve type inference, typeof * Test _angle_weights * Update logo code * Update tests * Hide jim * fft units * Type stable fbp_sino_filt * Remove helper.jl * window type inference * fft_filter units and type inference * fbp2 type inference * Remove sino_filt * Test stack of sinos
1 parent 65fafe8 commit ed697de

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+1469
-1517
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "Sinograms"
22
uuid = "02a14def-c6e6-4ab0-b2df-0ab64bc8cdd7"
33
authors = ["fessler <[email protected]>"]
4-
version = "0.3.0"
4+
version = "0.4.0"
55

66
[deps]
77
FFTW = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341"

docs/lit/examples/02-sino-geom.jl

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ This page was generated from a single Julia file:
2727
using Unitful: mm, °
2828
using Plots # these 2 must precede 'using Sinograms' for sino_plot_rays to work
2929
using Sinograms: SinoPar, SinoMoj, SinoFanArc, SinoFanFlat, SinoFan
30-
using Sinograms: sino_plot_rays, rays
30+
using Sinograms: sino_plot_rays, rays, angles
3131
using MIRTjim: jim, prompt
3232
using InteractiveUtils: versioninfo
3333

@@ -95,7 +95,7 @@ Everything is a named keyword argument with sensible default values.
9595
`orbit_start + (0:(nb-1))/nb * orbit`.
9696
=#
9797

98-
sg = SinoPar( ;
98+
rg = SinoPar( ;
9999
nb = 64, # number of radial samples ("bins")
100100
na = 30, # number of angular samples
101101
d = 2mm, # detector spacing
@@ -105,20 +105,20 @@ sg = SinoPar( ;
105105
)
106106

107107
#=
108-
The struct `sg` has numerous useful properties;
108+
The struct `rg` has numerous useful properties;
109109
type `?SinoGeom` to see the full list.
110110
111111
For example,
112112
to access the angular samples in degrees
113-
type `sg.ad`
113+
type `angles(rg)`
114114
=#
115115

116-
sg.ad
116+
angles(rg)
117117

118118

119119
# The following function visualizes the sampling pattern.
120120

121-
sino_plot_rays(sg; ylims=(0,180), yticks=(0:90:180), widen=true, title="Parallel")
121+
sino_plot_rays(rg; ylims=(0,180), yticks=(0:90:180), widen=true, title="Parallel")
122122

123123
#
124124
prompt()
@@ -144,15 +144,15 @@ These numbers are published in
144144
[IEEE T-MI Oct. 2006, p.1272-1283](http://doi.org/10.1109/TMI.2006.882141).
145145
=#
146146

147-
sg = SinoFanArc( ; nb=888, na=984,
147+
rg = SinoFanArc( ; nb=888, na=984,
148148
d=1.0239mm, offset=1.25, dsd=949.075mm, dod=408.075mm)
149149

150150

151151
# Here is a smaller example for plotting the rays.
152152

153-
sg = SinoFanArc( ; nb=64, na=30,
153+
rg = SinoFanArc( ; nb=64, na=30,
154154
d=20mm, offset=0.25, dsd=900mm, dod=400mm)
155-
sino_plot_rays(sg; ylims=(-50,400), yticks=(0:180:360), widen=true,
155+
sino_plot_rays(rg; ylims=(-50,400), yticks=(0:180:360), widen=true,
156156
title="Fan-beam for arc detector")
157157

158158
#
@@ -166,12 +166,12 @@ This geometry is the same as the arc detector
166166
except that `dfs=Inf`.
167167
=#
168168

169-
sg = SinoFanFlat( ; nb=64, na=30,
169+
rg = SinoFanFlat( ; nb=64, na=30,
170170
d=20mm, offset=0.25, dsd=900mm, dod=400mm)
171171

172172

173173
# Here is its sampling plot
174-
sino_plot_rays(sg; ylims=(-50,400), yticks=(0:180:360), widen=true,
174+
sino_plot_rays(rg; ylims=(-50,400), yticks=(0:180:360), widen=true,
175175
title="Fan-beam for flat detector")
176176

177177
#
@@ -184,10 +184,10 @@ This is a specialized sampling geometry
184184
that is currently incompletely supported.
185185
=#
186186

187-
sg = SinoMoj( ; nb=60, na=30)
187+
rg = SinoMoj( ; nb=60, na=30)
188188

189189
# Here is its sampling plot
190-
sino_plot_rays(sg; ylims=(0,180), yticks=(0:90:180), widen=true,
190+
sino_plot_rays(rg; ylims=(0,180), yticks=(0:90:180), widen=true,
191191
title="Mojette sampling")
192192

193193
#=
@@ -212,7 +212,7 @@ plot_ray!(r, ϕ) = plot!(
212212
color = :blue,
213213
)
214214
ia = 4 # pick an angle
215-
i = rays(sg) # iterator
215+
i = rays(rg) # iterator
216216
rs = [i[1] for i in i] # radial samples
217217
ϕs = [i[2] for i in i] # projection angle
218218
r = rs[:,ia]

docs/lit/examples/03-parallel-beam.jl

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ This page was generated from a single Julia file:
2424

2525
# Packages needed here.
2626

27-
using Sinograms: SinoPar, rays, plan_fbp, fbp
27+
using Sinograms: SinoPar, rays, plan_fbp, fbp, fbp_sino_filter
2828
using ImageGeoms: ImageGeom, fovs, MaskCircle
2929
using ImagePhantoms: SheppLogan, shepp_logan, radon, phantom
3030
using Unitful: mm
@@ -55,22 +55,22 @@ but units are optional.
5555
ig = ImageGeom(MaskCircle(); dims=(128,126), deltas = (2mm,2mm) )
5656

5757
# Use `SinoPar` to define the sinogram geometry.
58-
sg = SinoPar( ; nb = 130, d = 2mm, na = 100)
58+
rg = SinoPar( ; nb = 130, d = 2mm, na = 100)
5959

6060
# Ellipse parameters for Shepp-Logan phantom:
6161
μ = 0.01 / mm # typical linear attenuation coefficient
6262
ob = shepp_logan(SheppLogan(); fovs = fovs(ig), u = (1, 1, μ))
6363

6464
# Radon transform of Shepp-Logan phantom:
65-
sino = radon(rays(sg), ob)
66-
jim(axes(sg), sino; title="Shepp-Logan sinogram", xlabel="r", ylabel="ϕ")
65+
sino = radon(rays(rg), ob)
66+
jim(axes(rg), sino; title="Shepp-Logan sinogram", xlabel="r", ylabel="ϕ")
6767

6868
## Image reconstruction via FBP
6969
# Here we start with a "plan",
7070
# which would save work if we were reconstructing many images.
7171

72-
plan = plan_fbp(sg, ig)
73-
fbp_image, sino_filt = fbp(plan, sino)
72+
plan = plan_fbp(rg, ig)
73+
fbp_image = fbp(plan, sino)
7474

7575

7676
# A narrow color window is needed to see the soft tissue structures:
@@ -80,3 +80,7 @@ jim(axes(ig), fbp_image, "FBP image"; clim)
8080
# For comparison, here is the ideal phantom image
8181
true_image = phantom(axes(ig)..., ob, 2)
8282
jim(axes(ig)..., true_image, "True phantom image"; clim)
83+
84+
# For fun, here is the filtered sinogram:
85+
sino_filt = fbp_sino_filter(sino, plan.filter)
86+
jim(axes(rg), sino_filt; title="Filtered sinogram", xlabel="r", ylabel="ϕ")

docs/lit/examples/04-fan-arc.jl

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,11 @@ but units are optional.
6464
ig = ImageGeom(MaskCircle(); dims=(128,126), deltas = (2mm,2mm) )
6565

6666
# Use `SinoFanArc` to define the sinogram geometry.
67-
sg = SinoFanArc( ; nb = 130, d = 3.2mm, na = 100, dsd = 400mm, dod = 140mm)
67+
rg = SinoFanArc( ; nb = 130, d = 3.2mm, na = 100, dsd = 400mm, dod = 140mm)
6868

6969
# Examine the geometry to verify the FOV:
7070
jim(axes(ig), ig.mask; prompt=false)
71-
sino_geom_plot!(sg, ig)
71+
sino_geom_plot!(rg, ig)
7272

7373
#
7474
prompt()
@@ -78,8 +78,8 @@ prompt()
7878
ob = shepp_logan(SheppLogan(); fovs = fovs(ig), u = (1, 1, μ))
7979

8080
# Arc fan-beam sinogram for Shepp-Logan phantom:
81-
sino = radon(rays(sg), ob)
82-
jim(axes(sg), sino; title="Shepp-Logan sinogram", xlabel="r", ylabel="ϕ")
81+
sino = radon(rays(rg), ob)
82+
jim(axes(rg), sino; title="Shepp-Logan sinogram", xlabel="r", ylabel="ϕ")
8383

8484

8585
#=
@@ -88,8 +88,8 @@ Here we start with a "plan",
8888
which would save work if we were reconstructing many images.
8989
=#
9090

91-
plan = plan_fbp(sg, ig)
92-
fbp_image, sino_filt = fbp(plan, sino)
91+
plan = plan_fbp(rg, ig)
92+
fbp_image = fbp(plan, sino)
9393

9494

9595
# A narrow color window is needed to see the soft tissue structures:

docs/lit/examples/05-fan-flat.jl

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,11 @@ but units are optional.
6060
ig = ImageGeom(MaskCircle(); dims=(128,126), deltas = (0.2cm,0.2cm) )
6161

6262
# Use `SinoFanFlat` to define the sinogram geometry.
63-
sg = SinoFanFlat( ; nb = 130, d = 0.3cm, na = 100, dsd = 50cm, dod = 14cm)
63+
rg = SinoFanFlat( ; nb = 130, d = 0.3cm, na = 100, dsd = 50cm, dod = 14cm)
6464

6565
# Examine the geometry to verify the FOV:
6666
jim(axes(ig), ig.mask; prompt=false)
67-
sino_geom_plot!(sg, ig)
67+
sino_geom_plot!(rg, ig)
6868

6969
#
7070
prompt()
@@ -74,8 +74,8 @@ prompt()
7474
ob = shepp_logan(SheppLogan(); fovs = fovs(ig), u = (1, 1, μ))
7575

7676
# Arc fan-beam sinogram for Shepp-Logan phantom:
77-
sino = radon(rays(sg), ob)
78-
jim(axes(sg), sino; title="Shepp-Logan sinogram", xlabel="r", ylabel="ϕ")
77+
sino = radon(rays(rg), ob)
78+
jim(axes(rg), sino; title="Shepp-Logan sinogram", xlabel="r", ylabel="ϕ")
7979

8080

8181
#=
@@ -85,8 +85,8 @@ which would save work if we were reconstructing many images.
8585
For illustration we include `Hamming` window.
8686
=#
8787

88-
plan = plan_fbp(sg, ig; window = Window(Hamming(), 1.0))
89-
fbp_image, sino_filt = fbp(plan, sino)
88+
plan = plan_fbp(rg, ig; window = Window(Hamming(), 1.0))
89+
fbp_image = fbp(plan, sino)
9090

9191

9292
# A narrow color window is needed to see the soft tissue structures:

docs/lit/examples/06-fan-short.jl

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -74,14 +74,14 @@ Note that even though we specify `na = 100`
7474
we end up with `na = 67` views
7575
because of the `:short` option.
7676
=#
77-
sg = SinoFanArc( :short, ;
77+
rg = SinoFanArc( :short, ;
7878
nb = 130, d = 3.2mm, na = 100, dsd = 400mm, dod = 140mm,
7979
)
8080

8181
# Examine the geometry to verify the FOV.
8282
# The `na=67` blue dots show the `:short` scan.
8383
jim(axes(ig), ig.mask; prompt=false)
84-
sino_geom_plot!(sg, ig)
84+
sino_geom_plot!(rg, ig)
8585

8686
#
8787
prompt()
@@ -91,8 +91,8 @@ prompt()
9191
ob = shepp_logan(SheppLogan(); fovs = fovs(ig), u = (1, 1, μ))
9292

9393
# Short arc fan-beam sinogram for Shepp-Logan phantom:
94-
sino = radon(rays(sg), ob)
95-
jim(axes(sg), sino; title="Shepp-Logan 'short' sinogram",
94+
sino = radon(rays(rg), ob)
95+
jim(axes(rg), sino; title="Shepp-Logan 'short' sinogram",
9696
xlabel="r", ylabel="ϕ")
9797

9898

@@ -102,14 +102,14 @@ Here we start with a "plan",
102102
which would save work if we were reconstructing many images.
103103
=#
104104

105-
plan = plan_fbp(sg, ig)
105+
plan = plan_fbp(rg, ig)
106106

107107
# Examine Parker weights:
108-
jim(axes(sg), plan.parker_weight; title = "Parker weights",
108+
jim(axes(rg), plan.view_weight; title = "Parker weights",
109109
xlabel="r", ylabel="ϕ")
110110

111111
# Finally perform FBP:
112-
fbp_image, sino_filt = fbp(plan, sino);
112+
fbp_image = fbp(plan, sino);
113113

114114
# A narrow color window is needed to see the soft tissue structures:
115115
clim = (0.9, 1.1) .* μ

docs/lit/examples/07-fdk.jl

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -67,25 +67,25 @@ clim = (0.95, 1.05) .* μ
6767
# Here is the ideal phantom image:
6868
oversample = 3
6969
true_image = phantom(axes(ig)..., ob, oversample)
70-
jim(axes(ig), true_image, "True 3D Shepp-Logan phantom image"; clim)
70+
pt = jim(axes(ig), true_image, "True 3D Shepp-Logan phantom image"; clim)
7171

7272
# Define the system geometry
7373
# (for some explanation use `?CtGeom`):
7474
p = (ns = 130, ds = 0.3cm, nt = 80, dt = 0.4cm, na = 50, dsd = 200cm, dod = 40cm)
75-
cg = CtFanArc( ; p...)
75+
rg = CtFanArc( ; p...)
7676

7777
# Examine the geometry to verify the FOV
7878
# (this is more interesting when interacting via other Plot backends):
79-
ct_geom_plot3(cg, ig)
79+
ct_geom_plot3(rg, ig)
8080

8181
#
8282
prompt()
8383

8484

8585
# CBCT projections
8686
# using `Sinogram.rays` and `ImagePhantoms.radon`:
87-
proj_arc = radon(rays(cg), ob)
88-
jim(cg.s, cg.t, proj_arc ;
87+
proj_arc = radon(rays(rg), ob)
88+
pa = jim(axes(rg)[1:2], proj_arc ;
8989
title="Shepp-Logan projections (arc)", xlabel="s", ylabel="t")
9090

9191

@@ -103,31 +103,32 @@ which would save work if we were reconstructing many images.
103103
For illustration we include `Hamming` window.
104104
=#
105105

106-
plan = plan_fbp(cg, ig; window = Window(Hamming(), 1.0))
106+
plan = plan_fbp(rg, ig; window = Window(Hamming(), 1.0))
107107
fdk_arc = fdk(plan, proj_arc)
108-
jim(axes(ig), fdk_arc, "FDK image (arc)"; clim)
108+
par = jim(axes(ig), fdk_arc, "FDK image (arc)"; clim)
109109

110110
#
111111
err_arc = fdk_arc - true_image
112-
jim(axes(ig), err_arc, "Error image (arc)"; clim = (-1,1) .* (0.05μ))
112+
elim = (-1,1) .* (0.02μ)
113+
pae = jim(axes(ig), err_arc, "Error image (arc)"; clim = elim)
113114

114115

115116
#=
116117
## Repeat with flat detector geometry
117118
=#
118119

119-
cg = CtFanFlat( ; p...)
120-
proj_flat = radon(rays(cg), ob)
121-
jim(cg.s, cg.t, proj_flat ;
120+
rg = CtFanFlat( ; p...)
121+
proj_flat = radon(rays(rg), ob)
122+
pfp = jim(axes(rg)[1:2], proj_flat ;
122123
title="Shepp-Logan projections (flat)", xlabel="s", ylabel="t")
123124

124-
plan = plan_fbp(cg, ig; window = Window(Hamming(), 1.0))
125+
plan = plan_fbp(rg, ig; window = Window(Hamming(), 1.0))
125126
fdk_flat = fdk(plan, proj_flat)
126-
jim(axes(ig), fdk_flat, "FDK image (flat)"; clim)
127+
pfr = jim(axes(ig), fdk_flat, "FDK image (flat)"; clim)
127128

128129
#
129130
err_flat = fdk_flat - true_image
130-
jim(axes(ig), err_flat, "Error image (flat)"; clim = (-1,1) .* (0.05μ))
131+
pfe = jim(axes(ig), err_flat, "Error image (flat)"; clim = elim)
131132

132133
#=
133134
As expected for CBCT,
@@ -138,15 +139,21 @@ the largest errors are in the end slices.
138139
#=
139140
## Short scan
140141
=#
141-
cg = CtFanFlat(:short ; p...)
142-
proj_short = radon(rays(cg), ob)
143-
jim(cg.s, cg.t, proj_short ;
142+
rg = CtFanFlat(:short ; p..., na = 200)
143+
proj_short = radon(rays(rg), ob)
144+
psp = jim(axes(rg)[1:2], proj_short ;
144145
title="Shepp-Logan projections (flat,short)", xlabel="s", ylabel="t")
145146

146-
plan_short = plan_fbp(cg, ig; window = Window(Hamming(), 1.0))
147+
#
148+
plan_short = plan_fbp(rg, ig; window = Window(Hamming(), 1.0))
149+
psw = jim(axes(rg)[[1,3]], plan_short.view_weight[:,1,:];
150+
title = "View weights (including Parker)",
151+
xlabel="s", ylabel="angle")
152+
153+
#
147154
fdk_short = fdk(plan_short, proj_short)
148-
jim(axes(ig), fdk_short, "FDK image (flat,short)"; clim)
155+
psr = jim(axes(ig), fdk_short, "FDK image (flat,short)"; clim)
149156

150157
#
151158
err_short = fdk_short - true_image
152-
jim(axes(ig), err_flat, "Error image (flat,short)"; clim = (-1,1) .* (0.05μ))
159+
pse = jim(axes(ig), err_flat, "Error image (flat,short)"; clim = elim)

docs/make.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ binder_root_url =
2424

2525

2626
repo = eval(:($reps))
27-
DocMeta.setdocmeta!(repo, :DocTestSetup, :(using $reps); recursive=true)
27+
DocMeta.setdocmeta!(repo, :DocTestSetup, :(using $reps; import $reps); recursive=true)
2828

2929
for (root, _, files) in walkdir(lit), file in files
3030
splitext(file)[2] == ".jl" || continue # process .jl files only

0 commit comments

Comments
 (0)