lauracabayol commited on
Commit
d307831
·
1 Parent(s): d68d8b1

fixing repo, untracking files and adding plots

Browse files
.gitignore CHANGED
@@ -1,2 +1,6 @@
1
- /insight/__pycache__/
2
- /insight/notebooks/.ipynb_checkpoints/
 
 
 
 
 
1
+ /insight/__pycache__/*
2
+ /notebooks/.ipynb_checkpoints/
3
+ /notebooks/*.ipynb
4
+ /notebooks/developer_notebooks
5
+ insight/.ipynb_checkpoints/
6
+ *.ipynb
insight/.ipynb_checkpoints/archive-checkpoint.py DELETED
@@ -1,212 +0,0 @@
1
- import numpy as np
2
- import pandas as pd
3
- from astropy.io import fits
4
- import os
5
- from astropy.table import Table
6
- from scipy.spatial import KDTree
7
-
8
- import matplotlib.pyplot as plt
9
-
10
- from matplotlib import rcParams
11
- rcParams["mathtext.fontset"] = "stix"
12
- rcParams["font.family"] = "STIXGeneral"
13
-
14
-
15
- class archive():
16
- def __init__(self, path, aperture=2, drop_stars=True, clean_photometry=True, convert_colors=True, extinction_corr=True, only_zspec=True, only_zspec_test=True, flags_kept=[3,3.1,3.4,3.5,4]):
17
-
18
- self.aperture = aperture
19
- self.flags_kept=flags_kept
20
-
21
-
22
-
23
- filename_calib='euclid_cosmos_DC2_S1_v2.1_calib_clean.fits'
24
- filename_valid='euclid_cosmos_DC2_S1_v2.1_valid_matched.fits'
25
-
26
- hdu_list = fits.open(os.path.join(path,filename_calib))
27
- cat = Table(hdu_list[1].data).to_pandas()
28
-
29
- hdu_list = fits.open(os.path.join(path,filename_valid))
30
- cat_test = Table(hdu_list[1].data).to_pandas()
31
-
32
-
33
- if drop_stars==True:
34
- cat = cat[cat.mu_class_L07==1]
35
- cat_test = cat_test[cat_test.mu_class_L07==1]
36
-
37
- if clean_photometry==True:
38
- cat = self._clean_photometry(cat)
39
- cat_test = self._clean_photometry(cat_test)
40
-
41
-
42
- cat = self._set_combiend_target(cat)
43
-
44
-
45
- self._set_training_data(cat, only_zspec=only_zspec, extinction_corr=extinction_corr, convert_colors=convert_colors)
46
- self._set_testing_data(cat_test, only_zspec=only_zspec_test, extinction_corr=extinction_corr, convert_colors=convert_colors)
47
-
48
-
49
- def _extract_fluxes(self,catalogue):
50
- columns_f = [f'FLUX_{x}_{self.aperture}' for x in ['G','R','I','Z','Y','J','H']]
51
- columns_ferr = [f'FLUXERR_{x}_{self.aperture}' for x in ['G','R','I','Z','Y','J','H']]
52
-
53
- f = catalogue[columns_f].values
54
- ferr = catalogue[columns_ferr].values
55
- return f, ferr
56
-
57
- def _to_colors(self, flux, fluxerr):
58
- """ Convert fluxes to colors"""
59
- color = flux[:,:-1] / flux[:,1:]
60
- color_err = fluxerr[:,:-1]**2 / flux[:,1:]**2 + flux[:,:-1]**2 / flux[:,1:]**4 * fluxerr[:,:-1]**2
61
- return color,color_err
62
-
63
- def _set_combiend_target(self, catalogue):
64
- catalogue['target_z'] = catalogue.apply(lambda row: row['z_spec_S15'] if row['z_spec_S15'] > 0 else row['photo_z_L15'], axis=1)
65
-
66
- return catalogue
67
-
68
-
69
- def _clean_photometry(self,catalogue):
70
- """ Drops all object with FLAG_PHOT!=0"""
71
- catalogue = catalogue[catalogue['FLAG_PHOT']==0]
72
-
73
- return catalogue
74
-
75
- def _correct_extinction(self,catalogue, f):
76
- """Corrects for extinction"""
77
- ext_correction_cols = [f'EB_V_corr_FLUX_{x}' for x in ['G','R','I','Z','Y','J','H']]
78
- ext_correction = catalogue[ext_correction_cols].values
79
-
80
- f = f * ext_correction
81
- return f
82
-
83
- def _take_only_zspec(self,catalogue,cat_flag=None):
84
- """Selects only galaxies with spectroscopic redshift"""
85
- if cat_flag=='Calib':
86
- catalogue = catalogue[catalogue.z_spec_S15>0]
87
- elif cat_flag=='Valid':
88
- catalogue = catalogue[catalogue.z_spec_S15>0]
89
- return catalogue
90
-
91
- def _take_zspec_and_photoz(self,catalogue,cat_flag=None):
92
- """Selects only galaxies with spectroscopic redshift"""
93
- if cat_flag=='Calib':
94
- catalogue = catalogue[catalogue.target_z>0]
95
- elif cat_flag=='Valid':
96
- catalogue = catalogue[catalogue.z_spec_S15>0]
97
- return catalogue
98
-
99
- def _clean_zspec_sample(self,catalogue ,flags_kept=[3,3.1,3.4,3.5,4]):
100
- #[ 2.5, 3.5, 4. , 1.5, 1.1, 13.5, 9. , 3. , 2.1, 9.5, 3.1,
101
- #1. , 9.1, 2. , 9.3, 1.4, 3.4, 11.5, 2.4, 13. , 14. , 12.1,
102
- #12.5, 13.1, 9.4, 11.1]
103
-
104
- catalogue = catalogue[catalogue.Q_f_S15.isin(flags_kept)]
105
-
106
- return catalogue
107
-
108
-
109
-
110
- def _match_gold_sample(self,catalogue_valid, catalogue_gold, max_distance_arcsec=2):
111
- max_distance_deg = max_distance_arcsec / 3600.0
112
-
113
- gold_sample_radec = np.c_[catalogue_gold.RIGHT_ASCENSION,catalogue_gold.DECLINATION]
114
- valid_sample_radec = np.c_[catalogue_valid['RA'],catalogue_valid['DEC']]
115
-
116
- kdtree = KDTree(gold_sample_radec)
117
- distances, indices = kdtree.query(valid_sample_radec, k=1)
118
-
119
- specz_match_gold = catalogue_gold.FINAL_SPEC_Z.values[indices]
120
-
121
- zs = [specz_match_gold[i] if distance < max_distance_deg else -99 for i, distance in enumerate(distances)]
122
-
123
- catalogue_valid['z_spec_gold'] = zs
124
-
125
- return catalogue_valid
126
-
127
-
128
- def _set_training_data(self,catalogue, only_zspec=True, extinction_corr=True, convert_colors=True):
129
-
130
-
131
-
132
- if only_zspec:
133
- catalogue = self._take_only_zspec(catalogue, cat_flag='Calib')
134
- catalogue = self._clean_zspec_sample(catalogue, flags_kept=self.flags_kept)
135
- else:
136
- catalogue = self._take_zspec_and_photoz(catalogue, cat_flag='Calib')
137
-
138
-
139
- self.cat_train=catalogue
140
- f, ferr = self._extract_fluxes(catalogue)
141
-
142
-
143
- if extinction_corr==True:
144
- f = self._correct_extinction(catalogue,f)
145
-
146
- if convert_colors==True:
147
- col, colerr = self._to_colors(f, ferr)
148
-
149
- self.phot_train = col
150
- self.photerr_train = colerr
151
- else:
152
- self.phot_train = f
153
- self.photerr_train = ferr
154
-
155
- if only_zspec==True:
156
- self.target_z_train = catalogue['z_spec_S15'].values
157
- else:
158
- self.target_z_train = catalogue['target_z'].values
159
-
160
- self.VIS_mag_train = catalogue['MAG_VIS'].values
161
-
162
- def _set_testing_data(self,catalogue, only_zspec=True, extinction_corr=True, convert_colors=True):
163
-
164
- if only_zspec:
165
- catalogue = self._take_only_zspec(catalogue, cat_flag='Valid')
166
- catalogue = self._clean_zspec_sample(catalogue)
167
-
168
- self.cat_test=catalogue
169
-
170
- f, ferr = self._extract_fluxes(catalogue)
171
-
172
-
173
- if extinction_corr==True:
174
- f = self._correct_extinction(catalogue,f)
175
-
176
- if convert_colors==True:
177
- col, colerr = self._to_colors(f, ferr)
178
- self.phot_test = col
179
- self.photerr_test = colerr
180
- else:
181
- self.phot_test = f
182
- self.photerr_test = ferr
183
-
184
- self.target_z_test = catalogue['z_spec_S15'].values
185
- self.VIS_mag_test = catalogue['MAG_VIS'].values
186
-
187
-
188
- def get_training_data(self):
189
- return self.phot_train, self.photerr_train, self.target_z_train, self.VIS_mag_train
190
-
191
- def get_testing_data(self):
192
- return self.phot_test, self.photerr_test, self.target_z_test, self.VIS_mag_test
193
-
194
- def get_VIS_mag(self, catalogue):
195
- return catalogue[['MAG_VIS']].values
196
-
197
- def plot_zdistribution(self, plot_test=False, bins=50):
198
- _,_,specz = photoz_archive.get_training_data()
199
- plt.hist(specz, bins = bins, hisstype='step', color='navy', label=r'Training sample')
200
-
201
- if plot_test:
202
- _,_,specz_test = photoz_archive.get_training_data()
203
- plt.hist(specz, bins = bins, hisstype='step', color='goldenrod', label=r'Test sample',ls='--')
204
-
205
-
206
- plt.xticks(fontsize=12)
207
- plt.yticks(fontsize=12)
208
-
209
- plt.xlabel(r'Redshift', fontsize=14)
210
- plt.ylabel('Counts', fontsize=14)
211
-
212
- plt.show()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
insight/.ipynb_checkpoints/insight-checkpoint.py DELETED
@@ -1,284 +0,0 @@
1
- import torch
2
- from torch.utils.data import DataLoader, dataset, TensorDataset
3
- from torch import nn, optim
4
- from torch.optim import lr_scheduler
5
- import numpy as np
6
- import pandas as pd
7
- from astropy.io import fits
8
- import os
9
- from astropy.table import Table
10
- from scipy.spatial import KDTree
11
- from scipy.special import erf
12
- from scipy.stats import norm
13
-
14
- class Insight_module():
15
- """ Define class"""
16
-
17
- def __init__(self, model, batch_size=100,rejection_param=1):
18
- self.model=model
19
- self.device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
20
- self.batch_size=batch_size
21
- self.rejection_parameter=rejection_param
22
-
23
-
24
-
25
- def _get_dataloaders(self, input_data, target_data, additional_data=None, val_fraction=0.1):
26
- input_data = torch.Tensor(input_data)
27
- target_data = torch.Tensor(target_data)
28
-
29
- if additional_data is None:
30
- dataset = TensorDataset(input_data, target_data)
31
- else:
32
- additional_data = torch.Tensor(additional_data)
33
- dataset = TensorDataset(input_data, target_data,additional_data)
34
-
35
-
36
- trainig_dataset, val_dataset = torch.utils.data.random_split(dataset, [int(len(dataset)*(1-val_fraction)), int(len(dataset)*val_fraction)+1])
37
- loader_train = DataLoader(trainig_dataset, batch_size=self.batch_size, shuffle = True)
38
- loader_val = DataLoader(val_dataset, batch_size=64, shuffle = True)
39
-
40
- return loader_train, loader_val
41
-
42
-
43
-
44
-
45
- def _loss_function(self,mean, std, logmix, true):
46
-
47
- log_prob = logmix - 0.5*(mean - true[:,None]).pow(2) / std.pow(2) - torch.log(std)
48
- log_prob = torch.logsumexp(log_prob, 1)
49
- loss = -log_prob.mean()
50
-
51
-
52
- return loss
53
-
54
- def _to_numpy(self,x):
55
- return x.detach().cpu().numpy()
56
-
57
-
58
-
59
- def train(self,input_data, target_data, nepochs=10, step_size = 100, val_fraction=0.1, lr=1e-3 ):
60
- self.model = self.model.train()
61
- loader_train, loader_val = self._get_dataloaders(input_data, target_data, val_fraction=0.1)
62
- optimizer = optim.Adam(self.model.parameters(), lr=lr, weight_decay=1e-4)
63
- scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=step_size, gamma =0.1)
64
-
65
-
66
- self.model = self.model.to(self.device)
67
-
68
- self.loss_train, self.loss_validation = [],[]
69
-
70
-
71
-
72
- for epoch in range(nepochs):
73
- for input_data, target_data in loader_train:
74
- _loss_train, _loss_validation = [],[]
75
-
76
- input_data = input_data.to(self.device)
77
- target_data = target_data.to(self.device)
78
-
79
-
80
- optimizer.zero_grad()
81
-
82
- mu, logsig, logmix_coeff = self.model(input_data)
83
- logsig = torch.clamp(logsig,-6,2)
84
- sig = torch.exp(logsig)
85
-
86
-
87
-
88
- loss = self._loss_function(mu, sig, logmix_coeff, target_data)
89
- _loss_train.append(loss.item())
90
-
91
- loss.backward()
92
- optimizer.step()
93
-
94
- scheduler.step()
95
-
96
- self.loss_train.append(np.mean(_loss_train))
97
-
98
- for input_data, target_data in loader_val:
99
-
100
-
101
- input_data = input_data.to(self.device)
102
- target_data = target_data.to(self.device)
103
-
104
-
105
- mu, logsig, logmix_coeff = self.model(input_data)
106
- logsig = torch.clamp(logsig,-6,2)
107
- sig = torch.exp(logsig)
108
-
109
- loss_val = self._loss_function(mu, sig, logmix_coeff, target_data)
110
- _loss_validation.append(loss_val.item())
111
-
112
- self.loss_validation.append(np.mean(_loss_validation))
113
-
114
- print(f'training_loss:{loss}',f'testing_loss:{loss_val}')
115
-
116
-
117
-
118
-
119
- def get_pz(self,input_data, target_data, return_pz=False):
120
- self.model = self.model.eval()
121
- self.model = self.model.to(self.device)
122
-
123
- input_data = input_data.to(self.device)
124
- target_data = target_data.to(self.device)
125
-
126
-
127
-
128
- mu, logsig, logmix_coeff = self.model(input_data)
129
- logsig = torch.clamp(logsig,-6,2)
130
- sig = torch.exp(logsig)
131
-
132
- mix_coeff = torch.exp(logmix_coeff)
133
-
134
- z = (mix_coeff * mu).sum(1)
135
- zerr = torch.sqrt( (mix_coeff * sig**2).sum(1) + (mix_coeff * (mu - target_data[:,None])**2).sum(1))
136
-
137
- mu, mix_coeff, sig = mu.detach().cpu().numpy(), mix_coeff.detach().cpu().numpy(), sig.detach().cpu().numpy()
138
-
139
-
140
- if return_pz==True:
141
- x = np.linspace(0, 4, 1000)
142
- pdf_mixture = np.zeros(shape=(len(target_data), len(x)))
143
- for ii in range(len(input_data)):
144
- for i in range(6):
145
- pdf_mixture[ii] += mix_coeff[ii,i] * norm.pdf(x, mu[ii,i], sig[ii,i])
146
-
147
- return self._to_numpy(z),self._to_numpy(zerr), pdf_mixture
148
-
149
- else:
150
- return self._to_numpy(z),self._to_numpy(zerr)
151
-
152
- def pit(self, input_data, target_data):
153
-
154
- pit_list = []
155
-
156
- self.model = self.model.eval()
157
- self.model = self.model.to(self.device)
158
-
159
- input_data = input_data.to(self.device)
160
-
161
-
162
- mu, logsig, logmix_coeff = self.model(input_data)
163
- logsig = torch.clamp(logsig,-6,2)
164
- sig = torch.exp(logsig)
165
-
166
- mix_coeff = torch.exp(logmix_coeff)
167
-
168
- mu, mix_coeff, sig = mu.detach().cpu().numpy(), mix_coeff.detach().cpu().numpy(), sig.detach().cpu().numpy()
169
-
170
- for ii in range(len(input_data)):
171
- pit = (mix_coeff[ii] * norm.cdf(target_data[ii]*np.ones(mu[ii].shape),mu[ii], sig[ii])).sum()
172
- pit_list.append(pit)
173
-
174
-
175
- return pit_list
176
-
177
- def crps(self, input_data, target_data):
178
-
179
- def measure_crps(cdf, t):
180
- zgrid = np.linspace(0,4,1000)
181
- Deltaz = zgrid[None,:] - t[:,None]
182
- DeltaZ_heaviside = np.where(Deltaz < 0,0,1)
183
- integral = (cdf-DeltaZ_heaviside)**2
184
- crps_value = integral.sum(1) / 1000
185
-
186
- return crps_value
187
-
188
-
189
- crps_list = []
190
-
191
- self.model = self.model.eval()
192
- self.model = self.model.to(self.device)
193
-
194
- input_data = input_data.to(self.device)
195
-
196
-
197
- mu, logsig, logmix_coeff = self.model(input_data)
198
- logsig = torch.clamp(logsig,-6,2)
199
- sig = torch.exp(logsig)
200
-
201
- mix_coeff = torch.exp(logmix_coeff)
202
-
203
-
204
- mu, mix_coeff, sig = mu.detach().cpu().numpy(), mix_coeff.detach().cpu().numpy(), sig.detach().cpu().numpy()
205
-
206
- z = (mix_coeff * mu).sum(1)
207
-
208
- x = np.linspace(0, 4, 1000)
209
- pdf_mixture = np.zeros(shape=(len(target_data), len(x)))
210
- for ii in range(len(input_data)):
211
- for i in range(6):
212
- pdf_mixture[ii] += mix_coeff[ii,i] * norm.pdf(x, mu[ii,i], sig[ii,i])
213
-
214
- pdf_mixture = pdf_mixture / pdf_mixture.sum(1)[:,None]
215
-
216
-
217
- cdf_mixture = np.cumsum(pdf_mixture,1)
218
-
219
- crps_value = measure_crps(cdf_mixture, target_data)
220
-
221
-
222
-
223
- return crps_value
224
-
225
-
226
- def plot_photoz(self, df, nbins,xvariable,metric, type_bin='bin'):
227
- bin_edges = stats.mstats.mquantiles(df[xvariable].values, np.linspace(0.1,1,nbins))
228
- ydata,xlab = [],[]
229
-
230
-
231
- for k in range(len(bin_edges)-1):
232
- edge_min = bin_edges[k]
233
- edge_max = bin_edges[k+1]
234
-
235
- mean_mag = (edge_max + edge_min) / 2
236
-
237
- if type_bin=='bin':
238
- df_plot = df_test[(df_test.imag > edge_min) & (df_test.imag < edge_max)]
239
- elif type_bin=='cum':
240
- df_plot = df_test[(df_test.imag < edge_max)]
241
- else:
242
- raise ValueError("Only type_bin=='bin' for binned and 'cum' for cumulative are supported")
243
-
244
-
245
- xlab.append(mean_mag)
246
- if metric=='sig68':
247
- ydata.append(sigma68(df_plot.zwerr))
248
- elif metric=='bias':
249
- ydata.append(np.mean(df_plot.zwerr))
250
- elif metric=='nmad':
251
- ydata.append(nmad(df_plot.zwerr))
252
- elif metric=='outliers':
253
- ydata.append(len(df_plot[np.abs(df_plot.zwerr)>0.15])/len(df_plot))
254
-
255
- plt.plot(xlab,ydata, ls = '-', marker = '.', color = 'navy',lw = 1, label = '')
256
- plt.ylabel(f'{metric}$[\Delta z]$', fontsize = 18)
257
- plt.xlabel(f'{xvariable}', fontsize = 16)
258
-
259
- plt.xticks(fontsize = 14)
260
- plt.yticks(fontsize = 14)
261
-
262
- plt.grid(False)
263
-
264
- plt.show()
265
-
266
-
267
- def plot_pz(self, m, pz, specz):
268
- # Create a figure and axis
269
- fig, ax = plt.subplots(figsize=(8, 6))
270
-
271
- # Plot the PDF with a label
272
- ax.plot(np.linspace(0, 4, 1000), pz[m], label='PDF', color='navy')
273
-
274
- # Add a vertical line for 'specz_test'
275
- ax.axvline(specz[m], color='black', linestyle='--', label=r'$z_{\rm s}$')
276
-
277
- # Add labels and a legend
278
- ax.set_xlabel(r'$z$', fontsize = 18)
279
- ax.set_ylabel('Probability Density', fontsize=16)
280
- ax.legend(fontsize = 18)
281
-
282
- # Display the plot
283
- plt.show()
284
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
insight/.ipynb_checkpoints/insight_arch-checkpoint.py DELETED
@@ -1,60 +0,0 @@
1
- from torch import nn, optim
2
- import torch
3
-
4
- from torch import nn, optim
5
- import torch
6
- class Photoz_network(nn.Module):
7
- def __init__(self, num_gauss=10, dropout_prob=0):
8
- super(Photoz_network, self).__init__()
9
-
10
- self.features = nn.Sequential(
11
- nn.Linear(6, 10),
12
- nn.Dropout(dropout_prob),
13
- nn.ReLU(),
14
- nn.Linear(10, 20),
15
- nn.Dropout(dropout_prob),
16
- nn.ReLU(),
17
- nn.Linear(20, 50),
18
- nn.Dropout(dropout_prob),
19
- nn.ReLU(),
20
- nn.Linear(50, 20),
21
- nn.Dropout(dropout_prob),
22
- nn.ReLU(),
23
- nn.Linear(20, 10)
24
- )
25
-
26
- self.measure_mu = nn.Sequential(
27
- nn.Linear(10, 20),
28
- nn.Dropout(dropout_prob),
29
- nn.ReLU(),
30
- nn.Linear(20, num_gauss)
31
- )
32
-
33
- self.measure_coeffs = nn.Sequential(
34
- nn.Linear(10, 20),
35
- nn.Dropout(dropout_prob),
36
- nn.ReLU(),
37
- nn.Linear(20, num_gauss)
38
- )
39
-
40
- self.measure_sigma = nn.Sequential(
41
- nn.Linear(10, 20),
42
- nn.Dropout(dropout_prob),
43
- nn.ReLU(),
44
- nn.Linear(20, num_gauss)
45
- )
46
-
47
-
48
- def forward(self, x):
49
- f = self.features(x)
50
- mu = self.measure_mu(f)
51
- sigma = self.measure_sigma(f)
52
- logmix_coeff = self.measure_coeffs(f)
53
-
54
- logmix_coeff = logmix_coeff - torch.logsumexp(logmix_coeff, 1)[:,None]
55
-
56
- return mu, sigma, logmix_coeff
57
-
58
-
59
-
60
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
insight/.ipynb_checkpoints/utils-checkpoint.py DELETED
@@ -1,62 +0,0 @@
1
- import numpy as np
2
- import pandas as pd
3
- import matplotlib.pyplot as plt
4
- from scipy import stats
5
-
6
- def nmad(data):
7
- return 1.4826 * np.median(np.abs(data - np.median(data)))
8
-
9
- def sigma68(data): return 0.5*(pd.Series(data).quantile(q = 0.84) - pd.Series(data).quantile(q = 0.16))
10
-
11
-
12
- def plot_photoz_estimates(df, nbins,xvariable,metric, type_bin='bin'):
13
- bin_edges = stats.mstats.mquantiles(df[xvariable].values, np.linspace(0.1,1,nbins))
14
- ydata,xdata = [],[]
15
-
16
-
17
- for k in range(len(bin_edges)-1):
18
- edge_min = bin_edges[k]
19
- edge_max = bin_edges[k+1]
20
-
21
- mean_mag = (edge_max + edge_min) / 2
22
-
23
- if type_bin=='bin':
24
- df_plot = df_test[(df_test[xvariable] > edge_min) & (df_test[xvariable] < edge_max)]
25
- elif type_bin=='cum':
26
- df_plot = df_test[(df_test[xvariable] < edge_max)]
27
- else:
28
- raise ValueError("Only type_bin=='bin' for binned and 'cum' for cumulative are supported")
29
-
30
-
31
- xdata.append(mean_mag)
32
- if metric=='sig68':
33
- ydata.append(sigma68(df_plot.zwerr))
34
- ylab=r'$\sigma_{\rm NMAD} [\Delta z]$'
35
- elif metric=='bias':
36
- ydata.append(np.median(df_plot.zwerr))
37
- ylab=r'Median $[\Delta z]$'
38
- elif metric=='nmad':
39
- ydata.append(nmad(df_plot.zwerr))
40
- ylab=r'$\sigma_{\rm NMAD} [\Delta z]$'
41
- elif metric=='outliers':
42
- ydata.append(len(df_plot[np.abs(df_plot.zwerr)>0.15])/len(df_plot) *100)
43
- ylab=r'$\eta$ [%]'
44
-
45
- if xvariable=='VISmag':
46
- xlab='VIS'
47
- elif xvariable=='zs':
48
- xlab=r'$z_{\rm spec}$'
49
- elif xvariable=='z':
50
- xlab=r'$z$'
51
-
52
- plt.plot(xdata,ydata, ls = '-', marker = '.', color = 'navy',lw = 1, label = '')
53
- plt.ylabel(f'{ylab}', fontsize = 18)
54
- plt.xlabel(f'{xlab}', fontsize = 16)
55
-
56
- plt.xticks(fontsize = 14)
57
- plt.yticks(fontsize = 14)
58
-
59
- plt.grid(False)
60
-
61
- plt.show()
62
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
insight/__pycache__/archive.cpython-310.pyc DELETED
Binary file (6.76 kB)
 
insight/__pycache__/archive.cpython-39.pyc DELETED
Binary file (6.91 kB)
 
insight/__pycache__/insight.cpython-310.pyc DELETED
Binary file (7.18 kB)
 
insight/__pycache__/insight.cpython-39.pyc DELETED
Binary file (9.49 kB)
 
insight/__pycache__/insight_arch.cpython-310.pyc DELETED
Binary file (1.37 kB)
 
insight/__pycache__/insight_arch.cpython-39.pyc DELETED
Binary file (2.22 kB)
 
insight/__pycache__/utils.cpython-310.pyc DELETED
Binary file (2.4 kB)
 
insight/__pycache__/utils.cpython-39.pyc DELETED
Binary file (2.41 kB)
 
insight/archive.py CHANGED
@@ -13,7 +13,7 @@ rcParams["font.family"] = "STIXGeneral"
13
 
14
 
15
  class archive():
16
- def __init__(self, path, aperture=2, drop_stars=True, clean_photometry=True, convert_colors=True, extinction_corr=True, only_zspec=True, only_zspec_test=True, flags_kept=[3,3.1,3.4,3.5,4]):
17
 
18
  self.aperture = aperture
19
  self.flags_kept=flags_kept
@@ -25,6 +25,8 @@ class archive():
25
 
26
  hdu_list = fits.open(os.path.join(path,filename_calib))
27
  cat = Table(hdu_list[1].data).to_pandas()
 
 
28
 
29
  hdu_list = fits.open(os.path.join(path,filename_valid))
30
  cat_test = Table(hdu_list[1].data).to_pandas()
@@ -40,10 +42,20 @@ class archive():
40
 
41
 
42
  cat = self._set_combiend_target(cat)
43
-
 
 
 
 
 
 
 
 
 
 
44
 
45
  self._set_training_data(cat, only_zspec=only_zspec, extinction_corr=extinction_corr, convert_colors=convert_colors)
46
- self._set_testing_data(cat_test, only_zspec=only_zspec_test, extinction_corr=extinction_corr, convert_colors=convert_colors)
47
 
48
 
49
  def _extract_fluxes(self,catalogue):
@@ -80,7 +92,7 @@ class archive():
80
  f = f * ext_correction
81
  return f
82
 
83
- def _take_only_zspec(self,catalogue,cat_flag=None):
84
  """Selects only galaxies with spectroscopic redshift"""
85
  if cat_flag=='Calib':
86
  catalogue = catalogue[catalogue.z_spec_S15>0]
@@ -88,6 +100,19 @@ class archive():
88
  catalogue = catalogue[catalogue.z_spec_S15>0]
89
  return catalogue
90
 
 
 
 
 
 
 
 
 
 
 
 
 
 
91
  def _take_zspec_and_photoz(self,catalogue,cat_flag=None):
92
  """Selects only galaxies with spectroscopic redshift"""
93
  if cat_flag=='Calib':
@@ -127,10 +152,12 @@ class archive():
127
 
128
  def _set_training_data(self,catalogue, only_zspec=True, extinction_corr=True, convert_colors=True):
129
 
130
-
 
 
131
 
132
  if only_zspec:
133
- catalogue = self._take_only_zspec(catalogue, cat_flag='Calib')
134
  catalogue = self._clean_zspec_sample(catalogue, flags_kept=self.flags_kept)
135
  else:
136
  catalogue = self._take_zspec_and_photoz(catalogue, cat_flag='Calib')
@@ -138,6 +165,12 @@ class archive():
138
 
139
  self.cat_train=catalogue
140
  f, ferr = self._extract_fluxes(catalogue)
 
 
 
 
 
 
141
 
142
 
143
  if extinction_corr==True:
@@ -145,12 +178,17 @@ class archive():
145
 
146
  if convert_colors==True:
147
  col, colerr = self._to_colors(f, ferr)
148
-
 
149
  self.phot_train = col
150
  self.photerr_train = colerr
 
 
151
  else:
152
  self.phot_train = f
153
  self.photerr_train = ferr
 
 
154
 
155
  if only_zspec==True:
156
  self.target_z_train = catalogue['z_spec_S15'].values
@@ -159,16 +197,22 @@ class archive():
159
 
160
  self.VIS_mag_train = catalogue['MAG_VIS'].values
161
 
162
- def _set_testing_data(self,catalogue, only_zspec=True, extinction_corr=True, convert_colors=True):
163
-
164
- if only_zspec:
165
- catalogue = self._take_only_zspec(catalogue, cat_flag='Valid')
166
  catalogue = self._clean_zspec_sample(catalogue)
 
 
 
 
 
 
167
 
 
168
  self.cat_test=catalogue
169
 
170
  f, ferr = self._extract_fluxes(catalogue)
171
-
172
 
173
  if extinction_corr==True:
174
  f = self._correct_extinction(catalogue,f)
@@ -181,12 +225,12 @@ class archive():
181
  self.phot_test = f
182
  self.photerr_test = ferr
183
 
184
- self.target_z_test = catalogue['z_spec_S15'].values
185
  self.VIS_mag_test = catalogue['MAG_VIS'].values
186
 
187
 
188
  def get_training_data(self):
189
- return self.phot_train, self.photerr_train, self.target_z_train, self.VIS_mag_train
190
 
191
  def get_testing_data(self):
192
  return self.phot_test, self.photerr_test, self.target_z_test, self.VIS_mag_test
 
13
 
14
 
15
  class archive():
16
+ def __init__(self, path, aperture=2, drop_stars=True, clean_photometry=True, convert_colors=True, extinction_corr=True, only_zspec=True, target_test='specz', flags_kept=[3,3.1,3.4,3.5,4]):
17
 
18
  self.aperture = aperture
19
  self.flags_kept=flags_kept
 
25
 
26
  hdu_list = fits.open(os.path.join(path,filename_calib))
27
  cat = Table(hdu_list[1].data).to_pandas()
28
+ cat = cat[(cat['z_spec_S15'] > 0) | (cat['photo_z_L15'] > 0)]
29
+
30
 
31
  hdu_list = fits.open(os.path.join(path,filename_valid))
32
  cat_test = Table(hdu_list[1].data).to_pandas()
 
42
 
43
 
44
  cat = self._set_combiend_target(cat)
45
+ cat_test = self._set_combiend_target(cat_test)
46
+
47
+
48
+
49
+ cat = cat[cat.MAG_VIS<25]
50
+ cat_test = cat_test[cat_test.MAG_VIS<25]
51
+
52
+ cat = cat[cat.target_z<5]
53
+ cat_test = cat_test[cat_test.target_z<5]
54
+
55
+
56
 
57
  self._set_training_data(cat, only_zspec=only_zspec, extinction_corr=extinction_corr, convert_colors=convert_colors)
58
+ self._set_testing_data(cat_test, target=target_test, extinction_corr=extinction_corr, convert_colors=convert_colors)
59
 
60
 
61
  def _extract_fluxes(self,catalogue):
 
92
  f = f * ext_correction
93
  return f
94
 
95
+ def _select_only_zspec(self,catalogue,cat_flag=None):
96
  """Selects only galaxies with spectroscopic redshift"""
97
  if cat_flag=='Calib':
98
  catalogue = catalogue[catalogue.z_spec_S15>0]
 
100
  catalogue = catalogue[catalogue.z_spec_S15>0]
101
  return catalogue
102
 
103
+ def _exclude_only_zspec(self,catalogue):
104
+ """Selects only galaxies without spectroscopic redshift"""
105
+ catalogue = catalogue[(catalogue.z_spec_S15<0)&(catalogue.photo_z_L15>0)&(catalogue.photo_z_L15<4)]
106
+ return catalogue
107
+
108
+ def _select_L15_sample(self,catalogue):
109
+ """Selects only galaxies withoutidx spectroscopic redshift"""
110
+ catalogue = catalogue[(catalogue.target_z>0)]
111
+ catalogue = catalogue[(catalogue.target_z<4)]
112
+
113
+
114
+ return catalogue
115
+
116
  def _take_zspec_and_photoz(self,catalogue,cat_flag=None):
117
  """Selects only galaxies with spectroscopic redshift"""
118
  if cat_flag=='Calib':
 
152
 
153
  def _set_training_data(self,catalogue, only_zspec=True, extinction_corr=True, convert_colors=True):
154
 
155
+ cat_da = self._exclude_only_zspec(catalogue)
156
+ target_z_train_DA = cat_da['photo_z_L15'].values
157
+
158
 
159
  if only_zspec:
160
+ catalogue = self._select_only_zspec(catalogue, cat_flag='Calib')
161
  catalogue = self._clean_zspec_sample(catalogue, flags_kept=self.flags_kept)
162
  else:
163
  catalogue = self._take_zspec_and_photoz(catalogue, cat_flag='Calib')
 
165
 
166
  self.cat_train=catalogue
167
  f, ferr = self._extract_fluxes(catalogue)
168
+
169
+ f_DA, ferr_DA = self._extract_fluxes(cat_da)
170
+ idx = np.random.randint(0, len(f_DA), len(f))
171
+ f_DA, ferr_DA = f_DA[idx], ferr_DA[idx]
172
+ target_z_train_DA = target_z_train_DA[idx]
173
+ self.target_z_train_DA = target_z_train_DA
174
 
175
 
176
  if extinction_corr==True:
 
178
 
179
  if convert_colors==True:
180
  col, colerr = self._to_colors(f, ferr)
181
+ col_DA, colerr_DA = self._to_colors(f_DA, ferr_DA)
182
+
183
  self.phot_train = col
184
  self.photerr_train = colerr
185
+ self.phot_train_DA = col_DA
186
+ self.photerr_train_DA = colerr_DA
187
  else:
188
  self.phot_train = f
189
  self.photerr_train = ferr
190
+ self.phot_train_DA = f_DA
191
+ self.photerr_train_DA = ferr_DA
192
 
193
  if only_zspec==True:
194
  self.target_z_train = catalogue['z_spec_S15'].values
 
197
 
198
  self.VIS_mag_train = catalogue['MAG_VIS'].values
199
 
200
+ def _set_testing_data(self,catalogue, target='specz', extinction_corr=True, convert_colors=True):
201
+
202
+ if target=='specz':
203
+ catalogue = self._select_only_zspec(catalogue, cat_flag='Valid')
204
  catalogue = self._clean_zspec_sample(catalogue)
205
+ self.target_z_test = catalogue['z_spec_S15'].values
206
+
207
+ elif target=='L15':
208
+ catalogue = self._select_L15_sample(catalogue)
209
+ catalogue = catalogue[(catalogue.target_z>0.2)&(catalogue.target_z<2.6)]
210
+ self.target_z_test = catalogue['target_z'].values
211
 
212
+
213
  self.cat_test=catalogue
214
 
215
  f, ferr = self._extract_fluxes(catalogue)
 
216
 
217
  if extinction_corr==True:
218
  f = self._correct_extinction(catalogue,f)
 
225
  self.phot_test = f
226
  self.photerr_test = ferr
227
 
228
+
229
  self.VIS_mag_test = catalogue['MAG_VIS'].values
230
 
231
 
232
  def get_training_data(self):
233
+ return self.phot_train, self.photerr_train, self.target_z_train, self.VIS_mag_train, self.phot_train_DA, self.photerr_train_DA, self.target_z_train_DA
234
 
235
  def get_testing_data(self):
236
  return self.phot_test, self.photerr_test, self.target_z_test, self.VIS_mag_test
insight/insight.py CHANGED
@@ -10,29 +10,38 @@ from astropy.table import Table
10
  from scipy.spatial import KDTree
11
  from scipy.special import erf
12
  from scipy.stats import norm
 
 
 
 
13
 
14
  class Insight_module():
15
  """ Define class"""
16
 
17
- def __init__(self, model, batch_size=100,rejection_param=1):
18
- self.model=model
 
 
 
 
 
19
  self.device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
20
  self.batch_size=batch_size
21
  self.rejection_parameter=rejection_param
22
 
23
 
24
 
25
- def _get_dataloaders(self, input_data, target_data, additional_data=None, val_fraction=0.1):
26
  input_data = torch.Tensor(input_data)
27
  target_data = torch.Tensor(target_data)
28
-
29
- if additional_data is None:
30
- dataset = TensorDataset(input_data, target_data)
31
  else:
32
- additional_data = torch.Tensor(additional_data)
33
- dataset = TensorDataset(input_data, target_data,additional_data)
34
-
35
-
36
  trainig_dataset, val_dataset = torch.utils.data.random_split(dataset, [int(len(dataset)*(1-val_fraction)), int(len(dataset)*val_fraction)+1])
37
  loader_train = DataLoader(trainig_dataset, batch_size=self.batch_size, shuffle = True)
38
  loader_val = DataLoader(val_dataset, batch_size=64, shuffle = True)
@@ -48,61 +57,103 @@ class Insight_module():
48
  log_prob = torch.logsumexp(log_prob, 1)
49
  loss = -log_prob.mean()
50
 
51
-
52
- return loss
 
 
 
 
 
 
 
 
53
 
54
  def _to_numpy(self,x):
55
  return x.detach().cpu().numpy()
56
 
57
 
58
 
59
- def train(self,input_data, target_data, nepochs=10, step_size = 100, val_fraction=0.1, lr=1e-3 ):
60
- self.model = self.model.train()
61
- loader_train, loader_val = self._get_dataloaders(input_data, target_data, val_fraction=0.1)
62
- optimizer = optim.Adam(self.model.parameters(), lr=lr, weight_decay=1e-4)
63
- scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=step_size, gamma =0.1)
64
-
65
-
66
- self.model = self.model.to(self.device)
 
 
 
 
 
 
 
 
 
 
67
 
 
 
 
68
  self.loss_train, self.loss_validation = [],[]
69
 
70
-
71
-
72
  for epoch in range(nepochs):
73
- for input_data, target_data in loader_train:
74
  _loss_train, _loss_validation = [],[]
75
 
76
  input_data = input_data.to(self.device)
77
  target_data = target_data.to(self.device)
 
 
 
 
78
 
 
 
79
 
80
- optimizer.zero_grad()
 
 
81
 
82
- mu, logsig, logmix_coeff = self.model(input_data)
83
  logsig = torch.clamp(logsig,-6,2)
84
  sig = torch.exp(logsig)
85
 
86
-
87
-
88
- loss = self._loss_function(mu, sig, logmix_coeff, target_data)
89
- _loss_train.append(loss.item())
 
90
 
 
 
 
 
 
 
 
 
 
 
 
91
  loss.backward()
92
- optimizer.step()
 
93
 
94
- scheduler.step()
 
95
 
96
  self.loss_train.append(np.mean(_loss_train))
97
 
98
- for input_data, target_data in loader_val:
99
-
100
 
101
  input_data = input_data.to(self.device)
102
  target_data = target_data.to(self.device)
103
 
104
 
105
- mu, logsig, logmix_coeff = self.model(input_data)
 
 
106
  logsig = torch.clamp(logsig,-6,2)
107
  sig = torch.exp(logsig)
108
 
@@ -110,41 +161,79 @@ class Insight_module():
110
  _loss_validation.append(loss_val.item())
111
 
112
  self.loss_validation.append(np.mean(_loss_validation))
 
 
 
113
 
114
- print(f'training_loss:{loss}',f'testing_loss:{loss_val}')
115
 
116
-
117
 
 
 
 
 
 
 
 
118
 
119
- def get_pz(self,input_data, target_data, return_pz=False):
120
- self.model = self.model.eval()
121
- self.model = self.model.to(self.device)
 
 
 
 
 
122
 
123
  input_data = input_data.to(self.device)
124
- target_data = target_data.to(self.device)
125
 
126
 
127
-
128
- mu, logsig, logmix_coeff = self.model(input_data)
129
  logsig = torch.clamp(logsig,-6,2)
130
  sig = torch.exp(logsig)
131
 
132
  mix_coeff = torch.exp(logmix_coeff)
133
 
134
  z = (mix_coeff * mu).sum(1)
135
- zerr = torch.sqrt( (mix_coeff * sig**2).sum(1) + (mix_coeff * (mu - target_data[:,None])**2).sum(1))
136
 
137
  mu, mix_coeff, sig = mu.detach().cpu().numpy(), mix_coeff.detach().cpu().numpy(), sig.detach().cpu().numpy()
138
 
139
 
140
  if return_pz==True:
141
- x = np.linspace(0, 4, 1000)
142
- pdf_mixture = np.zeros(shape=(len(target_data), len(x)))
143
  for ii in range(len(input_data)):
144
- for i in range(6):
145
- pdf_mixture[ii] += mix_coeff[ii,i] * norm.pdf(x, mu[ii,i], sig[ii,i])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
146
 
147
- return self._to_numpy(z),self._to_numpy(zerr), pdf_mixture
 
 
 
 
148
 
149
  else:
150
  return self._to_numpy(z),self._to_numpy(zerr)
@@ -152,14 +241,18 @@ class Insight_module():
152
  def pit(self, input_data, target_data):
153
 
154
  pit_list = []
155
-
156
- self.model = self.model.eval()
157
- self.model = self.model.to(self.device)
 
 
158
 
159
  input_data = input_data.to(self.device)
160
 
161
 
162
- mu, logsig, logmix_coeff = self.model(input_data)
 
 
163
  logsig = torch.clamp(logsig,-6,2)
164
  sig = torch.exp(logsig)
165
 
@@ -188,13 +281,16 @@ class Insight_module():
188
 
189
  crps_list = []
190
 
191
- self.model = self.model.eval()
192
- self.model = self.model.to(self.device)
 
 
193
 
194
  input_data = input_data.to(self.device)
195
 
196
 
197
- mu, logsig, logmix_coeff = self.model(input_data)
 
198
  logsig = torch.clamp(logsig,-6,2)
199
  sig = torch.exp(logsig)
200
 
@@ -221,64 +317,6 @@ class Insight_module():
221
 
222
 
223
  return crps_value
224
-
225
-
226
- def plot_photoz(self, df, nbins,xvariable,metric, type_bin='bin'):
227
- bin_edges = stats.mstats.mquantiles(df[xvariable].values, np.linspace(0.1,1,nbins))
228
- ydata,xlab = [],[]
229
 
230
 
231
- for k in range(len(bin_edges)-1):
232
- edge_min = bin_edges[k]
233
- edge_max = bin_edges[k+1]
234
-
235
- mean_mag = (edge_max + edge_min) / 2
236
-
237
- if type_bin=='bin':
238
- df_plot = df_test[(df_test.imag > edge_min) & (df_test.imag < edge_max)]
239
- elif type_bin=='cum':
240
- df_plot = df_test[(df_test.imag < edge_max)]
241
- else:
242
- raise ValueError("Only type_bin=='bin' for binned and 'cum' for cumulative are supported")
243
-
244
-
245
- xlab.append(mean_mag)
246
- if metric=='sig68':
247
- ydata.append(sigma68(df_plot.zwerr))
248
- elif metric=='bias':
249
- ydata.append(np.mean(df_plot.zwerr))
250
- elif metric=='nmad':
251
- ydata.append(nmad(df_plot.zwerr))
252
- elif metric=='outliers':
253
- ydata.append(len(df_plot[np.abs(df_plot.zwerr)>0.15])/len(df_plot))
254
-
255
- plt.plot(xlab,ydata, ls = '-', marker = '.', color = 'navy',lw = 1, label = '')
256
- plt.ylabel(f'{metric}$[\Delta z]$', fontsize = 18)
257
- plt.xlabel(f'{xvariable}', fontsize = 16)
258
-
259
- plt.xticks(fontsize = 14)
260
- plt.yticks(fontsize = 14)
261
-
262
- plt.grid(False)
263
-
264
- plt.show()
265
-
266
 
267
- def plot_pz(self, m, pz, specz):
268
- # Create a figure and axis
269
- fig, ax = plt.subplots(figsize=(8, 6))
270
-
271
- # Plot the PDF with a label
272
- ax.plot(np.linspace(0, 4, 1000), pz[m], label='PDF', color='navy')
273
-
274
- # Add a vertical line for 'specz_test'
275
- ax.axvline(specz[m], color='black', linestyle='--', label=r'$z_{\rm s}$')
276
-
277
- # Add labels and a legend
278
- ax.set_xlabel(r'$z$', fontsize = 18)
279
- ax.set_ylabel('Probability Density', fontsize=16)
280
- ax.legend(fontsize = 18)
281
-
282
- # Display the plot
283
- plt.show()
284
-
 
10
  from scipy.spatial import KDTree
11
  from scipy.special import erf
12
  from scipy.stats import norm
13
+ import sys
14
+
15
+ sys.path.append('/.')
16
+ from utils import maximum_mean_discrepancy, compute_kernel
17
 
18
  class Insight_module():
19
  """ Define class"""
20
 
21
+ def __init__(self, modelF, modelZ, batch_size=100,rejection_param=1, da=True, verbose=False):
22
+ self.modelZ=modelZ
23
+ self.modelF=modelF
24
+ self.da=da
25
+ self.verbose=verbose
26
+ self.ngaussians=modelZ.ngaussians
27
+
28
  self.device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
29
  self.batch_size=batch_size
30
  self.rejection_parameter=rejection_param
31
 
32
 
33
 
34
+ def _get_dataloaders(self, input_data, target_data, input_data_DA, target_data_DA, val_fraction=0.1):
35
  input_data = torch.Tensor(input_data)
36
  target_data = torch.Tensor(target_data)
37
+ if input_data_DA is not None:
38
+ input_data_DA = torch.Tensor(input_data_DA)
39
+ target_data_DA = torch.Tensor(target_data_DA)
40
  else:
41
+ input_data_DA = input_data.clone()
42
+ target_data_DA = target_data.clone()
43
+
44
+ dataset = TensorDataset(input_data, input_data_DA, target_data, target_data_DA)
45
  trainig_dataset, val_dataset = torch.utils.data.random_split(dataset, [int(len(dataset)*(1-val_fraction)), int(len(dataset)*val_fraction)+1])
46
  loader_train = DataLoader(trainig_dataset, batch_size=self.batch_size, shuffle = True)
47
  loader_val = DataLoader(val_dataset, batch_size=64, shuffle = True)
 
57
  log_prob = torch.logsumexp(log_prob, 1)
58
  loss = -log_prob.mean()
59
 
60
+ return loss
61
+
62
+ def _loss_function_DA(self,f1, f2):
63
+ kl_loss = nn.KLDivLoss(reduction="batchmean",log_target=True)
64
+ loss = kl_loss(f1, f2)
65
+ loss = torch.log(loss)
66
+ #print('f1',f1)
67
+ #print('f2',f2)
68
+
69
+ return loss
70
 
71
  def _to_numpy(self,x):
72
  return x.detach().cpu().numpy()
73
 
74
 
75
 
76
+ def train(self,input_data,
77
+ input_data_DA,
78
+ target_data,
79
+ target_data_DA,
80
+ nepochs=10,
81
+ step_size = 100,
82
+ val_fraction=0.1,
83
+ lr=1e-3,
84
+ weight_decay=0):
85
+ self.modelZ = self.modelZ.train()
86
+ self.modelF = self.modelF.train()
87
+
88
+ loader_train, loader_val = self._get_dataloaders(input_data, target_data, input_data_DA, target_data_DA, val_fraction=0.1)
89
+ optimizerZ = optim.Adam(self.modelZ.parameters(), lr=lr, weight_decay=weight_decay)
90
+ optimizerF = optim.Adam(self.modelF.parameters(), lr=lr, weight_decay=weight_decay)
91
+
92
+ schedulerZ = torch.optim.lr_scheduler.StepLR(optimizerZ, step_size=step_size, gamma =0.1)
93
+ schedulerF = torch.optim.lr_scheduler.StepLR(optimizerF, step_size=step_size, gamma =0.1)
94
 
95
+ self.modelZ = self.modelZ.to(self.device)
96
+ self.modelF = self.modelF.to(self.device)
97
+
98
  self.loss_train, self.loss_validation = [],[]
99
 
 
 
100
  for epoch in range(nepochs):
101
+ for input_data, input_data_da, target_data, target_data_DA in loader_train:
102
  _loss_train, _loss_validation = [],[]
103
 
104
  input_data = input_data.to(self.device)
105
  target_data = target_data.to(self.device)
106
+
107
+ if self.da:
108
+ input_data_da = input_data_da.to(self.device)
109
+ target_data_DA = target_data_DA.to(self.device)
110
 
111
+ optimizerF.zero_grad()
112
+ optimizerZ.zero_grad()
113
 
114
+ features = self.modelF(input_data)
115
+ if self.da:
116
+ features_DA = self.modelF(input_data_da)
117
 
118
+ mu, logsig, logmix_coeff = self.modelZ(features)
119
  logsig = torch.clamp(logsig,-6,2)
120
  sig = torch.exp(logsig)
121
 
122
+ lossZ = self._loss_function(mu, sig, logmix_coeff, target_data)
123
+
124
+ #mu, logsig, logmix_coeff = self.modelZ(features_DA)
125
+ #logsig = torch.clamp(logsig,-6,2)
126
+ #sig = torch.exp(logsig)
127
 
128
+ #lossZ_DA = self._loss_function(mu, sig, logmix_coeff, target_data_DA)
129
+
130
+ if self.da:
131
+ lossDA = maximum_mean_discrepancy(features, features_DA, kernel_type='rbf')
132
+ lossDA = lossDA.sum()
133
+ loss = lossZ +1e3*lossDA
134
+ else:
135
+ loss = lossZ
136
+
137
+ _loss_train.append(lossZ.item())
138
+
139
  loss.backward()
140
+ optimizerF.step()
141
+ optimizerZ.step()
142
 
143
+ schedulerF.step()
144
+ schedulerZ.step()
145
 
146
  self.loss_train.append(np.mean(_loss_train))
147
 
148
+ for input_data, _, target_data, _ in loader_val:
 
149
 
150
  input_data = input_data.to(self.device)
151
  target_data = target_data.to(self.device)
152
 
153
 
154
+ features = self.modelF(input_data)
155
+ mu, logsig, logmix_coeff = self.modelZ(features)
156
+
157
  logsig = torch.clamp(logsig,-6,2)
158
  sig = torch.exp(logsig)
159
 
 
161
  _loss_validation.append(loss_val.item())
162
 
163
  self.loss_validation.append(np.mean(_loss_validation))
164
+
165
+
166
+ if self.verbose:
167
 
168
+ print(f'training_loss:{loss}',f'testing_loss:{loss_val}')
169
 
 
170
 
171
+ def get_features(self, input_data):
172
+ self.modelF = self.modelF.eval()
173
+ self.modelF = self.modelF.to(self.device)
174
+
175
+ input_data = input_data.to(self.device)
176
+
177
+ features = self.modelF(input_data)
178
 
179
+ return features.detach().cpu().numpy()
180
+
181
+
182
+ def get_pz(self,input_data, return_pz=True, return_flag=True, retrun_odds=False):
183
+ self.modelZ = self.modelZ.eval()
184
+ self.modelZ = self.modelZ.to(self.device)
185
+ self.modelF = self.modelF.eval()
186
+ self.modelF = self.modelF.to(self.device)
187
 
188
  input_data = input_data.to(self.device)
 
189
 
190
 
191
+ features = self.modelF(input_data)
192
+ mu, logsig, logmix_coeff = self.modelZ(features)
193
  logsig = torch.clamp(logsig,-6,2)
194
  sig = torch.exp(logsig)
195
 
196
  mix_coeff = torch.exp(logmix_coeff)
197
 
198
  z = (mix_coeff * mu).sum(1)
199
+ zerr = torch.sqrt( (mix_coeff * sig**2).sum(1) + (mix_coeff * (mu - mu.mean(1)[:,None])**2).sum(1))
200
 
201
  mu, mix_coeff, sig = mu.detach().cpu().numpy(), mix_coeff.detach().cpu().numpy(), sig.detach().cpu().numpy()
202
 
203
 
204
  if return_pz==True:
205
+ zgrid = np.linspace(0, 5, 1000)
206
+ pdf_mixture = np.zeros(shape=(len(input_data), len(zgrid)))
207
  for ii in range(len(input_data)):
208
+ for i in range(self.ngaussians):
209
+ pdf_mixture[ii] += mix_coeff[ii,i] * norm.pdf(zgrid, mu[ii,i], sig[ii,i])
210
+ if return_flag==True:
211
+ #narrow peak
212
+ pdf_mixture = pdf_mixture / pdf_mixture.sum(1)[:,None]
213
+ diff_matrix = np.abs(self._to_numpy(z)[:,None] - zgrid[None,:])
214
+ #odds
215
+ idx_peak = np.argmax(pdf_mixture,1)
216
+ zpeak = zgrid[idx_peak]
217
+ diff_matrix_upper = np.abs((zpeak+0.05)[:,None] - zgrid[None,:])
218
+ diff_matrix_lower = np.abs((zpeak-0.05)[:,None] - zgrid[None,:])
219
+
220
+ idx = np.argmin(diff_matrix,1)
221
+ idx_upper = np.argmin(diff_matrix_upper,1)
222
+ idx_lower = np.argmin(diff_matrix_lower,1)
223
+
224
+ p_z_x = np.zeros(shape=(len(z)))
225
+ odds = np.zeros(shape=(len(z)))
226
+
227
+ for ii in range(len(z)):
228
+ p_z_x[ii] = pdf_mixture[ii,idx[ii]]
229
+ odds[ii] = pdf_mixture[ii,:idx_upper[ii]].sum() - pdf_mixture[ii,:idx_lower[ii]].sum()
230
+
231
 
232
+
233
+ return self._to_numpy(z),self._to_numpy(zerr), pdf_mixture, p_z_x, odds
234
+ else:
235
+
236
+ return self._to_numpy(z),self._to_numpy(zerr), pdf_mixture
237
 
238
  else:
239
  return self._to_numpy(z),self._to_numpy(zerr)
 
241
  def pit(self, input_data, target_data):
242
 
243
  pit_list = []
244
+
245
+ self.modelF = self.modelF.eval()
246
+ self.modelF = self.modelF.to(self.device)
247
+ self.modelZ = self.modelZ.eval()
248
+ self.modelZ = self.modelZ.to(self.device)
249
 
250
  input_data = input_data.to(self.device)
251
 
252
 
253
+ features = self.modelF(input_data)
254
+ mu, logsig, logmix_coeff = self.modelZ(features)
255
+
256
  logsig = torch.clamp(logsig,-6,2)
257
  sig = torch.exp(logsig)
258
 
 
281
 
282
  crps_list = []
283
 
284
+ self.modelF = self.modelF.eval()
285
+ self.modelF = self.modelF.to(self.device)
286
+ self.modelZ = self.modelZ.eval()
287
+ self.modelZ = self.modelZ.to(self.device)
288
 
289
  input_data = input_data.to(self.device)
290
 
291
 
292
+ features = self.modelF(input_data)
293
+ mu, logsig, logmix_coeff = self.modelZ(features)
294
  logsig = torch.clamp(logsig,-6,2)
295
  sig = torch.exp(logsig)
296
 
 
317
 
318
 
319
  return crps_value
 
 
 
 
 
320
 
321
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
322
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
insight/insight_arch.py CHANGED
@@ -1,14 +1,14 @@
1
- from torch import nn, optim
2
  import torch
3
-
4
  from torch import nn, optim
5
- import torch
6
- class Photoz_network(nn.Module):
7
- def __init__(self, num_gauss=10, dropout_prob=0):
8
- super(Photoz_network, self).__init__()
 
 
9
 
10
  self.features = nn.Sequential(
11
- nn.Linear(6, 10),
12
  nn.Dropout(dropout_prob),
13
  nn.ReLU(),
14
  nn.Linear(10, 20),
@@ -22,7 +22,19 @@ class Photoz_network(nn.Module):
22
  nn.ReLU(),
23
  nn.Linear(20, 10)
24
  )
 
 
 
 
 
 
 
 
 
 
 
25
 
 
26
  self.measure_mu = nn.Sequential(
27
  nn.Linear(10, 20),
28
  nn.Dropout(dropout_prob),
@@ -45,8 +57,7 @@ class Photoz_network(nn.Module):
45
  )
46
 
47
 
48
- def forward(self, x):
49
- f = self.features(x)
50
  mu = self.measure_mu(f)
51
  sigma = self.measure_sigma(f)
52
  logmix_coeff = self.measure_coeffs(f)
 
 
1
  import torch
 
2
  from torch import nn, optim
3
+ import torch.nn.functional as F
4
+
5
+
6
+ class EncoderPhotometry(nn.Module):
7
+ def __init__(self, input_dim=6, dropout_prob=0):
8
+ super(EncoderPhotometry, self).__init__()
9
 
10
  self.features = nn.Sequential(
11
+ nn.Linear(input_dim, 10),
12
  nn.Dropout(dropout_prob),
13
  nn.ReLU(),
14
  nn.Linear(10, 20),
 
22
  nn.ReLU(),
23
  nn.Linear(20, 10)
24
  )
25
+
26
+ def forward(self, x):
27
+ f = self.features(x)
28
+ f = F.log_softmax(f, dim=1)
29
+ return f
30
+
31
+
32
+
33
+ class MeasureZ(nn.Module):
34
+ def __init__(self, num_gauss=10, dropout_prob=0):
35
+ super(MeasureZ, self).__init__()
36
 
37
+ self.ngaussians=num_gauss
38
  self.measure_mu = nn.Sequential(
39
  nn.Linear(10, 20),
40
  nn.Dropout(dropout_prob),
 
57
  )
58
 
59
 
60
+ def forward(self, f):
 
61
  mu = self.measure_mu(f)
62
  sigma = self.measure_sigma(f)
63
  logmix_coeff = self.measure_coeffs(f)
insight/plots.py ADDED
@@ -0,0 +1,283 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+ import pandas as pd
3
+ import matplotlib.pyplot as plt
4
+ from utils import nmad
5
+
6
+ import numpy as np
7
+ import matplotlib.pyplot as plt
8
+ from scipy import stats
9
+
10
+ def plot_photoz(df_list, nbins, xvariable, metric, type_bin='bin',label_list=None, samp='zs', save=False):
11
+ #plot properties
12
+ plt.rcParams['font.family'] = 'serif'
13
+ plt.rcParams['font.size'] = 12
14
+
15
+ if xvariable == 'VISmag':
16
+ xvariable_lab = 'VIS'
17
+ if xvariable == 'zs':
18
+ xvariable_lab = r'$z_{\rm s}$'
19
+
20
+ bin_edges = stats.mstats.mquantiles(df_list[0][xvariable].values, np.linspace(0.05, 1, nbins))
21
+ cmap = plt.get_cmap('Dark2') # Choose a colormap for coloring lines
22
+ #plt.figure(figsize=(6, 5))
23
+ ls = ['--',':','-']
24
+ fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(8, 8), gridspec_kw={'height_ratios': [3, 1]})
25
+
26
+ ydata_dict = {}
27
+
28
+ for i, df in enumerate(df_list):
29
+ ydata, xlab = [], []
30
+
31
+ label = label_list[i]
32
+
33
+ if label == 'zs':
34
+ label_lab = r'$z_{\rm s}$'
35
+ if label == 'zs+L15':
36
+ label_lab = r'$z_{\rm s}$+L15'
37
+ if label == 'TEMPS':
38
+ label_lab = 'TEMPS'
39
+
40
+ for k in range(len(bin_edges)-1):
41
+ edge_min = bin_edges[k]
42
+ edge_max = bin_edges[k+1]
43
+
44
+ mean_mag = (edge_max + edge_min) / 2
45
+
46
+ if type_bin == 'bin':
47
+ df_plot = df[(df[xvariable] > edge_min) & (df[xvariable] < edge_max)]
48
+ elif type_bin == 'cum':
49
+ df_plot = df[(df[xvariable] < edge_max)]
50
+ else:
51
+ raise ValueError("Only type_bin=='bin' for binned and 'cum' for cumulative are supported")
52
+
53
+ xlab.append(mean_mag)
54
+ if metric == 'sig68':
55
+ ydata.append(sigma68(df_plot.zwerr))
56
+ elif metric == 'bias':
57
+ ydata.append(np.mean(df_plot.zwerr))
58
+ elif metric == 'nmad':
59
+ ydata.append(nmad(df_plot.zwerr))
60
+ elif metric == 'outliers':
61
+ ydata.append(len(df_plot[np.abs(df_plot.zwerr) > 0.15]) / len(df_plot)*100)
62
+
63
+ ydata_dict[f'{i}'] = ydata
64
+ color = cmap(i) # Get a different color for each dataframe
65
+ ax1.plot(xlab, ydata,marker='.', lw=1, label=label_lab, color=color, ls=ls[i])
66
+
67
+
68
+
69
+ ax1.set_ylabel(f'{metric} $[\Delta z]$', fontsize=18)
70
+ #ax1.set_xlabel(f'{xvariable_lab}', fontsize=16)
71
+ ax1.grid(False)
72
+ ax1.legend()
73
+
74
+ # Plot ratios between lines in the upper panel
75
+
76
+ ax2.plot(xlab, np.array(ydata_dict['1'])/np.array(ydata_dict['0']), marker='.', color = cmap(1))
77
+ ax2.plot(xlab, np.array(ydata_dict['2'])/np.array(ydata_dict['0']), marker='.', color = cmap(2))
78
+ ax2.set_ylabel(r'Method $X$ / $z_{\rm z}$', fontsize=14)
79
+
80
+
81
+ ax2.set_xlabel(f'{xvariable_lab}', fontsize=16)
82
+ ax2.grid(True)
83
+
84
+
85
+ if save==True:
86
+ plt.savefig(f'{metric}_{xvariable}_{samp}.pdf', dpi=300, bbox_inches='tight')
87
+ plt.show()
88
+
89
+
90
+ def plot_pz(m, pz, specz):
91
+ # Create a figure and axis
92
+ fig, ax = plt.subplots(figsize=(8, 6))
93
+
94
+ # Plot the PDF with a label
95
+ ax.plot(np.linspace(0, 4, 1000), pz[m], label='PDF', color='navy')
96
+
97
+ # Add a vertical line for 'specz_test'
98
+ ax.axvline(specz[m], color='black', linestyle='--', label=r'$z_{\rm s}$')
99
+
100
+ # Add labels and a legend
101
+ ax.set_xlabel(r'$z$', fontsize = 18)
102
+ ax.set_ylabel('Probability Density', fontsize=16)
103
+ ax.legend(fontsize = 18)
104
+
105
+ # Display the plot
106
+ plt.show()
107
+
108
+
109
+ def plot_zdistribution(archive, plot_test=False, bins=50):
110
+ _,_,specz = archive.get_training_data()
111
+ plt.hist(specz, bins = bins, hisstype='step', color='navy', label=r'Training sample')
112
+
113
+ if plot_test:
114
+ _,_,specz_test = archive.get_training_data()
115
+ plt.hist(specz, bins = bins, hisstype='step', color='goldenrod', label=r'Test sample',ls='--')
116
+
117
+
118
+ plt.xticks(fontsize=12)
119
+ plt.yticks(fontsize=12)
120
+
121
+ plt.xlabel(r'Redshift', fontsize=14)
122
+ plt.ylabel('Counts', fontsize=14)
123
+
124
+ plt.show()
125
+
126
+ def plot_som_map(som_data, plot_arg = 'z', vmin=0, vmax=1):
127
+ """
128
+ Plot the Self-Organizing Map (SOM) data.
129
+
130
+ Parameters:
131
+ - som_data (numpy.ndarray): The SOM data to be visualized.
132
+ - plot_arg (str, optional): The column name to be plotted. Default is 'z'.
133
+ - vmin (float, optional): Minimum value for color scaling. Default is 0.
134
+ - vmax (float, optional): Maximum value for color scaling. Default is 1.
135
+
136
+ Returns:
137
+ None
138
+ """
139
+ plt.imshow(som_data, vmin=vmin, vmax=vmax, cmap='viridis') # Choose an appropriate colormap
140
+ plt.colorbar(label=f'{plot_arg}') # Add a colorbar with a label
141
+ plt.xlabel(r'$x$ [pixel]', fontsize=14) # Add an appropriate X-axis label
142
+ plt.ylabel(r'$y$ [pixel]', fontsize=14) # Add an appropriate Y-axis label
143
+ plt.show()
144
+
145
+
146
+ def plot_PIT(pit_list_1, pit_list_2 = None, pit_list_3=None, sample='specz', labels=None, save =True):
147
+ #plot properties
148
+ plt.rcParams['font.family'] = 'serif'
149
+ plt.rcParams['font.size'] = 12
150
+ fig, ax = plt.subplots(figsize=(8, 6))
151
+ kwargs=dict(bins=30, histtype='step', density=True, range=(0,1))
152
+ cmap = plt.get_cmap('Dark2')
153
+
154
+
155
+ # Create a histogram
156
+ hist, bins, _ = ax.hist(pit_list_1, color=cmap(0), ls='--', **kwargs, label=labels[0])
157
+ if pit_list_2!= None:
158
+ hist, bins, _ = ax.hist(pit_list_2, color=cmap(1), ls=':', **kwargs, label=labels[1])
159
+ if pit_list_3!= None:
160
+ hist, bins, _ = ax.hist(pit_list_3, color=cmap(2), ls='-', **kwargs, label=labels[2])
161
+
162
+
163
+ # Add labels and a title
164
+ ax.set_xlabel('PIT values', fontsize = 18)
165
+ ax.set_ylabel('Frequency', fontsize = 18)
166
+
167
+ # Add grid lines
168
+ ax.grid(True, linestyle='--', alpha=0.7)
169
+
170
+ # Customize the x-axis
171
+ ax.set_xlim(0, 1)
172
+ #ax.set_ylim(0,3)
173
+
174
+ plt.legend(fontsize=12)
175
+
176
+ # Make ticks larger
177
+ ax.tick_params(axis='both', which='major', labelsize=14)
178
+ if save==True:
179
+ plt.savefig(f'{sample}_PIT.pdf', bbox_inches='tight')
180
+
181
+ # Show the plot
182
+ plt.show()
183
+
184
+
185
+ import numpy as np
186
+ import matplotlib.pyplot as plt
187
+ from scipy import stats
188
+
189
+ def plot_photoz(df_list, nbins, xvariable, metric, type_bin='bin',label_list=None, samp='zs', save=False):
190
+ #plot properties
191
+ plt.rcParams['font.family'] = 'serif'
192
+ plt.rcParams['font.size'] = 12
193
+
194
+
195
+
196
+
197
+ bin_edges = stats.mstats.mquantiles(df_list[0][xvariable].values, np.linspace(0.05, 1, nbins))
198
+ print(bin_edges)
199
+ cmap = plt.get_cmap('Dark2') # Choose a colormap for coloring lines
200
+ plt.figure(figsize=(6, 5))
201
+ ls = ['--',':','-']
202
+
203
+ for i, df in enumerate(df_list):
204
+ ydata, xlab = [], []
205
+
206
+ for k in range(len(bin_edges)-1):
207
+ edge_min = bin_edges[k]
208
+ edge_max = bin_edges[k+1]
209
+
210
+ mean_mag = (edge_max + edge_min) / 2
211
+
212
+ if type_bin == 'bin':
213
+ df_plot = df[(df[xvariable] > edge_min) & (df[xvariable] < edge_max)]
214
+ elif type_bin == 'cum':
215
+ df_plot = df[(df[xvariable] < edge_max)]
216
+ else:
217
+ raise ValueError("Only type_bin=='bin' for binned and 'cum' for cumulative are supported")
218
+
219
+ xlab.append(mean_mag)
220
+ if metric == 'sig68':
221
+ ydata.append(sigma68(df_plot.zwerr))
222
+ elif metric == 'bias':
223
+ ydata.append(np.mean(df_plot.zwerr))
224
+ elif metric == 'nmad':
225
+ ydata.append(nmad(df_plot.zwerr))
226
+ elif metric == 'outliers':
227
+ ydata.append(len(df_plot[np.abs(df_plot.zwerr) > 0.15]) / len(df_plot)*100)
228
+
229
+ print(ydata)
230
+ color = cmap(i) # Get a different color for each dataframe
231
+ plt.plot(xlab, ydata,marker='.', lw=1, label=f'{label_list[i]}', color=color, ls=ls[i])
232
+
233
+ if xvariable == 'VISmag':
234
+ xvariable_lab = 'VIS'
235
+
236
+
237
+
238
+ plt.ylabel(f'{metric} $[\\Delta z]$', fontsize=18)
239
+ plt.xlabel(f'{xvariable_lab}', fontsize=16)
240
+ plt.grid(False)
241
+ plt.legend()
242
+
243
+ if save==True:
244
+ plt.savefig(f'{metric}_{xvariable}_{samp}.pdf', dpi=300, bbox_inches='tight')
245
+ plt.show()
246
+
247
+
248
+ def plot_nz(df_list, zcuts = [0.1, 0.5, 1, 1.5, 2, 3, 4]):
249
+ # Plot properties
250
+ plt.rcParams['font.family'] = 'serif'
251
+ plt.rcParams['font.size'] = 16
252
+
253
+ cmap = plt.get_cmap('Dark2') # Choose a colormap for coloring lines
254
+
255
+ # Create subplots
256
+ fig, axs = plt.subplots(3, 1, figsize=(20, 8), sharex=True)
257
+
258
+ for i, df in enumerate(df_list):
259
+ dfplot = df_list[i].copy() # Assuming df_list contains dataframes
260
+ ax = axs[i] # Selecting the appropriate subplot
261
+
262
+ for iz in range(len(zcuts)-1):
263
+ dfplot_z = dfplot[(dfplot['zs'] > zcuts[iz]) & (dfplot['zs'] < zcuts[iz + 1])]
264
+ color = cmap(iz) # Get a different color for each redshift
265
+
266
+ zt_mean = np.median(dfplot_z.zs.values)
267
+ zp_mean = np.median(dfplot_z.z.values)
268
+
269
+
270
+ # Plot histogram on the selected subplot
271
+ ax.hist(dfplot_z.z, bins=50, color=color, histtype='step', linestyle='-', density=True, range=(0, 4))
272
+ ax.axvline(zt_mean, color=color, linestyle='-', lw=2)
273
+ ax.axvline(zp_mean, color=color, linestyle='--', lw=2)
274
+
275
+ ax.set_ylabel(f'Frequency', fontsize=14)
276
+ ax.grid(False)
277
+ ax.set_xlim(0, 3.5)
278
+
279
+ axs[-1].set_xlabel(f'$z$', fontsize=18)
280
+
281
+ plt.savefig(f'nz_hist.pdf', dpi=300, bbox_inches='tight')
282
+
283
+ plt.show()
insight/utils.py CHANGED
@@ -2,65 +2,71 @@ import numpy as np
2
  import pandas as pd
3
  import matplotlib.pyplot as plt
4
  from scipy import stats
 
 
5
 
6
  def nmad(data):
7
  return 1.4826 * np.median(np.abs(data - np.median(data)))
8
 
9
  def sigma68(data): return 0.5*(pd.Series(data).quantile(q = 0.84) - pd.Series(data).quantile(q = 0.16))
10
 
11
- def plot_photoz_estimates(df, nbins,xvariable,metric, type_bin='bin'):
12
- bin_edges = stats.mstats.mquantiles(df[xvariable].values, np.linspace(0.1,1,nbins))
13
- ydata,xdata = [],[]
 
 
 
14
 
15
 
16
- for k in range(len(bin_edges)-1):
17
- edge_min = bin_edges[k]
18
- edge_max = bin_edges[k+1]
 
 
 
 
 
 
 
 
 
 
19
 
20
- mean_mag = (edge_max + edge_min) / 2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
 
22
- if type_bin=='bin':
23
- df_plot = df[(df[xvariable] > edge_min) & (df[xvariable] < edge_max)]
24
- elif type_bin=='cum':
25
- df_plot = df[(df[xvariable] < edge_max)]
26
- else:
27
- raise ValueError("Only type_bin=='bin' for binned and 'cum' for cumulative are supported")
28
-
29
-
30
- xdata.append(mean_mag)
31
- if metric=='sig68':
32
- ydata.append(sigma68(df_plot.zwerr))
33
- ylab=r'$\sigma_{\rm NMAD} [\Delta z]$'
34
- elif metric=='bias':
35
- ydata.append(np.median(df_plot.zwerr))
36
- ylab=r'Median $[\Delta z]$'
37
- elif metric=='nmad':
38
- ydata.append(nmad(df_plot.zwerr))
39
- ylab=r'$\sigma_{\rm NMAD} [\Delta z]$'
40
- elif metric=='outliers':
41
- ydata.append(len(df_plot[np.abs(df_plot.zwerr)>0.15])/len(df_plot) *100)
42
- ylab=r'$\eta$ [%]'
43
-
44
- if xvariable=='VISmag':
45
- xlab='VIS'
46
- elif xvariable=='zs':
47
- xlab=r'$z_{\rm spec}$'
48
- elif xvariable=='z':
49
- xlab=r'$z$'
50
-
51
- plt.plot(xdata,ydata, ls = '-', marker = '.', color = 'navy',lw = 1, label = '')
52
- plt.ylabel(f'{ylab}', fontsize = 18)
53
- plt.xlabel(f'{xlab}', fontsize = 16)
54
-
55
- plt.xticks(fontsize = 14)
56
- plt.yticks(fontsize = 14)
57
 
 
 
 
58
  plt.grid(False)
 
59
 
 
 
60
  plt.show()
61
-
62
- return
63
-
64
 
65
  def plot_nz(df, bins=np.arange(0,5,0.2)):
66
  kwargs=dict( bins=bins,alpha=0.5)
@@ -77,4 +83,86 @@ def plot_nz(df, bins=np.arange(0,5,0.2)):
77
  plt.show()
78
 
79
  return
80
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
  import pandas as pd
3
  import matplotlib.pyplot as plt
4
  from scipy import stats
5
+ import torch
6
+ from scipy.stats import gaussian_kde
7
 
8
  def nmad(data):
9
  return 1.4826 * np.median(np.abs(data - np.median(data)))
10
 
11
  def sigma68(data): return 0.5*(pd.Series(data).quantile(q = 0.84) - pd.Series(data).quantile(q = 0.16))
12
 
13
+ def plot_photoz(df_list, nbins, xvariable, metric, type_bin='bin',label_list=None, samp='zs', save=False):
14
+ #plot properties
15
+ plt.rcParams['font.family'] = 'serif'
16
+ plt.rcParams['font.size'] = 12
17
+
18
+
19
 
20
 
21
+ bin_edges = stats.mstats.mquantiles(df_list[0][xvariable].values, np.linspace(0.05, 1, nbins))
22
+ print(bin_edges)
23
+ cmap = plt.get_cmap('Dark2') # Choose a colormap for coloring lines
24
+ plt.figure(figsize=(6, 5))
25
+
26
+ for i, df in enumerate(df_list):
27
+ ydata, xlab = [], []
28
+
29
+ for k in range(len(bin_edges)-1):
30
+ edge_min = bin_edges[k]
31
+ edge_max = bin_edges[k+1]
32
+
33
+ mean_mag = (edge_max + edge_min) / 2
34
 
35
+ if type_bin == 'bin':
36
+ df_plot = df[(df[xvariable] > edge_min) & (df[xvariable] < edge_max)]
37
+ elif type_bin == 'cum':
38
+ df_plot = df[(df[xvariable] < edge_max)]
39
+ else:
40
+ raise ValueError("Only type_bin=='bin' for binned and 'cum' for cumulative are supported")
41
+
42
+ xlab.append(mean_mag)
43
+ if metric == 'sig68':
44
+ ydata.append(sigma68(df_plot.zwerr))
45
+ elif metric == 'bias':
46
+ ydata.append(np.mean(df_plot.zwerr))
47
+ elif metric == 'nmad':
48
+ ydata.append(nmad(df_plot.zwerr))
49
+ elif metric == 'outliers':
50
+ ydata.append(len(df_plot[np.abs(df_plot.zwerr) > 0.15]) / len(df_plot)*100)
51
+
52
+ print(ydata)
53
+ color = cmap(i) # Get a different color for each dataframe
54
+ plt.plot(xlab, ydata, ls='-', marker='.', lw=1, label=f'{label_list[i]}', color=color)
55
+
56
+ if xvariable == 'VISmag':
57
+ xvariable_lab = 'VIS'
58
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59
 
60
+
61
+ plt.ylabel(f'{metric} $[\\Delta z]$', fontsize=18)
62
+ plt.xlabel(f'{xvariable_lab}', fontsize=16)
63
  plt.grid(False)
64
+ plt.legend()
65
 
66
+ if save==True:
67
+ plt.savefig(f'{metric}_{xvariable}_{samp}.pdf', dpi=300, bbox_inches='tight')
68
  plt.show()
69
+
 
 
70
 
71
  def plot_nz(df, bins=np.arange(0,5,0.2)):
72
  kwargs=dict( bins=bins,alpha=0.5)
 
83
  plt.show()
84
 
85
  return
86
+
87
+
88
+ def plot_scatter(df, sample='specz', save=True):
89
+ # Calculate the point density
90
+ xy = np.vstack([df.zs.values,df.z.values])
91
+ zd = gaussian_kde(xy)(xy)
92
+
93
+ fig, ax = plt.subplots()
94
+ plt.scatter(df.zs.values, df.z.values,c=zd, s=1)
95
+ plt.xlim(0,5)
96
+ plt.ylim(0,5)
97
+
98
+ plt.xlabel(r'$z_{\rm s}$', fontsize = 14)
99
+ plt.ylabel('$z$', fontsize = 14)
100
+
101
+ plt.xticks(fontsize = 12)
102
+ plt.yticks(fontsize = 12)
103
+
104
+ if save==True:
105
+ plt.savefig(f'{sample}_scatter.pdf', dpi = 300, bbox_inches='tight')
106
+
107
+ plt.show()
108
+
109
+
110
+
111
+
112
+ def maximum_mean_discrepancy(x, y, kernel_type='rbf', kernel_mul=2.0, kernel_num=5):
113
+ """
114
+ Compute the Maximum Mean Discrepancy (MMD) between two sets of samples.
115
+
116
+ Args:
117
+ - x: Tensor, samples from the source domain
118
+ - y: Tensor, samples from the target domain
119
+ - kernel_type: str, the type of kernel to be used ('linear', 'poly', 'rbf', 'sigmoid')
120
+ - kernel_mul: float, multiplier for the kernel bandwidth
121
+ - kernel_num: int, number of kernels for the MMD approximation
122
+
123
+ Returns:
124
+ - mmd_loss: Tensor, the MMD loss
125
+ """
126
+ x_kernel = compute_kernel(x, x, kernel_type, kernel_mul, kernel_num)
127
+ y_kernel = compute_kernel(y, y, kernel_type, kernel_mul, kernel_num)
128
+ xy_kernel = compute_kernel(x, y, kernel_type, kernel_mul, kernel_num)
129
+
130
+ mmd_loss = torch.mean(x_kernel) + torch.mean(y_kernel) - 2 * torch.mean(xy_kernel)
131
+ return mmd_loss
132
+
133
+ def compute_kernel(x, y, kernel_type='rbf', kernel_mul=2.0, kernel_num=5):
134
+ """
135
+ Compute the kernel matrix based on the chosen kernel type.
136
+
137
+ Args:
138
+ - x: Tensor, samples
139
+ - y: Tensor, samples
140
+ - kernel_type: str, the type of kernel to be used ('linear', 'poly', 'rbf', 'sigmoid')
141
+ - kernel_mul: float, multiplier for the kernel bandwidth
142
+ - kernel_num: int, number of kernels for the MMD approximation
143
+
144
+ Returns:
145
+ - kernel_matrix: Tensor, the computed kernel matrix
146
+ """
147
+ x_size = x.size(0)
148
+ y_size = y.size(0)
149
+ dim = x.size(1)
150
+
151
+ x = x.unsqueeze(1).expand(x_size, y_size, dim)
152
+ y = y.unsqueeze(0).expand(x_size, y_size, dim)
153
+
154
+ kernel_input = (x - y).pow(2).mean(2) # Pairwise squared Euclidean distances
155
+
156
+ if kernel_type == 'linear':
157
+ kernel_matrix = kernel_input
158
+ elif kernel_type == 'poly':
159
+ kernel_matrix = (1 + kernel_input / kernel_mul).pow(kernel_num)
160
+ elif kernel_type == 'rbf':
161
+ kernel_matrix = torch.exp(-kernel_input / (2 * kernel_mul**2))
162
+ elif kernel_type == 'sigmoid':
163
+ kernel_matrix = torch.tanh(kernel_mul * kernel_input)
164
+ else:
165
+ raise ValueError("Invalid kernel type. Supported types are 'linear', 'poly', 'rbf', and 'sigmoid'.")
166
+
167
+ return kernel_matrix
168
+
notebooks/Colourspace.ipynb DELETED
@@ -1,410 +0,0 @@
1
- {
2
- "cells": [
3
- {
4
- "cell_type": "code",
5
- "execution_count": 2,
6
- "id": "2899a039-94b5-4435-9f2a-6e047da46ff6",
7
- "metadata": {},
8
- "outputs": [],
9
- "source": [
10
- "import numpy as np\n",
11
- "import pandas as pd\n",
12
- "from astropy.io import fits\n",
13
- "import os\n",
14
- "from astropy.table import Table\n",
15
- "from scipy.spatial import KDTree\n",
16
- "\n",
17
- "import matplotlib.pyplot as plt\n",
18
- "\n",
19
- "from IPython.display import Image\n",
20
- "from IPython.core.display import HTML "
21
- ]
22
- },
23
- {
24
- "cell_type": "code",
25
- "execution_count": 3,
26
- "id": "92ae41a8-9627-46e8-81d1-29191e253f7f",
27
- "metadata": {},
28
- "outputs": [],
29
- "source": [
30
- "import torch\n",
31
- "from torch.utils.data import DataLoader, dataset, TensorDataset\n",
32
- "from torch import nn, optim\n",
33
- "from torch.optim import lr_scheduler"
34
- ]
35
- },
36
- {
37
- "cell_type": "code",
38
- "execution_count": 4,
39
- "id": "465d798e-a52c-423c-ac49-c37d5b1a3a8f",
40
- "metadata": {},
41
- "outputs": [],
42
- "source": [
43
- "import sys\n",
44
- "sys.path.append('../insight')\n",
45
- "from archive import archive \n",
46
- "from insight_arch import Photoz_network\n",
47
- "from insight import Insight_module\n",
48
- "from utils import sigma68, nmad, plot_photoz_estimates\n",
49
- "from scipy import stats\n",
50
- "from scipy.stats import norm\n"
51
- ]
52
- },
53
- {
54
- "cell_type": "code",
55
- "execution_count": 5,
56
- "id": "0efc8f49-a27b-4176-ae4f-3054786f41ff",
57
- "metadata": {},
58
- "outputs": [],
59
- "source": [
60
- "from matplotlib import rcParams\n",
61
- "rcParams[\"mathtext.fontset\"] = \"stix\"\n",
62
- "rcParams[\"font.family\"] = \"STIXGeneral\"\n",
63
- "parent_dir = '/data/astro/scratch/lcabayol/Euclid/NNphotozs/Euclid_EXT_MER_PHZ_DC2_v1.5'"
64
- ]
65
- },
66
- {
67
- "cell_type": "code",
68
- "execution_count": 78,
69
- "id": "4ddb6562-d708-4a47-a78f-7de8117afefa",
70
- "metadata": {},
71
- "outputs": [],
72
- "source": [
73
- "photoz_archive = archive(path = parent_dir,only_zspec=False,flags_kept=[1. , 1.1, 1.4, 1.5, 2,2.1,2.4,2.5,3., 3.1, 3.4, 3.5, 4., 9. , 9.1, 9.3, 9.4, 9.5,11.1, 11.5, 12.1, 12.5, 13. , 13.1, 13.5, 14, ], convert_colors=True)\n",
74
- "f, ferr, specz ,VIS_mag = photoz_archive.get_training_data()"
75
- ]
76
- },
77
- {
78
- "cell_type": "markdown",
79
- "id": "ce4ea81e-3678-4947-af87-b4bc4e247c29",
80
- "metadata": {},
81
- "source": [
82
- "## SOM TRAINING"
83
- ]
84
- },
85
- {
86
- "cell_type": "code",
87
- "execution_count": 8,
88
- "id": "2a21c8cc-c682-4008-b6bd-299c90576c3a",
89
- "metadata": {},
90
- "outputs": [],
91
- "source": [
92
- "import SOM"
93
- ]
94
- },
95
- {
96
- "cell_type": "code",
97
- "execution_count": 125,
98
- "id": "e27e5d57-156f-4363-8b7f-0f05f851b1f7",
99
- "metadata": {},
100
- "outputs": [],
101
- "source": [
102
- "nx, ny = 25,25\n",
103
- "epochs = 1_000_000"
104
- ]
105
- },
106
- {
107
- "cell_type": "code",
108
- "execution_count": 126,
109
- "id": "b722f505-59a5-4333-9bb7-1c5d176af0ba",
110
- "metadata": {},
111
- "outputs": [],
112
- "source": [
113
- "selforgmap = SOM.SOM(x = nx, \n",
114
- " y = ny, \n",
115
- " epochs = epochs, \n",
116
- " vec_size = 3, \n",
117
- " metric = 'Euclidean',\n",
118
- " lr0 = 0.001, \n",
119
- " sigma0 = 6, \n",
120
- " initialisation = 'RandomNormal'\n",
121
- " )"
122
- ]
123
- },
124
- {
125
- "cell_type": "code",
126
- "execution_count": 127,
127
- "id": "bca007d7-9feb-40f7-8bb4-fdfcdf661eab",
128
- "metadata": {},
129
- "outputs": [],
130
- "source": [
131
- "selforgmap.train(f, samples_epoch = 1)"
132
- ]
133
- },
134
- {
135
- "cell_type": "markdown",
136
- "id": "8763fae7-8af5-4ba0-8c30-b6aac4f09b37",
137
- "metadata": {},
138
- "source": [
139
- "## SOM VISUAIZATION IN THE SPEC-Z SAMPLE"
140
- ]
141
- },
142
- {
143
- "cell_type": "code",
144
- "execution_count": 150,
145
- "id": "a1dfe3f4-5625-4121-89f7-d59d803ce1b0",
146
- "metadata": {},
147
- "outputs": [],
148
- "source": [
149
- "f_test, _, specz_test ,VISmag = photoz_archive.get_testing_data()"
150
- ]
151
- },
152
- {
153
- "cell_type": "code",
154
- "execution_count": 151,
155
- "id": "d75eb21e-a87a-4fb9-b9bf-61542c43ed30",
156
- "metadata": {},
157
- "outputs": [],
158
- "source": [
159
- "bmu = selforgmap.test_obj(f_test)"
160
- ]
161
- },
162
- {
163
- "cell_type": "code",
164
- "execution_count": 152,
165
- "id": "1efb5055-9f2a-44e6-9a26-9fffc85ac457",
166
- "metadata": {},
167
- "outputs": [],
168
- "source": [
169
- "df = pd.DataFrame(np.c_[specz_test, bmu], columns = ['zs','cell'])"
170
- ]
171
- },
172
- {
173
- "cell_type": "code",
174
- "execution_count": 153,
175
- "id": "ae3c9304-d0bd-4c3d-9232-41d173234bdd",
176
- "metadata": {},
177
- "outputs": [],
178
- "source": [
179
- "som_vis = df.groupby('cell').zs.mean().reset_index().rename(columns = {'zs':'zs_som'})\n",
180
- "\n"
181
- ]
182
- },
183
- {
184
- "cell_type": "code",
185
- "execution_count": 154,
186
- "id": "c57dd19b-225a-4378-a895-667fa5b799fa",
187
- "metadata": {},
188
- "outputs": [],
189
- "source": [
190
- "x_cells = np.arange(0,nx)\n",
191
- "y_cells = np.arange(0,ny)\n",
192
- "index_cell = np.arange(nx*ny)\n",
193
- "cells = np.array(np.meshgrid(x_cells,y_cells)).T.reshape(-1,2)\n",
194
- "cells = pd.DataFrame(np.c_[cells[:,0],cells[:,1],index_cell], columns = ['x_cell','y_cell','cell'])"
195
- ]
196
- },
197
- {
198
- "cell_type": "code",
199
- "execution_count": 155,
200
- "id": "524e6c22-4e50-48b2-960b-4c48fb553de6",
201
- "metadata": {},
202
- "outputs": [],
203
- "source": [
204
- "som_data = som_vis.merge(cells, on = 'cell')\n",
205
- "som_data = som_data.pivot(index = 'x_cell', columns = 'y_cell', values = 'zs_som')"
206
- ]
207
- },
208
- {
209
- "cell_type": "code",
210
- "execution_count": 156,
211
- "id": "54bcfc2e-864a-4ebc-a0d1-303cbd602dd7",
212
- "metadata": {},
213
- "outputs": [
214
- {
215
- "data": {
216
- "text/plain": [
217
- "<matplotlib.colorbar.Colorbar at 0x2b2c1c878bb0>"
218
- ]
219
- },
220
- "execution_count": 156,
221
- "metadata": {},
222
- "output_type": "execute_result"
223
- },
224
- {
225
- "data": {
226
- "image/png": "iVBORw0KGgoAAAANSUhEUgAAAdUAAAGhCAYAAAA3Ci4gAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/MnkTPAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAzWklEQVR4nO3df3xU9Z3v8fck5EdjMrMY5ZcNP1I6oUBadZXC8mOBXQXvpcijCnVZzC4+tGB94NVsrZKlaCo1W6ESTVt34V5rLYu7smIJC4K7biJwm6tZAhItikASIxB+mc4ghPyYOfcPZHRIQjLfOTmZDK/n43EeMZPzOd9vhjN+8v2e7zkfl2VZlgAAQNQSersDAADEC5IqAAA2IakCAGATkioAADYhqQIAYBOSKgAANiGpAgBgE5IqAAA2IakCAGCTfr3dAQAAnHLu3DnddNNN2rp1q4YPH97u58XFxTp37pzOnj2rzMxM5efnR3R8kioA4IpRUlKi/fv3d/izDRs2aOPGjdqxY4ckaeLEiRo9erRmzpzZ7eMz/QsAuCJs2rRJ06ZN6/Tnq1at0q233hr6ftasWSopKYmojZgYqQaDQR09elQZGRlyuVy93R0AuCJZlqUzZ85oyJAhSkjomTHX+fPn1dLSYsuxLMtqlzNSUlKUkpLSbt+PP/5Yx44d0+23397hsVpaWlRVVaUf/vCHode8Xq+efPLJiPoUE0n16NGjysrK6u1uAAAk1dfX66tf/artxz1//rxGDEtXw4mALcdLT0/XZ599Fvba448/rieeeCLstUAgoLVr16qwsLDTY50+fVptbW1yu92h1zwej5qamtTY2Kj+/ft3q08xkVQzMjIkXfiH/PIvFMv+x5xnjGO3/i6yC992+fMf/MI41vd1s7jUE1HMPEQR+lm2+Ye232dmf6G3us3bzDhg/lFMnn7aOLYtYD4aGXT/CaO4jbXPGbeJnuX3+5WVlRX6f7LdWlpa1HAioLrdw+XOiG4k7D8T1LA/rW2XNzoapf7yl7/UokWLLjv6TkpKCvsqXZhF/fLX7oiJpHpx+O52u/tMUu3XL9U4trd+x8Rk8z4nGIYmpvROUk34inmCS2gz+7BH02ZiivlHMTGt/f9EusuKIqn2cyUbxfWVz/iVrKcvw6VnuJSeEV0bQXU/b5SUlOhHP/pR2Gs5OTl68MEHtXLlSklSZmamkpOT5ff7Q/v4fD6lpqYqMzOz2/2KiaQKALhyBKygAlb0x+iujz76KOx7l8ulDz/8MOyWGpfLpSlTpujQoUOh1w4cOKCpU6dG1C/brkTX1NRo8eLFWrNmjfLy8lRXV2fXoQEA6BGFhYWqrq6WJC1cuFBbtmwJ/Wzbtm265557IjqeLSPVYDCo2bNn69lnn9X06dM1YsQI3XXXXaqoqLDj8ACAOBKUpaCiG6pGG39RaWmpcnNzlZubq/nz56u2tlbLly9XIBDQzJkzNXfu3IiOZ0tS3b59uw4ePKjJkydLkqZPn645c+aosrJSN998sx1NAADiRFBBdX/ytvNjmLKsLxLy7t27w35WUFBgfFzJpunfiooKZWdnh1ZNJSYmKjs7W2VlZR3u39zcLL/fH7YBANDX2ZJUjx8/3m71lcfj0ZEjRzrcv6ioSB6PJ7RxjyoAXDkClmXLFotsSapJSUlh9/ZIF66zdnZvz9KlS+Xz+UJbfX29Hd0AAPQBF6+pRrvFIluuqQ4ePFi7du0Ke83n8+m6667rcP/OHiMFAIh/QVkKxMhCJbvZMlKdOnWqampqQhd/W1tbVVtbe9kHFwMAEG9sSaoTJkzQkCFDtHPnTknSjh07NHz4cI0bN86OwwMA4gjTv11ISEjQpk2btGLFClVXV6uiokKvvfYaFWcAAO3YsdAoVhcq2faYQq/Xq5deekmS9MADD9h1WAAA+gye/Wuo/I3HjGO9//YT49j+GeeMY+c/srvrnTrxyk9mGsUF+5n/Nekfbn51IqnRPNZKNIu7fVyVcZvPLXrZOPbhPd8zjl19w78ax8q8OE6f87M/mJ3/kvTo6G029iQ+BD/foj1GLCKpAgAcFbBh9W+08T2lZ0q7AwBwBWKkCgBwVMCSDaXf7OmL3UiqAABHxfM1VaZ/AQCwCSNVAICjgnIpoOieYxCMMr6nkFQBAI4KWhe2aI8Ri0iqAABHBWwYqUYb31O4pgoAgE0YqQIAHBXPI1WSKgDAUUHLpaAV5UKlKON7CtO/AADYhJEqAMBRTP8CAGCTgBIUiHKiNGBTX+wWF0n1B7sXGMcebXIbxW0c+R/GbTb77zWOffvO5cax0Xho9deN4r75zl8Zt5n2739iHPvn979tHPvae9cbxR3wDzBuMxqVp4YZx44tNT+ffuDdYRS3+ZZvGbf5ev2zxrHRoHwbuisukioAoO+wbFioZMXoQiWSKgDAUfF8TZXVvwAA2ISRKgDAUQErQQEryoVKPPsXAIALFWaCUU6UBhWbWZWkCgBwFNdUAQBAlxipAgAcZc81VaZ/AQD4/JpqlA/UZ/oXAID4xkgVAOCooA3P/mX1LwAA6jvXVC3L0rFjxzRkyJBuxzD9CwCIe3v27NGkSZN09dVX6y//8i916tSpDvdbt26dXC6XXC6XEhISdPDgwYjaiYuR6q/+dJ1x7J2/X2wUdy7YYtzm7TfsNY4NNphVi5GkmbPNq/m88c5HRnHvzTZuUoomNgofnnnQKG5//SDjNoe98DPj2G/83PxjvOv9nxjHjij+uVHcdS8cN25z2n/9nXFs2XSz/sJ+QSU4+vCH8+fP69VXX9Ubb7why7J0yy236JlnntFTTz3Vbt/y8nJVVlZKklJTUzV27NiI+hUXSRUA0HcELJcCUVaZiSTe5/Np+fLlSk5OliRNnjxZCQntk3pFRYXq6urU2NioadOmqV+/yFMk078AgD7L7/eHbc3Nze32GThwYCihtrS0qKGhQQ8//HC7/fbu3asTJ05oxowZGjlypKqqqiLuD0kVAOCowOerf6PdJCkrK0sejye0FRUVddru1q1bNX78eJWVlen9999v9/P7779f7777rvbv369BgwZp1qxZampqiuh3Y/oXAOCooJWgYJSrf4Ofr/6tr6+X2+0OvZ6SktJpzIwZMzRq1CgVFBRowYIF+vjjjzvcLycnR6WlpRo1apTKy8t12223dbtfJFUAgKMCNtynGvh8oZLb7Q5LqpeTmJio7OxsvfDCC8rMzNTJkyd17bXXdrjvgAEDNGHCBPl8voj6xfQvAOCKkpaWpmuuuUb9+/e/7H6BQEA5OTkRHZukCgBwVFBfrAA23YIRtHf69Glt3rxZ1udTxm+99Zbuvvtu9evXT4WFhaqurlZbW5uefvpp1dTUSJL279+vlJQU3XDDDRH9bkz/AgAcZc99qt2Pr6mp0b333qucnBzdeeedSk9P109/+lNJUmlpqXJzc+X1erV582atXLlSixcvltvt1vr16yPuF0kVABDXbrrpJh0/3vFDR3bv3h367507d0bdFkkVAOAoe579G5tXL0mqAABHUU8VAAB0iZEqAMBRTP8CAGATex7+QFLtMa3HvmYc+29/dsgobvTvnjBuc2Rmx3X8uuO++onGsVm/rDGONZXzqnlpsQ/vWG4cG02JvA+O/q1R3HfH7DVu8+2Tw41jP3j0auPYB/f8lXFsv6abjeKOnPgT4zaH/rP5/7IWpi80jv31uF8bx6K9oOVSMMoqNdHG95TYTPUAAPRBcTFSBQD0HUEbpn+jfXhETyGpAgAcZU+VmthMqrHZKwAA+iBGqgAARwXkUiDKhzdEG99TSKoAAEcx/QsAALrESBUA4KiAop++DdjTFduRVAEAjmL6FwAAdImRKgDAUTxQHwAAm1g21FO1uKUGAID4HqnGZq8AAOiD4mKkmjTYrHxbNP4w5wnH25Skb29/zDi2oTbTvGGzKl9RlW/7m3fuMY79zbiPjGMP32UW9/Ce7xm3uexr/24e2zbHOHbTnuuNY+uW5hvF3fn7xcZtVs42L/NYd8BrHDvhj48ax1bc+jPj2HgVz6Xf4iKpAgD6jnguUh6bvQIAoA/qsaR69OjRnjo0AKAPuzj9G+0Wi2xLqpZlyev1yuVyyeVyacGCBXYdGgAQR4JKsGWLRbZdU3399df14IMPavz48ZKkESNG2HVoAAD6BNtS/S9+8QslJiZqwIABuummm5SZGcVKUwBA3ApYLlu2WGRLUj1z5oyam5u1bNkyjRgxQkuWLJFlWZ3u39zcLL/fH7YBAK4MXFPtQkZGht588001NDSouLhYzz//vJ577rlO9y8qKpLH4wltWVlZdnQDAIBeZeuV3qSkJC1ZskSPPfaY1q9f3+l+S5culc/nC2319fV2dgMAEMOsz0u/RbNZV9JjCm+//Xb5fL5Of56SkiK32x22AQCuDAG5bNliUY88USkQCCgnJ6cnDg0A6OOCVvSPGQx2vmynV9kyUt25c6fWrVsXWpy0Zs0aPfLII3YcGgCAPsOWkWp9fb0eeughvfzyyxo/frzy8vI0adIkOw4NAIgzF6+LRnuMWGRLUp0/f77mz59vx6EAAHEuaEOR8mjjewpVagyN/NcVxrHf/OoR49i3ZzxvHBtNKbXe8JtxL/R2FyKyL/9bxrE/f7nKOPappFbj2Gf/vPNV+l3JfjlgGDnUuM26xb1zWenW8od6pV3YZ8+ePVqyZIn+8Ic/6MYbb9S//Mu/6Jprrmm3X3Fxsc6dO6ezZ88qMzNT+fmRlTgkqQIAHGXHE5EiiT9//rxeffVVvfHGG7IsS7fccoueeeYZPfXUU2H7bdiwQRs3btSOHTskSRMnTtTo0aM1c+bMbrcVm5PSAIC4Fe09qpFek/X5fFq+fLnS0tJ01VVXafLkyUpIaB+/atUq3XrrraHvZ82apZKSkoh+N5IqAKDPuvSRt83Nze32GThwoJKTkyVJLS0tamho0MMPPxy2T0tLi6qqqsJuB/V6vSorK4uoPyRVAICjgrLh2b+fL1TKysoKe+xtUVFRp+1u3bpV48ePV1lZmd5///2wn50+fVptbW1hDyPyeDxqampSY2Njt383rqkCABxl2bD61/o8vr6+PiwRpqSkdBozY8YMjRo1SgUFBVqwYIE+/vjj0M+SkpLCvkpSMBgM+9odJFUAQJ8VyaNuExMTlZ2drRdeeEGZmZk6efKkrr32WklSZmamkpOTw6qm+Xw+paamRlTKlKQKAHCUHaXboolPS0vTNddco/79+4dec7lcmjJlig4dOhR67cCBA5o6dWpEx+aaKgDAUU6v/j19+rQ2b94cepTuW2+9pbvvvlv9+vVTYWGhqqurJUkLFy7Uli1bQnHbtm3TPfdEdn8/I1UAgKOcHqnW1NTo3nvvVU5Oju68806lp6frpz/9qSSptLRUubm5ys3N1fz581VbW6vly5crEAho5syZmjt3bkT9IqkCAOLaTTfdpOPHj3f4s927d4d9X1BQEFVbJFUAgKN49i8AADbp7YVKPYmFSgAA2ISRKgDAUfE8Uo2LpDoz51Hj2IM/yTCL+94y4zZ7y+//Y6xx7NfrnjSK+2rmH43bLJv+c+PYCd9bZRzb9hWzCZwTC3rn41Q+9ne90u6cvzJb0BFs+HoUrUa3iMRU89NDzIOn2taNuBHPSZXpXwAAbBIXI1UAQN8RzyNVkioAwFGWor8lxrKnK7Zj+hcAAJswUgUAOIrpXwAAbEJSBQDAJvGcVLmmCgCATRipAgAcFc8jVZIqAMBRluWSFWVSjDa+pzD9CwCATRipAgAcRT1VAABswjXVGLf1rY3GsQmDPjKK+8ZrTxi3+f6EfzaOLT2bZhz70d+/axxrKpqKJN/+a/PKIEmt5g8xa0s1DEwwbzP71UXGsf3fM7+Ks+f5fOPYby8wqyL09jqzz1xvemvrj3q7CxFZ+M5Co7iWz1ps7smVJy6SKgCg74jnhUokVQCAo+J5+pfVvwAA2ISRKgDAUUz/AgBgE8uG6V+SKgAAulBg3IqyyjhFygEAiHOMVAEAjgrKJRdPVAIAIHrxvFCJ6V8AAGzCSBUA4Kig5ZIrTh/+QFIFADjKsmxY/Rujy3+Z/gUAwCaMVAEAjornhUpxkVT/4g+zjWOv+miJUVxm+leM2zQtNydJ6yvMS4TN+ZpxqHEJt28/er9xm6lnAsaxroD53FBqwKzdAW8lGbeZdDZoHDv87/Ybx0ZTmq9ilWmb/2jc5m0j/8w4dvtnvzGO9f7bT4xjD9y53DjW1K/H/doozu/3a73W29yb9uI5qTL9CwBAByzL0tGjRyOKIakCABx1sfRbtFskSktLlZOTI7fbrTvuuEOffvpph/utW7dOLpdLLpdLCQkJOnjwYETtxMX0LwCg73B69e/hw4e1ZcsWbdy4UR9++KHuu+8+Pfroo1q7dm27fcvLy1VZWSlJSk1N1dixYyPqF0kVAOCoC0k12muq3d93165dKikpUXJyssaMGaN9+/Zpw4YN7farqKhQXV2dGhsbNW3aNPXrF3mKZPoXANBn+f3+sK25ubndPnl5eUpOTg59P3DgQA0dOrTdfnv37tWJEyc0Y8YMjRw5UlVVVRH3h6QKAHDUxdW/0W6SlJWVJY/HE9qKioq6bL+qqkqLFrW/k+L+++/Xu+++q/3792vQoEGaNWuWmpqaIvrdmP4FADjKUvT1UC/G19fXy+12h15PSUm5bNyxY8fU1tamOXPmdLpPTk6OSktLNWrUKJWXl+u2227rdr9IqgCAPsvtdocl1csJBAIqLi5WSUlJl/sOGDBAEyZMkM/ni6g/JFUAgKN66+EPq1evVn5+vtLT0yVJLS0tYddaLxUIBJSTkxNRGyRVAICz7Jz/7abi4mJ5vV41NjaqsbFRhw8fVltbm/bs2aPvfve7+sY3vqFnnnlGc+fO1YgRI7R//36lpKTohhtuiKgdkioAIK698sorys/Pl/Wl+3DS0tLU0NCgwsJC5ebmyuv1avPmzVq5cqUWL14st9ut9esjf2QjSRUA4Cwbpn8VQfy8efM0b968Dn+2e/fu0H/v3Lkzuj6JpAoAcBj1VAEAQJfiYqRaNv3njrdZXmteMsv75GDj2AM//ifj2GjKfN30uFkJt9Qm85JmrqD5n6L9mszLxiW0GvbZ6nwVYZehicaheqf8G+bBf1tuHDr2uR8Yxb334K+M23z94O+NY7+28hnj2EOPOF++Lfvn5v09/Hf5NvbEfvFc+i0ukioAoA+xXBFdE+30GDGIpAoAcBTXVDvQ1NQU8ZMmAACIZxEn1WAwqBdffFFer1d79uwJvV5TU6PFixdrzZo1ysvLU11dna0dBQDECcumLQZFPP176tQpTZs2TZ988knotWAwqNmzZ+vZZ5/V9OnTNWLECN11112qqKiwtbMAgL4vnhcqRTxSHTBggIYNGxb22vbt23Xw4EFNnjxZkjR9+nTt27cvVD0dAIArgS33qVZUVCg7O1tJSUmSpMTERGVnZ6usrKzD/Zubm9sVlgUAXEHicOpXsimpHj9+vF3pHY/HoyNHjnS4f1FRUVhR2aysLDu6AQDoA+wsUh5rbEmqSUlJoVHqRcFgUMFgxzfRL126VD6fL7TV19fb0Q0AAHqVLfepDh48WLt27Qp7zefz6brrrutw/5SUlC6rswMA4lQvlH5zii0j1alTp6qmpiZUVqe1tVW1tbWaNm2aHYcHAMQVl01b7DFKqpdO606YMEFDhgwJlc3ZsWOHhg8frnHjxkXfQwAA+oiIp39PnjyptWvXSpLWrVunQYMGadSoUdq0aZNWrFih6upqVVRU6LXXXpPLFZt/SQAAelEcT/9GnFSvvfZaFRQUqKCgIOx1r9erl156SZL0wAMP2NM7AED8IaniUm+eGWMcm/ytRht70n1TfvB949irAmal1FwB8zM/oS2K0m9nW41j1cmq9a4k/9G8yRM3p5kHjzhrHJq9cZFxbOLVZv8+CYM+Mm7z1pufMI49VBnb5dAuFevl26ISx1VqKFIOAIBNGKkCABwVz6XfSKoAAGfF8TVVpn8BALAJI1UAgLPieKESSRUA4CiXdWGL9hixiOlfAABswkgVAOCsOF6oRFIFADgrjq+pMv0LAIBNGKkCAJzF9C8AADYhqQIAYJM4TqpcUwUAwCYxNVId8+tnlfCV1Ijj+u9NNG5z76/Myis9mfs74zZ3PvIz49hRu1cbxw46Z1bSTJKCiWYr7aK5Qbvf2Tbj2AR/k3nDhk/qthLN/0a9994txrFL+tcZx059b45x7KfnvmIU99nRYcZtvlFp/rsihsTx6t+YSqoAgPjHE5UAAECXGKkCAJzVCwuVSktL9cgjj+jYsWO65ZZbtHbtWl199dXt9isuLta5c+d09uxZZWZmKj8/skuEJFUAQFw7fPiwtmzZoo0bN+rDDz/Ufffdp0cffVRr164N22/Dhg3auHGjduzYIUmaOHGiRo8erZkzZ3a7LZIqACCu7dq1SyUlJUpOTtaYMWO0b98+bdiwod1+q1at0ne+853Q97NmzVJJSUlESZVrqgAAR7n0xWIl4+3zY/n9/rCtubm5XXt5eXlKTk4OfT9w4EANHTo0bJ+WlhZVVVUpJycn9JrX61VZWVlEvxtJFQDgrIu31ES7ScrKypLH4wltRUVFXTZfVVWlRYsWhb12+vRptbW1ye12h17zeDxqampSY2Njt381pn8BAH1WfX19WCJMSUm57P7Hjh1TW1ub5syZE/Z6UlJS2FdJCgaDYV+7g6QKAHCWjat/3W53WFK9nEAgoOLiYpWUlLT7WWZmppKTk+X3+0Ov+Xw+paamKjMzs9vdYvoXAOAsy6YtQqtXr1Z+fr7S09MlXbiOepHL5dKUKVN06NCh0GsHDhzQ1KlTI2qDpAoAcFTUi5QMnshUXFwsr9erxsZGffDBB9q6dau2bdumwsJCVVdXS5IWLlyoLVu+eGTotm3bdM8990TUDtO/AIC49sorryg/P1/Wl57rnZaWpoaGBhUWFio3N1e5ubmaP3++amtrtXz5cgUCAc2cOVNz586NqC2SKgDAWQ4/UWnevHmaN29ehz/bvXt32PcFBQXR9Cq2kuqM699TcnpS1zte4lffX2fcZrDh60ZxCYM+Mm7zv17838axkx9Y1PVOPcAVNPsE9DsfMG6zX+M541hXq3mFG6ufWdWjVndy1zt14nfHvmUc+8LBCcax//TN3xrH/s1/RzYtdlH6EPNKM6afVym6zyxsRj1VAADQlZgaqQIA4l88l34jqQIAnBXHRcqZ/gUAwCaMVAEAzorjhUokVQCAo+L5mirTvwAA2ISRKgDAWUz/AgBgExumf0mqAABIcT1S5ZoqAAA2YaQKAHBWHI9USaoAAEdxSw0AAOhSTI1UVw35b7kznM3zKz/9mlFc2V+Y19yrveMHxrGZMi+lFo2EVsM/C4NRNNrSahxqWr5NkqzUyMsPSlJrhvnH6ZPDA41jv/unu7veqRN3//ODxrGtGWbnxA1b/t64zT/+caFxbM1fG4cC3RZTSRUAcAWI42uqTP8CAGATRqoAAEfF80IlkioAwHkxmhSjxfQvAAA2YaQKAHBWHC9UIqkCABzFNVUAAOwSxyNVrqkCAGATRqoAAEcx/QsAgF2Y/gUAAF1hpAoAcFYcj1RJqgAAR3FN1SHfeuuvlZCWGnHcoGseNW4z6bnpRnEn55iVB5OktjFnjWNT/q95STNX0PmzMPF8m3GsK2BeN85yuYxjlWB2VSTtyDnjJq86nGEcu+XYeOPYf1rwj8ax976dZxTXWNvfuM2v/WuzcWz5xK8bx9779t8Yxx783jKjuIf3fM+4zdU3/KtxLKITU0kVAHAFYPoXAACbxHFSNV7929TUJJ/P1+nPjx49anpoAAD6pIiTajAY1Isvviiv16s9e/aEXrcsS16vVy6XSy6XSwsWLLC1owCA+HBxoVK0m4muBoRfZllWxAPEiJPqqVOnNG3aNH3yySdhr7/++ut68MEHVVlZqcrKSm3YsCHSQwMArgSWTVsEOhsQXmrdunWhwWFCQoIOHjwYUTsRX1MdMGBAh6//4he/0He+8x0NGDBAQ4cOvewxmpub1dz8xSo+v98faTcAAH1Ub9xS09mA8FLl5eWqrKyUJKWmpmrs2LERtWPLE5XOnDmj5uZmLVu2TCNGjNCSJUtkWZ3/xkVFRfJ4PKEtKyvLjm4AANChAQMGaNiwYZfdp6KiQnV1dWpsbNT1118fcUKVbEqqGRkZevPNN9XQ0KDi4mI9//zzeu655zrdf+nSpfL5fKGtvr7ejm4AAPoCG6d//X5/2PblWdBI7d27VydOnNCMGTM0cuRIVVVVRXwMW5/9m5SUpCVLluixxx7T+vXrO90vJSVFbrc7bAMAXCFsTKpZWVlhM59FRUXG3br//vv17rvvav/+/Ro0aJBmzZqlpqamiI7RIw/Uv/3227u9ugoAAFP19fVhM59Lly6N+pg5OTkqLS3V+fPnVV5eHlFsjzz8IRAIKCcnpycODQDo41yfb9EeQ1KPzXYOGDBAEyZMiHiAaDRSDQbDn8m6c+dOrVu3LrQ4ac2aNXrkkUdMDg0AiHe9cEuNCZMBYsRJ9eTJk/qHf/gHSRfu5/nggw9UX1+vhx56SLNmzdKTTz6pvLw8TZo0KdJDAwDQYy4dEEpSYWGhqqur1dbWpqefflo1NTWSpP379yslJUU33HBDRG1EPP177bXXqqCgQAUFBaHXRo0apfnz50d6KADAFag37lM9efKk1q5dK+nCgHDQoEEaNWqUSktLlZubK6/Xq82bN2vlypVavHix3G73ZRfcdt6vy91Q6hC/3y+Px6OF5fOUnJ4ccfzrVbnGbaceMyvhltxo3KRSG83f8oRW89j0T8yXmicfMfyFW1qN21Q05dv6mZfIsxLN1u+1DTC/rnNk6lXGsc2Z5iXyBo45YRzbcNJjFHdzdp1xm9F4e99I49i6RVfG5ayL/y/2+Xw9cp3y4vHHLHpKiSmRl/n8skDzeb3/TwU91ldTPbL6FwCAKxGl3wAAzuv1OdKeQVIFADiqN66pOoWkCgBwFkXKAQBAVxipAgAcxfQvAAB2YfoXAAB0hZEqAMBRTP8CAGAXpn8BAEBXGKkCAJwVxyNVkioAwFHxfE2V6V8AAGwSUyPV3x8docS0lIjjEs+Yl/lKO2b2504wybws2adjjEPVr8n876DWdPNSS+6UTKO4xPMB4zZb3WZl+SQp7eCnxrFRlZwz1HZV7/zZfbTe7N9VkpKPm/3v4x1ruHGbtQuWGsdO+/E/GMdqkXlob5j2X39nFNd21rw8ZESY/gUAwB4uy5IrylLe0cb3FJIqAMBZcTxS5ZoqAAA2YaQKAHBUPK/+JakCAJzF9C8AAOgKI1UAgKOY/gUAwC5M/wIAgK4wUgUAOIrpXwAA7ML0LwAA6AojVQCA42J1+jZaMZVU3/mfBXK73RHHLXxnoXGbZdfkGMWl74u8ms5FSf4oqqBEEZriMz+Lm682qxiT0GZ+iiU2B41jLYNqRyFBs3atJPOJn4QW83/Yr0+sNY79w3tDjWP/ZvZ/GcUtG/vvxm1Go+w/H+uVdntD2fSfG8X5/X559Eube9MBy7qwRXuMGBRTSRUAEP/ieaES11QBALAJI1UAgLPiePUvSRUA4ChX8MIW7TFiEdO/AADYhJEqAMBZTP8CAGCP3lz929TUpJaWFnk8nug60AmSKgAg7gWDQb300kv68Y9/rN/+9reaOnVqh/sVFxfr3LlzOnv2rDIzM5Wfnx9ROyRVAICzeuHhD6dOndK0adP0ySefdLrPhg0btHHjRu3YsUOSNHHiRI0ePVozZ87sdjssVAIAOOri9G+0WyQGDBigYcOGXXafVatW6dZbbw19P2vWLJWUlETUDkkVANBn+f3+sK25udnoOC0tLaqqqlJOzhePrvV6vSorK4voOCRVAICzLJs2SVlZWfJ4PKGtqKjIqEunT59WW1tb2PPnPR6Pmpqa1NjY2O3jcE0VAOAoO1f/1tfXhyXClBSzYhpJSUlhX6ULi5u+/LU7SKoAAGfZuFDJ7XYbVTe7VGZmppKTk+X3+0Ov+Xw+paamKjMzs9vHiamkOmfno+p3VeR/ZZw8O8S4zRu/VmcU98l/jDRuM9jPvMyXP9s81hWM0bulOxHN+xRMTowiNtkoznKZ9zehxThU7qTzxrH9h3V/WutSLx/6U6O4ZWONmwR6jMvl0pQpU3To0KHQawcOHOj01pvOcE0VAOCo3lj9K3U8jVtYWKjq6mpJ0sKFC7Vly5bQz7Zt26Z77rknojZiaqQKALgC9MJjCk+ePKm1a9dKktatW6dBgwZp1KhRKi0tVW5urnJzczV//nzV1tZq+fLlCgQCmjlzpubOnRtROyRVAEDcu/baa1VQUKCCgoKw13fv3h32/aU/jxRJFQDgqN589m9PI6kCAJwVtC5s0R4jBrFQCQAAmzBSBQA4i3qqAADYwyUbrqna0hP7kVQBAM7qhdJvTuGaKgAANmGkCgBwFLfUAABglzheqMT0LwAANmGkCgBwlMuy5IpyoVG08T0lppLq7yb/zKgu3qTvrjRuc+PGnxrFXd+4zLjNjLUe49izQ8z/yVrSzScmUv8YMAuM4rxvTTPvb8vXrzKODSaZLdZvvcp8kX/y+E+NY+uezTGOTTWOlHzfjiL4ClKw77tGcU99c6PNPYkhwc+3aI8Rg5j+BQDAJjE1UgUAxL94nv6NaKRaWlqqnJwcud1u3XHHHfr00wtTVjU1NVq8eLHWrFmjvLw81dXV9UhnAQBxwLJpi0HdTqqHDx/Wli1btHHjRr344osqLy/Xo48+qmAwqNmzZ2vevHn6/ve/r7vvvlt33XVXT/YZAICY1O3p3127dqmkpETJyckaM2aM9u3bpw0bNmj79u06ePCgJk+eLEmaPn265syZo8rKSt1888091nEAQB/FYwqlvLw8JScnh74fOHCghg4dqoqKCmVnZyspKUmSlJiYqOzsbJWVlXV6rObmZvn9/rANAHBluPhEpWi3WGS8+reqqkqLFi3S8ePH290G4/F4dOTIkU5ji4qK5PF4QltWVpZpNwAAfc3FkWq0WwwySqrHjh1TW1ub5syZo6SkpNAo9aJgMKhgsPObiJYuXSqfzxfa6uvrTboBAEBMifiWmkAgoOLiYpWUlEiSBg8erF27doXt4/P5dN1113V6jJSUFKWkpETaNAAgDriCF7ZojxGLIh6prl69Wvn5+UpPT5ckTZo0STU1NbI+H4q3traqtrZW06ZNs7enAID4EMfTvxGNVIuLi+X1etXY2KjGxkYdPnxYbW1tGjJkiHbu3KkpU6Zox44dGj58uMaNG9dTfQYAICZ1O6m+8sorys/PD41IJSktLU0NDQ3atGmTVqxYoerqalVUVOi1116Ty2X+HFQAQByL49Jv3U6q8+bN07x58zr8WUZGhl566SVJ0gMPPGBPzwAAcYnHFAIAgC7FxQP1T3/D/Nf4xw//3CguMWGScZujflxtHPvuc98yjj03wPxvqMRmw9gorgJY0cQmmgen+MyWFQYTzd/fM/v6G8f+8dZW49jvXP+ucewvblxvFLfivVnGbS4b++/GsaMeX20c+0Hhw8axpiXcvvmQeX/3FZv31xFx/ESluEiqAIA+xFL09VBjM6cy/QsAgF0YqQIAHBXPC5VIqgAAZ1my4ZqqLT2xHUkVAOCsOF6oxDVVAABswkgVAOCsoKK63S50jBjESBUA4KiLC5Wi3XqaZVk6evRoRDEkVQBA3KupqdHixYu1Zs0a5eXlqa6ursP91q1bJ5fLJZfLpYSEBB08eDCidpj+BQA4y+GFSsFgULNnz9azzz6r6dOna8SIEbrrrrtUUVHRbt/y8nJVVlZKklJTUzV27NiIusVIFQDgLIfrqW7fvl0HDx7U5MmTJUnTp0/Xvn37QsnzooqKCtXV1amxsVHXX399xAlVIqkCAPowv98ftjU3N7fbp6KiQtnZ2UpKSpIkJSYmKjs7W2VlZWH77d27VydOnNCMGTM0cuRIVVVVRdwfkioAwFk2jlSzsrLk8XhCW1FRUbvmjh8/LrfbHfaax+PRkSNHwl67//779e6772r//v0aNGiQZs2apaampoh+Na6pAgCcZeMtNfX19WEJMyUlpd2uSUlJoVFqKDwYVDDY8X05OTk5Ki0t1ahRo1ReXq7bbrut292KqaT63fFPql9i+zekK/urVxi3eWt5xyvAulJ54yvGbY597gfGsYGvGYcqmGy+MCDZb/YJSGw/E9NtwSjOztYM809s07WJRnEt7q736UzSGJ9xbOCQecMf/K8xxrHPrvlLo7hlY//TuM37/jvPOLbtquuNY2fc+Lhx7PaqQqO4mC/fFiPcbne7UeilBg8erF27doW95vP5dN1113UaM2DAAE2YMEE+X2SfTaZ/AQCOcvo+1alTp6qmpkbW5zGtra2qra3VtGnTLhsXCASUk5MT0e9GUgUAOMvh1b8TJkzQkCFDtHPnTknSjh07NHz4cI0bN06FhYWqrq5WW1ubnn76adXU1EiS9u/fr5SUFN1www0R/WoxNf0LALgCBC3JFeV9qsHuxyckJGjTpk1asWKFqqurVVFRoddee00ul0ulpaXKzc2V1+vV5s2btXLlSi1evFhut1vr16+PuFskVQBA3PN6vXrppZckSQ888EDo9d27d4f+++JINhokVQCAs+K49BtJFQDgMBuSaoxWKWehEgAANmGkCgBwFtO/AADYJGgp6unbCFb/OonpXwAAbMJIFQDgLCt4YYv2GDGIpAoAcFYcX1Nl+hcAAJvE1Eh14//7cZfVBjoybO3Txm3W3VdsFPfbj/6fcZupp8z/wjo9scW83drIKwBdZCWa9bn1KuMmFUgxrzSTdM78PT4XRYUbU8Eqj3FsYIT5OXHux37j2GfeMatSs/q/29e77K6EU98yjj38o3zjWP3IPLQ3/MW0p4zi2trO29yTTsTxQqWYSqoAgCtAHE//klQBAM6yZENStaUntuOaKgAANmGkCgBwFtO/AADYJBiUFOV9psHYvE+V6V8AAGzCSBUA4CymfwEAsEkcJ1WmfwEAsAkjVQCAs3iiEgAA9rCsoKwoq8xEG99TmP4FAMAmjFQBAM6yrOinb2N0oRJJFQDgLMuGa6ok1a5Nv6dE/ZJSI46rWb3WuM0Fb39oFHejO8O4zao1UZSgisJflJm3e+jItUZxGXsi//e8qO0rxqFq8ZiXb+tnWP3q/JCAcZspJxONY7896rBx7O7/m2Mcm9Zo9h7/2Zx3jdv8Pze/aBx7JXmzrMAozu/3y+N50ubedCAYlFxRXhPlmioAAPEtpkaqAIArANO/AADYwwoGZUU5/cstNQAAxDlGqgAAZzH9CwCATYKW5IrPpMr0LwAANmGkCgBwlmVJivY+1dgcqZJUAQCOsoKWrCinf60YTapM/wIAYBNGqgAAZ1lBRT/9G1l8TU2Nfvazn+nGG2/Url279OSTT2rYsGHt9isuLta5c+d09uxZZWZmKj8/sse7klQBAI5yevo3GAxq9uzZevbZZzV9+nSNGDFCd911lyoqKsL227BhgzZu3KgdO3ZIkiZOnKjRo0dr5syZ3W6L6V8AgLOsoD1bN23fvl0HDx7U5MmTJUnTp0/Xvn37VFlZGbbfqlWrdOutt4a+nzVrlkpKSiL61WJipHrxL45Aq1l5EP8Z82mE1rMtRnHnE9qM2/T7/cax0Wg722wcG2wy+7cJmDepQBR/8gXNC8bIZdjnYJN5o4Hz5lVqTM9hSQqeNyzJIynQbFalpuUz8/721mfnSnHx/e3pRUBtao362Q9tapXU/pxISUlRSkpK2GsVFRXKzs5WUlKSJCkxMVHZ2dkqKyvTzTffLElqaWlRVVWVfvjDH4bivF6vnnwysqo9MZFUz5w5I0naW7rCKL7/q9G0blY265UoWvx7eaKIBsIdKurtHkTmo5+bx67Ty/Z1BJ06c+aMPB77/z+VnJysQYMGaVfDVluOl56erqysrLDXHn/8cT3xxBNhrx0/flxutzvsNY/HoyNHjoS+P336tNra2sL283g8ampqUmNjo/r379+tPsVEUh0yZIjq6+uVkZEhlyv8r1+/36+srCzV19e3e1PwBd6n7uF96h7ep+6Jt/fJsiydOXNGQ4YM6ZHjp6amqqamRi0t5rMVX2ZZVruccekoVZKSkpJCo9SLgsGggsFg2D5f/npxny9/7Y6YSKoJCQn66le/etl93G53XJy0PY33qXt4n7qH96l74ul96okR6pelpqYqNTW1R9u41ODBg7Vr166w13w+n6677rrQ95mZmUpOTg6bTvb5fEpNTVVmZma322KhEgAgrk2dOlU1NTWha8Wtra2qra3VtGnTQvu4XC5NmTJFhw4dCr124MABTZ06NaK2SKoAgLg2YcIEDRkyRDt37pQk7dixQ8OHD9e4ceNUWFio6upqSdLChQu1ZcuWUNy2bdt0zz33RNRWTEz/Xk5KSooef/zxDufJ8QXep+7hfeoe3qfu4X3qGxISErRp0yatWLFC1dXVqqio0GuvvSaXy6XS0lLl5uYqNzdX8+fPV21trZYvX65AIKCZM2dq7ty5EbXlsmL1AYoAAPQxTP8CAGATkioAADYhqQIAYBOSahw6evRob3ch5jQ1Ncnn8/V2N2JaV+8R5xXQtZhOqjU1NVq8eLHWrFmjvLw81dXV9XaXYpJlWfJ6vXK5XHK5XFqwYEFvdylmBINBvfjii/J6vdqzZ0/odc6tL3T2HnFehSstLVVOTo7cbrfuuOMOffrpp5I4l3AJK0YFAgFr7Nix1ptvvmlZlmW98cYb1vjx43u5V7Fpy5YtVklJiVVZWWlVVlZap06d6u0uxYzjx49btbW1liSrrKzMsizOrUt19B5ZFufVlx06dMj6/ve/b7333nvWq6++al199dXWvffey7mEdmI2qW7dutVKTU21WlpaLMuyrLa2NistLc165513erlnsee2226zfvWrX1l1dXW93ZWY9eWEwbnVsUuTKufVF37zm99Yzc3Noe8ff/xxa/To0ZxLaCdmp38vV6oHXzhz5oyam5u1bNkyjRgxQkuWLOnxsk19HedW1zivwuXl5Sk5OTn0/cCBAzV06FDOJbQTs0m1O6V6IGVkZOjNN99UQ0ODiouL9fzzz+u5557r7W7FNM6trnFeXV5VVZUWLVrEuYR2YjapdqdUD76QlJSkJUuW6LHHHtP69et7uzsxjXOr+ziv2jt27Jja2to0Z84cziW0E7NJdfDgwe0qul9aqgft3X777dw60gXOrchxXl0QCARUXFyskpISSZxLaC9mk2p3SvWgvUAgoJycnN7uRkzj3Ioc59UFq1evVn5+vtLT0yVJkyZN4lxCmJhNqpcr1YMv7Ny5U+vWrQt9qNesWaNHHnmkl3sVWy6diuPcau/S94jzqr3i4mJ5vV41Njbqgw8+0NatW+Xz+TiXECZmS79drlQPvlBfX6+HHnpIL7/8ssaPH6+8vDxNmjSpt7sVM06ePKm1a9dKktatW6dBgwZp1KhRnFtf0tF7xHkV7pVXXlF+fn7YCui0tDQ1NDRwLiEMpd8AALBJzE7/AgDQ15BUAQCwCUkVAACbkFQBALAJSRUAAJuQVAEAsAlJFQAAm5BUAQCwCUkVAACbkFQBALAJSRUAAJv8f/2CJKtLqW1tAAAAAElFTkSuQmCC\n",
227
- "text/plain": [
228
- "<Figure size 640x480 with 2 Axes>"
229
- ]
230
- },
231
- "metadata": {},
232
- "output_type": "display_data"
233
- }
234
- ],
235
- "source": [
236
- "plt.imshow(som_data, vmin = 0, vmax=4)\n",
237
- "plt.colorbar()"
238
- ]
239
- },
240
- {
241
- "cell_type": "markdown",
242
- "id": "06b4a006-f404-4e13-a4ea-ca5abd93f669",
243
- "metadata": {
244
- "tags": []
245
- },
246
- "source": [
247
- "## SOM VISUAIZATION IN THE TRAINING SAMPLE"
248
- ]
249
- },
250
- {
251
- "cell_type": "code",
252
- "execution_count": 135,
253
- "id": "07359f91-eb81-40e8-886c-8b845b8d1e96",
254
- "metadata": {},
255
- "outputs": [],
256
- "source": [
257
- "f, ferr, specz ,VIS_mag = photoz_archive.get_training_data()"
258
- ]
259
- },
260
- {
261
- "cell_type": "code",
262
- "execution_count": 136,
263
- "id": "807cc874-769b-4c4a-a499-6df524a9731e",
264
- "metadata": {},
265
- "outputs": [],
266
- "source": [
267
- "bmu = selforgmap.test_obj(f)"
268
- ]
269
- },
270
- {
271
- "cell_type": "code",
272
- "execution_count": 137,
273
- "id": "2b4d6675-4950-47ea-a0f8-98bcfae8377b",
274
- "metadata": {},
275
- "outputs": [],
276
- "source": [
277
- "df = pd.DataFrame(np.c_[specz, bmu], columns = ['zs','cell'])"
278
- ]
279
- },
280
- {
281
- "cell_type": "code",
282
- "execution_count": 142,
283
- "id": "8f163e3f-9d6e-43a5-abd9-c22ca24d9b1a",
284
- "metadata": {},
285
- "outputs": [],
286
- "source": [
287
- "som_vis = df.groupby('cell').zs.mean().reset_index().rename(columns = {'zs':'zs_som'})\n",
288
- "\n"
289
- ]
290
- },
291
- {
292
- "cell_type": "code",
293
- "execution_count": 143,
294
- "id": "cdead865-1dbe-4f23-859c-24d360ab87f1",
295
- "metadata": {},
296
- "outputs": [],
297
- "source": [
298
- "x_cells = np.arange(0,nx)\n",
299
- "y_cells = np.arange(0,ny)\n",
300
- "index_cell = np.arange(nx*ny)\n",
301
- "cells = np.array(np.meshgrid(x_cells,y_cells)).T.reshape(-1,2)\n",
302
- "cells = pd.DataFrame(np.c_[cells[:,0],cells[:,1],index_cell], columns = ['x_cell','y_cell','cell'])"
303
- ]
304
- },
305
- {
306
- "cell_type": "code",
307
- "execution_count": 144,
308
- "id": "c278f2a8-7c2c-4e1a-899a-da7d7430450b",
309
- "metadata": {},
310
- "outputs": [],
311
- "source": [
312
- "som_data = som_vis.merge(cells, on = 'cell')\n",
313
- "som_data = som_data.pivot(index = 'x_cell', columns = 'y_cell', values = 'zs_som')"
314
- ]
315
- },
316
- {
317
- "cell_type": "code",
318
- "execution_count": 145,
319
- "id": "53956233-3465-40d6-9316-6612edfc236a",
320
- "metadata": {},
321
- "outputs": [
322
- {
323
- "data": {
324
- "text/plain": [
325
- "<matplotlib.colorbar.Colorbar at 0x2b2c1c782160>"
326
- ]
327
- },
328
- "execution_count": 145,
329
- "metadata": {},
330
- "output_type": "execute_result"
331
- },
332
- {
333
- "data": {
334
- "image/png": "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\n",
335
- "text/plain": [
336
- "<Figure size 640x480 with 2 Axes>"
337
- ]
338
- },
339
- "metadata": {},
340
- "output_type": "display_data"
341
- }
342
- ],
343
- "source": [
344
- "plt.imshow(som_data, vmin = 0, vmax=4)\n",
345
- "plt.colorbar()"
346
- ]
347
- },
348
- {
349
- "cell_type": "markdown",
350
- "id": "456f4ab6-fe27-4e28-8be6-2847de9ebbab",
351
- "metadata": {},
352
- "source": [
353
- "with predicted and PAUS redshifts"
354
- ]
355
- },
356
- {
357
- "cell_type": "code",
358
- "execution_count": null,
359
- "id": "e8847b26-70dd-4287-93c5-c04e66ee3112",
360
- "metadata": {},
361
- "outputs": [],
362
- "source": []
363
- },
364
- {
365
- "cell_type": "code",
366
- "execution_count": null,
367
- "id": "44c3104f-8057-409a-948d-6bfbd87f8080",
368
- "metadata": {},
369
- "outputs": [],
370
- "source": []
371
- },
372
- {
373
- "cell_type": "code",
374
- "execution_count": null,
375
- "id": "84e483fd-4981-443f-8c61-e6b263ffa167",
376
- "metadata": {},
377
- "outputs": [],
378
- "source": []
379
- },
380
- {
381
- "cell_type": "code",
382
- "execution_count": null,
383
- "id": "e3afd654-9116-485b-8921-5412d64d5fe5",
384
- "metadata": {},
385
- "outputs": [],
386
- "source": []
387
- }
388
- ],
389
- "metadata": {
390
- "kernelspec": {
391
- "display_name": "DLenv2",
392
- "language": "python",
393
- "name": "dlenv2"
394
- },
395
- "language_info": {
396
- "codemirror_mode": {
397
- "name": "ipython",
398
- "version": 3
399
- },
400
- "file_extension": ".py",
401
- "mimetype": "text/x-python",
402
- "name": "python",
403
- "nbconvert_exporter": "python",
404
- "pygments_lexer": "ipython3",
405
- "version": "3.9.7"
406
- }
407
- },
408
- "nbformat": 4,
409
- "nbformat_minor": 5
410
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
notebooks/HandsON_outreach.ipynb DELETED
The diff for this file is too large to render. See raw diff
 
notebooks/Insight_notebook.ipynb DELETED
The diff for this file is too large to render. See raw diff
 
notebooks/PLOTS.ipynb DELETED
@@ -1,579 +0,0 @@
1
- {
2
- "cells": [
3
- {
4
- "cell_type": "code",
5
- "execution_count": 1,
6
- "id": "873187db-8223-4aa9-88ef-9ee3cc8fbfa4",
7
- "metadata": {
8
- "tags": []
9
- },
10
- "outputs": [],
11
- "source": [
12
- "import numpy as np\n",
13
- "import pandas as pd\n",
14
- "from astropy.io import fits\n",
15
- "import os\n",
16
- "from astropy.table import Table\n",
17
- "from scipy.spatial import KDTree\n",
18
- "\n",
19
- "import matplotlib.pyplot as plt\n",
20
- "\n",
21
- "from IPython.display import Image\n",
22
- "from IPython.core.display import HTML "
23
- ]
24
- },
25
- {
26
- "cell_type": "code",
27
- "execution_count": 2,
28
- "id": "0cd7baac-bec6-4619-bf86-b03baf28ea8c",
29
- "metadata": {},
30
- "outputs": [
31
- {
32
- "name": "stderr",
33
- "output_type": "stream",
34
- "text": [
35
- "/data/astro/scratch/lcabayol/anaconda3/envs/DESIenv6/lib/python3.10/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n",
36
- " from .autonotebook import tqdm as notebook_tqdm\n"
37
- ]
38
- }
39
- ],
40
- "source": [
41
- "import torch\n",
42
- "from torch.utils.data import DataLoader, dataset, TensorDataset\n",
43
- "from torch import nn, optim\n",
44
- "from torch.optim import lr_scheduler"
45
- ]
46
- },
47
- {
48
- "cell_type": "code",
49
- "execution_count": 3,
50
- "id": "8a694b63-85ec-49b9-9836-c5b579d94281",
51
- "metadata": {},
52
- "outputs": [],
53
- "source": [
54
- "import sys\n",
55
- "sys.path.append('../insight')\n",
56
- "from archive import archive \n",
57
- "from insight_arch import Photoz_network\n",
58
- "from insight import Insight_module\n",
59
- "from utils import sigma68, nmad, plot_photoz\n",
60
- "from scipy import stats"
61
- ]
62
- },
63
- {
64
- "cell_type": "code",
65
- "execution_count": 4,
66
- "id": "6f50d39b-eac8-4f49-a4b7-7579c9984a61",
67
- "metadata": {},
68
- "outputs": [],
69
- "source": [
70
- "from matplotlib import rcParams\n",
71
- "rcParams[\"mathtext.fontset\"] = \"stix\"\n",
72
- "rcParams[\"font.family\"] = \"STIXGeneral\"\n",
73
- "parent_dir = '/data/astro/scratch/lcabayol/Euclid/NNphotozs/Euclid_EXT_MER_PHZ_DC2_v1.5'"
74
- ]
75
- },
76
- {
77
- "cell_type": "code",
78
- "execution_count": 6,
79
- "id": "661b9a50-684f-4e7d-9293-a73ec5edb98f",
80
- "metadata": {},
81
- "outputs": [],
82
- "source": [
83
- "photoz_archive = archive(path = parent_dir, Qz_cut=1)\n",
84
- "f, ferr, specz, specqz = photoz_archive.get_training_data()"
85
- ]
86
- },
87
- {
88
- "cell_type": "code",
89
- "execution_count": 100,
90
- "id": "eff8e565-4e6e-41a0-ad54-4035bea6b14b",
91
- "metadata": {},
92
- "outputs": [],
93
- "source": [
94
- "f_test, ferr_test, specz_test = photoz_archive.get_testing_data()"
95
- ]
96
- },
97
- {
98
- "cell_type": "code",
99
- "execution_count": null,
100
- "id": "667e4edc-1a58-438d-b1ef-e01ad199e79f",
101
- "metadata": {},
102
- "outputs": [],
103
- "source": []
104
- },
105
- {
106
- "cell_type": "code",
107
- "execution_count": 74,
108
- "id": "ace74805-afb6-4d05-826a-901c0e115b8d",
109
- "metadata": {
110
- "tags": []
111
- },
112
- "outputs": [],
113
- "source": [
114
- "df_test = pd.read_csv('/data/astro/scratch/lcabayol/Euclid/NNphotozs/results/df1.csv', sep=',', header = 0, comment='#')"
115
- ]
116
- },
117
- {
118
- "cell_type": "code",
119
- "execution_count": 76,
120
- "id": "854d72a7-e748-4e79-8f18-0c80b2a58ed8",
121
- "metadata": {
122
- "tags": []
123
- },
124
- "outputs": [
125
- {
126
- "data": {
127
- "text/html": [
128
- "<div>\n",
129
- "<style scoped>\n",
130
- " .dataframe tbody tr th:only-of-type {\n",
131
- " vertical-align: middle;\n",
132
- " }\n",
133
- "\n",
134
- " .dataframe tbody tr th {\n",
135
- " vertical-align: top;\n",
136
- " }\n",
137
- "\n",
138
- " .dataframe thead th {\n",
139
- " text-align: right;\n",
140
- " }\n",
141
- "</style>\n",
142
- "<table border=\"1\" class=\"dataframe\">\n",
143
- " <thead>\n",
144
- " <tr style=\"text-align: right;\">\n",
145
- " <th></th>\n",
146
- " <th>VISmag</th>\n",
147
- " <th>zs</th>\n",
148
- " <th>z</th>\n",
149
- " <th>zuncert</th>\n",
150
- " <th>zwerr</th>\n",
151
- " </tr>\n",
152
- " </thead>\n",
153
- " <tbody>\n",
154
- " <tr>\n",
155
- " <th>0</th>\n",
156
- " <td>23.103798</td>\n",
157
- " <td>1.103000</td>\n",
158
- " <td>1.077487</td>\n",
159
- " <td>0.147231</td>\n",
160
- " <td>-0.012132</td>\n",
161
- " </tr>\n",
162
- " <tr>\n",
163
- " <th>1</th>\n",
164
- " <td>22.471019</td>\n",
165
- " <td>0.468800</td>\n",
166
- " <td>0.416247</td>\n",
167
- " <td>0.177303</td>\n",
168
- " <td>-0.035780</td>\n",
169
- " </tr>\n",
170
- " <tr>\n",
171
- " <th>2</th>\n",
172
- " <td>21.853940</td>\n",
173
- " <td>0.694600</td>\n",
174
- " <td>0.639316</td>\n",
175
- " <td>0.124684</td>\n",
176
- " <td>-0.032623</td>\n",
177
- " </tr>\n",
178
- " <tr>\n",
179
- " <th>3</th>\n",
180
- " <td>22.005561</td>\n",
181
- " <td>0.649200</td>\n",
182
- " <td>0.628935</td>\n",
183
- " <td>0.128350</td>\n",
184
- " <td>-0.012288</td>\n",
185
- " </tr>\n",
186
- " <tr>\n",
187
- " <th>4</th>\n",
188
- " <td>22.204387</td>\n",
189
- " <td>0.666900</td>\n",
190
- " <td>0.611376</td>\n",
191
- " <td>0.104980</td>\n",
192
- " <td>-0.033309</td>\n",
193
- " </tr>\n",
194
- " <tr>\n",
195
- " <th>...</th>\n",
196
- " <td>...</td>\n",
197
- " <td>...</td>\n",
198
- " <td>...</td>\n",
199
- " <td>...</td>\n",
200
- " <td>...</td>\n",
201
- " </tr>\n",
202
- " <tr>\n",
203
- " <th>12048</th>\n",
204
- " <td>22.449399</td>\n",
205
- " <td>0.690462</td>\n",
206
- " <td>0.722806</td>\n",
207
- " <td>0.123866</td>\n",
208
- " <td>0.019133</td>\n",
209
- " </tr>\n",
210
- " <tr>\n",
211
- " <th>12049</th>\n",
212
- " <td>22.102501</td>\n",
213
- " <td>0.915746</td>\n",
214
- " <td>0.956847</td>\n",
215
- " <td>0.117305</td>\n",
216
- " <td>0.021454</td>\n",
217
- " </tr>\n",
218
- " <tr>\n",
219
- " <th>12050</th>\n",
220
- " <td>22.982543</td>\n",
221
- " <td>0.721060</td>\n",
222
- " <td>0.745688</td>\n",
223
- " <td>0.180621</td>\n",
224
- " <td>0.014309</td>\n",
225
- " </tr>\n",
226
- " <tr>\n",
227
- " <th>12051</th>\n",
228
- " <td>20.037661</td>\n",
229
- " <td>0.345100</td>\n",
230
- " <td>0.358207</td>\n",
231
- " <td>0.070814</td>\n",
232
- " <td>0.009744</td>\n",
233
- " </tr>\n",
234
- " <tr>\n",
235
- " <th>12052</th>\n",
236
- " <td>22.764413</td>\n",
237
- " <td>0.487737</td>\n",
238
- " <td>0.363416</td>\n",
239
- " <td>0.228689</td>\n",
240
- " <td>-0.083564</td>\n",
241
- " </tr>\n",
242
- " </tbody>\n",
243
- "</table>\n",
244
- "<p>12053 rows × 5 columns</p>\n",
245
- "</div>"
246
- ],
247
- "text/plain": [
248
- " VISmag zs z zuncert zwerr\n",
249
- "0 23.103798 1.103000 1.077487 0.147231 -0.012132\n",
250
- "1 22.471019 0.468800 0.416247 0.177303 -0.035780\n",
251
- "2 21.853940 0.694600 0.639316 0.124684 -0.032623\n",
252
- "3 22.005561 0.649200 0.628935 0.128350 -0.012288\n",
253
- "4 22.204387 0.666900 0.611376 0.104980 -0.033309\n",
254
- "... ... ... ... ... ...\n",
255
- "12048 22.449399 0.690462 0.722806 0.123866 0.019133\n",
256
- "12049 22.102501 0.915746 0.956847 0.117305 0.021454\n",
257
- "12050 22.982543 0.721060 0.745688 0.180621 0.014309\n",
258
- "12051 20.037661 0.345100 0.358207 0.070814 0.009744\n",
259
- "12052 22.764413 0.487737 0.363416 0.228689 -0.083564\n",
260
- "\n",
261
- "[12053 rows x 5 columns]"
262
- ]
263
- },
264
- "execution_count": 76,
265
- "metadata": {},
266
- "output_type": "execute_result"
267
- }
268
- ],
269
- "source": [
270
- "df_test"
271
- ]
272
- },
273
- {
274
- "cell_type": "code",
275
- "execution_count": null,
276
- "id": "d72d3057-b2d6-42ee-8729-0ea6f18c0028",
277
- "metadata": {
278
- "tags": []
279
- },
280
- "outputs": [],
281
- "source": []
282
- },
283
- {
284
- "cell_type": "code",
285
- "execution_count": 77,
286
- "id": "78f955d8-8165-4642-99b2-f8d3d4a0cf1a",
287
- "metadata": {
288
- "tags": []
289
- },
290
- "outputs": [],
291
- "source": [
292
- "def plot_nz(df, bins=np.arange(0,5,0.2)):\n",
293
- " kwargs=dict( bins=bins,alpha=0.5)\n",
294
- " plt.hist(df.zs.values, color='grey', ls='-' ,**kwargs)\n",
295
- " counts, _, =np.histogram(df.z.values, bins=bins)\n",
296
- " \n",
297
- " plt.plot((bins[:-1]+bins[1:])*0.5,counts, color ='purple')\n",
298
- " \n",
299
- " #plt.legend(fontsize=14)\n",
300
- " plt.xlabel(r'Redshift', fontsize=14)\n",
301
- " plt.ylabel(r'Counts', fontsize=14)\n",
302
- " plt.yscale('log')\n",
303
- " \n",
304
- " plt.show()\n",
305
- " "
306
- ]
307
- },
308
- {
309
- "cell_type": "code",
310
- "execution_count": 58,
311
- "id": "fa8a38f9-d741-489b-aaaa-997f0671a1cc",
312
- "metadata": {
313
- "tags": []
314
- },
315
- "outputs": [
316
- {
317
- "data": {
318
- "image/png": "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6lhETldaWor77rsPH330ESZMmID58+djypQpPTqGIPb0fiwiIiIiD8DLVUREROSVWHKIiIjIK7HkEBERkVdiySEiIiKvxJJDREREXoklh4iIiLwSSw4ReTSz2YwffvgBy5cv79H7DAaDixIRkbtgySEil1i/fj3mzp0LQRAgCALS09MxefJkDBw4EKNHj8aTTz6JxsbGXp1Dp9Ph6aefxowZM7q1cZ/RaMSLL76IqVOnXnBTy7a2NgwaNAh//vOfz3quvr4e999/PxYvXozIyEhcc801aGtrc/jnICLXYMkhIpeYOXOmfRVqANizZw927tyJo0eP4t5778Wzzz6L0aNH96roaLVaPPPMM93eBFetVuOOO+7AwYMHYbVaz/taURTP+Zrbb78dcXFxePHFF/Hpp5/CZDLBZDKhpaUFFRUVPf45iMg1WHKIyGW0Wq39nzs27pTJZPjLX/6C6667DoWFhXj33Xd7fR65XN7t14aEhCAkJOSCr/P398fJkyfxwQcfdHq8vLwca9euRUREBABg2rRpWL9+PTQaDRYuXIhjx471KDsRuQ5LDhFJ4qKLLgIAFBcXSxukh06dOoWudsN5+eWXnVLYiMh5WHKISBI5OTkAgBEjRnR6/PXXX8fs2bMxefJkXHzxxfj00087Pd/a2or7778f8+bNwwMPPIDHH38cJpOp02saGxtxzz334JVXXsG9994Lf39/rF279qwMu3btwvjx4xEQEIBx48bhyJEj9uesViu2bNmCp556yv7Yww8/jKeffhoAsGLFCtxyyy1YsmQJ9u3bZz/+kiVLcMstt+DkyZOOfjRE5CwiEZELARDP/KPm+PHj4oIFC0QA4pw5c0SLxWJ/7tFHHxXnzZsn2mw2URRFMTMzU5TJZOKPP/4oiqIo2mw28Xe/+534xBNP2N+TnZ0tAhAvvfRS+2P33XefuHTpUvv3b7/9trhmzRr794mJieLAgQPF++67TywuLhZ37twpBgYGildccYUoiqJYU1MjPvvss6Kfn5+YmJjY6efZsmWLCEBcuXJlp8dXrlwpAhC3bNniyMdERC7AkRwi6hNXX3014uPjMXDgQFgsFvz000/47LPP7PNpysrK8Pzzz+Phhx+GIAgAgJtvvhk2mw1vv/02AOCDDz7Azp078cADD9iPO2HCBMTGxnY618mTJ7Fp0yZYLBYAwLx58xAfH9/pNSEhIXjllVeQmJiISZMmYfr06di9ezcAICIiAo8++ihGjRrlmg+DiPqEQuoAROQbvvrqK7z22mu47777kJ+fj7Fjx3Z6fuPGjbBYLFiyZIm95FgsFgwfPhxKpRIA8PHHH+Oiiy5CYGBgp/d2PN/hxhtvxE033YRJkybhjTfewLhx4zB69OhOrwkICOj0fVhYGBoaGs57XCLyLCw5RNRnFi5ciK1bt2Lt2rV44IEHsHTpUvtzVVVVAIDly5dDrVZ3+f4TJ04gODj4gue58cYb0djYiH/84x+YMGEC7rrrLrz00ktnlSMi8m68XEVEfeq9995DYmIiXnnlFXzxxRf2x6OjowEABQUFZ73HaDTCaDRCq9We8+6mM5lMJtx99904fPgw5s6di7feeqvLRf2IyLux5BCRy3RVRkJDQ/HJJ59AqVTitttuw/HjxwEAY8aMAQA89thjMJvN9tdbLBY89NBDsNlsGDVqFGpqavDdd9+ddZ4zz/XSSy8BAJKTk/Hxxx9jwYIF2Lx5s9N/vjN1zC06MzsRSYslh4hcpra21v7PZ853GT9+PJ577jno9XrMmTMHLS0tSE9Pxx//+Ed88803mDx5Ml5++WUsW7YMl1xyCaZMmQJ/f3889NBD8Pf3x4IFC7Bt2zbU19fj7bffRl1dHfLz8/Hxxx+jra0NP/zwAw4cOGA/X0JCAiZNmmT/3mg0nrV3VWtrKwB02p7BYDCctV1DS0sLAKC5ubnT4x0Tmzdu3IhTp05hw4YNDn1mRORE0t7cRUTeav369eLMmTPtt5DPnj27023cNptNvPrqq0UA4ujRo8X3339fbGpqEhcsWCBGRESIQUFB4qRJk8T169d3Ou727dvF8ePHiyqVSkxOThZXr14tXnXVVeIDDzwg7t+/XxRFUbz00kvF8PBw8aGHHhKfeuop8eabbxYrKyvF1tZW8d///rcIQFQqleLSpUtFo9EorlixQgwNDRUBiPfcc49YXFwsvv7666JKpRIBiP/617/EyspK8auvvhJnzJghAhCHDBkirlq1SmxsbBRFURQtFos4c+ZMMSAgQLz++utFvV7fZ581EXVNEMULXNwmIiIi8kC8XEVEREReiSWHiIiIvBJLDhEREXkllhwiIiLySiw5RERE5JVYcoiIiMgrseQQERGRV2LJISIiIq/EkkNEREReiSWHiIiIvBJLDhEREXkllhwiIiLySiw5RERE5JX+PwI4nHpXCItKAAAAAElFTkSuQmCC",
319
- "text/plain": [
320
- "<Figure size 640x480 with 1 Axes>"
321
- ]
322
- },
323
- "metadata": {},
324
- "output_type": "display_data"
325
- }
326
- ],
327
- "source": [
328
- "plot_nz(df_test)"
329
- ]
330
- },
331
- {
332
- "cell_type": "code",
333
- "execution_count": 68,
334
- "id": "b8f71544-5a64-4d52-8f50-af5f7fa9929e",
335
- "metadata": {
336
- "tags": []
337
- },
338
- "outputs": [],
339
- "source": [
340
- "def plot_photoz(df, nbins,xvariable,metric, type_bin='bin'):\n",
341
- " bin_edges = stats.mstats.mquantiles(df[xvariable].values, np.linspace(0.1,1,nbins))\n",
342
- " ydata,xdata = [],[]\n",
343
- " \n",
344
- " \n",
345
- " for k in range(len(bin_edges)-1):\n",
346
- " edge_min = bin_edges[k]\n",
347
- " edge_max = bin_edges[k+1]\n",
348
- "\n",
349
- " mean_mag = (edge_max + edge_min) / 2\n",
350
- " \n",
351
- " if type_bin=='bin':\n",
352
- " df_plot = df[(df[xvariable] > edge_min) & (df[xvariable] < edge_max)]\n",
353
- " elif type_bin=='cum':\n",
354
- " df_plot = df[(df[xvariable] < edge_max)]\n",
355
- " else:\n",
356
- " raise ValueError(\"Only type_bin=='bin' for binned and 'cum' for cumulative are supported\")\n",
357
- "\n",
358
- "\n",
359
- " xdata.append(mean_mag)\n",
360
- " if metric=='sig68':\n",
361
- " ydata.append(sigma68(df_plot.zwerr))\n",
362
- " ylab=r'$\\sigma_{\\rm NMAD} [\\Delta z]$'\n",
363
- " elif metric=='bias':\n",
364
- " ydata.append(np.median(df_plot.zwerr))\n",
365
- " ylab=r'Median $[\\Delta z]$'\n",
366
- " elif metric=='nmad':\n",
367
- " ydata.append(nmad(df_plot.zwerr))\n",
368
- " ylab=r'$\\sigma_{\\rm NMAD} [\\Delta z]$'\n",
369
- " elif metric=='outliers':\n",
370
- " ydata.append(len(df_plot[np.abs(df_plot.zwerr)>0.15])/len(df_plot) *100)\n",
371
- " ylab=r'$\\eta$ [%]'\n",
372
- " \n",
373
- " if xvariable=='VISmag':\n",
374
- " xlab='VIS'\n",
375
- " elif xvariable=='zs':\n",
376
- " xlab=r'$z_{\\rm spec}$'\n",
377
- " elif xvariable=='z':\n",
378
- " xlab=r'$z$'\n",
379
- "\n",
380
- " plt.plot(xdata,ydata, ls = '-', marker = '.', color = 'navy',lw = 1, label = '')\n",
381
- " plt.ylabel(f'{ylab}', fontsize = 18)\n",
382
- " plt.xlabel(f'{xlab}', fontsize = 16)\n",
383
- "\n",
384
- " plt.xticks(fontsize = 14)\n",
385
- " plt.yticks(fontsize = 14)\n",
386
- "\n",
387
- " plt.grid(False)\n",
388
- " \n",
389
- " plt.show()\n",
390
- " "
391
- ]
392
- },
393
- {
394
- "cell_type": "code",
395
- "execution_count": 71,
396
- "id": "be87adb7-eb06-433a-8b2c-2cb0c1bb3ae3",
397
- "metadata": {},
398
- "outputs": [
399
- {
400
- "data": {
401
- "image/png": "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PpVVcjJvcxIRET0NAxrViY4drWFsLOFtTiIiohpgQKM6YWZmAnd3awY0IiKiGmBAozrj5dWGAY2IiKgGGNCozlS8yfnkBOpERESkigGN6oynpw3u3XuIq1fzxS6FiIhIrzGgUZ3x8moDALzNSURE9BQMaFRn2rZtBiurxgxoRERET8GARnVGIpHA09MGiYkMaERERNVhQKM6VT4nJwMaERFRdRjQqE55edkgLe0O7t9/KHYpREREeosBjeqUp6cNBAE4f/6W2KUQERHpLQY0qlMeHq1gZCRBYuI/YpdCRESktxjQqE41bmyKDh2s+BwaERFRNRjQqM55edkgKemm2GUQERHpLQY0qnMVb3IKAqd8IiIiqgwDGtU5T08b5Oc/QHZ2gdilEBER6SUGNKpznp42ADjlExERUVUY0KjO2dtboHnzRgxoREREVWBAozrHKZ+IiIiqx4BGovD0bM0raERERFVgQCNReHra4PLlPBQXl4hdChERkd5hQCNReHm1gUIhICWFUz4RERE9iQGNRNGpUytIJOBzaERERJVgQCNRNG0qhatrSz6HRkREVAkGNBJNxYwCREREpIoBjURTPicnp3wiIiJ6EgMaicbT0wZ5ecW4fv2e2KUQERHpFQY0Eg2nfCIiIqocAxqJxtGxOczNpQxoRERET2BAI9EYGUn+/0WBm2KXQkREpFcY0EhU5XNy/iN2GURERHqFAU1PnDlzRuwSROHpaYOLF29DLi8VuxQiIiK9YaJJp6ysLG3XARMTE9ja2mp9uxXkcjkWL16M3NxcWFhYICUlBfPnz4ePj89T+6ampiIsLAzt27dHbm4upFIpvv76a5ibm6us9+eff2LdunXo0KEDUlJS0KNHD3z44YeQSCQq661btw5vvPGGStv06dOxbt26Zz/QesbT0wZlZQIuXLiNLl3aiF0OERGRXtAooLVv314tdDyr9u3b48qVK1rdZgWFQoFXX30VpaWlOHDgAADgxIkTCAgIQGxsLLp27Vpl37S0NHTv3h0REREYPXo0ACAkJARBQUGIioqCiUn5Kdy1axemTJmC8+fPw9HREXK5HN26dcOtW7cQHh6uUsuaNWvw4YcfKtuMjIwQGhqqi0PXe507twZQ/iYnAxoREVE5iaDBKKFGRkaws7ODi4uLVoq4evUqACA9PV0r23vSjh07MHbsWERFRcHf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",
402
- "text/plain": [
403
- "<Figure size 640x480 with 1 Axes>"
404
- ]
405
- },
406
- "metadata": {},
407
- "output_type": "display_data"
408
- }
409
- ],
410
- "source": [
411
- "plot_photoz(df_test, 8,'z','bias', type_bin='bin')"
412
- ]
413
- },
414
- {
415
- "cell_type": "code",
416
- "execution_count": 109,
417
- "id": "d67d2991-0c55-4ec8-9c5c-8c5cc20364b1",
418
- "metadata": {},
419
- "outputs": [
420
- {
421
- "data": {
422
- "text/plain": [
423
- "0.04460718134171633"
424
- ]
425
- },
426
- "execution_count": 109,
427
- "metadata": {},
428
- "output_type": "execute_result"
429
- }
430
- ],
431
- "source": [
432
- "nmad(df_test[df_test.VISmag<25].zwerr)"
433
- ]
434
- },
435
- {
436
- "cell_type": "code",
437
- "execution_count": 110,
438
- "id": "a7c59672-ff90-473b-8539-e28d9eaec4b7",
439
- "metadata": {
440
- "tags": []
441
- },
442
- "outputs": [],
443
- "source": [
444
- "df_test = df_test[df_test.VISmag<25]"
445
- ]
446
- },
447
- {
448
- "cell_type": "code",
449
- "execution_count": 111,
450
- "id": "81e8b270-0da6-41af-b43d-1912fa98ccaa",
451
- "metadata": {
452
- "tags": []
453
- },
454
- "outputs": [
455
- {
456
- "data": {
457
- "text/plain": [
458
- "0.13433240659117107"
459
- ]
460
- },
461
- "execution_count": 111,
462
- "metadata": {},
463
- "output_type": "execute_result"
464
- }
465
- ],
466
- "source": [
467
- "len(df_test[np.abs(df_test.zwerr)>0.15])/len(df_test)"
468
- ]
469
- },
470
- {
471
- "cell_type": "code",
472
- "execution_count": 112,
473
- "id": "5c58a724-ecd8-48ed-89da-0e7eb9a5ca99",
474
- "metadata": {
475
- "tags": []
476
- },
477
- "outputs": [],
478
- "source": [
479
- "torch.save(insight.model.state_dict(),'/data/astro/scratch/lcabayol/Euclid/NNphotozs/models/insight_v0.pt')\n",
480
- " \n",
481
- " "
482
- ]
483
- },
484
- {
485
- "cell_type": "code",
486
- "execution_count": 113,
487
- "id": "c966fd40-3d3f-4df5-a988-c55a1ab2e204",
488
- "metadata": {},
489
- "outputs": [],
490
- "source": [
491
- "df_test.to_csv('/data/astro/scratch/lcabayol/Euclid/NNphotozs/results/df0.csv', sep=',')"
492
- ]
493
- },
494
- {
495
- "cell_type": "code",
496
- "execution_count": 114,
497
- "id": "f8487c14-3b26-4742-a5c0-e6a820400cc9",
498
- "metadata": {},
499
- "outputs": [
500
- {
501
- "name": "stderr",
502
- "output_type": "stream",
503
- "text": [
504
- "/tmp/ipykernel_678/2146862925.py:13: FutureWarning: the 'line_terminator'' keyword is deprecated, use 'lineterminator' instead.\n",
505
- " df_test.to_csv(f, header=True, index=False, line_terminator='\\n')\n"
506
- ]
507
- }
508
- ],
509
- "source": [
510
- "# Create a list of additional header lines\n",
511
- "header_lines = [\n",
512
- " \"# Training spect-zs with a strict quality cut\",\n",
513
- " \"#10 MDN components\",\n",
514
- " \"# For 300 epochs with lr0=1e-3 + 100 epochs with lr=1e-4\",\n",
515
- " \"# Date: 2023-07-26\",\n",
516
- "]\n",
517
- "\n",
518
- "# Write DataFrame to a CSV file with custom header lines\n",
519
- "with open('/data/astro/scratch/lcabayol/Euclid/NNphotozs/results/df0.csv', 'w') as f:\n",
520
- " for line in header_lines:\n",
521
- " f.write(line + '\\n')\n",
522
- " df_test.to_csv(f, header=True, index=False, line_terminator='\\n')\n"
523
- ]
524
- },
525
- {
526
- "cell_type": "code",
527
- "execution_count": null,
528
- "id": "e20b30c3-00a8-4dd0-969d-0426121b99f5",
529
- "metadata": {},
530
- "outputs": [],
531
- "source": []
532
- },
533
- {
534
- "cell_type": "code",
535
- "execution_count": null,
536
- "id": "f9c0ad7d-7796-41b5-8b91-7c8dec41f17b",
537
- "metadata": {},
538
- "outputs": [],
539
- "source": []
540
- },
541
- {
542
- "cell_type": "code",
543
- "execution_count": null,
544
- "id": "60b50881-860c-48c1-80c3-f8a9ab51226f",
545
- "metadata": {},
546
- "outputs": [],
547
- "source": []
548
- },
549
- {
550
- "cell_type": "code",
551
- "execution_count": null,
552
- "id": "c174cd6f-340e-4986-a04d-6318ce11e067",
553
- "metadata": {},
554
- "outputs": [],
555
- "source": []
556
- }
557
- ],
558
- "metadata": {
559
- "kernelspec": {
560
- "display_name": "DESIenv6",
561
- "language": "python",
562
- "name": "desienv6"
563
- },
564
- "language_info": {
565
- "codemirror_mode": {
566
- "name": "ipython",
567
- "version": 3
568
- },
569
- "file_extension": ".py",
570
- "mimetype": "text/x-python",
571
- "name": "python",
572
- "nbconvert_exporter": "python",
573
- "pygments_lexer": "ipython3",
574
- "version": "3.10.9"
575
- }
576
- },
577
- "nbformat": 4,
578
- "nbformat_minor": 5
579
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
notebooks/backup_notebook.ipynb DELETED
The diff for this file is too large to render. See raw diff
 
notebooks/insight_notebook.ipynb DELETED
The diff for this file is too large to render. See raw diff
 
notebooks/match_catalogues.ipynb DELETED
@@ -1,1193 +0,0 @@
1
- {
2
- "cells": [
3
- {
4
- "cell_type": "code",
5
- "execution_count": 1,
6
- "id": "0bd364f7-e6cf-4bd5-906e-2a096ad22ec1",
7
- "metadata": {
8
- "tags": []
9
- },
10
- "outputs": [],
11
- "source": [
12
- "import pandas as pd\n",
13
- "from astropy.io import fits\n",
14
- "from astropy.table import Table\n",
15
- "import numpy as np\n",
16
- "\n",
17
- "import os"
18
- ]
19
- },
20
- {
21
- "cell_type": "code",
22
- "execution_count": 3,
23
- "id": "cd8362c5-87b5-4b69-bb4b-608d605c2028",
24
- "metadata": {
25
- "tags": []
26
- },
27
- "outputs": [],
28
- "source": [
29
- "path = '/data/astro/scratch2/lcabayol/insight/data/Euclid_EXT_MER_PHZ_DC2_v1.5'\n",
30
- "filename_calib='euclid_cosmos_DC2_S1_v2.1_calib_clean.fits'\n",
31
- "filename_valid='euclid_cosmos_DC2_S1_v2.1_valid.fits'"
32
- ]
33
- },
34
- {
35
- "cell_type": "code",
36
- "execution_count": 4,
37
- "id": "db81717b-09c9-473e-b7c3-488ad3f63b90",
38
- "metadata": {
39
- "tags": []
40
- },
41
- "outputs": [],
42
- "source": [
43
- "hdu_list = fits.open(os.path.join(path,filename_calib))\n",
44
- "cat_calib = Table(hdu_list[1].data).to_pandas()\n",
45
- "\n",
46
- "hdu_list = fits.open(os.path.join(path,filename_valid))\n",
47
- "cat_valid = Table(hdu_list[1].data).to_pandas()"
48
- ]
49
- },
50
- {
51
- "cell_type": "code",
52
- "execution_count": 5,
53
- "id": "066de14f-db52-4419-93e3-4645901bb216",
54
- "metadata": {
55
- "tags": []
56
- },
57
- "outputs": [],
58
- "source": [
59
- "hdu_list = fits.open('/data/astro/scratch2/lcabayol/insight/data/Euclid_EXT_MER_PHZ_DC2_v1.5/euclid_cosmos_DC2_S2_v2.1_full.fits')\n",
60
- "cat_all = Table(hdu_list[1].data).to_pandas()\n",
61
- "\n",
62
- "\n"
63
- ]
64
- },
65
- {
66
- "cell_type": "code",
67
- "execution_count": 6,
68
- "id": "77924201-557e-4174-b040-2e2c6e309fc7",
69
- "metadata": {
70
- "tags": []
71
- },
72
- "outputs": [
73
- {
74
- "data": {
75
- "text/html": [
76
- "<div>\n",
77
- "<style scoped>\n",
78
- " .dataframe tbody tr th:only-of-type {\n",
79
- " vertical-align: middle;\n",
80
- " }\n",
81
- "\n",
82
- " .dataframe tbody tr th {\n",
83
- " vertical-align: top;\n",
84
- " }\n",
85
- "\n",
86
- " .dataframe thead th {\n",
87
- " text-align: right;\n",
88
- " }\n",
89
- "</style>\n",
90
- "<table border=\"1\" class=\"dataframe\">\n",
91
- " <thead>\n",
92
- " <tr style=\"text-align: right;\">\n",
93
- " <th></th>\n",
94
- " <th>ID</th>\n",
95
- " <th>RA</th>\n",
96
- " <th>DEC</th>\n",
97
- " <th>FLUX_G_1</th>\n",
98
- " <th>FLUX_G_2</th>\n",
99
- " <th>FLUX_G_3</th>\n",
100
- " <th>FLUX_R_1</th>\n",
101
- " <th>FLUX_R_2</th>\n",
102
- " <th>FLUX_R_3</th>\n",
103
- " <th>FLUX_I_1</th>\n",
104
- " <th>...</th>\n",
105
- " <th>mu_class_L07</th>\n",
106
- " <th>photo_z_L15</th>\n",
107
- " <th>z_spec_S15</th>\n",
108
- " <th>Q_f_S15</th>\n",
109
- " <th>Instr_S15</th>\n",
110
- " <th>reliable_S15</th>\n",
111
- " <th>flag_X_ray_s15</th>\n",
112
- " <th>flag_IRAC_s15</th>\n",
113
- " <th>STAR</th>\n",
114
- " <th>AGN</th>\n",
115
- " </tr>\n",
116
- " </thead>\n",
117
- " <tbody>\n",
118
- " <tr>\n",
119
- " <th>391281</th>\n",
120
- " <td>391282</td>\n",
121
- " <td>149.553146</td>\n",
122
- " <td>2.735168</td>\n",
123
- " <td>3.187</td>\n",
124
- " <td>3.208</td>\n",
125
- " <td>3.167</td>\n",
126
- " <td>8.187</td>\n",
127
- " <td>8.348</td>\n",
128
- " <td>8.272</td>\n",
129
- " <td>12.89</td>\n",
130
- " <td>...</td>\n",
131
- " <td>-99</td>\n",
132
- " <td>0.322</td>\n",
133
- " <td>0.299501</td>\n",
134
- " <td>2.0</td>\n",
135
- " <td>PRIMUS</td>\n",
136
- " <td>-99</td>\n",
137
- " <td>0</td>\n",
138
- " <td>0</td>\n",
139
- " <td>0</td>\n",
140
- " <td>0</td>\n",
141
- " </tr>\n",
142
- " </tbody>\n",
143
- "</table>\n",
144
- "<p>1 rows × 123 columns</p>\n",
145
- "</div>"
146
- ],
147
- "text/plain": [
148
- " ID RA DEC FLUX_G_1 FLUX_G_2 FLUX_G_3 FLUX_R_1 \\\n",
149
- "391281 391282 149.553146 2.735168 3.187 3.208 3.167 8.187 \n",
150
- "\n",
151
- " FLUX_R_2 FLUX_R_3 FLUX_I_1 ... mu_class_L07 photo_z_L15 \\\n",
152
- "391281 8.348 8.272 12.89 ... -99 0.322 \n",
153
- "\n",
154
- " z_spec_S15 Q_f_S15 Instr_S15 reliable_S15 flag_X_ray_s15 \\\n",
155
- "391281 0.299501 2.0 PRIMUS -99 0 \n",
156
- "\n",
157
- " flag_IRAC_s15 STAR AGN \n",
158
- "391281 0 0 0 \n",
159
- "\n",
160
- "[1 rows x 123 columns]"
161
- ]
162
- },
163
- "execution_count": 6,
164
- "metadata": {},
165
- "output_type": "execute_result"
166
- }
167
- ],
168
- "source": [
169
- "cat_all[(cat_all.RA==149.553146)&(cat_all.DEC==2.735168)]"
170
- ]
171
- },
172
- {
173
- "cell_type": "code",
174
- "execution_count": 7,
175
- "id": "34596af4-352c-4e7b-bce9-0724a67c5edb",
176
- "metadata": {
177
- "tags": []
178
- },
179
- "outputs": [],
180
- "source": [
181
- "df_ra_dec = cat_all[['RA', 'DEC']].values\n",
182
- "ra_dec_pairs = cat_valid[['RA', 'DEC']].values"
183
- ]
184
- },
185
- {
186
- "cell_type": "code",
187
- "execution_count": 8,
188
- "id": "b7c1f725-b0b3-4480-ab69-7b811727b027",
189
- "metadata": {
190
- "tags": []
191
- },
192
- "outputs": [],
193
- "source": [
194
- "# Find the common rows using numpy's isin() function\n",
195
- "common_rows = np.isin(df_ra_dec, ra_dec_pairs).all(axis=1)"
196
- ]
197
- },
198
- {
199
- "cell_type": "code",
200
- "execution_count": 9,
201
- "id": "ce02f1f7-4cf8-49d1-81ef-0b1c90338e12",
202
- "metadata": {
203
- "tags": []
204
- },
205
- "outputs": [],
206
- "source": [
207
- "# Filter the dataframe based on matching RA, DEC pairs\n",
208
- "cat_valid_match = cat_all[common_rows]"
209
- ]
210
- },
211
- {
212
- "cell_type": "code",
213
- "execution_count": 10,
214
- "id": "4891c5be-d1f9-4dbc-84e2-c05638ce5182",
215
- "metadata": {
216
- "tags": []
217
- },
218
- "outputs": [
219
- {
220
- "data": {
221
- "text/html": [
222
- "<div>\n",
223
- "<style scoped>\n",
224
- " .dataframe tbody tr th:only-of-type {\n",
225
- " vertical-align: middle;\n",
226
- " }\n",
227
- "\n",
228
- " .dataframe tbody tr th {\n",
229
- " vertical-align: top;\n",
230
- " }\n",
231
- "\n",
232
- " .dataframe thead th {\n",
233
- " text-align: right;\n",
234
- " }\n",
235
- "</style>\n",
236
- "<table border=\"1\" class=\"dataframe\">\n",
237
- " <thead>\n",
238
- " <tr style=\"text-align: right;\">\n",
239
- " <th></th>\n",
240
- " <th>ID</th>\n",
241
- " <th>RA</th>\n",
242
- " <th>DEC</th>\n",
243
- " <th>FLUX_G_1</th>\n",
244
- " <th>FLUX_G_2</th>\n",
245
- " <th>FLUX_G_3</th>\n",
246
- " <th>FLUX_R_1</th>\n",
247
- " <th>FLUX_R_2</th>\n",
248
- " <th>FLUX_R_3</th>\n",
249
- " <th>FLUX_I_1</th>\n",
250
- " <th>...</th>\n",
251
- " <th>mu_class_L07</th>\n",
252
- " <th>photo_z_L15</th>\n",
253
- " <th>z_spec_S15</th>\n",
254
- " <th>Q_f_S15</th>\n",
255
- " <th>Instr_S15</th>\n",
256
- " <th>reliable_S15</th>\n",
257
- " <th>flag_X_ray_s15</th>\n",
258
- " <th>flag_IRAC_s15</th>\n",
259
- " <th>STAR</th>\n",
260
- " <th>AGN</th>\n",
261
- " </tr>\n",
262
- " </thead>\n",
263
- " <tbody>\n",
264
- " <tr>\n",
265
- " <th>368</th>\n",
266
- " <td>369</td>\n",
267
- " <td>149.862381</td>\n",
268
- " <td>1.624455</td>\n",
269
- " <td>0.4753</td>\n",
270
- " <td>0.4252</td>\n",
271
- " <td>0.4659</td>\n",
272
- " <td>1.507</td>\n",
273
- " <td>1.374</td>\n",
274
- " <td>1.2680</td>\n",
275
- " <td>3.983</td>\n",
276
- " <td>...</td>\n",
277
- " <td>1</td>\n",
278
- " <td>1.189000</td>\n",
279
- " <td>1.279900</td>\n",
280
- " <td>1.5</td>\n",
281
- " <td>zBRIGHT</td>\n",
282
- " <td>-99</td>\n",
283
- " <td>0</td>\n",
284
- " <td>0</td>\n",
285
- " <td>0</td>\n",
286
- " <td>0</td>\n",
287
- " </tr>\n",
288
- " <tr>\n",
289
- " <th>614</th>\n",
290
- " <td>615</td>\n",
291
- " <td>149.967209</td>\n",
292
- " <td>1.625431</td>\n",
293
- " <td>1.3970</td>\n",
294
- " <td>1.3210</td>\n",
295
- " <td>1.2990</td>\n",
296
- " <td>3.310</td>\n",
297
- " <td>3.165</td>\n",
298
- " <td>2.8200</td>\n",
299
- " <td>3.815</td>\n",
300
- " <td>...</td>\n",
301
- " <td>1</td>\n",
302
- " <td>0.499900</td>\n",
303
- " <td>0.498300</td>\n",
304
- " <td>2.5</td>\n",
305
- " <td>zBRIGHT</td>\n",
306
- " <td>-99</td>\n",
307
- " <td>0</td>\n",
308
- " <td>0</td>\n",
309
- " <td>0</td>\n",
310
- " <td>0</td>\n",
311
- " </tr>\n",
312
- " <tr>\n",
313
- " <th>863</th>\n",
314
- " <td>864</td>\n",
315
- " <td>150.029968</td>\n",
316
- " <td>1.625488</td>\n",
317
- " <td>1.8440</td>\n",
318
- " <td>1.5770</td>\n",
319
- " <td>1.5760</td>\n",
320
- " <td>3.141</td>\n",
321
- " <td>3.037</td>\n",
322
- " <td>2.9770</td>\n",
323
- " <td>6.058</td>\n",
324
- " <td>...</td>\n",
325
- " <td>1</td>\n",
326
- " <td>0.818700</td>\n",
327
- " <td>0.838300</td>\n",
328
- " <td>2.5</td>\n",
329
- " <td>zBRIGHT</td>\n",
330
- " <td>-99</td>\n",
331
- " <td>0</td>\n",
332
- " <td>0</td>\n",
333
- " <td>0</td>\n",
334
- " <td>0</td>\n",
335
- " </tr>\n",
336
- " <tr>\n",
337
- " <th>951</th>\n",
338
- " <td>952</td>\n",
339
- " <td>149.713226</td>\n",
340
- " <td>1.625920</td>\n",
341
- " <td>2.3280</td>\n",
342
- " <td>2.3360</td>\n",
343
- " <td>2.3340</td>\n",
344
- " <td>5.336</td>\n",
345
- " <td>5.136</td>\n",
346
- " <td>5.1460</td>\n",
347
- " <td>8.928</td>\n",
348
- " <td>...</td>\n",
349
- " <td>1</td>\n",
350
- " <td>0.611600</td>\n",
351
- " <td>0.615000</td>\n",
352
- " <td>1.5</td>\n",
353
- " <td>zBRIGHT</td>\n",
354
- " <td>-99</td>\n",
355
- " <td>0</td>\n",
356
- " <td>0</td>\n",
357
- " <td>0</td>\n",
358
- " <td>0</td>\n",
359
- " </tr>\n",
360
- " <tr>\n",
361
- " <th>1292</th>\n",
362
- " <td>1293</td>\n",
363
- " <td>149.530899</td>\n",
364
- " <td>1.626842</td>\n",
365
- " <td>1.0330</td>\n",
366
- " <td>0.8639</td>\n",
367
- " <td>0.8805</td>\n",
368
- " <td>1.963</td>\n",
369
- " <td>1.939</td>\n",
370
- " <td>1.9980</td>\n",
371
- " <td>3.388</td>\n",
372
- " <td>...</td>\n",
373
- " <td>1</td>\n",
374
- " <td>0.751600</td>\n",
375
- " <td>0.763700</td>\n",
376
- " <td>9.5</td>\n",
377
- " <td>zBRIGHT</td>\n",
378
- " <td>-99</td>\n",
379
- " <td>0</td>\n",
380
- " <td>0</td>\n",
381
- " <td>0</td>\n",
382
- " <td>0</td>\n",
383
- " </tr>\n",
384
- " <tr>\n",
385
- " <th>...</th>\n",
386
- " <td>...</td>\n",
387
- " <td>...</td>\n",
388
- " <td>...</td>\n",
389
- " <td>...</td>\n",
390
- " <td>...</td>\n",
391
- " <td>...</td>\n",
392
- " <td>...</td>\n",
393
- " <td>...</td>\n",
394
- " <td>...</td>\n",
395
- " <td>...</td>\n",
396
- " <td>...</td>\n",
397
- " <td>...</td>\n",
398
- " <td>...</td>\n",
399
- " <td>...</td>\n",
400
- " <td>...</td>\n",
401
- " <td>...</td>\n",
402
- " <td>...</td>\n",
403
- " <td>...</td>\n",
404
- " <td>...</td>\n",
405
- " <td>...</td>\n",
406
- " <td>...</td>\n",
407
- " </tr>\n",
408
- " <tr>\n",
409
- " <th>391055</th>\n",
410
- " <td>391056</td>\n",
411
- " <td>149.911942</td>\n",
412
- " <td>2.737337</td>\n",
413
- " <td>2.5840</td>\n",
414
- " <td>2.7920</td>\n",
415
- " <td>2.7740</td>\n",
416
- " <td>4.309</td>\n",
417
- " <td>4.247</td>\n",
418
- " <td>4.0800</td>\n",
419
- " <td>6.144</td>\n",
420
- " <td>...</td>\n",
421
- " <td>1</td>\n",
422
- " <td>0.207600</td>\n",
423
- " <td>9.999900</td>\n",
424
- " <td>0.0</td>\n",
425
- " <td>zBRIGHT</td>\n",
426
- " <td>-99</td>\n",
427
- " <td>0</td>\n",
428
- " <td>0</td>\n",
429
- " <td>0</td>\n",
430
- " <td>0</td>\n",
431
- " </tr>\n",
432
- " <tr>\n",
433
- " <th>391111</th>\n",
434
- " <td>391112</td>\n",
435
- " <td>149.960968</td>\n",
436
- " <td>2.735883</td>\n",
437
- " <td>1.1160</td>\n",
438
- " <td>1.0270</td>\n",
439
- " <td>1.0280</td>\n",
440
- " <td>4.790</td>\n",
441
- " <td>4.807</td>\n",
442
- " <td>4.8790</td>\n",
443
- " <td>14.450</td>\n",
444
- " <td>...</td>\n",
445
- " <td>1</td>\n",
446
- " <td>0.690500</td>\n",
447
- " <td>0.696300</td>\n",
448
- " <td>1.5</td>\n",
449
- " <td>zBRIGHT</td>\n",
450
- " <td>-99</td>\n",
451
- " <td>0</td>\n",
452
- " <td>0</td>\n",
453
- " <td>0</td>\n",
454
- " <td>0</td>\n",
455
- " </tr>\n",
456
- " <tr>\n",
457
- " <th>391133</th>\n",
458
- " <td>391134</td>\n",
459
- " <td>149.802002</td>\n",
460
- " <td>2.735837</td>\n",
461
- " <td>1.1510</td>\n",
462
- " <td>0.9859</td>\n",
463
- " <td>1.0060</td>\n",
464
- " <td>2.038</td>\n",
465
- " <td>2.059</td>\n",
466
- " <td>1.9160</td>\n",
467
- " <td>3.724</td>\n",
468
- " <td>...</td>\n",
469
- " <td>1</td>\n",
470
- " <td>-99.900002</td>\n",
471
- " <td>0.680074</td>\n",
472
- " <td>2.0</td>\n",
473
- " <td>PRIMUS</td>\n",
474
- " <td>-99</td>\n",
475
- " <td>0</td>\n",
476
- " <td>0</td>\n",
477
- " <td>0</td>\n",
478
- " <td>0</td>\n",
479
- " </tr>\n",
480
- " <tr>\n",
481
- " <th>391178</th>\n",
482
- " <td>391179</td>\n",
483
- " <td>149.902161</td>\n",
484
- " <td>2.735792</td>\n",
485
- " <td>0.6982</td>\n",
486
- " <td>0.6542</td>\n",
487
- " <td>0.5222</td>\n",
488
- " <td>1.162</td>\n",
489
- " <td>1.024</td>\n",
490
- " <td>0.7999</td>\n",
491
- " <td>3.115</td>\n",
492
- " <td>...</td>\n",
493
- " <td>1</td>\n",
494
- " <td>0.860600</td>\n",
495
- " <td>0.881794</td>\n",
496
- " <td>2.0</td>\n",
497
- " <td>PRIMUS</td>\n",
498
- " <td>-99</td>\n",
499
- " <td>0</td>\n",
500
- " <td>0</td>\n",
501
- " <td>0</td>\n",
502
- " <td>0</td>\n",
503
- " </tr>\n",
504
- " <tr>\n",
505
- " <th>391281</th>\n",
506
- " <td>391282</td>\n",
507
- " <td>149.553146</td>\n",
508
- " <td>2.735168</td>\n",
509
- " <td>3.1870</td>\n",
510
- " <td>3.2080</td>\n",
511
- " <td>3.1670</td>\n",
512
- " <td>8.187</td>\n",
513
- " <td>8.348</td>\n",
514
- " <td>8.2720</td>\n",
515
- " <td>12.890</td>\n",
516
- " <td>...</td>\n",
517
- " <td>-99</td>\n",
518
- " <td>0.322000</td>\n",
519
- " <td>0.299501</td>\n",
520
- " <td>2.0</td>\n",
521
- " <td>PRIMUS</td>\n",
522
- " <td>-99</td>\n",
523
- " <td>0</td>\n",
524
- " <td>0</td>\n",
525
- " <td>0</td>\n",
526
- " <td>0</td>\n",
527
- " </tr>\n",
528
- " </tbody>\n",
529
- "</table>\n",
530
- "<p>10057 rows × 123 columns</p>\n",
531
- "</div>"
532
- ],
533
- "text/plain": [
534
- " ID RA DEC FLUX_G_1 FLUX_G_2 FLUX_G_3 FLUX_R_1 \\\n",
535
- "368 369 149.862381 1.624455 0.4753 0.4252 0.4659 1.507 \n",
536
- "614 615 149.967209 1.625431 1.3970 1.3210 1.2990 3.310 \n",
537
- "863 864 150.029968 1.625488 1.8440 1.5770 1.5760 3.141 \n",
538
- "951 952 149.713226 1.625920 2.3280 2.3360 2.3340 5.336 \n",
539
- "1292 1293 149.530899 1.626842 1.0330 0.8639 0.8805 1.963 \n",
540
- "... ... ... ... ... ... ... ... \n",
541
- "391055 391056 149.911942 2.737337 2.5840 2.7920 2.7740 4.309 \n",
542
- "391111 391112 149.960968 2.735883 1.1160 1.0270 1.0280 4.790 \n",
543
- "391133 391134 149.802002 2.735837 1.1510 0.9859 1.0060 2.038 \n",
544
- "391178 391179 149.902161 2.735792 0.6982 0.6542 0.5222 1.162 \n",
545
- "391281 391282 149.553146 2.735168 3.1870 3.2080 3.1670 8.187 \n",
546
- "\n",
547
- " FLUX_R_2 FLUX_R_3 FLUX_I_1 ... mu_class_L07 photo_z_L15 \\\n",
548
- "368 1.374 1.2680 3.983 ... 1 1.189000 \n",
549
- "614 3.165 2.8200 3.815 ... 1 0.499900 \n",
550
- "863 3.037 2.9770 6.058 ... 1 0.818700 \n",
551
- "951 5.136 5.1460 8.928 ... 1 0.611600 \n",
552
- "1292 1.939 1.9980 3.388 ... 1 0.751600 \n",
553
- "... ... ... ... ... ... ... \n",
554
- "391055 4.247 4.0800 6.144 ... 1 0.207600 \n",
555
- "391111 4.807 4.8790 14.450 ... 1 0.690500 \n",
556
- "391133 2.059 1.9160 3.724 ... 1 -99.900002 \n",
557
- "391178 1.024 0.7999 3.115 ... 1 0.860600 \n",
558
- "391281 8.348 8.2720 12.890 ... -99 0.322000 \n",
559
- "\n",
560
- " z_spec_S15 Q_f_S15 Instr_S15 reliable_S15 flag_X_ray_s15 \\\n",
561
- "368 1.279900 1.5 zBRIGHT -99 0 \n",
562
- "614 0.498300 2.5 zBRIGHT -99 0 \n",
563
- "863 0.838300 2.5 zBRIGHT -99 0 \n",
564
- "951 0.615000 1.5 zBRIGHT -99 0 \n",
565
- "1292 0.763700 9.5 zBRIGHT -99 0 \n",
566
- "... ... ... ... ... ... \n",
567
- "391055 9.999900 0.0 zBRIGHT -99 0 \n",
568
- "391111 0.696300 1.5 zBRIGHT -99 0 \n",
569
- "391133 0.680074 2.0 PRIMUS -99 0 \n",
570
- "391178 0.881794 2.0 PRIMUS -99 0 \n",
571
- "391281 0.299501 2.0 PRIMUS -99 0 \n",
572
- "\n",
573
- " flag_IRAC_s15 STAR AGN \n",
574
- "368 0 0 0 \n",
575
- "614 0 0 0 \n",
576
- "863 0 0 0 \n",
577
- "951 0 0 0 \n",
578
- "1292 0 0 0 \n",
579
- "... ... ... ... \n",
580
- "391055 0 0 0 \n",
581
- "391111 0 0 0 \n",
582
- "391133 0 0 0 \n",
583
- "391178 0 0 0 \n",
584
- "391281 0 0 0 \n",
585
- "\n",
586
- "[10057 rows x 123 columns]"
587
- ]
588
- },
589
- "execution_count": 10,
590
- "metadata": {},
591
- "output_type": "execute_result"
592
- }
593
- ],
594
- "source": [
595
- "cat_valid_match[(cat_valid_match.reliable_S15<0)&(cat_valid_match.z_spec_S15>0)]"
596
- ]
597
- },
598
- {
599
- "cell_type": "code",
600
- "execution_count": 11,
601
- "id": "2d4324c9-2f8d-4aac-9435-c25b91cb4b26",
602
- "metadata": {
603
- "tags": []
604
- },
605
- "outputs": [],
606
- "source": [
607
- "cat_valid_match_fitTable = Table.from_pandas(cat_valid_match)\n",
608
- "\n",
609
- "# Define the output file path\n",
610
- "output_file_path = \"/data/astro/scratch2/lcabayol/insight/data/Euclid_EXT_MER_PHZ_DC2_v1.5/euclid_cosmos_DC2_S1_v2.1_valid_matched.fits\"\n",
611
- "\n",
612
- "# Save the FITS table to the output file\n",
613
- "cat_valid_match_fitTable.write(output_file_path, format='fits', overwrite=True)"
614
- ]
615
- },
616
- {
617
- "cell_type": "code",
618
- "execution_count": 14,
619
- "id": "29dc6866-f714-49eb-86e5-b33b1aa40ebe",
620
- "metadata": {
621
- "tags": []
622
- },
623
- "outputs": [
624
- {
625
- "data": {
626
- "text/html": [
627
- "<div><i>Table length=192864</i>\n",
628
- "<table id=\"table47896132584976\" class=\"table-striped table-bordered table-condensed\">\n",
629
- "<thead><tr><th>ID</th><th>RA</th><th>DEC</th><th>FLUX_G_1</th><th>FLUX_G_2</th><th>FLUX_G_3</th><th>FLUX_R_1</th><th>FLUX_R_2</th><th>FLUX_R_3</th><th>FLUX_I_1</th><th>FLUX_I_2</th><th>FLUX_I_3</th><th>FLUX_VIS</th><th>FLUX_Z_1</th><th>FLUX_Z_2</th><th>FLUX_Z_3</th><th>FLUX_Y_1</th><th>FLUX_Y_2</th><th>FLUX_Y_3</th><th>FLUX_J_1</th><th>FLUX_J_2</th><th>FLUX_J_3</th><th>FLUX_H_1</th><th>FLUX_H_2</th><th>FLUX_H_3</th><th>FLUXERR_G_1</th><th>FLUXERR_G_2</th><th>FLUXERR_G_3</th><th>FLUXERR_R_1</th><th>FLUXERR_R_2</th><th>FLUXERR_R_3</th><th>FLUXERR_I_1</th><th>FLUXERR_I_2</th><th>FLUXERR_I_3</th><th>FLUXERR_VIS</th><th>FLUXERR_Z_1</th><th>FLUXERR_Z_2</th><th>FLUXERR_Z_3</th><th>FLUXERR_Y_1</th><th>FLUXERR_Y_2</th><th>FLUXERR_Y_3</th><th>FLUXERR_J_1</th><th>FLUXERR_J_2</th><th>FLUXERR_J_3</th><th>FLUXERR_H_1</th><th>FLUXERR_H_2</th><th>FLUXERR_H_3</th><th>FLAG_PHOT</th><th>FLAG_Iband</th><th>EB_V</th><th>EB_V_corr_FLUX_G</th><th>EB_V_corr_FLUX_R</th><th>EB_V_corr_FLUX_I</th><th>EB_V_corr_FLUX_VIS</th><th>EB_V_corr_FLUX_Z</th><th>EB_V_corr_FLUX_Y</th><th>EB_V_corr_FLUX_J</th><th>EB_V_corr_FLUX_H</th><th>MAG_G_1</th><th>MAG_G_2</th><th>MAG_G_3</th><th>MAG_R_1</th><th>MAG_R_2</th><th>MAG_R_3</th><th>MAG_I_1</th><th>MAG_I_2</th><th>MAG_I_3</th><th>MAG_VIS</th><th>MAG_Z_1</th><th>MAG_Z_2</th><th>MAG_Z_3</th><th>MAG_Y_1</th><th>MAG_Y_2</th><th>MAG_Y_3</th><th>MAG_J_1</th><th>MAG_J_2</th><th>MAG_J_3</th><th>MAG_H_1</th><th>MAG_H_2</th><th>MAG_H_3</th><th>MAGERR_G_1</th><th>MAGERR_G_2</th><th>MAGERR_G_3</th><th>MAGERR_R_1</th><th>MAGERR_R_2</th><th>MAGERR_R_3</th><th>MAGERR_I_1</th><th>MAGERR_I_2</th><th>MAGERR_I_3</th><th>MAGERR_VIS</th><th>MAGERR_Z_1</th><th>MAGERR_Z_2</th><th>MAGERR_Z_3</th><th>MAGERR_Y_1</th><th>MAGERR_Y_2</th><th>MAGERR_Y_3</th><th>MAGERR_J_1</th><th>MAGERR_J_2</th><th>MAGERR_J_3</th><th>MAGERR_H_1</th><th>MAGERR_H_2</th><th>MAGERR_H_3</th><th>X_IMAGE_DETECT</th><th>Y_IMAGE_DETECT</th><th>FWHM_IMAGE_DETECT</th><th>FLUX_RADIUS_DETECT</th><th>MU_MAX_DETECT</th><th>MU_THRESHOLD_DETECT</th><th>FLAGS_DETECT</th><th>CLASS_STAR_DETECT</th><th>ELLIPTICITY_DETECT</th><th>MASKED</th><th>SHEAR_SAMPLE</th><th>mu_class_L07</th><th>photo_z_L15</th><th>z_spec_S15</th><th>Q_f_S15</th><th>Instr_S15</th><th>reliable_S15</th><th>flag_X_ray_s15</th><th>flag_IRAC_s15</th><th>STAR</th><th>AGN</th></tr></thead>\n",
630
- "<thead><tr><th>int32</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float32</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>int16</th><th>int16</th><th>float32</th><th>float32</th><th>float32</th><th>float32</th><th>float32</th><th>float32</th><th>float32</th><th>float32</th><th>float32</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float64</th><th>float32</th><th>float64</th><th>float32</th><th>float32</th><th>int16</th><th>float32</th><th>float32</th><th>int16</th><th>int16</th><th>int32</th><th>float32</th><th>float64</th><th>float32</th><th>str10</th><th>int16</th><th>int16</th><th>int16</th><th>int16</th><th>int16</th></tr></thead>\n",
631
- "<tr><td>6</td><td>150.069244</td><td>1.624058</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>1</td><td>0</td><td>0.018708352</td><td>1.0655923</td><td>1.0440009</td><td>1.0328002</td><td>1.0311464</td><td>1.0243992</td><td>1.0203122</td><td>1.0167669</td><td>1.0110366</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>23934.8633</td><td>2.0323</td><td>3.57</td><td>2.126</td><td>23.4117</td><td>24.7342</td><td>24</td><td>0.136</td><td>0.38</td><td>1</td><td>0</td><td>1</td><td>0.1363</td><td>-99.0</td><td>-99.0</td><td>-99</td><td>-99</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>\n",
632
- "<tr><td>7</td><td>149.988235</td><td>1.624047</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>1</td><td>0</td><td>0.018918319</td><td>1.0663524</td><td>1.0445056</td><td>1.0331743</td><td>1.0315014</td><td>1.0246763</td><td>1.0205425</td><td>1.0169567</td><td>1.0111612</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>26850.2832</td><td>1.8137</td><td>8.06</td><td>2.666</td><td>23.1684</td><td>24.7342</td><td>24</td><td>0.004</td><td>0.709</td><td>1</td><td>0</td><td>1</td><td>-99.9</td><td>-99.0</td><td>-99.0</td><td>-99</td><td>-99</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>\n",
633
- "<tr><td>10</td><td>149.575302</td><td>1.62399</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>1</td><td>0</td><td>0.020030802</td><td>1.0703884</td><td>1.0471835</td><td>1.035159</td><td>1.0333844</td><td>1.0261462</td><td>1.0217634</td><td>1.0179628</td><td>1.0118214</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>41711.2617</td><td>2.434</td><td>8.3</td><td>2.227</td><td>22.8817</td><td>24.7342</td><td>24</td><td>0.185</td><td>0.603</td><td>1</td><td>0</td><td>1</td><td>2.4208</td><td>-99.0</td><td>-99.0</td><td>-99</td><td>-99</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>\n",
634
- "<tr><td>11</td><td>149.549957</td><td>1.623974</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>1</td><td>0</td><td>0.020030802</td><td>1.0703884</td><td>1.0471835</td><td>1.035159</td><td>1.0333844</td><td>1.0261462</td><td>1.0217634</td><td>1.0179628</td><td>1.0118214</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>42623.7148</td><td>2.1264</td><td>2.44</td><td>1.24</td><td>21.9707</td><td>24.7342</td><td>24</td><td>0.969</td><td>0.258</td><td>1</td><td>0</td><td>1</td><td>1.9102</td><td>-99.0</td><td>-99.0</td><td>-99</td><td>-99</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>\n",
635
- "<tr><td>12</td><td>149.523422</td><td>1.623958</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>1</td><td>0</td><td>0.019504732</td><td>1.068478</td><td>1.0459163</td><td>1.03422</td><td>1.0324936</td><td>1.0254508</td><td>1.0211859</td><td>1.0174869</td><td>1.0115092</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>43578.6016</td><td>1.8235</td><td>4.86</td><td>1.685</td><td>21.9404</td><td>24.7342</td><td>24</td><td>0.853</td><td>0.517</td><td>1</td><td>0</td><td>1</td><td>0.5091</td><td>-99.0</td><td>-99.0</td><td>-99</td><td>-99</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>\n",
636
- "<tr><td>15</td><td>149.737442</td><td>1.624018</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>1</td><td>0</td><td>0.02313314</td><td>1.0817248</td><td>1.0546877</td><td>1.0407139</td><td>1.0386537</td><td>1.0302564</td><td>1.0251763</td><td>1.0207735</td><td>1.0136647</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>35875.6875</td><td>2.0121</td><td>9.63</td><td>3.132</td><td>23.0523</td><td>24.7342</td><td>24</td><td>0.014</td><td>0.608</td><td>1</td><td>0</td><td>1</td><td>-99.9</td><td>-99.0</td><td>-99.0</td><td>-99</td><td>-99</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>\n",
637
- "<tr><td>16</td><td>149.559097</td><td>1.623963</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>1</td><td>0</td><td>0.020030802</td><td>1.0703884</td><td>1.0471835</td><td>1.035159</td><td>1.0333844</td><td>1.0261462</td><td>1.0217634</td><td>1.0179628</td><td>1.0118214</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>42294.6523</td><td>1.6269</td><td>3.66</td><td>1.399</td><td>21.8347</td><td>24.7342</td><td>26</td><td>0.972</td><td>0.431</td><td>1</td><td>0</td><td>1</td><td>1.3856</td><td>-99.0</td><td>-99.0</td><td>-99</td><td>-99</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>\n",
638
- "<tr><td>17</td><td>149.992615</td><td>1.624071</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>1</td><td>0</td><td>0.018918319</td><td>1.0663524</td><td>1.0445056</td><td>1.0331743</td><td>1.0315014</td><td>1.0246763</td><td>1.0205425</td><td>1.0169567</td><td>1.0111612</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>26692.9688</td><td>2.6712</td><td>3.87</td><td>1.39</td><td>23.3575</td><td>24.7342</td><td>24</td><td>0.157</td><td>0.223</td><td>1</td><td>0</td><td>1</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99</td><td>-99</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>\n",
639
- "<tr><td>19</td><td>149.646317</td><td>1.62402</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>1</td><td>0</td><td>0.02129529</td><td>1.0749947</td><td>1.0502357</td><td>1.0374196</td><td>1.0355289</td><td>1.0278195</td><td>1.0231532</td><td>1.0191075</td><td>1.0125723</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>39155.6875</td><td>2.8399</td><td>3.57</td><td>1.929</td><td>22.7226</td><td>24.7342</td><td>24</td><td>0.308</td><td>0.099</td><td>1</td><td>0</td><td>1</td><td>0.3163</td><td>-99.0</td><td>-99.0</td><td>-99</td><td>-99</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>\n",
640
- "<tr><td>22</td><td>149.604645</td><td>1.62402</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>0.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>1</td><td>0</td><td>0.020338759</td><td>1.0715084</td><td>1.0479261</td><td>1.0357091</td><td>1.0339063</td><td>1.0265535</td><td>1.0221018</td><td>1.0182414</td><td>1.0120043</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>-inf</td><td>40655.4453</td><td>3.2193</td><td>8.58</td><td>3.033</td><td>23.7319</td><td>24.7342</td><td>24</td><td>0.0</td><td>0.246</td><td>1</td><td>0</td><td>-99</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99</td><td>-99</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>\n",
641
- "<tr><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td></tr>\n",
642
- "<tr><td>391255</td><td>150.005234</td><td>2.735809</td><td>0.2727</td><td>0.2277</td><td>0.09763</td><td>0.2231</td><td>0.1551</td><td>0.1594</td><td>0.2257</td><td>0.03906</td><td>0.05882</td><td>0.3584</td><td>0.01253</td><td>-0.3012</td><td>-0.4305</td><td>0.6769</td><td>0.6085</td><td>0.5974</td><td>0.8711</td><td>0.7607</td><td>0.5939</td><td>1.168</td><td>0.8813</td><td>0.5398</td><td>0.10394417539999999</td><td>0.09198180119999999</td><td>0.1061645118</td><td>0.14301444800000002</td><td>0.12652246500000003</td><td>0.14603588</td><td>0.32369910999999996</td><td>0.28642884999999996</td><td>0.33060101</td><td>0.04932417783014477</td><td>0.5164025400000001</td><td>0.45684054</td><td>0.527361948</td><td>0.1213023018</td><td>0.1071705548</td><td>0.12346532430000001</td><td>0.1339676488</td><td>0.11852573400000002</td><td>0.1368081348</td><td>0.232692636</td><td>0.20585811240000002</td><td>0.237684</td><td>0</td><td>0</td><td>0.021491202</td><td>1.07571</td><td>1.0507094</td><td>1.0377703</td><td>1.0358616</td><td>1.0280789</td><td>1.0233686</td><td>1.019285</td><td>1.0126886</td><td>25.310787155145924</td><td>25.50659242346214</td><td>26.426041776722485</td><td>25.528751074290405</td><td>25.923470505465986</td><td>25.893779207349766</td><td>25.51617110230559</td><td>27.42066940262041</td><td>26.97618744957237</td><td>25.01408003623817</td><td>28.65512232251462</td><td>-99.0</td><td>-99.0</td><td>24.32368871475685</td><td>24.43934854358479</td><td>24.459336954329725</td><td>24.049829965651618</td><td>24.19696645936245</td><td>24.465716686807443</td><td>23.73139289305905</td><td>24.0371905746947</td><td>24.569417799448754</td><td>0.41383275112497253</td><td>0.43857989267826086</td><td>1.1806085266952782</td><td>0.6959694585100854</td><td>0.8856572550000004</td><td>0.9946747485319952</td><td>1.5571117577625166</td><td>7.96149007795699</td><td>6.102235915623938</td><td>0.1494175830904875</td><td>44.74527036536314</td><td>-1.6467190381075698</td><td>-1.3299811078829271</td><td>0.19456036203909</td><td>0.19121622242622843</td><td>0.2243828299171577</td><td>0.16697127344984505</td><td>0.16916443986302093</td><td>0.2500969724740866</td><td>0.21629657098047947</td><td>0.2536028056651311</td><td>0.47805394368284565</td><td>26235.0566</td><td>40026.5781</td><td>3.92</td><td>1.767</td><td>22.7034</td><td>24.7528</td><td>0</td><td>0.048</td><td>0.238</td><td>0</td><td>0</td><td>1</td><td>1.365</td><td>-99.0</td><td>-99.0</td><td>-99</td><td>-99</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>\n",
643
- "<tr><td>391274</td><td>149.756409</td><td>2.737342</td><td>0.4296</td><td>0.4827</td><td>0.2974</td><td>0.6213</td><td>0.5303</td><td>0.5383</td><td>1.105</td><td>0.9342</td><td>0.7961</td><td>0.8178</td><td>0.7203</td><td>0.4679</td><td>-0.03101</td><td>1.092</td><td>0.9184</td><td>0.8212</td><td>0.8879</td><td>0.6808</td><td>0.6462</td><td>0.9409</td><td>1.027</td><td>1.148</td><td>0.1197360062</td><td>0.11717887719999999</td><td>0.147565054</td><td>0.164793937</td><td>0.161268933</td><td>0.20293951600000004</td><td>0.372840638</td><td>0.36483443399999993</td><td>0.45939046399999994</td><td>0.054034564145170154</td><td>0.5947861320000001</td><td>0.582039864</td><td>0.732731724</td><td>0.1679370669</td><td>0.1632937786</td><td>0.20436236580000003</td><td>0.17254661320000003</td><td>0.168492465</td><td>0.211616207</td><td>0.337273596</td><td>0.329667708</td><td>0.41475858</td><td>0</td><td>0</td><td>0.020267427</td><td>1.0712489</td><td>1.0477539</td><td>1.0355817</td><td>1.0337855</td><td>1.0264591</td><td>1.0220234</td><td>1.0181769</td><td>1.0119618</td><td>24.81733931827125</td><td>24.690806752953268</td><td>25.21664758953516</td><td>24.41674661596721</td><td>24.588695932203592</td><td>24.57243905046078</td><td>23.791594304947175</td><td>23.97390034262059</td><td>24.14758094020219</td><td>24.11838225382595</td><td>24.256216463058273</td><td>24.72461738701955</td><td>-99.0</td><td>23.804443404078203</td><td>23.99242031236525</td><td>24.113877648253613</td><td>24.029089860029075</td><td>24.31745113230867</td><td>24.374082615795935</td><td>23.966141328668776</td><td>23.8710738910068</td><td>23.75014527984511</td><td>0.3026009821493017</td><td>0.2635614397680547</td><td>0.5387067220168124</td><td>0.2879716359261227</td><td>0.3301709986009806</td><td>0.4093097390325099</td><td>0.36632857979782807</td><td>0.4239999411194605</td><td>0.626504492858686</td><td>0.07173554333470301</td><td>0.8965143738892131</td><td>1.3505464422842488</td><td>-25.653880449751693</td><td>0.16696819920634615</td><td>0.1930401300370427</td><td>0.27018536355219197</td><td>0.2109853113540264</td><td>0.26870192310590485</td><td>0.3555427359020427</td><td>0.3891783857765969</td><td>0.3485104484669913</td><td>0.39225033998780495</td><td>35182.9414</td><td>40083.7305</td><td>6.19</td><td>2.472</td><td>22.3469</td><td>24.7485</td><td>0</td><td>0.019</td><td>0.243</td><td>0</td><td>1</td><td>1</td><td>0.3572</td><td>-99.0</td><td>-99.0</td><td>-99</td><td>-99</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>\n",
644
- "<tr><td>391275</td><td>149.806961</td><td>2.736647</td><td>0.48</td><td>0.4337</td><td>0.3315</td><td>1.134</td><td>0.9581</td><td>0.9082</td><td>1.965</td><td>1.899</td><td>1.989</td><td>1.798</td><td>1.996</td><td>1.839</td><td>1.893</td><td>2.447</td><td>2.404</td><td>2.622</td><td>2.831</td><td>2.892</td><td>3.16</td><td>2.663</td><td>2.752</td><td>3.121</td><td>0.1122642</td><td>0.09387781879999998</td><td>0.0989047602</td><td>0.154470711</td><td>0.129166218</td><td>0.136090333</td><td>0.349650254</td><td>0.292364484</td><td>0.307962778</td><td>0.06669243183344603</td><td>0.557738568</td><td>0.46637046000000004</td><td>0.49126737600000003</td><td>0.1504886854</td><td>0.1258013886</td><td>0.1327230606</td><td>0.15666571420000003</td><td>0.13104969500000002</td><td>0.138021797</td><td>0.31160372399999997</td><td>0.260501664</td><td>0.27452502</td><td>0</td><td>0</td><td>0.01969525</td><td>1.0691695</td><td>1.046375</td><td>1.03456</td><td>1.0328162</td><td>1.0257026</td><td>1.0213951</td><td>1.0176592</td><td>1.0116222</td><td>24.69689690656103</td><td>24.807026444628093</td><td>25.09879116814802</td><td>23.76346736360778</td><td>23.946472899585277</td><td>24.00454625608763</td><td>23.166593613221384</td><td>23.203687588157454</td><td>23.15341304218891</td><td>23.2630257947523</td><td>23.149598657621617</td><td>23.238545676904806</td><td>23.207123465090508</td><td>22.928415076620524</td><td>22.947663841673243</td><td>22.853418281614836</td><td>22.770150326587242</td><td>22.747004278443764</td><td>22.65078229345399</td><td>22.836572083902645</td><td>22.800878926091315</td><td>22.664265578336668</td><td>0.253927587375</td><td>0.2350084110471755</td><td>0.3239242779762896</td><td>0.14789140293888892</td><td>0.14636860753846156</td><td>0.16268803626745212</td><td>0.193188438049771</td><td>0.16715119551279622</td><td>0.16810215589472097</td><td>0.04027139828971397</td><td>0.30337513190260523</td><td>0.27533355542251226</td><td>0.2817585790402536</td><td>0.06676974488711891</td><td>0.056814711981289526</td><td>0.054957065939519455</td><td>0.0600819377982833</td><td>0.049198013091805</td><td>0.04742096993762659</td><td>0.1270402415121292</td><td>0.10277131417325584</td><td>0.09549881903684719</td><td>33364.9023</td><td>40058.1602</td><td>5.47</td><td>2.469</td><td>21.6187</td><td>24.7527</td><td>0</td><td>0.028</td><td>0.293</td><td>0</td><td>1</td><td>1</td><td>0.699</td><td>-99.0</td><td>-99.0</td><td>-99</td><td>-99</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>\n",
645
- "<tr><td>391276</td><td>150.061966</td><td>2.736018</td><td>0.1867</td><td>0.1835</td><td>0.1943</td><td>0.2688</td><td>0.2575</td><td>0.2643</td><td>0.4256</td><td>0.1926</td><td>0.2687</td><td>0.3481</td><td>0.5257</td><td>0.5524</td><td>0.6304</td><td>0.4646</td><td>0.4489</td><td>0.4178</td><td>0.5148</td><td>0.5157</td><td>0.4845</td><td>1.09</td><td>0.8295</td><td>0.6682</td><td>0.0780360928</td><td>0.045841215</td><td>0.038481672999999994</td><td>0.1073615504</td><td>0.06308498230000001</td><td>0.05295059580000001</td><td>0.24294687999999998</td><td>0.142731292</td><td>0.11983078779999999</td><td>0.0605087503965199</td><td>0.3876294960000001</td><td>0.22776508800000003</td><td>0.19119402000000002</td><td>0.1057285398</td><td>0.062093165900000004</td><td>0.0520855818</td><td>0.11418753720000002</td><td>0.0670871148</td><td>0.0563449132</td><td>0.18979067400000002</td><td>0.111354954</td><td>0.0932434332</td><td>0</td><td>0</td><td>0.020559706</td><td>1.0723127</td><td>1.048459</td><td>1.036104</td><td>1.0342809</td><td>1.0268458</td><td>1.0223445</td><td>1.0184414</td><td>1.0121354</td><td>25.722139205127302</td><td>25.740909828529727</td><td>25.67881799850054</td><td>25.326426839045528</td><td>25.373056916556973</td><td>25.344757092170724</td><td>24.82749595178252</td><td>25.68835929302871</td><td>25.32683083391708</td><td>25.045739921264925</td><td>24.598155057453937</td><td>24.544365825233513</td><td>24.40095948879625</td><td>24.732301986339458</td><td>24.769625986495868</td><td>24.847578910889276</td><td>24.620903654419127</td><td>24.61900717148321</td><td>24.68676554653304</td><td>23.80643375514844</td><td>24.10295902409905</td><td>24.337733821744717</td><td>0.4537963896784146</td><td>0.2712251069509537</td><td>0.21502600296500254</td><td>0.4336400121625001</td><td>0.26598588459460204</td><td>0.21751215232712834</td><td>0.6197542942105264</td><td>0.804586519856698</td><td>0.4841841693876442</td><td>0.18872263448330984</td><td>0.8005503971984025</td><td>0.4476548805966692</td><td>0.3292819598889595</td><td>0.24707162217145934</td><td>0.15017721144493207</td><td>0.13535020622369556</td><td>0.24081858806923082</td><td>0.14123808520139616</td><td>0.12626144945560375</td><td>0.18904195849706423</td><td>0.14574812966582282</td><td>0.15150313592523199</td><td>24194.5723</td><td>40033.9297</td><td>7.36</td><td>2.659</td><td>23.0846</td><td>24.7429</td><td>0</td><td>0.085</td><td>0.345</td><td>0</td><td>0</td><td>1</td><td>-99.0</td><td>-99.0</td><td>-99.0</td><td>-99</td><td>-99</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>\n",
646
- "<tr><td>391281</td><td>150.111298</td><td>2.73576</td><td>4.851</td><td>4.987</td><td>4.848</td><td>21.52</td><td>21.17</td><td>20.92</td><td>39.08</td><td>38.33</td><td>38.02</td><td>35.07</td><td>46.4</td><td>44.44</td><td>43.65</td><td>57.58</td><td>56.49</td><td>56.22</td><td>71.63</td><td>70.33</td><td>69.87</td><td>83.6</td><td>84.8</td><td>85.81</td><td>0.143573438</td><td>0.12760697399999998</td><td>0.151182456</td><td>0.19752611700000003</td><td>0.17562073500000003</td><td>0.20797523600000004</td><td>0.447105082</td><td>0.39741140199999997</td><td>0.470847618</td><td>0.11630711061291397</td><td>0.713195388</td><td>0.6339779280000001</td><td>0.750957696</td><td>0.2055736584</td><td>0.1784060958</td><td>0.20799624360000002</td><td>0.2198277938</td><td>0.1922750796</td><td>0.22339131260000003</td><td>0.351534636</td><td>0.309226884</td><td>0.363181152</td><td>0</td><td>0</td><td>0.01991791</td><td>1.0699782</td><td>1.0469115</td><td>1.0349574</td><td>1.0331932</td><td>1.0259969</td><td>1.0216395</td><td>1.0178607</td><td>1.0117544</td><td>22.18542181343484</td><td>22.15540157945409</td><td>22.186093472104425</td><td>20.567894332514122</td><td>20.58569785495147</td><td>20.59859579951191</td><td>19.92011361238316</td><td>19.94115295186412</td><td>19.94996971867644</td><td>20.037660594744214</td><td>19.733705048612798</td><td>19.780564874327922</td><td>19.800039379896027</td><td>19.499320848644842</td><td>19.520071063159183</td><td>19.525272896821445</td><td>19.262262622103442</td><td>19.282148456466484</td><td>19.289273141864143</td><td>19.094484306402457</td><td>19.079010369358215</td><td>19.06615524507074</td><td>0.032133102790476195</td><td>0.027780808436294366</td><td>0.033857011650000005</td><td>0.009965339462216546</td><td>0.009006680774185169</td><td>0.010793437558565967</td><td>0.012421238166003072</td><td>0.011256706474077746</td><td>0.013445535477711733</td><td>0.00360064531198376</td><td>0.016687849843784484</td><td>0.015488520171683173</td><td>0.018678459806350516</td><td>0.0038761952227315045</td><td>0.0034288457817323423</td><td>0.004016747094922092</td><td>0.0033319424225695944</td><td>0.002968193572042088</td><td>0.0034712458578763424</td><td>0.004565324812263159</td><td>0.003959052216495283</td><td>0.004595102863610302</td><td>22420.7383</td><td>40024.5664</td><td>3.91</td><td>3.075</td><td>18.4772</td><td>24.7292</td><td>0</td><td>0.032</td><td>0.615</td><td>0</td><td>1</td><td>1</td><td>-99.9</td><td>0.3451</td><td>3.5</td><td>zBRIGHT</td><td>1</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>\n",
647
- "<tr><td>391282</td><td>149.553146</td><td>2.735168</td><td>3.187</td><td>3.208</td><td>3.167</td><td>8.187</td><td>8.348</td><td>8.272</td><td>12.89</td><td>12.85</td><td>12.87</td><td>12.34</td><td>14.76</td><td>15.0</td><td>14.56</td><td>18.65</td><td>18.48</td><td>18.42</td><td>23.18</td><td>22.79</td><td>22.52</td><td>30.92</td><td>29.54</td><td>28.83</td><td>0.154300906</td><td>0.129478044</td><td>0.152554574</td><td>0.21225559800000002</td><td>0.178138595</td><td>0.209863631</td><td>0.48037223999999995</td><td>0.403347036</td><td>0.474988758</td><td>0.10307860336028041</td><td>0.7662055680000001</td><td>0.643388724</td><td>0.7576286400000001</td><td>0.1898268546</td><td>0.1578718022</td><td>0.1846067603</td><td>0.22055082660000003</td><td>0.18455412220000003</td><td>0.21693566260000002</td><td>0.359853576</td><td>0.30043257600000006</td><td>0.35272305600000003</td><td>0</td><td>0</td><td>0.018174222</td><td>1.0636612</td><td>1.0427182</td><td>1.0318489</td><td>1.0302439</td><td>1.0236943</td><td>1.0197265</td><td>1.0162843</td><td>1.0107199</td><td>22.641544841315667</td><td>22.634414100969686</td><td>22.648379841570218</td><td>21.617188024026103</td><td>21.596043899016458</td><td>21.60597368562533</td><td>21.124367706616493</td><td>21.127742180831717</td><td>21.126053632739033</td><td>21.17171208733148</td><td>20.97728410628244</td><td>20.959771852360795</td><td>20.992096562557453</td><td>20.72330290963823</td><td>20.73324508278978</td><td>20.736775935347925</td><td>20.487216420931055</td><td>20.50563918704906</td><td>20.518579034551728</td><td>20.174401286884283</td><td>20.22397377256017</td><td>20.25038839402948</td><td>0.052564949370630686</td><td>0.04381992280885287</td><td>0.052298232078244404</td><td>0.02814778340644926</td><td>0.02316783332432918</td><td>0.02754460156875</td><td>0.0404608332791311</td><td>0.03407890093270039</td><td>0.040069564456923085</td><td>0.009069079277506059</td><td>0.05635971444292684</td><td>0.04656847584312</td><td>0.05649432791538462</td><td>0.011050671101298662</td><td>0.00927496837925</td><td>0.01088097500856189</td><td>0.010330113565125972</td><td>0.00879203205232734</td><td>0.010458572330587036</td><td>0.012635608908900389</td><td>0.01104196505630332</td><td>0.013283087821685746</td><td>42492.6094</td><td>40008.4688</td><td>12.23</td><td>4.488</td><td>20.5647</td><td>24.7147</td><td>0</td><td>0.029</td><td>0.591</td><td>0</td><td>1</td><td>-99</td><td>0.322</td><td>0.29950076</td><td>2.0</td><td>PRIMUS</td><td>-99</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>\n",
648
- "<tr><td>391284</td><td>150.061554</td><td>2.735742</td><td>1.076</td><td>1.094</td><td>1.047</td><td>2.33</td><td>2.227</td><td>2.086</td><td>3.033</td><td>3.104</td><td>2.833</td><td>2.846</td><td>3.812</td><td>3.782</td><td>4.066</td><td>3.965</td><td>3.829</td><td>3.576</td><td>4.127</td><td>4.04</td><td>3.867</td><td>3.708</td><td>3.679</td><td>3.694</td><td>0.1209459648</td><td>0.1103182872</td><td>0.13159859</td><td>0.16643054600000004</td><td>0.151826958</td><td>0.18103413400000004</td><td>0.376705702</td><td>0.343576582</td><td>0.409834822</td><td>0.07139244035378099</td><td>0.600861456</td><td>0.5479704000000001</td><td>0.653752512</td><td>0.161217277</td><td>0.1467394464</td><td>0.1750894613</td><td>0.17357951720000003</td><td>0.15870569960000003</td><td>0.1898994004</td><td>0.295203528</td><td>0.268107552</td><td>0.318734244</td><td>0</td><td>0</td><td>0.020559706</td><td>1.0723127</td><td>1.048459</td><td>1.036104</td><td>1.0342809</td><td>1.0268458</td><td>1.0223445</td><td>1.0184414</td><td>1.0121354</td><td>23.82046932167407</td><td>23.80245669500647</td><td>23.85013329580289</td><td>22.98161019743495</td><td>23.030699457414904</td><td>23.10171423977372</td><td>22.69531897422334</td><td>22.67019571853462</td><td>22.769383563698906</td><td>22.76441277736517</td><td>22.447117770084276</td><td>22.455696188727448</td><td>22.37708156424495</td><td>22.40439202086594</td><td>22.44228658413078</td><td>22.5165062246903</td><td>22.36091382780646</td><td>22.384046587223487</td><td>22.431564569817336</td><td>22.47715068631885</td><td>22.48567553042218</td><td>22.48125777223944</td><td>0.1220362769362082</td><td>0.10948132030442415</td><td>0.13646283587679084</td><td>0.0775509200824893</td><td>0.07401819860826225</td><td>0.0942227992731544</td><td>0.13484648224906035</td><td>0.12017432186771909</td><td>0.15706236012897987</td><td>0.027234987240643778</td><td>0.17113202591269677</td><td>0.15730604528820732</td><td>0.1745644619474668</td><td>0.044144665230491806</td><td>0.04160747374157221</td><td>0.05315845305744128</td><td>0.04566398881125274</td><td>0.042650192588049515</td><td>0.05331620869259892</td><td>0.08643540192815534</td><td>0.07912051351084536</td><td>0.09367887620757986</td><td>24209.6953</td><td>40023.9766</td><td>3.67</td><td>2.374</td><td>20.8995</td><td>24.748</td><td>0</td><td>0.03</td><td>0.349</td><td>0</td><td>1</td><td>1</td><td>0.4825</td><td>0.48773733</td><td>4.0</td><td>PRIMUS</td><td>1</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>\n",
649
- "<tr><td>391287</td><td>149.530014</td><td>2.735158</td><td>0.4498</td><td>0.3174</td><td>0.28</td><td>0.5858</td><td>0.4755</td><td>0.4707</td><td>0.4406</td><td>0.4729</td><td>0.4766</td><td>0.7128</td><td>0.8716</td><td>0.998</td><td>1.001</td><td>0.49</td><td>0.4708</td><td>0.5188</td><td>0.6313</td><td>0.5129</td><td>0.4449</td><td>0.5575</td><td>0.5045</td><td>0.445</td><td>0.1094825426</td><td>0.09569899359999999</td><td>0.09730811379999998</td><td>0.150693921</td><td>0.131684078</td><td>0.13382425900000003</td><td>0.34095386</td><td>0.298024042</td><td>0.30299340999999996</td><td>0.04956280913151801</td><td>0.5439201840000001</td><td>0.475423884</td><td>0.48340519200000004</td><td>0.1337901517</td><td>0.117091618</td><td>0.1191392793</td><td>0.160874798</td><td>0.1406815248</td><td>0.14326378480000002</td><td>0.2555103</td><td>0.2229951288</td><td>0.22689314640000002</td><td>0</td><td>0</td><td>0.019297935</td><td>1.0677279</td><td>1.0454186</td><td>1.0338511</td><td>1.0321436</td><td>1.0251776</td><td>1.0209589</td><td>1.0172999</td><td>1.0113864</td><td>24.767451372250964</td><td>25.145982693952924</td><td>25.28210492164445</td><td>24.48062658163605</td><td>24.707123696816417</td><td>24.718139504233502</td><td>24.789888767963127</td><td>24.71307671496143</td><td>24.704614904973905</td><td>24.26758073291626</td><td>24.049206946064455</td><td>23.90217364678157</td><td>23.8989148063017</td><td>24.674509799928714</td><td>24.717908864571505</td><td>24.612500081469893</td><td>24.399410526681613</td><td>24.624918252335615</td><td>24.779343985629886</td><td>24.534387820699504</td><td>24.642847073567676</td><td>24.77909997254767</td><td>0.2642623310378391</td><td>0.3273484478623818</td><td>0.37731221125949993</td><td>0.27929052582741554</td><td>0.30067172131356473</td><td>0.3086743105933717</td><td>0.8401579795778485</td><td>0.684213792343836</td><td>0.6902222938250104</td><td>0.07549149819843444</td><td>0.6775288478301975</td><td>0.5172021150889781</td><td>0.524308708246154</td><td>0.29644075040957146</td><td>0.27002202562149535</td><td>0.24932443241328064</td><td>0.27666999554664984</td><td>0.2977928084916358</td><td>0.3496100048490898</td><td>0.49759198692376694</td><td>0.4798925893719724</td><td>0.55356828999209</td><td>43324.6875</td><td>40008.5078</td><td>5.48</td><td>2.371</td><td>22.6908</td><td>24.716</td><td>0</td><td>0.02</td><td>0.165</td><td>0</td><td>1</td><td>1</td><td>-99.9</td><td>-99.0</td><td>-99.0</td><td>-99</td><td>-99</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>\n",
650
- "<tr><td>391290</td><td>149.673889</td><td>2.73574</td><td>0.08647</td><td>0.1009</td><td>0.1272</td><td>0.7007</td><td>0.5679</td><td>0.495</td><td>1.075</td><td>0.8945</td><td>0.6616</td><td>0.8182</td><td>1.292</td><td>1.04</td><td>1.108</td><td>1.606</td><td>1.697</td><td>1.651</td><td>1.598</td><td>1.798</td><td>1.947</td><td>1.886</td><td>2.285</td><td>2.37</td><td>0.1000897712</td><td>0.071537243</td><td>0.0588888098</td><td>0.13772694200000002</td><td>0.09842314740000001</td><td>0.08102473480000001</td><td>0.311689804</td><td>0.22279333199999998</td><td>0.183452502</td><td>0.06435798460256309</td><td>0.497223576</td><td>0.355346892</td><td>0.29256854400000004</td><td>0.12196562870000001</td><td>0.0868958239</td><td>0.0713220619</td><td>0.1327539866</td><td>0.0946140064</td><td>0.0777518486</td><td>0.2363292012</td><td>0.16958753399999998</td><td>0.14009094960000001</td><td>0</td><td>0</td><td>0.0201357</td><td>1.0707698</td><td>1.0474364</td><td>1.0353464</td><td>1.0335622</td><td>1.0262849</td><td>1.0218787</td><td>1.0180577</td><td>1.0118836</td><td>26.55783635256094</td><td>26.390272084407723</td><td>26.138782221719012</td><td>24.286169706266058</td><td>24.51432032829135</td><td>24.663487002666077</td><td>23.82147883937094</td><td>24.021049137741517</td><td>24.348511258638773</td><td>24.117851322471278</td><td>23.621843715852336</td><td>23.85741665175305</td><td>23.788650599018972</td><td>23.385636147643343</td><td>23.32579539420581</td><td>23.355632316843014</td><td>23.391058062555068</td><td>23.263025781506975</td><td>23.17658512119992</td><td>23.211145778996723</td><td>23.002784488985327</td><td>22.96312913497474</td><td>1.2567071191377357</td><td>0.7697520785441031</td><td>0.5026382138353773</td><td>0.213401085956044</td><td>0.18816342865324887</td><td>0.1777142516613334</td><td>0.314792204839814</td><td>0.27041556238390163</td><td>0.30104954870223705</td><td>0.08539900336205575</td><td>0.41782943998699695</td><td>0.3709616544657693</td><td>0.2866802059754513</td><td>0.08245210652527397</td><td>0.05559386918575722</td><td>0.046901491583785586</td><td>0.09019462030764708</td><td>0.05713149429837598</td><td>0.043356539304067805</td><td>0.13604592457202547</td><td>0.08057819941522976</td><td>0.06417584134207596</td><td>38150.2539</td><td>40027.1172</td><td>3.24</td><td>2.239</td><td>22.1356</td><td>24.7595</td><td>0</td><td>0.02</td><td>0.061</td><td>0</td><td>1</td><td>1</td><td>0.3075</td><td>-99.0</td><td>-99.0</td><td>-99</td><td>-99</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>\n",
651
- "<tr><td>391293</td><td>150.035202</td><td>2.737025</td><td>0.1009</td><td>0.03854</td><td>-0.01078</td><td>0.1853</td><td>0.2034</td><td>0.1022</td><td>0.6207</td><td>0.4503</td><td>0.3578</td><td>0.2571</td><td>0.02907</td><td>0.1176</td><td>0.2719</td><td>0.3632</td><td>0.3618</td><td>0.3522</td><td>0.2948</td><td>0.2812</td><td>0.1888</td><td>0.3374</td><td>0.2025</td><td>0.1798</td><td>0.0959734172</td><td>0.0874662856</td><td>0.0993413432</td><td>0.132061757</td><td>0.1203411187</td><td>0.136719798</td><td>0.29885227</td><td>0.27234897399999997</td><td>0.30934315799999995</td><td>0.03506851240448654</td><td>0.476734248</td><td>0.43444522800000007</td><td>0.493530732</td><td>0.10538245620000002</td><td>0.0960670393</td><td>0.1091028549</td><td>0.11323210100000002</td><td>0.10334204520000001</td><td>0.11751865260000001</td><td>0.1974916356</td><td>0.1799743248</td><td>0.2043844716</td><td>0</td><td>0</td><td>0.021491202</td><td>1.07571</td><td>1.0507094</td><td>1.0377703</td><td>1.0358616</td><td>1.0280789</td><td>1.0233686</td><td>1.019285</td><td>1.0126886</td><td>26.390272084407723</td><td>27.435220724201415</td><td>-99.0</td><td>25.730311451702754</td><td>25.629122628533185</td><td>26.376372760503262</td><td>24.417795636536507</td><td>24.766245132592665</td><td>25.015899159421615</td><td>25.374744867192558</td><td>27.74138742057393</td><td>26.223981695649698</td><td>25.31397698103125</td><td>24.99963540037738</td><td>25.00382859369051</td><td>25.033026620921852</td><td>25.226181302032465</td><td>25.27746170913053</td><td>25.709995025094873</td><td>25.079637304367232</td><td>25.63393743112328</td><td>25.763025781506972</td><td>1.0326891878497524</td><td>2.463989265073171</td><td>-10.005092422285717</td><td>0.7737692907441986</td><td>0.6423517825594396</td><td>1.4524137445068495</td><td>0.5227386975012083</td><td>0.6566495249207195</td><td>0.9386636854125209</td><td>0.14808979377479875</td><td>17.8049663933127</td><td>4.010860408500001</td><td>1.9706742027671944</td><td>0.3150157838555617</td><td>0.2882807754781924</td><td>0.3363230254540886</td><td>0.41701523763805975</td><td>0.3989987854681366</td><td>0.6757944974990467</td><td>0.63549694360083</td><td>0.9649290095573334</td><td>1.2341502826258068</td><td>25157.3125</td><td>40070.2656</td><td>3.91</td><td>1.619</td><td>22.8827</td><td>24.7088</td><td>0</td><td>0.908</td><td>0.344</td><td>0</td><td>0</td><td>1</td><td>0.6928</td><td>-99.0</td><td>-99.0</td><td>-99</td><td>-99</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>\n",
652
- "</table></div>"
653
- ],
654
- "text/plain": [
655
- "<Table length=192864>\n",
656
- " ID RA DEC FLUX_G_1 ... flag_X_ray_s15 flag_IRAC_s15 STAR AGN \n",
657
- "int32 float64 float64 float64 ... int16 int16 int16 int16\n",
658
- "------ ---------- -------- -------- ... -------------- ------------- ----- -----\n",
659
- " 6 150.069244 1.624058 0.0 ... 0 0 0 0\n",
660
- " 7 149.988235 1.624047 0.0 ... 0 0 0 0\n",
661
- " 10 149.575302 1.62399 0.0 ... 0 0 0 0\n",
662
- " 11 149.549957 1.623974 0.0 ... 0 0 0 0\n",
663
- " 12 149.523422 1.623958 0.0 ... 0 0 0 0\n",
664
- " 15 149.737442 1.624018 0.0 ... 0 0 0 0\n",
665
- " 16 149.559097 1.623963 0.0 ... 0 0 0 0\n",
666
- " 17 149.992615 1.624071 0.0 ... 0 0 0 0\n",
667
- " 19 149.646317 1.62402 0.0 ... 0 0 0 0\n",
668
- " 22 149.604645 1.62402 0.0 ... 0 0 0 0\n",
669
- " ... ... ... ... ... ... ... ... ...\n",
670
- "391255 150.005234 2.735809 0.2727 ... 0 0 0 0\n",
671
- "391274 149.756409 2.737342 0.4296 ... 0 0 0 0\n",
672
- "391275 149.806961 2.736647 0.48 ... 0 0 0 0\n",
673
- "391276 150.061966 2.736018 0.1867 ... 0 0 0 0\n",
674
- "391281 150.111298 2.73576 4.851 ... 0 0 0 0\n",
675
- "391282 149.553146 2.735168 3.187 ... 0 0 0 0\n",
676
- "391284 150.061554 2.735742 1.076 ... 0 0 0 0\n",
677
- "391287 149.530014 2.735158 0.4498 ... 0 0 0 0\n",
678
- "391290 149.673889 2.73574 0.08647 ... 0 0 0 0\n",
679
- "391293 150.035202 2.737025 0.1009 ... 0 0 0 0"
680
- ]
681
- },
682
- "execution_count": 14,
683
- "metadata": {},
684
- "output_type": "execute_result"
685
- }
686
- ],
687
- "source": [
688
- "cat_valid_match_fitTable"
689
- ]
690
- },
691
- {
692
- "cell_type": "code",
693
- "execution_count": 12,
694
- "id": "7df1acba-15a2-4555-b2ae-6ce4ad55df4b",
695
- "metadata": {
696
- "tags": []
697
- },
698
- "outputs": [
699
- {
700
- "data": {
701
- "text/plain": [
702
- "array([ 0. , 3. , 9. , 1. , 4. , 20. , 9.5, 2. , -10. ,\n",
703
- " 22. , 21. , 2.5, 3.5, 3.1, 14. , 13.1, 10. , 1.1,\n",
704
- " 13. , 32. , 13.5, 1.5, 33. , 2.1, 4.5, 4.1, 14.5,\n",
705
- " 29. , 39. , 22.5], dtype=float32)"
706
- ]
707
- },
708
- "execution_count": 12,
709
- "metadata": {},
710
- "output_type": "execute_result"
711
- }
712
- ],
713
- "source": [
714
- "cat_calib[cat_calib.z_spec_S15>3].Q_f_S15.unique()"
715
- ]
716
- },
717
- {
718
- "cell_type": "code",
719
- "execution_count": 13,
720
- "id": "13ab99c4-0c15-46d2-8c57-27eeb1d6c762",
721
- "metadata": {
722
- "tags": []
723
- },
724
- "outputs": [
725
- {
726
- "data": {
727
- "text/plain": [
728
- "array([-99. , 2.5, 3.5, 4.5, 0. , 21.1, 4. , 1.5, 13.5,\n",
729
- " 1.1, 23.5, 9. , 3. , 24.4, 2. , 2.1, 4.1, 1. ,\n",
730
- " 9.5, 3.1, 23.1, 29.5, 4.4, 9.1, 22.4, 22.5, 2.4,\n",
731
- " 9.3, 24.5, 22.1, 20. , 14.5, 11.5, 6. , -10. , 22. ,\n",
732
- " 23. , 21. , 24. , 31. , 3.4, 1.4, -1. , 13.1, 18.1,\n",
733
- " 21.5, 29.4, 12.1, 39. , 14. , 23.4, 29. , 19. , 0.5,\n",
734
- " 12.5, 29.3, 10. , 13. , 24.1, 34. , 14.1, 32. , 21.4,\n",
735
- " 33. , 18.5, 29.1, 5. , 18.3, 11.1, 14.4, 12. , 9.4,\n",
736
- " 5.1], dtype=float32)"
737
- ]
738
- },
739
- "execution_count": 13,
740
- "metadata": {},
741
- "output_type": "execute_result"
742
- }
743
- ],
744
- "source": [
745
- "cat_calib.Q_f_S15.unique()"
746
- ]
747
- },
748
- {
749
- "cell_type": "code",
750
- "execution_count": 94,
751
- "id": "12c171b0-8465-47e0-b894-243837e02795",
752
- "metadata": {
753
- "tags": []
754
- },
755
- "outputs": [],
756
- "source": [
757
- "weight_dict={(-99,0.99):0,\n",
758
- " (1,1.99):0.5,\n",
759
- " (2,2.99):0.75,\n",
760
- " (3,4):1,\n",
761
- " (9,9.99):0.25,\n",
762
- " (10,10.99):0,\n",
763
- " (11,11.99):0.5,\n",
764
- " (12,12.99):0.75,\n",
765
- " (13,14):1,\n",
766
- " (14.01,40):0\n",
767
- " }"
768
- ]
769
- },
770
- {
771
- "cell_type": "code",
772
- "execution_count": 96,
773
- "id": "d3080023-1af2-46cb-8294-034d47d52a41",
774
- "metadata": {
775
- "tags": []
776
- },
777
- "outputs": [],
778
- "source": [
779
- "def map_weight(Qz):\n",
780
- " for key, value in weight_dict.items():\n",
781
- " if key[0] <= Qz <= key[1]:\n",
782
- " return value\n",
783
- " return None\n",
784
- "\n",
785
- "# Apply the function to create the 'wQz' column\n",
786
- "cat_calib['w_Q_f_S15'] = cat_calib['Q_f_S15'].apply(map_weight)\n"
787
- ]
788
- },
789
- {
790
- "cell_type": "code",
791
- "execution_count": 93,
792
- "id": "3367b799-da93-4710-b41e-55bb2a2d4059",
793
- "metadata": {
794
- "tags": []
795
- },
796
- "outputs": [
797
- {
798
- "data": {
799
- "text/html": [
800
- "<div>\n",
801
- "<style scoped>\n",
802
- " .dataframe tbody tr th:only-of-type {\n",
803
- " vertical-align: middle;\n",
804
- " }\n",
805
- "\n",
806
- " .dataframe tbody tr th {\n",
807
- " vertical-align: top;\n",
808
- " }\n",
809
- "\n",
810
- " .dataframe thead th {\n",
811
- " text-align: right;\n",
812
- " }\n",
813
- "</style>\n",
814
- "<table border=\"1\" class=\"dataframe\">\n",
815
- " <thead>\n",
816
- " <tr style=\"text-align: right;\">\n",
817
- " <th></th>\n",
818
- " <th>ID</th>\n",
819
- " <th>RA</th>\n",
820
- " <th>DEC</th>\n",
821
- " <th>FLUX_G_1</th>\n",
822
- " <th>FLUX_G_2</th>\n",
823
- " <th>FLUX_G_3</th>\n",
824
- " <th>FLUX_R_1</th>\n",
825
- " <th>FLUX_R_2</th>\n",
826
- " <th>FLUX_R_3</th>\n",
827
- " <th>FLUX_I_1</th>\n",
828
- " <th>...</th>\n",
829
- " <th>photo_z_L15</th>\n",
830
- " <th>z_spec_S15</th>\n",
831
- " <th>Q_f_S15</th>\n",
832
- " <th>Instr_S15</th>\n",
833
- " <th>reliable_S15</th>\n",
834
- " <th>flag_X_ray_s15</th>\n",
835
- " <th>flag_IRAC_s15</th>\n",
836
- " <th>STAR</th>\n",
837
- " <th>AGN</th>\n",
838
- " <th>wQz</th>\n",
839
- " </tr>\n",
840
- " </thead>\n",
841
- " <tbody>\n",
842
- " <tr>\n",
843
- " <th>0</th>\n",
844
- " <td>32</td>\n",
845
- " <td>-99.0</td>\n",
846
- " <td>-99.0</td>\n",
847
- " <td>0.27910</td>\n",
848
- " <td>0.26540</td>\n",
849
- " <td>-0.060160</td>\n",
850
- " <td>0.16420</td>\n",
851
- " <td>0.10770</td>\n",
852
- " <td>0.09359</td>\n",
853
- " <td>0.6225</td>\n",
854
- " <td>...</td>\n",
855
- " <td>2.095800</td>\n",
856
- " <td>-99.0</td>\n",
857
- " <td>-99.0</td>\n",
858
- " <td>-99</td>\n",
859
- " <td>-99</td>\n",
860
- " <td>0</td>\n",
861
- " <td>0</td>\n",
862
- " <td>0</td>\n",
863
- " <td>0</td>\n",
864
- " <td>NaN</td>\n",
865
- " </tr>\n",
866
- " <tr>\n",
867
- " <th>1</th>\n",
868
- " <td>36</td>\n",
869
- " <td>-99.0</td>\n",
870
- " <td>-99.0</td>\n",
871
- " <td>0.16160</td>\n",
872
- " <td>0.11760</td>\n",
873
- " <td>0.093950</td>\n",
874
- " <td>0.13680</td>\n",
875
- " <td>0.02803</td>\n",
876
- " <td>0.06321</td>\n",
877
- " <td>0.3125</td>\n",
878
- " <td>...</td>\n",
879
- " <td>0.138100</td>\n",
880
- " <td>-99.0</td>\n",
881
- " <td>-99.0</td>\n",
882
- " <td>-99</td>\n",
883
- " <td>-99</td>\n",
884
- " <td>0</td>\n",
885
- " <td>0</td>\n",
886
- " <td>0</td>\n",
887
- " <td>0</td>\n",
888
- " <td>NaN</td>\n",
889
- " </tr>\n",
890
- " <tr>\n",
891
- " <th>2</th>\n",
892
- " <td>38</td>\n",
893
- " <td>-99.0</td>\n",
894
- " <td>-99.0</td>\n",
895
- " <td>0.20970</td>\n",
896
- " <td>0.23170</td>\n",
897
- " <td>0.199000</td>\n",
898
- " <td>0.38770</td>\n",
899
- " <td>0.39770</td>\n",
900
- " <td>0.33170</td>\n",
901
- " <td>0.1775</td>\n",
902
- " <td>...</td>\n",
903
- " <td>1.080600</td>\n",
904
- " <td>-99.0</td>\n",
905
- " <td>-99.0</td>\n",
906
- " <td>-99</td>\n",
907
- " <td>-99</td>\n",
908
- " <td>0</td>\n",
909
- " <td>0</td>\n",
910
- " <td>0</td>\n",
911
- " <td>0</td>\n",
912
- " <td>NaN</td>\n",
913
- " </tr>\n",
914
- " <tr>\n",
915
- " <th>3</th>\n",
916
- " <td>39</td>\n",
917
- " <td>-99.0</td>\n",
918
- " <td>-99.0</td>\n",
919
- " <td>0.15680</td>\n",
920
- " <td>0.04144</td>\n",
921
- " <td>0.006729</td>\n",
922
- " <td>0.32470</td>\n",
923
- " <td>0.28490</td>\n",
924
- " <td>0.10140</td>\n",
925
- " <td>0.2689</td>\n",
926
- " <td>...</td>\n",
927
- " <td>-99.000000</td>\n",
928
- " <td>-99.0</td>\n",
929
- " <td>-99.0</td>\n",
930
- " <td>-99</td>\n",
931
- " <td>-99</td>\n",
932
- " <td>0</td>\n",
933
- " <td>0</td>\n",
934
- " <td>0</td>\n",
935
- " <td>0</td>\n",
936
- " <td>NaN</td>\n",
937
- " </tr>\n",
938
- " <tr>\n",
939
- " <th>4</th>\n",
940
- " <td>40</td>\n",
941
- " <td>-99.0</td>\n",
942
- " <td>-99.0</td>\n",
943
- " <td>0.29370</td>\n",
944
- " <td>0.36790</td>\n",
945
- " <td>0.381100</td>\n",
946
- " <td>0.59510</td>\n",
947
- " <td>0.48770</td>\n",
948
- " <td>0.55310</td>\n",
949
- " <td>0.2876</td>\n",
950
- " <td>...</td>\n",
951
- " <td>1.601600</td>\n",
952
- " <td>-99.0</td>\n",
953
- " <td>-99.0</td>\n",
954
- " <td>-99</td>\n",
955
- " <td>-99</td>\n",
956
- " <td>0</td>\n",
957
- " <td>0</td>\n",
958
- " <td>0</td>\n",
959
- " <td>0</td>\n",
960
- " <td>NaN</td>\n",
961
- " </tr>\n",
962
- " <tr>\n",
963
- " <th>...</th>\n",
964
- " <td>...</td>\n",
965
- " <td>...</td>\n",
966
- " <td>...</td>\n",
967
- " <td>...</td>\n",
968
- " <td>...</td>\n",
969
- " <td>...</td>\n",
970
- " <td>...</td>\n",
971
- " <td>...</td>\n",
972
- " <td>...</td>\n",
973
- " <td>...</td>\n",
974
- " <td>...</td>\n",
975
- " <td>...</td>\n",
976
- " <td>...</td>\n",
977
- " <td>...</td>\n",
978
- " <td>...</td>\n",
979
- " <td>...</td>\n",
980
- " <td>...</td>\n",
981
- " <td>...</td>\n",
982
- " <td>...</td>\n",
983
- " <td>...</td>\n",
984
- " <td>...</td>\n",
985
- " </tr>\n",
986
- " <tr>\n",
987
- " <th>190681</th>\n",
988
- " <td>197465</td>\n",
989
- " <td>-99.0</td>\n",
990
- " <td>-99.0</td>\n",
991
- " <td>0.23410</td>\n",
992
- " <td>0.11830</td>\n",
993
- " <td>0.060100</td>\n",
994
- " <td>0.14460</td>\n",
995
- " <td>0.24370</td>\n",
996
- " <td>0.46160</td>\n",
997
- " <td>0.2579</td>\n",
998
- " <td>...</td>\n",
999
- " <td>-99.900002</td>\n",
1000
- " <td>-99.0</td>\n",
1001
- " <td>-99.0</td>\n",
1002
- " <td>-99</td>\n",
1003
- " <td>-99</td>\n",
1004
- " <td>0</td>\n",
1005
- " <td>0</td>\n",
1006
- " <td>0</td>\n",
1007
- " <td>0</td>\n",
1008
- " <td>NaN</td>\n",
1009
- " </tr>\n",
1010
- " <tr>\n",
1011
- " <th>190682</th>\n",
1012
- " <td>197479</td>\n",
1013
- " <td>-99.0</td>\n",
1014
- " <td>-99.0</td>\n",
1015
- " <td>0.04739</td>\n",
1016
- " <td>0.04522</td>\n",
1017
- " <td>0.036710</td>\n",
1018
- " <td>0.17800</td>\n",
1019
- " <td>0.16930</td>\n",
1020
- " <td>0.10800</td>\n",
1021
- " <td>0.3385</td>\n",
1022
- " <td>...</td>\n",
1023
- " <td>-99.000000</td>\n",
1024
- " <td>-99.0</td>\n",
1025
- " <td>-99.0</td>\n",
1026
- " <td>-99</td>\n",
1027
- " <td>-99</td>\n",
1028
- " <td>0</td>\n",
1029
- " <td>0</td>\n",
1030
- " <td>0</td>\n",
1031
- " <td>0</td>\n",
1032
- " <td>NaN</td>\n",
1033
- " </tr>\n",
1034
- " <tr>\n",
1035
- " <th>190683</th>\n",
1036
- " <td>197490</td>\n",
1037
- " <td>-99.0</td>\n",
1038
- " <td>-99.0</td>\n",
1039
- " <td>4.81900</td>\n",
1040
- " <td>4.76700</td>\n",
1041
- " <td>4.774000</td>\n",
1042
- " <td>12.73000</td>\n",
1043
- " <td>12.71000</td>\n",
1044
- " <td>12.67000</td>\n",
1045
- " <td>20.5300</td>\n",
1046
- " <td>...</td>\n",
1047
- " <td>-99.900002</td>\n",
1048
- " <td>-99.0</td>\n",
1049
- " <td>-99.0</td>\n",
1050
- " <td>-99</td>\n",
1051
- " <td>-99</td>\n",
1052
- " <td>0</td>\n",
1053
- " <td>0</td>\n",
1054
- " <td>0</td>\n",
1055
- " <td>0</td>\n",
1056
- " <td>NaN</td>\n",
1057
- " </tr>\n",
1058
- " <tr>\n",
1059
- " <th>190684</th>\n",
1060
- " <td>197492</td>\n",
1061
- " <td>-99.0</td>\n",
1062
- " <td>-99.0</td>\n",
1063
- " <td>-0.16100</td>\n",
1064
- " <td>-0.48150</td>\n",
1065
- " <td>-0.490300</td>\n",
1066
- " <td>0.29440</td>\n",
1067
- " <td>-0.63920</td>\n",
1068
- " <td>-0.05621</td>\n",
1069
- " <td>-1.5310</td>\n",
1070
- " <td>...</td>\n",
1071
- " <td>-99.000000</td>\n",
1072
- " <td>-99.0</td>\n",
1073
- " <td>-99.0</td>\n",
1074
- " <td>-99</td>\n",
1075
- " <td>-99</td>\n",
1076
- " <td>0</td>\n",
1077
- " <td>0</td>\n",
1078
- " <td>0</td>\n",
1079
- " <td>0</td>\n",
1080
- " <td>NaN</td>\n",
1081
- " </tr>\n",
1082
- " <tr>\n",
1083
- " <th>190685</th>\n",
1084
- " <td>197497</td>\n",
1085
- " <td>-99.0</td>\n",
1086
- " <td>-99.0</td>\n",
1087
- " <td>0.10890</td>\n",
1088
- " <td>0.07218</td>\n",
1089
- " <td>0.086700</td>\n",
1090
- " <td>0.00439</td>\n",
1091
- " <td>0.06940</td>\n",
1092
- " <td>0.07060</td>\n",
1093
- " <td>0.3944</td>\n",
1094
- " <td>...</td>\n",
1095
- " <td>-99.900002</td>\n",
1096
- " <td>-99.0</td>\n",
1097
- " <td>-99.0</td>\n",
1098
- " <td>-99</td>\n",
1099
- " <td>-99</td>\n",
1100
- " <td>0</td>\n",
1101
- " <td>0</td>\n",
1102
- " <td>0</td>\n",
1103
- " <td>0</td>\n",
1104
- " <td>NaN</td>\n",
1105
- " </tr>\n",
1106
- " </tbody>\n",
1107
- "</table>\n",
1108
- "<p>190686 rows × 124 columns</p>\n",
1109
- "</div>"
1110
- ],
1111
- "text/plain": [
1112
- " ID RA DEC FLUX_G_1 FLUX_G_2 FLUX_G_3 FLUX_R_1 FLUX_R_2 \\\n",
1113
- "0 32 -99.0 -99.0 0.27910 0.26540 -0.060160 0.16420 0.10770 \n",
1114
- "1 36 -99.0 -99.0 0.16160 0.11760 0.093950 0.13680 0.02803 \n",
1115
- "2 38 -99.0 -99.0 0.20970 0.23170 0.199000 0.38770 0.39770 \n",
1116
- "3 39 -99.0 -99.0 0.15680 0.04144 0.006729 0.32470 0.28490 \n",
1117
- "4 40 -99.0 -99.0 0.29370 0.36790 0.381100 0.59510 0.48770 \n",
1118
- "... ... ... ... ... ... ... ... ... \n",
1119
- "190681 197465 -99.0 -99.0 0.23410 0.11830 0.060100 0.14460 0.24370 \n",
1120
- "190682 197479 -99.0 -99.0 0.04739 0.04522 0.036710 0.17800 0.16930 \n",
1121
- "190683 197490 -99.0 -99.0 4.81900 4.76700 4.774000 12.73000 12.71000 \n",
1122
- "190684 197492 -99.0 -99.0 -0.16100 -0.48150 -0.490300 0.29440 -0.63920 \n",
1123
- "190685 197497 -99.0 -99.0 0.10890 0.07218 0.086700 0.00439 0.06940 \n",
1124
- "\n",
1125
- " FLUX_R_3 FLUX_I_1 ... photo_z_L15 z_spec_S15 Q_f_S15 Instr_S15 \\\n",
1126
- "0 0.09359 0.6225 ... 2.095800 -99.0 -99.0 -99 \n",
1127
- "1 0.06321 0.3125 ... 0.138100 -99.0 -99.0 -99 \n",
1128
- "2 0.33170 0.1775 ... 1.080600 -99.0 -99.0 -99 \n",
1129
- "3 0.10140 0.2689 ... -99.000000 -99.0 -99.0 -99 \n",
1130
- "4 0.55310 0.2876 ... 1.601600 -99.0 -99.0 -99 \n",
1131
- "... ... ... ... ... ... ... ... \n",
1132
- "190681 0.46160 0.2579 ... -99.900002 -99.0 -99.0 -99 \n",
1133
- "190682 0.10800 0.3385 ... -99.000000 -99.0 -99.0 -99 \n",
1134
- "190683 12.67000 20.5300 ... -99.900002 -99.0 -99.0 -99 \n",
1135
- "190684 -0.05621 -1.5310 ... -99.000000 -99.0 -99.0 -99 \n",
1136
- "190685 0.07060 0.3944 ... -99.900002 -99.0 -99.0 -99 \n",
1137
- "\n",
1138
- " reliable_S15 flag_X_ray_s15 flag_IRAC_s15 STAR AGN wQz \n",
1139
- "0 -99 0 0 0 0 NaN \n",
1140
- "1 -99 0 0 0 0 NaN \n",
1141
- "2 -99 0 0 0 0 NaN \n",
1142
- "3 -99 0 0 0 0 NaN \n",
1143
- "4 -99 0 0 0 0 NaN \n",
1144
- "... ... ... ... ... ... ... \n",
1145
- "190681 -99 0 0 0 0 NaN \n",
1146
- "190682 -99 0 0 0 0 NaN \n",
1147
- "190683 -99 0 0 0 0 NaN \n",
1148
- "190684 -99 0 0 0 0 NaN \n",
1149
- "190685 -99 0 0 0 0 NaN \n",
1150
- "\n",
1151
- "[190686 rows x 124 columns]"
1152
- ]
1153
- },
1154
- "execution_count": 93,
1155
- "metadata": {},
1156
- "output_type": "execute_result"
1157
- }
1158
- ],
1159
- "source": [
1160
- "cat_calib"
1161
- ]
1162
- },
1163
- {
1164
- "cell_type": "code",
1165
- "execution_count": null,
1166
- "id": "968017d9-c4d7-4891-b74a-4422ee7bb73c",
1167
- "metadata": {},
1168
- "outputs": [],
1169
- "source": []
1170
- }
1171
- ],
1172
- "metadata": {
1173
- "kernelspec": {
1174
- "display_name": "insight",
1175
- "language": "python",
1176
- "name": "insight"
1177
- },
1178
- "language_info": {
1179
- "codemirror_mode": {
1180
- "name": "ipython",
1181
- "version": 3
1182
- },
1183
- "file_extension": ".py",
1184
- "mimetype": "text/x-python",
1185
- "name": "python",
1186
- "nbconvert_exporter": "python",
1187
- "pygments_lexer": "ipython3",
1188
- "version": "3.10.13"
1189
- }
1190
- },
1191
- "nbformat": 4,
1192
- "nbformat_minor": 5
1193
- }