Example #1
0
def _next_fall_equinox(jd):
    '''Return the julian day count of the previous fall equinox.'''
    y, _, _ = gregorian.from_jd(jd)
    eqx = Sun.get_equinox_solstice(y, "autumn").jde()
    if eqx < jd:
        eqx = Sun.get_equinox_solstice(y + 1, "autumn").jde()

    return eqx
Example #2
0
def equinox_jd(gyear):
    """Calculate Julian day during which the March equinox, reckoned from the
    Tehran meridian, occurred for a given Gregorian year."""
    mean_jd = Sun.get_equinox_solstice(gyear, target='spring')
    deltat_jd = mean_jd - Epoch.tt2ut(gyear, 3) / (24 * 60 * 60.)
    # Apparent JD in universal time
    apparent_jd = deltat_jd + (Sun.equation_of_time(deltat_jd)[0] / (24 * 60.))
    # Correct for meridian of Tehran + 52.5 degrees
    return floor(apparent_jd.jde() + (52.5 / 360))
Example #3
0
def gregorian_day_of_nawruz(year):

    if year == 2059:
        return 20

    # get time of spring equinox
    equinox = Sun.get_equinox_solstice(year, "spring")

    # get sunset times in Tehran
    latitude = Angle(35.6944)
    longitude = Angle(51.4215)

    # get time of sunset in Tehran
    days = [19, 20, 21]
    sunsets = list(
        map(lambda x: Epoch(year, 3, x).rise_set(latitude, longitude)[1],
            days))

    # compare
    if equinox < sunsets[1]:
        if equinox < sunsets[0]:
            return 19
        else:
            return 20
    else:
        if equinox < sunsets[2]:
            return 21
        else:
            return 22
Example #4
0
def test_sun_apparent_longitude_coarse():
    """Tests apparent_longitude_coarse() method of Sun class"""

    epoch = Epoch(1992, 10, 13)
    alon, r = Sun.apparent_longitude_coarse(epoch)

    assert alon.dms_str(n_dec=0) == "199d 54' 32.0''", \
        "ERROR: 1st apparent_longitude_coarse() test, 'alon' doesn't match"
Example #5
0
def test_sun_get_equinox_solstice():
    """Tests the get_equinox_solstice() method of Sun class"""

    epoch = Sun.get_equinox_solstice(1962, target="summer")
    y, m, d, h, mi, s = epoch.get_full_date()
    st = "{}/{}/{} {}:{}:{}".format(y, m, d, h, mi, round(s, 0))

    assert st == "1962/6/21 21:24:42.0", \
        "ERROR: 1st get_equinox_solstice() test, time stamp doesn't match"
Example #6
0
def test_sun_true_longitude_coarse():
    """Tests the true_longitude_coarse() method of Sun class"""

    epoch = Epoch(1992, 10, 13)
    true_lon, r = Sun.true_longitude_coarse(epoch)

    assert true_lon.dms_str(n_dec=0) == "199d 54' 36.0''", \
        "ERROR: 1st true_longitude_coarse() test, 'true_lon' doesn't match"

    assert abs(round(r, 5) - 0.99766) < TOL, \
        "ERROR: 2nd true_longitude_coarse() test, 'r' value doesn't match"
Example #7
0
def test_sun_equation_of_time():
    """Tests the equation_of_time() method of Sun class"""

    epoch = Epoch(1992, 10, 13.0)
    m, s = Sun.equation_of_time(epoch)

    assert abs(m) - 13 < TOL, \
        "ERROR: 1st equation_of_time() test, 'm' doesn't match"

    assert abs(round(s, 1)) - 42.6 < TOL, \
        "ERROR: 2nd equation_of_time() test, 's' doesn't match"
Example #8
0
def test_sun_apparent_rightascension_declination_coarse():
    """Tests apparent_rightascension_declination_coarse() method of Sun
    class"""

    epoch = Epoch(1992, 10, 13)
    ra, delta, r = Sun.apparent_rightascension_declination_coarse(epoch)

    assert ra.ra_str(n_dec=1) == "13h 13' 31.4''", \
        "ERROR: 1st rightascension_declination_coarse() test doesn't match"

    assert delta.dms_str(n_dec=0) == "-7d 47' 6.0''", \
        "ERROR: 2nd rightascension_declination_coarse() test doesn't match"
Example #9
0
def test_rectangular_coordinates_mean_equinox():
    """Tests rectangular_coordinates_mean_equinox() method of Sun class"""

    epoch = Epoch(1992, 10, 13.0)
    x, y, z = Sun.rectangular_coordinates_mean_equinox(epoch)

    assert abs(round(x, 7) - (-0.9379963)) < TOL, \
        "ERROR: 1st rectangular_coordinates_mean_equinox(), 'x' doesn't match"

    assert abs(round(y, 6) - (-0.311654)) < TOL, \
        "ERROR: 2nd rectangular_coordinates_mean_equinox(), 'y' doesn't match"

    assert abs(round(z, 7) - (-0.1351207)) < TOL, \
        "ERROR: 3rd rectangular_coordinates_mean_equinox(), 'z' doesn't match"
