コード例 #1
0
ファイル: equinox.py プロジェクト: ztessler/fvcom-py
def equinox(jd, season, delta):
    """Return the precise moment of an equinox or solstice event on Earth.
    
    Parameters:
        jd     : Julian Day of an approximate time of the event in dynamical time
        season : one of ("spring", "summer", "autumn", "winter")
        delta  : the required precision in days. Times accurate to a second are
            reasonable when using the VSOP model.
        
    Returns:
        Julian Day of the event in dynamical time

    """
    #
    # If we knew that the starting approximate time was close enough
    # to the actual time, we could pull nut_in_lon() and the aberration
    # out of the loop and save some calculating.
    #
    circ = _circle[season]
    sun = Sun()
    for i in range(20):
        jd0 = jd
        L, B, R = sun.dimension3(jd)
        L += nut_in_lon(jd) + aberration_low(R)
        L, B = vsop_to_fk5(jd, L, B)
        # Meeus uses jd + 58 * sin(diff(...))
        jd += diff_angle(L, circ) * _k_sun_motion
        if abs(jd - jd0) < delta:
            return jd
    raise Error, "bailout"
コード例 #2
0
ファイル: equinox.py プロジェクト: songgz/fvcom-py
def equinox(jd, season, delta):
    """Return the precise moment of an equinox or solstice event on Earth.
    
    Parameters:
        jd     : Julian Day of an approximate time of the event in dynamical time
        season : one of ("spring", "summer", "autumn", "winter")
        delta  : the required precision in days. Times accurate to a second are
            reasonable when using the VSOP model.
        
    Returns:
        Julian Day of the event in dynamical time

    """
    #
    # If we knew that the starting approximate time was close enough
    # to the actual time, we could pull nut_in_lon() and the aberration
    # out of the loop and save some calculating.
    #
    circ = _circle[season]
    sun = Sun()
    for i in range(20):
        jd0 = jd
        L, B, R = sun.dimension3(jd)
        L += nut_in_lon(jd) + aberration_low(R)
        L, B = vsop_to_fk5(jd, L, B)
        # Meeus uses jd + 58 * sin(diff(...))
        jd += diff_angle(L, circ) * _k_sun_motion
        if abs(jd - jd0) < delta: 
            return jd
    raise Error, "bailout"
コード例 #3
0
ファイル: riseset.py プロジェクト: songgz/fvcom-py
def rise(jd, raList, decList, h0, delta):
    """Return the Julian Day of the rise time of an object.
    
    Parameters:
        jd      : Julian Day number of the day in question, at 0 hr UT
        raList  : a sequence of three right accension values, in radians,
            for (jd-1, jd, jd+1)
        decList : a sequence of three right declination values, in radians,
            for (jd-1, jd, jd+1)
        h0      : the standard altitude in radians
        delta   : desired accuracy in days. Times less than one minute are
            infeasible for rise times because of atmospheric refraction.
            
    Returns:
        Julian Day of the rise time
    
    """
    longitude = astronomia.globals.longitude
    latitude = astronomia.globals.latitude
    THETA0 = sidereal_time_greenwich(jd)
    deltaT_days = deltaT_seconds(jd) / seconds_per_day

    cosH0 = (sin(h0) - sin(latitude) * sin(decList[1])) / (cos(latitude) * cos(decList[1]))
    #
    # future: return some indicator when the object is circumpolar or always
    # below the horizon.
    #
    if cosH0 < -1.0: # circumpolar
        return None
    if cosH0 > 1.0:  # never rises
        return None

    H0 = acos(cosH0)    
    m0 = (raList[1] + longitude - THETA0) / pi2
    m = m0 - H0 / pi2  # this is the only difference between rise() and set()
    if m < 0:
        m += 1
    elif m > 1:
        m -= 1
    if not 0 <= m <= 1:
        raise Error, "m is out of range = " + str(m)
    for bailout in range(20):
        m0 = m
        theta0 = modpi2(THETA0 + _k1 * m)
        n = m + deltaT_days
        if not -1 < n < 1:
            return None # Bug: this is where we drop some events
        ra = interpolate_angle3(n, raList)
        dec = interpolate3(n, decList)
        H = theta0 - longitude - ra
