def test_keplerprf_gradient_against_calculus(param_to_test): """is the gradient of KeplerPRF consistent with Calculus?""" params = OrderedDict([ ("center_col", 7), ("center_row", 7), ("flux", 1000.0), ("scale_col", 1.0), ("scale_row", 1.0), ("rotation_angle", 0), ]) param_order = OrderedDict(zip(params.keys(), range(0, 6))) kwargs = {"channel": 56, "shape": [15, 15], "column": 0, "row": 0} prf = KeplerPRF(**kwargs) h = 1e-8 f = prf.evaluate inc_params = params.copy() # increment the parameter under test for later finite difference computation inc_params[param_to_test] += h # compute finite differences diff_prf = (f(**inc_params) - f(**params)) / h # compute analytical gradient prf_grad = prf.gradient(**params) # assert that the average absolute/relative error is less than 1e-5 assert (np.max( np.abs(prf_grad[param_order[param_to_test]] - diff_prf) / (1.0 + np.abs(diff_prf))) < 1e-5)
def test_keplerprf_gradient_against_simplekeplerprf(): """is the gradient of KeplerPRF consistent with the gradient of SimpleKeplerPRF? """ kwargs = {"channel": 56, "shape": [15, 15], "column": 0, "row": 0} params = {"center_col": 7, "center_row": 7, "flux": 1.0} simple_prf = SimpleKeplerPRF(**kwargs) prf = KeplerPRF(**kwargs) prf_grad = prf.gradient(rotation_angle=0.0, scale_col=1.0, scale_row=1.0, **params) assert_allclose(prf_grad[:-3], simple_prf.gradient(**params))
def test_prf_normalization(): """Does the PRF model integrate to the requested flux across the focal plane?""" for channel in [1, 20, 40, 60, 84]: for col in [123, 678]: for row in [234, 789]: shape = (18, 14) flux = 100 prf = KeplerPRF(channel=channel, column=col, row=row, shape=shape) prf_sum = prf.evaluate(col + shape[0] / 2, row + shape[1] / 2, flux, 1, 1, 0).sum() assert np.isclose(prf_sum, flux, rtol=0.1)
def test_tpf_model_fitting(): # Is the PRF photometry result consistent with simple aperture photometry? tpf_fn = os.path.join(TESTDATA, "ktwo201907706-c01-first-cadence.fits.gz") tpf = fits.open(tpf_fn) col, row = 173, 526 fluxsum = np.sum(tpf[1].data) bkg = mode(tpf[1].data, None)[0] prfmodel = KeplerPRF( channel=tpf[0].header["CHANNEL"], column=col, row=row, shape=tpf[1].data.shape ) star_priors = [ StarPrior( col=UniformPrior(lb=prfmodel.col_coord[0], ub=prfmodel.col_coord[-1]), row=UniformPrior(lb=prfmodel.row_coord[0], ub=prfmodel.row_coord[-1]), flux=UniformPrior(lb=0.5 * fluxsum, ub=1.5 * fluxsum), ) ] background_prior = BackgroundPrior(flux=UniformPrior(lb=0.5 * bkg, ub=1.5 * bkg)) model = TPFModel( star_priors=star_priors, background_prior=background_prior, prfmodel=prfmodel ) # Does fitting run without errors? result = model.fit(tpf[1].data) # Can we change model parameters? assert result.motion.fitted == False model.fit_motion = True result = model.fit(tpf[1].data) assert result.motion.fitted == True # Does fitting via the PRFPhotometry class run without errors? phot = PRFPhotometry(model) phot.run([tpf[1].data])
def test_get_model_prf(): tpf_fn = get_pkg_data_filename("../../tests/data/test-tpf-star.fits") tpf = KeplerTargetPixelFile(tpf_fn) prf = KeplerPRF(channel=tpf.channel, shape=tpf.shape[1:], column=tpf.column, row=tpf.row) prf_from_tpf = tpf.get_prf_model() assert type(prf) == type(prf_from_tpf) assert prf.channel == prf_from_tpf.channel assert prf.shape == prf_from_tpf.shape assert prf.column == prf_from_tpf.column assert prf.row == prf_from_tpf.row
def test_model_with_one_star(): """Can we fit the background flux in a model with one star?""" channel = 42 shape = (10, 12) starflux, col, row = 1000.0, 60.0, 70.0 bgflux = 10.0 scale_col, scale_row, rotation_angle = 1.2, 1.3, 0.2 prf = KeplerPRF(channel=channel, shape=shape, column=col, row=row) star_prior = StarPrior( col=GaussianPrior(col + 6, 0.01), row=GaussianPrior(row + 6, 0.01), flux=UniformPrior(lb=0.5 * starflux, ub=1.5 * starflux), ) background_prior = BackgroundPrior(flux=UniformPrior(lb=0, ub=100)) focus_prior = FocusPrior( scale_col=UniformPrior(lb=0.5, ub=1.5), scale_row=UniformPrior(lb=0.5, ub=1.5), rotation_angle=UniformPrior(lb=0.0, ub=0.5), ) model = TPFModel( star_priors=[star_prior], background_prior=background_prior, focus_prior=focus_prior, prfmodel=prf, fit_background=True, fit_focus=True, ) # Generate and fit fake data fake_data = bgflux + prf( col + 6, row + 6, starflux, scale_col=scale_col, scale_row=scale_row, rotation_angle=rotation_angle, ) results = model.fit(fake_data, tol=1e-12, options={"maxiter": 100}) # Do the results match the input? assert np.isclose(results.stars[0].col, col + 6) assert np.isclose(results.stars[0].row, row + 6) assert np.isclose(results.stars[0].flux, starflux) assert np.isclose(results.background.flux, bgflux) assert np.isclose(results.focus.scale_col, scale_col) assert np.isclose(results.focus.scale_row, scale_row) assert np.isclose(results.focus.rotation_angle, rotation_angle)
def test_tpf_model(): col, row, flux, bgflux = 1, 2, 3, 4 shape = (7, 8) model = TPFModel( star_priors=[ StarPrior( col=GaussianPrior(mean=col, var=2 ** 2), row=GaussianPrior(mean=row, var=2 ** 2), flux=UniformPrior(lb=flux - 0.5, ub=flux + 0.5), targetid="TESTSTAR", ) ], background_prior=BackgroundPrior(flux=GaussianPrior(mean=bgflux, var=bgflux)), focus_prior=FocusPrior( scale_col=GaussianPrior(mean=1, var=0.0001), scale_row=GaussianPrior(mean=1, var=0.0001), rotation_angle=UniformPrior(lb=-3.1415, ub=3.1415), ), motion_prior=MotionPrior( shift_col=GaussianPrior(mean=0.0, var=0.01), shift_row=GaussianPrior(mean=0.0, var=0.01), ), prfmodel=KeplerPRF(channel=40, shape=shape, column=30, row=20), fit_background=True, fit_focus=False, fit_motion=False, ) # Sanity checks assert model.star_priors[0].col.mean == col assert model.star_priors[0].targetid == "TESTSTAR" # Test initial guesses params = model.get_initial_guesses() assert params.stars[0].col == col assert params.stars[0].row == row assert params.stars[0].flux == flux assert params.background.flux == bgflux assert len(params.to_array()) == 4 # The model has 4 free parameters assert_allclose([col, row, flux, bgflux], params.to_array(), rtol=1e-5) # Predict should return an image assert model.predict().shape == shape # Test __repr__ assert "TESTSTAR" in str(model)