Skip to content

Commit 25d9fcf

Browse files
authored
Use in, abandon 1.6, add gpu urls (#44)
* Use `in` * Abandon 1.6 * urls * fix label
1 parent dd33526 commit 25d9fcf

File tree

12 files changed

+57
-52
lines changed

12 files changed

+57
-52
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ jobs:
2323
strategy:
2424
fail-fast: false
2525
matrix:
26-
version: ['1.6', '1', 'nightly']
26+
version: ['1', 'nightly']
2727
os: [ubuntu-latest, windows-latest, macOS-latest]
2828
steps:
2929
- uses: actions/checkout@v3

README.md

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,20 @@ The examples include an illustration
2424
of how to integrate deep learning
2525
into SPECT reconstruction.
2626

27-
For a GPU-focused version, see
27+
Tested with Julia ≥ 1.8.
28+
29+
## Related packages
30+
31+
- Pytorch/GPU version:
32+
https://github.com/ZongyuLi-umich/SPECTrecon-pytorch
33+
34+
- Julia/GPU version:
2835
[CuSPECTrecon.jl](https://github.com/JuliaImageRecon/CuSPECTrecon.jl).
2936

3037
Designed for use with the
3138
[Michigan Image Reconstruction Toolbox (MIRT)](https://github.com/JeffFessler/MIRT.jl)
3239
or similar frameworks.
3340

34-
Tested with Julia ≥ 1.6.
35-
3641
<!-- URLs -->
3742
[action-img]: https://github.com/JuliaImageRecon/SPECTrecon.jl/workflows/CI/badge.svg
3843
[action-url]: https://github.com/JuliaImageRecon/SPECTrecon.jl/actions

src/backproject.jl

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ function backproject!(
1313
viewidx::Int,
1414
)
1515

16-
Threads.@threads for z = 1:plan.imgsize[3] # 1:nz
16+
Threads.@threads for z in 1:plan.imgsize[3] # 1:nz
1717
thid = Threads.threadid() # thread id
1818

1919
# rotate mumap
@@ -26,11 +26,11 @@ function backproject!(
2626
end
2727

2828
# adjoint of convolving img with psf and applying attenuation map
29-
Threads.@threads for y = 1:plan.imgsize[2] # 1:ny
29+
Threads.@threads for y in 1:plan.imgsize[2] # 1:ny
3030
thid = Threads.threadid() # thread id
3131
# account for half of the final slice thickness
3232
scale3dj!(plan.exp_mumapr[thid], plan.mumapr, y, -0.5)
33-
for j = 1:y
33+
for j in 1:y
3434
plus3dj!(plan.exp_mumapr[thid], plan.mumapr, j)
3535
end
3636

@@ -48,7 +48,7 @@ function backproject!(
4848
end
4949

5050
# adjoint of rotating image
51-
Threads.@threads for z = 1:plan.imgsize[3] # 1:nz
51+
Threads.@threads for z in 1:plan.imgsize[3] # 1:nz
5252
thid = Threads.threadid()
5353

5454
imrotate_adj!((@view image[:, :, z]),
@@ -74,7 +74,7 @@ function backproject!(
7474
viewidx::Int,
7575
)
7676

77-
for z = 1:plan.imgsize[3] # 1:nz
77+
for z in 1:plan.imgsize[3] # 1:nz
7878
# thid = Threads.threadid() # thread id
7979

8080
# rotate mumap
@@ -87,11 +87,11 @@ function backproject!(
8787
end
8888

8989
# adjoint of convolving img with psf and applying attenuation map
90-
for y = 1:plan.imgsize[2] # 1:ny
90+
for y in 1:plan.imgsize[2] # 1:ny
9191
thid = Threads.threadid() # thread id
9292
# account for half of the final slice thickness
9393
scale3dj!(plan.exp_mumapr[thid], plan.mumapr[thid], y, -0.5)
94-
for j = 1:y
94+
for j in 1:y
9595
plus3dj!(plan.exp_mumapr[thid], plan.mumapr[thid], j)
9696
end
9797

@@ -109,7 +109,7 @@ function backproject!(
109109
end
110110

111111
# adjoint of rotating image
112-
for z = 1:plan.imgsize[3] # 1:nz
112+
for z in 1:plan.imgsize[3] # 1:nz
113113
imrotate_adj!((@view plan.imgr[thid][:, :, z]),
114114
(@view plan.imgr[thid][:, :, z]),
115115
plan.viewangle[viewidx],
@@ -138,13 +138,13 @@ function backproject!(
138138
# loop over each view index
139139
image .= zero(plan.T) # must be initialized as zero
140140
if plan.mode === :fast
141-
[plan.add_img[i] .= zero(plan.T) for i = 1:plan.nthread]
141+
[plan.add_img[i] .= zero(plan.T) for i in 1:plan.nthread]
142142
Threads.@threads for (i, viewidx) in collect(enumerate(index))
143143
thid = Threads.threadid()
144144
backproject!(plan.add_img[thid], (@view views[:, :, i]), plan, thid, viewidx)
145145
end
146146

147-
for i = 1:plan.nthread
147+
for i in 1:plan.nthread
148148
broadcast!(+, image, image, plan.add_img[i])
149149
end
150150
else

src/fft_convolve.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,25 +93,25 @@ function fft_conv_adj!(
9393
(M, N) = size(img)
9494
# adjoint of replicate padding
9595
plan.workvecz .= zero(T)
96-
for i = 1:plan.padsize[1]
96+
for i in 1:plan.padsize[1]
9797
plus2di!(plan.workvecz, plan.workmat, i)
9898
end
9999
plus1di!(plan.workmat, plan.workvecz, 1+plan.padsize[1])
100100

101101
plan.workvecz .= zero(T)
102-
for i = (plan.padsize[1]+M+1):size(plan.workmat, 1)
102+
for i in (plan.padsize[1]+M+1):size(plan.workmat, 1)
103103
plus2di!(plan.workvecz, plan.workmat, i)
104104
end
105105
plus1di!(plan.workmat, plan.workvecz, M+plan.padsize[1])
106106

107107
plan.workvecx .= zero(T)
108-
for j = 1:plan.padsize[3]
108+
for j in 1:plan.padsize[3]
109109
plus2dj!(plan.workvecx, plan.workmat, j)
110110
end
111111
plus1dj!(plan.workmat, plan.workvecx, 1+plan.padsize[3])
112112

113113
plan.workvecx .= zero(T)
114-
for j = (plan.padsize[3]+N+1):size(plan.workmat, 2)
114+
for j in (plan.padsize[3]+N+1):size(plan.workmat, 2)
115115
plus2dj!(plan.workvecx, plan.workmat, j)
116116
end
117117
plus1dj!(plan.workmat, plan.workvecx, N+plan.padsize[3])

src/helper.jl

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ Base.@propagate_inbounds function padzero!(
2929
size(img) .+ (padsize[1] + padsize[2], padsize[3] + padsize[4]) || throw("size")
3030
M, N = size(img)
3131
output .= zero(T)
32-
for j = padsize[3] + 1:padsize[3] + N, i = padsize[1] + 1:padsize[1] + M
32+
for j in padsize[3] + 1:padsize[3] + N, i in padsize[1] + 1:padsize[1] + M
3333
@inbounds output[i, j] = img[i - padsize[1], j - padsize[3]]
3434
end
3535
return output
@@ -50,7 +50,7 @@ Base.@propagate_inbounds function padrepl!(
5050
@boundscheck size(output) ==
5151
size(img) .+ (padsize[1] + padsize[2], padsize[3] + padsize[4]) || throw("size")
5252
M, N = size(img)
53-
for j = 1:size(output, 2), i = 1:size(output, 1)
53+
for j in 1:size(output, 2), i in 1:size(output, 1)
5454
@inbounds output[i, j] = img[clamp(i - padsize[1], 1, M), clamp(j - padsize[3], 1, N)]
5555
end
5656
return output
@@ -75,7 +75,7 @@ Base.@propagate_inbounds function pad2sizezero!(
7575
dims = size(img)
7676
pad_dims = ceil.(Int, (padsize .- dims) ./ 2)
7777
output .= zero(T)
78-
for j = pad_dims[2]+1:pad_dims[2]+dims[2], i = pad_dims[1]+1:pad_dims[1]+dims[1]
78+
for j in pad_dims[2]+1:pad_dims[2]+dims[2], i in pad_dims[1]+1:pad_dims[1]+dims[1]
7979
@inbounds output[i, j] = img[i - pad_dims[1], j - pad_dims[2]]
8080
end
8181
return output
@@ -119,7 +119,7 @@ Base.@propagate_inbounds function fftshift2!(
119119
if size(src,2) == 1
120120
@boundscheck iseven(size(src, 1)) || throw("odd $(size(src))")
121121
m = size(src,1) ÷ 2
122-
for i = 1:m
122+
for i in 1:m
123123
@inbounds dst[i, 1] = src[m+i, 1]
124124
@inbounds dst[i+m, 1] = src[i, 1]
125125
end
@@ -128,16 +128,16 @@ Base.@propagate_inbounds function fftshift2!(
128128

129129
@boundscheck (iseven(size(src, 1)) && iseven(size(src, 2))) || throw("odd")
130130
m, n = div.(size(src), 2)
131-
for j = 1:n, i = 1:m
131+
for j in 1:n, i in 1:m
132132
@inbounds dst[i, j] = src[m+i, n+j]
133133
end
134-
for j = n+1:2n, i = 1:m
134+
for j in n+1:2n, i in 1:m
135135
@inbounds dst[i, j] = src[m+i, j-n]
136136
end
137-
for j = 1:n, i = m+1:2m
137+
for j in 1:n, i in m+1:2m
138138
@inbounds dst[i, j] = src[i-m, j+n]
139139
end
140-
for j = n+1:2n, i = m+1:2m
140+
for j in n+1:2n, i in m+1:2m
141141
@inbounds dst[i, j] = src[i-m, j-n]
142142
end
143143
return dst

src/ml-os-em.jl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ function mlem!(
3636
back = similar(x0)
3737
copyto!(out, x0)
3838
time0 = time()
39-
for iter = 1:niter
39+
for iter in 1:niter
4040
chat && (@show iter, extrema(out), time() - time0)
4141
mul!(ybar, A, out)
4242
@. yratio = ynoisy / (ybar + background) # coalesce broadcast!
@@ -70,7 +70,7 @@ function Ablock(plan::SPECTplan, nblocks::Int)
7070
nview = plan.nview
7171
rem(nview, nblocks) == 0 || throw("nview must be divisible by nblocks!")
7272
Ab = Vector{LinearMapAO}(undef, nblocks)
73-
for nb = 1:nblocks
73+
for nb in 1:nblocks
7474
viewidx = nb:nblocks:nview
7575
forw!(y,x) = project!(y, x, plan; index = viewidx)
7676
back!(x,y) = backproject!(x, y, plan; index = viewidx)
@@ -106,7 +106,7 @@ function osem!(
106106
nx, nz, nview = size(ynoisy)
107107
nblocks = length(Ab)
108108
asum = Vector{Array{eltype(ynoisy), 3}}(undef, nblocks)
109-
for nb = 1:nblocks
109+
for nb in 1:nblocks
110110
asum[nb] = Ab[nb]' * ones(eltype(ynoisy), nx, nz, nview÷nblocks)
111111
(asum[nb])[asum[nb] .== 0] .= Inf # avoid divide by zero
112112
end
@@ -115,8 +115,8 @@ function osem!(
115115
back = similar(x0)
116116
copyto!(out, x0)
117117
time0 = time()
118-
for iter = 1:niter
119-
for nb = 1:nblocks
118+
for iter in 1:niter
119+
for nb in 1:nblocks
120120
chat && (@show iter, nb, extrema(out), time() - time0)
121121
mul!(ybar, Ab[nb], out)
122122
@. yratio = (@view ynoisy[:,:,nb:nblocks:nview]) /

src/plan-psf.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ function plan_psf( ;
104104
nthread::Int = Threads.nthreads(),
105105
T::DataType = Float32,
106106
)
107-
return [PlanPSF( ; nx, nz, px, pz, T) for id = 1:nthread]
107+
return [PlanPSF( ; nx, nz, px, pz, T) for id in 1:nthread]
108108
end
109109

110110

src/plan-rotate.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ function plan_rotate(
9999
method::Symbol = :two,
100100
nthread::Int = Threads.nthreads(),
101101
)
102-
return [PlanRotate(nx; T, method) for id = 1:nthread]
102+
return [PlanRotate(nx; T, method) for id in 1:nthread]
103103
end
104104

105105

src/project.jl

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ function project!(
1515
)
1616
# rotate image and mumap using multiple processors
1717

18-
Threads.@threads for z = 1:plan.imgsize[3] # 1:nz
18+
Threads.@threads for z in 1:plan.imgsize[3] # 1:nz
1919
thid = Threads.threadid() # thread id
2020
# rotate image in plan.imgr
2121
imrotate!(
@@ -33,12 +33,12 @@ function project!(
3333
)
3434
end
3535

36-
Threads.@threads for y = 1:plan.imgsize[2] # 1:ny
36+
Threads.@threads for y in 1:plan.imgsize[2] # 1:ny
3737
thid = Threads.threadid() # thread id
3838
# account for half of the final slice thickness
3939
scale3dj!(plan.exp_mumapr[thid], plan.mumapr, y, -0.5)
4040

41-
for j = 1:y
41+
for j in 1:y
4242
plus3dj!(plan.exp_mumapr[thid], plan.mumapr, j)
4343
end
4444

@@ -82,7 +82,7 @@ function project!(
8282
)
8383
# rotate image and mumap using multiple processors
8484

85-
for z = 1:plan.imgsize[3] # 1:nz
85+
for z in 1:plan.imgsize[3] # 1:nz
8686
# rotate image in plan.imgr
8787
imrotate!(
8888
(@view plan.imgr[thid][:, :, z]),
@@ -99,11 +99,11 @@ function project!(
9999
)
100100
end
101101

102-
for y = 1:plan.imgsize[2] # 1:ny
102+
for y in 1:plan.imgsize[2] # 1:ny
103103
# account for half of the final slice thickness
104104
scale3dj!(plan.exp_mumapr[thid], plan.mumapr[thid], y, -0.5)
105105

106-
for j = 1:y
106+
for j in 1:y
107107
plus3dj!(plan.exp_mumapr[thid], plan.mumapr[thid], j)
108108
end
109109

src/psf-gauss.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ having specified full-width half-maximum (FHWM) values.
1414
- 'pz::Int = px' (should be odd)
1515
- 'fwhm_start::Real = 1'
1616
- 'fwhm_end::Real = 4'
17-
- 'fwhm::AbstractVector{<:Real} = LinRange(fwhm_start, fwhm_end, ny)'
17+
- 'fwhm::AbstractVector{<:Real} = range(fwhm_start, fwhm_end, ny)'
1818
- 'fwhm_x::AbstractVector{<:Real} = fwhm,
1919
- 'fwhm_z::AbstractVector{<:Real} = fwhm_x'
2020
- 'T::DataType == Float32'
@@ -27,7 +27,7 @@ function psf_gauss( ;
2727
pz::Int = px,
2828
fwhm_start::Real = 1,
2929
fwhm_end::Real = 4,
30-
fwhm::AbstractVector{<:Real} = LinRange(fwhm_start, fwhm_end, ny),
30+
fwhm::AbstractVector{<:Real} = range(fwhm_start, fwhm_end, ny),
3131
fwhm_x::AbstractVector{<:Real} = fwhm,
3232
fwhm_z::AbstractVector{<:Real} = fwhm_x,
3333
T::DataType = Float32,

0 commit comments

Comments
 (0)