#        if H > pi:
#            H = H - pi2
        H = diff_angle(0.0, H)
        A, h = equ_to_horiz(H, dec)
        dm = (h - h0) / (pi2 * cos(dec) * cos(latitude) * sin(H))
        m += dm
        if abs(m - m0) < delta:
            return jd + m

    raise Error, "bailout"
コード例 #4
0
ファイル: riseset.py プロジェクト: timcera/astronomia
def _riseset(jd, raList, decList, h0, delta, mode,
             longitude=astronomia.globals.longitude,
             latitude=astronomia.globals.latitude):
    # Private function since rise/set so similar

    THETA0 = sidereal_time_greenwich(jd)
    deltaT_days = deltaT_seconds(jd) / seconds_per_day

    cosH0 = (np.sin(h0) - np.sin(latitude)*np.sin(decList[1])) / (
        np.cos(latitude)*np.cos(decList[1]))
    #
    # future: return some indicator when the object is circumpolar or always
    # below the horizon.
    #
    if cosH0 < -1.0:  # circumpolar
        return None
    if cosH0 > 1.0:  # never rises
        return None

    H0 = np.arccos(cosH0)
    m0 = (raList[1] + longitude - THETA0) / pi2
    if mode == 'rise':
        m = m0 - H0 / pi2  # the only difference between rise() and settime()
    elif mode == 'set':
        m = m0 + H0 / pi2  # the only difference between rise() and settime()
    if m < 0:
        m += 1
    elif m > 1:
        m -= 1
    if not 0 <= m <= 1:
        raise Error("m is out of range = " + str(m))
    for bailout in range(20):
        m0 = m
        theta0 = modpi2(THETA0 + _k1 * m)
        n = m + deltaT_days
        if not -1 < n < 1:
            return None  # Bug: this is where we drop some events
        ra = interpolate_angle3(n, raList)
        dec = interpolate3(n, decList)
        H = theta0 - longitude - ra
#        if H > pi:
#            H = H - pi2
        H = diff_angle(0.0, H)
        A, h = equ_to_horiz(H, dec)
        dm = (h - h0) / (pi2 * np.cos(dec) * np.cos(latitude) * np.sin(H))
        m += dm
        if abs(m - m0) < delta:
            return jd + m

    raise Error("bailout")
コード例 #5
0
def transit(jd, raList, delta):
    """Return the Julian Day of the transit time of an object.
    
    Parameters:
        jd      : Julian Day number of the day in question, at 0 hr UT
        raList  : a sequence of three right accension values, in radians,
            for (jd-1, jd, jd+1)
        delta   : desired accuracy in days. 
            
    Returns:
        Julian Day of the transit time
    
    """
    #
    # future: report both upper and lower culmination, and transits of objects below
    # the horizon
    #
    longitude = astronomia.globals.longitude
    THETA0 = sidereal_time_greenwich(jd)
    deltaT_days = deltaT_seconds(jd) / seconds_per_day

    m = (raList[1] + longitude - THETA0) / pi2
    if m < 0:
        m += 1
    elif m > 1:
        m -= 1
    if not 0 <= m <= 1:
        raise Error, "m is out of range = " + str(m)
    for bailout in range(20):
        m0 = m
        theta0 = modpi2(THETA0 + _k1 * m)
        n = m + deltaT_days
        if not -1 < n < 1:
            return None  # Bug: this is where we drop some events
        ra = interpolate_angle3(n, raList)
        H = theta0 - longitude - ra
        #        if H > pi:
        #            H = H - pi2
        H = diff_angle(0.0, H)
        dm = -H / pi2
        m += dm
        if abs(m - m0) < delta:
            return jd + m

    raise Error, "bailout"
