Esempio n. 1
0
def test_errwarn_reporting():
    """
    Test that the ERFA error reporting mechanism works as it should
    """

    # no warning
    erfa.dat(1990, 1, 1, 0.5)

    # check warning is raised for a scalar
    with catch_warnings() as w:
        erfa.dat(100, 1, 1, 0.5)
        assert len(w) == 1
        assert w[0].category == erfa.ErfaWarning
        assert '1 of "dubious year (Note 1)"' in str(w[0].message)

    # and that the count is right for a vector.
    with catch_warnings() as w:
        erfa.dat([100, 200, 1990], 1, 1, 0.5)
        assert len(w) == 1
        assert w[0].category == erfa.ErfaWarning
        assert '2 of "dubious year (Note 1)"' in str(w[0].message)

    try:
        erfa.dat(1990, [1, 34, 2], [1, 1, 43], 0.5)
    except erfa.ErfaError as e:
        if '1 of "bad day (Note 3)", 1 of "bad month"' not in e.args[0]:
            assert False, 'Raised the correct type of error, but wrong message: ' + e.args[
                0]

    try:
        erfa.dat(200, [1, 34, 2], [1, 1, 43], 0.5)
    except erfa.ErfaError as e:
        if 'warning' in e.args[0]:
            assert False, 'Raised the correct type of error, but there were warnings mixed in: ' + e.args[
                0]
Esempio n. 2
0
    def test_update_leap_seconds(self):
        assert erfa.dat(2018, 1, 1, 0.) == 37.0
        leap_seconds = erfa.leap_seconds.get()
        # Get old and new leap seconds
        old_leap_seconds = leap_seconds[leap_seconds['year'] < 2017]
        new_leap_seconds = leap_seconds[leap_seconds['year'] >= 2017]
        # Updating with either of these should do nothing.
        n_update = erfa.leap_seconds.update(new_leap_seconds)
        assert n_update == 0
        assert_array_equal(erfa.leap_seconds.get(), self.erfa_ls)
        n_update = erfa.leap_seconds.update(old_leap_seconds)
        assert n_update == 0
        assert_array_equal(erfa.leap_seconds.get(), self.erfa_ls)

        # But after setting to older part, update with newer should work.
        erfa.leap_seconds.set(old_leap_seconds)
        # Check the 2017 leap second is indeed missing.
        assert erfa.dat(2018, 1, 1, 0.) == 36.0
        # Update with missing leap seconds.
        n_update = erfa.leap_seconds.update(new_leap_seconds)
        assert n_update == len(new_leap_seconds)
        assert erfa.dat(2018, 1, 1, 0.) == 37.0

        # Also a final try with overlapping data.
        erfa.leap_seconds.set(old_leap_seconds)
        n_update = erfa.leap_seconds.update(leap_seconds)
        assert n_update == len(new_leap_seconds)
        assert erfa.dat(2018, 1, 1, 0.) == 37.0
Esempio n. 3
0
 def test_set_leap_seconds(self):
     assert erfa.dat(2018, 1, 1, 0.) == 37.0
     leap_seconds = erfa.leap_seconds.get()
     # Set to a table that misses the 2017 leap second.
     part_leap_seconds = leap_seconds[leap_seconds['year'] < 2017]
     erfa.leap_seconds.set(part_leap_seconds)
     new_leap_seconds = erfa.leap_seconds.get()
     assert_array_equal(new_leap_seconds, part_leap_seconds)
     # Check the 2017 leap second is indeed missing.
     assert erfa.dat(2018, 1, 1, 0.) == 36.0
     # And that this would be expected from the expiration date.
     assert erfa.leap_seconds.expires < datetime(2018, 1, 1)
     assert erfa.leap_seconds.expired
     # Reset and check it is back.
     erfa.leap_seconds.set()
     assert erfa.dat(2018, 1, 1, 0.) == 37.0
    def test_auto_update_leap_seconds(self):
        # Sanity check.
        assert erfa.dat(2018, 1, 1, 0.) == 37.0
        # Set expired leap seconds
        expired = self.erfa_ls[self.erfa_ls['year'] < 2017]
        expired.update_erfa_leap_seconds(initialize_erfa='empty')
        # Check the 2017 leap second is indeed missing.
        assert erfa.dat(2018, 1, 1, 0.) == 36.0

        # Update with missing leap seconds.
        n_update = update_leap_seconds([iers.IERS_LEAP_SECOND_FILE])
        assert n_update >= 1
        assert erfa.leap_seconds.expires == self.built_in.expires
        assert erfa.dat(2018, 1, 1, 0.) == 37.0

        # Doing it again does not change anything
        n_update2 = update_leap_seconds([iers.IERS_LEAP_SECOND_FILE])
        assert n_update2 == 0
        assert erfa.dat(2018, 1, 1, 0.) == 37.0
Esempio n. 5
0
 def test_validation(self, table, match):
     with pytest.raises(ValueError, match=match):
         erfa.leap_seconds.set(table)
     # Check leap-second table is not corrupted.
     assert_array_equal(erfa.leap_seconds.get(), self.erfa_ls)
     assert erfa.dat(2018, 1, 1, 0.) == 37.0
