Ejemplo n.º 1
0
def test_coordinates_kepler_equation():
    """Tests the kepler_equation() method of Coordinates module"""

    e1, v1 = kepler_equation(0.1, Angle(5.0))
    e2, v2 = kepler_equation(0.99, Angle(1.0))
    e3, v3 = kepler_equation(0.99, Angle(0.2, radians=True))

    assert abs(round(e1(), 6) - 5.554589) < TOL, \
        "ERROR: 1st kepler_equation() test, 'e1' value doesn't match"

    assert abs(round(v1(), 6) - 6.139762) < TOL, \
        "ERROR: 2nd kepler_equation() test, 'v1' value doesn't match"

    assert abs(round(e2(), 6) - 24.725822) < TOL, \
        "ERROR: 3rd kepler_equation() test, 'e2' value doesn't match"

    assert abs(round(v2(), 6) - 144.155952) < TOL, \
        "ERROR: 4th kepler_equation() test, 'v2' value doesn't match"

    assert abs(round(e3(), 8) - 61.13444578) < TOL, \
        "ERROR: 5th kepler_equation() test, 'e3' value doesn't match"

    assert abs(round(v3(), 6) - 166.311977) < TOL, \
        "ERROR: 6th kepler_equation() test, 'v3' value doesn't match"
Ejemplo n.º 2
0
    def heliocentric_ecliptical_position(self, epoch):
        """This method computes the heliocentric position of a minor celestial
        body, providing the result in ecliptical coordinates.

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

        :returns: A tuple containing longitude and latitude, 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)
        >>> epoch = Epoch(1990, 10, 6.0)
        >>> minor = Minor(q, e, i, omega, w, t)
        >>> lon, lat = minor.heliocentric_ecliptical_position(epoch)
        >>> print(lon.dms_str(n_dec=1))
        66d 51' 57.8''
        >>> print(lat.dms_str(n_dec=1))
        11d 56' 14.4''
        """

        # First check that input value is of correct types
        if not isinstance(epoch, Epoch):
            raise TypeError("Invalid input type")
        # Get the mean motion and other orbital parameters
        n = self._n
        a = self._a
        e = self._e
        i = self._i
        omega = self._omega
        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)
        # 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()
        r = a * (1.0 - e * cos(er))
        # Compute the heliocentric rectangular ecliptical coordinates
        wr = w.rad()
        vr = Angle(v).rad()
        ur = wr + vr
        omer = omega.rad()
        ir = i.rad()
        x = r * (cos(omer) * cos(ur) - sin(omer) * sin(ur) * cos(ir))
        y = r * (sin(omer) * cos(ur) + cos(omer) * sin(ur) * cos(ir))
        z = r * sin(ir) * sin(ur)
        lon = atan2(y, x)
        lat = atan2(z, sqrt(x * x + y * y))
        return Angle(lon, radians=True), Angle(lat, radians=True)
Ejemplo n.º 3
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