-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmainGibbs.py
283 lines (239 loc) · 10.3 KB
/
mainGibbs.py
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
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
###################################################
# Main script for running experiments with geometric parameterization of pipes
# By Silja L. Christensen
# June 2024
###################################################
import numpy as np
import matplotlib.pyplot as plt
import os
import sys
import dill
from AnnulusGeometry2024 import PipeParam, PipeParamsCollection, DiskFree, DiskConcentric, AnnulusFree, AnnulusConcentricConnected
# cuqipy version 1.0.0
from cuqi.distribution import Gaussian, Gamma, Uniform, JointDistribution
from cuqi.sampler import CWMH
from cuqi.experimental.mcmc import CWMHNew, HybridGibbsNew, MHNew
from cuqi.likelihood import Likelihood
from cuqi.array import CUQIarray
# cuqipy-cil version 0.6.0
from cuqipy_cil.model import FanBeam2DModel, ShiftedFanBeam2DModel
# CIL version 22.1
from cil.utilities.display import show_geometry
import subprocess
try:
subprocess.check_output('nvidia-smi')
print('Nvidia GPU detected!')
except Exception: # this command not being found can raise quite a few different errors depending on the configuration
print('No Nvidia GPU in system!')
#%%=======================================================================
# Paths
#=========================================================================
# path for saving results
resultpath = '../../../../../../work3/swech/results/'
resultname = 'GibbsTest'
os.makedirs(resultpath, exist_ok=True)
#%%=======================================================================
# Discretization
#=========================================================================
N = 500
N_phantom = 1024
imagesize = 4
#%%=======================================================================
# Parameter lib
#=========================================================================
# DiskFree
DF1 = PipeParam(paramtype = "center_x",
layerno = 0,
truevalue = -0.1,
prior=Gaussian(mean = 0, sqrtcov = 0.5))
DF2 = PipeParam(paramtype = "center_y",
layerno = 0,
truevalue = 0.2,
prior=Gaussian(mean = 0, sqrtcov = 0.5))
DF3 = PipeParam(paramtype = "radius",
layerno = 0,
truevalue = 0.4,
prior=Uniform(low = 0.3, high = 0.5))
DF4 = PipeParam(paramtype = "center_x",
layerno = 1,
truevalue = -0.1,
prior=Gaussian(mean = 0, sqrtcov = 0.5))
DF5 = PipeParam(paramtype = "center_y",
layerno = 1,
truevalue = 0.2,
prior=Gaussian(mean = 0, sqrtcov = 0.5))
DF6 = PipeParam(paramtype = "radius",
layerno = 1,
truevalue = 0.9,
prior=Uniform(low = 0.7, high = 1.1))
DF7 = PipeParam(paramtype = "abscoeff",
layerno = 1,
truevalue = 0.7,
prior=Gamma(shape = 2, rate = 2))
DF8 = PipeParam(paramtype = "center_x",
layerno = 2,
truevalue = 0,
prior=Gaussian(mean = 0, sqrtcov = 0.5))
DF9 = PipeParam(paramtype = "center_y",
layerno = 2,
truevalue = 0.1,
prior=Gaussian(mean = 0, sqrtcov = 0.5))
DF10 = PipeParam(paramtype = "radius",
layerno = 2,
truevalue = 1.1,
prior=Uniform(low = 0.9, high = 1.3))
DF11 = PipeParam(paramtype = "abscoeff",
layerno = 2,
truevalue = 0.3,
prior=Gamma(shape = 2, rate = 2))
#%%=======================================================================
# Parameter lib
#=========================================================================
nolayers = 2
pipeparams_list = [DF1, DF2, DF3, DF4, DF5, DF6, DF7, DF8, DF9, DF10, DF11]
pipe_geometry = DiskFree(nolayers, imagesize, N)
# Collect the info above in one object
PPCollection = PipeParamsCollection(pipeparams_list = pipeparams_list, pipe_geometry = pipe_geometry)
#%%=======================================================================
# Sampling params
#=========================================================================
Ns = 150 # no of samples in each chain
Nb = 50 # Burnin
Nt = 1#50 # Thinning
sample_scale = 1e-3 # Initial sample scale
#%%=======================================================================
# Define model
#=========================================================================
# Scan Geometry parameters
DetectorCount = 300 # no of detectors
AngleCount = 100 # no of view angles
maxAngle = 2*np.pi
angles = np.linspace(0,maxAngle,AngleCount, endpoint=True)
source_object_dist = 7
object_detector_dist = 5
det_spacing = 10/DetectorCount
m = DetectorCount * AngleCount
# Model
A = ShiftedFanBeam2DModel(im_size = (N,N),
det_count = DetectorCount,
angles = angles,
source_y = -source_object_dist,
detector_y = object_detector_dist,
beamshift_x = -1.2,
det_spacing = 4/DetectorCount,
domain = (imagesize,imagesize))
# Configure model
A.domain_geometry = pipe_geometry
show_geometry(A.acquisition_geometry, A.image_geometry)
plt.savefig(resultpath + resultname + '_ag.png')
# FP = A(CUQIarray([0, 0, 0, 0, 0, 0, 0.1, 0.2, 0.3, 0.1, 0.2], geometry = pipe_geometry))
# fig, ax = plt.subplots(1,1, figsize=(5,3))
# cs = FP.plot(aspect = 1/2, extent = [0, 300, 360, 0], interpolation = "none")
# cs[0].axes.set_xticks(np.linspace(0,300, 5, endpoint = True))
# cs[0].axes.set_yticks(np.linspace(0,360, 7, endpoint = True))
# cs[0].axes.set_xlabel('Detector')
# cs[0].axes.set_ylabel('View angle [degree]')
# fig.subplots_adjust(right=0.85, bottom=0.15)
# cax = fig.add_axes([cs[0].axes.get_position().x1+0.01,cs[0].axes.get_position().y0,0.03,cs[0].axes.get_position().height])
# cbar = plt.colorbar(cs[0], cax=cax)
# plt.savefig(resultpath + resultname + '_FP.png')
# sys.exit()
#%%=======================================================================
# Synthetic data
#=========================================================================
pipeparams_list_phantom = [DF1, DF2, DF3, DF4, DF5, DF6, DF7, DF8, DF9, DF10, DF11]
pipe_geometry_phantom = DiskFree(nolayers, imagesize, N_phantom)
# Model
A_phantom = ShiftedFanBeam2DModel(im_size = (N_phantom,N_phantom),
det_count = DetectorCount,
angles = angles,
source_y = -source_object_dist,
detector_y = object_detector_dist,
beamshift_x = -1.2,
det_spacing = 4/DetectorCount,
domain = (imagesize,imagesize))
# Configure model
A_phantom.domain_geometry = pipe_geometry_phantom
# prior
PPCollection_phantom = PipeParamsCollection(pipeparams_list = pipeparams_list_phantom, pipe_geometry = pipe_geometry_phantom)
theta_phantom = PPCollection_phantom.get_prior()
# True values in CUQIarray
theta_true = PPCollection_phantom.get_truth()
# data
noise_std = 0.1
d_phantom = Gaussian(mean = A_phantom(theta_phantom), sqrtcov = noise_std, geometry=A_phantom.range_geometry)
np.random.seed(10)
d_obs = d_phantom(theta_phantom = theta_true).sample()
fig, ax = plt.subplots(1,1, figsize=(5,3))
cs = d_obs.plot(aspect = 1/2, extent = [0, 300, 360, 0], interpolation = "none")
cs[0].axes.set_xticks(np.linspace(0,300, 5, endpoint = True))
cs[0].axes.set_yticks(np.linspace(0,360, 7, endpoint = True))
cs[0].axes.set_xlabel('Detector')
cs[0].axes.set_ylabel('View angle [degree]')
fig.subplots_adjust(right=0.85, bottom=0.15)
cax = fig.add_axes([cs[0].axes.get_position().x1+0.01,cs[0].axes.get_position().y0,0.03,cs[0].axes.get_position().height])
cbar = plt.colorbar(cs[0], cax=cax)
plt.savefig(resultpath + resultname + '_sinogram.png')
#%%=======================================================================
# Specification and sampling of Bayesian problem
#=========================================================================
# prior
cx0 = DF1.prior
cy0 = DF2.prior
r0 = DF3.prior
cx1 = DF4.prior
cy1 = DF5.prior
r1 = DF6.prior
phi1 = DF7.prior
cx2 = DF8.prior
cy2 = DF9.prior
r2 = DF10.prior
phi2 = DF11.prior
# data
d = Gaussian(mean = lambda cx0, cx1, cx2, cy0, cy1, cy2, r0, r1, r2, phi1, phi2: A(CUQIarray([cx0, cx1, cx2, cy0, cy1, cy2, r0, r1, r2, phi1, phi2], geometry = pipe_geometry)),
sqrtcov = noise_std, geometry=A.range_geometry)
# cx0, cx1, cx2, cy0, cy1, cy2, r0, r1, r2, phi1, phi2
# 0, 0, 0, 0, 0, 0, 0.4, 0.9, 1.1, 0.7, 0.3
# posterior
posterior = JointDistribution(cx0, cx1, cx2, cy0, cy1, cy2, r0, r1, r2, phi1, phi2, d)(d=d_obs)
print(posterior(cx1=0, cx2=0, cy0=0, cy1=0, cy2=0, r0=0.4, r1=0.9, r2=1.1, phi1=0.7, phi2=0.3).logd(1))
# sample
np.random.seed(10)
# setup initial guess as random sample from prior
theta = PPCollection.get_prior()
theta0 = theta.sample(1)
# Gibbs sampler
sampling_strategy = {
"cx0" : MHNew(scale = sample_scale, initial_point = 0),
"cx1" : MHNew(scale = sample_scale, initial_point = 0),
"cx2" : MHNew(scale = sample_scale, initial_point = 0),
"cy0" : MHNew(scale = sample_scale, initial_point = 0),
"cy1" : MHNew(scale = sample_scale, initial_point = 0),
"cy2" : MHNew(scale = sample_scale, initial_point = 0),
"r0" : MHNew(scale = sample_scale, initial_point = 0.4),
"r1" : MHNew(scale = sample_scale, initial_point = 0.9),
"r2" : MHNew(scale = sample_scale, initial_point = 1.1),
"phi1" : MHNew(scale = sample_scale, initial_point = 0.7),
"phi2" : MHNew(scale = sample_scale, initial_point = 0.3)
}
sampler = HybridGibbsNew(posterior, sampling_strategy)
print(sampler)
# warmup
sampler.warmup(Nb)
# sample
sampler.sample(Ns)
samples_all = sampler.get_samples()
samples = samples_all.burnthin(Nb)
#%%=======================================================================
# save data
#=========================================================================
paramnames = pipe_geometry.variables
# plot chain
plt.figure()
samples_all.plot_chain(variable_indices=range(pipe_geometry.par_shape[0]))
plt.savefig(resultpath + resultname + '_chainswithwarmup.png')
#%%=======================================================================
# save data
#=========================================================================
with open('{}{}.pkl'.format(resultpath,resultname), 'wb') as f: # Python 3: open(..., 'wb')
dill.dump([samples, sampler, PPCollection, A], f)