def test_IERS_B_builtin_agree_with_IERS_Auto_dX(): A = IERS_Auto.open() B = IERS_B.open(IERS_B_FILE) mjd = B["MJD"].to(u.day).value A.pm_xy(mjd) # ensure that data is available for these dates # We're going to look up the OK auto values in the B table ok_A = A["MJD"] < B["MJD"][-1] # Let's get rid of some trouble values and see if they agree on a restricted subset # IERS Auto ends with a bunch of 1e20 values meant as sentinels (?) ok_A &= abs(A["dX_2000A_B"]) < 1e6 * u.marcsec # For some reason IERS B starts with zeros up to MJD 45700? IERS Auto doesn't match this ok_A &= A["MJD"] > 45700 * u.d # Maybe the old values are bogus? ok_A &= A["MJD"] > 50000 * u.d mjds_A = A["MJD"][ok_A].to(u.day).value i_B = np.searchsorted(B["MJD"].to(u.day).value, mjds_A) assert np.all(np.diff(i_B) == 1), "Valid region not contiguous" assert_equal(A["MJD"][ok_A], B["MJD"][i_B], "MJDs don't make sense") assert_allclose( A["dX_2000A_B"][ok_A].to(u.marcsec).value, B["dX_2000A"][i_B].to(u.marcsec).value, atol=1e-5, rtol=1e-3, err_msg= "IERS B values included in IERS A (dX_2000A) don't match IERS_B_FILE values", )
def get_iers_b_up_to_date(mjd): """Update the IERS B table to include MJD if necessary """ if Time.now().mjd <= mjd: raise ValueError("IERS B data requested for future MJD {}".format(mjd)) might_be_old = is_url_in_cache(IERS_B_URL) iers_b = IERS_B.open(download_file(IERS_B_URL, cache=True)) if might_be_old and iers_b[-1]["MJD"].to_value(u.d) < mjd: # Try wiping the download and re-downloading clear_download_cache(IERS_B_URL) iers_b = IERS_B.open(download_file(IERS_B_URL, cache=True)) if iers_b[-1]["MJD"].to_value(u.d) < mjd: raise ValueError( "IERS B data not yet available for MJD {}".format(mjd)) return iers_b
def test_IERS_B_agree_with_IERS_Auto(): A = IERS_Auto.open() B = IERS_B.open(download_file(IERS_B_URL, cache=True)) mjd = B["MJD"].to(u.day).value A.pm_xy(mjd) # ensure that data is available for this date # Let's get rid of some trouble values and see if they agree on a restricted subset # IERS Auto ends with a bunch of 1e20 values meant as sentinels (?) ok_A = abs(A["PM_X_B"]) < 1e6 * u.marcsec # Maybe the old values are bogus? ok_A &= A["MJD"] > 50000 * u.d mjds_A = A["MJD"][ok_A].to(u.day).value i_B = np.searchsorted(B["MJD"].to(u.day).value, mjds_A) assert np.all(np.diff(i_B) == 1), "Valid region not contiguous" assert_equal(A["MJD"][ok_A], B["MJD"][i_B], "MJDs don't make sense") for atag, btag, unit in [ ("UT1_UTC_B", "UT1_UTC", u.s), # s, six decimal places ("PM_X_B", "PM_x", u.arcsec), ("PM_Y_B", "PM_y", u.arcsec), ]: assert_allclose( A[atag][ok_A].to(unit).value, B[btag][i_B].to(unit).value, atol=1e-5, rtol=1e-5, # should be "close enough" err_msg="Inserted IERS B {} values don't match IERS_B_URL {} values" .format(atag, btag), )
def test_IERS_B_agree_with_IERS_Auto_dX(): A = IERS_Auto.open() B = IERS_B.open(download_file(IERS_B_URL, cache=True)) mjd = B["MJD"].to(u.day).value A.pm_xy(mjd) # ensure that data is available for this date # Let's get rid of some trouble values and see if they agree on a restricted subset # IERS Auto ends with a bunch of 1e20 values meant as sentinels (?) ok_A = abs(A["dX_2000A_B"]) < 1e6 * u.marcsec # For some reason IERS B starts with zeros up to MJD 45700? IERS Auto doesn't match this # ok_A &= A['MJD'] > 45700*u.d # Maybe the old values are bogus? ok_A &= A["MJD"] > 50000 * u.d mjds_A = A["MJD"][ok_A].to(u.day).value i_B = np.searchsorted(B["MJD"].to(u.day).value, mjds_A) assert np.all(np.diff(i_B) == 1), "Valid region not contiguous" assert_equal(A["MJD"][ok_A], B["MJD"][i_B], "MJDs don't make sense") for tag in ["dX_2000A", "dY_2000A"]: assert_allclose( A[tag + "_B"][ok_A].to(u.marcsec).value, B[tag][i_B].to(u.marcsec).value, atol=1e-5, rtol=1e-3, err_msg= "IERS A-derived IERS B {} values don't match current IERS B values" .format(tag), )
def test_IERS_B_all_in_IERS_Auto(): B = IERS_B.open(download_file(IERS_B_URL, cache=True)) mjd = B["MJD"].to(u.day).value A = IERS_Auto.open() A.pm_xy(mjd) # ensure that data is available for this date i_A = np.searchsorted(A["MJD"].to(u.day).value, mjd) assert_equal(A["dX_2000A_B"][i_A], B["dX_2000A"])
def test_IERS_B_builtin_agree_with_IERS_Auto(): """The UT1-UTC, PM_X, and PM_Y values are correctly copied""" A = IERS_Auto.open() B = IERS_B.open(IERS_B_FILE) mjd = B["MJD"].to(u.day).value A.pm_xy(mjd) # ensure that data is available for these dates # We're going to look up the OK auto values in the B table ok_A = A["MJD"] < B["MJD"][-1] # Let's get rid of some trouble values and see if they agree on a restricted subset # IERS Auto ends with a bunch of 1e20 values meant as sentinels (?) ok_A &= abs(A["PM_X_B"]) < 1e6 * u.marcsec # For some reason IERS B starts with zeros up to MJD 45700? IERS Auto doesn't match this ok_A &= A["MJD"] > 45700 * u.d # Maybe the old values are bogus? ok_A &= A["MJD"] > 50000 * u.d mjds_A = A["MJD"][ok_A].to(u.day).value i_B = np.searchsorted(B["MJD"].to(u.day).value, mjds_A) assert np.all(np.diff(i_B) == 1), "Valid region not contiguous" assert_equal(A["MJD"][ok_A], B["MJD"][i_B], "MJDs don't make sense") for atag, btag, unit in [ ("UT1_UTC_B", "UT1_UTC", u.s), ("PM_X_B", "PM_x", u.arcsec), ("PM_Y_B", "PM_y", u.arcsec), ]: assert_allclose( A[atag][ok_A].to(unit).value, B[btag][i_B].to(unit).value, atol=1e-5, rtol=1e-5, # should be exactly equal err_msg="Inserted IERS B {} values don't match IERS_B_FILE {} values" .format(atag, btag), )
def test_iers_discrepancies(): iers_auto = IERS_Auto.open() iers_b = IERS_B.open() for mjd in [56000, 56500, 57000]: t = Time(mjd, scale="tdb", format="mjd") b_x, b_y = iers_b.pm_xy(t) a_x, a_y = iers_auto.pm_xy(t) assert abs(a_x - b_x) < 1 * u.marcsec assert abs(a_y - b_y) < 1 * u.marcsec
def test_IERS_B_parameters_loaded_into_IERS_Auto(b_name, a_name): A = IERS_Auto.open() A[a_name] B = IERS_B.open(IERS_B_FILE) ok_A = A["MJD"] < B["MJD"][-1] mjds_A = A["MJD"][ok_A].to(u.day).value i_B = np.searchsorted(B["MJD"].to(u.day).value, mjds_A) assert_equal(np.diff(i_B), 1, err_msg="Valid region not contiguous") assert_equal(A["MJD"][ok_A], B["MJD"][i_B], err_msg="MJDs don't make sense") assert_equal( A[a_name][ok_A], B[b_name][i_B], err_msg="IERS B parameter {} not copied over IERS A parameter {}".format( b_name, a_name ), )
import numpy as np import astropy.units as u try: import astropy.erfa as erfa except ImportError: import astropy._erfa as erfa import astropy.table as table from astropy.time import Time SECS_PER_DAY = erfa.DAYSEC from astropy.utils.iers import IERS_A, IERS_A_URL, IERS_B, IERS_B_URL, IERS from astropy.utils.data import download_file # iers_a_file = download_file(IERS_A_URL, cache=True) iers_b_file = download_file(IERS_B_URL, cache=True) # iers_a = IERS_A.open(iers_a_file) iers_b = IERS_B.open(iers_b_file) IERS.iers_table = iers_b iers_tab = IERS.iers_table # Earth rotation rate in radians per UT1 second # # This is from Capitaine, Guinot, McCarthy, 2000 and is # in IAU Resolution B1.8 on the Earth Rotation Angle (ERA) # and the relation of it to UT1. The number 1.00273781191135448 # below is a defining constant. See here: # http://iau-c31.nict.go.jp/pdf/2009_IAUGA_JD6/JD06_capitaine_wallace.pdf OM = 1.00273781191135448 * 2.0 * np.pi / SECS_PER_DAY # arcsec to radians asec2rad = 4.84813681109536e-06
def test_astropy_IERS_B_vs_downloaded(): P = IERS_B.open(IERS_B_FILE) B = IERS_B.open(download_file(IERS_B_URL, cache=True)) assert B["MJD"][-1] > P["MJD"][-1]
import numpy as np import astropy.units as u try: import astropy.erfa as erfa except ImportError: import astropy._erfa as erfa import astropy.table as table from astropy.time import Time SECS_PER_DAY = erfa.DAYSEC from astropy.utils.iers import IERS_A, IERS_A_URL, IERS_B, IERS_B_URL, IERS from astropy.utils.data import download_file # iers_a_file = download_file(IERS_A_URL, cache=True) iers_b_file = download_file(IERS_B_URL, cache=True) # iers_a = IERS_A.open(iers_a_file) iers_b = IERS_B.open(iers_b_file) IERS.iers_table = iers_b iers_tab = IERS.iers_table # Earth rotation rate in radians per UT1 second # # This is from Capitaine, Guinot, McCarthy, 2000 and is # in IAU Resolution B1.8 on the Earth Rotation Angle (ERA) # and the relation of it to UT1. The number 1.00273781191135448 # below is a defining constant. See here: # http://iau-c31.nict.go.jp/pdf/2009_IAUGA_JD6/JD06_capitaine_wallace.pdf OM = 1.00273781191135448 * 2.0 * np.pi / SECS_PER_DAY # arcsec to radians asec2rad = 4.84813681109536e-06