コード例 #6
0
ファイル: riseset.py プロジェクト: timcera/astronomia
def transit(jd, raList, delta):
    """Return the Julian Day of the transit time of an object.

    Arguments:
      - `jd`      : Julian Day number of the day in question, at 0 hr UT
      - `raList`  : a sequence of three right accension values, in radians, for
        (jd-1, jd, jd+1)
      - `delta`   : desired accuracy in days.

    Returns:
      - Julian Day of the transit time

    """
    #
    # future: report both upper and lower culmination, and transits of objects
    # below the horizon
    #
    longitude = astronomia.globals.longitude
    THETA0 = sidereal_time_greenwich(jd)
    deltaT_days = deltaT_seconds(jd) / seconds_per_day

    m = (raList[1] + longitude - THETA0) / pi2
    if m < 0:
        m += 1
    elif m > 1:
        m -= 1
    if not 0 <= m <= 1:
        raise Error("m is out of range = " + str(m))
    for bailout in range(20):
        m0 = m
        theta0 = modpi2(THETA0 + _k1 * m)
        n = m + deltaT_days
        if not -1 < n < 1:
            return None  # Bug: this is where we drop some events
        ra = interpolate_angle3(n, raList)
        H = theta0 - longitude - ra
#        if H > pi:
#            H = H - pi2
        H = diff_angle(0.0, H)
        dm = -H/pi2
        m += dm
        if abs(m - m0) < delta:
            return jd + m

    raise Error("bailout")
コード例 #7
0
ファイル: planets.py プロジェクト: timcera/astronomia
def geocentric_planet(jd, planet, deltaPsi, epsilon, delta):
    """Calculate the equatorial coordinates of a planet

    The results will be geocentric, corrected for light-time and
    aberration.

    Arguments:
      - `jd`       : Julian Day in dynamical time
      - `planet`   : must be one of ("Mercury", "Venus", "Earth", "Mars",
        "Jupiter", "Saturn", "Uranus", "Neptune")
      - `deltaPsi` : nutation in longitude, in radians
      - `epsilon`  : True obliquity (corrected for nutation), in radians
      - `delta`    : desired accuracy, in days

    Returns:
      - right accension, in radians
      - declination, in radians

    """
    jd = np.atleast_1d(jd)
    vsop = VSOP87d()
    t = jd
    l0 = -100.0  # impossible value
    # We need to iterate to correct for light-time and aberration.
    # At most three passes through the loop always nails it.
    # Note that we move both the Earth and the other planet during
    #    the iteration.
    for bailout in range(20):
        # heliocentric geometric ecliptic coordinates of the Earth
        L0, B0, R0 = vsop.dimension3(t, "Earth")

        # heliocentric geometric ecliptic coordinates of the planet
        L, B, R = vsop.dimension3(t, planet)

        # rectangular offset
        cosB0 = np.cos(B0)
        cosB = np.cos(B)
        x = R*cosB*np.cos(L) - R0*cosB0*np.cos(L0)
        y = R*cosB*np.sin(L) - R0*cosB0*np.sin(L0)
        z = R*np.sin(B) - R0*np.sin(B0)

        # geocentric geometric ecliptic coordinates of the planet
        x2 = x*x
        y2 = y*y
        l = np.arctan2(y, x)
        b = np.arctan2(z, np.sqrt(x2 + y2))

        # distance to planet in AU
        dist = np.sqrt(x2 + y2 + z*z)

        # light time in days
        tau = 0.0057755183 * dist

        if abs(diff_angle(l, l0)) < pi2 * delta:
            break

        # adjust for light travel time and try again
        l0 = l
        t = jd - tau
    else:
        raise Error("bailout")

    # transform to FK5 ecliptic and equinox
    l, b = vsop_to_fk5(jd, l, b)

    # nutation in longitude
    l = l + deltaPsi

    # equatorial coordinates
    ra, dec = ecl_to_equ(l, b, epsilon)

    return ra, dec
