def kic_llc(k, quarter=9): ## 9 or 3! kclient = k2plr.API() if k > 100000000: star = kclient.k2_star(k) ## K2 else: star = kclient.star(k) # Kepler lcs = star.get_light_curves(short_cadence=False) quarters = np.zeros_like(lcs, dtype=int) for i, lc in enumerate(lcs): hdu_list = lc.open() quarters[i] = hdu_list[0].header['QUARTER'] hdu_list.close() qq, = np.where(quarters == 9) if len(qq) == 0: print("No Q9", k) return False if len(qq) > 1: print("Two or more", k) return False lc = lcs[qq[0]] with lc.open() as f: hdu_data = f[1].data time = hdu_data["time"] flux = hdu_data["sap_flux"] / np.nanmedian(hdu_data["sap_flux"]) - 1. ferr = hdu_data["sap_flux_err"] / np.nanmedian(hdu_data["sap_flux"]) mask = hdu_data["sap_quality"] == 0 name = f[0].header['OBJECT'].replace(' ', '') one_star(time, flux, ferr, name, mask) return True
def get_ra_dec(epicnum, verbose=False): client = k2plr.API() if verbose: print('\nquerying RA and DEC...\n') epic = client.k2_star(int(epicnum)) ra = epic.k2_ra dec = epic.k2_dec return ra, dec
def GetSources(ID, darcsec=None, stars_only=False): ''' Grabs the EPIC coordinates from the TPF and searches MAST for other EPIC targets within the same aperture. :param int ID: The 9-digit :py:obj:`EPIC` number of the target :param float darcsec: The search radius in arcseconds. \ Default is four times the largest dimension of the aperture. :param bool stars_only: If :py:obj:`True`, only returns objects \ explicitly designated as `"stars"` in MAST. Default :py:obj:`False` :returns: A list of :py:class:`Source` instances containing \ other :py:obj:`EPIC` targets within or close to this \ target's aperture ''' client = kplr.API() star = client.k2_star(ID) tpf = star.get_target_pixel_files()[0] with tpf.open() as f: crpix1 = f[2].header['CRPIX1'] crpix2 = f[2].header['CRPIX2'] crval1 = f[2].header['CRVAL1'] crval2 = f[2].header['CRVAL2'] cdelt1 = f[2].header['CDELT1'] cdelt2 = f[2].header['CDELT2'] pc1_1 = f[2].header['PC1_1'] pc1_2 = f[2].header['PC1_2'] pc2_1 = f[2].header['PC2_1'] pc2_2 = f[2].header['PC2_2'] pc = np.array([[pc1_1, pc1_2], [pc2_1, pc2_2]]) pc = np.linalg.inv(pc) crpix1p = f[2].header['CRPIX1P'] crpix2p = f[2].header['CRPIX2P'] crval1p = f[2].header['CRVAL1P'] crval2p = f[2].header['CRVAL2P'] cdelt1p = f[2].header['CDELT1P'] cdelt2p = f[2].header['CDELT2P'] if darcsec is None: darcsec = 4 * max(f[2].data.shape) epicid, ra, dec, kepmag = MASTRADec( star.k2_ra, star.k2_dec, darcsec, stars_only) sources = [] for i, epic in enumerate(epicid): dra = (ra[i] - crval1) * np.cos(np.radians(dec[i])) / cdelt1 ddec = (dec[i] - crval2) / cdelt2 sx = pc[0, 0] * dra + pc[0, 1] * ddec + crpix1 + crval1p - 1.0 sy = pc[1, 0] * dra + pc[1, 1] * ddec + crpix2 + crval2p - 1.0 sources.append(dict(ID=epic, x=sx, y=sy, mag=kepmag[i], x0=crval1p, y0=crval2p)) return sources
def get_coord_from_epicid(epicid): try: import k2plr client = k2plr.API() except Exception: raise ModuleNotFoundError( "pip install git+https://github.com/rodluger/k2plr.git") epicid = int(epicid) star = client.k2_star(epicid) ra = float(star.k2_ra) dec = float(star.k2_dec) coord = SkyCoord(ra=ra, dec=dec, unit="deg") return coord
def __init__(self, epicid): client = k2plr.API() self.s = client.k2_star(epicid)
def get_k2_star(epicid): """ Uses k2plr """ client = k2plr.API() return client.k2_star(epicid)
def GetHiResImage(ID): ''' Queries the Palomar Observatory Sky Survey II catalog to obtain a higher resolution optical image of the star with EPIC number :py:obj:`ID`. ''' # Get the TPF info client = kplr.API() star = client.k2_star(ID) k2ra = star.k2_ra k2dec = star.k2_dec tpf = star.get_target_pixel_files()[0] with tpf.open() as f: k2wcs = WCS(f[2].header) shape = np.array(f[1].data.field('FLUX'), dtype='float64')[0].shape # Get the POSS URL hou = int(k2ra * 24 / 360.) min = int(60 * (k2ra * 24 / 360. - hou)) sec = 60 * (60 * (k2ra * 24 / 360. - hou) - min) ra = '%02d+%02d+%.2f' % (hou, min, sec) sgn = '' if np.sign(k2dec) >= 0 else '-' deg = int(np.abs(k2dec)) min = int(60 * (np.abs(k2dec) - deg)) sec = 3600 * (np.abs(k2dec) - deg - min / 60) dec = '%s%02d+%02d+%.1f' % (sgn, deg, min, sec) url = 'https://archive.stsci.edu/cgi-bin/dss_search?v=poss2ukstu_red&' + \ 'r=%s&d=%s&e=J2000&h=3&w=3&f=fits&c=none&fov=NONE&v3=' % (ra, dec) # Query the server r = urllib.request.Request(url) handler = urllib.request.urlopen(r) code = handler.getcode() if int(code) != 200: # Unavailable return None data = handler.read() # Atomically write to a temp file f = NamedTemporaryFile("wb", delete=False) f.write(data) f.flush() os.fsync(f.fileno()) f.close() # Now open the POSS fits file with pyfits.open(f.name) as ff: img = ff[0].data # Map POSS pixels onto K2 pixels xy = np.empty((img.shape[0] * img.shape[1], 2)) z = np.empty(img.shape[0] * img.shape[1]) pwcs = WCS(f.name) k = 0 for i in range(img.shape[0]): for j in range(img.shape[1]): ra, dec = pwcs.all_pix2world(float(j), float(i), 0) xy[k] = k2wcs.all_world2pix(ra, dec, 0) z[k] = img[i, j] k += 1 # Resample grid_x, grid_y = np.mgrid[-0.5:shape[1] - 0.5:0.1, -0.5:shape[0] - 0.5:0.1] resampled = griddata(xy, z, (grid_x, grid_y), method='cubic') # Rotate to align with K2 image. Not sure why, but it is necessary resampled = np.rot90(resampled) return resampled
import astropy.io.fits as pyfits except ImportError: raise Exception('Please install the `pyfits` package.') from astropy.wcs import WCS from scipy.interpolate import griddata from k2plr.api import K2_CAMPAIGNS import numpy as np from tempfile import NamedTemporaryFile from six.moves import urllib import re import os import subprocess import logging import k2plr as kplr log = logging.getLogger(__name__) kplr_client = kplr.API() __all__ = ['Campaign', 'GetK2Stars', 'GetK2Campaign', 'Channel', 'RemoveBackground', 'GetNeighboringChannels', 'GetSources', 'GetHiResImage', 'GetCustomAperture', 'StatsPicker', 'SaturationFlux', 'Module', 'Channels'] def _range10_90(x): ''' Returns the 10th-90th percentile range of array :py:obj:`x`. ''' x = np.delete(x, np.where(np.isnan(x))) i = np.argsort(x)
def get_outliers(campaign, pipeline='everest2', sigma=5): ''' Computes the number of outliers for a given `campaign` and a given `pipeline`. Stores the results in a file under "/missions/k2/tables/". :param int sigma: The sigma level at which to clip outliers. Default 5 ''' # Imports from .utils import GetK2Campaign client = k2plr.API() # Check pipeline assert pipeline.lower() in Pipelines, 'Invalid pipeline: `%s`.' % pipeline # Create file if it doesn't exist file = os.path.join(EVEREST_SRC, 'missions', 'k2', 'tables', 'c%02d_%s.out' % (int(campaign), pipeline)) if not os.path.exists(file): open(file, 'a').close() # Get all EPIC stars stars = GetK2Campaign(campaign, epics_only=True) nstars = len(stars) # Remove ones we've done with warnings.catch_warnings(): warnings.simplefilter("ignore") done = np.loadtxt(file, dtype=float) if len(done): done = [int(s) for s in done[:, 0]] stars = list(set(stars) - set(done)) n = len(done) + 1 # Open the output file with open(file, 'a', 1) as outfile: # Loop over all to get the CDPP for EPIC in stars: # Progress sys.stdout.write('\rRunning target %d/%d...' % (n, nstars)) sys.stdout.flush() n += 1 # Get the number of outliers try: time, flux = get(EPIC, pipeline=pipeline, campaign=campaign) # Get the raw K2 data tpf = os.path.join( KPLR_ROOT, "data", "k2", "target_pixel_files", "%09d" % EPIC, "ktwo%09d-c%02d_lpd-targ.fits.gz" % (EPIC, campaign)) if not os.path.exists(tpf): client.k2_star(EPIC).get_target_pixel_files(fetch=True) with pyfits.open(tpf) as f: k2_qual = np.array(f[1].data.field('QUALITY'), dtype=int) k2_time = np.array(f[1].data.field('TIME'), dtype='float64') mask = [] for b in [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13, 14, 16, 17 ]: mask += list(np.where(k2_qual & 2**(b - 1))[0]) mask = np.array(sorted(list(set(mask)))) # Fill in missing cadences, if any tol = 0.005 if not ((len(time) == len(k2_time)) and (np.abs(time[0] - k2_time[0]) < tol) and (np.abs(time[-1] - k2_time[-1]) < tol)): ftmp = np.zeros_like(k2_time) * np.nan j = 0 for i, t in enumerate(k2_time): if np.abs(time[j] - t) < tol: ftmp[i] = flux[j] j += 1 if j == len(time) - 1: break flux = ftmp # Remove flagged cadences flux = np.delete(flux, mask) # Remove nans nanmask = np.where(np.isnan(flux))[0] flux = np.delete(flux, nanmask) # Iterative sigma clipping inds = np.array([], dtype=int) m = 1 while len(inds) < m: m = len(inds) f = SavGol(np.delete(flux, inds)) med = np.nanmedian(f) MAD = 1.4826 * np.nanmedian(np.abs(f - med)) inds = np.append( inds, np.where((f > med + sigma * MAD) | (f < med - sigma * MAD))[0]) nout = len(inds) ntot = len(flux) except (urllib.error.HTTPError, urllib.error.URLError, TypeError, ValueError, IndexError): print("{:>09d} {:>5d} {:>5d}".format(EPIC, -1, -1), file=outfile) continue # Log to file print("{:>09d} {:>5d} {:>5d}".format(EPIC, nout, ntot), file=outfile)
import k2plr kclient = k2plr.API() from appaloosa import detrend # these are nearby M dwarfs with short cadence Kepler data #kid = [9726699,8451881,201885041] kid = [9726699,8451881] for k in kid: if k>100000000: star = kclient.k2_star(k) else: star = kclient.star(k) lcs = star.get_light_curves(short_cadence=True, fetch=True) name = str(kid)+'.pkl' time, flux, ferr, quality = [], [], [], [] for lc in lcs[0:1]: with lc.open() as f: if f[0].header['OBSMODE'] == 'short cadence': print star, lc hdu_data = f[1].data time.append(hdu_data["time"]) flux.append(hdu_data["sap_flux"]) ferr.append(hdu_data["sap_flux_err"]) quality.append(hdu_data["sap_quality"]) box1 = detrend.MultiBoxcar(time_i[fin], flux_i[fin], err_i[fin], kernel=2.0, numpass=2) sin1, per = detrend.FitSin(time_i[fin], box1, err_i[fin], maxnum=5, maxper=(max(time_i)-min(time_i)
def generate_target(mag=12., roll=1., background_level=0., ccd_args=[], neighbor_magdiff=1., photnoise_conversion=.000625, ncadences=1000, apsize=7, ID=205998445, custom_ccd=False, transit=False, variable=False, neighbor=False, ftpf=None): """ Parameters ---------- `mag` : Magnitude of primary target PSF. `roll` : Coefficient on K2 motion vectors of target. roll=1 corresponds to current K2 motion. `background_level` : Constant background signal in each pixel. Defaults to 0. `ccd_args` : Autogenerated if nothing passed, otherwise takes the following arguments: `cx` : sensitivity variation coefficients in `x` `cy` : sensitivity variation coefficients in `y` `apsize` : see below `background_level` : see above `inter` : matrix (apsize x apsize) of stochastic inter-pixel sensitivity variation `photnoise_conversion`: see below `neighbor_magdiff` : Difference between magnitude of target and neighbor. Only accessed if neighbor initialized as `True` or if AddNeighbor() function is called. `photnoise_conversion` : Conversion factor for photon noise, defaults to 0.000625 for consistency with benchmark. `ncadences` : Number of cadences in simulated light curve. `apsize` : Dimension of aperture on each side. Returns ------- `Target`: :class:`Target` object A simulated CCD observation """ aperture = np.ones((ncadences, apsize, apsize)) # calculate PSF amplitude for given Kp Mag A = _calculate_PSF_amplitude(mag) # read in K2 motion vectors for provided K2 target (EPIC ID #) if ftpf is None: try: # access target information client = k2plr.API() star = client.k2_star(ID) tpf = star.get_target_pixel_files(fetch=True)[0] ftpf = os.path.join(KPLR_ROOT, 'data', 'k2', 'target_pixel_files', '%d' % ID, tpf._filename) except OSError: raise ScopeError( 'Unable to access internet. Please provide a path ' '(str) to desired file for motion using the `ftpf` ' 'keyword.') with fits.open(ftpf) as hdu: # read motion vectors in x and y xpos = _interpolate_nans(hdu[1].data['pos_corr1']) ypos = _interpolate_nans(hdu[1].data['pos_corr2']) t = _interpolate_nans(hdu[1].data['time'][:ncadences]) # throw out outliers for i in range(len(xpos)): if abs(xpos[i]) >= 50 or abs(ypos[i]) >= 50: xpos[i] = 0 ypos[i] = 0 if np.isnan(xpos[i]): xpos[i] = 0 if np.isnan(ypos[i]): ypos[i] = 0 # crop to desired length and multiply by roll coefficient xpos = xpos[0:ncadences] * roll ypos = ypos[0:ncadences] * roll # create self.inter-pixel sensitivity variation matrix # random normal distribution centered at 0.975 inter = np.zeros((apsize, apsize)) for i in range(apsize): for j in range(apsize): inter[i][j] = (0.975 + 0.001 * np.random.randn()) # assign PSF model parameters to be passed into PixelFlux function if not custom_ccd: # cx,cy: intra-pixel variation polynomial coefficients in x,y cx = [1.0, 0.0, -0.05] cy = [1.0, 0.0, -0.05] # x0,y0: center of PSF, half of aperture size plus random deviation x0 = (apsize / 2.0) + 0.2 * np.random.randn() y0 = (apsize / 2.0) + 0.2 * np.random.randn() # sx,sy: standard deviation of Gaussian in x,y # rho: rotation angle between x and y dimensions of Gaussian sx = [0.5 + 0.05 * np.random.randn()] sy = [0.5 + 0.05 * np.random.randn()] rho = [0.05 + 0.02 * np.random.randn()] psf_args = np.concatenate([[A], np.array([x0]), np.array([y0]), sx, sy, rho]) ccd_args = [cx, cy, apsize, background_level, inter, photnoise_conversion] ccd_args = ccd_args # initialize pixel flux light curve, target light curve, and isolated noise in each pixel fpix = np.zeros((ncadences, apsize, apsize)) target = np.zeros((ncadences, apsize, apsize)) ferr = np.zeros((ncadences, apsize, apsize)) ''' Here is where the light curves are created PSF function calculates flux in each pixel Iterate through cadences (c), and x and y dimensions on the detector (i,j) ''' for c in tqdm(range(ncadences)): fpix[c], target[c], ferr[c] = PSF(psf_args, ccd_args, xpos[c], ypos[c]) flux = np.sum(fpix.reshape((ncadences), -1), axis=1) return Target(fpix, flux, ferr, target, t, mag=mag, roll=roll, neighbor_magdiff=neighbor_magdiff, ncadences=ncadences, apsize=apsize, transit=transit, variable=variable, neighbor=neighbor, ccd_args=ccd_args, xpos=xpos, ypos=ypos)