def test_compute_stats(data, with_units, with_err): t, y, dy, params = data y_unit = 1 if with_units: y_unit = u.mag t = t * u.day y = y * u.mag dy = dy * u.mag params["period"] = params["period"] * u.day params["duration"] = params["duration"] * u.day params["transit_time"] = params["transit_time"] * u.day params["depth"] = params["depth"] * u.mag if not with_err: dy = None model = BoxLeastSquares(t, y, dy) results = model.power(params["period"], params["duration"], oversample=1000) stats = model.compute_stats(params["period"], params["duration"], params["transit_time"]) # Test the calculated transit times tt = params["period"] * np.arange(int(t.max() / params["period"]) + 1) tt += params["transit_time"] assert_quantity_allclose(tt, stats["transit_times"]) # Test that the other parameters are consistent with the periodogram assert_allclose(stats["per_transit_count"], [9, 7, 7, 7, 8]) assert_quantity_allclose(np.sum(stats["per_transit_log_likelihood"]), results["log_likelihood"]) assert_quantity_allclose(stats["depth"][0], results["depth"]) # Check the half period result results_half = model.power(0.5 * params["period"], params["duration"], oversample=1000) assert_quantity_allclose(stats["depth_half"][0], results_half["depth"]) # Skip the uncertainty tests when the input errors are None if not with_err: assert_quantity_allclose(stats["harmonic_amplitude"], 0.029945029964964204 * y_unit) assert_quantity_allclose(stats["harmonic_delta_log_likelihood"], -0.5875918155223113 * y_unit * y_unit) return assert_quantity_allclose(stats["harmonic_amplitude"], 0.033027988742275853 * y_unit) assert_quantity_allclose(stats["harmonic_delta_log_likelihood"], -12407.505922833765) assert_quantity_allclose(stats["depth"][1], results["depth_err"]) assert_quantity_allclose(stats["depth_half"][1], results_half["depth_err"]) for f, k in zip((1.0, 1.0, 1.0, 0.0), ("depth", "depth_even", "depth_odd", "depth_phased")): res = np.abs((stats[k][0] - f * params["depth"]) / stats[k][1]) assert res < 1, f'f={f}, k={k}, res={res}'
def test_compute_stats(data, with_units, with_err): t, y, dy, params = data y_unit = 1 if with_units: y_unit = u.mag t = t * u.day y = y * u.mag dy = dy * u.mag params["period"] = params["period"] * u.day params["duration"] = params["duration"] * u.day params["transit_time"] = params["transit_time"] * u.day params["depth"] = params["depth"] * u.mag if not with_err: dy = None model = BoxLeastSquares(t, y, dy) results = model.power(params["period"], params["duration"], oversample=1000) stats = model.compute_stats(params["period"], params["duration"], params["transit_time"]) # Test the calculated transit times tt = params["period"] * np.arange(int(t.max() / params["period"]) + 1) tt += params["transit_time"] assert_quantity_allclose(tt, stats["transit_times"]) # Test that the other parameters are consistent with the periodogram assert_allclose(stats["per_transit_count"], np.array([9, 7, 7, 7, 8])) assert_quantity_allclose(np.sum(stats["per_transit_log_likelihood"]), results["log_likelihood"]) assert_quantity_allclose(stats["depth"][0], results["depth"]) # Check the half period result results_half = model.power(0.5*params["period"], params["duration"], oversample=1000) assert_quantity_allclose(stats["depth_half"][0], results_half["depth"]) # Skip the uncertainty tests when the input errors are None if not with_err: assert_quantity_allclose(stats["harmonic_amplitude"], 0.029945029964964204 * y_unit) assert_quantity_allclose(stats["harmonic_delta_log_likelihood"], -0.5875918155223113 * y_unit * y_unit) return assert_quantity_allclose(stats["harmonic_amplitude"], 0.033027988742275853 * y_unit) assert_quantity_allclose(stats["harmonic_delta_log_likelihood"], -12407.505922833765) assert_quantity_allclose(stats["depth"][1], results["depth_err"]) assert_quantity_allclose(stats["depth_half"][1], results_half["depth_err"]) for f, k in zip((1.0, 1.0, 1.0, 0.0), ("depth", "depth_even", "depth_odd", "depth_phased")): assert np.abs((stats[k][0]-f*params["depth"]) / stats[k][1]) < 1.0
def test_absolute_times(data, timedelta): # Make sure that we handle absolute times correctly. We also check that # TimeDelta works properly when timedelta is True. # The example data uses relative times t, y, dy, params = data # FIXME: There seems to be a numerical stability issue in that if we run # the algorithm with the same values but offset in time, the transit_time # is not offset by a fixed amount. To avoid this issue in this test, we # make sure the first time is also the smallest so that internally the # values of the relative time should be the same. t[0] = 0. # Add units t = t * u.day y = y * u.mag dy = dy * u.mag # We now construct a set of absolute times but keeping the rest the same. start = Time('2019-05-04T12:34:56') trel = TimeDelta(t) if timedelta else t t = trel + start # and we set up two instances of BoxLeastSquares, one with absolute and one # with relative times. bls1 = BoxLeastSquares(t, y, dy) bls2 = BoxLeastSquares(trel, y, dy) results1 = bls1.autopower(0.16 * u.day) results2 = bls2.autopower(0.16 * u.day) # All the results should match except transit time which should be # absolute instead of relative in the first case. for key in results1: if key == 'transit_time': assert_quantity_allclose((results1[key] - start).to(u.day), results2[key]) elif key == 'objective': assert results1[key] == results2[key] else: assert_allclose(results1[key], results2[key]) # Check that model evaluation works fine model1 = bls1.model(t, 0.2 * u.day, 0.05 * u.day, Time('2019-06-04T12:34:56')) model2 = bls2.model(trel, 0.2 * u.day, 0.05 * u.day, TimeDelta(1 * u.day)) assert_quantity_allclose(model1, model2) # Check model validation with pytest.raises(TypeError) as exc: bls1.model(t, 0.2 * u.day, 0.05 * u.day, 1 * u.day) assert exc.value.args[0] == ('transit_time was provided as a relative time ' 'but the BoxLeastSquares class was initialized ' 'with absolute times.') with pytest.raises(TypeError) as exc: bls1.model(trel, 0.2 * u.day, 0.05 * u.day, Time('2019-06-04T12:34:56')) assert exc.value.args[0] == ('t_model was provided as a relative time ' 'but the BoxLeastSquares class was initialized ' 'with absolute times.') with pytest.raises(TypeError) as exc: bls2.model(trel, 0.2 * u.day, 0.05 * u.day, Time('2019-06-04T12:34:56')) assert exc.value.args[0] == ('transit_time was provided as an absolute time ' 'but the BoxLeastSquares class was initialized ' 'with relative times.') with pytest.raises(TypeError) as exc: bls2.model(t, 0.2 * u.day, 0.05 * u.day, 1 * u.day) assert exc.value.args[0] == ('t_model was provided as an absolute time ' 'but the BoxLeastSquares class was initialized ' 'with relative times.') # Check compute_stats stats1 = bls1.compute_stats(0.2 * u.day, 0.05 * u.day, Time('2019-06-04T12:34:56')) stats2 = bls2.compute_stats(0.2 * u.day, 0.05 * u.day, 1 * u.day) for key in stats1: if key == 'transit_times': assert_quantity_allclose((stats1[key] - start).to(u.day), stats2[key], atol=1e-10 * u.day) elif key.startswith('depth'): for value1, value2 in zip(stats1[key], stats2[key]): assert_quantity_allclose(value1, value2) else: assert_allclose(stats1[key], stats2[key]) # Check compute_stats validation with pytest.raises(TypeError) as exc: bls1.compute_stats(0.2 * u.day, 0.05 * u.day, 1 * u.day) assert exc.value.args[0] == ('transit_time was provided as a relative time ' 'but the BoxLeastSquares class was initialized ' 'with absolute times.') with pytest.raises(TypeError) as exc: bls2.compute_stats(0.2 * u.day, 0.05 * u.day, Time('2019-06-04T12:34:56')) assert exc.value.args[0] == ('transit_time was provided as an absolute time ' 'but the BoxLeastSquares class was initialized ' 'with relative times.') # Check transit_mask mask1 = bls1.transit_mask(t, 0.2 * u.day, 0.05 * u.day, Time('2019-06-04T12:34:56')) mask2 = bls2.transit_mask(trel, 0.2 * u.day, 0.05 * u.day, 1 * u.day) assert_equal(mask1, mask2) # Check transit_mask validation with pytest.raises(TypeError) as exc: bls1.transit_mask(t, 0.2 * u.day, 0.05 * u.day, 1 * u.day) assert exc.value.args[0] == ('transit_time was provided as a relative time ' 'but the BoxLeastSquares class was initialized ' 'with absolute times.') with pytest.raises(TypeError) as exc: bls1.transit_mask(trel, 0.2 * u.day, 0.05 * u.day, Time('2019-06-04T12:34:56')) assert exc.value.args[0] == ('t was provided as a relative time ' 'but the BoxLeastSquares class was initialized ' 'with absolute times.') with pytest.raises(TypeError) as exc: bls2.transit_mask(trel, 0.2 * u.day, 0.05 * u.day, Time('2019-06-04T12:34:56')) assert exc.value.args[0] == ('transit_time was provided as an absolute time ' 'but the BoxLeastSquares class was initialized ' 'with relative times.') with pytest.raises(TypeError) as exc: bls2.transit_mask(t, 0.2 * u.day, 0.05 * u.day, 1 * u.day) assert exc.value.args[0] == ('t was provided as an absolute time ' 'but the BoxLeastSquares class was initialized ' 'with relative times.')