Esempio n. 6
0
def utc2cel06a_parameters(t, eop, iau55=False):
    """
    Purpose:
        This function calculates the cartesian transformation matrix for transforming GCRS to ITRS or vice versa
    :param eop:
        eop is a dataframe containing the Earth Orientation Parameters as per IAU definitions
    :param t:
        t is a datetime object or a list of datetime objects with the UTC times for the transformation matrix to be
            calculated for
    :return:
        jd is the julian date (always xxx.5 because it is based on a noon day break) in days
        ttb is the leap second offset in fractions of a day
        utb is the UT1 offset in fractions of a day
        xp and yp are the coordinates (in radians) of the Celestial Intermediate Pole with respect to the International
            Terrestrial Reference System (see IERS Conventions 2003), measured along the meridians to 0 and 90 deg west
            respectively (as extrapolated from between the two published points before and after).
        dx06 and dy06 are the CIP offsets wrt IAU 2006/2000A (mas->radians) as extrapolated from between the two
            published points before and after
    """
    year, month, day, hour, minute, second = t.year, t.month, t.day, t.hour, t.minute, t.second
    # TT (MJD). */
    djmjd0, date = erfa.cal2jd(iy=year, im=month, id=day)
    jd = djmjd0 + date
    day_frac = (60.0 * (60 * hour + minute) + second) / DAYSEC
    dat_s = erfa.dat(year, month, day, day_frac)
    ttb = dat_s / DAYSEC + 32.184 / DAYSEC

    # Polar motion (arcsec->radians)
    xp_l = eop["x"][date]
    yp_l = eop["y"][date]
    xp_h = eop["x"][date + 1]
    yp_h = eop["y"][date + 1]
    xp = (xp_l * (1 - day_frac) + xp_h * day_frac) * DAS2R
    yp = (yp_l * (1 - day_frac) + yp_h * day_frac) * DAS2R

    # UT1-UTC (s). */
    dut_l = eop["UT1-UTC"][date]
    dut_h = eop["UT1-UTC"][date + 1]
    dut1 = (dut_l * (1 - day_frac) + dut_h * day_frac)

    # CIP offsets wrt IAU 2006/2000A (mas->radians). */
    dx_l = eop["dX"][date]
    dx_h = eop["dX"][date + 1]
    dy_l = eop["dY"][date]
    dy_h = eop["dY"][date + 1]
    dx06 = (dx_l * (1 - day_frac) + dx_h * day_frac) * DAS2R
    dy06 = (dy_l * (1 - day_frac) + dy_h * day_frac) * DAS2R

    if iau55:
        # CIP offsets wrt IAU 2006/2000A (mas->radians). */
        dx06 = float64(0.1750 * DMAS2R, dtype="f64")
        dy06 = float64(-0.2259 * DMAS2R, dtype="f64")
        # UT1-UTC (s). */
        dut1 = float64(-0.072073685, dtype="f64")
        # Polar motion (arcsec->radians)
        xp = float64(0.0349282 * DAS2R, dtype="f64")
        yp = float64(0.4833163 * DAS2R, dtype="f64")

    # UT1. */
    utb = day_frac + dut1 / DAYSEC

    return jd, ttb, utb, xp, dx06, yp, dy06
Esempio n. 7
0
def gcrs2irts_matrix_b(t, eop):
    """
    Ref: http://www.iausofa.org/sofa_pn_c.pdf
    Purpose:
        This function calculates the cartesian transformation matrix for transforming GCRS to ITRS or vice versa
    :param eop:
        eop is a dataframe containing the Earth Orientation Parameters as per IAU definitions
    :param t:
        t is a datetime object or a list of datetime objects with the UTC times for the transformation matrix to be
        calculated for
    :return:
        matrix is a [3,3] numpy array or list of arrays used for transforming GCRS to ITRS or vice versa at the
        specified times; ITRS = matrix @ GCRS
    """
    if not (isinstance(t, Iterable)):
        t = [t]
    matrix = []
    for ti in t:
        year = ti.year
        month = ti.month
        day = ti.day
        hour = ti.hour
        minute = ti.minute
        second = ti.second

        # TT (MJD). */
        djmjd0, date = erfa.cal2jd(iy=year, im=month, id=day)
        # jd = djmjd0 + date
        day_frac = (60.0 * (60.0 * hour + minute) + second) / DAYSEC
        utc = date + day_frac
        Dat = erfa.dat(year, month, day, day_frac)
        tai = utc + Dat / DAYSEC
        tt = tai + 32.184 / DAYSEC

        # UT1. */
        dut1 = eop["UT1-UTC"][date] * (
            1 - day_frac) + eop["UT1-UTC"][date + 1] * day_frac
        tut = day_frac + dut1 / DAYSEC
        # ut1 = date + tut

        # CIP and CIO, IAU 2006/2000A. */
        x, y, s = erfa.xys06a(djmjd0, tt)

        # X, Y offsets
        dx06 = (eop["dX"][date] *
                (1 - day_frac) + eop["dX"][date + 1] * day_frac) * DAS2R
        dy06 = (eop["dY"][date] *
                (1 - day_frac) + eop["dY"][date + 1] * day_frac) * DAS2R

        # Add CIP corrections. */
        x = x + dx06
        y = y + dy06

        # GCRS to CIRS matrix. */
        rc2i = erfa.c2ixys(x, y, s)

        # Earth rotation angle. */
        era = erfa.era00(djmjd0 + date, tut)

        # Form celestial-terrestrial matrix (no polar motion yet). */
        rc2ti = erfa.cr(rc2i)
        rc2ti = eraRZ(era, rc2ti)
        #rc2ti = erfa.rz(era, rc2ti)

        # Polar motion matrix (TIRS->ITRS, IERS 2003). */
        xp = (eop["x"][date] *
              (1 - day_frac) + eop["x"][date + 1] * day_frac) * DAS2R
        yp = (eop["y"][date] *
              (1 - day_frac) + eop["y"][date + 1] * day_frac) * DAS2R
        rpom = erfa.pom00(xp, yp, erfa.sp00(djmjd0, tt))

        # Form celestial-terrestrial matrix (including polar motion). */
        rc2it = erfa.rxr(rpom, rc2ti)
        matrix.append(rc2it)
    if len(matrix) == 1:
        matrix = matrix[0]
    return matrix