Example #10
0
def test_sun_apparent_geocentric_position():
    """Tests the apparent_geocentric_position() method of Sun class"""

    epoch = Epoch(1992, 10, 13.0)
    lon, lat, r = Sun.apparent_geocentric_position(epoch)

    assert lon.to_positive().dms_str(n_dec=3) == "199d 54' 21.548''", \
        "ERROR: 1st apparent_geocentric_position() test, 'lon' doesn't match"

    assert lat.dms_str(n_dec=3) == "0.721''", \
        "ERROR: 2nd apparent_geocentric_position() test, 'lat' doesn't match"

    assert abs(round(r, 8) - 0.99760852) < TOL, \
        "ERROR: 3rd apparent_geocentric_position() test, 'r' doesn't match"
Example #11
0
def test_rectangular_coordinates_b1950():
    """Tests rectangular_coordinates_b1950() method of Sun class"""

    epoch = Epoch(1992, 10, 13.0)
    x, y, z = Sun.rectangular_coordinates_b1950(epoch)

    assert abs(round(x, 8) - (-0.94149557)) < TOL, \
        "ERROR: 1st rectangular_coordinates_b1950() test, 'x' doesn't match"

    assert abs(round(y, 8) - (-0.30259922)) < TOL, \
        "ERROR: 2nd rectangular_coordinates_b1950() test, 'y' doesn't match"

    assert abs(round(z, 8) - (-0.11578695)) < TOL, \
        "ERROR: 3rd rectangular_coordinates_b1950() test, 'z' doesn't match"
Example #12
0
def test_sun_ephemeris_physical_observations():
    """Tests the ephemeris_physical_observations() method of Sun class"""

    epoch = Epoch(1992, 10, 13)
    p, b0, l0 = Sun.ephemeris_physical_observations(epoch)

    assert abs(round(p, 2)) - 26.27 < TOL, \
        "ERROR: 1st ephemeris_physical_observations() test, 'p' doesn't match"

    assert abs(round(b0, 2)) - 5.99 < TOL, \
        "ERROR: 2nd ephemeris_physical_observations() test, 'b0' doesn't match"

    assert abs(round(l0, 2)) - 238.63 < TOL, \
        "ERROR: 3rd ephemeris_physical_observations() test, 'l0' doesn't match"
Example #13
0
def test_sun_geometric_geocentric_position():
    """Tests the geometric_geocentric_position() method of Sun class"""

    epoch = Epoch(1992, 10, 13.0)
    lon, lat, r = Sun.geometric_geocentric_position(epoch, tofk5=False)

    assert abs(round(lon.to_positive(), 6) - 199.907297) < TOL, \
        "ERROR: 1st geometric_geocentric_position() test, 'lon' doesn't match"

    assert lat.dms_str(n_dec=3) == "0.744''", \
        "ERROR: 2nd geometric_geocentric_position() test, 'lat' doesn't match"

    assert abs(round(r, 8) - 0.99760852) < TOL, \
        "ERROR: 3rd geometric_geocentric_position() test, 'r' doesn't match"
Example #14
0
def test_rectangular_coordinates_j2000():
    """Tests rectangular_coordinates_j2000() method of Sun class"""

    epoch = Epoch(1992, 10, 13.0)
    x, y, z = Sun.rectangular_coordinates_j2000(epoch)

    assert abs(round(x, 8) - (-0.93740485)) < TOL, \
        "ERROR: 1st rectangular_coordinates_j2000() test, 'x' doesn't match"

    assert abs(round(y, 8) - (-0.3131474)) < TOL, \
        "ERROR: 2nd rectangular_coordinates_j2000() test, 'y' doesn't match"

    assert abs(round(z, 8) - (-0.13577045)) < TOL, \
        "ERROR: 3rd rectangular_coordinates_j2000() test, 'z' doesn't match"
Example #15
0
def test_rectangular_coordinates_equinox():
    """Tests rectangular_coordinates_equinox() method of Sun class"""

    epoch = Epoch(1992, 10, 13.0)
    e_equinox = Epoch(2467616.0)
    x, y, z = Sun.rectangular_coordinates_equinox(epoch, e_equinox)

    assert abs(round(x, 8) - (-0.93368986)) < TOL, \
        "ERROR: 1st rectangular_coordinates_equinox() test, 'x' doesn't match"

    assert abs(round(y, 8) - (-0.32235085)) < TOL, \
        "ERROR: 2nd rectangular_coordinates_equinox() test, 'y' doesn't match"

    assert abs(round(z, 8) - (-0.13977098)) < TOL, \
        "ERROR: 3rd rectangular_coordinates_equinox() test, 'z' doesn't match"
