mimical 0.1.0__py3-none-any.whl → 0.1.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mimical/fitting/fitter.py +43 -5
- mimical/plotting/plotting.py +109 -31
- {mimical-0.1.0.dist-info → mimical-0.1.2.dist-info}/METADATA +2 -2
- {mimical-0.1.0.dist-info → mimical-0.1.2.dist-info}/RECORD +6 -6
- {mimical-0.1.0.dist-info → mimical-0.1.2.dist-info}/WHEEL +1 -1
- {mimical-0.1.0.dist-info → mimical-0.1.2.dist-info}/top_level.txt +0 -0
mimical/fitting/fitter.py
CHANGED
|
@@ -14,11 +14,15 @@ from ..plotting import Plotter
|
|
|
14
14
|
|
|
15
15
|
from ..utils import filter_set
|
|
16
16
|
|
|
17
|
+
from tqdm import tqdm
|
|
18
|
+
|
|
19
|
+
|
|
17
20
|
dir_path = os.getcwd()
|
|
18
21
|
if not os.path.isdir(dir_path + "/mimical"):
|
|
19
22
|
os.system('mkdir ' + dir_path + "/mimical")
|
|
20
23
|
os.system('mkdir ' + dir_path + "/mimical/plots")
|
|
21
24
|
os.system('mkdir ' + dir_path + "/mimical/posteriors")
|
|
25
|
+
os.system('mkdir ' + dir_path + "/mimical/cats")
|
|
22
26
|
|
|
23
27
|
|
|
24
28
|
|
|
@@ -162,6 +166,7 @@ class mimical(object):
|
|
|
162
166
|
self.samples = pd.read_csv(dir_path+'/mimical/posteriors' + f'/{self.id}.txt', delimiter=' ').to_numpy()
|
|
163
167
|
fit_dic = dict(zip((np.array((list(self.fitter_prior.keys)))+"_50").tolist(), np.median(self.samples, axis=0).tolist()))
|
|
164
168
|
print(f"Loading existing posterior at " + dir_path + '/mimical/posteriors' + f'/{self.id}.txt')
|
|
169
|
+
self.save_cat()
|
|
165
170
|
print(" ")
|
|
166
171
|
return fit_dic
|
|
167
172
|
|
|
@@ -185,7 +190,7 @@ class mimical(object):
|
|
|
185
190
|
|
|
186
191
|
# Plot and save the corner plot
|
|
187
192
|
corner.corner(points, weights=np.exp(log_w), bins=20, labels=np.array(self.fitter_prior.keys), color='purple', plot_datapoints=False, range=np.repeat(0.999, len(self.fitter_prior.keys)))
|
|
188
|
-
plt.savefig(dir_path+'/mimical/plots' + f'/
|
|
193
|
+
plt.savefig(dir_path+'/mimical/plots' + f'/{self.id}_corner.pdf', bbox_inches='tight')
|
|
189
194
|
|
|
190
195
|
# Sample an appropriately weighted posterior for representative samples.
|
|
191
196
|
n_post = 10000
|
|
@@ -200,15 +205,48 @@ class mimical(object):
|
|
|
200
205
|
print("Sampling finished successfully.")
|
|
201
206
|
print(" ")
|
|
202
207
|
|
|
208
|
+
self.save_cat()
|
|
209
|
+
|
|
203
210
|
return fit_dic
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
def save_cat(self):
|
|
214
|
+
|
|
215
|
+
user_samples = np.zeros((self.samples.shape[0], len(self.wavs), len(self.user_prior.keys())))
|
|
216
|
+
# Get median Nautilus parameters and transalte into median model parameters.
|
|
217
|
+
for j in tqdm(range(self.samples.shape[0])):
|
|
218
|
+
# Get median Nautilus parameters and transalte into median model parameters.
|
|
219
|
+
param_dict = dict(zip(list(self.fitter_prior.keys), self.samples[j]))
|
|
220
|
+
pars = self.prior_handler.revert(param_dict, self.wavs)
|
|
221
|
+
user_samples[j] = pars
|
|
222
|
+
|
|
223
|
+
quantiles = np.percentile(user_samples, q=(16, 50, 84), axis=0)
|
|
224
|
+
|
|
225
|
+
dic = {}
|
|
226
|
+
for j in range(len(self.filter_names)):
|
|
227
|
+
for i in range(len(self.user_prior.keys())):
|
|
228
|
+
key = list(self.user_prior.keys())[i]
|
|
229
|
+
dic[key + "_" + self.filter_names[j] + "_16"] = [quantiles[0, j, i]]
|
|
230
|
+
dic[key + "_" + self.filter_names[j] + "_50"] = [quantiles[1, j, i]]
|
|
231
|
+
dic[key + "_" + self.filter_names[j] + "_84"] = [quantiles[2, j, i]]
|
|
232
|
+
|
|
233
|
+
df = pd.DataFrame(dic)
|
|
234
|
+
df.to_csv(dir_path+'/mimical/cats' + f'/{self.id}.csv', index=False)
|
|
235
|
+
|
|
236
|
+
|
|
204
237
|
|
|
205
238
|
|
|
206
|
-
def plot_model(self):
|
|
239
|
+
def plot_model(self, type='median'):
|
|
207
240
|
if self.success != True:
|
|
208
241
|
print(f'Sampling failed, cannot plot model for {self.id}.')
|
|
209
242
|
else:
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
243
|
+
if type=='median':
|
|
244
|
+
# Plot and save the median-parameter fit
|
|
245
|
+
Plotter().plot_median(self.images, self.wavs, self.convolved_models, self.samples, list(self.fitter_prior.keys), self.prior_handler, self.filter_names)
|
|
246
|
+
plt.savefig(dir_path+'/mimical/plots' + f'/{self.id}_median_model.pdf', bbox_inches='tight')
|
|
247
|
+
elif type=='median-param':
|
|
248
|
+
# Plot and save the median-parameter fit
|
|
249
|
+
Plotter().plot_median_param(self.images, self.wavs, self.convolved_models, self.samples, list(self.fitter_prior.keys), self.prior_handler, self.filter_names)
|
|
250
|
+
plt.savefig(dir_path+'/mimical/plots' + f'/{self.id}_median_param_model.pdf', bbox_inches='tight')
|
|
213
251
|
|
|
214
252
|
|
mimical/plotting/plotting.py
CHANGED
|
@@ -2,42 +2,94 @@ import matplotlib.pyplot as plt
|
|
|
2
2
|
import numpy as np
|
|
3
3
|
from astropy.convolution.utils import discretize_model
|
|
4
4
|
from tqdm import tqdm
|
|
5
|
+
from matplotlib import ticker
|
|
5
6
|
|
|
6
7
|
class Plotter(object):
|
|
7
8
|
|
|
8
|
-
def
|
|
9
|
+
def plot_median_param(self, images, wavs, convolved_models, samples, fitter_keys, prior_handler, filter_names):
|
|
10
|
+
|
|
11
|
+
fig = plt.figure()
|
|
12
|
+
gs = fig.add_gridspec(nrows=4, ncols=images.shape[0]+1, width_ratios=np.append(np.ones(images.shape[0]), 0.25))
|
|
9
13
|
|
|
10
|
-
fig,axes=plt.subplots(3, images.shape[0], figsize=(images.shape[0],3))
|
|
11
14
|
|
|
12
15
|
# Get median Nautilus parameters and transalte into median model parameters.
|
|
13
16
|
param_dict = dict(zip(fitter_keys, np.median(samples, axis=0)))
|
|
14
17
|
pars = prior_handler.revert(param_dict, wavs)
|
|
15
18
|
|
|
19
|
+
|
|
20
|
+
models = np.zeros_like(images)
|
|
16
21
|
for i in range(len(wavs)):
|
|
17
22
|
convolved_models[i].parameters = pars[i]
|
|
18
23
|
model = discretize_model(model=convolved_models[i],
|
|
19
24
|
x_range=[0,images[i].shape[1]],
|
|
20
25
|
y_range=[0,images[i].shape[0]],
|
|
21
26
|
mode='center')
|
|
22
|
-
|
|
27
|
+
models[i]=model
|
|
23
28
|
|
|
24
|
-
|
|
29
|
+
|
|
30
|
+
residuals = images - models
|
|
31
|
+
|
|
32
|
+
vmins = [-np.percentile(images.flatten(), q=95), -np.percentile(images.flatten(), q=95), -np.percentile(images.flatten(), q=95), min(np.percentile(residuals.flatten(), q=5), -np.percentile(residuals.flatten(), q=95))]
|
|
33
|
+
vmaxs = [np.percentile(images.flatten(), q=95), np.percentile(images.flatten(), q=95), np.percentile(images.flatten(), q=95), max(-np.percentile(residuals.flatten(), q=5), np.percentile(residuals.flatten(), q=95))]
|
|
34
|
+
cmaps = ['binary', 'binary', 'RdGy']
|
|
35
|
+
|
|
36
|
+
ax = fig.add_subplot(gs[0, 0])
|
|
37
|
+
ax.set_axis_off()
|
|
38
|
+
im1 = ax.pcolormesh(np.zeros_like(images[0]), vmax=vmaxs[0], vmin=vmins[0], cmap='RdGy')
|
|
39
|
+
cbarax1 = fig.add_subplot(gs[:3, -1])
|
|
40
|
+
cbarax1.set_yticks([])
|
|
41
|
+
cbarax1.set_xticks([])
|
|
42
|
+
cbar1 = plt.colorbar(im1, cax=cbarax1, fraction=1)
|
|
43
|
+
tick_locator = ticker.MaxNLocator(nbins=5)
|
|
44
|
+
cbar1.locator = tick_locator
|
|
45
|
+
cbar1.update_ticks()
|
|
46
|
+
|
|
47
|
+
im2 = ax.pcolormesh(np.zeros_like(images[0]), vmax=vmaxs[-1], vmin=vmins[-1], cmap='RdGy')
|
|
48
|
+
cbarax2 = fig.add_subplot(gs[3, -1])
|
|
49
|
+
cbarax2.set_yticks([])
|
|
50
|
+
cbarax2.set_xticks([])
|
|
51
|
+
cbar2 = plt.colorbar(im2, cax=cbarax2, fraction=1)
|
|
52
|
+
tick_locator = ticker.MaxNLocator(nbins=3)
|
|
53
|
+
cbar2.locator = tick_locator
|
|
54
|
+
cbar2.update_ticks()
|
|
25
55
|
|
|
26
|
-
|
|
27
|
-
axes[0,i].set_axis_off()
|
|
56
|
+
for i in range(len(wavs)):
|
|
28
57
|
|
|
29
|
-
|
|
30
|
-
axes[1,i].set_axis_off()
|
|
58
|
+
plotims = [images[i], models[i], residuals[i], residuals[i]]
|
|
31
59
|
|
|
32
|
-
|
|
33
|
-
axes[2,i].set_axis_off()
|
|
60
|
+
for j in range(4):
|
|
34
61
|
|
|
62
|
+
ax = fig.add_subplot(gs[j, i])
|
|
63
|
+
im = ax.pcolormesh(plotims[j], vmax=vmaxs[j], vmin=vmins[j], cmap='RdGy')
|
|
64
|
+
ax.set_yticks([])
|
|
65
|
+
ax.set_xticks([])
|
|
35
66
|
|
|
36
|
-
|
|
67
|
+
if j==0:
|
|
68
|
+
ax.set_title(filter_names[i].upper())
|
|
69
|
+
|
|
70
|
+
if i==0:
|
|
71
|
+
if j==0:
|
|
72
|
+
ax.set_ylabel('Data')
|
|
73
|
+
if j==1:
|
|
74
|
+
ax.set_ylabel('Best\nModel')
|
|
75
|
+
if j==2:
|
|
76
|
+
ax.set_ylabel('Residual')
|
|
77
|
+
if j==3:
|
|
78
|
+
ax.set_ylabel('Residual\nZoom')
|
|
37
79
|
|
|
38
|
-
fig,axes=plt.subplots(3, images.shape[0], figsize=(images.shape[0],3))
|
|
39
80
|
|
|
81
|
+
plt.subplots_adjust(hspace=0.1, wspace=0.1)
|
|
82
|
+
fig.set_size_inches(images.shape[0],4, forward=True)
|
|
83
|
+
|
|
84
|
+
|
|
40
85
|
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def plot_median(self, images, wavs, convolved_models, samples, fitter_keys, prior_handler, filter_names):
|
|
89
|
+
|
|
90
|
+
fig = plt.figure()
|
|
91
|
+
gs = fig.add_gridspec(nrows=4, ncols=images.shape[0]+1, width_ratios=np.append(np.ones(images.shape[0]), 0.25))
|
|
92
|
+
|
|
41
93
|
models = np.zeros((samples.shape[0], *images.shape))
|
|
42
94
|
|
|
43
95
|
print("Computing median model image...")
|
|
@@ -55,33 +107,59 @@ class Plotter(object):
|
|
|
55
107
|
models[j,k] = model
|
|
56
108
|
|
|
57
109
|
|
|
58
|
-
|
|
110
|
+
models = np.median(models, axis=0)
|
|
111
|
+
residuals = images - models
|
|
59
112
|
|
|
60
113
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
114
|
+
vmins = [-np.percentile(images.flatten(), q=95), -np.percentile(images.flatten(), q=95), -np.percentile(images.flatten(), q=95), min(np.percentile(residuals.flatten(), q=5), -np.percentile(residuals.flatten(), q=95))]
|
|
115
|
+
vmaxs = [np.percentile(images.flatten(), q=95), np.percentile(images.flatten(), q=95), np.percentile(images.flatten(), q=95), max(-np.percentile(residuals.flatten(), q=5), np.percentile(residuals.flatten(), q=95))]
|
|
116
|
+
cmaps = ['binary', 'binary', 'RdGy']
|
|
64
117
|
|
|
65
|
-
|
|
66
|
-
|
|
118
|
+
ax = fig.add_subplot(gs[0, 0])
|
|
119
|
+
ax.set_axis_off()
|
|
120
|
+
im1 = ax.pcolormesh(np.zeros_like(images[0]), vmax=vmaxs[0], vmin=vmins[0], cmap='RdGy')
|
|
121
|
+
cbarax1 = fig.add_subplot(gs[:3, -1])
|
|
122
|
+
cbarax1.set_yticks([])
|
|
123
|
+
cbarax1.set_xticks([])
|
|
124
|
+
cbar1 = plt.colorbar(im1, cax=cbarax1, fraction=1)
|
|
125
|
+
tick_locator = ticker.MaxNLocator(nbins=5)
|
|
126
|
+
cbar1.locator = tick_locator
|
|
127
|
+
cbar1.update_ticks()
|
|
67
128
|
|
|
68
|
-
|
|
69
|
-
|
|
129
|
+
im2 = ax.pcolormesh(np.zeros_like(images[0]), vmax=vmaxs[-1], vmin=vmins[-1], cmap='RdGy')
|
|
130
|
+
cbarax2 = fig.add_subplot(gs[3, -1])
|
|
131
|
+
cbarax2.set_yticks([])
|
|
132
|
+
cbarax2.set_xticks([])
|
|
133
|
+
cbar2 = plt.colorbar(im2, cax=cbarax2, fraction=1)
|
|
134
|
+
tick_locator = ticker.MaxNLocator(nbins=3)
|
|
135
|
+
cbar2.locator = tick_locator
|
|
136
|
+
cbar2.update_ticks()
|
|
70
137
|
|
|
71
|
-
|
|
72
|
-
|
|
138
|
+
for i in range(len(wavs)):
|
|
139
|
+
|
|
140
|
+
plotims = [images[i], models[i], residuals[i], residuals[i]]
|
|
73
141
|
|
|
74
|
-
|
|
75
|
-
for i in range(len(wavs)):
|
|
142
|
+
for j in range(4):
|
|
76
143
|
|
|
77
|
-
|
|
144
|
+
ax = fig.add_subplot(gs[j, i])
|
|
145
|
+
im = ax.pcolormesh(plotims[j], vmax=vmaxs[j], vmin=vmins[j], cmap='RdGy')
|
|
146
|
+
ax.set_yticks([])
|
|
147
|
+
ax.set_xticks([])
|
|
78
148
|
|
|
79
|
-
|
|
80
|
-
|
|
149
|
+
if j==0:
|
|
150
|
+
ax.set_title(filter_names[i].upper())
|
|
81
151
|
|
|
82
|
-
|
|
83
|
-
|
|
152
|
+
if i==0:
|
|
153
|
+
if j==0:
|
|
154
|
+
ax.set_ylabel('Data')
|
|
155
|
+
if j==1:
|
|
156
|
+
ax.set_ylabel('Median\nModel')
|
|
157
|
+
if j==2:
|
|
158
|
+
ax.set_ylabel('Residual')
|
|
159
|
+
if j==3:
|
|
160
|
+
ax.set_ylabel('Residual\nZoom')
|
|
84
161
|
|
|
85
|
-
|
|
86
|
-
|
|
162
|
+
|
|
163
|
+
plt.subplots_adjust(hspace=0.1, wspace=0.1)
|
|
164
|
+
fig.set_size_inches(images.shape[0],4, forward=True)
|
|
87
165
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mimical
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.2
|
|
4
4
|
Summary: Intesity modelling of multiply-imaged objects
|
|
5
5
|
Author: Struan Stevenson
|
|
6
6
|
Author-email: struan.stevenson@ed.ac.uk
|
|
@@ -17,7 +17,7 @@ Dynamic: description-content-type
|
|
|
17
17
|
Dynamic: requires-dist
|
|
18
18
|
Dynamic: summary
|
|
19
19
|
|
|
20
|
-
# Mimical (Modelling the Intensity of Multiply-Imaged
|
|
20
|
+
# Mimical (Modelling the Intensity of Multiply-Imaged Celestial Ancient Light)
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
#### Mimical is an intensity modelling code for multiply-imaged objects, performing simultaenous Bayseian inference of model parameters via the nested sampling algorithm. Mimical supports any astropy model, and supports user defined parameter polynomial depenency with image wavelength.
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
mimical/__init__.py,sha256=cBuyDtPwn6KcIkjlT7oct36jigvYDJmbZNmnt1I1QJU,75
|
|
2
2
|
mimical/fitting/__init__.py,sha256=xcnLoeBDtt4Le5NhD6GhJe2ZRPNSsEySRHFYNuJyNEQ,69
|
|
3
|
-
mimical/fitting/fitter.py,sha256=
|
|
3
|
+
mimical/fitting/fitter.py,sha256=BjPT3wgGJ_KO4iyB9n0t4cqn0jfpU9d4IT0Gc1COoJc,10489
|
|
4
4
|
mimical/fitting/prior_handler.py,sha256=yXvxbohS6f94CMRyeIViFc83hRYAj82IZNA5mzhMSRw,4193
|
|
5
5
|
mimical/plotting/__init__.py,sha256=I1ZpQA48g-YPkqwrDGgTrqaTxDUgR8n0mbBX0MdbZtU,30
|
|
6
|
-
mimical/plotting/plotting.py,sha256=
|
|
6
|
+
mimical/plotting/plotting.py,sha256=y6uNeUh3Ifp8fapTPyN2eKT3OfnRhfNCUYq3ZN6lei4,6708
|
|
7
7
|
mimical/utils/__init__.py,sha256=yolMgYFpvXoHuyV-ijGo26SQ0_niw0gz__iAFgdiQiY,35
|
|
8
8
|
mimical/utils/filter_set.py,sha256=EITLa2c3FG3n1-v7KatKRwHCRyfZ4TTjsi_WM7Bz64k,6819
|
|
9
|
-
mimical-0.1.
|
|
10
|
-
mimical-0.1.
|
|
11
|
-
mimical-0.1.
|
|
12
|
-
mimical-0.1.
|
|
9
|
+
mimical-0.1.2.dist-info/METADATA,sha256=shzoz1K-wMSdIY0qzujhX7pxsoU6FBqcqy_3hRMgH1o,839
|
|
10
|
+
mimical-0.1.2.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
11
|
+
mimical-0.1.2.dist-info/top_level.txt,sha256=z6HTYpsoNjLUFayXjn8WyjX8C1mIbZw8Arb334cUbwc,8
|
|
12
|
+
mimical-0.1.2.dist-info/RECORD,,
|
|
File without changes
|