-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathexample_spatialRegularization.jl
More file actions
182 lines (150 loc) · 5.53 KB
/
Copy pathexample_spatialRegularization.jl
File metadata and controls
182 lines (150 loc) · 5.53 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
#################################################
# Two Step Reconstruction with Tikhonov matrix #
#################################################
# Example for the proceedings article
# "Two-Step Reconstruction with Spatially
# Adaptive Regularization for Increasing
# the Dynamic Range in MPI"
# DOI: 10.18416/IJMPI.2022.2203044
#################################################
# Phantom: Vessel and Kidneys (Dilution: 1 : 2^(-5))
# Julia: 1.7
##############################
# Activate local environment #
##############################
using Pkg
Pkg.activate(".")
Pkg.instantiate()
# load packages
using MPIReco
using Plots, Plots.PlotMeasures
using LazyArtifacts
pyplot() # use PyPlot backend for plotting
###################
# Parameter setup #
###################
## Regularization parameter
λ_high = 0.001
λ_low = 0.5
# SNR threshold
Θ_high = 2
Θ_low = 15
# iterations
ι_high = 3
ι_low = 20
# Threshold
Γ = 0.2
# Frequency selection
minFreq = 80e3
recChannels = [1,2,3]
# Plotting
vmin = 0.0
vmax = 0.0094
MIPplanes = 10
########
# Data #
########
@info "Load data"
# get calibration and experiment data
pathToMDFStore = artifact"MDFStore"
store = MDFDatasetStore(pathToMDFStore)
study = getStudies(store,"IncreasedDynamicRange")[1]
exp = getExperiments(study)
# load MPIFiles
bEmpty = MPIFile(exp[2]) # background scan
bMeas = MPIFile(exp[1]) # measurement
bSF = MPIFile(joinpath(calibdir(store),"1.mdf")) # system matrix
# Frequency selection
freq_high = filterFrequencies(bSF, minFreq=minFreq, SNRThresh=Θ_high, recChannels=recChannels)
freq_low = filterFrequencies(bSF, minFreq=minFreq, SNRThresh=Θ_low, recChannels=recChannels)
# load measurements
uEmpty_high = getMeasurementsFD(bEmpty,frequencies=freq_high, numAverages=acqNumFrames(bEmpty)) # background
uEmpty_low = getMeasurementsFD(bEmpty,frequencies=freq_low, numAverages=acqNumFrames(bEmpty)) # background
uMeas_high = getMeasurementsFD(bMeas,frequencies=freq_high,
numAverages=acqNumFrames(bMeas), spectralLeakageCorrection=false) # measurement
uMeas_low = getMeasurementsFD(bMeas,frequencies=freq_low,
numAverages=acqNumFrames(bMeas), spectralLeakageCorrection=false) # measurement
uMeas_high .-= uEmpty_high # subtract background
uMeas_low .-= uEmpty_low # subtract background
# load system matrix
S_high, grid = getSF(bSF, freq_high, nothing, "kaczmarz"; bgcorrection=true)
S_low, grid = getSF(bSF, freq_low, nothing, "kaczmarz"; bgcorrection=true)
#####################
# Utility functions #
#####################
# masking function
function generateMask(c, Γ; nOverscan::Int=0)
# initial masking
mask = c .> Γ*maximum(c)
# create larger mask around higher concentrated part if nOverscan > 0
if nOverscan == 0
return mask
else
maskO = zeros(Bool,size(mask)...)
for i in CartesianIndices(c)
if mask[i]
I1 = i-CartesianIndex(nOverscan,nOverscan,nOverscan) # left voxel
I2 = i+CartesianIndex(nOverscan,nOverscan,nOverscan) # right voxel
for j in CartesianIndices((I1[1]:I2[1],I1[2]:I2[2],I1[3]:I2[3]))
if j in CartesianIndices(c) # test if j is a valid index
maskO[j] = true
end
end
end
end
return maskO
end
end
# build Tikhonov matrix
function getTikhonovMatrix(λ_high, λ_low, S_high, S_low, mask)
Λ = zeros(size(S_low,2))
# get factors based on the traces of the system matrices
rel_high = MPIReco.calculateTraceOfNormalMatrix(S_high,nothing)/(size(S_high,2)^2)
rel_low = MPIReco.calculateTraceOfNormalMatrix(S_low,nothing)/(size(S_low,2)^2)
# fill Tikhonov matrix
for i in eachindex(Λ)
Λ[i] = mask[i] ? λ_high*rel_high : λ_low*rel_low
end
return Λ
end
##################################
# Two-step reconstruction with #
# Tikhonov regularization matrix #
##################################
@info "Start two-step reconstruction with Tikhonov regularization matrix"
## Step 1: First reconstruction
cPre = reconstruction(S_high, uMeas_high, λ=λ_high, iterations=ι_high)
## Step 2: Thresholding
mask = generateMask(reshape(cPre,shape(grid)...), Γ; nOverscan=2) # use an overscan of 2 voxel around the higher concentrated part
## Step 3: Build Tikhonov matrix
Λ = getTikhonovMatrix(λ_high, λ_low, S_high, S_low, mask) # SMs used for relative regularization
## Step 4: Second reconstruction
cΛ = reconstruction(S_low, uMeas_low, λ=1.0, relativeLambda=false, iterations=ι_low, regMatrix=Λ)
##############################################
# Reconstruction with P_low (for comparison) #
##############################################
@info "Start reconstruction with P_low"
cLow = reconstruction(S_low, uMeas_low, λ=λ_low, iterations=ι_low)
#################
# Visualization #
#################
# Reshaping
cΛ = reshape(cΛ[:,1], shape(grid)...)
cLow = reshape(cLow[:,1], shape(grid)...)
# Create plots
p1 = heatmap(-21:2:21,-21:2:21,squeeze(reverse(maximum(cΛ[:,:,MIPplanes],dims=3),dims=1)),
clim=(vmin,vmax), c = :viridis,
colorbar_ticks = ([0,vmax],[0,"κ₁"]),
title = "cΛ", aspect_ratio = 1 )
p2 = heatmap(-21:2:21,-21:2:21,squeeze(reverse(maximum(cLow[:,:,MIPplanes],dims=3),dims=1)),
clim = (vmin,vmax), c = :viridis,
colorbar_ticks = ([0,vmax],[0,"κ₁"]),
title = "cLow", aspect_ratio = 1 )
# Figure
plot(p1, p2, layout = (1, 2), size=(600,300),
xaxis = ("y / mm", (-21,21)),
yaxis = ("x / mm", (-21,21)),
colorbar_title = "concentration",
left_margin = 5mm,
tickfontsize = 10,
colorbar_tickfontsize = 10)