# -*- coding: utf-8 -*- # Licensed under a 3-clause BSD style license - see LICENSE.rst import pytest import numpy as np from numpy.testing import assert_allclose, assert_equal from astropy import units as u from astropy.time import Time, TimeDelta from astropy.tests.helper import assert_quantity_allclose from astropy.timeseries.periodograms.bls import BoxLeastSquares from astropy.timeseries.periodograms.lombscargle.core import has_units def assert_allclose_blsresults(blsresult, other, **kwargs): """Assert that another BoxLeastSquaresResults object is consistent This method loops over all attributes and compares the values using :func:`~astropy.tests.helper.assert_quantity_allclose` function. Parameters ---------- other : BoxLeastSquaresResults The other results object to compare. """ for k, v in blsresult.items(): if k not in other: raise AssertionError(f"missing key '{k}'") if k == "objective": assert v == other[k], ( f"Mismatched objectives. Expected '{v}', got '{other[k]}'" ) continue assert_quantity_allclose(v, other[k], **kwargs) # NOTE: PR 10644 replaced deprecated usage of RandomState but could not # find a new seed that did not cause test failure, resorted to hardcoding. @pytest.fixture def data(): t = np.array([ 6.96469186, 2.86139335, 2.26851454, 5.51314769, 7.1946897, 4.2310646, 9.80764198, 6.84829739, 4.80931901, 3.92117518, 3.43178016, 7.29049707, 4.38572245, 0.59677897, 3.98044255, 7.37995406, 1.8249173, 1.75451756, 5.31551374, 5.31827587, 6.34400959, 8.49431794, 7.24455325, 6.11023511, 7.22443383, 3.22958914, 3.61788656, 2.28263231, 2.93714046, 6.30976124, 0.9210494, 4.33701173, 4.30862763, 4.93685098, 4.2583029, 3.12261223, 4.26351307, 8.93389163, 9.44160018, 5.01836676, 6.23952952, 1.15618395, 3.17285482, 4.14826212, 8.66309158, 2.50455365, 4.83034264, 9.85559786, 5.19485119, 6.12894526, 1.20628666, 8.26340801, 6.03060128, 5.45068006, 3.42763834, 3.04120789, 4.17022211, 6.81300766, 8.75456842, 5.10422337, 6.69313783, 5.85936553, 6.24903502, 6.74689051, 8.42342438, 0.83194988, 7.63682841, 2.43666375, 1.94222961, 5.72456957, 0.95712517, 8.85326826, 6.27248972, 7.23416358, 0.16129207, 5.94431879, 5.56785192, 1.58959644, 1.53070515, 6.95529529, 3.18766426, 6.91970296, 5.5438325, 3.88950574, 9.2513249, 8.41669997, 3.57397567, 0.43591464, 3.04768073, 3.98185682, 7.0495883, 9.95358482, 3.55914866, 7.62547814, 5.93176917, 6.91701799, 1.51127452, 3.98876293, 2.40855898, 3.43456014, 5.13128154, 6.6662455, 1.05908485, 1.30894951, 3.21980606, 6.61564337, 8.46506225, 5.53257345, 8.54452488, 3.84837811, 3.16787897, 3.54264676, 1.71081829, 8.29112635, 3.38670846, 5.52370075, 5.78551468, 5.21533059, 0.02688065, 9.88345419, 9.05341576, 2.07635861, 2.92489413, 5.20010153, 9.01911373, 9.83630885, 2.57542064, 5.64359043, 8.06968684, 3.94370054, 7.31073036, 1.61069014, 6.00698568, 8.65864458, 9.83521609, 0.7936579, 4.28347275, 2.0454286, 4.50636491, 5.47763573, 0.9332671, 2.96860775, 9.2758424, 5.69003731, 4.57411998, 7.53525991, 7.41862152, 0.48579033, 7.08697395, 8.39243348, 1.65937884, 7.80997938, 2.86536617, 3.06469753, 6.65261465, 1.11392172, 6.64872449, 8.87856793, 6.96311268, 4.40327877, 4.38214384, 7.65096095, 5.65642001, 0.84904163, 5.82671088, 8.14843703, 3.37066383, 9.2757658, 7.50717, 5.74063825, 7.51643989, 0.79148961, 8.59389076, 8.21504113, 9.0987166, 1.28631198, 0.81780087, 1.38415573, 3.9937871, 4.24306861, 5.62218379, 1.2224355, 2.01399501, 8.11644348, 4.67987574, 8.07938209, 0.07426379, 5.51592726, 9.31932148, 5.82175459, 2.06095727, 7.17757562, 3.7898585, 6.68383947, 0.29319723, 6.35900359, 0.32197935, 7.44780655, 4.72913002, 1.21754355, 5.42635926, 0.66774443, 6.53364871, 9.96086327, 7.69397337, 5.73774114, 1.02635259, 6.99834075, 6.61167867, 0.49097131, 7.92299302, 5.18716591, 4.25867694, 7.88187174, 4.11569223, 4.81026276, 1.81628843, 3.213189, 8.45532997, 1.86903749, 4.17291061, 9.89034507, 2.36599812, 9.16832333, 9.18397468, 0.91296342, 4.63652725, 5.02216335, 3.1366895, 0.47339537, 2.41685637, 0.95529642, 2.38249906, 8.07791086, 8.94978288, 0.43222892, 3.01946836, 9.80582199, 5.39504823, 6.26309362, 0.05545408, 4.84909443, 9.88328535, 3.75185527, 0.97038159, 4.61908762, 9.63004466, 3.41830614, 7.98922733, 7.98846331, 2.08248297, 4.43367702, 7.15601275, 4.10519785, 1.91006955, 9.67494307, 6.50750366, 8.65459852, 2.52423578e-01, 2.66905815, 5.02071100, 6.74486351e-01, 9.93033261, 2.36462396, 3.74292182, 2.14011915, 1.05445866, 2.32479786, 3.00610136, 6.34442268, 2.81234781, 3.62276761, 5.94284372e-02, 3.65719126, 5.33885982, 1.62015837, 5.97433108, 2.93152469, 6.32050495, 2.61966053e-01, 8.87593460, 1.61186304e-01, 1.26958031, 7.77162462, 4.58952322e-01, 7.10998694, 9.71046141, 8.71682933, 7.10161651, 9.58509743, 4.29813338, 8.72878914, 3.55957668, 9.29763653, 1.48777656, 9.40029015, 8.32716197, 8.46054838, 1.23923010, 5.96486898, 1.63924809e-01, 7.21184366, 7.73751413e-02, 8.48222774e-01, 2.25498410, 8.75124534, 3.63576318, 5.39959935, 5.68103214, 2.25463360, 5.72146768, 6.60951795, 2.98245393, 4.18626859, 4.53088925, 9.32350662, 5.87493747, 9.48252372, 5.56034754, 5.00561421, 3.53221097e-02, 4.80889044, 9.27454999, 1.98365689, 5.20911344e-01, 4.06778893, 3.72396481, 8.57153058, 2.66111156e-01, 9.20149230, 6.80902999, 9.04225994, 6.07529071, 8.11953312, 3.35543874, 3.49566228, 3.89874230, 7.54797082, 3.69291174, 2.42219806, 9.37668357, 9.08011084, 3.48797316, 6.34638070, 2.73842212, 2.06115129, 3.36339529, 3.27099893, 8.82276101, 8.22303815, 7.09623229, 9.59345225, 4.22543353, 2.45033039, 1.17398437, 3.01053358, 1.45263734, 9.21860974e-01, 6.02932197, 3.64187450, 5.64570343, 1.91335721, 6.76905860, 2.15505447, 2.78023594, 7.41760422, 5.59737896, 3.34836413, 5.42988783, 6.93984703, 9.12132121, 5.80713213, 2.32686379, 7.46697631, 7.77769018, 2.00401315, 8.20574220, 4.64934855, 7.79766662, 2.37478220, 3.32580270, 9.53697119, 6.57815073, 7.72877831, 6.88374343, 2.04304118, 4.70688748, 8.08963873, 6.75035127, 6.02788565e-02, 8.74077427e-01, 3.46794720, 9.44365540, 4.91190481, 2.70176267, 3.60423719, 2.10652628, 4.21200057, 2.18035440, 8.45752507, 4.56270599, 2.79802018, 9.32891648, 3.14351354, 9.09714662, 4.34180910e-01, 7.07115060, 4.83889039, 4.44221061, 3.63233444e-01, 4.06831905e-01, 3.32753617, 9.47119540, 6.17659977, 3.68874842, 6.11977039, 2.06131536, 1.65066443, 3.61817266, 8.63353352, 5.09401727, 2.96901516, 9.50251625, 8.15966090, 3.22973943, 9.72098245, 9.87351098, 4.08660134, 6.55923103, 4.05653198, 2.57348106, 8.26526760e-01, 2.63610346, 2.71479854, 3.98639080, 1.84886031, 9.53818403, 1.02879885, 6.25208533, 4.41697388, 4.23518049, 3.71991783, 8.68314710, 2.80476981, 2.05761574e-01, 9.18097016, 8.64480278, 2.76901790, 5.23487548, 1.09088197, 9.34270688e-01, 8.37466108, 4.10265718, 6.61716540, 9.43200558, 2.45130592, 1.31598313e-01, 2.41484058e-01, 7.09385692, 9.24551885, 4.67330273, 3.75109148, 5.42860425, 8.58916838, 6.52153874, 2.32979897, 7.74580205, 1.34613497, 1.65559971, 6.12682283, 2.38783406, 7.04778548, 3.49518527, 2.77423960, 9.98918406, 4.06161246e-01, 6.45822522, 3.86995850e-01, 7.60210258, 2.30089957, 8.98318671e-01, 6.48449712, 7.32601217, 6.78095315, 5.19009471e-01, 2.94306946, 4.51088346, 2.87103290, 8.10513456, 1.31115105, 6.12179362, 9.88214944, 9.02556539, 2.22157062, 8.18876137e-04, 9.80597342, 8.82712985, 9.19472466, 4.15503551, 7.44615462]) y = np.ones_like(t) dy = np.array([ 0.00606416, 0.00696152, 0.00925774, 0.00563806, 0.00946933, 0.00748254, 0.00713048, 0.00652823, 0.00958424, 0.00758812, 0.00902013, 0.00928826, 0.00961191, 0.0065169, 0.00669905, 0.00797537, 0.00720662, 0.00966421, 0.00698782, 0.00738889, 0.00808593, 0.0070237, 0.00996239, 0.00549426, 0.00610302, 0.00661328, 0.00573861, 0.0064211, 0.00889623, 0.00761446, 0.00516977, 0.00991311, 0.00808003, 0.0052947, 0.00830584, 0.00689185, 0.00567837, 0.00781832, 0.0086354, 0.00835563, 0.00623757, 0.00762433, 0.00768832, 0.00858402, 0.00679934, 0.00898866, 0.00813961, 0.00519166, 0.0077324, 0.00930956, 0.00783787, 0.00587914, 0.00755188, 0.00878473, 0.00555053, 0.0090855, 0.00583741, 0.00767038, 0.00692872, 0.00624312, 0.00823716, 0.00518696, 0.00880023, 0.0076347, 0.00937886, 0.00760359, 0.00517517, 0.005718, 0.00897802, 0.00745988, 0.0072094, 0.00659217, 0.00642275, 0.00982943, 0.00716485, 0.00942002, 0.00824082, 0.00929214, 0.00926225, 0.00978156, 0.00848971, 0.00902698, 0.00866564, 0.00802613, 0.00858677, 0.00857875, 0.00520454, 0.00758055, 0.00896326, 0.00621481, 0.00732574, 0.00717493, 0.00701394, 0.0056092, 0.00762856, 0.00723124, 0.00831696, 0.00774707, 0.00513771, 0.00515959, 0.0085068, 0.00853791, 0.0097997, 0.00938352, 0.0073403, 0.00812953, 0.00728591, 0.00611473, 0.00688338, 0.00551942, 0.00833264, 0.00596015, 0.00737734, 0.00983718, 0.00515834, 0.00575865, 0.0064929, 0.00970903, 0.00954421, 0.00581, 0.00990559, 0.00875374, 0.00769989, 0.00965851, 0.00940304, 0.00695658, 0.00828172, 0.00823693, 0.00663484, 0.00589695, 0.00733405, 0.00631641, 0.00677533, 0.00977072, 0.00730569, 0.00842446, 0.00668115, 0.00997931, 0.00829384, 0.00598005, 0.00549092, 0.0097159, 0.00972389, 0.00810664, 0.00508496, 0.00612767, 0.00900638, 0.0093773, 0.00726995, 0.0068276, 0.00637113, 0.00558485, 0.00557872, 0.00976301, 0.00904313, 0.0058239, 0.00603525, 0.00827776, 0.00882332, 0.00905157, 0.00581669, 0.00992064, 0.00613901, 0.00794708, 0.00793808, 0.00983681, 0.00828834, 0.00792452, 0.00759386, 0.00882329, 0.00553028, 0.00501046, 0.00976244, 0.00749329, 0.00664168, 0.00684027, 0.00901922, 0.00691185, 0.00885085, 0.00720231, 0.00922039, 0.00538102, 0.00740564, 0.00733425, 0.00632164, 0.00971807, 0.00952514, 0.00721798, 0.0054858, 0.00603392, 0.00635746, 0.0074211, 0.00669189, 0.00887068, 0.00738013, 0.00935185, 0.00997891, 0.00609918, 0.00805836, 0.00923751, 0.00972618, 0.00645043, 0.00863521, 0.00507508, 0.00939571, 0.00531969, 0.00866698, 0.00997305, 0.00750595, 0.00604667, 0.00797322, 0.00812075, 0.00834036, 0.00586306, 0.00949356, 0.00810496, 0.00521784, 0.00842021, 0.00598042, 0.0051367, 0.00775477, 0.00906657, 0.00929971, 0.0055176, 0.00831521, 0.00855038, 0.00647258, 0.00985682, 0.00639344, 0.00534991, 0.0075964, 0.00847157, 0.0062233, 0.00669291, 0.00781814, 0.00943339, 0.00873663, 0.00604796, 0.00625889, 0.0076194, 0.00884479, 0.00809381, 0.00750662, 0.00798563, 0.0087803, 0.0076854, 0.00948876, 0.00973534, 0.00957677, 0.00877259, 0.00623161, 0.00692636, 0.0064, 0.0082883, 0.00662111, 0.00877196, 0.00556755, 0.00887682, 0.00792951, 0.00917694, 0.00715438, 0.00812482, 0.00777206, 0.00987836, 0.00877737, 0.00772407, 0.00587016, 0.00952057, 0.00602919, 0.00825022, 0.00968236, 0.0061179, 0.00612962, 0.00925909, 0.00913828, 0.00675852, 0.00632548, 0.00563694, 0.00993968, 0.00917672, 0.00949696, 0.0075684, 0.00557192, 0.0052629, 0.00665291, 0.00960165, 0.00973791, 0.00920582, 0.0057934, 0.00709962, 0.00623121, 0.00602675, 0.00842413, 0.00743056, 0.00662455, 0.00550107, 0.00772382, 0.00673513, 0.00695548, 0.00655254, 0.00693598, 0.0077793, 0.00507072, 0.00923823, 0.0096096, 0.00775265, 0.00634011, 0.0099512, 0.00691597, 0.00846828, 0.00844976, 0.00717155, 0.00599579, 0.0098329, 0.00531845, 0.00742575, 0.00610365, 0.00646987, 0.00914264, 0.00683633, 0.00541674, 0.00598155, 0.00930187, 0.00988514, 0.00633991, 0.00837704, 0.00540599, 0.00861733, 0.00708218, 0.0095908, 0.00655768, 0.00970733, 0.00751624, 0.00674446, 0.0082351, 0.00624873, 0.00614882, 0.00598173, 0.0097995, 0.00746457, 0.00875807, 0.00736996, 0.0079377, 0.00792069, 0.00989943, 0.00834217, 0.00619885, 0.00507599, 0.00609341, 0.0072776, 0.0069671, 0.00906163, 0.00892778, 0.00544548, 0.00976005, 0.00763728, 0.00798202, 0.00702528, 0.0082475, 0.00935663, 0.00836968, 0.00985049, 0.00850561, 0.0091086, 0.0052252, 0.00836349, 0.00827376, 0.00550873, 0.00921194, 0.00807086, 0.00549164, 0.00797234, 0.00739208, 0.00616647, 0.00509878, 0.00682784, 0.00809926, 0.0066464, 0.00653627, 0.00875561, 0.00879312, 0.00859383, 0.00550591, 0.00758083, 0.00778899, 0.00872402, 0.00951589, 0.00684519, 0.00714332, 0.00866384, 0.00831318, 0.00778935, 0.0067507, 0.00597676, 0.00591904, 0.00540792, 0.005406, 0.00922899, 0.00691836, 0.0053037, 0.00948213, 0.00611635, 0.00634062, 0.00597249, 0.00983751, 0.0055627, 0.00861082, 0.00966044, 0.00834001, 0.00929363, 0.00621224, 0.00836964, 0.00850436, 0.00729166, 0.00935273, 0.00847193, 0.00947439, 0.00876602, 0.00760145, 0.00749344, 0.00726864, 0.00510823, 0.00767571, 0.00711487, 0.00578767, 0.00559535, 0.00724676, 0.00519957, 0.0099329, 0.0068906, 0.00691055, 0.00525563, 0.00713336, 0.00507873, 0.00515047, 0.0066955, 0.00910484, 0.00729411, 0.0050742, 0.0058161, 0.00869961, 0.00869147, 0.00877261, 0.00675835, 0.00676138, 0.00901038, 0.00699069, 0.00863596, 0.00790562, 0.00682171, 0.00540003, 0.00558063, 0.00944779, 0.0072617, 0.00997002, 0.00681948, 0.00624977, 0.0067527, 0.00671543, 0.00818678, 0.00506369, 0.00881634, 0.00708207, 0.0071612, 0.00740558, 0.00724606, 0.00748735, 0.00672952, 0.00726673, 0.00702326, 0.00759121, 0.00811635, 0.0062052, 0.00754219, 0.00797311, 0.00508474, 0.00760247, 0.00619647, 0.00702269, 0.00913265, 0.00663118, 0.00741608, 0.00512371, 0.00654375, 0.00819861, 0.00657581, 0.00602899, 0.00645328, 0.00977189, 0.00543401, 0.00731679, 0.00529193, 0.00769329, 0.00573018, 0.00817042, 0.00632199, 0.00845458, 0.00673573, 0.00502084, 0.00647447]) period = 2.0 transit_time = 0.5 duration = 0.16 depth = 0.2 m = np.abs((t-transit_time+0.5*period) % period-0.5*period) < 0.5*duration y[m] = 1.0 - depth randn_arr = np.array([ -1.00326528e-02, -8.45644428e-01, 9.11460610e-01, -1.37449688e+00, -5.47065645e-01, -7.55266106e-05, -1.21166803e-01, -2.00858547e+00, -9.20646543e-01, 1.68234342e-01, -1.31989156e+00, 1.26642930e+00, 4.95180889e-01, -5.14240391e-01, -2.20292465e-01, 1.86156412e+00, 9.35988451e-01, 3.80219145e-01, -1.41551877e+00, 1.62961132e+00, 1.05240107e+00, -1.48405388e-01, -5.49698069e-01, -1.87903939e-01, -1.20193668e+00, -4.70785558e-01, 7.63160514e-01, -1.80762128e+00, -3.14074374e-01, 1.13755973e-01, 1.03568037e-01, -1.17893695e+00, -1.18215289e+00, 1.08916538e+00, -1.22452909e+00, 1.00865096e+00, -4.82365315e-01, 1.07979635e+00, -4.21078505e-01, -1.16647132e+00, 8.56554856e-01, -1.73912222e-02, 1.44857659e+00, 8.92200085e-01, -2.29426629e-01, -4.49667602e-01, 2.33723433e-02, 1.90210018e-01, -8.81748527e-01, 8.41939573e-01, -3.97363492e-01, -4.23027745e-01, -5.40688337e-01, 2.31017267e-01, -6.92052602e-01, 1.34970110e-01, 2.76660307e+00, -5.36094601e-02, -4.34004738e-01, -1.66768923e+00, 5.02219248e-02, -1.10923094e+00, -3.75558119e-01, 1.51607594e-01, -1.73098945e+00, 1.57462752e-01, 3.04515175e-01, -1.29710002e+00, -3.92309192e-01, -1.83066636e+00, 1.57550094e+00, 3.30563277e-01, -1.79588501e-01, -1.63435831e-01, 1.13144361e+00, -9.41655519e-02, 3.30816771e-01, 1.51862956e+00, -3.46167148e-01, -1.09263532e+00, -8.24500575e-01, 1.42866383e+00, 9.14283085e-02, -5.02331288e-01, 9.73644380e-01, 9.97957386e-01, -4.75647768e-01, -9.71936837e-01, -1.57052860e+00, -1.79388892e+00, -2.64986452e-01, -8.93195947e-01, 1.85847441e+00, 5.85377547e-02, -1.94214954e+00, 1.41872928e+00, 1.61710309e-01, 7.04979480e-01, 6.82034777e-01, 2.96556567e-01, 5.23342630e-01, 2.38760672e-01, -1.10638591e+00, 3.66732198e-01, 1.02390550e+00, -2.10056413e-01, 5.51302218e-01, 4.19589145e-01, 1.81565206e+00, -2.52750301e-01, -2.92004163e-01, -1.16931740e-01, -1.02391075e-01, -2.27261771e+00, -6.42609841e-01, 2.99885067e-01, -8.25651467e-03, -7.99339154e-01, -6.64779252e-01, -3.55613128e-01, -8.01571781e-01, -5.13050610e-01, -5.39390119e-01, 8.95370847e-01, 1.01639127e+00, 9.33585094e-01, 4.26701799e-01, -7.08322484e-01, 9.59830450e-01, -3.14250587e-01, 2.30522083e-02, 1.33822053e+00, 8.39928561e-02, 2.47284030e-01, -1.41277949e+00, 4.87009294e-01, -9.80006647e-01, 1.01193966e+00, -1.84599177e-01, -2.23616884e+00, -3.58020103e-01, -2.28034538e-01, 4.85475226e-01, 6.70512391e-01, -3.27764245e-01, 1.01286819e+00, -3.16705533e+00, -7.13988998e-01, -1.11236427e+00, -1.25418351e+00, 9.59706371e-01, 8.29170399e-01, -7.75770020e-01, 1.17805700e+00, 1.01466892e-01, -4.21684101e-01, -6.92922796e-01, -7.78271726e-01, 4.72774857e-01, 6.50154901e-01, 2.38501212e-01, -2.05021768e+00, 2.96358656e-01, 5.65396564e-01, -6.69205605e-01, 4.32505429e-02, -1.86388430e+00, -1.22996906e+00, -3.24235348e-01, -3.09751144e-01, 3.51679372e-01, -1.18692539e+00, -3.41206065e-01, -4.89779780e-01, 5.28010474e-01, 1.42104277e+00, 1.72092032e+00, -1.56844005e+00, -4.80141918e-02, -1.11252931e+00, -6.47449515e-02, 4.22919280e-01, 8.14908987e-02, -4.90116988e-02, 1.48303917e+00, 7.20989392e-01, -2.72654462e-01, 2.42113609e-02, 8.70897807e-01, 6.09790506e-01, -4.25076104e-01, -1.77524284e+00, -1.18465749e+00, 1.45979225e-01, -1.78652685e+00, -1.52394498e-01, -4.53569176e-01, 9.99252803e-01, -1.31804382e+00, -1.93176898e+00, -4.19640742e-01, 6.34763132e-01, 1.06991860e+00, -9.09327017e-01, 4.70263748e-01, -1.11143045e+00, -7.48827466e-01, 5.67594726e-01, 7.18150543e-01, -9.99380749e-01, 4.74898323e-01, -1.86849981e+00, -2.02658907e-01, -1.13424803e+00, -8.07699340e-01, -1.27607735e+00, 5.53626395e-01, 5.53874470e-01, -6.91200445e-01, 3.75582306e-01, 2.61272553e-01, -1.28451754e-01, 2.15817020e+00, -8.40878617e-01, 1.43050907e-02, -3.82387029e-01, -3.71780015e-01, 1.59412004e-01, -2.94395700e-01, -8.60426760e-01, 1.24227498e-01, 1.18233165e+00, 9.42766380e-01, 2.03044488e-01, -7.35396814e-01, 1.86429600e-01, 1.08464302e+00, 1.19118926e+00, 3.59687060e-01, -3.64357200e-01, -2.02752749e-01, 7.72045927e-01, 6.86346215e-01, -1.75769961e+00, 6.58617565e-01, 7.11288340e-01, -8.87191425e-01, -7.64981116e-01, -7.57164098e-01, -6.80262803e-01, -1.41674959e+00, 3.13091930e-01, -7.85719399e-01, -7.03838361e-02, -4.97568783e-01, 2.55177521e-01, -1.01061704e+00, 2.45265375e-01, 3.89781016e-01, 8.27594585e-01, 1.96776909e+00, -2.09210177e+00, 3.20314334e-01, -7.09162842e-01, -1.92505867e+00, 8.41630623e-01, 1.33219988e+00, -3.91627710e-01, 2.10916296e-01, -6.40767402e-02, 4.34197668e-01, 8.80535749e-01, 3.44937336e-01, 3.45769929e-01, 1.25973654e+00, -1.64662222e-01, 9.23064571e-01, -8.22000422e-01, 1.60708495e+00, 7.37825392e-01, -4.03759534e-01, -2.11454815e+00, -3.10717131e-04, -1.18180941e+00, 2.99634603e-01, 1.45116882e+00, 1.60059793e-01, -1.78012614e-01, 3.42205404e-01, 2.85650196e-01, -2.36286411e+00, 2.40936864e-01, 6.20277356e-01, -2.59341634e-01, 9.78559078e-01, -1.27674575e-01, 7.66998762e-01, 2.27310511e+00, -9.63911290e-02, -1.94213217e+00, -3.36591724e-01, -1.72589000e+00, 6.11237826e-01, 1.30935097e+00, 6.95879662e-01, 3.20308213e-01, -6.44925458e-01, 1.57564975e+00, 7.53276212e-01, 2.84469557e-01, 2.04860319e-01, 1.11627359e-01, 4.52216424e-01, -6.13327179e-01, 1.52524993e+00, 1.52339753e-01, 6.00054450e-01, -4.33567278e-01, 3.74918534e-01, -2.28175243e+00, -1.11829888e+00, -3.14131532e-02, -1.32247311e+00, 2.43941406e+00, -1.66808131e+00, 3.45900749e-01, 1.65577315e+00, 4.81287059e-01, -3.10227553e-01, -5.52144084e-01, 6.73255489e-01, -8.00270681e-01, -1.19486110e-01, 6.91198606e-01, -3.07879027e-01, 8.75100102e-02, -3.04086293e-01, -9.69797604e-01, 1.18915048e+00, 1.39306624e+00, -3.16699954e-01, -2.65576159e-01, -1.77899339e-01, 5.38803274e-01, -9.05300265e-01, -8.85253056e-02, 2.62959055e-01, 6.42042149e-01, -2.78083727e+00, 4.03403210e-01, 3.45846762e-01, 1.00772824e+00, -5.26264015e-01, -5.18353205e-01, 1.20251659e+00, -1.56315671e+00, 1.62909029e+00, 2.55589446e+00, 4.77451685e-01, 8.14098474e-01, -1.48958171e+00, -6.94559787e-01, 1.05786255e+00, 3.61815347e-01, -1.81427463e-01, 2.32869132e-01, 5.06976484e-01, -2.93095701e-01, -2.89459450e-02, -3.63073748e-02, -1.05227898e+00, 3.23594628e-01, 1.80358591e+00, 1.73196213e+00, -1.47639930e+00, 5.70631220e-01, 6.75503781e-01, -4.10510463e-01, -9.64200035e-01, -1.32081431e+00, -4.44703779e-01, 3.50009137e-01, -1.58058176e-01, -6.10933088e-01, -1.24915663e+00, 3.50716258e-01, 1.06654245e+00, -9.26921972e-01, 4.48428964e-01, -1.87947524e+00, -6.57466109e-01, 7.29604120e-01, -1.11776721e+00, -6.04436725e-01, 1.41796683e+00, -7.32843980e-01, -8.53944819e-01, 5.75848362e-01, 1.95473356e+00, -2.39669947e-01, 7.68735860e-01, 1.34576918e+00, 3.25552163e-01, -2.69917901e-01, -8.76326739e-01, -1.42521096e+00, 1.11170175e+00, 1.80957146e-01, 1.33280094e+00, 9.88925316e-01, -6.16970520e-01, -1.18688670e+00, 4.12669583e-01, -6.32506884e-01, 3.76689141e-01, -7.31151938e-01, -8.61225253e-01, -1.40990810e-01, 9.34100620e-01, 3.06539895e-01, 1.17837515e+00, -1.23356170e+00, -1.05707714e+00, -8.91636992e-02, 2.16570138e+00, 6.74286114e-01, -1.06661274e+00, -7.61404530e-02, 2.20714791e-01, -5.68685746e-01, 6.13274991e-01, -1.56446138e-01, -2.99330718e-01, 1.26025679e+00, -1.70966090e+00, -9.61805342e-01, -8.17308981e-01, -8.47681070e-01, -7.28753045e-01, 4.88475958e-01, 1.09653283e+00, 9.16041261e-01, -1.01956213e+00, -1.07417899e-01, 4.52265213e-01, 2.40002952e-01, 1.30574740e+00, -6.75334236e-01, 1.56319421e-01, -3.93230715e-01, 2.51075019e-01, -1.07889691e+00, -9.28937721e-01, -7.30110860e-01, -5.63669311e-01, 1.54792327e+00, 1.17540191e+00, -2.12649671e-01, 1.72933294e-01, -1.59443602e+00, -1.79292347e-01, 1.59614713e-01, 1.14568421e+00, 3.26804720e-01, 4.32890059e-01, 2.97762890e-01, 2.69001190e-01, -1.39675918e+00, -4.16757668e-01, 1.43488680e+00, 8.23896443e-01, 4.94234499e-01, 6.67153092e-02, 6.59441396e-01, -9.44889409e-01, -1.58005956e+00, -3.82086552e-01, 5.37923058e-01, 1.07829882e-01, 1.01395868e+00, 3.51450517e-01, 4.48421962e-02, 1.32748495e+00, 1.13237578e+00, -9.80913012e-02, -1.10304986e+00, -9.07361492e-01, -1.61451138e-01, -3.66811384e-01, 1.65776233e+00, -1.68013415e+00, -6.42577869e-02, -1.06622649e+00, 1.16801869e-01, 3.82264833e-01, -4.04896974e-01, 5.30481414e-01, -1.98626941e-01, -1.79395613e-01, -4.17888725e-01]) y += dy * randn_arr return t, y, dy, dict(period=period, transit_time=transit_time, duration=duration, depth=depth) 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) @pytest.mark.parametrize("objective", ["likelihood", "snr"]) 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 @pytest.mark.parametrize("objective", ["likelihood", "snr"]) @pytest.mark.parametrize("offset", [False, True]) 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_input_units(data): t, y, dy, params = data t_unit = u.day y_unit = u.mag with pytest.raises(u.UnitConversionError): BoxLeastSquares(t * t_unit, y * y_unit, dy * u.one) with pytest.raises(u.UnitConversionError): BoxLeastSquares(t * t_unit, y * u.one, dy * y_unit) with pytest.raises(u.UnitConversionError): BoxLeastSquares(t * t_unit, y, dy * y_unit) model = BoxLeastSquares(t*t_unit, y * u.one, dy) assert model.dy.unit == model.y.unit model = BoxLeastSquares(t*t_unit, y * y_unit, dy) assert model.dy.unit == model.y.unit model = BoxLeastSquares(t*t_unit, y*y_unit) assert model.dy is None def test_period_units(data): t, y, dy, params = data t_unit = u.day y_unit = u.mag model = BoxLeastSquares(t * t_unit, y * y_unit, dy) p = model.autoperiod(params["duration"]) assert p.unit == t_unit p = model.autoperiod(params["duration"] * 24 * u.hour) assert p.unit == t_unit with pytest.raises(u.UnitConversionError): model.autoperiod(params["duration"] * u.mag) p = model.autoperiod(params["duration"], minimum_period=0.5) assert p.unit == t_unit with pytest.raises(u.UnitConversionError): p = model.autoperiod(params["duration"], minimum_period=0.5*u.mag) p = model.autoperiod(params["duration"], maximum_period=0.5) assert p.unit == t_unit with pytest.raises(u.UnitConversionError): p = model.autoperiod(params["duration"], maximum_period=0.5*u.mag) p = model.autoperiod(params["duration"], minimum_period=0.5, maximum_period=1.5) p2 = model.autoperiod(params["duration"], maximum_period=0.5, minimum_period=1.5) assert_quantity_allclose(p, p2) @pytest.mark.parametrize("method", ["fast", "slow"]) @pytest.mark.parametrize("with_err", [True, False]) @pytest.mark.parametrize("t_unit", [None, u.day]) @pytest.mark.parametrize("y_unit", [None, u.mag]) @pytest.mark.parametrize("objective", ["likelihood", "snr"]) 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 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) @pytest.mark.parametrize("with_units", [True, False]) def test_model(data, with_units): t, y, dy, params = data # Compute the model using linear regression A = np.zeros((len(t), 2)) p = params["period"] dt = np.abs((t-params["transit_time"]+0.5*p) % p-0.5*p) m_in = dt < 0.5*params["duration"] A[~m_in, 0] = 1.0 A[m_in, 1] = 1.0 w = np.linalg.solve(np.dot(A.T, A / dy[:, None]**2), np.dot(A.T, y / dy**2)) model_true = np.dot(A, w) if with_units: t = t * u.day y = y * u.mag dy = dy * u.mag model_true = model_true * u.mag # Compute the model using the periodogram pgram = BoxLeastSquares(t, y, dy) model = pgram.model(t, p, params["duration"], params["transit_time"]) # Make sure that the transit mask is consistent with the model transit_mask = pgram.transit_mask(t, p, params["duration"], params["transit_time"]) transit_mask0 = (model - model.max()) < 0.0 assert_allclose(transit_mask, transit_mask0) assert_quantity_allclose(model, model_true) @pytest.mark.parametrize("shape", [(1,), (2,), (3,), (2, 3)]) 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 @pytest.mark.parametrize("with_units", [True, False]) @pytest.mark.parametrize("with_err", [True, False]) 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_negative_times(data): t, y, dy, params = data mu = np.mean(t) duration = params["duration"] + np.linspace(-0.1, 0.1, 3) model1 = BoxLeastSquares(t, y, dy) results1 = model1.autopower(duration) # Compute the periodogram with offset (negative) times model2 = BoxLeastSquares(t - mu, y, dy) results2 = model2.autopower(duration) # Shift the transit times back into the unshifted coordinates results2.transit_time = (results2.transit_time + mu) % results2.period assert_allclose_blsresults(results1, results2) @pytest.mark.parametrize('timedelta', [False, True]) 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 # 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) # noqa: E501 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.') def test_transit_time_in_range(data): t, y, dy, params = data t_ref = 10230.0 t2 = t + t_ref bls1 = BoxLeastSquares(t, y, dy) bls2 = BoxLeastSquares(t2, y, dy) results1 = bls1.autopower(0.16) results2 = bls2.autopower(0.16) assert np.allclose(results1.transit_time, results2.transit_time - t_ref) assert np.all(results1.transit_time >= t.min()) assert np.all(results1.transit_time <= t.max()) assert np.all(results2.transit_time >= t2.min()) assert np.all(results2.transit_time <= t2.max())