コード例 #8
0
def rise(jd, raList, decList, h0, delta):
    """Return the Julian Day of the rise time of an object.
    
    Parameters:
        jd      : Julian Day number of the day in question, at 0 hr UT
        raList  : a sequence of three right accension values, in radians,
            for (jd-1, jd, jd+1)
        decList : a sequence of three right declination values, in radians,
            for (jd-1, jd, jd+1)
        h0      : the standard altitude in radians
        delta   : desired accuracy in days. Times less than one minute are
            infeasible for rise times because of atmospheric refraction.
            
    Returns:
        Julian Day of the rise time
    
    """
    longitude = astronomia.globals.longitude
    latitude = astronomia.globals.latitude
    THETA0 = sidereal_time_greenwich(jd)
    deltaT_days = deltaT_seconds(jd) / seconds_per_day

    cosH0 = (sin(h0) - sin(latitude) * sin(decList[1])) / (cos(latitude) *
                                                           cos(decList[1]))
    #
    # future: return some indicator when the object is circumpolar or always
    # below the horizon.
    #
    if cosH0 < -1.0:  # circumpolar
        return None
    if cosH0 > 1.0:  # never rises
        return None

    H0 = acos(cosH0)
    m0 = (raList[1] + longitude - THETA0) / pi2
    m = m0 - H0 / pi2  # this is the only difference between rise() and set()
    if m < 0:
        m += 1
    elif m > 1:
        m -= 1
    if not 0 <= m <= 1:
        raise Error, "m is out of range = " + str(m)
    for bailout in range(20):
        m0 = m
        theta0 = modpi2(THETA0 + _k1 * m)
        n = m + deltaT_days
        if not -1 < n < 1:
            return None  # Bug: this is where we drop some events
        ra = interpolate_angle3(n, raList)
        dec = interpolate3(n, decList)
        H = theta0 - longitude - ra
        #        if H > pi:
        #            H = H - pi2
        H = diff_angle(0.0, H)
        A, h = equ_to_horiz(H, dec)
        dm = (h - h0) / (pi2 * cos(dec) * cos(latitude) * sin(H))
        m += dm
        if abs(m - m0) < delta:
            return jd + m

    raise Error, "bailout"
コード例 #9
0
ファイル: planets.py プロジェクト: webplate/astrini
def geocentric_planet(jd, planet, deltaPsi, epsilon, delta):
    """Calculate the equatorial coordinates of a planet

    The results will be geocentric, corrected for light-time and
    aberration.

    Arguments:
      - `jd`       : Julian Day in dynamical time
      - `planet`   : must be one of ("Mercury", "Venus", "Earth", "Mars",
        "Jupiter", "Saturn", "Uranus", "Neptune")
      - `deltaPsi` : nutation in longitude, in radians
      - `epsilon`  : True obliquity (corrected for nutation), in radians
      - `delta`    : desired accuracy, in days

    Returns:
      - right accension, in radians
      - declination, in radians

    """
    jd = np.atleast_1d(jd)
    vsop = VSOP87d()
    t = jd
    l0 = -100.0  # impossible value
    # We need to iterate to correct for light-time and aberration.
    # At most three passes through the loop always nails it.
    # Note that we move both the Earth and the other planet during
    #    the iteration.
    for bailout in range(20):
        # heliocentric geometric ecliptic coordinates of the Earth
        L0, B0, R0 = vsop.dimension3(t, "Earth")

        # heliocentric geometric ecliptic coordinates of the planet
        L, B, R = vsop.dimension3(t, planet)

        # rectangular offset
        cosB0 = np.cos(B0)
        cosB = np.cos(B)
        x = R * cosB * np.cos(L) - R0 * cosB0 * np.cos(L0)
        y = R * cosB * np.sin(L) - R0 * cosB0 * np.sin(L0)
        z = R * np.sin(B) - R0 * np.sin(B0)

        # geocentric geometric ecliptic coordinates of the planet
        x2 = x * x
        y2 = y * y
        l = np.arctan2(y, x)
        b = np.arctan2(z, np.sqrt(x2 + y2))

        # distance to planet in AU
        dist = np.sqrt(x2 + y2 + z * z)

        # light time in days
        tau = 0.0057755183 * dist

        if abs(diff_angle(l, l0)) < pi2 * delta:
            break

        # adjust for light travel time and try again
        l0 = l
        t = jd - tau
    else:
        raise Error("bailout")

    # transform to FK5 ecliptic and equinox
    l, b = vsop_to_fk5(jd, l, b)

    # nutation in longitude
    l = l + deltaPsi

    # equatorial coordinates
    ra, dec = ecl_to_equ(l, b, epsilon)

    return ra, dec