Example #16
0
def gregorian_nawruz(year):
    '''
        Return Nawruz in the Gregorian calendar.
        Returns a tuple (month, day), where month is always 3
    '''
    if year == 2059:
        return 3, 20

    # Timestamp of spring equinox.
    equinox = Sun.get_equinox_solstice(year, "spring")

    # Get times of sunsets in Tehran near vernal equinox.
    x, y = Angle(TEHRAN[0]), Angle(TEHRAN[1])
    days = trunc(equinox.get_date()[2]), ceil(equinox.get_date()[2])

    for day in days:
        sunset = Epoch(year, 3, day).rise_set(y, x)[1]
        if sunset > equinox:
            return 3, day
Example #17
0
    def geocentric_position(self, epoch):
        """This method computes the geocentric position of a minor celestial
        body (right ascension and declination) for the given epoch, and
        referred to the standard equinox J2000.0. Additionally, it also
        computes the elongation angle to the Sun.

        :param epoch: Epoch to compute geocentric position, as an Epoch object
        :type epoch: :py:class:`Epoch`

        :returns: A tuple containing the right ascension, the declination and
            the elongation angle to the Sun, as Angle objects
        :rtype: tuple
        :raises: TypeError if input value is of wrong type.

        >>> a = 2.2091404
        >>> e = 0.8502196
        >>> q = a * (1.0 - e)
        >>> i = Angle(11.94524)
        >>> omega = Angle(334.75006)
        >>> w = Angle(186.23352)
        >>> t = Epoch(1990, 10, 28.54502)
        >>> minor = Minor(q, e, i, omega, w, t)
        >>> epoch = Epoch(1990, 10, 6.0)
        >>> ra, dec, p = minor.geocentric_position(epoch)
        >>> print(ra.ra_str(n_dec=1))
        10h 34' 13.7''
        >>> print(dec.dms_str(n_dec=0))
        19d 9' 32.0''
        >>> print(round(p, 2))
        40.51
        >>> t = Epoch(1998, 4, 14.4358)
        >>> q = 1.487469
        >>> e = 1.0
        >>> i = Angle(0.0)
        >>> omega = Angle(0.0)
        >>> w = Angle(0.0)
        >>> minor = Minor(q, e, i, omega, w, t)
        >>> epoch = Epoch(1998, 8, 5.0)
        >>> ra, dec, p = minor.geocentric_position(epoch)
        >>> print(ra.ra_str(n_dec=1))
        5h 45' 34.5''
        >>> print(dec.dms_str(n_dec=0))
        23d 23' 53.0''
        >>> print(round(p, 2))
        45.73
        """

        # First check that input value is of correct types
        if not isinstance(epoch, Epoch):
            raise TypeError("Invalid input type")
        # Get internal parameters
        aa, bb, cc = self._aa, self._bb, self._cc
        am, bm, cm = self._am, self._bm, self._cm
        # Get the mean motion and other orbital parameters
        n = self._n
        a = self._a
        e = self._e
        w = self._w
        t = self._t
        # Time since perihelion
        t_peri = epoch - t
        # Now, compute the mean anomaly, in degrees
        m = t_peri * n
        m = Angle(m)
        if e < 0.98:
            # Elliptic case
            # With the mean anomaly, use Kepler's equation to find E and v
            ee, v = kepler_equation(e, m)
            ee = Angle(ee).to_positive()
            # Get r
            er = ee.rad()
            rr = a * (1.0 - e * cos(er))
        elif abs(e - 1.0) < self._tol:
            # Parabolic case
            q = self._q
            ww = (0.03649116245 * (epoch - self._t)) / (q * sqrt(q))
            sp = ww / 3.0
            iterate = True
            while iterate:
                s = (2.0 * sp * sp * sp + ww) / (3.0 * (sp * sp + 1.0))
                iterate = abs(s - sp) > self._tol
                sp = s
            v = 2.0 * atan(s)
            v = Angle(v, radians=True)
            rr = q * (1.0 + s * s)
        else:
            # We are in the near-parabolic case
            v, rr = self._near_parabolic(t_peri)
        # Compute the heliocentric rectangular equatorial coordinates
        wr = w.rad()
        vr = Angle(v).rad()
        x = rr * am * sin(aa + wr + vr)
        y = rr * bm * sin(bb + wr + vr)
        z = rr * cm * sin(cc + wr + vr)
        # Now let's compute Sun's rectangular coordinates
        xs, ys, zs = Sun.rectangular_coordinates_j2000(epoch)
        xi = x + xs
        eta = y + ys
        zeta = z + zs
        delta = sqrt(xi * xi + eta * eta + zeta * zeta)
        # We need to correct for the effect of light-time. Compute delay tau
        tau = 0.0057755183 * delta
        # Recompute some critical parameters
        t_peri = epoch - t - tau
        # Now, compute the mean anomaly, in degrees
        m = t_peri * n
        m = Angle(m)
        if e < 0.98:
            # Elliptic case
            # With the mean anomaly, use Kepler's equation to find E and v
            ee, v = kepler_equation(e, m)
            ee = Angle(ee).to_positive()
            # Get r
            er = ee.rad()
            rr = a * (1.0 - e * cos(er))
        elif abs(e - 1.0) < self._tol:
            # Parabolic case
            q = self._q
            ww = (0.03649116245 * (epoch - self._t)) / (q * sqrt(q))
            sp = ww / 3.0
            iterate = True
            while iterate:
                s = (2.0 * sp * sp * sp + ww) / (3.0 * (sp * sp + 1.0))
                iterate = abs(s - sp) > self._tol
                sp = s
            v = 2.0 * atan(s)
            v = Angle(v, radians=True)
            rr = q * (1.0 + s * s)
        else:
            # We are in the near-parabolic case
            v, rr = self._near_parabolic(t_peri)
        # Compute the heliocentric rectangular equatorial coordinates
        wr = w.rad()
        vr = Angle(v).rad()
        x = rr * am * sin(aa + wr + vr)
        y = rr * bm * sin(bb + wr + vr)
        z = rr * cm * sin(cc + wr + vr)
        xi = x + xs
        eta = y + ys
        zeta = z + zs
        ra = Angle(atan2(eta, xi), radians=True)
        dec = Angle(atan2(zeta, sqrt(xi * xi + eta * eta)), radians=True)
        r_sun = sqrt(xs * xs + ys * ys + zs * zs)
        psi = acos((xi * xs + eta * ys + zeta * zs) / (r_sun * delta))
        psi = Angle(psi, radians=True)
        return ra, dec, psi
