예제 #1
0
파일: test_jdcal.py 프로젝트: Jon1ke/script
def test_gcal2jd_with_astropy_erfa_cal2jd():
    """Compare gcal2jd with astropy._erfa.cal2jd."""
    import random
    import numpy as np
    from astropy import _erfa

    n = 1000
    mday = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]

    # sla_cldj needs year > -4699 i.e., 4700 BC.
    year = [random.randint(-4699, 2200) for i in range(n)]
    month = [random.randint(1, 12) for i in range(n)]
    day = [random.randint(1, 31) for i in range(n)]
    for i in range(n):
        x = 0
        if is_leap(year[i]) and month[i] == 2:
            x = 1
        if day[i] > mday[month[i]] + x:
            day[i] = mday[month[i]]

    jd_jdcal = np.array(
        [gcal2jd(y, m, d) for y, m, d in zip(year, month, day)])
    jd_erfa = np.array(_erfa.cal2jd(year, month, day)).T

    assert np.allclose(jd_jdcal, jd_erfa)
예제 #2
0
def _test_erfa_conversion(leap, i_f):
    i_i, f_i = i_f
    assume(0 <= f_i < 1)
    if leap:
        assume(i_i in leap_sec_days)
    else:
        assume(i_i not in leap_sec_days)
    jd1_in, jd2_in = day_frac(erfa.DJM0 + i_i, f_i)
    y, mo, d, f = erfa.jd2cal(jd1_in, jd2_in)
    assert 0 < y < 3000
    assert 0 < mo <= 12
    assert 0 <= d < 32
    assert 0 <= f < 1

    jd1_temp, jd2_temp = erfa.cal2jd(y, mo, d)
    jd1_temp, jd2_temp = day_frac(jd1_temp, jd2_temp)  # improve numerics
    jd1_temp, jd2_temp = day_frac(jd1_temp, jd2_temp + f)
    jd_change = abs((jd1_temp - jd1_in) + (jd2_temp - jd2_in)) * u.day
    assert jd_change.to(u.ns) < 1 * u.ns

    ft = 24 * f
    h = safe_kind_conversion(np.floor(ft), dtype=int)
    ft -= h
    ft *= 60
    m = safe_kind_conversion(np.floor(ft), dtype=int)
    ft -= m
    ft *= 60
    s = ft
    assert 0 <= h < 24
    assert 0 <= m < 60
    assert 0 <= s < 60

    jd1, jd2 = erfa.dtf2d("UTC", y, mo, d, h, m, s)
    y2, mo2, d2, f2 = erfa.jd2cal(jd1, jd2)
    # assert (y, mo, d) == (y2, mo2, d2)
    # assert (abs(f2-f)*u.day).to(u.s) < 1*u.ns

    assert jd1 == np.floor(jd1) + 0.5
    assert 0 <= jd2 < 1
    jd1, jd2 = day_frac(jd1, jd2)
    jd_change = abs((jd1 - jd1_in) + (jd2 - jd2_in)) * u.day
    if leap:
        assert jd_change.to(u.s) < 1 * u.s
    else:
        assert jd_change.to(u.ns) < 2 * u.ns
        # assert jd_change.to(u.ns) < 1 * u.ns
    return

    i_o, f_o = day_frac(jd1 - erfa.DJM0, jd2)

    mjd_change = abs((i_o - i_i) + (f_o - f_i)) * u.day
    if leap:
        assert mjd_change.to(u.s) < 1 * u.s
    else:
        assert mjd_change.to(u.ns) < 1 * u.ns
예제 #3
0
 def value(self):
     if self._scale == 'utc':
         # Do the reverse of the above calculation
         # Note this will return an incorrect value during 
         # leap seconds, so raise an exception in that 
         # case.
         y, mo, d, hmsf = erfa.d2dtf('UTC',9,self.jd1,self.jd2)
         if 60 in hmsf[...,2]:
             raise ValueError('UTC times during a leap second cannot be represented in pulsar_mjd format')
         j1, j2 = erfa.cal2jd(y,mo,d)
         return (j1 - erfa.DJM0 + j2) + (hmsf[...,0]/24.0 
                 + hmsf[...,1]/1440.0 
                 + hmsf[...,2]/86400.0 
                 + hmsf[...,3]/86400.0e9)
     else:
         # As in TimeMJD
         return (self.jd1 - erfa.DJM0) + self.jd2
예제 #4
0
 def value(self):
     if self._scale == 'utc':
         # Do the reverse of the above calculation
         # Note this will return an incorrect value during
         # leap seconds, so raise an exception in that
         # case.
         y, mo, d, hmsf = erfa.d2dtf('UTC', 9, self.jd1, self.jd2)
         if 60 in hmsf[..., 2]:
             raise ValueError(
                 'UTC times during a leap second cannot be represented in pulsar_mjd format'
             )
         j1, j2 = erfa.cal2jd(y, mo, d)
         return (j1 - erfa.DJM0 +
                 j2) + (hmsf[..., 0] / 24.0 + hmsf[..., 1] / 1440.0 +
                        hmsf[..., 2] / 86400.0 + hmsf[..., 3] / 86400.0e9)
     else:
         # As in TimeMJD
         return (self.jd1 - erfa.DJM0) + self.jd2
