exovetter 0.0.2__py3-none-any.whl → 0.0.4__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.
- exovetter/centroid/__init__.py +1 -0
- exovetter/centroid/centroid.py +29 -14
- exovetter/centroid/covar.py +5 -3
- exovetter/leo.py +227 -0
- exovetter/lightkurve_utils.py +1 -1
- exovetter/lpp.py +2 -1
- exovetter/sweet.py +6 -3
- exovetter/tce.py +6 -0
- exovetter/trapezoid_fit.py +2 -1
- exovetter/utils.py +58 -18
- exovetter/version.py +1 -1
- exovetter/vetters.py +524 -119
- exovetter/viz_transits.py +17 -9
- {exovetter-0.0.2.dist-info → exovetter-0.0.4.dist-info}/METADATA +5 -4
- exovetter-0.0.4.dist-info/RECORD +28 -0
- {exovetter-0.0.2.dist-info → exovetter-0.0.4.dist-info}/WHEEL +1 -1
- exovetter/__init__.py.mine +0 -11
- exovetter/centroid/untitled0.py +0 -24
- exovetter/junk +0 -89
- exovetter-0.0.2.dist-info/RECORD +0 -29
- {exovetter-0.0.2.dist-info → exovetter-0.0.4.dist-info}/LICENSE.rst +0 -0
- {exovetter-0.0.2.dist-info → exovetter-0.0.4.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
exovetter/centroid/centroid.py
CHANGED
|
@@ -11,7 +11,8 @@ def compute_diff_image_centroids(
|
|
|
11
11
|
cube,
|
|
12
12
|
period_days,
|
|
13
13
|
epoch,
|
|
14
|
-
duration_days,
|
|
14
|
+
duration_days,
|
|
15
|
+
remove_transits,
|
|
15
16
|
max_oot_shift_pix=1.5,
|
|
16
17
|
plot=False
|
|
17
18
|
):
|
|
@@ -38,7 +39,9 @@ def compute_diff_image_centroids(
|
|
|
38
39
|
epoch
|
|
39
40
|
(float) Epoch of transit centre in the same time system as `time`.
|
|
40
41
|
duration_days
|
|
41
|
-
(float) Duration of transit.
|
|
42
|
+
(float) Duration of transit.
|
|
43
|
+
remove_transits
|
|
44
|
+
(list) List of 0 indexed transit integers to not calculate on.
|
|
42
45
|
max_oot_shift_pix
|
|
43
46
|
(float) Passed to `fastpsffit.fastGaussianPrfFit()
|
|
44
47
|
|
|
@@ -73,21 +76,30 @@ def compute_diff_image_centroids(
|
|
|
73
76
|
|
|
74
77
|
figs = []
|
|
75
78
|
centroids = []
|
|
79
|
+
|
|
76
80
|
for i in range(len(transits)):
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
81
|
+
if i not in remove_transits:
|
|
82
|
+
cin = transits[i]
|
|
83
|
+
cents, fig = measure_centroids(
|
|
84
|
+
cube,
|
|
85
|
+
cin,
|
|
86
|
+
max_oot_shift_pix=max_oot_shift_pix,
|
|
87
|
+
plot=plot
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
if plot == True:
|
|
91
|
+
fig.suptitle('Transit '+str(i))
|
|
92
|
+
|
|
93
|
+
centroids.append(cents)
|
|
94
|
+
figs.append(fig)
|
|
95
|
+
|
|
86
96
|
centroids = np.array(centroids)
|
|
87
|
-
|
|
97
|
+
all_transits = list(np.arange(len(transits)))
|
|
98
|
+
kept_transits = [x for x in all_transits if x not in remove_transits]
|
|
99
|
+
return centroids, figs, kept_transits
|
|
88
100
|
|
|
89
101
|
|
|
90
|
-
def measure_centroid_shift(centroids, plot=False):
|
|
102
|
+
def measure_centroid_shift(centroids, kept_transits, plot=False):
|
|
91
103
|
"""Measure the average offset of the DIC centroids from the OOT centroids.
|
|
92
104
|
|
|
93
105
|
Inputs
|
|
@@ -95,6 +107,9 @@ def measure_centroid_shift(centroids, plot=False):
|
|
|
95
107
|
centroids
|
|
96
108
|
(2d np array) Output of :func:`compute_diff_image_centroids`
|
|
97
109
|
|
|
110
|
+
kept_transits
|
|
111
|
+
(list) List of 0 indexed transit integers to calculate on.
|
|
112
|
+
|
|
98
113
|
Returns
|
|
99
114
|
-----------
|
|
100
115
|
offset
|
|
@@ -122,7 +137,7 @@ def measure_centroid_shift(centroids, plot=False):
|
|
|
122
137
|
|
|
123
138
|
fig = None
|
|
124
139
|
if plot:
|
|
125
|
-
fig = covar.diagnostic_plot(dcol, drow, flags)
|
|
140
|
+
fig = covar.diagnostic_plot(dcol, drow, kept_transits, flags)
|
|
126
141
|
return offset_pix, signif, fig
|
|
127
142
|
|
|
128
143
|
|
exovetter/centroid/covar.py
CHANGED
|
@@ -45,7 +45,7 @@ import numpy as np
|
|
|
45
45
|
"""
|
|
46
46
|
|
|
47
47
|
|
|
48
|
-
def diagnostic_plot(x, y, flag=None):
|
|
48
|
+
def diagnostic_plot(x, y, kept_transits, flag=None):
|
|
49
49
|
|
|
50
50
|
if flag is None:
|
|
51
51
|
flag = np.zeros(len(x))
|
|
@@ -57,7 +57,8 @@ def diagnostic_plot(x, y, flag=None):
|
|
|
57
57
|
mu_y = np.mean(y[~idx])
|
|
58
58
|
sma, smi = compute_eigen_vectors(x[~idx], y[~idx])
|
|
59
59
|
|
|
60
|
-
plt.clf()
|
|
60
|
+
# plt.clf()
|
|
61
|
+
plt.figure()
|
|
61
62
|
plt.gcf().set_size_inches((10, 8))
|
|
62
63
|
plt.plot(x, y, "ko", mec="w", label="Centroids", zorder=+5)
|
|
63
64
|
if np.any(idx):
|
|
@@ -71,7 +72,8 @@ def diagnostic_plot(x, y, flag=None):
|
|
|
71
72
|
|
|
72
73
|
# prob = compute_prob_of_points(x, y, sma, smi)
|
|
73
74
|
for i in range(len(x)):
|
|
74
|
-
|
|
75
|
+
|
|
76
|
+
plt.text(x[i], y[i], " %i" % (kept_transits[i]), zorder=+5)
|
|
75
77
|
|
|
76
78
|
sigma_a = np.linalg.norm(sma)
|
|
77
79
|
sigma_b = np.linalg.norm(smi)
|
exovetter/leo.py
ADDED
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
def phasefold(t, per, epo):
|
|
4
|
+
# Phase will span -0.5 to 0.5, with transit centred at phase 0
|
|
5
|
+
phase = np.mod(t - epo, per) / per
|
|
6
|
+
phase[phase > 0.5] -= 1
|
|
7
|
+
return phase
|
|
8
|
+
|
|
9
|
+
def weighted_mean(y, dy):
|
|
10
|
+
w = 1 / dy**2
|
|
11
|
+
mean = np.sum(w * y) / np.sum(w)
|
|
12
|
+
return mean
|
|
13
|
+
|
|
14
|
+
def weighted_std(y, dy):
|
|
15
|
+
w = 1 / dy**2
|
|
16
|
+
N = len(w)
|
|
17
|
+
mean = np.sum(w * y) / np.sum(w)
|
|
18
|
+
std = np.sqrt(np.sum(w * (y - mean) ** 2) / ((N - 1) * np.sum(w) / N))
|
|
19
|
+
return std
|
|
20
|
+
|
|
21
|
+
def weighted_err(y, dy):
|
|
22
|
+
w = 1 / dy**2
|
|
23
|
+
err = 1 / np.sqrt(np.sum(w))
|
|
24
|
+
return err
|
|
25
|
+
|
|
26
|
+
class Leo:
|
|
27
|
+
def __init__(self, time, per, epo, dur, flux, flux_err, frac, max_chases_phase):
|
|
28
|
+
'''
|
|
29
|
+
Parameters
|
|
30
|
+
-----------
|
|
31
|
+
time : array
|
|
32
|
+
Array of times from lc
|
|
33
|
+
|
|
34
|
+
per : float
|
|
35
|
+
Orbital period in days
|
|
36
|
+
|
|
37
|
+
epo : float
|
|
38
|
+
Time of first transit in TESS BJD
|
|
39
|
+
|
|
40
|
+
dur : float
|
|
41
|
+
Transit duration in days
|
|
42
|
+
|
|
43
|
+
flux : array
|
|
44
|
+
Array of flux values from lc
|
|
45
|
+
|
|
46
|
+
flux_err : array
|
|
47
|
+
Array of flux error values from lc
|
|
48
|
+
|
|
49
|
+
frac : float
|
|
50
|
+
fraction of SES for a transit which triggers the chases false alarm statistic (default 0.7)
|
|
51
|
+
|
|
52
|
+
max_chases_phase : float
|
|
53
|
+
maximum to allow the chases search to run on (default 0.1)
|
|
54
|
+
|
|
55
|
+
Attributes
|
|
56
|
+
------------
|
|
57
|
+
qtran : Transit duration divided by the period of the transit
|
|
58
|
+
phase : Array of phases for the time series spanning -0.5 to 0.5 with transit at 0
|
|
59
|
+
in_tran : Phases in transit
|
|
60
|
+
near_tran : Boolean of cadences within 1 transit duration
|
|
61
|
+
epochs : Number of transits accounting for gaps
|
|
62
|
+
tran_epochs : Epochs of the transits
|
|
63
|
+
N_transit : Length of tran_epochs
|
|
64
|
+
fit_tran : Cadences within 2 transit durations
|
|
65
|
+
zpt : Out-of-transit wieghted mean of the fluxes
|
|
66
|
+
dep : Depth of the transit based on the weighted mean of the in transit points
|
|
67
|
+
'''
|
|
68
|
+
self.time = time
|
|
69
|
+
self.per = per
|
|
70
|
+
self.epo = epo
|
|
71
|
+
self.dur = dur
|
|
72
|
+
self.flux = flux
|
|
73
|
+
self.flux_err = flux_err
|
|
74
|
+
self.qtran = dur / per
|
|
75
|
+
|
|
76
|
+
# Phase spans -0.5 to 0.5 with transit at 0
|
|
77
|
+
self.phase = phasefold(time, per, epo)
|
|
78
|
+
# Cadences in-transit
|
|
79
|
+
self.in_tran = abs(self.phase) < 0.5 * self.qtran
|
|
80
|
+
# Cadences within 1 transit duration
|
|
81
|
+
self.near_tran = abs(self.phase) < self.qtran
|
|
82
|
+
# Actual number of transits accounting for gaps
|
|
83
|
+
self.epochs = np.round((time - epo) / per)
|
|
84
|
+
|
|
85
|
+
self.tran_epochs = np.unique(self.epochs[self.in_tran])
|
|
86
|
+
self.N_transit = len(self.tran_epochs)
|
|
87
|
+
# Cadences within 2 transit durations
|
|
88
|
+
self.fit_tran = abs(self.phase) < 2 * self.qtran # can change to a variable other than 2
|
|
89
|
+
# Number of transit datapoints
|
|
90
|
+
self.n_in = np.sum(self.in_tran)
|
|
91
|
+
|
|
92
|
+
# Out-of-transit flux and transit depth
|
|
93
|
+
self.zpt = weighted_mean(self.flux[~self.near_tran], self.flux_err[~self.near_tran])
|
|
94
|
+
self.dep = self.zpt - weighted_mean(self.flux[self.in_tran], self.flux_err[self.in_tran])
|
|
95
|
+
|
|
96
|
+
self.frac = frac
|
|
97
|
+
self.max_chases_phase = max_chases_phase
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def get_SES_MES(self):
|
|
101
|
+
N = len(self.time)
|
|
102
|
+
dep_SES = np.zeros(N)
|
|
103
|
+
n_SES = np.zeros(N)
|
|
104
|
+
dep_MES = np.zeros(N)
|
|
105
|
+
n_MES = np.zeros(N)
|
|
106
|
+
N_transit_MES = np.zeros(N)
|
|
107
|
+
bin_flux = np.zeros(N)
|
|
108
|
+
bin_flux_err = np.zeros(N)
|
|
109
|
+
phase = phasefold(self.time, self.per, self.epo)
|
|
110
|
+
phase[phase < 0] += 1
|
|
111
|
+
for i in np.arange(N):
|
|
112
|
+
# Get individual transit depth at this cadence, i.e. only use datapoints close in time
|
|
113
|
+
in_tran = abs(self.time - self.time[i]) < 0.5 * self.dur
|
|
114
|
+
n_SES[i] = np.sum(in_tran)
|
|
115
|
+
dep_SES[i] = self.zpt - weighted_mean(
|
|
116
|
+
self.flux[in_tran], self.flux_err[in_tran]
|
|
117
|
+
)
|
|
118
|
+
# Get overall transit depth at this cadence, i.e. use all datapoints close in phase
|
|
119
|
+
all_tran = (abs(phase - phase[i]) < 0.5 * self.qtran) | (
|
|
120
|
+
abs(phase - phase[i]) > 1 - 0.5 * self.qtran
|
|
121
|
+
)
|
|
122
|
+
n_MES[i] = np.sum(all_tran)
|
|
123
|
+
dep_MES[i] = self.zpt - weighted_mean(
|
|
124
|
+
self.flux[all_tran], self.flux_err[all_tran]
|
|
125
|
+
)
|
|
126
|
+
epochs = np.round((self.time - self.time[i]) / self.per)
|
|
127
|
+
tran_epochs = np.unique(epochs[all_tran])
|
|
128
|
+
N_transit_MES[i] = len(tran_epochs)
|
|
129
|
+
# Get running mean and uncertainty of out-of-transit fluxes, binned over transit timescale
|
|
130
|
+
in_bin = in_tran & ~self.near_tran
|
|
131
|
+
bin_flux[i] = weighted_mean(self.flux[in_bin], self.flux_err[in_bin])
|
|
132
|
+
bin_flux_err[i] = weighted_err(self.flux[in_bin], self.flux_err[in_bin]).value
|
|
133
|
+
# Estimate white and red noise following Hartman & Bakos (2016)
|
|
134
|
+
mask = ~np.isnan(bin_flux) & ~self.near_tran
|
|
135
|
+
std = weighted_std(self.flux[mask], self.flux_err[mask])
|
|
136
|
+
bin_std = weighted_std(bin_flux[mask], bin_flux_err[mask])
|
|
137
|
+
expected_bin_std = (
|
|
138
|
+
std
|
|
139
|
+
* np.sqrt(np.nanmean(bin_flux_err[mask] ** 2))
|
|
140
|
+
/ np.sqrt(np.nanmean(self.flux_err[mask] ** 2))
|
|
141
|
+
).value
|
|
142
|
+
self.sig_w = std
|
|
143
|
+
sig_r2 = bin_std**2 - expected_bin_std**2
|
|
144
|
+
self.sig_r = np.sqrt(sig_r2) if sig_r2 > 0 else 0
|
|
145
|
+
# Estimate signal-to-pink-noise following Pont et al. (2006)
|
|
146
|
+
self.err = np.sqrt(
|
|
147
|
+
(self.sig_w**2 / self.n_in) + (self.sig_r**2 / self.N_transit)
|
|
148
|
+
)
|
|
149
|
+
err_SES = np.sqrt((self.sig_w**2 / n_SES) + self.sig_r**2)
|
|
150
|
+
err_MES = np.sqrt((self.sig_w**2 / n_MES) + (self.sig_r**2 / N_transit_MES))
|
|
151
|
+
self.SES_series = dep_SES / err_SES
|
|
152
|
+
self.dep_series = dep_MES
|
|
153
|
+
self.err_series = err_MES
|
|
154
|
+
self.MES_series = dep_MES / err_MES
|
|
155
|
+
self.MES = self.dep / self.err
|
|
156
|
+
Fmin = np.nanmin(-self.dep_series)
|
|
157
|
+
Fmax = np.nanmax(-self.dep_series)
|
|
158
|
+
self.SHP = Fmax / (Fmax - Fmin)
|
|
159
|
+
|
|
160
|
+
def get_chases(self):
|
|
161
|
+
deps = np.zeros(self.N_transit)
|
|
162
|
+
errs = np.zeros(self.N_transit)
|
|
163
|
+
self.SES = np.zeros(self.N_transit)
|
|
164
|
+
self.rubble = np.zeros(self.N_transit)
|
|
165
|
+
self.chases = np.zeros(self.N_transit)
|
|
166
|
+
# self.redchi2 = np.zeros(self.N_transit)
|
|
167
|
+
# Search range for chases metric is between 1.5 durations and n times the period away
|
|
168
|
+
chases_tran = (abs(self.phase) > 1.5 * self.qtran) & (abs(self.phase) < self.max_chases_phase)
|
|
169
|
+
|
|
170
|
+
# Get metrics for each transit event
|
|
171
|
+
for i in range(self.N_transit):
|
|
172
|
+
epoch = self.tran_epochs[i]
|
|
173
|
+
in_epoch = self.in_tran & (self.epochs == epoch)
|
|
174
|
+
# Compute the transit time, depth, and SES for this transit
|
|
175
|
+
transit_time = self.epo + self.per * epoch
|
|
176
|
+
n_in = np.sum(in_epoch)
|
|
177
|
+
dep = self.zpt - weighted_mean(self.flux[in_epoch], self.flux_err[in_epoch])
|
|
178
|
+
err = np.sqrt((self.sig_w**2 / n_in) + self.sig_r**2)
|
|
179
|
+
deps[i], errs[i] = dep, err
|
|
180
|
+
self.SES[i] = dep / err
|
|
181
|
+
# Find the most significant nearby event
|
|
182
|
+
chases_epoch = (chases_tran & (self.epochs == epoch) & (np.abs(self.SES_series) > self.frac * self.SES[i]))
|
|
183
|
+
|
|
184
|
+
if np.any(chases_epoch):
|
|
185
|
+
self.chases[i] = np.min(np.abs(self.time[chases_epoch] - transit_time)) / (
|
|
186
|
+
self.max_chases_phase * self.per
|
|
187
|
+
)
|
|
188
|
+
else:
|
|
189
|
+
self.chases[i] = 1
|
|
190
|
+
# Find how much of the transit falls in gaps
|
|
191
|
+
fit_epoch = self.fit_tran & (self.epochs == epoch)
|
|
192
|
+
n_obs = np.sum(fit_epoch)
|
|
193
|
+
cadence = np.nanmedian(np.diff(self.time[fit_epoch]))
|
|
194
|
+
n_exp = 4 * self.dur / cadence # 4 is used because of the 2 transit duration on either side above in fit_tran
|
|
195
|
+
self.rubble[i] = n_obs / n_exp
|
|
196
|
+
# if ("transit_aic" in tlc.metrics) and ~np.isnan(tlc.metrics["transit_aic"]):
|
|
197
|
+
# tm = TransitModel(
|
|
198
|
+
# tlc.metrics["transit_per"],
|
|
199
|
+
# tlc.metrics["transit_epo"],
|
|
200
|
+
# tlc.metrics["transit_RpRs"],
|
|
201
|
+
# tlc.metrics["transit_aRs"],
|
|
202
|
+
# tlc.metrics["transit_b"],
|
|
203
|
+
# tlc.metrics["transit_u1"],
|
|
204
|
+
# tlc.metrics["transit_u2"],
|
|
205
|
+
# tlc.metrics["transit_zpt"],
|
|
206
|
+
# )
|
|
207
|
+
# resid = tm.residual(
|
|
208
|
+
# tm.params,
|
|
209
|
+
# tlc.time[fit_epoch],
|
|
210
|
+
# tlc.flux[fit_epoch],
|
|
211
|
+
# tlc.flux_err[fit_epoch],
|
|
212
|
+
# )
|
|
213
|
+
# chi2 = np.sum(resid**2)
|
|
214
|
+
# tlc.redchi2[i] = chi2 / (np.sum(fit_epoch) - 6)
|
|
215
|
+
# else:
|
|
216
|
+
# tlc.redchi2[i] = np.nan
|
|
217
|
+
O = self.SES
|
|
218
|
+
E = self.dep / errs
|
|
219
|
+
chi2 = np.sum((O - E) ** 2 / E)
|
|
220
|
+
self.CHI = self.MES / np.sqrt(chi2 / (self.N_transit - 1))
|
|
221
|
+
self.med_chases = np.nanmedian(self.chases)
|
|
222
|
+
self.mean_chases = np.nanmean(self.chases)
|
|
223
|
+
self.max_SES = np.nanmax(self.SES)
|
|
224
|
+
self.DMM = np.nanmean(deps) / np.nanmedian(deps)
|
|
225
|
+
|
|
226
|
+
def plot (self):
|
|
227
|
+
print('Plotting not yet implemented')
|
exovetter/lightkurve_utils.py
CHANGED
exovetter/lpp.py
CHANGED
exovetter/sweet.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"""Module
|
|
1
|
+
"""Module to handle SWEET vetter."""
|
|
2
2
|
|
|
3
3
|
import os
|
|
4
4
|
|
|
@@ -63,7 +63,8 @@ def sweet(time, flux, period, epoch, duration, plot=False):
|
|
|
63
63
|
|
|
64
64
|
if plot:
|
|
65
65
|
import matplotlib.pyplot as plt
|
|
66
|
-
plt.clf()
|
|
66
|
+
#plt.clf() # swapped with a plt.figure below MD 2023
|
|
67
|
+
plt.figure(figsize=(7,7))
|
|
67
68
|
|
|
68
69
|
out = []
|
|
69
70
|
for i, per in enumerate([period * 0.5, period, 2 * period]):
|
|
@@ -77,9 +78,11 @@ def sweet(time, flux, period, epoch, duration, plot=False):
|
|
|
77
78
|
if plot:
|
|
78
79
|
srt = np.argsort(phase)
|
|
79
80
|
plt.subplot(3, 1, i + 1)
|
|
80
|
-
plt.plot(phase, flux, 'ko')
|
|
81
|
+
plt.plot(phase, flux, 'ko', ms=2.5)
|
|
81
82
|
plt.plot(phase[srt], f_obj.get_best_fit_model(phase[srt]), '-')
|
|
82
83
|
plt.ylabel("P=%g" % (per))
|
|
84
|
+
if i==0:
|
|
85
|
+
plt.title('SWEET: Folded at 1/2, 1, and 2 times the period')
|
|
83
86
|
|
|
84
87
|
result = np.array(out)
|
|
85
88
|
|
exovetter/tce.py
CHANGED
|
@@ -130,9 +130,15 @@ class Tce(dict):
|
|
|
130
130
|
"""
|
|
131
131
|
if 'epoch' not in self or 'epoch_offset' not in self:
|
|
132
132
|
raise KeyError('epoch and epoch_offset must be defined first')
|
|
133
|
+
|
|
134
|
+
# Puts into bjd
|
|
133
135
|
epoch = self["epoch"] - self["epoch_offset"]
|
|
136
|
+
|
|
134
137
|
if offset is not None:
|
|
138
|
+
# Transforms from bjd into desired time system
|
|
135
139
|
epoch = epoch + offset
|
|
140
|
+
|
|
141
|
+
|
|
136
142
|
return epoch
|
|
137
143
|
|
|
138
144
|
def validate(self):
|
exovetter/trapezoid_fit.py
CHANGED
|
@@ -742,7 +742,8 @@ class TrapezoidFit:
|
|
|
742
742
|
|
|
743
743
|
"""
|
|
744
744
|
import scipy.optimize as opt
|
|
745
|
-
from astropy.utils.compat.context import nullcontext
|
|
745
|
+
# from astropy.utils.compat.context import nullcontext # removed as depricated MD 2023
|
|
746
|
+
from contextlib import nullcontext # added instead of astropy's nullcontext ^
|
|
746
747
|
from astropy.utils.misc import NumpyRNGContext
|
|
747
748
|
|
|
748
749
|
if options is None:
|
exovetter/utils.py
CHANGED
|
@@ -5,6 +5,9 @@ import warnings
|
|
|
5
5
|
|
|
6
6
|
import numpy as np
|
|
7
7
|
|
|
8
|
+
__all__ = ['sine', 'estimate_scatter', 'mark_transit_cadences', 'median_detrend',
|
|
9
|
+
'plateau', 'set_median_flux_to_zero', 'set_median_flux_to_one', 'sigmaClip',
|
|
10
|
+
'get_mast_tce', 'WqedLSF', 'compute_phases', 'first_epoch']
|
|
8
11
|
|
|
9
12
|
def sine(x, order, period=1):
|
|
10
13
|
"""Sine function for SWEET vetter."""
|
|
@@ -115,7 +118,8 @@ def mark_transit_cadences(time, period_days, epoch_bkjd, duration_days,
|
|
|
115
118
|
big_num = sys.float_info.max # A large value that isn't NaN
|
|
116
119
|
max_diff = 0.5 * duration_days * num_durations
|
|
117
120
|
|
|
118
|
-
idx = np.zeros_like(time, dtype=np.
|
|
121
|
+
idx = np.zeros_like(time, dtype=np.bool_)
|
|
122
|
+
# Changed from np.bool8 to np.bool_ for py 3.11
|
|
119
123
|
for tt in transit_times:
|
|
120
124
|
diff = time - tt
|
|
121
125
|
diff[flags] = big_num
|
|
@@ -150,25 +154,32 @@ def median_detrend(flux, nPoints):
|
|
|
150
154
|
|
|
151
155
|
|
|
152
156
|
def plateau(array, threshold):
|
|
153
|
-
"""Find plateaus in an array, i.e continuous regions that exceed threshold
|
|
157
|
+
"""Find plateaus in an array, i.e continuous regions that exceed threshold.
|
|
154
158
|
|
|
155
159
|
Given an array of numbers, return a 2d array such that
|
|
156
160
|
out[:,0] marks the indices where the array crosses threshold from
|
|
157
161
|
below, and out[:,1] marks the next time the array crosses that
|
|
158
162
|
same threshold from below.
|
|
159
163
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
164
|
+
Parameters
|
|
165
|
+
----------
|
|
166
|
+
array : array_like
|
|
167
|
+
Numpy 1D array
|
|
168
|
+
|
|
169
|
+
threshold : float or array_like
|
|
170
|
+
If threshold is a single number, any point
|
|
171
|
+
above that value is above threshold. If it's an array,
|
|
172
|
+
it must have the same length as the first argument, and
|
|
173
|
+
an array[i] > threshold[i] to be included as a plateau
|
|
174
|
+
|
|
175
|
+
Returns
|
|
176
|
+
-------
|
|
177
|
+
loc : array_like
|
|
178
|
+
Numpy 2d array with 2 columns.
|
|
169
179
|
|
|
170
180
|
|
|
171
|
-
Notes
|
|
181
|
+
Notes
|
|
182
|
+
-----
|
|
172
183
|
To find the length of the plateaus, use
|
|
173
184
|
out[:,1] - out[:,0]
|
|
174
185
|
|
|
@@ -180,7 +191,7 @@ def plateau(array, threshold):
|
|
|
180
191
|
to ensure floating point arithmetic prevents two numbers being
|
|
181
192
|
exactly equal.
|
|
182
193
|
"""
|
|
183
|
-
|
|
194
|
+
|
|
184
195
|
arr = array.astype(np.float32)
|
|
185
196
|
arr = arr - threshold + 1e-12
|
|
186
197
|
arrPlus = np.roll(arr, 1)
|
|
@@ -316,6 +327,7 @@ def get_mast_tce(name):
|
|
|
316
327
|
url = planeturl + name + "/properties/"
|
|
317
328
|
|
|
318
329
|
r = requests.get(url = url, headers = header)
|
|
330
|
+
|
|
319
331
|
if len(r.json()) < 1:
|
|
320
332
|
print("No TCE Information was returned from MAST.")
|
|
321
333
|
return []
|
|
@@ -330,6 +342,7 @@ def get_mast_tce(name):
|
|
|
330
342
|
epoch_offset_str = 'mjd'
|
|
331
343
|
depth = prop['transit_depth']
|
|
332
344
|
duration = prop['transit_duration']
|
|
345
|
+
catalog_name = prop['catalog_name']
|
|
333
346
|
if duration is None:
|
|
334
347
|
duration = 0
|
|
335
348
|
durunit = prop['transit_duration_unit']
|
|
@@ -341,7 +354,8 @@ def get_mast_tce(name):
|
|
|
341
354
|
epoch_offset = const.__dict__['string_to_offset'][epoch_offset_str],
|
|
342
355
|
depth = depth * const.frac_amp,
|
|
343
356
|
duration = duration * u.__dict__[durunit],
|
|
344
|
-
target = name
|
|
357
|
+
target = name,
|
|
358
|
+
catalog_name = catalog_name
|
|
345
359
|
)
|
|
346
360
|
|
|
347
361
|
tces.append(atce)
|
|
@@ -437,7 +451,8 @@ class WqedLSF:
|
|
|
437
451
|
covar = np.linalg.inv(A)
|
|
438
452
|
|
|
439
453
|
wy = self.y / self.s
|
|
440
|
-
|
|
454
|
+
df = df.T # transposed to work with np.dot updates MD 2023
|
|
455
|
+
beta = np.dot(df, wy) # swapped order in dot product MD 2023
|
|
441
456
|
params = np.dot(beta, covar)
|
|
442
457
|
|
|
443
458
|
# Store results
|
|
@@ -600,7 +615,32 @@ def compute_phases(time, period, epoch, offset=0.5):
|
|
|
600
615
|
|
|
601
616
|
return phases
|
|
602
617
|
|
|
618
|
+
def first_epoch(epoch, period, lc):
|
|
619
|
+
"""Returns epoch of the first time in a lc file. Usefull when pulling down TCEs from MAST.
|
|
603
620
|
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
621
|
+
Parameters
|
|
622
|
+
----------
|
|
623
|
+
epoch : float
|
|
624
|
+
Time of transit from a given TCE in same time system as lc.
|
|
625
|
+
|
|
626
|
+
period : float
|
|
627
|
+
Period in units of time.
|
|
628
|
+
|
|
629
|
+
lc : lightkurve object
|
|
630
|
+
lightkurve object with flux and time.
|
|
631
|
+
|
|
632
|
+
Returns
|
|
633
|
+
-------
|
|
634
|
+
first_epoch : float
|
|
635
|
+
Epoch of first transit in lc in the time system of the lc.
|
|
636
|
+
|
|
637
|
+
"""
|
|
638
|
+
# TODO might need to assert epoch.value is within lc.time.value
|
|
639
|
+
if epoch.value >= lc.time.value[0]:
|
|
640
|
+
N = np.floor((epoch.value-lc.time.value[0])/period.value)
|
|
641
|
+
first_epoch = epoch - N*period
|
|
642
|
+
else:
|
|
643
|
+
N = np.ceil((lc.time.value[0]-epoch.value)/period.value)
|
|
644
|
+
first_epoch = epoch + N*period
|
|
645
|
+
|
|
646
|
+
return first_epoch
|
exovetter/version.py
CHANGED