#!/usr/bin/env python # coding: utf-8 # # Replicate Vanderburg & Johnson 2014 K2SFF Method # In this notebook we will replicate the K2SFF method from [Vanderburg and Johnson 2014](http://adsabs.harvard.edu/abs/2014PASP..126..948V). The paper introduces a method for "Self Flat Fielding", by tracking how the lightcurve changes with motion of the spacecraft. # In[1]: from pyke import KeplerTargetPixelFile get_ipython().run_line_magic('matplotlib', 'inline') get_ipython().run_line_magic('config', "InlineBackend.figure_format = 'retina'") import numpy as np import matplotlib.pyplot as plt # In[2]: #from oktopus import UniformPrior, JointPrior #from pyke import PRFPhotometry, SceneModel #from pyke.utils import KeplerQualityFlags # ## Get data # In[3]: #! wget https://www.cfa.harvard.edu/~avanderb/k2/ep60021426alldiagnostics.csv # In[4]: import pandas as pd # In[5]: df = pd.read_csv('ep60021426alldiagnostics.csv',index_col=False) # In[6]: df.head() # Let's use the provided $x-y$ centroids, but we could compute these on our own too. # In[7]: col = df[' X-centroid'].values col = col - np.mean(col) row = df[' Y-centroid'].values row = row - np.mean(row) # In[8]: def _get_eigen_vectors(centroid_col, centroid_row): centroids = np.array([centroid_col, centroid_row]) eig_val, eig_vec = np.linalg.eigh(np.cov(centroids)) return eig_val, eig_vec # In[9]: def _rotate(eig_vec, centroid_col, centroid_row): centroids = np.array([centroid_col, centroid_row]) return np.dot(eig_vec, centroids) # In[10]: eig_val, eig_vec = _get_eigen_vectors(col, row) # In[11]: v1, v2 = eig_vec # The major axis is the last one. # In[12]: plt.figure(figsize=(5, 6)) plt.plot(col*4.0, row*4.0, 'ko', ms=4) plt.plot(col*4.0, row*4.0, 'ro', ms=1) plt.xticks([-2, -1,0, 1, 2]) plt.yticks([-2, -1,0, 1, 2]) plt.xlabel('X position [arcseconds]') plt.ylabel('Y position [arcseconds]') plt.xlim(-2, 2) plt.ylim(-2, 2) plt.plot([0, v1[0]], [0, v1[1]], color='blue', lw=3) plt.plot([0, v2[0]], [0, v2[1]], color='blue', lw=3); # Following the form of Figure 2 of Vanderburg & Johsnon 2014. # In[13]: rot_colp, rot_rowp = _rotate(eig_vec, col, row) # You can rotate into the new reference frame. # In[14]: plt.figure(figsize=(5, 6)) plt.plot(rot_rowp*4.0, rot_colp*4.0, 'ko', ms=4) plt.plot(rot_rowp*4.0, rot_colp*4.0, 'ro', ms=1) plt.xticks([-2, -1,0, 1, 2]) plt.yticks([-2, -1,0, 1, 2]) plt.xlabel("X' position [arcseconds]") plt.ylabel("Y' position [arcseconds]") plt.xlim(-2, 2) plt.ylim(-2, 2) plt.plot([0, 1], [0, 0], color='blue') plt.plot([0, 0], [0, 1], color='blue'); # We need to calculate the arclength using: # $$s= \int_{x'_0}^{x'_1}\sqrt{1+\left( \frac{dy'_p}{dx'}\right)^2} dx'$$ # # > where $x^\prime_0$ is the transformed $x$ coordinate of the point with the smallest $x^\prime$ position, and $y^\prime_p$ is the best--fit polynomial function. # In[15]: z = np.polyfit(rot_rowp, rot_colp, 5) p5 = np.poly1d(z) p5_deriv = p5.deriv() # In[16]: x0_prime = np.min(rot_rowp) xmax_prime = np.max(rot_rowp) # In[17]: x_dense = np.linspace(x0_prime, xmax_prime, 2000) # In[18]: plt.plot(rot_rowp, rot_colp, '.') plt.plot(x_dense, p5(x_dense)); # In[19]: @np.vectorize def arclength(x): '''Input x1_prime, get out arclength''' gi = x_dense