Skip to content

Commit dd33526

Browse files
authored
https url (#43)
* using/import * using/import * https url
1 parent f5b496f commit dd33526

File tree

10 files changed

+412
-290
lines changed

10 files changed

+412
-290
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ Tested with Julia ≥ 1.6.
4848
[docs-stable-url]: https://JuliaImageRecon.github.io/SPECTrecon.jl/stable
4949
[docs-dev-img]: https://img.shields.io/badge/docs-dev-blue.svg
5050
[docs-dev-url]: https://JuliaImageRecon.github.io/SPECTrecon.jl/dev
51-
[license-img]: http://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat
51+
[license-img]: https://img.shields.io/badge/license-MIT-brightgreen.svg
5252
[license-url]: LICENSE
5353
[colprac-img]: https://img.shields.io/badge/ColPrac-Contributor's%20Guide-blueviolet
5454
[colprac-url]: https://github.com/SciML/ColPrac

docs/lit/examples/1-overview.jl

Lines changed: 112 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,24 @@
1-
#---------------------------------------------------------
2-
# # [SPECTrecon overview](@id 1-overview)
3-
#---------------------------------------------------------
1+
#=
2+
# [SPECTrecon overview](@id 1-overview)
43
5-
# This page gives an overview of the Julia package
6-
# [`SPECTrecon`](https://github.com/JuliaImageRecon/SPECTrecon.jl).
4+
This page gives an overview of the Julia package
5+
[`SPECTrecon`](https://github.com/JuliaImageRecon/SPECTrecon.jl).
76
8-
# ### Setup
7+
This page was generated from a single Julia file:
8+
[1-overview.jl](@__REPO_ROOT_URL__/1-overview.jl).
9+
=#
10+
11+
#md # In any such Julia documentation,
12+
#md # you can access the source code
13+
#md # using the "Edit on GitHub" link in the top right.
14+
15+
#md # The corresponding notebook can be viewed in
16+
#md # [nbviewer](https://nbviewer.org/) here:
17+
#md # [`1-overview.ipynb`](@__NBVIEWER_ROOT_URL__/1-overview.ipynb),
18+
#md # and opened in [binder](https://mybinder.org/) here:
19+
#md # [`1-overview.ipynb`](@__BINDER_ROOT_URL__/1-overview.ipynb).
20+
21+
# ## Setup
922

1023
# Packages needed here.
1124

@@ -22,46 +35,48 @@ using InteractiveUtils: versioninfo
2235

2336
isinteractive() ? jim(:prompt, true) : prompt(:draw);
2437

25-
# ### Overview
26-
27-
# To perform SPECT image reconstruction,
28-
# one must have a model for the imaging system
29-
# encapsulated in a forward projector and back projector.
30-
31-
# Mathematically, we write the forward projection process in SPECT
32-
# as "y = A * x" where A is a "system matrix"
33-
# that models the physics of the imaging system
34-
# (including depth-dependent collimator/detector response
35-
# and attenuation)
36-
# and "x" is the current guess of the emission image.
37-
38-
# However, in code we usually cannot literally store "A"
39-
# as dense matrix because it is too large.
40-
# A typical size in SPECT is that
41-
# the image `x` is
42-
# `nx × ny × nz = 128 × 128 × 100`
43-
# and the array of projection views `y` is
44-
# `nx × nz × nview = 128 × 100 × 120`.
45-
# So the system matrix `A` has `1536000 × 1638400` elements
46-
# which is far to many to store,
47-
# even accounting for some sparsity.
48-
49-
# Instead, we write functions called forward projectors
50-
# that calculate `A * x` "on the fly".
51-
52-
# Similarly, the operation `A' * y`
53-
# is called "back projection",
54-
# where `A'` denotes the transpose or "adjoint" of `A`.
55-
56-
57-
# ### Example
58-
59-
# To illustrate forward and back projection,
60-
# it is easiest to start with a simulation example
61-
# using a digital phantom.
62-
# The fancy way would be to use a 3D phantom from
63-
# [ImagePhantoms](https://github.com/JuliaImageRecon/ImagePhantoms.jl),
64-
# but instead we just use two simple cubes.
38+
#=
39+
## Overview
40+
41+
To perform SPECT image reconstruction,
42+
one must have a model for the imaging system
43+
encapsulated in a forward projector and back projector.
44+
45+
Mathematically, we write the forward projection process in SPECT
46+
as "y = A * x" where A is a "system matrix"
47+
that models the physics of the imaging system
48+
(including depth-dependent collimator/detector response
49+
and attenuation)
50+
and "x" is the current guess of the emission image.
51+
52+
However, in code we usually cannot literally store "A"
53+
as dense matrix because it is too large.
54+
A typical size in SPECT is that
55+
the image `x` is
56+
`nx × ny × nz = 128 × 128 × 100`
57+
and the array of projection views `y` is
58+
`nx × nz × nview = 128 × 100 × 120`.
59+
So the system matrix `A` has `1536000 × 1638400` elements
60+
which is far to many to store,
61+
even accounting for some sparsity.
62+
63+
Instead, we write functions called forward projectors
64+
that calculate `A * x` "on the fly".
65+
66+
Similarly, the operation `A' * y`
67+
is called "back projection",
68+
where `A'` denotes the transpose or "adjoint" of `A`.
69+
70+
71+
## Example
72+
73+
To illustrate forward and back projection,
74+
it is easiest to start with a simulation example
75+
using a digital phantom.
76+
The fancy way would be to use a 3D phantom from
77+
[ImagePhantoms](https://github.com/JuliaImageRecon/ImagePhantoms.jl),
78+
but instead we just use two simple cubes.
79+
=#
6580

6681
nx,ny,nz = 128,128,80
6782
T = Float32
@@ -80,18 +95,20 @@ end
8095
jim(mid3(xtrue), "Middle slices of x")
8196

8297

83-
# ### PSF
98+
# ## PSF
8499

85100
# Create a synthetic depth-dependent PSF for a single view
86101
px = 11
87102
psf1 = psf_gauss( ; ny, px, fwhm_end = 6)
88103
jim(psf1, "PSF for each of $ny planes")
89104

90105

91-
# In general the PSF can vary from view to view
92-
# due to non-circular detector orbits.
93-
# For simplicity, here we illustrate the case
94-
# where the PSF is the same for every view.
106+
#=
107+
In general the PSF can vary from view to view
108+
due to non-circular detector orbits.
109+
For simplicity, here we illustrate the case
110+
where the PSF is the same for every view.
111+
=#
95112

96113
nview = 60
97114
psfs = repeat(psf1, 1, 1, 1, nview)
@@ -103,11 +120,13 @@ size(psfs)
103120
plan = plan_psf( ; nx, nz, px)
104121

105122

106-
# ### Basic SPECT forward projection
123+
#=
124+
## Basic SPECT forward projection
107125
108-
# Here is a simple illustration
109-
# of a SPECT forward projection operation.
110-
# (This is a memory inefficient way to do it!)
126+
Here is a simple illustration
127+
of a SPECT forward projection operation.
128+
(This is a memory inefficient way to do it!)
129+
=#
111130

112131
dy = 4 # transaxial pixel size in mm
113132
mumap = zeros(T, size(xtrue)) # μ-map just zero for illustration here
@@ -120,14 +139,16 @@ size(views)
120139
jim(views[:,:,1:4:end], "Every 4th of $nview projection views")
121140

122141

123-
# ### Basic SPECT back projection
142+
#=
143+
## Basic SPECT back projection
124144
125-
# This illustrates an "unfiltered backprojection"
126-
# that leads to a very blurry image
127-
# (again, with a simple memory inefficient usage).
145+
This illustrates an "unfiltered backprojection"
146+
that leads to a very blurry image
147+
(again, with a simple memory inefficient usage).
128148
129-
# First, back-project two "rays"
130-
# to illustrate the depth-dependent PSF.
149+
First, back-project two "rays"
150+
to illustrate the depth-dependent PSF.
151+
=#
131152
tmp = zeros(T, size(views))
132153
tmp[nx÷2, nz÷2, nview÷5] = 1
133154
tmp[nx÷2, nz÷2, 1] = 1
@@ -141,18 +162,20 @@ back = backproject(views, mumap, psfs, dy)
141162
jim(mid3(back), "Back-projection of ytrue")
142163

143164

144-
# ### Memory efficiency
165+
#=
166+
## Memory efficiency
145167
146-
# For iterative reconstruction,
147-
# one must do forward and back-projection repeatedly.
148-
# It is more efficient to pre-allocate work arrays
149-
# for those operations,
150-
# instead of repeatedly making system calls.
168+
For iterative reconstruction,
169+
one must do forward and back-projection repeatedly.
170+
It is more efficient to pre-allocate work arrays
171+
for those operations,
172+
instead of repeatedly making system calls.
151173
152-
# Here we illustrate the memory efficient versions
153-
# that are recommended for iterative SPECT reconstruction.
174+
Here we illustrate the memory efficient versions
175+
that are recommended for iterative SPECT reconstruction.
154176
155-
# First construction the SPECT plan.
177+
First construction the SPECT plan.
178+
=#
156179

157180
#viewangle = (0:(nview-1)) * 2π # default
158181
plan = SPECTplan(mumap, psfs, dy; T)
@@ -168,16 +191,18 @@ project!(tmp, xtrue, plan)
168191

169192
tmp = Array{T}(undef, nx, ny, nz)
170193
backproject!(tmp, views, plan)
171-
@assert tmp == back
194+
@assert tmp back
172195

173196

174-
# ### Using `LinearMapAA`
197+
#=
198+
## Using `LinearMapAA`
175199
176-
# Calling `project!` and `backproject!` repeatedly
177-
# leads to application-specific code.
178-
# More general code uses the fact that SPECT projection and back-projection
179-
# are linear operations,
180-
# so we use `LinearMapAA` to define a "system matrix" for these operations.
200+
Calling `project!` and `backproject!` repeatedly
201+
leads to application-specific code.
202+
More general code uses the fact that SPECT projection and back-projection
203+
are linear operations,
204+
so we use `LinearMapAA` to define a "system matrix" for these operations.
205+
=#
181206

182207
forw! = (y,x) -> project!(y, x, plan)
183208
back! = (x,y) -> backproject!(x, y, plan)
@@ -187,27 +212,30 @@ A = LinearMapAA(forw!, back!, (prod(odim),prod(idim)); T, odim, idim)
187212

188213
# Simple forward and back-projection:
189214
@assert A * xtrue == views
190-
@assert A' * views == back
215+
@assert A' * views back
191216

192217
# Mutating version:
193218
tmp = Array{T}(undef, nx, nz, nview)
194219
mul!(tmp, A, xtrue)
195220
@assert tmp == views
196221
tmp = Array{T}(undef, nx, ny, nz)
197222
mul!(tmp, A', views)
198-
@assert tmp == back
223+
@assert tmp back
224+
199225

226+
#=
227+
## Units
200228
201-
# ### Units
229+
The pixel dimensions `deltas` can (and should!) be values with units.
202230
203-
# The pixel dimensions `deltas` can (and should!) be values with units.
231+
Here is an example ... (todo)
232+
=#
204233

205-
# Here is an example ... (todo)
206234
#using UnitfulRecipes
207235
#using Unitful: mm
208236

209237

210-
# ### Projection view animation
238+
# ## Projection view animation
211239

212240
anim = @animate for i in 1:nview
213241
ymax = maximum(views)
@@ -219,7 +247,7 @@ end
219247
gif(anim, "views.gif", fps = 8)
220248

221249

222-
# ### Reproducibility
250+
# ## Reproducibility
223251

224252
# This page was generated with the following version of Julia:
225253

0 commit comments

Comments
 (0)