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_fast_method(data, objective, offset): t, y, dy, params = data if offset: t = t - params["transit_time"] + params["period"] model = BoxLeastSquares(t, y, dy) periods = np.exp(np.linspace(np.log(params["period"]) - 1, np.log(params["period"]) + 1, 10)) durations = params["duration"] results = model.power(periods, durations, objective=objective) assert_allclose_blsresults(results, model.power(periods, durations, method="slow", objective=objective))
def test_shapes(data, shape): t, y, dy, params = data duration = params["duration"] model = BoxLeastSquares(t, y, dy) period = np.empty(shape) period.flat = np.linspace(params["period"]-1, params["period"]+1, period.size) if len(period.shape) > 1: with pytest.raises(ValueError): results = model.power(period, duration) else: results = model.power(period, duration) for k, v in results.items(): if k == "objective": continue assert v.shape == shape
def test_autopower(data): t, y, dy, params = data duration = params["duration"] + np.linspace(-0.1, 0.1, 3) model = BoxLeastSquares(t, y, dy) period = model.autoperiod(duration) results1 = model.power(period, duration) results2 = model.autopower(duration) assert_allclose_blsresults(results1, results2)
def test_correct_model(data, objective): t, y, dy, params = data model = BoxLeastSquares(t, y, dy) periods = np.exp(np.linspace(np.log(params["period"]) - 0.1, np.log(params["period"]) + 0.1, 1000)) results = model.power(periods, params["duration"], objective=objective) ind = np.argmax(results.power) for k, v in params.items(): assert_allclose(results[k][ind], v, atol=0.01) chi = (results.depth[ind]-params["depth"]) / results.depth_err[ind] assert np.abs(chi) < 1
def test_results_units(data, method, with_err, t_unit, y_unit, objective): t, y, dy, params = data periods = np.linspace(params["period"] - 1.0, params["period"] + 1.0, 3) if t_unit is not None: t = t * t_unit if y_unit is not None: y = y * y_unit dy = dy * y_unit if not with_err: dy = None model = BoxLeastSquares(t, y, dy) results = model.power(periods, params["duration"], method=method, objective=objective) if t_unit is None: assert not has_units(results.period) assert not has_units(results.duration) assert not has_units(results.transit_time) else: assert results.period.unit == t_unit assert results.duration.unit == t_unit assert results.transit_time.unit == t_unit if y_unit is None: assert not has_units(results.power) assert not has_units(results.depth) assert not has_units(results.depth_err) assert not has_units(results.depth_snr) assert not has_units(results.log_likelihood) else: assert results.depth.unit == y_unit assert results.depth_err.unit == y_unit assert results.depth_snr.unit == units.one if dy is None: assert results.log_likelihood.unit == y_unit * y_unit if objective == "snr": assert results.power.unit == units.one else: assert results.power.unit == y_unit * y_unit else: assert results.log_likelihood.unit == units.one assert results.power.unit == units.one
def test_32bit_bug(): rand = np.random.RandomState(42) t = rand.uniform(0, 10, 500) y = np.ones_like(t) y[np.abs((t + 1.0) % 2.0 - 1) < 0.08] = 1.0 - 0.1 y += 0.01 * rand.randn(len(t)) model = BoxLeastSquares(t, y) results = model.autopower(0.16) assert np.allclose(results.period[np.argmax(results.power)], 1.9923406038842544) periods = np.linspace(1.9, 2.1, 5) results = model.power(periods, 0.16) assert np.allclose( results.power, np.array([0.01421067, 0.02842475, 0.10867671, 0.05117755, 0.01783253]))
def test_32bit_bug(): rand = np.random.default_rng(42) t = rand.uniform(0, 10, 500) y = np.ones_like(t) y[np.abs((t + 1.0) % 2.0 - 1) < 0.08] = 1.0 - 0.1 y += 0.01 * rand.standard_normal(len(t)) model = BoxLeastSquares(t, y) results = model.autopower(0.16) assert_allclose(results.period[np.argmax(results.power)], 2.000412388152837) periods = np.linspace(1.9, 2.1, 5) results = model.power(periods, 0.16) assert_allclose(results.power, [0.01723948, 0.0643028, 0.1338783, 0.09428816, 0.03577543], rtol=1.1e-7)
def test_32bit_bug(): rand = np.random.RandomState(42) t = rand.uniform(0, 10, 500) y = np.ones_like(t) y[np.abs((t + 1.0) % 2.0-1) < 0.08] = 1.0 - 0.1 y += 0.01 * rand.randn(len(t)) model = BoxLeastSquares(t, y) results = model.autopower(0.16) assert np.allclose(results.period[np.argmax(results.power)], 1.9923406038842544) periods = np.linspace(1.9, 2.1, 5) results = model.power(periods, 0.16) assert np.allclose( results.power, np.array([0.01421067, 0.02842475, 0.10867671, 0.05117755, 0.01783253]) )
def test_results_units(data, method, with_err, t_unit, y_unit, objective): t, y, dy, params = data periods = np.linspace(params["period"]-1.0, params["period"]+1.0, 3) if t_unit is not None: t = t * t_unit if y_unit is not None: y = y * y_unit dy = dy * y_unit if not with_err: dy = None model = BoxLeastSquares(t, y, dy) results = model.power(periods, params["duration"], method=method, objective=objective) if t_unit is None: assert not has_units(results.period) assert not has_units(results.duration) assert not has_units(results.transit_time) else: assert results.period.unit == t_unit assert results.duration.unit == t_unit assert results.transit_time.unit == t_unit if y_unit is None: assert not has_units(results.power) assert not has_units(results.depth) assert not has_units(results.depth_err) assert not has_units(results.depth_snr) assert not has_units(results.log_likelihood) else: assert results.depth.unit == y_unit assert results.depth_err.unit == y_unit assert results.depth_snr.unit == u.one if dy is None: assert results.log_likelihood.unit == y_unit * y_unit if objective == "snr": assert results.power.unit == u.one else: assert results.power.unit == y_unit * y_unit else: assert results.log_likelihood.unit == u.one assert results.power.unit == u.one