tglc 0.6.4__tar.gz → 0.6.6__tar.gz
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-0.6.4/tglc.egg-info → tglc-0.6.6}/PKG-INFO +15 -2
- {tglc-0.6.4 → tglc-0.6.6}/README.rst +1 -0
- {tglc-0.6.4 → tglc-0.6.6}/setup.py +4 -4
- tglc-0.6.6/tglc/__init__.py +3 -0
- {tglc-0.6.4 → tglc-0.6.6}/tglc/effective_psf.py +5 -2
- {tglc-0.6.4 → tglc-0.6.6}/tglc/ffi.py +1 -1
- {tglc-0.6.4 → tglc-0.6.6}/tglc/quick_lc.py +121 -67
- {tglc-0.6.4 → tglc-0.6.6}/tglc/target_lightcurve.py +14 -5
- {tglc-0.6.4 → tglc-0.6.6/tglc.egg-info}/PKG-INFO +15 -2
- {tglc-0.6.4 → tglc-0.6.6}/tglc.egg-info/requires.txt +2 -1
- tglc-0.6.4/tglc/__init__.py +0 -3
- {tglc-0.6.4 → tglc-0.6.6}/LICENSE +0 -0
- {tglc-0.6.4 → tglc-0.6.6}/MANIFEST.in +0 -0
- {tglc-0.6.4 → tglc-0.6.6}/setup.cfg +0 -0
- {tglc-0.6.4 → tglc-0.6.6}/tglc/background_mask/__init__.py +0 -0
- {tglc-0.6.4 → tglc-0.6.6}/tglc/background_mask/median_mask.fits +0 -0
- {tglc-0.6.4 → tglc-0.6.6}/tglc/ffi_cut.py +0 -0
- {tglc-0.6.4 → tglc-0.6.6}/tglc/lc_plot.py +0 -0
- {tglc-0.6.4 → tglc-0.6.6}/tglc/mast.py +0 -0
- {tglc-0.6.4 → tglc-0.6.6}/tglc/run.py +0 -0
- {tglc-0.6.4 → tglc-0.6.6}/tglc/source_output.py +0 -0
- {tglc-0.6.4 → tglc-0.6.6}/tglc.egg-info/SOURCES.txt +0 -0
- {tglc-0.6.4 → tglc-0.6.6}/tglc.egg-info/dependency_links.txt +0 -0
- {tglc-0.6.4 → tglc-0.6.6}/tglc.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: tglc
|
|
3
|
-
Version: 0.6.
|
|
3
|
+
Version: 0.6.6
|
|
4
4
|
Summary: TESS-Gaia Light Curve
|
|
5
5
|
Home-page: https://github.com/TeHanHunter/TESS_Gaia_Light_Curve
|
|
6
6
|
Author: Te Han
|
|
@@ -8,9 +8,21 @@ Author-email: tehanhunter@gmail.com
|
|
|
8
8
|
Classifier: Programming Language :: Python :: 3
|
|
9
9
|
Classifier: License :: OSI Approved :: MIT License
|
|
10
10
|
Classifier: Operating System :: OS Independent
|
|
11
|
-
Requires-Python: >=3.8
|
|
11
|
+
Requires-Python: >=3.8, <3.13
|
|
12
12
|
Description-Content-Type: text/x-rst
|
|
13
13
|
License-File: LICENSE
|
|
14
|
+
Requires-Dist: astropy>=5.1
|
|
15
|
+
Requires-Dist: astroquery==0.4.7
|
|
16
|
+
Requires-Dist: matplotlib
|
|
17
|
+
Requires-Dist: numpy
|
|
18
|
+
Requires-Dist: oauthlib
|
|
19
|
+
Requires-Dist: requests
|
|
20
|
+
Requires-Dist: scipy
|
|
21
|
+
Requires-Dist: threadpoolctl
|
|
22
|
+
Requires-Dist: tqdm
|
|
23
|
+
Requires-Dist: wheel
|
|
24
|
+
Requires-Dist: wotan
|
|
25
|
+
Requires-Dist: seaborn
|
|
14
26
|
|
|
15
27
|
==================================
|
|
16
28
|
Introduction
|
|
@@ -18,6 +30,7 @@ Introduction
|
|
|
18
30
|
|
|
19
31
|
TESS-Gaia Light Curve (`TGLC <https://archive.stsci.edu/hlsp/tglc>`_) is a dataset of TESS full-frame image light curves publicly available via the MAST portal. It is fitted with effective PSF and decontaminated with Gaia DR3 and achieved percent-level photometric precision down to 16th TESS magnitude! It unlocks astrophysics to a vast number of dim stars below 12th TESS magnitude. A package called tglc is pip-installable for customized light curve fits.
|
|
20
32
|
|
|
33
|
+
|
|
21
34
|
==================================
|
|
22
35
|
Usage
|
|
23
36
|
==================================
|
|
@@ -4,6 +4,7 @@ Introduction
|
|
|
4
4
|
|
|
5
5
|
TESS-Gaia Light Curve (`TGLC <https://archive.stsci.edu/hlsp/tglc>`_) is a dataset of TESS full-frame image light curves publicly available via the MAST portal. It is fitted with effective PSF and decontaminated with Gaia DR3 and achieved percent-level photometric precision down to 16th TESS magnitude! It unlocks astrophysics to a vast number of dim stars below 12th TESS magnitude. A package called tglc is pip-installable for customized light curve fits.
|
|
6
6
|
|
|
7
|
+
|
|
7
8
|
==================================
|
|
8
9
|
Usage
|
|
9
10
|
==================================
|
|
@@ -6,7 +6,7 @@ with open("README.rst", "r", encoding="utf-8") as fh:
|
|
|
6
6
|
long_description = fh.read()
|
|
7
7
|
setuptools.setup(
|
|
8
8
|
name="tglc",
|
|
9
|
-
version='0.6.
|
|
9
|
+
version='0.6.6',
|
|
10
10
|
author="Te Han",
|
|
11
11
|
author_email="tehanhunter@gmail.com",
|
|
12
12
|
description="TESS-Gaia Light Curve",
|
|
@@ -18,9 +18,9 @@ setuptools.setup(
|
|
|
18
18
|
"License :: OSI Approved :: MIT License",
|
|
19
19
|
"Operating System :: OS Independent",
|
|
20
20
|
],
|
|
21
|
-
install_requires=['astropy>=5.1', 'astroquery', 'matplotlib', 'numpy', 'oauthlib', 'requests', 'scipy',
|
|
22
|
-
'threadpoolctl', 'tqdm', 'wheel', 'wotan'],
|
|
21
|
+
install_requires=['astropy>=5.1', 'astroquery==0.4.7', 'matplotlib', 'numpy', 'oauthlib', 'requests', 'scipy',
|
|
22
|
+
'threadpoolctl', 'tqdm', 'wheel', 'wotan', 'seaborn'],
|
|
23
23
|
packages=setuptools.find_packages(include=['tglc', 'tglc.*']),
|
|
24
|
-
python_requires=">=3.8",
|
|
24
|
+
python_requires=">=3.8, <3.13",
|
|
25
25
|
include_package_data=True
|
|
26
26
|
)
|
|
@@ -191,16 +191,19 @@ def fit_lc(A, source, star_info=None, x=0., y=0., star_num=0, factor=2, psf_size
|
|
|
191
191
|
coord = np.arange(size ** 2).reshape(size, size)
|
|
192
192
|
index = np.array(coord[down:up, left:right]).flatten()
|
|
193
193
|
A_cut = np.zeros((len(index), np.shape(A)[1]))
|
|
194
|
+
A_target = np.zeros((len(index), np.shape(A)[1]))
|
|
194
195
|
for i in range(len(index)):
|
|
195
196
|
A_ = np.zeros(np.shape(A)[-1])
|
|
196
197
|
star_pos = np.where(star_info_num[0] == index[i])[0]
|
|
197
198
|
A_[star_info_num[1][star_pos]] = star_info_num[2][star_pos]
|
|
199
|
+
A_target[i] = A_
|
|
198
200
|
A_cut[i] = A[index[i], :] - A_
|
|
199
201
|
aperture = np.zeros((len(source.time), len(index)))
|
|
200
202
|
for j in range(len(source.time)):
|
|
201
203
|
aperture[j] = np.array(source.flux[j][down:up, left:right]).flatten() - np.dot(A_cut, e_psf[j])
|
|
202
204
|
aperture = aperture.reshape((len(source.time), up - down, right - left))
|
|
203
|
-
|
|
205
|
+
target_5x5 = (np.dot(A_target, np.nanmedian(e_psf, axis=0)).reshape(cut_size, cut_size))
|
|
206
|
+
field_stars_5x5 = (np.dot(A_cut, np.nanmedian(e_psf, axis=0)).reshape(cut_size, cut_size))
|
|
204
207
|
|
|
205
208
|
# psf_lc
|
|
206
209
|
over_size = psf_size * factor + 1
|
|
@@ -262,7 +265,7 @@ def fit_lc(A, source, star_info=None, x=0., y=0., star_num=0, factor=2, psf_size
|
|
|
262
265
|
portion = np.nansum(psf_shape[:, 4:7, 4:7]) / np.nansum(psf_shape)
|
|
263
266
|
# print(np.nansum(psf_shape[:, 5, 5]) / np.nansum(psf_shape))
|
|
264
267
|
# np.save(f'toi-5344_psf_{source.sector}.npy', psf_shape)
|
|
265
|
-
return aperture, psf_lc, y - down, x - left, portion
|
|
268
|
+
return aperture, psf_lc, y - down, x - left, portion, target_5x5, field_stars_5x5
|
|
266
269
|
|
|
267
270
|
|
|
268
271
|
def fit_lc_float_field(A, source, star_info=None, x=np.array([]), y=np.array([]), star_num=0, factor=2, psf_size=11,
|
|
@@ -86,7 +86,7 @@ def convert_gaia_id(catalogdata_tic):
|
|
|
86
86
|
FROM gaiadr3.dr2_neighbourhood
|
|
87
87
|
WHERE dr2_source_id IN {gaia_ids}
|
|
88
88
|
"""
|
|
89
|
-
gaia_array = np.array(catalogdata_tic['GAIA'])
|
|
89
|
+
gaia_array = np.array([str(item) for item in catalogdata_tic['GAIA']], dtype=object)
|
|
90
90
|
gaia_array = gaia_array[gaia_array != 'None']
|
|
91
91
|
# np.save('gaia_array.npy', gaia_array)
|
|
92
92
|
segment = (len(gaia_array) - 1) // 10000
|
|
@@ -14,12 +14,14 @@ 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
|
|
17
19
|
# Tesscut._service_api_connection.TIMEOUT = 6000
|
|
18
|
-
|
|
19
20
|
# warnings.simplefilter('ignore', UserWarning)
|
|
20
21
|
from threadpoolctl import ThreadpoolController, threadpool_limits
|
|
21
22
|
import numpy as np
|
|
22
|
-
|
|
23
|
+
import seaborn as sns
|
|
24
|
+
import itertools
|
|
23
25
|
controller = ThreadpoolController()
|
|
24
26
|
|
|
25
27
|
|
|
@@ -40,10 +42,6 @@ def tglc_lc(target='TIC 264468702', local_directory='', size=90, save_aper=True,
|
|
|
40
42
|
os.makedirs(local_directory + f'lc/', exist_ok=True)
|
|
41
43
|
os.makedirs(local_directory + f'epsf/', exist_ok=True)
|
|
42
44
|
os.makedirs(local_directory + f'source/', exist_ok=True)
|
|
43
|
-
if first_sector_only:
|
|
44
|
-
sector = 'first'
|
|
45
|
-
elif last_sector_only:
|
|
46
|
-
sector = 'last'
|
|
47
45
|
print(f'Target: {target}')
|
|
48
46
|
target_ = Catalogs.query_object(target, radius=42 * 0.707 / 3600, catalog="Gaia", version=2)
|
|
49
47
|
if len(target_) == 0:
|
|
@@ -77,7 +75,7 @@ def tglc_lc(target='TIC 264468702', local_directory='', size=90, save_aper=True,
|
|
|
77
75
|
elif first_sector_only:
|
|
78
76
|
print(f'Only processing the first sector the target is observed in: Sector {sector_table["sector"][0]}.')
|
|
79
77
|
print('Downloading Data from MAST and Gaia ...')
|
|
80
|
-
|
|
78
|
+
sector = sector_table["sector"][0]
|
|
81
79
|
source = ffi_cut(target=target, size=size, local_directory=local_directory, sector=sector,
|
|
82
80
|
limit_mag=limit_mag, transient=transient) # sector
|
|
83
81
|
source.select_sector(sector=source.sector_table['sector'][0])
|
|
@@ -86,6 +84,7 @@ def tglc_lc(target='TIC 264468702', local_directory='', size=90, save_aper=True,
|
|
|
86
84
|
elif last_sector_only:
|
|
87
85
|
print(f'Only processing the last sector the target is observed in: Sector {sector_table["sector"][-1]}.')
|
|
88
86
|
print('Downloading Data from MAST and Gaia ...')
|
|
87
|
+
sector = sector_table["sector"][-1]
|
|
89
88
|
source = ffi_cut(target=target, size=size, local_directory=local_directory, sector=sector,
|
|
90
89
|
limit_mag=limit_mag, transient=transient) # sector
|
|
91
90
|
source.select_sector(sector=source.sector_table['sector'][-1])
|
|
@@ -296,47 +295,58 @@ def plot_pf_lc(local_directory=None, period=None, mid_transit_tbjd=None, kind='c
|
|
|
296
295
|
plt.close(fig)
|
|
297
296
|
|
|
298
297
|
|
|
299
|
-
def plot_contamination(local_directory=None, gaia_dr3=None):
|
|
300
|
-
|
|
298
|
+
def plot_contamination(local_directory=None, gaia_dr3=None, ymin=None, ymax=None, pm_years=3000):
|
|
299
|
+
sns.set(rc={'font.family': 'serif', 'font.serif': 'DejaVu Serif', 'font.size': 12,
|
|
300
|
+
'axes.edgecolor': '0.2', 'axes.labelcolor': '0.', 'xtick.color': '0.', 'ytick.color': '0.',
|
|
301
|
+
'axes.facecolor': '0.95', 'grid.color': '0.9'})
|
|
302
|
+
files = glob(f'{local_directory}lc/*{gaia_dr3}*.fits')
|
|
301
303
|
os.makedirs(f'{local_directory}plots/', exist_ok=True)
|
|
302
304
|
for i in range(len(files)):
|
|
303
305
|
with fits.open(files[i], mode='denywrite') as hdul:
|
|
304
306
|
sector = hdul[0].header['SECTOR']
|
|
307
|
+
q = [a and b for a, b in
|
|
308
|
+
zip(list(hdul[1].data['TESS_flags'] == 0), list(hdul[1].data['TGLC_flags'] == 0))]
|
|
309
|
+
if ymin is None and ymax is None:
|
|
310
|
+
ymin = np.nanmin(hdul[1].data['cal_aper_flux'][q]) - 0.01
|
|
311
|
+
ymax = np.nanmax(hdul[1].data['cal_aper_flux'][q]) + 0.01
|
|
305
312
|
with open(glob(f'{local_directory}source/*_{sector}.pkl')[0], 'rb') as input_:
|
|
306
313
|
source = pickle.load(input_)
|
|
307
314
|
source.select_sector(sector=sector)
|
|
308
315
|
star_num = np.where(source.gaia['DESIGNATION'] == f'Gaia DR3 {gaia_dr3}')
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
plt.close()
|
|
312
|
-
# print(source.gaia[891])
|
|
313
|
-
# print(source.gaia[star_num])
|
|
314
|
-
nearby_stars = np.argsort(
|
|
316
|
+
|
|
317
|
+
distances = np.sqrt(
|
|
315
318
|
(source.gaia[f'sector_{sector}_x'][:500] - source.gaia[star_num][f'sector_{sector}_x']) ** 2 +
|
|
316
|
-
(source.gaia[f'sector_{sector}_y'][:500] - source.gaia[star_num][f'sector_{sector}_y']) ** 2)
|
|
317
|
-
|
|
319
|
+
(source.gaia[f'sector_{sector}_y'][:500] - source.gaia[star_num][f'sector_{sector}_y']) ** 2)
|
|
320
|
+
|
|
321
|
+
# Find closest 5 stars (6-self) or those within 5 pixels
|
|
322
|
+
nearby_stars = np.argsort(distances)[:6]
|
|
323
|
+
nearby_stars = nearby_stars[distances[nearby_stars] <= 5]
|
|
318
324
|
star_x = source.gaia[star_num][f'sector_{sector}_x'][0]
|
|
319
325
|
star_y = source.gaia[star_num][f'sector_{sector}_y'][0]
|
|
320
326
|
max_flux = np.nanmax(
|
|
321
|
-
np.nanmedian(
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
gs.
|
|
326
|
-
|
|
327
|
+
np.nanmedian(
|
|
328
|
+
source.flux[:, round(star_y) - 2:round(star_y) + 3, round(star_x) - 2:round(star_x) + 3],
|
|
329
|
+
axis=0))
|
|
330
|
+
fig = plt.figure(constrained_layout=False, figsize=(20, 12))
|
|
331
|
+
gs = fig.add_gridspec(21, 10)
|
|
332
|
+
gs.update(wspace=0.03, hspace=0.1)
|
|
333
|
+
ax0 = fig.add_subplot(gs[:10, :3])
|
|
327
334
|
ax0.imshow(np.median(source.flux, axis=0), cmap='RdBu', vmin=-max_flux, vmax=max_flux, origin='lower')
|
|
328
|
-
|
|
329
|
-
ax0.
|
|
330
|
-
|
|
331
|
-
ax0.scatter(source.gaia[f'sector_{sector}_x'][
|
|
332
|
-
source.gaia[f'sector_{sector}_y'][nearby_stars], s=50,
|
|
335
|
+
ax0.set_xlabel('x pixel')
|
|
336
|
+
ax0.set_ylabel('y pixel')
|
|
337
|
+
ax0.scatter(star_x, star_y, s=300, c='r', marker='*', label='target star')
|
|
338
|
+
ax0.scatter(source.gaia[f'sector_{sector}_x'][:500], source.gaia[f'sector_{sector}_y'][:500], s=30,
|
|
333
339
|
c='r', label='background stars')
|
|
340
|
+
ax0.scatter(source.gaia[f'sector_{sector}_x'][nearby_stars[nearby_stars != star_num[0][0]]],
|
|
341
|
+
source.gaia[f'sector_{sector}_y'][nearby_stars[nearby_stars != star_num[0][0]]],
|
|
342
|
+
s=30, c='r', edgecolor='black', linewidth=1, label='background stars')
|
|
343
|
+
ax0.grid(False)
|
|
334
344
|
for l in range(len(nearby_stars)):
|
|
335
345
|
index = np.where(
|
|
336
346
|
source.tic['dr3_source_id'] == int(source.gaia['DESIGNATION'][nearby_stars[l]].split(' ')[-1]))
|
|
337
347
|
gaia_targets = source.gaia
|
|
338
348
|
median_time = np.median(source.time)
|
|
339
|
-
interval = (median_time - 388.5) / 365.25 +
|
|
349
|
+
interval = (median_time - 388.5) / 365.25 + pm_years
|
|
340
350
|
ra = gaia_targets['ra'][nearby_stars[l]]
|
|
341
351
|
dec = gaia_targets['dec'][nearby_stars[l]]
|
|
342
352
|
if not np.isnan(gaia_targets['pmra'][nearby_stars[l]]):
|
|
@@ -352,43 +362,37 @@ def plot_contamination(local_directory=None, gaia_dr3=None):
|
|
|
352
362
|
y_gaia - source.gaia[f'sector_{sector}_y'][nearby_stars[l]],
|
|
353
363
|
width=0.02, color='r', edgecolor=None, head_width=0.1)
|
|
354
364
|
try:
|
|
355
|
-
ax0.text(source.gaia[f'sector_{sector}_x'][nearby_stars[l]]
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
ax0.scatter(star_x, star_y, s=300, c='r', marker='*', label='target star')
|
|
365
|
+
txt = ax0.text(source.gaia[f'sector_{sector}_x'][nearby_stars[l]] + 0.5,
|
|
366
|
+
source.gaia[f'sector_{sector}_y'][nearby_stars[l]] - 0.05,
|
|
367
|
+
f'TIC {int(source.tic["TIC"][index])}', size=7)
|
|
368
|
+
|
|
369
|
+
except TypeError:
|
|
370
|
+
designation = source.gaia[f"DESIGNATION"][nearby_stars[l]]
|
|
371
|
+
formatted_text = '\n'.join([designation[i:i + 15] for i in range(0, len(designation), 15)])
|
|
363
372
|
|
|
364
|
-
|
|
373
|
+
txt = ax0.text(source.gaia[f'sector_{sector}_x'][nearby_stars[l]] + 0.5,
|
|
374
|
+
source.gaia[f'sector_{sector}_y'][nearby_stars[l]] - 0.05,
|
|
375
|
+
formatted_text, size=7)
|
|
365
376
|
ax0.set_xlim(round(star_x) - 5.5, round(star_x) + 5.5)
|
|
366
377
|
ax0.set_ylim(round(star_y) - 5.5, round(star_y) + 5.5)
|
|
367
|
-
ax0.set_title(f'TIC_{hdul[0].header["TICID"]}
|
|
368
|
-
ax0.vlines(round(star_x) - 2.5, round(star_y) - 2.5, round(star_y) + 2.5, colors='k')
|
|
369
|
-
ax0.vlines(round(star_x) + 2.5, round(star_y) - 2.5, round(star_y) + 2.5, colors='k')
|
|
370
|
-
ax0.hlines(round(star_y) - 2.5, round(star_x) - 2.5, round(star_x) + 2.5, colors='k')
|
|
371
|
-
ax0.hlines(round(star_y) + 2.5, round(star_x) - 2.5, round(star_x) + 2.5, colors='k')
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
# cal_lc, trend = flatten(hdul[1].data['time'],
|
|
378
|
-
# source.flux[:, round(star_y) - 2 + j, round(star_x) - 2 + k],
|
|
379
|
-
# window_length=1, method='biweight', return_trend=True)
|
|
380
|
-
# ax_.plot(hdul[1].data['time'], cal_lc, '.k', ms=1, label='center pixel')
|
|
381
|
-
|
|
382
|
-
t_, y_, x_ = np.shape(hdul[0].data)
|
|
378
|
+
ax0.set_title(f'TIC_{hdul[0].header["TICID"]}_Sector_{hdul[0].header["SECTOR"]:04d}')
|
|
379
|
+
ax0.vlines(round(star_x) - 2.5, round(star_y) - 2.5, round(star_y) + 2.5, colors='k', lw=1.2)
|
|
380
|
+
ax0.vlines(round(star_x) + 2.5, round(star_y) - 2.5, round(star_y) + 2.5, colors='k', lw=1.2)
|
|
381
|
+
ax0.hlines(round(star_y) - 2.5, round(star_x) - 2.5, round(star_x) + 2.5, colors='k', lw=1.2)
|
|
382
|
+
ax0.hlines(round(star_y) + 2.5, round(star_x) - 2.5, round(star_x) + 2.5, colors='k', lw=1.2)
|
|
383
|
+
try:
|
|
384
|
+
t_, y_, x_ = np.shape(hdul[0].data)
|
|
385
|
+
except ValueError:
|
|
386
|
+
warnings.warn('Light curves need to have the primary hdu. Set save_aperture=True when producing the light curve to enable this plot.')
|
|
387
|
+
sys.exit()
|
|
383
388
|
max_flux = np.max(
|
|
384
389
|
np.median(source.flux[:, int(star_y) - 2:int(star_y) + 3, int(star_x) - 2:int(star_x) + 3], axis=0))
|
|
390
|
+
arrays = []
|
|
385
391
|
for j in range(y_):
|
|
386
392
|
for k in range(x_):
|
|
387
|
-
ax_ = fig.add_subplot(gs[(
|
|
388
|
-
ax_.patch.set_facecolor('
|
|
393
|
+
ax_ = fig.add_subplot(gs[(19 - 2 * j):(21 - 2 * j), (2 * k):(2 + 2 * k)])
|
|
394
|
+
ax_.patch.set_facecolor('#4682B4')
|
|
389
395
|
ax_.patch.set_alpha(min(1, max(0, 5 * np.nanmedian(hdul[0].data[:, j, k]) / max_flux)))
|
|
390
|
-
q = [a and b for a, b in
|
|
391
|
-
zip(list(hdul[1].data['TESS_flags'] == 0), list(hdul[1].data['TGLC_flags'] == 0))]
|
|
392
396
|
|
|
393
397
|
_, trend = flatten(hdul[1].data['time'][q],
|
|
394
398
|
hdul[0].data[:, j, k][q] - np.nanmin(hdul[0].data[:, j, k][q]) + 1000,
|
|
@@ -396,18 +400,68 @@ def plot_contamination(local_directory=None, gaia_dr3=None):
|
|
|
396
400
|
cal_aper = (hdul[0].data[:, j, k][q] - np.nanmin(
|
|
397
401
|
hdul[0].data[:, j, k][q]) + 1000 - trend) / np.nanmedian(
|
|
398
402
|
hdul[0].data[:, j, k][q]) + 1
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
403
|
+
if 1 <= j <= 3 and 1 <= k <= 3:
|
|
404
|
+
arrays.append(cal_aper)
|
|
405
|
+
ax_.plot(hdul[1].data['time'][q], cal_aper, '.k', ms=0.5)
|
|
406
|
+
# ax_.plot(hdul[1].data['time'][q], hdul[0].data[:, j, k][q], '.k', ms=0.5)
|
|
407
|
+
ax_.set_ylim(ymin, ymax)
|
|
408
|
+
ax_.set_xlabel('TBJD')
|
|
409
|
+
ax_.set_ylabel('')
|
|
402
410
|
if j != 0:
|
|
403
411
|
ax_.set_xticklabels([])
|
|
412
|
+
ax_.set_xlabel('')
|
|
404
413
|
if k != 0:
|
|
405
414
|
ax_.set_yticklabels([])
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
415
|
+
if j == 2 and k == 0:
|
|
416
|
+
ax_.set_ylabel('Normalized and detrended Flux of each pixel')
|
|
417
|
+
|
|
418
|
+
combinations = itertools.combinations(arrays, 2)
|
|
419
|
+
median_abs_diffs = []
|
|
420
|
+
for arr_a, arr_b in combinations:
|
|
421
|
+
abs_diff = np.abs(arr_a - arr_b)
|
|
422
|
+
median_diff = np.median(abs_diff)
|
|
423
|
+
median_abs_diffs.append(median_diff)
|
|
424
|
+
median_abs_diffs = np.array(median_abs_diffs)
|
|
425
|
+
iqr = np.percentile(median_abs_diffs, 75) - np.percentile(median_abs_diffs, 25)
|
|
426
|
+
print(f"Interquartile Range (IQR): {iqr}")
|
|
427
|
+
std_dev = np.std(median_abs_diffs)
|
|
428
|
+
print(f"Standard Deviation: {std_dev}")
|
|
429
|
+
ax1 = fig.add_subplot(gs[:10, 4:7])
|
|
430
|
+
ax1.hist(median_abs_diffs, color='k', edgecolor='k', facecolor='none', rwidth=0.8, linewidth=2)
|
|
431
|
+
ax1.set_box_aspect(1)
|
|
432
|
+
ax1.set_title(f'Distribution of the MADs among combinations of the center 3*3 pixels')
|
|
433
|
+
ax1.set_xlabel('MAD between combinations of center 3*3 pixel fluxes')
|
|
434
|
+
ax1.set_ylabel('Counts')
|
|
435
|
+
text_ax = fig.add_axes([0.71, 0.9, 0.3, 0.3]) # [left, bottom, width, height] in figure coordinates
|
|
436
|
+
text_ax.axis('off') # Turn off axis lines, ticks, etc.
|
|
437
|
+
text_ax.text(0., 0., f"Gaia DR3 {gaia_dr3} \n"
|
|
438
|
+
f" ←← TESS SPOC FFI and TIC/Gaia stars with proper motions. \n"
|
|
439
|
+
f" Arrows show Gaia proper motion after {pm_years} years. \n"
|
|
440
|
+
f" ← Histogram of the MADs between 3*3 pixel fluxes. \n"
|
|
441
|
+
f" ↓ Fluxes of each pixels after contaminations are removed. \n"
|
|
442
|
+
f" The fluxes are normalized and detrended. The background \n"
|
|
443
|
+
f" color shows the pixel brightness after the decontamination. \n"
|
|
444
|
+
f"\n"
|
|
445
|
+
f"How to interpret these plots: \n"
|
|
446
|
+
f" If the signals you are interested in (i.e. transits, \n"
|
|
447
|
+
f" eclipses, variable stars) show similar amplitudes in \n"
|
|
448
|
+
f" all (especially the center 3*3) pixels, then the star \n"
|
|
449
|
+
f" is likely to be the source. The median absolute \n"
|
|
450
|
+
f" differences (MADs) taken between all combinations \n"
|
|
451
|
+
f" of the center pixel fluxes are shown in the histogram \n"
|
|
452
|
+
f" for a quantititive comparison to other possible sources. \n"
|
|
453
|
+
f" The star with smaller distribution width (IQR or \n"
|
|
454
|
+
f" STD) is more likely to be the source of the signal. \n"
|
|
455
|
+
f"\n"
|
|
456
|
+
f"Interquartile Range (IQR): {iqr:05f} \n"
|
|
457
|
+
f"Standard Deviation: {std_dev:05f}", transform=text_ax.transAxes, ha='left',
|
|
458
|
+
va='top')
|
|
459
|
+
plt.subplots_adjust(top=.98, bottom=0.05, left=0.05, right=0.95)
|
|
460
|
+
plt.savefig(
|
|
461
|
+
f'{local_directory}plots/contamination_sector_{hdul[0].header["SECTOR"]:04d}_Gaia_DR3_{gaia_dr3}.pdf',
|
|
462
|
+
dpi=300)
|
|
463
|
+
# plt.savefig(f'{local_directory}plots/contamination_sector_{hdul[0].header["SECTOR"]:04d}_Gaia_DR3_{gaia_dr3}.png',
|
|
464
|
+
# dpi=600)
|
|
411
465
|
|
|
412
466
|
def plot_epsf(local_directory=None):
|
|
413
467
|
files = glob(f'{local_directory}epsf/*.npy')
|
|
@@ -458,7 +512,7 @@ def get_tglc_lc(tics=None, method='query', server=1, directory=None, prior=None)
|
|
|
458
512
|
|
|
459
513
|
if __name__ == '__main__':
|
|
460
514
|
tics = [16005254]
|
|
461
|
-
directory = f'/
|
|
515
|
+
directory = f'/Users/tehan/Downloads/'
|
|
462
516
|
os.makedirs(directory, exist_ok=True)
|
|
463
517
|
get_tglc_lc(tics=tics, method='query', server=1, directory=directory)
|
|
464
518
|
# plot_lc(local_directory=f'{directory}TIC {tics[0]}/', kind='cal_aper_flux')
|
|
@@ -20,7 +20,7 @@ warnings.simplefilter('always', UserWarning)
|
|
|
20
20
|
def lc_output(source, local_directory='', index=0, time=None, psf_lc=None, cal_psf_lc=None, aper_lc=None,
|
|
21
21
|
cal_aper_lc=None, bg=None, tess_flag=None, tglc_flag=None, cadence=None, aperture=None,
|
|
22
22
|
cut_x=None, cut_y=None, star_x=2, star_y=2, x_aperture=None, y_aperture=None, near_edge=False,
|
|
23
|
-
local_bg=None, save_aper=False, portion=1, prior=None, transient=None):
|
|
23
|
+
local_bg=None, save_aper=False, portion=1, prior=None, transient=None, target_5x5=None, field_stars_5x5=None):
|
|
24
24
|
"""
|
|
25
25
|
lc output to .FITS file in MAST HLSP standards
|
|
26
26
|
:param tglc_flag: np.array(), required
|
|
@@ -82,6 +82,13 @@ def lc_output(source, local_directory='', index=0, time=None, psf_lc=None, cal_p
|
|
|
82
82
|
primary_hdu = fits.PrimaryHDU(aperture)
|
|
83
83
|
else:
|
|
84
84
|
primary_hdu = fits.PrimaryHDU()
|
|
85
|
+
# Simulated star images based on ePSF, used to estimate contamination ratio and others
|
|
86
|
+
image_data = np.zeros((3, 5, 5))
|
|
87
|
+
image_data[0] = target_5x5
|
|
88
|
+
image_data[1] = field_stars_5x5
|
|
89
|
+
# This is the pixel-wise contamination ratio
|
|
90
|
+
image_data[2] = field_stars_5x5/target_5x5
|
|
91
|
+
image_hdu = fits.ImageHDU(data=image_data)
|
|
85
92
|
|
|
86
93
|
primary_hdu.header = fits.Header(cards=[
|
|
87
94
|
fits.Card('SIMPLE', True, 'conforms to FITS standard'),
|
|
@@ -116,6 +123,7 @@ def lc_output(source, local_directory='', index=0, time=None, psf_lc=None, cal_p
|
|
|
116
123
|
fits.Card('GAIA_bp', gaia_bp, 'Gaia DR3 bp band magnitude'),
|
|
117
124
|
fits.Card('GAIA_rp', gaia_rp, 'Gaia DR3 rp band magnitude'),
|
|
118
125
|
fits.Card('RAWFLUX', raw_flux, 'median flux of raw FFI'),
|
|
126
|
+
fits.Card('CONTAMRT', round(np.nansum(field_stars_5x5[1:4,1:4])/np.nansum(target_5x5[1:4,1:4]), 9), 'contamination ratio of default 3*3 aperture'),
|
|
119
127
|
fits.Card('CALIB', 'TGLC', 'pipeline used for image calibration')])
|
|
120
128
|
if save_aper:
|
|
121
129
|
primary_hdu.header.comments['NAXIS1'] = "Time (hdul[1].data['time'])"
|
|
@@ -190,13 +198,14 @@ def lc_output(source, local_directory='', index=0, time=None, psf_lc=None, cal_p
|
|
|
190
198
|
if type(prior) == float:
|
|
191
199
|
table_hdu.header.append(('PRIOR', prior, 'prior of field stars'), end=True)
|
|
192
200
|
|
|
193
|
-
hdul = fits.HDUList([primary_hdu, table_hdu])
|
|
201
|
+
hdul = fits.HDUList([primary_hdu, table_hdu, image_hdu])
|
|
194
202
|
hdul.writeto(
|
|
195
|
-
f'{local_directory}hlsp_tglc_tess_ffi_gaiaid-{objid}-s{source.sector:04d}-cam{source.camera}-ccd{source.ccd}
|
|
203
|
+
f'{local_directory}hlsp_tglc_tess_ffi_gaiaid-{objid}-s{source.sector:04d}-cam{source.camera}-ccd{source.ccd}_tess_v2_llc.fits',
|
|
196
204
|
overwrite=True)
|
|
197
205
|
return
|
|
198
206
|
|
|
199
207
|
|
|
208
|
+
|
|
200
209
|
def epsf(source, psf_size=11, factor=2, local_directory='', target=None, cut_x=0, cut_y=0, sector=0,
|
|
201
210
|
limit_mag=16, edge_compression=1e-4, power=1.4, name=None, save_aper=False, no_progress_bar=False, prior=None):
|
|
202
211
|
"""
|
|
@@ -310,7 +319,7 @@ def epsf(source, psf_size=11, factor=2, local_directory='', target=None, cut_x=0
|
|
|
310
319
|
fit_lc_float_field(A, source, star_info=star_info, x=x_round, y=y_round, star_num=i, e_psf=e_psf,
|
|
311
320
|
near_edge=near_edge, prior=prior)
|
|
312
321
|
else:
|
|
313
|
-
aperture, psf_lc, star_y, star_x, portion = \
|
|
322
|
+
aperture, psf_lc, star_y, star_x, portion, target_5x5, field_stars_5x5 = \
|
|
314
323
|
fit_lc(A, source, star_info=star_info, x=x_round[i], y=y_round[i], star_num=i, e_psf=e_psf,
|
|
315
324
|
near_edge=near_edge)
|
|
316
325
|
aper_lc = np.sum(
|
|
@@ -359,4 +368,4 @@ def epsf(source, psf_size=11, factor=2, local_directory='', target=None, cut_x=0
|
|
|
359
368
|
bg=background_, time=source.time, psf_lc=psf_lc, cal_psf_lc=cal_psf_lc, aper_lc=aper_lc,
|
|
360
369
|
cal_aper_lc=cal_aper_lc, local_bg=local_bg, x_aperture=x_aperture[i],
|
|
361
370
|
y_aperture=y_aperture[i], near_edge=near_edge, save_aper=save_aper, portion=portion,
|
|
362
|
-
prior=prior, transient=source.transient)
|
|
371
|
+
prior=prior, transient=source.transient, target_5x5=target_5x5, field_stars_5x5=field_stars_5x5)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: tglc
|
|
3
|
-
Version: 0.6.
|
|
3
|
+
Version: 0.6.6
|
|
4
4
|
Summary: TESS-Gaia Light Curve
|
|
5
5
|
Home-page: https://github.com/TeHanHunter/TESS_Gaia_Light_Curve
|
|
6
6
|
Author: Te Han
|
|
@@ -8,9 +8,21 @@ Author-email: tehanhunter@gmail.com
|
|
|
8
8
|
Classifier: Programming Language :: Python :: 3
|
|
9
9
|
Classifier: License :: OSI Approved :: MIT License
|
|
10
10
|
Classifier: Operating System :: OS Independent
|
|
11
|
-
Requires-Python: >=3.8
|
|
11
|
+
Requires-Python: >=3.8, <3.13
|
|
12
12
|
Description-Content-Type: text/x-rst
|
|
13
13
|
License-File: LICENSE
|
|
14
|
+
Requires-Dist: astropy>=5.1
|
|
15
|
+
Requires-Dist: astroquery==0.4.7
|
|
16
|
+
Requires-Dist: matplotlib
|
|
17
|
+
Requires-Dist: numpy
|
|
18
|
+
Requires-Dist: oauthlib
|
|
19
|
+
Requires-Dist: requests
|
|
20
|
+
Requires-Dist: scipy
|
|
21
|
+
Requires-Dist: threadpoolctl
|
|
22
|
+
Requires-Dist: tqdm
|
|
23
|
+
Requires-Dist: wheel
|
|
24
|
+
Requires-Dist: wotan
|
|
25
|
+
Requires-Dist: seaborn
|
|
14
26
|
|
|
15
27
|
==================================
|
|
16
28
|
Introduction
|
|
@@ -18,6 +30,7 @@ Introduction
|
|
|
18
30
|
|
|
19
31
|
TESS-Gaia Light Curve (`TGLC <https://archive.stsci.edu/hlsp/tglc>`_) is a dataset of TESS full-frame image light curves publicly available via the MAST portal. It is fitted with effective PSF and decontaminated with Gaia DR3 and achieved percent-level photometric precision down to 16th TESS magnitude! It unlocks astrophysics to a vast number of dim stars below 12th TESS magnitude. A package called tglc is pip-installable for customized light curve fits.
|
|
20
32
|
|
|
33
|
+
|
|
21
34
|
==================================
|
|
22
35
|
Usage
|
|
23
36
|
==================================
|
tglc-0.6.4/tglc/__init__.py
DELETED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|