Example #18
0
    def geocentric_position(epoch):
        """This method computes the geocentric position of Pluto (right
        ascension and declination) for the given epoch, for the standard
        equinox J2000.0.

        :param epoch: Epoch to compute geocentric position, as an Epoch object
        :type epoch: :py:class:`Epoch`

        :returns: A tuple containing the right ascension and the declination as
            Angle objects
        :rtype: tuple
        :raises: TypeError if input value is of wrong type.
        :raises: ValueError if input epoch outside the 1885-2099 range.

        >>> epoch = Epoch(1992, 10, 13.0)
        >>> ra, dec = Pluto.geocentric_position(epoch)
        >>> print(ra.ra_str(n_dec=1))
        15h 31' 43.7''
        >>> print(dec.dms_str(n_dec=0))
        -4d 27' 29.0''
        """

        # First check that input value is of correct types
        if not isinstance(epoch, Epoch):
            raise TypeError("Invalid input type")
        # Check that the input epoch is within valid range
        y = epoch.year()
        if y < 1885.0 or y > 2099.0:
            raise ValueError("Epoch outside the 1885-2099 range")
        # Compute the heliocentric position of Pluto
        ll, b, r = Pluto.geometric_heliocentric_position(epoch)
        # Change angles to radians
        ll = ll.rad()
        b = b.rad()
        # Values corresponding to obliquity of ecliptic (epsilon) for J2000.0
        sine = 0.397777156
        cose = 0.917482062
        x = r * cos(ll) * cos(b)
        y = r * (sin(ll) * cos(b) * cose - sin(b) * sine)
        z = r * (sin(ll) * cos(b) * sine + sin(b) * cose)
        # Compute Sun's J2000.0 rectacngular coordinates
        xs, ys, zs = Sun.rectangular_coordinates_j2000(epoch)
        # Compute auxiliary quantities
        xi = x + xs
        eta = y + ys
        zeta = z + zs
        # Compute Pluto's distance to Earth
        delta = sqrt(xi * xi + eta * eta + zeta * zeta)
        # Get the light-time difference
        tau = 0.0057755183 * delta
        # Repeat the computations using the light-time correction
        ll, b, r = Pluto.geometric_heliocentric_position(epoch - tau)
        # Change angles to radians
        ll = ll.rad()
        b = b.rad()
        x = r * cos(ll) * cos(b)
        y = r * (sin(ll) * cos(b) * cose - sin(b) * sine)
        z = r * (sin(ll) * cos(b) * sine + sin(b) * cose)
        # Compute auxiliary quantities
        xi = x + xs
        eta = y + ys
        zeta = z + zs
        # Compute Pluto's distance to Earth
        delta = sqrt(xi * xi + eta * eta + zeta * zeta)
        # Compute right ascension and declination
        alpha = Angle(atan2(eta, xi), radians=True)
        dec = Angle(asin(zeta / delta), radians=True)
        return alpha.to_positive(), dec