def cut_ffi(tic_id:int,clip :float = 4,iter : int = 1,do_pca : bool = False, do_psf :bool = False,flux_type = 'PDCSAP') -> Tuple[LightCurve, List[Figure],List[eleanor.TargetData]]: """ Extracts light curves from FFIs using TESScut and Eleanor. This function automatically combines all available sectors for a given target. :param tic_id: TIC ID of the target :param clip: Sigma clip range of the target. :param iter: Iterations of the sigma clipping :param do_pca: Perform pca analysis with eleanor :param do_psf: Perform psf analysis with eleanor :param flux_type: Flux type that is returned. Choose between 'PDCSAP','SAP','PSF' :return: Lightcurve """ flux_types = ['SAP','PDCSAP', 'PSF'] if flux_type not in flux_types: raise ValueError(mprint(f"Flux type {flux_type} not recognized. Possible values are: {flux_types}",error)) f = io.StringIO() with redirect_stdout(f): stars = eleanor.multi_sectors(tic=tic_id, sectors='all',tc=True) mprint(f.getvalue().strip(), log) lc_list = [] data_list = [] q_list = [] pca_flag = do_pca or flux_type == 'PDCSAP' psf_flag = do_psf or flux_type == 'PSF' for star in stars: f = io.StringIO() with warnings.catch_warnings(): warnings.simplefilter('ignore') data = eleanor.TargetData(star, height=15, width=15, bkg_size=31, do_pca=pca_flag, do_psf=psf_flag) mprint(f.getvalue().strip(), log) q = data.quality == 0 if flux_type == 'SAP': lc_list.append(LightCurve(lk.TessLightCurve(time=data.time[q], flux=data.corr_flux[q], targetid=tic_id))) elif flux_type == 'PDCSAP': lc_list.append(LightCurve(lk.TessLightCurve(time=data.time[q], flux=data.pca_flux[q], targetid=tic_id))) else: lc_list.append(LightCurve(lk.TessLightCurve(time=data.time[q], flux=data.psf_flux[q], targetid=tic_id))) data_list.append(data) q_list.append(q) fig = create_validation_page(data_list, q_list, f'TIC {tic_id}',do_pca=pca_flag,do_psf=psf_flag,flux_type=flux_type) lc : LightCurve = combine_light_curves(lc_list,clip,iter) mprint(f"Extracted light curve for TIC {tic_id}!", info) return lc, fig,data_list
def get_lc(ra, dec): # Collect data on target from each sector in TESS. # You may need to eleanor.Update(sector=##) to ensure you have all data. global targetname # https://adina.feinste.in/eleanor/api.html#eleanor.multi_sectors data = eleanor.multi_sectors('all', coords=(ra, dec), tc=True) # Extract LC data for each sector using PSF photometry mjd, flux, ferr = ([] for x in range(3)) for k in data: # https://adina.feinste.in/eleanor/api.html#eleanor.TargetData d = eleanor.TargetData(k, height=15, width=15, bkg_size=31, do_psf=True, do_pca=True, crowded_field=True) quality = d.quality index = np.where(quality == 0) # Keep only quality = 0 data # Based on fits file headers, time is Barycentric Julian Date (-2457000 days) t = d.time[index] # corr_flux = Systematics-corrected version of lightcurve derived using aperture and tpf. f = d.corr_flux[index] # flux_err = Estimated uncertainty on raw_flux. e = d.flux_err[index] # 'Append' all data from all sectors together into a 1-D array mjd = np.concatenate((mjd, t)) flux = np.concatenate((flux, f / np.median(f))) ferr = np.concatenate((ferr, e)) # LC's may be large. Clear space after finished. del (d, t, f, e) # Save LC to file for easy access later. # No reason to run eleanor everytime. lcname = str(targetname) + "_tess.txt" with open(lcname, 'w') as ofile: for k in range(len(mjd)): ofile.write( str(mjd[k]) + " " + str(flux[k]) + " " + str(ferr[k]) + "\n") return (mjd, flux, ferr)
def download_eleanor_data(self): """ Download Eleanor data. Data may not always be available due to not being observed by TESS, or errors in the download (which Im still trying to solve). """ coords = SkyCoord(ra=self.j.ra, dec=self.j.dec, unit=(u.deg, u.deg)) star = eleanor.multi_sectors(coords=coords, sectors='all') for s in star: try: datum = eleanor.TargetData(s) datum.save(output_fn=f'lc_sector_{s.sector}.fits', directory=f'{self.j.output_path}/{self.j.gaiaid}/') except TypeError: print( f'There is some kind of Eleanor error for Sector {s.sector}' ) print('Try running eleanor.Update(), or raise an issue on the ' 'Eleanor GitHub!') print('Moving on the next sector... \n')
def get_eleanor_lightcurves(tic_id, download_dir=None): """This downloads light curves from the Eleanor project for a given TIC ID. Parameters ---------- tic_id : str The TIC ID of the object as a string. Returns ------- lcfiles : list or None List of light-curve file paths. These are saved as CSV, rather than FITS, by this function. """ if not eleanor_dependency: LOGERROR("The eleanor package is required for this function to work.") return None stars = eleanor.multi_sectors(tic=np.int64(tic_id), sectors='all', tc=False) for star in stars: d = eleanor.TargetData(star, height=15, width=15, bkg_size=31, do_psf=False, do_pca=False) d.save(directory=download_dir) lcfiles = glob( os.path.join(download_dir, 'hlsp_eleanor_tess_ffi_tic{}*.fits'.format(tic_id))) return lcfiles
star_ids = [] for i in hdul[1].data: star_ids.append(i[2]) star_ids_test = [234284556, 234523599]#, 267263253, 410153553,140068425,261136679,179317684,29857954,425997655,307210830,279741379,441462736,410214986,55652896,200723869] #star_ids[9:10] real_period = [1.106,3.796]#,4.127,0.463,2.281,6.268,4.231,9.477,17.667,2.253,7.790,14.277,8.138,17.089,18.371,] ''' best_fit_period = [] #well_fit_target = [] #poor_fit_target = [] failed_tic = [] best_fit_uncert = [] for j,i in enumerate(tic_ids): try: print(i) star = eleanor.multi_sectors(tic=i, sectors='all') #print('Found TIC {0} (Gaia {1}), with TESS magnitude {2}, RA {3}, and Dec {4}' # .format(star.tic, star.gaia, star.tess_mag, star.coords[0], star.coords[1])) #data = eleanor.TargetData(star, height=15, width=15, bkg_size=31, do_psf=True, do_pca=True, regressors='corner') #plt.figure(figsize=(15,5)) data = [] #plot_fmt = ['k.', 'r.','k.', 'r.'] for s in star: datum = eleanor.TargetData(s, height=15, width=15, bkg_size=31, do_psf=False, do_pca=False, aperture_mode='small') data.append(datum)
def build(self, object_info): mission_id = object_info.mission_id() sherlock_id = object_info.sherlock_id() quarters = None sectors = None logging.info("Retrieving star catalog info...") mission, mission_prefix, id = super().parse_object_id(mission_id) transits_min_count = 1 star_info = None quarters = None if mission_prefix not in self.star_catalogs: raise ValueError("Wrong object id " + mission_id) if mission_prefix == self.MISSION_ID_KEPLER or mission_prefix == self.MISSION_ID_KEPLER_2: if object_info.sectors != 'all': lcf = lk.search_lightcurvefile( str(mission_id), mission=mission, cadence="long", quarter=object_info.sectors).download_all() else: lcf = lk.search_lightcurvefile(str(mission_id), mission=mission, cadence="long").download_all() lc = lcf.PDCSAP_FLUX.stitch().remove_nans() transits_min_count = 1 if len(lcf) == 0 else 2 if mission_prefix == self.MISSION_ID_KEPLER: quarters = [lcfile.quarter for lcfile in lcf] elif mission_prefix == self.MISSION_ID_KEPLER_2: logging.info("Correcting K2 motion in light curve...") quarters = [lcfile.campaign for lcfile in lcf] lc = lc.to_corrector("sff").correct(windows=20) star_info = starinfo.StarInfo( sherlock_id, *self.star_catalogs[mission_prefix].catalog_info(id)) else: if isinstance(object_info, MissionFfiCoordsObjectInfo): coords = SkyCoord(ra=object_info.ra, dec=object_info.dec, unit=(u.deg, u.deg)) star = eleanor.multi_sectors(coords=coords, sectors=object_info.sectors) else: object_id_parsed = re.search(super().NUMBERS_REGEX, object_info.id) object_id_parsed = object_info.id[ object_id_parsed.regs[0][0]:object_id_parsed.regs[0][1]] star = eleanor.multi_sectors(tic=object_id_parsed, sectors=object_info.sectors) if star[0].tic: # TODO FIX star info objectid logging.info("Assotiated TIC is " + star[0].tic) star_info = starinfo.StarInfo( object_info.sherlock_id(), *self.star_catalog.catalog_info(int(star[0].tic))) data = [] for s in star: datum = eleanor.TargetData(s, height=15, width=15, bkg_size=31, do_pca=True) data.append(datum) quality_bitmask = np.bitwise_and(data[0].quality.astype(int), 175) lc = data[0].to_lightkurve( data[0].pca_flux, quality_mask=quality_bitmask).remove_nans().flatten() sectors = [datum.source_info.sector for datum in data] if len(data) > 1: for datum in data[1:]: quality_bitmask = np.bitwise_and(datum.quality, 175) lc = lc.append( datum.to_lightkurve(datum.pca_flux, quality_mask=quality_bitmask). remove_nans().flatten()) transits_min_count = 2 return lc, star_info, transits_min_count, sectors, quarters
def get_eleanor(sectors='all', tic=None, coords=None, out_sec=False, height=15, width=15, bkg_size=31, do_psf=False, do_pca=False, out_flux='corr_flux', norm=True, errorcalc=True, qual_flag=True): #!!Add more docstrings for all keywords!! #!!Add common name processing instead of just tic!! """ Function to get a light curve from the TESS full frame images (FFIs) using the Python package eleanor. Parameters ---------- sectors : str or array or list The sectors that eleanor will use to produce the light curve. If set to 'all', then all available sectors will be used in the light curve production. tic : int or None TIC ID for the object that a light curve is desired for. If set to None, coords must have a valid input. coords : tuple of floats The RA and Dec of the object that a light curve is desired for. Must be of the form (RA, Dec) in decimal degrees. If set to None, the tic argument cannot be None. out_sec : bool Flag controlling whether an array containing the sectors used to extract the light curve will be output. If True, an additional output will be expected. height : int Height in pixels of the postage stamp with which to extract the light curve. width : int Height in pixels of the postage stamp with which to extract the light curve. bkg_size : int Background size to be considered for the background subtraction from the light curve. do_psf : bool Flag to determine whether a PSF-corrected light curve will be generated as an additional option to the corrected light curve. do_pca : bool Flag to deteremine whether a PCA-corrected light curve will be generated as an additional option to the corrected light curve. out_flux : str Which of the light curves to output. Options are 'corr_flux', 'psf_flux', and 'pca_flux'. Only one may be selected. If either 'psf_flux' or 'pca_flux' are selected, the do_psf and do_pca flags must be set to True, respectively. norm : bool Flag determining whether the light curve will be normalized prior to output. errorcalc : bool Flag determining whether the RMS errors will be calculated for the light curve. qual_flag : bool Flag determining whether the timestamps with bad quality flags will be excluded automatically. Returns ------- lc : 'LightCurve' object The combined light curve from each sector for the coordinates or TIC ID requested. sectors : array Optional output array containing the sectors that the combined light curve was extracted from. """ import eleanor if tic is None and coords is None: raise ValueError('Please make sure either tic or coords have valid ' + 'input') if tic: star = eleanor.multi_sectors(tic=tic, sectors=sectors) else: star = eleanor.multi_sectors(coords=coords, sectors=sectors) secs = [] data = [] for s in star: datum = eleanor.TargetData(s, height=height, width=width, bkg_size=bkg_size, do_psf=do_psf, do_pca=do_pca) data.append(datum) sec = s.sector secs.append(sec) for i in range(len(data)): q = data[i].quality == 0 time = data[i].time if out_flux == 'corr_flux': flux = data[i].corr_flux elif out_flux == 'pca_flux': flux = data[i].pca_flux elif out_flux == 'psf_flux': flux = data[i].psf_flux if qual_flag: time = time[q] flux = flux[q] if norm: flux = flux / np.median(flux) flux_err = None if errorcalc: flux_err = np.ones(len(flux)) * rms(flux) if i == 0: lc = LightCurve(time, flux, flux_err=flux_err) else: sec_lc = LightCurve(time, flux, flux_err=flux_err) lc = lc.append(lc) if out_sec: return lc, secs else: return lc
def get_eleanor_lightcurves(tic_id, download_dir=None, targetdata_kwargs=None): """This downloads light curves from the Eleanor project for a given TIC ID. Parameters ---------- tic_id : str The TIC ID of the object as a string. download_dir : str The light curve FITS files will be downloaded here. targetdata_kwargs : dict Optional dictionary of keys and values to be passed ``eleanor.TargetData`` (see https://adina.feinste.in/eleanor/api.html). For instance, you might pass ``{'height':8, 'width':8, 'do_pca':True, 'do_psf':True, 'crowded_field':False}`` to run these settings through to eleanor. The default options used if targetdata_kwargs is None are as follows:: { height=15, width=15, save_postcard=True, do_pca=False, do_psf=False, bkg_size=31, crowded_field=True, cal_cadences=None, try_load=True, regressors=None } Returns ------- lcfiles : list or None List of light-curve file paths. These are saved as CSV, rather than FITS, by this function. """ if not eleanor_dependency: LOGERROR("The eleanor package is required for this function to work.") return None stars = eleanor.multi_sectors(tic=np.int64(tic_id), sectors='all', tc=False) for star in stars: if targetdata_kwargs is None: d = eleanor.TargetData(star, height=15, width=15, save_postcard=True, do_pca=False, do_psf=False, bkg_size=31, crowded_field=True, cal_cadences=None, try_load=True) else: d = eleanor.TargetData(star, **targetdata_kwargs) d.save(directory=download_dir) lcfiles = glob( os.path.join(download_dir, 'hlsp_eleanor_tess_ffi_tic{}*.fits'.format(tic_id))) return lcfiles
star_ids = [] for i in hdul[1].data: star_ids.append(i[2]) star_ids_test = [234284556, 234523599]#, 267263253, 410153553,140068425,261136679,179317684,29857954,425997655,307210830,279741379,441462736,410214986,55652896,200723869] #star_ids[9:10] real_period = [1.106,3.796]#,4.127,0.463,2.281,6.268,4.231,9.477,17.667,2.253,7.790,14.277,8.138,17.089,18.371,] ''' best_fit_period = [] #well_fit_target = [] #poor_fit_target = [] failed_tic = [] best_fit_uncert = [] try: print(tic_ids) star = eleanor.multi_sectors(tic=tic_ids, sectors='all') #print('Found TIC {0} (Gaia {1}), with TESS magnitude {2}, RA {3}, and Dec {4}' # .format(star.tic, star.gaia, star.tess_mag, star.coords[0], star.coords[1])) #data = eleanor.TargetData(star, height=15, width=15, bkg_size=31, do_psf=True, do_pca=True, regressors='corner') #plt.figure(figsize=(15,5)) data = [] #plot_fmt = ['k.', 'r.','k.', 'r.'] for s in star: datum = eleanor.TargetData(s, do_psf=False, do_pca=False,
def eleanor_lc(self, plot=False): """ retrieves + produces eleanor light curves from FFI files """ import eleanor from astropy import units as u from astropy.coordinates import SkyCoord import warnings warnings.filterwarnings('ignore') from eleanor.utils import SearchError download_dir_tesscut = os.path.join(os.path.expanduser('~'), '.eleanor', 'tesscut') download_dir_mastdownload = os.path.join(os.path.expanduser('~'), '.eleanor', 'mastDownload') print(download_dir_tesscut, download_dir_mastdownload) gaia_ids = [] print(self.radecall[:10]) for n in range(len(self.radecall)): #for n in range(10): try: coords = SkyCoord(ra=self.radecall[n][0], dec=self.radecall[n][1], unit=(u.deg, u.deg)) #try: files = eleanor.multi_sectors( coords=coords, tic=0, gaia=0, sectors='all' ) #by not providing a sector argument, will ONLY retrieve most recent sector print(len(files)) print( 'Found TIC {0} (Gaia {1}), with TESS magnitude {2}, RA {3}, and Dec {4}' .format(files[0].tic, files[0].gaia, files[0].tess_mag, files[0].coords[0], files[0].coords[1])) #data = eleanor.TargetData(files) for file in files: data = eleanor.TargetData(file) q = data.quality == 0 fluxandtime = [ data.time[q], data.raw_flux[q], data.corr_flux[q] ] lightcurve = np.asarray(fluxandtime) if plot: #!!! put plotting background here print("Plotting TPF + aperture") fig, (ax1, ax2, ax3) = plt.subplots(ncols=3, figsize=(15, 4)) ax1.imshow(data.tpf[0]) ax1.set_title('Target Pixel File') ax2.imshow(data.bkg_tpf[0]) ax2.set_title('2D interpolated background') ax3.imshow(data.aperture) ax3.set_title('Aperture') plt.savefig(self.path + self.folderlabel + self.identifiers[n] + ".png") if not os.path.isfile(self.lightcurvefilepath): #setting up fits file + save first one hdr = fits.Header() # >> make the header hdu = fits.PrimaryHDU(lightcurve, header=hdr) hdu.writeto(self.lightcurvefilepath) print(int(n)) else: #save the rest fits.append(self.lightcurvefilepath, lightcurve) print(int(n)) gaia_ids.append(int(file.gaia)) except (SearchError, ValueError, LinAlgError): print("Search Error or ValueError or LinAlgError occurred") #try: for root, dirs, files in os.walk(download_dir_tesscut): for file in files: try: os.remove(os.path.join(root, file)) #print("Deleted", os.path.join(root, file)) except (PermissionError, OSError): #print("Unable to delete", os.path.join(root, file)) continue for root, dirs, files in os.walk(download_dir_mastdownload): for file in files: try: os.remove(os.path.join(root, file)) #print("Deleted", os.path.join(root, file)) except (PermissionError, OSError): #print("Deleted", os.path.join(root, file)) continue fits.append(self.lightcurvefilepath, np.asarray(gaia_ids)) print("All light curves saved into fits file") return gaia_ids
params, params_covariance = optimize.curve_fit(sine_func, phase, flux_phased, p0=[np.mean(flux), 0.0]) flux_fit = 1.0 + params[0] * np.sin(2.*np.pi*phase + params[1]) return np.array(phase), np.array(flux_phased), np.array(flux_err_phased), np.array(flux_fit), params[0] ####### ## User inputs ## gaia_id = np.int(sys.argv[1]) aperture = input("Which aperture type would you like?\n(Check elanor documentation to see what this implies)\nOptions are normal, small, large: ") clip = int(input("How many standard deviations should be clipped?\n")) ####### # Download the data for this star star = eleanor.multi_sectors(gaia=gaia_id, sectors='all') # Do the photometry for all sectors using the selected aperture size data = [] for s in star: datum = eleanor.TargetData(s, height=15, width=15, bkg_size=31, aperture_mode=aperture, regressors='corner', do_psf=False, do_pca=False) data.append(datum) # Create flux vector time = [] flux = [] err = []
# Psi-Eri ra = [] dec = [] with open(file, 'r') as f: reader = csv.reader(f) #next(reader) for row in reader: RA = row[RA_col] DEC = row[DEC_col] ra.append(float(RA)) dec.append(float(DEC)) for (r, d) in zip(ra, dec): print(r, d) try: star = eleanor.multi_sectors(coords=(r, d), sectors='all', tc=True) for s in star: data = eleanor.TargetData(s) data.save(directory=lc_dir) except: pass '''#young_bois tic_list = [] sector_list = [] bad = [] for filename in os.listdir('/home/earleyn/old_lc'): res_tic = re.findall("tic(\d+)_", filename) tic_list.append(int(res_tic[0])) res_sector = re.findall("s0(\d+)_", filename) sector_list.append(int(res_sector[0]))