tglc 0.6.5__py3-none-any.whl → 0.7.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.
- tglc/__init__.py +2 -2
- tglc/barycentric_correction.py +107 -0
- tglc/effective_psf.py +15 -3
- tglc/ephemeris_data/20180720_tess_ephem.csv +10385 -0
- tglc/ephemeris_data/20190101_tess_ephem.csv +9635 -0
- tglc/ephemeris_data/20200101_tess_ephem.csv +9659 -0
- tglc/ephemeris_data/20210101_tess_ephem.csv +9275 -0
- tglc/ephemeris_data/20211215_tess_ephem.csv +12512 -0
- tglc/ephemeris_data/20221201_tess_ephem.csv +10308 -0
- tglc/ephemeris_data/20231201_tess_ephem.csv +10339 -0
- tglc/ephemeris_data/20241201_tess_ephem.csv +10314 -0
- tglc/ephemeris_data/README.md +48 -0
- tglc/ephemeris_data/plot_ephemerides.py +54 -0
- tglc/ffi.py +3 -3
- tglc/ffi_cut.py +125 -22
- tglc/quick_lc.py +243 -124
- tglc/target_lightcurve.py +39 -11
- {tglc-0.6.5.dist-info → tglc-0.7.0.dist-info}/METADATA +42 -13
- tglc-0.7.0.dist-info/RECORD +28 -0
- {tglc-0.6.5.dist-info → tglc-0.7.0.dist-info}/WHEEL +1 -1
- tglc-0.6.5.dist-info/RECORD +0 -17
- {tglc-0.6.5.dist-info → tglc-0.7.0.dist-info/licenses}/LICENSE +0 -0
- {tglc-0.6.5.dist-info → tglc-0.7.0.dist-info}/top_level.txt +0 -0
tglc/quick_lc.py
CHANGED
|
@@ -9,24 +9,30 @@ import matplotlib.pyplot as plt
|
|
|
9
9
|
from multiprocessing import Pool
|
|
10
10
|
from functools import partial
|
|
11
11
|
from tglc.target_lightcurve import epsf
|
|
12
|
-
from tglc.ffi_cut import ffi_cut
|
|
12
|
+
from tglc.ffi_cut import ffi_cut, _dot_wait
|
|
13
13
|
from astroquery.mast import Catalogs
|
|
14
14
|
import astropy.units as u
|
|
15
15
|
from astropy.coordinates import SkyCoord
|
|
16
16
|
from astroquery.mast import Tesscut
|
|
17
|
+
import sys
|
|
18
|
+
import warnings
|
|
19
|
+
import requests
|
|
20
|
+
import time
|
|
17
21
|
# Tesscut._service_api_connection.TIMEOUT = 6000
|
|
18
|
-
|
|
19
22
|
# warnings.simplefilter('ignore', UserWarning)
|
|
20
23
|
from threadpoolctl import ThreadpoolController, threadpool_limits
|
|
21
24
|
import numpy as np
|
|
22
25
|
import seaborn as sns
|
|
23
26
|
import itertools
|
|
27
|
+
from astropy import units
|
|
28
|
+
from astroquery.utils.tap.core import TapPlus
|
|
24
29
|
controller = ThreadpoolController()
|
|
25
30
|
|
|
26
31
|
|
|
27
32
|
@controller.wrap(limits=1, user_api='blas')
|
|
28
33
|
def tglc_lc(target='TIC 264468702', local_directory='', size=90, save_aper=True, limit_mag=16, get_all_lc=False,
|
|
29
|
-
first_sector_only=False, last_sector_only=False, sector=None, prior=None, transient=None
|
|
34
|
+
first_sector_only=False, last_sector_only=False, sector=None, prior=None, transient=None, ffi='SPOC',
|
|
35
|
+
mast_timeout=3600):
|
|
30
36
|
'''
|
|
31
37
|
Generate light curve for a single target.
|
|
32
38
|
|
|
@@ -36,81 +42,152 @@ def tglc_lc(target='TIC 264468702', local_directory='', size=90, save_aper=True,
|
|
|
36
42
|
:kind local_directory: str, required
|
|
37
43
|
:param size: size of the FFI cut, default size is 90. Recommend large number for better quality. Cannot exceed 100.
|
|
38
44
|
:kind size: int, optional
|
|
45
|
+
:param mast_timeout: timeout in seconds for MAST Tesscut requests
|
|
46
|
+
:kind mast_timeout: int, optional
|
|
39
47
|
'''
|
|
40
48
|
os.makedirs(local_directory + f'logs/', exist_ok=True)
|
|
41
49
|
os.makedirs(local_directory + f'lc/', exist_ok=True)
|
|
42
50
|
os.makedirs(local_directory + f'epsf/', exist_ok=True)
|
|
51
|
+
os.makedirs(local_directory + f'plots/', exist_ok=True)
|
|
43
52
|
os.makedirs(local_directory + f'source/', exist_ok=True)
|
|
44
53
|
print(f'Target: {target}')
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
54
|
+
if ffi.upper() == 'TICA':
|
|
55
|
+
warnings.warn('TICA support is experimental; Tesscut product availability may be limited.')
|
|
56
|
+
|
|
57
|
+
def _parse_tic_id(t):
|
|
58
|
+
if not isinstance(t, str):
|
|
59
|
+
return None
|
|
60
|
+
s = t.strip()
|
|
61
|
+
if s.upper().startswith('TIC'):
|
|
62
|
+
parts = s.split()
|
|
63
|
+
if len(parts) > 1 and parts[1].isdigit():
|
|
64
|
+
return int(parts[1])
|
|
65
|
+
s = s[3:].strip()
|
|
66
|
+
return int(s) if s.isdigit() else None
|
|
67
|
+
def _is_tic_id(t):
|
|
68
|
+
if not isinstance(t, str):
|
|
69
|
+
return False
|
|
70
|
+
s = t.strip()
|
|
71
|
+
return s.upper().startswith('TIC') or s.isdigit()
|
|
72
|
+
|
|
73
|
+
radius_deg = 42 * 0.707 / 3600
|
|
74
|
+
target_ = None
|
|
75
|
+
is_tic = _is_tic_id(target) and _parse_tic_id(target) is not None
|
|
76
|
+
try:
|
|
77
|
+
target_ = Catalogs.query_object(target, radius=radius_deg, catalog="Gaia", version=2)
|
|
78
|
+
except requests.exceptions.RequestException as e:
|
|
79
|
+
warnings.warn(f'MAST name lookup failed for "{target}": {e}')
|
|
80
|
+
|
|
81
|
+
if target_ is None or len(target_) == 0:
|
|
82
|
+
if is_tic:
|
|
83
|
+
raise RuntimeError(
|
|
84
|
+
f'MAST name lookup failed for TIC target "{target}". Please retry when MAST is available.'
|
|
85
|
+
)
|
|
86
|
+
try:
|
|
87
|
+
if not isinstance(target, str):
|
|
88
|
+
target_ = Catalogs.query_object(target.name, radius=5 * 21 * 0.707 / 3600, catalog="Gaia", version=2)
|
|
89
|
+
except Exception as e:
|
|
90
|
+
warnings.warn(f'MAST name lookup (target.name) failed: {e}')
|
|
91
|
+
|
|
92
|
+
if target_ is None or len(target_) == 0:
|
|
93
|
+
raise RuntimeError(
|
|
94
|
+
f'Unable to resolve target "{target}". MAST name lookup appears unavailable; '
|
|
95
|
+
f'try passing RA/Dec or a different target.'
|
|
96
|
+
)
|
|
97
|
+
|
|
48
98
|
ra = target_[0]['ra']
|
|
49
99
|
dec = target_[0]['dec']
|
|
50
100
|
coord = SkyCoord(ra=ra, dec=dec, unit=(u.degree, u.degree), frame='icrs')
|
|
51
101
|
sector_table = Tesscut.get_sectors(coordinates=coord)
|
|
52
102
|
print(sector_table)
|
|
103
|
+
print(f'Found {len(sector_table)} sector(s) for this target.')
|
|
53
104
|
if get_all_lc:
|
|
54
105
|
name = None
|
|
55
106
|
else:
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
107
|
+
if is_tic:
|
|
108
|
+
TIC_ID = int(target.strip().split()[-1])
|
|
109
|
+
with _dot_wait('Resolving TIC -> Gaia DR3 designation via TAP'):
|
|
110
|
+
ticvals = Catalogs.query_object(
|
|
111
|
+
f'TIC {TIC_ID}',
|
|
112
|
+
radius=3.0 * units.arcsec.to('degree'),
|
|
113
|
+
catalog="tic"
|
|
114
|
+
).to_pandas()
|
|
115
|
+
if ticvals.shape[0] > 1:
|
|
116
|
+
ticvals = ticvals[ticvals.ID.astype(int).isin([TIC_ID])].reset_index(drop=True)
|
|
117
|
+
tmpgaiavals = TapPlus(url="https://gea.esac.esa.int/tap-server/tap").launch_job(
|
|
118
|
+
"SELECT TOP 1 * FROM gaiadr3.dr2_neighbourhood WHERE dr2_source_id = {}".format(
|
|
119
|
+
ticvals.loc[0, 'GAIA'])).get_results().to_pandas()
|
|
120
|
+
gaiavals = TapPlus(url="https://gea.esac.esa.int/tap-server/tap").launch_job(
|
|
121
|
+
"SELECT TOP 1 * FROM gaiadr3.gaia_source WHERE source_id = {}".format(
|
|
122
|
+
tmpgaiavals.loc[0, 'dr3_source_id'])).get_results().to_pandas()
|
|
123
|
+
dr2_id = tmpgaiavals.loc[0, 'dr2_source_id']
|
|
124
|
+
dr3_designation = gaiavals.loc[0, 'designation'.upper()]
|
|
125
|
+
print(f'DR2 source_id: {dr2_id}; DR3 designation: {dr3_designation}')
|
|
126
|
+
name = f'{dr3_designation}'
|
|
59
127
|
elif transient is not None:
|
|
60
128
|
name = transient[0]
|
|
61
129
|
else:
|
|
130
|
+
try:
|
|
131
|
+
catalogdata = Catalogs.query_object(str(target), radius=0.02, catalog="TIC")
|
|
132
|
+
except requests.exceptions.RequestException as e:
|
|
133
|
+
raise RuntimeError(f'MAST name lookup failed for "{target}": {e}')
|
|
62
134
|
name = int(np.array(catalogdata['ID'])[0])
|
|
63
135
|
print("Since the provided target is not TIC ID, the resulted light curve with get_all_lc=False can not be "
|
|
64
136
|
"guaranteed to be the target's light curve. Please check the TIC ID of the output file before using "
|
|
65
137
|
"the light curve or try use TIC ID as the target in the format of 'TIC 12345678'.")
|
|
66
138
|
if type(sector) == int:
|
|
67
139
|
print(f'Only processing Sector {sector}.')
|
|
68
|
-
print('Downloading
|
|
140
|
+
print('Downloading data from MAST and Gaia.')
|
|
141
|
+
print(f'MAST Tesscut timeout set to {mast_timeout}s.')
|
|
69
142
|
source = ffi_cut(target=target, size=size, local_directory=local_directory, sector=sector,
|
|
70
|
-
limit_mag=limit_mag, transient=transient) # sector
|
|
143
|
+
limit_mag=limit_mag, transient=transient, ffi=ffi, mast_timeout=mast_timeout) # sector
|
|
71
144
|
source.select_sector(sector=sector)
|
|
72
145
|
epsf(source, factor=2, sector=source.sector, target=target, local_directory=local_directory,
|
|
73
|
-
name=name, limit_mag=limit_mag, save_aper=save_aper, prior=prior)
|
|
146
|
+
name=name, limit_mag=limit_mag, save_aper=save_aper, prior=prior, ffi=ffi)
|
|
74
147
|
elif first_sector_only:
|
|
75
148
|
print(f'Only processing the first sector the target is observed in: Sector {sector_table["sector"][0]}.')
|
|
76
|
-
print('Downloading
|
|
149
|
+
print('Downloading data from MAST and Gaia.')
|
|
150
|
+
print(f'MAST Tesscut timeout set to {mast_timeout}s.')
|
|
77
151
|
sector = sector_table["sector"][0]
|
|
78
152
|
source = ffi_cut(target=target, size=size, local_directory=local_directory, sector=sector,
|
|
79
|
-
limit_mag=limit_mag, transient=transient) # sector
|
|
153
|
+
limit_mag=limit_mag, transient=transient, ffi=ffi, mast_timeout=mast_timeout) # sector
|
|
80
154
|
source.select_sector(sector=source.sector_table['sector'][0])
|
|
81
155
|
epsf(source, factor=2, sector=source.sector, target=target, local_directory=local_directory,
|
|
82
|
-
name=name, limit_mag=limit_mag, save_aper=save_aper, prior=prior)
|
|
156
|
+
name=name, limit_mag=limit_mag, save_aper=save_aper, prior=prior, ffi=ffi)
|
|
83
157
|
elif last_sector_only:
|
|
84
158
|
print(f'Only processing the last sector the target is observed in: Sector {sector_table["sector"][-1]}.')
|
|
85
|
-
print('Downloading
|
|
159
|
+
print('Downloading data from MAST and Gaia.')
|
|
160
|
+
print(f'MAST Tesscut timeout set to {mast_timeout}s.')
|
|
86
161
|
sector = sector_table["sector"][-1]
|
|
87
162
|
source = ffi_cut(target=target, size=size, local_directory=local_directory, sector=sector,
|
|
88
|
-
limit_mag=limit_mag, transient=transient) # sector
|
|
163
|
+
limit_mag=limit_mag, transient=transient, ffi=ffi, mast_timeout=mast_timeout) # sector
|
|
89
164
|
source.select_sector(sector=source.sector_table['sector'][-1])
|
|
90
165
|
epsf(source, factor=2, sector=source.sector, target=target, local_directory=local_directory,
|
|
91
|
-
name=name, limit_mag=limit_mag, save_aper=save_aper, prior=prior)
|
|
166
|
+
name=name, limit_mag=limit_mag, save_aper=save_aper, prior=prior, ffi=ffi)
|
|
92
167
|
elif sector == None:
|
|
93
168
|
print(f'Processing all available sectors of the target.')
|
|
94
|
-
print('Downloading
|
|
169
|
+
print('Downloading data from MAST and Gaia.')
|
|
170
|
+
print(f'MAST Tesscut timeout set to {mast_timeout}s.')
|
|
95
171
|
for j in range(len(sector_table)):
|
|
96
172
|
print(f'################################################')
|
|
97
|
-
print(f'Downloading Sector {sector_table["sector"][j]}.')
|
|
173
|
+
print(f'Downloading Sector {sector_table["sector"][j]} (product={ffi}).')
|
|
98
174
|
source = ffi_cut(target=target, size=size, local_directory=local_directory,
|
|
99
175
|
sector=sector_table['sector'][j],
|
|
100
|
-
limit_mag=limit_mag, transient=transient)
|
|
176
|
+
limit_mag=limit_mag, transient=transient, ffi=ffi, mast_timeout=mast_timeout)
|
|
101
177
|
epsf(source, factor=2, sector=source.sector, target=target, local_directory=local_directory,
|
|
102
|
-
name=name, limit_mag=limit_mag, save_aper=save_aper, prior=prior)
|
|
178
|
+
name=name, limit_mag=limit_mag, save_aper=save_aper, prior=prior, ffi=ffi)
|
|
103
179
|
else:
|
|
104
180
|
print(
|
|
105
181
|
f'Processing all available sectors of the target in a single run. Note that if the number of sectors is '
|
|
106
182
|
f'large, the download might cause a timeout error from MAST.')
|
|
107
|
-
print('Downloading
|
|
183
|
+
print('Downloading data from MAST and Gaia.')
|
|
184
|
+
print(f'MAST Tesscut timeout set to {mast_timeout}s.')
|
|
108
185
|
source = ffi_cut(target=target, size=size, local_directory=local_directory, sector=sector,
|
|
109
|
-
limit_mag=limit_mag, transient=transient) # sector
|
|
186
|
+
limit_mag=limit_mag, transient=transient, ffi=ffi, mast_timeout=mast_timeout) # sector
|
|
110
187
|
for j in range(len(source.sector_table)):
|
|
111
188
|
source.select_sector(sector=source.sector_table['sector'][j])
|
|
112
189
|
epsf(source, factor=2, sector=source.sector, target=target, local_directory=local_directory,
|
|
113
|
-
name=name, limit_mag=limit_mag, save_aper=save_aper, prior=prior)
|
|
190
|
+
name=name, limit_mag=limit_mag, save_aper=save_aper, prior=prior, ffi=ffi)
|
|
114
191
|
|
|
115
192
|
|
|
116
193
|
def search_stars(i, sector=1, tics=None, local_directory=None):
|
|
@@ -222,83 +299,123 @@ def plot_aperture(local_directory=None, kind='cal_aper_flux'):
|
|
|
222
299
|
])
|
|
223
300
|
data = np.append(data, data_, axis=1)
|
|
224
301
|
np.savetxt(f'{local_directory}TESS_TOI-5344_5_5_aper.csv', data, delimiter=',')
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
302
|
+
def _phase_centered(t, period, t0):
|
|
303
|
+
# phase in [-0.5, 0.5)
|
|
304
|
+
return ((t - t0)/period + 0.5) % 1.0 - 0.5
|
|
305
|
+
|
|
306
|
+
def phasebin_centered(time, meas, meas_err, period, t0, binsize_days=None, nbins=None):
|
|
307
|
+
phase = _phase_centered(time, period, t0)
|
|
308
|
+
|
|
309
|
+
if nbins is None:
|
|
310
|
+
if binsize_days is None:
|
|
311
|
+
raise ValueError("Provide binsize_days (days) or nbins.")
|
|
312
|
+
bw = binsize_days / period
|
|
313
|
+
nbins = max(1, int(np.floor(1.0 / bw))) # at least one bin
|
|
314
|
+
|
|
315
|
+
edges = np.linspace(-0.5, 0.5, nbins + 1)
|
|
316
|
+
centers = 0.5 * (edges[:-1] + edges[1:])
|
|
317
|
+
|
|
318
|
+
# Bin index for each point
|
|
319
|
+
idx = np.digitize(phase, edges) - 1
|
|
320
|
+
valid = (idx >= 0) & (idx < nbins) & np.isfinite(meas) & np.isfinite(meas_err)
|
|
321
|
+
|
|
322
|
+
# Build weights; if all invalid or <=0, fall back to unweighted
|
|
323
|
+
w = np.zeros_like(meas, dtype=float)
|
|
324
|
+
with np.errstate(divide="ignore", invalid="ignore"):
|
|
325
|
+
w = 1.0 / np.square(meas_err)
|
|
326
|
+
badw = ~np.isfinite(w) | (w <= 0)
|
|
327
|
+
if np.all(~valid) or np.all(badw[valid]):
|
|
328
|
+
# fallback to ones for all finite measurements
|
|
329
|
+
valid = (idx >= 0) & (idx < nbins) & np.isfinite(meas)
|
|
330
|
+
w = np.ones_like(meas, dtype=float)
|
|
331
|
+
|
|
332
|
+
# Apply validity mask
|
|
333
|
+
idx_v = idx[valid]
|
|
334
|
+
w_v = w[valid]
|
|
335
|
+
y_v = meas[valid]
|
|
336
|
+
|
|
337
|
+
# Accumulate per-bin sums
|
|
338
|
+
wsum = np.bincount(idx_v, weights=w_v, minlength=nbins)
|
|
339
|
+
ysum = np.bincount(idx_v, weights=w_v * y_v, minlength=nbins)
|
|
340
|
+
|
|
341
|
+
# Bin mean and error (1/sqrt(sum of weights)); if unweighted, this becomes 1/sqrt(N)
|
|
342
|
+
y = np.divide(ysum, wsum, out=np.full(nbins, np.nan), where=wsum > 0)
|
|
343
|
+
yerr = np.divide(1.0, np.sqrt(wsum), out=np.full(nbins, np.nan), where=wsum > 0)
|
|
344
|
+
|
|
345
|
+
m = wsum > 0
|
|
346
|
+
return centers[m], y[m], yerr[m]
|
|
347
|
+
|
|
348
|
+
def plot_pf_lc(local_directory=None, period=None, mid_transit_tbjd=None, kind='cal_aper_flux',
|
|
349
|
+
binsize_days=60/86400, nbins=None):
|
|
350
|
+
files = sorted(glob(f'{local_directory}*.fits'))
|
|
229
351
|
os.makedirs(f'{local_directory}plots/', exist_ok=True)
|
|
352
|
+
|
|
230
353
|
fig = plt.figure(figsize=(13, 5))
|
|
231
|
-
t_all =
|
|
232
|
-
f_all =
|
|
233
|
-
f_err_all =
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
time_out, meas_out, meas_err_out = timebin(time=t_all % period, meas=f_all,
|
|
277
|
-
meas_err=f_err_all,
|
|
278
|
-
binsize=300 / 86400)
|
|
279
|
-
plt.errorbar(np.array(time_out) / period, meas_out, meas_err_out, c=f'r', ls='', elinewidth=1.5,
|
|
280
|
-
marker='.', ms=8, zorder=3, label=f'All sectors')
|
|
281
|
-
|
|
282
|
-
plt.ylim(0.998, 1.001)
|
|
283
|
-
# plt.xlim(0.3, 0.43)
|
|
354
|
+
t_all = []
|
|
355
|
+
f_all = []
|
|
356
|
+
f_err_all = []
|
|
357
|
+
ticid = None
|
|
358
|
+
n_used = 0
|
|
359
|
+
|
|
360
|
+
for path in files:
|
|
361
|
+
with fits.open(path, mode='denywrite') as hdul:
|
|
362
|
+
hdr = hdul[0].header
|
|
363
|
+
dat = hdul[1].data
|
|
364
|
+
ticid = hdr.get("TICID", ticid)
|
|
365
|
+
|
|
366
|
+
# Good-time mask
|
|
367
|
+
q = (dat['TESS_flags'] == 0) & (dat['TGLC_flags'] == 0)
|
|
368
|
+
|
|
369
|
+
if len(dat[kind]) == len(dat['time']):
|
|
370
|
+
t = dat['time'][q]
|
|
371
|
+
f = dat[kind][q]
|
|
372
|
+
ferr = np.full(len(t), hdul[1].header['CAPE_ERR'], dtype=float)
|
|
373
|
+
|
|
374
|
+
# Scatter (phase-folded, centered on mid-transit)
|
|
375
|
+
ph = _phase_centered(t, period, mid_transit_tbjd)
|
|
376
|
+
# plt.errorbar(ph, f, ferr, c='silver', ls='', elinewidth=0.1,
|
|
377
|
+
# marker='.', ms=3, zorder=2)
|
|
378
|
+
plt.scatter(ph, f, c='silver', s=20, marker='.', zorder=2) # s ~ ms^2
|
|
379
|
+
t_all.append(t); f_all.append(f); f_err_all.append(ferr)
|
|
380
|
+
n_used += 1
|
|
381
|
+
|
|
382
|
+
if n_used == 0:
|
|
383
|
+
plt.close(fig)
|
|
384
|
+
raise RuntimeError("No valid data to plot.")
|
|
385
|
+
|
|
386
|
+
t_all = np.concatenate(t_all)
|
|
387
|
+
f_all = np.concatenate(f_all)
|
|
388
|
+
f_err_all = np.concatenate(f_err_all)
|
|
389
|
+
print(f_err_all)
|
|
390
|
+
# Phase-bin AFTER fold
|
|
391
|
+
ph_c, f_c, f_cerr = phasebin_centered(
|
|
392
|
+
time=t_all, meas=f_all, meas_err=f_err_all,
|
|
393
|
+
period=period, t0=mid_transit_tbjd,
|
|
394
|
+
binsize_days=binsize_days, nbins=nbins
|
|
395
|
+
)
|
|
396
|
+
plt.errorbar(ph_c, f_c, f_cerr, c='r', ls='', elinewidth=1.5,
|
|
397
|
+
marker='.', ms=8, zorder=3, label='All sectors (binned)')
|
|
398
|
+
plt.ylim(0., 2.)
|
|
284
399
|
plt.legend()
|
|
400
|
+
title = f'TIC_{ticid} with {n_used} sector(s) of data, {kind}'
|
|
285
401
|
plt.title(title)
|
|
286
|
-
|
|
287
|
-
#
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
plt.vlines(x=
|
|
291
|
-
|
|
402
|
+
|
|
403
|
+
# Zoom ±1% of period around transit (now at phase 0)
|
|
404
|
+
dphi = 0.05 # = 1% of phase since centered
|
|
405
|
+
plt.xlim(-dphi, dphi)
|
|
406
|
+
plt.vlines(x=0.0, ymin=0, ymax=2, ls='dotted', colors='grey')
|
|
407
|
+
|
|
408
|
+
plt.xlabel('Phase (centered at mid-transit)')
|
|
292
409
|
plt.ylabel('Normalized flux')
|
|
410
|
+
plt.tight_layout()
|
|
293
411
|
plt.savefig(f'{local_directory}/plots/{title}.png', dpi=300)
|
|
294
412
|
plt.close(fig)
|
|
295
413
|
|
|
296
|
-
|
|
297
|
-
def plot_contamination(local_directory=None, gaia_dr3=None, ymin=None, ymax=None, pm_years=3000):
|
|
414
|
+
# newest
|
|
415
|
+
def plot_contamination(local_directory=None, gaia_dr3=None, ymin=None, ymax=None, pm_years=3000, detrend=True):
|
|
298
416
|
sns.set(rc={'font.family': 'serif', 'font.serif': 'DejaVu Serif', 'font.size': 12,
|
|
299
417
|
'axes.edgecolor': '0.2', 'axes.labelcolor': '0.', 'xtick.color': '0.', 'ytick.color': '0.',
|
|
300
|
-
'axes.facecolor': '0.95',
|
|
301
|
-
|
|
418
|
+
'axes.facecolor': '0.95', 'grid.color': '0.9'})
|
|
302
419
|
files = glob(f'{local_directory}lc/*{gaia_dr3}*.fits')
|
|
303
420
|
os.makedirs(f'{local_directory}plots/', exist_ok=True)
|
|
304
421
|
for i in range(len(files)):
|
|
@@ -327,10 +444,10 @@ def plot_contamination(local_directory=None, gaia_dr3=None, ymin=None, ymax=None
|
|
|
327
444
|
np.nanmedian(
|
|
328
445
|
source.flux[:, round(star_y) - 2:round(star_y) + 3, round(star_x) - 2:round(star_x) + 3],
|
|
329
446
|
axis=0))
|
|
330
|
-
fig = plt.figure(constrained_layout=False, figsize=(
|
|
447
|
+
fig = plt.figure(constrained_layout=False, figsize=(15, 9))
|
|
331
448
|
gs = fig.add_gridspec(21, 10)
|
|
332
|
-
gs.update(wspace=0.
|
|
333
|
-
ax0 = fig.add_subplot(gs[:
|
|
449
|
+
gs.update(wspace=0.05, hspace=0.15)
|
|
450
|
+
ax0 = fig.add_subplot(gs[:9, :3])
|
|
334
451
|
ax0.imshow(np.median(source.flux, axis=0), cmap='RdBu', vmin=-max_flux, vmax=max_flux, origin='lower')
|
|
335
452
|
ax0.set_xlabel('x pixel')
|
|
336
453
|
ax0.set_ylabel('y pixel')
|
|
@@ -340,7 +457,7 @@ def plot_contamination(local_directory=None, gaia_dr3=None, ymin=None, ymax=None
|
|
|
340
457
|
ax0.scatter(source.gaia[f'sector_{sector}_x'][nearby_stars[nearby_stars != star_num[0][0]]],
|
|
341
458
|
source.gaia[f'sector_{sector}_y'][nearby_stars[nearby_stars != star_num[0][0]]],
|
|
342
459
|
s=30, c='r', edgecolor='black', linewidth=1, label='background stars')
|
|
343
|
-
|
|
460
|
+
ax0.grid(False)
|
|
344
461
|
for l in range(len(nearby_stars)):
|
|
345
462
|
index = np.where(
|
|
346
463
|
source.tic['dr3_source_id'] == int(source.gaia['DESIGNATION'][nearby_stars[l]].split(' ')[-1]))
|
|
@@ -380,25 +497,28 @@ def plot_contamination(local_directory=None, gaia_dr3=None, ymin=None, ymax=None
|
|
|
380
497
|
ax0.vlines(round(star_x) + 2.5, round(star_y) - 2.5, round(star_y) + 2.5, colors='k', lw=1.2)
|
|
381
498
|
ax0.hlines(round(star_y) - 2.5, round(star_x) - 2.5, round(star_x) + 2.5, colors='k', lw=1.2)
|
|
382
499
|
ax0.hlines(round(star_y) + 2.5, round(star_x) - 2.5, round(star_x) + 2.5, colors='k', lw=1.2)
|
|
383
|
-
|
|
500
|
+
try:
|
|
501
|
+
t_, y_, x_ = np.shape(hdul[0].data)
|
|
502
|
+
except ValueError:
|
|
503
|
+
warnings.warn('Light curves need to have the primary hdu. Set save_aperture=True when producing the light curve to enable this plot.')
|
|
504
|
+
sys.exit()
|
|
384
505
|
max_flux = np.max(
|
|
385
506
|
np.median(source.flux[:, int(star_y) - 2:int(star_y) + 3, int(star_x) - 2:int(star_x) + 3], axis=0))
|
|
386
|
-
sns.set(rc={'font.family': 'serif', 'font.serif': 'DejaVu Serif', 'font.size': 12,
|
|
387
|
-
'axes.edgecolor': '0.2', 'axes.labelcolor': '0.', 'xtick.color': '0.', 'ytick.color': '0.',
|
|
388
|
-
'axes.facecolor': '0.95', 'grid.color': '0.9'})
|
|
389
507
|
arrays = []
|
|
390
508
|
for j in range(y_):
|
|
391
509
|
for k in range(x_):
|
|
392
510
|
ax_ = fig.add_subplot(gs[(19 - 2 * j):(21 - 2 * j), (2 * k):(2 + 2 * k)])
|
|
393
511
|
ax_.patch.set_facecolor('#4682B4')
|
|
394
512
|
ax_.patch.set_alpha(min(1, max(0, 5 * np.nanmedian(hdul[0].data[:, j, k]) / max_flux)))
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
513
|
+
if detrend:
|
|
514
|
+
_, trend = flatten(hdul[1].data['time'][q],
|
|
515
|
+
hdul[0].data[:, j, k][q] - np.nanmin(hdul[0].data[:, j, k][q]) + 1000,
|
|
516
|
+
window_length=1, method='biweight', return_trend=True)
|
|
517
|
+
cal_aper = (hdul[0].data[:, j, k][q] - np.nanmin(
|
|
518
|
+
hdul[0].data[:, j, k][q]) + 1000 - trend) / np.nanmedian(
|
|
519
|
+
hdul[0].data[:, j, k][q]) + 1
|
|
520
|
+
else:
|
|
521
|
+
cal_aper = (hdul[0].data[:, j, k][q]) / np.nanmedian(hdul[0].data[:, j, k][q])
|
|
402
522
|
if 1 <= j <= 3 and 1 <= k <= 3:
|
|
403
523
|
arrays.append(cal_aper)
|
|
404
524
|
ax_.plot(hdul[1].data['time'][q], cal_aper, '.k', ms=0.5)
|
|
@@ -425,13 +545,13 @@ def plot_contamination(local_directory=None, gaia_dr3=None, ymin=None, ymax=None
|
|
|
425
545
|
print(f"Interquartile Range (IQR): {iqr}")
|
|
426
546
|
std_dev = np.std(median_abs_diffs)
|
|
427
547
|
print(f"Standard Deviation: {std_dev}")
|
|
428
|
-
ax1 = fig.add_subplot(gs[:
|
|
548
|
+
ax1 = fig.add_subplot(gs[:9, 3:6])
|
|
429
549
|
ax1.hist(median_abs_diffs, color='k', edgecolor='k', facecolor='none', rwidth=0.8, linewidth=2)
|
|
430
550
|
ax1.set_box_aspect(1)
|
|
431
|
-
ax1.set_title(f'Distribution of the MADs among combinations of the center 3*3 pixels')
|
|
432
|
-
ax1.set_xlabel('MAD between combinations of
|
|
551
|
+
# ax1.set_title(f'Distribution of the MADs among combinations of the center 3*3 pixels')
|
|
552
|
+
ax1.set_xlabel('MAD between combinations of fluxes')
|
|
433
553
|
ax1.set_ylabel('Counts')
|
|
434
|
-
text_ax = fig.add_axes([0.
|
|
554
|
+
text_ax = fig.add_axes([0.6, 0.95, 0.3, 0.3]) # [left, bottom, width, height] in figure coordinates
|
|
435
555
|
text_ax.axis('off') # Turn off axis lines, ticks, etc.
|
|
436
556
|
text_ax.text(0., 0., f"Gaia DR3 {gaia_dr3} \n"
|
|
437
557
|
f" ←← TESS SPOC FFI and TIC/Gaia stars with proper motions. \n"
|
|
@@ -440,7 +560,6 @@ def plot_contamination(local_directory=None, gaia_dr3=None, ymin=None, ymax=None
|
|
|
440
560
|
f" ↓ Fluxes of each pixels after contaminations are removed. \n"
|
|
441
561
|
f" The fluxes are normalized and detrended. The background \n"
|
|
442
562
|
f" color shows the pixel brightness after the decontamination. \n"
|
|
443
|
-
f"\n"
|
|
444
563
|
f"How to interpret these plots: \n"
|
|
445
564
|
f" If the signals you are interested in (i.e. transits, \n"
|
|
446
565
|
f" eclipses, variable stars) show similar amplitudes in \n"
|
|
@@ -455,15 +574,14 @@ def plot_contamination(local_directory=None, gaia_dr3=None, ymin=None, ymax=None
|
|
|
455
574
|
f"Interquartile Range (IQR): {iqr:05f} \n"
|
|
456
575
|
f"Standard Deviation: {std_dev:05f}", transform=text_ax.transAxes, ha='left',
|
|
457
576
|
va='top')
|
|
458
|
-
plt.subplots_adjust(top=.
|
|
577
|
+
plt.subplots_adjust(top=.97, bottom=0.06, left=0.05, right=0.95)
|
|
459
578
|
plt.savefig(
|
|
460
579
|
f'{local_directory}plots/contamination_sector_{hdul[0].header["SECTOR"]:04d}_Gaia_DR3_{gaia_dr3}.pdf',
|
|
461
|
-
dpi=300)
|
|
580
|
+
dpi=300,)
|
|
462
581
|
# plt.savefig(f'{local_directory}plots/contamination_sector_{hdul[0].header["SECTOR"]:04d}_Gaia_DR3_{gaia_dr3}.png',
|
|
463
582
|
# dpi=600)
|
|
464
583
|
plt.close()
|
|
465
584
|
|
|
466
|
-
|
|
467
585
|
def plot_epsf(local_directory=None):
|
|
468
586
|
files = glob(f'{local_directory}epsf/*.npy')
|
|
469
587
|
os.makedirs(f'{local_directory}plots/', exist_ok=True)
|
|
@@ -497,7 +615,7 @@ def choose_prior(tics, local_directory=None, priors=np.logspace(-5, 0, 100)):
|
|
|
497
615
|
# plt.show()
|
|
498
616
|
|
|
499
617
|
|
|
500
|
-
def get_tglc_lc(tics=None, method='query', server=1, directory=None, prior=None):
|
|
618
|
+
def get_tglc_lc(tics=None, method='query', server=1, directory=None, prior=None, ffi='SPOC', mast_timeout=3600):
|
|
501
619
|
if method == 'query':
|
|
502
620
|
for i in range(len(tics)):
|
|
503
621
|
target = f'TIC {tics[i]}'
|
|
@@ -505,22 +623,23 @@ def get_tglc_lc(tics=None, method='query', server=1, directory=None, prior=None)
|
|
|
505
623
|
os.makedirs(local_directory, exist_ok=True)
|
|
506
624
|
tglc_lc(target=target, local_directory=local_directory, size=90, save_aper=True, limit_mag=16,
|
|
507
625
|
get_all_lc=False, first_sector_only=False, last_sector_only=False, sector=None, prior=prior,
|
|
508
|
-
transient=None)
|
|
509
|
-
plot_lc(local_directory=f'{directory}TIC {tics[i]}/', kind='cal_aper_flux')
|
|
626
|
+
transient=None, ffi=ffi, mast_timeout=mast_timeout)
|
|
627
|
+
plot_lc(local_directory=f'{directory}TIC {tics[i]}/', kind='cal_aper_flux', ffi=ffi)
|
|
510
628
|
if method == 'search':
|
|
511
629
|
star_spliter(server=server, tics=tics, local_directory=directory)
|
|
512
630
|
|
|
513
631
|
|
|
514
632
|
if __name__ == '__main__':
|
|
515
|
-
tics = [16005254]
|
|
516
|
-
directory = f'/
|
|
633
|
+
tics = [16005254] # can be a list of TIC IDs
|
|
634
|
+
directory = f'/Users/tehan/Downloads/'
|
|
635
|
+
# directory = f'/home/tehan/data/WD/'
|
|
517
636
|
os.makedirs(directory, exist_ok=True)
|
|
518
|
-
get_tglc_lc(tics=tics,
|
|
637
|
+
get_tglc_lc(tics=tics, directory=directory, ffi='SPOC')
|
|
519
638
|
# plot_lc(local_directory=f'{directory}TIC {tics[0]}/', kind='cal_aper_flux')
|
|
520
639
|
# plot_lc(local_directory=f'/home/tehan/Documents/tglc/TIC 16005254/', kind='cal_aper_flux', ylow=0.9, yhigh=1.1)
|
|
521
640
|
# plot_contamination(local_directory=f'{directory}TIC {tics[0]}/', gaia_dr3=5751990597042725632)
|
|
522
641
|
# plot_epsf(local_directory=f'{directory}TIC {tics[0]}/')
|
|
523
|
-
|
|
524
|
-
|
|
642
|
+
plot_pf_lc(local_directory=f'{directory}TIC {tics[0]}/lc/', period=1.4079405, mid_transit_tbjd=1779.3750828,
|
|
643
|
+
kind='cal_aper_flux')
|
|
525
644
|
# plot_pf_lc(local_directory=f'{directory}TIC {tics[0]}/lc/', period=0.23818244, mid_transit_tbjd=1738.71248,
|
|
526
|
-
# kind='cal_aper_flux')
|
|
645
|
+
# kind='cal_aper_flux')
|