예제 #5
0
 def value(self):
     if self._scale == 'utc':
         # Do the reverse of the above calculation
         # Note this will return an incorrect value during
         # leap seconds, so raise an exception in that
         # case.
         y, mo, d, hmsf = erfa.d2dtf('UTC',9,self.jd1,self.jd2)
         # For ASTROPY_LT_3_1, convert to the new structured array dtype that
         # is returned by the new erfa gufuncs.
         if not hmsf.dtype.names:
             hmsf = hmsf.view(self._new_ihmsfs_dtype)
         if numpy.any(hmsf['s'] == 60):
             raise ValueError('UTC times during a leap second cannot be represented in pulsar_mjd format')
         j1, j2 = erfa.cal2jd(y,mo,d)
         return (j1 - erfa.DJM0 + j2) + (hmsf['h']/24.0
                 + hmsf['m']/1440.0
                 + hmsf['s']/86400.0
                 + hmsf['f']/86400.0e9)
     else:
         # As in TimeMJD
         return (self.jd1 - erfa.DJM0) + self.jd2
예제 #6
0
파일: pulsar_mjd.py 프로젝트: nanograv/PINT
 def value(self):
     if self._scale == 'utc':
         # Do the reverse of the above calculation
         # Note this will return an incorrect value during
         # leap seconds, so raise an exception in that
         # case.
         y, mo, d, hmsf = erfa.d2dtf('UTC',9,self.jd1,self.jd2)
         # For ASTROPY_LT_3_1, convert to the new structured array dtype that
         # is returned by the new erfa gufuncs.
         if not hmsf.dtype.names:
             hmsf = hmsf.view(self._new_ihmsfs_dtype)
         if numpy.any(hmsf['s'] == 60):
             raise ValueError('UTC times during a leap second cannot be represented in pulsar_mjd format')
         j1, j2 = erfa.cal2jd(y,mo,d)
         return (j1 - erfa.DJM0 + j2) + (hmsf['h']/24.0
                 + hmsf['m']/1440.0
                 + hmsf['s']/86400.0
                 + hmsf['f']/86400.0e9)
     else:
         # As in TimeMJD
         return (self.jd1 - erfa.DJM0) + self.jd2
예제 #7
0
def jds_to_mjds_pulsar(jd1, jd2):
    # Do the reverse of the above calculation
    # Note this will return an incorrect value during
    # leap seconds, so raise an exception in that
    # case.
    y, mo, d, hmsf = erfa.d2dtf("UTC", _digits, jd1, jd2)
    # For ASTROPY_LT_3_1, convert to the new structured array dtype that
    # is returned by the new erfa gufuncs.
    if not hmsf.dtype.names:
        hmsf = hmsf.view(_new_ihmsfs_dtype)[..., 0]
    if np.any((hmsf["s"] == 60) & (hmsf["f"] != 0)):
        # if f is exactly zero, this is probably fine to treat as the end of the day.
        raise ValueError(
            "UTC times during a leap second cannot be represented in pulsar_mjd format"
        )
    j1, j2 = erfa.cal2jd(y, mo, d)
    return day_frac(
        j1 - erfa.DJM0 + j2,
        hmsf["h"] / 24.0
        + hmsf["m"] / 1440.0
        + hmsf["s"] / 86400.0
        + hmsf["f"] / 86400.0 / 10 ** _digits,
    )
예제 #8
0
파일: test_jdcal.py 프로젝트: phn/jdcal
def test_gcal2jd_with_astropy_erfa_cal2jd():
    """Compare gcal2jd with astropy._erfa.cal2jd."""
    import random
    import numpy as np
    from astropy import _erfa

    n = 1000
    mday = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]

    # sla_cldj needs year > -4699 i.e., 4700 BC.
    year = [random.randint(-4699, 2200) for i in range(n)]
    month = [random.randint(1, 12) for i in range(n)]
    day = [random.randint(1, 31) for i in range(n)]
    for i in range(n):
        x = 0
        if is_leap(year[i]) and month[i] == 2:
            x = 1
        if day[i] > mday[month[i]] + x:
            day[i] = mday[month[i]]

    jd_jdcal = np.array([gcal2jd(y, m, d) for y, m, d in zip(year, month, day)])
    jd_erfa = np.array(_erfa.cal2jd(year, month, day)).T

    assert np.allclose(jd_jdcal, jd_erfa)
예제 #9
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
예제 #10
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