Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 46 additions & 12 deletions src/lightkurve/missions/prf.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,13 @@
class PRF(ABC):
"""Abstract PRF class for working with Point Spread Functions"""

@abstractmethod
def __init__(
self,
supersamp_prf: npt.ArrayLike
target_locations: Union[List[Tuple], Tuple] = (5.5, 5.5),
origin: Tuple = (0, 0),
shape: Tuple = (11, 11),

):
"""
A generic base class object for PRFs. Not to be used directly.
Expand All @@ -37,6 +38,8 @@ def __init__(
self.origin_row, self.origin_column = origin
self.shape = shape
self.target_row, self.target_column = np.atleast_2d(target_locations)
self.col_coord, self.row_coord, self.interpolate = _prepare_prf(supersamp_prf)


def __repr__(self):
return "PRF Base Class"
Expand Down Expand Up @@ -195,13 +198,13 @@ def evaluate(
Parameters
----------
center_col, center_row : float
Column and row coordinates of the center
Column and row coordinates of the center
scale : float
Pixel scale stretch parameter, can be used to account for focus changes.
Values > 1 stretch the image, Values < 1 make the PRF more compact.
E.g. a scale value of 2 will double the PRF footprint.
Pixel scale stretch parameter, can be used to account for focus changes.
Values > 1 stretch the image, Values < 1 make the PRF more compact.
E.g. a scale value of 2 will double the PRF footprint.
rotation_angle : float
Rotation angle in radians
Rotation angle in radians

Returns
-------
Expand Down Expand Up @@ -424,13 +427,44 @@ def _prf_model(
)
return np.expand_dims(prf_model, axis=0)

def interpolate(self, row_grid, column_grid, dx=None, dy=None, grid=True):
raise NotImplementedError
#def interpolate(self, row_grid, column_grid, dx=None, dy=None, grid=True):
# raise NotImplementedError

@abstractmethod
def _prepare_prf(self):
"""Method to open PRF files for given mission"""
pass
def _prepare_prf(self, supersamp_prf: npt.ArrayLike,
crval1p: float,
crval2p: float,
cdelt1p: float,
cdelt2p: float),
pixel_offset: float = 0.5:
"""

pixel_offset: 0.5 offset necessary for TESS and Kepler
"""

PRFcol = np.arange(pixel_offset, np.shape(supersampled_prf)[1] + pixel_offset)
PRFrow = np.arange(pixel_offset, np.shape(supersampled_prf)[0] + pixel_offset)
PRFcol = (PRFcol - np.size(PRFcol) / 2) * cdelt1p
PRFrow = (PRFrow - np.size(PRFrow) / 2) * cdelt2p

# interpolate the calibrated PRF shape to the target position
rowdim, coldim = self.shape[0], self.shape[1]
ref_column = self.column + pixel_offset * coldim
ref_row = self.row + pixel_offset * rowdim


supersamp_prf /= np.nansum(supersamp_prf) * cdelt1p * cdelt2p

# location of the data image centered on the PRF image (in PRF pixel units)
col_coord = np.arange(self.column + pixel_offset, self.column + coldim + pixel_offset)
row_coord = np.arange(self.row + pixel_offset, self.row + rowdim + pixel_offset)
# x-axis correspond to row-axis in scipy.RectBivariate
# not to be confused with our convention, in which the
# x-axis correspond to the column-axis
interpolate = scipy.interpolate.RectBivariateSpline(
PRFrow, PRFcol, supersamp_prf
)

return col_coord, row_coord, interpolate

@abstractmethod
def _read_prf_calibration_file(self):
Expand Down
51 changes: 51 additions & 0 deletions tests/test_prf.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
"""
Tests for the functionality of the generic PRF module
"""
from lightkurve import PRF
# Create a grid that is super-sampled relative to true PRF pixels - to do this, creae a 2D Gaussian/exponential funcition

def make2DGaussian(size, fwhm = 3, center=None):
""" Make a square gaussian kernel.

size is the length of a side of the square
fwhm is full-width-half-maximum, which
can be thought of as an effective radius.
"""

x = np.arange(0, size, 1, float)
y = x[:,np.newaxis]

if center is None:
x0 = y0 = size // 2
else:
x0 = center[0]
y0 = center[1]

return np.exp(-4*np.log(2) * ((x-x0)**2 + (y-y0)**2) / fwhm**2)

generic_prf = PRF() #initialize model here
supersample_factor=10
supersampled_prf = make2DGaussian(prf_model.shape[0]*supersample_factor, fwhm=prf_model.shape[0]*supersample_factor/3)

# Need to flesh out _prepare_prf()
prf_model = generic_prf.evaluate()


class PRF(object):

def __init__(self, prf_image:np.NDArray, row, column):



class KeplerPRF(PRF):
"""Grabs the PRF files from the right place online
Intializes them from files correctly"""
def __init__(self, ..., quarter, channel):
# open file
# initialize super class



# Add check for completeness and contamination
# check the aperture matches expectation