ExoIris 0.17.0__py3-none-any.whl → 0.18.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {ExoIris-0.17.0.dist-info → ExoIris-0.18.0.dist-info}/METADATA +1 -1
- ExoIris-0.18.0.dist-info/RECORD +15 -0
- exoiris/exoiris.py +88 -103
- exoiris/tsdata.py +51 -13
- exoiris/tslpf.py +21 -4
- exoiris/wlpf.py +1 -1
- ExoIris-0.17.0.dist-info/RECORD +0 -15
- {ExoIris-0.17.0.dist-info → ExoIris-0.18.0.dist-info}/LICENSE +0 -0
- {ExoIris-0.17.0.dist-info → ExoIris-0.18.0.dist-info}/WHEEL +0 -0
- {ExoIris-0.17.0.dist-info → ExoIris-0.18.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
exoiris/__init__.py,sha256=gaNfxNKXH41yRK35JghqackXpENyB-NOg-JlciqO1YU,1145
|
|
2
|
+
exoiris/binning.py,sha256=-Y9hdK0jZj8DOS82keaprneid2lZ4rCx-keWlKi0LP8,6455
|
|
3
|
+
exoiris/ephemeris.py,sha256=dthBkJztT5yAP6VnnO7jGvxikboFUQBUGPUfBCFrA3w,1316
|
|
4
|
+
exoiris/exoiris.py,sha256=UgwujRngsk-VNXi8DnDQ2z9-v5_E8_eC2_uaE_pYe0k,47974
|
|
5
|
+
exoiris/ldtkld.py,sha256=u4c5Yh6JlG0Zfec7-nOCQGXxIt1VVp9mniFMM7h-L6s,3489
|
|
6
|
+
exoiris/tsdata.py,sha256=c1HLbVBR_Ib291NPAi4gaD44NLtXHcmlRRwIO_mD7Fw,33254
|
|
7
|
+
exoiris/tslpf.py,sha256=7qrVm_HDeiwgPFdu2GsGdS2f7H13hPc5hrVpVPN9Xc8,28581
|
|
8
|
+
exoiris/tsmodel.py,sha256=6NaGY48fWHUT_7ti6Ao618PN-LgyoIhfQd8lZQqZ7hU,5160
|
|
9
|
+
exoiris/util.py,sha256=5PynwYYHRrzyXJHskBtp2J-pcM59zsA1_VtDxencQm4,4630
|
|
10
|
+
exoiris/wlpf.py,sha256=8VB5ChEbtS8398QctIxbwtDInLoLEkr4yoRkSniEnwA,4537
|
|
11
|
+
ExoIris-0.18.0.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
12
|
+
ExoIris-0.18.0.dist-info/METADATA,sha256=P1UH_KJ4kEvToWhzHRMFhkMUhXikCu1HDF2DWB48rUk,4189
|
|
13
|
+
ExoIris-0.18.0.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
|
14
|
+
ExoIris-0.18.0.dist-info/top_level.txt,sha256=EoNxT6c5mQDcM0f_LUQB-ETsYg03lNaV3o2L_Yc6-aE,8
|
|
15
|
+
ExoIris-0.18.0.dist-info/RECORD,,
|
exoiris/exoiris.py
CHANGED
|
@@ -33,7 +33,8 @@ from celerite2 import GaussianProcess, terms
|
|
|
33
33
|
from emcee import EnsembleSampler
|
|
34
34
|
from matplotlib.pyplot import subplots, setp, figure, Figure, Axes
|
|
35
35
|
from numpy import (where, sqrt, clip, percentile, median, squeeze, floor, ndarray,
|
|
36
|
-
array, inf, newaxis, arange, tile, sort, argsort, concatenate, full, nan, r_, nanpercentile
|
|
36
|
+
array, inf, newaxis, arange, tile, sort, argsort, concatenate, full, nan, r_, nanpercentile, log10,
|
|
37
|
+
ceil)
|
|
37
38
|
from numpy.random import normal, permutation
|
|
38
39
|
from pytransit import UniformPrior, NormalPrior
|
|
39
40
|
from pytransit.orbits import epoch
|
|
@@ -555,6 +556,22 @@ class ExoIris:
|
|
|
555
556
|
"""
|
|
556
557
|
return self._wa.plot(axs=axs, figsize=figsize, ncols=ncols or min(self.data.size, 2))
|
|
557
558
|
|
|
559
|
+
def plot_white_gp_predictions(self, axs = None, ncol: int = 1, figsize: tuple[float, float] | None = None):
|
|
560
|
+
ndata = self.data.size
|
|
561
|
+
|
|
562
|
+
if axs is None:
|
|
563
|
+
nrow = int(ceil(ndata / ncol))
|
|
564
|
+
fig, axs = subplots(nrow, ncol, sharey='all', constrained_layout=True, squeeze=False, figsize=figsize)
|
|
565
|
+
else:
|
|
566
|
+
fig = axs[0].axes
|
|
567
|
+
|
|
568
|
+
for i in range(ndata):
|
|
569
|
+
tref = floor(self.white_times[i][0])
|
|
570
|
+
axs.flat[i].plot(self.white_times[i] - tref, self.white_fluxes[i]-self.white_models[i])
|
|
571
|
+
axs.flat[i].plot(self.white_times[i] - tref, self.white_gp_models[i], 'k')
|
|
572
|
+
setp(axs.flat[i], xlabel=f'Time - {tref:.0f} [d]', xlim=self.white_times[i][[0,-1]]-tref)
|
|
573
|
+
setp(axs[:, 0], ylabel='Residuals')
|
|
574
|
+
|
|
558
575
|
def normalize_baseline(self, deg: int = 1) -> None:
|
|
559
576
|
"""Normalize the baseline flux for each spectroscopic light curve.
|
|
560
577
|
|
|
@@ -1120,87 +1137,15 @@ class ExoIris:
|
|
|
1120
1137
|
pvp = self._tsa._mc_chains[:, -1, :] = pvp
|
|
1121
1138
|
|
|
1122
1139
|
def optimize_gp_hyperparameters(self,
|
|
1123
|
-
log10_sigma_bounds: float | tuple[float, float] =
|
|
1140
|
+
log10_sigma_bounds: float | tuple[float, float] | None = None,
|
|
1124
1141
|
log10_rho_bounds: float | tuple[float, float] = (-5, 0),
|
|
1125
1142
|
log10_sigma_prior=None, log10_rho_prior=None,
|
|
1126
|
-
npop: int = 10, niter: int = 100
|
|
1127
|
-
"""Optimize the Matern-3/2 kernel Gaussian Process hyperparameters.
|
|
1128
|
-
|
|
1129
|
-
Parameters
|
|
1130
|
-
----------
|
|
1131
|
-
log10_sigma_bounds
|
|
1132
|
-
The bounds for the log10 of the sigma hyperparameter. If float is provided, the parameter will be
|
|
1133
|
-
fixed to the given value. Default is (-5, -2).
|
|
1134
|
-
log10_rho_bounds
|
|
1135
|
-
The bounds for the log10 of the rho hyperparameter. If float is provided, the parameter will be fixed
|
|
1136
|
-
to the given value. Default is (-5, 0).
|
|
1137
|
-
log10_sigma_prior
|
|
1138
|
-
The prior distribution for the sigma hyperparameter expressed as an object with a `logpdf` method
|
|
1139
|
-
or as an iterable containing the mean and standard deviation of the prior distribution. Default is None.
|
|
1140
|
-
log10_rho_prior
|
|
1141
|
-
The prior distribution for the rho hyperparameter expressed as an object with a `logpdf` method
|
|
1142
|
-
or as an iterable containing the mean and standard deviation of the prior distribution. Default is None.
|
|
1143
|
-
npop
|
|
1144
|
-
The population size for the differential evolution optimizer. Default is 10.
|
|
1145
|
-
niter
|
|
1146
|
-
The number of iterations for the differential evolution optimization process. Default is 100.
|
|
1147
|
-
subset
|
|
1148
|
-
The subset used for the optimization process. If `subset` is a float, a random subset of size
|
|
1149
|
-
`0.5 * self.npb` is used. If `subset` is an iterable, it must contain the indices of the subset.
|
|
1150
|
-
Default is None.
|
|
1151
|
-
|
|
1152
|
-
Returns
|
|
1153
|
-
-------
|
|
1154
|
-
tuple[float, float]
|
|
1155
|
-
The optimized values for the log10 of the sigma and rho hyperparameters.
|
|
1156
|
-
float
|
|
1157
|
-
The fitness value.
|
|
1158
|
-
|
|
1159
|
-
Raises
|
|
1160
|
-
------
|
|
1161
|
-
ValueError
|
|
1162
|
-
If `subset` is not an iterable or a float.
|
|
1163
|
-
ValueError
|
|
1164
|
-
If `log10_sigma_prior` is not an object with a `logpdf` method or iterable.
|
|
1165
|
-
ValueError
|
|
1166
|
-
If `log10_rho_prior` is not an object with a `logpdf` method or iterable.
|
|
1167
|
-
|
|
1168
|
-
Notes
|
|
1169
|
-
-----
|
|
1170
|
-
- The Gaussian Process is reconfigured with the optimal hyperparameters. Any previous kernels are overwritten.
|
|
1171
|
-
"""
|
|
1172
|
-
|
|
1143
|
+
npop: int = 10, niter: int = 100):
|
|
1173
1144
|
if self._tsa.noise_model != 'fixed_gp':
|
|
1174
1145
|
raise ValueError("The noise model must be set to 'fixed_gp' before the hyperparameter optimization.")
|
|
1175
1146
|
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
bounds = array([sb, rb])
|
|
1179
|
-
|
|
1180
|
-
data = self.data[0]
|
|
1181
|
-
if subset is not None:
|
|
1182
|
-
if isinstance(subset, float):
|
|
1183
|
-
ids = sort(permutation(data.nwl)[:int(subset*data.nwl)])
|
|
1184
|
-
elif isinstance(subset, Sequence):
|
|
1185
|
-
ids = array(subset, int)
|
|
1186
|
-
else:
|
|
1187
|
-
raise ValueError("subset must be either an iterable or a float.")
|
|
1188
|
-
else:
|
|
1189
|
-
ids = arange(data.nwl)
|
|
1190
|
-
|
|
1191
|
-
class DummyPrior:
|
|
1192
|
-
def logpdf(self, x):
|
|
1193
|
-
return 0.0
|
|
1194
|
-
|
|
1195
|
-
if log10_sigma_prior is not None:
|
|
1196
|
-
if isinstance(log10_sigma_prior, Sequence):
|
|
1197
|
-
sp = norm(*log10_sigma_prior)
|
|
1198
|
-
elif hasattr(log10_sigma_prior, 'logpdf'):
|
|
1199
|
-
sp = log10_sigma_prior
|
|
1200
|
-
else:
|
|
1201
|
-
raise ValueError('Bad sigma_prior')
|
|
1202
|
-
else:
|
|
1203
|
-
sp = DummyPrior()
|
|
1147
|
+
if self._wa is None:
|
|
1148
|
+
raise ValueError("The white light curves must be fit using 'fit_white()' before the hyperparameter optimization.")
|
|
1204
1149
|
|
|
1205
1150
|
if log10_rho_prior is not None:
|
|
1206
1151
|
if isinstance(log10_rho_prior, Sequence):
|
|
@@ -1210,29 +1155,69 @@ class ExoIris:
|
|
|
1210
1155
|
else:
|
|
1211
1156
|
raise ValueError('Bad rho_prior')
|
|
1212
1157
|
else:
|
|
1213
|
-
rp =
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1158
|
+
rp = norm(-2, 1)
|
|
1159
|
+
|
|
1160
|
+
times = self.white_times
|
|
1161
|
+
errors = self.white_errors
|
|
1162
|
+
residuals = [o-m for o,m in zip(self.white_fluxes, self.white_models)]
|
|
1163
|
+
self.white_gp_models = []
|
|
1164
|
+
|
|
1165
|
+
gp_hyperparameters = []
|
|
1166
|
+
for i in range(len(times)):
|
|
1167
|
+
time = times[i]
|
|
1168
|
+
fres = residuals[i]
|
|
1169
|
+
ferr = errors[i]
|
|
1170
|
+
|
|
1171
|
+
log10_sigma_guess = log10(fres.std())
|
|
1172
|
+
|
|
1173
|
+
match log10_sigma_bounds:
|
|
1174
|
+
case None:
|
|
1175
|
+
sb = [log10_sigma_guess-1, log10_sigma_guess+1]
|
|
1176
|
+
case _ if isinstance(log10_sigma_bounds, Sequence):
|
|
1177
|
+
sb = log10_sigma_bounds
|
|
1178
|
+
case _ if isinstance(log10_sigma_bounds, float):
|
|
1179
|
+
sb = [log10_sigma_bounds-1, log10_sigma_bounds+1]
|
|
1180
|
+
|
|
1181
|
+
match log10_rho_bounds:
|
|
1182
|
+
case None:
|
|
1183
|
+
rb = [-5, -2]
|
|
1184
|
+
case _ if isinstance(log10_rho_bounds, Sequence):
|
|
1185
|
+
rb = log10_rho_bounds
|
|
1186
|
+
case _ if isinstance(log10_rho_bounds, float):
|
|
1187
|
+
rb = [log10_rho_bounds-1, log10_rho_bounds+1]
|
|
1188
|
+
|
|
1189
|
+
bounds = array([sb, rb])
|
|
1190
|
+
|
|
1191
|
+
if log10_sigma_prior is not None:
|
|
1192
|
+
if isinstance(log10_sigma_prior, Sequence):
|
|
1193
|
+
sp = norm(*log10_sigma_prior)
|
|
1194
|
+
elif hasattr(log10_sigma_prior, 'logpdf'):
|
|
1195
|
+
sp = log10_sigma_prior
|
|
1196
|
+
else:
|
|
1197
|
+
raise ValueError('Bad sigma_prior')
|
|
1198
|
+
else:
|
|
1199
|
+
sp = norm(log10_sigma_guess, 0.1)
|
|
1200
|
+
|
|
1201
|
+
gp = GaussianProcess(terms.Matern32Term(sigma=fres.std(), rho=0.1))
|
|
1202
|
+
|
|
1203
|
+
def nll(log10x):
|
|
1204
|
+
x = 10**log10x
|
|
1205
|
+
if any(log10x < bounds[:,0]) or any(log10x > bounds[:,1]):
|
|
1206
|
+
return inf
|
|
1207
|
+
gp.kernel = terms.Matern32Term(sigma=x[0], rho=x[1])
|
|
1208
|
+
gp.compute(time, yerr=ferr, quiet=True)
|
|
1209
|
+
return -(gp.log_likelihood(fres) + sp.logpdf(log10x[0]) + rp.logpdf(log10x[1]))
|
|
1210
|
+
|
|
1211
|
+
de = DiffEvol(nll, bounds, npop, min_ptp=0.2)
|
|
1212
|
+
if isinstance(log10_sigma_bounds, float):
|
|
1213
|
+
de.population[:, 0] = log10_sigma_bounds
|
|
1214
|
+
if isinstance(log10_rho_bounds, float):
|
|
1215
|
+
de.population[:, 1] = log10_rho_bounds
|
|
1216
|
+
|
|
1217
|
+
de.optimize(niter)
|
|
1218
|
+
x = de.minimum_location
|
|
1219
|
+
gp_hyperparameters.append(10**x)
|
|
1220
|
+
gp.kernel = terms.Matern32Term(sigma=10**x[0], rho=10**x[1])
|
|
1221
|
+
self.white_gp_models.append(gp.predict(fres))
|
|
1222
|
+
self._tsa.set_gp_hyperparameters(10**x[0], 10**x[1], i)
|
|
1223
|
+
return gp_hyperparameters
|
exoiris/tsdata.py
CHANGED
|
@@ -47,7 +47,7 @@ class TSData:
|
|
|
47
47
|
def __init__(self, time: Sequence, wavelength: Sequence, fluxes: Sequence, errors: Sequence, name: str,
|
|
48
48
|
noise_group: str = 'a', wl_edges : Sequence | None = None, tm_edges : Sequence | None = None,
|
|
49
49
|
transit_mask: ndarray | None = None, ephemeris: Ephemeris | None = None, n_baseline: int = 1,
|
|
50
|
-
mask: ndarray = None) -> None:
|
|
50
|
+
mask: ndarray = None, ephemeris_group: int = 0, offset_group: int = 0) -> None:
|
|
51
51
|
"""
|
|
52
52
|
Parameters
|
|
53
53
|
----------
|
|
@@ -81,6 +81,12 @@ class TSData:
|
|
|
81
81
|
if n_baseline < 1:
|
|
82
82
|
raise ValueError("n_baseline must be greater than zero.")
|
|
83
83
|
|
|
84
|
+
if ephemeris_group < 0:
|
|
85
|
+
raise ValueError("ephemeris_group must be a non-negative integer.")
|
|
86
|
+
|
|
87
|
+
if offset_group < 0:
|
|
88
|
+
raise ValueError("offset_group must be a non-negative integer.")
|
|
89
|
+
|
|
84
90
|
self.name: str = name
|
|
85
91
|
self.time: ndarray = time.copy()
|
|
86
92
|
self.wavelength: ndarray = wavelength
|
|
@@ -92,6 +98,8 @@ class TSData:
|
|
|
92
98
|
self.ephemeris: Ephemeris | None = ephemeris
|
|
93
99
|
self.n_baseline: int = n_baseline
|
|
94
100
|
self._noise_group: str = noise_group
|
|
101
|
+
self.ephemeris_group: int = ephemeris_group
|
|
102
|
+
self.offset_group: int = offset_group
|
|
95
103
|
self._dataset: Optional['TSDataSet'] = None
|
|
96
104
|
self._update()
|
|
97
105
|
|
|
@@ -129,6 +137,8 @@ class TSData:
|
|
|
129
137
|
mask = pf.ImageHDU(self.mask.astype(int), name=f'mask_{self.name}')
|
|
130
138
|
data.header['ngroup'] = self.noise_group
|
|
131
139
|
data.header['nbasel'] = self.n_baseline
|
|
140
|
+
data.header['epgroup'] = self.ephemeris_group
|
|
141
|
+
data.header['offgroup'] = self.offset_group
|
|
132
142
|
#TODO: export ephemeris
|
|
133
143
|
return pf.HDUList([time, wave, data, ootm, mask])
|
|
134
144
|
|
|
@@ -153,6 +163,8 @@ class TSData:
|
|
|
153
163
|
ootm = hdul[f'OOTM_{name}'].data.astype(bool)
|
|
154
164
|
mask = hdul[f'MASK_{name}'].data.astype(bool)
|
|
155
165
|
noise_group = hdul[f'DATA_{name}'].header['NGROUP']
|
|
166
|
+
ephemeris_group = hdul[f'DATA_{name}'].header['EPGROUP']
|
|
167
|
+
offset_group = hdul[f'DATA_{name}'].header['OFFGROUP']
|
|
156
168
|
|
|
157
169
|
try:
|
|
158
170
|
n_baseline = hdul[f'DATA_{name}'].header['NBASEL']
|
|
@@ -161,7 +173,7 @@ class TSData:
|
|
|
161
173
|
|
|
162
174
|
#TODO: import ephemeris
|
|
163
175
|
return TSData(time, wave, data[0], data[1], name=name, noise_group=noise_group, transit_mask=ootm,
|
|
164
|
-
n_baseline=n_baseline, mask=mask)
|
|
176
|
+
n_baseline=n_baseline, mask=mask, ephemeris_group=ephemeris_group, offset_group=offset_group)
|
|
165
177
|
|
|
166
178
|
def __repr__(self) -> str:
|
|
167
179
|
return f"TSData Name:'{self.name}' [{self.wavelength[0]:.2f} - {self.wavelength[-1]:.2f}] nwl={self.nwl} npt={self.npt}"
|
|
@@ -286,13 +298,20 @@ class TSData:
|
|
|
286
298
|
m = masks[0]
|
|
287
299
|
d = TSData(name=f'{self.name}_1', time=self.time[m], wavelength=self.wavelength,
|
|
288
300
|
fluxes=self.fluxes[:, m], errors=self.errors[:, m], mask=self.mask[:, m],
|
|
289
|
-
noise_group=self.noise_group,
|
|
290
|
-
|
|
301
|
+
noise_group=self.noise_group,
|
|
302
|
+
ephemeris_group=self.ephemeris_group,
|
|
303
|
+
offset_group=self.offset_group,
|
|
304
|
+
transit_mask=self.transit_mask[m],
|
|
305
|
+
ephemeris=self.ephemeris,
|
|
306
|
+
n_baseline=self.n_baseline)
|
|
291
307
|
for i, m in enumerate(masks[1:]):
|
|
292
308
|
d = d + TSData(name=f'{self.name}_{i+2}', time=self.time[m], wavelength=self.wavelength,
|
|
293
309
|
fluxes=self.fluxes[:, m], errors=self.errors[:, m], mask=self.mask[:, m],
|
|
294
310
|
noise_group=self.noise_group,
|
|
295
|
-
|
|
311
|
+
ephemeris_group=self.ephemeris_group,
|
|
312
|
+
offset_group=self.offset_group,
|
|
313
|
+
transit_mask=self.transit_mask[m],
|
|
314
|
+
ephemeris=self.ephemeris,
|
|
296
315
|
n_baseline=self.n_baseline)
|
|
297
316
|
return d
|
|
298
317
|
|
|
@@ -325,6 +344,8 @@ class TSData:
|
|
|
325
344
|
errors=self.errors[m],
|
|
326
345
|
mask=self.mask[m],
|
|
327
346
|
noise_group=self.noise_group,
|
|
347
|
+
ephemeris_group=self.ephemeris_group,
|
|
348
|
+
offset_group=self.offset_group,
|
|
328
349
|
wl_edges=(self._wl_l_edges[m], self._wl_r_edges[m]),
|
|
329
350
|
tm_edges=(self._tm_l_edges, self._tm_r_edges),
|
|
330
351
|
transit_mask=self.transit_mask, ephemeris=self.ephemeris,
|
|
@@ -360,6 +381,8 @@ class TSData:
|
|
|
360
381
|
errors=self.errors[:, m],
|
|
361
382
|
mask = self.mask[:, m],
|
|
362
383
|
noise_group=self.noise_group,
|
|
384
|
+
ephemeris_group=self.ephemeris_group,
|
|
385
|
+
offset_group=self.offset_group,
|
|
363
386
|
wl_edges=(self._wl_l_edges, self._wl_r_edges),
|
|
364
387
|
tm_edges=(self._tm_l_edges[m], self._tm_r_edges[m]),
|
|
365
388
|
transit_mask=self.transit_mask[m], ephemeris=self.ephemeris,
|
|
@@ -574,10 +597,16 @@ class TSData:
|
|
|
574
597
|
binning.bins, estimate_errors=estimate_errors)
|
|
575
598
|
if not all(isfinite(be)):
|
|
576
599
|
warnings.warn('Error estimation failed for some bins, check the error array.')
|
|
577
|
-
return TSData(self.time, binning.bins.mean(1), bf, be,
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
600
|
+
return TSData(self.time, binning.bins.mean(1), bf, be,
|
|
601
|
+
wl_edges=(binning.bins[:,0], binning.bins[:,1]),
|
|
602
|
+
name=self.name,
|
|
603
|
+
tm_edges=(self._tm_l_edges, self._tm_r_edges),
|
|
604
|
+
noise_group=self.noise_group,
|
|
605
|
+
ephemeris_group=self.ephemeris_group,
|
|
606
|
+
offset_group=self.offset_group,
|
|
607
|
+
transit_mask=self.transit_mask,
|
|
608
|
+
ephemeris=self.ephemeris,
|
|
609
|
+
n_baseline=self.n_baseline)
|
|
581
610
|
|
|
582
611
|
def bin_time(self, binning: Optional[Union[Binning, CompoundBinning]] = None,
|
|
583
612
|
nb: Optional[int] = None, bw: Optional[float] = None,
|
|
@@ -609,10 +638,14 @@ class TSData:
|
|
|
609
638
|
bf, be = bin2d(self.fluxes.T, self.errors.T, self._tm_l_edges, self._tm_r_edges,
|
|
610
639
|
binning.bins, estimate_errors=estimate_errors)
|
|
611
640
|
d = TSData(binning.bins.mean(1), self.wavelength, bf.T, be.T,
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
641
|
+
wl_edges=(self._wl_l_edges, self._wl_r_edges),
|
|
642
|
+
tm_edges=(binning.bins[:,0], binning.bins[:,1]),
|
|
643
|
+
name=self.name,
|
|
644
|
+
noise_group=self.noise_group,
|
|
645
|
+
ephemeris=self.ephemeris,
|
|
646
|
+
n_baseline=self.n_baseline,
|
|
647
|
+
ephemeris_group=self.ephemeris_group,
|
|
648
|
+
offset_group=self.offset_group)
|
|
616
649
|
if self.ephemeris is not None:
|
|
617
650
|
d.mask_transit(ephemeris=self.ephemeris)
|
|
618
651
|
return d
|
|
@@ -683,6 +716,11 @@ class TSDataSet:
|
|
|
683
716
|
"""Number of noise groups."""
|
|
684
717
|
return len(set(self.noise_groups))
|
|
685
718
|
|
|
719
|
+
@property
|
|
720
|
+
def offset_groups(self) -> list[int]:
|
|
721
|
+
"""List of offset groups."""
|
|
722
|
+
return [d.offset_group for d in self.data]
|
|
723
|
+
|
|
686
724
|
@property
|
|
687
725
|
def n_baselines(self) -> list[int]:
|
|
688
726
|
"""Number of baseline coefficients for each data set."""
|
exoiris/tslpf.py
CHANGED
|
@@ -207,6 +207,7 @@ class TSLPF(LogPosteriorFunction):
|
|
|
207
207
|
self._init_p_radius_ratios()
|
|
208
208
|
self._init_p_noise()
|
|
209
209
|
self._init_p_baseline()
|
|
210
|
+
self._init_p_bias()
|
|
210
211
|
self.ps.freeze()
|
|
211
212
|
self.ndim = len(self.ps)
|
|
212
213
|
|
|
@@ -345,6 +346,16 @@ class TSLPF(LogPosteriorFunction):
|
|
|
345
346
|
self._start_baseline = ps.blocks[-1].start
|
|
346
347
|
self._sl_baseline = ps.blocks[-1].slice
|
|
347
348
|
|
|
349
|
+
def _init_p_bias(self):
|
|
350
|
+
ps = self.ps
|
|
351
|
+
offset_groups = self.data.offset_groups
|
|
352
|
+
pp = []
|
|
353
|
+
for i in range(1, max(offset_groups) + 1):
|
|
354
|
+
pp.append(GParameter(f'bias_{i:02d}', 'bias offset', '', NP(0.0, 1e-6), (-inf, inf)))
|
|
355
|
+
ps.add_global_block('bias_offsets', pp)
|
|
356
|
+
self._start_bias = ps.blocks[-1].start
|
|
357
|
+
self._sl_bias = ps.blocks[-1].slice
|
|
358
|
+
|
|
348
359
|
def set_ldtk_prior(self, teff, logg, metal, dataset: str = 'visir-lowres', width: float = 50,
|
|
349
360
|
uncertainty_multiplier: float = 10):
|
|
350
361
|
hw = 0.5 * width
|
|
@@ -573,15 +584,21 @@ class TSLPF(LogPosteriorFunction):
|
|
|
573
584
|
inc = i_from_ba(pv[:, 3], aor)
|
|
574
585
|
ecc = pv[:, 4] ** 2 + pv[:, 5] ** 2
|
|
575
586
|
w = arctan2(pv[:, 5], pv[:, 4])
|
|
587
|
+
fluxes = []
|
|
576
588
|
if isinstance(self.ldmodel, LDTkLD):
|
|
577
589
|
ldp, istar = self.ldmodel(self.tms[0].mu, ldp)
|
|
578
590
|
ldpi = dstack([ldp, istar])
|
|
579
|
-
flux = []
|
|
580
591
|
for i, tm in enumerate(self.tms):
|
|
581
|
-
|
|
582
|
-
return flux
|
|
592
|
+
fluxes.append(tm.evaluate(k[i], ldpi[:, self.ldmodel.wlslices[i], :], t0, p, aor, inc, ecc, w, copy))
|
|
583
593
|
else:
|
|
584
|
-
|
|
594
|
+
for i, tm in enumerate(self.tms):
|
|
595
|
+
fluxes.append(tm.evaluate(k[i], ldp[i], t0, p, aor, inc, ecc, w, copy))
|
|
596
|
+
|
|
597
|
+
for i, d in enumerate(self.data):
|
|
598
|
+
if d.offset_group > 0:
|
|
599
|
+
biases = pv[:, self._start_bias + d.offset_group - 1][:, None, None]
|
|
600
|
+
fluxes[i] = biases + (1.0 - biases) * fluxes[i]
|
|
601
|
+
return fluxes
|
|
585
602
|
|
|
586
603
|
def baseline_model(self, pv):
|
|
587
604
|
pv = atleast_2d(pv)[:, self._sl_baseline]
|
exoiris/wlpf.py
CHANGED
|
@@ -79,7 +79,7 @@ class WhiteLPF(BaseLPF):
|
|
|
79
79
|
def plot(self, axs=None, figsize=None, ncols=2) -> Figure:
|
|
80
80
|
if axs is None:
|
|
81
81
|
nrows = int(ceil(self.nlc / ncols))
|
|
82
|
-
fig, axs = subplots(nrows, ncols, figsize=figsize, sharey='all', squeeze=False)
|
|
82
|
+
fig, axs = subplots(nrows, ncols, figsize=figsize, sharey='all', squeeze=False, constrained_layout=True)
|
|
83
83
|
else:
|
|
84
84
|
fig = axs[0].get_figure()
|
|
85
85
|
|
ExoIris-0.17.0.dist-info/RECORD
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
exoiris/__init__.py,sha256=gaNfxNKXH41yRK35JghqackXpENyB-NOg-JlciqO1YU,1145
|
|
2
|
-
exoiris/binning.py,sha256=-Y9hdK0jZj8DOS82keaprneid2lZ4rCx-keWlKi0LP8,6455
|
|
3
|
-
exoiris/ephemeris.py,sha256=dthBkJztT5yAP6VnnO7jGvxikboFUQBUGPUfBCFrA3w,1316
|
|
4
|
-
exoiris/exoiris.py,sha256=_qQNSiv9r189rnGdKW7WInZhPzW4k0BdwL-Yg0HR9U8,48774
|
|
5
|
-
exoiris/ldtkld.py,sha256=u4c5Yh6JlG0Zfec7-nOCQGXxIt1VVp9mniFMM7h-L6s,3489
|
|
6
|
-
exoiris/tsdata.py,sha256=uIHml2RKRS6eAF9O0pkdvVj7xL7RqTHfHXQlCUhgtOc,31506
|
|
7
|
-
exoiris/tslpf.py,sha256=qZLQw2okT3j66ObFiJsboUC_Ay4w6xdyyIUI-NTMKaY,27902
|
|
8
|
-
exoiris/tsmodel.py,sha256=6NaGY48fWHUT_7ti6Ao618PN-LgyoIhfQd8lZQqZ7hU,5160
|
|
9
|
-
exoiris/util.py,sha256=5PynwYYHRrzyXJHskBtp2J-pcM59zsA1_VtDxencQm4,4630
|
|
10
|
-
exoiris/wlpf.py,sha256=Xelg7pRamgG9TRreXnphJo5w_qK7VwXbUJxnI_lphpU,4512
|
|
11
|
-
ExoIris-0.17.0.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
12
|
-
ExoIris-0.17.0.dist-info/METADATA,sha256=VwkZypbMCrzKvc_xcmN8nOo8THiu0KGpGGAuKBhE820,4189
|
|
13
|
-
ExoIris-0.17.0.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
|
14
|
-
ExoIris-0.17.0.dist-info/top_level.txt,sha256=EoNxT6c5mQDcM0f_LUQB-ETsYg03lNaV3o2L_Yc6-aE,8
|
|
15
|
-
ExoIris-0.17.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|