예제 #1
0
def hcrs_to_hgs(hcrscoord, hgsframe):
    """
    Convert from HCRS to Heliographic Stonyhurst (HGS).

    HGS shares the same origin (the Sun) as HCRS, but has its Z axis aligned with the Sun's
    rotation axis and its X axis aligned with the projection of the Sun-Earth vector onto the Sun's
    equatorial plane (i.e., the component of the Sun-Earth vector perpendicular to the Z axis).
    Thus, the transformation matrix is the product of the matrix to align the Z axis (by de-tilting
    the Sun's rotation axis) and the matrix to align the X axis.  The first matrix is independent
    of time and is pre-computed, while the second matrix depends on the time-varying Sun-Earth
    vector.
    """
    if hgsframe.obstime is None:
        raise ValueError("To perform this transformation the coordinate"
                         " Frame needs an obstime Attribute")

    # Determine the Sun-Earth vector in ICRS
    # Since HCRS is ICRS with an origin shift, this is also the Sun-Earth vector in HCRS
    sun_pos_icrs = get_body_barycentric('sun', hgsframe.obstime)
    earth_pos_icrs = get_body_barycentric('earth', hgsframe.obstime)
    sun_earth = earth_pos_icrs - sun_pos_icrs

    # De-tilt the Sun-Earth vector to the frame with the Sun's rotation axis parallel to the Z axis
    sun_earth_detilt = sun_earth.transform(_SUN_DETILT_MATRIX)

    # Remove the component of the Sun-Earth vector that is parallel to the Sun's north pole
    hgs_x_axis_detilt = CartesianRepresentation(sun_earth_detilt.xyz * [1, 1, 0])

    # The above vector, which is in the Sun's equatorial plane, is also the X axis of HGS
    x_axis = CartesianRepresentation(1, 0, 0)
    rot_matrix = _make_rotation_matrix_from_reprs(hgs_x_axis_detilt, x_axis)

    return matrix_product(rot_matrix, _SUN_DETILT_MATRIX)
예제 #2
0
def _sun_earth_icrf(time):
    """
    Return the Sun-Earth vector for ICRF-based frames.
    """
    sun_pos_icrs = get_body_barycentric('sun', time)
    earth_pos_icrs = get_body_barycentric('earth', time)
    return earth_pos_icrs - sun_pos_icrs
예제 #3
0
def hcrs_to_hgs(hcrscoord, hgsframe):
    """
    Convert from HCRS to Heliographic Stonyhurst (HGS).

    HGS shares the same origin (the Sun) as HCRS, but has its Z axis aligned with the Sun's
    rotation axis and its X axis aligned with the projection of the Sun-Earth vector onto the Sun's
    equatorial plane (i.e., the component of the Sun-Earth vector perpendicular to the Z axis).
    Thus, the transformation matrix is the product of the matrix to align the Z axis (by de-tilting
    the Sun's rotation axis) and the matrix to align the X axis.  The first matrix is independent
    of time and is pre-computed, while the second matrix depends on the time-varying Sun-Earth
    vector.
    """
    if hgsframe.obstime is None:
        raise ValueError("To perform this transformation the coordinate"
                         " Frame needs an obstime Attribute")

    # Determine the Sun-Earth vector in ICRS
    # Since HCRS is ICRS with an origin shift, this is also the Sun-Earth vector in HCRS
    sun_pos_icrs = get_body_barycentric('sun', hgsframe.obstime)
    earth_pos_icrs = get_body_barycentric('earth', hgsframe.obstime)
    sun_earth = earth_pos_icrs - sun_pos_icrs

    # De-tilt the Sun-Earth vector to the frame with the Sun's rotation axis parallel to the Z axis
    sun_earth_detilt = sun_earth.transform(_SUN_DETILT_MATRIX)

    # Remove the component of the Sun-Earth vector that is parallel to the Sun's north pole
    hgs_x_axis_detilt = CartesianRepresentation(sun_earth_detilt.xyz *
                                                [1, 1, 0])

    # The above vector, which is in the Sun's equatorial plane, is also the X axis of HGS
    x_axis = CartesianRepresentation(1, 0, 0)
    rot_matrix = _make_rotation_matrix_from_reprs(hgs_x_axis_detilt, x_axis)

    return matrix_product(rot_matrix, _SUN_DETILT_MATRIX)
예제 #4
0
def get_body_heliographic_stonyhurst(body, time='now', observer=None):
    """
    Return a `~sunpy.coordinates.frames.HeliographicStonyhurst` frame for the location of a
    solar-system body at a specified time.  The location can be corrected for light travel time
    to an observer.

    Parameters
    ----------
    body : `str`
        The solar-system body for which to calculate positions
    time : {parse_time_types}
        Time to use in a parse_time-compatible format
    observer : `~astropy.coordinates.SkyCoord`
        If None, the returned coordinate is the instantaneous or "true" location.
        If not None, the returned coordinate is the astrometric location (i.e., accounts for light
        travel time to the specified observer)

    Returns
    -------
    out : `~sunpy.coordinates.frames.HeliographicStonyhurst`
        Location of the solar-system body in the `~sunpy.coordinates.HeliographicStonyhurst` frame

    Notes
    -----
    There is no correction for aberration due to observer motion.  For a body close to the Sun in
    angular direction relative to the observer, the correction can be negligible because the
    apparent location of the body will shift in tandem with the Sun.
    """
    obstime = parse_time(time)

    if observer is None:
        body_icrs = get_body_barycentric(body, obstime)
    else:
        observer_icrs = SkyCoord(observer).icrs.cartesian

        # This implementation is modeled after Astropy's `_get_apparent_body_position`
        light_travel_time = 0. * u.s
        emitted_time = obstime
        delta_light_travel_time = 1. * u.s  # placeholder value
        while np.any(np.fabs(delta_light_travel_time) > 1.0e-8 * u.s):
            body_icrs = get_body_barycentric(body, emitted_time)
            distance = (body_icrs - observer_icrs).norm()
            delta_light_travel_time = light_travel_time - distance / speed_of_light
            light_travel_time = distance / speed_of_light
            emitted_time = obstime - light_travel_time

        if light_travel_time.isscalar:
            ltt_string = f"{light_travel_time.to_value('s'):.2f}"
        else:
            ltt_string = f"{light_travel_time.to_value('s')}"
        log.info(
            f"Apparent body location accounts for {ltt_string} seconds of light travel time"
        )

    body_hgs = ICRS(body_icrs).transform_to(
        HeliographicStonyhurst(obstime=obstime))

    return body_hgs
예제 #5
0
def hcrs_to_hgs(hcrscoord, hgsframe):
    """
    Convert from HCRS to Heliographic Stonyhurst (HGS).

    HGS shares the same origin (the Sun) as HCRS, but has its Z axis aligned with the Sun's
    rotation axis and its X axis aligned with the projection of the Sun-Earth vector onto the Sun's
    equatorial plane (i.e., the component of the Sun-Earth vector perpendicular to the Z axis).
    Thus, the transformation matrix is the product of the matrix to align the Z axis (by de-tilting
    the Sun's rotation axis) and the matrix to align the X axis.  The first matrix is independent
    of time and is pre-computed, while the second matrix depends on the time-varying Sun-Earth
    vector.
    """
    if hgsframe.obstime is None:
        raise ValueError("To perform this transformation the coordinate"
                         " Frame needs an obstime Attribute")

    # Check whether differentials are involved on either end
    has_differentials = (
        (hcrscoord._data is not None and hcrscoord.data.differentials)
        or (hgsframe._data is not None and hgsframe.data.differentials))

    # Determine the Sun-Earth vector in ICRS
    # Since HCRS is ICRS with an origin shift, this is also the Sun-Earth vector in HCRS
    # If differentials exist, also obtain Sun and Earth velocities
    if has_differentials:
        sun_pos_icrs, sun_vel = get_body_barycentric_posvel(
            'sun', hgsframe.obstime)
        earth_pos_icrs, earth_vel = get_body_barycentric_posvel(
            'earth', hgsframe.obstime)
    else:
        sun_pos_icrs = get_body_barycentric('sun', hgsframe.obstime)
        earth_pos_icrs = get_body_barycentric('earth', hgsframe.obstime)
    sun_earth = earth_pos_icrs - sun_pos_icrs

    # De-tilt the Sun-Earth vector to the frame with the Sun's rotation axis parallel to the Z axis
    sun_earth_detilt = sun_earth.transform(_SUN_DETILT_MATRIX)

    # Rotate the Sun-Earth vector about the Z axis so that it lies in the XZ plane
    rot_matrix = _rotation_matrix_reprs_to_xz_about_z(sun_earth_detilt)

    total_matrix = rot_matrix @ _SUN_DETILT_MATRIX

    # All of the above is calculated for the HGS observation time
    # If the HCRS observation time is different, calculate the translation in origin
    if not _ignore_sun_motion and np.any(
            hcrscoord.obstime != hgsframe.obstime):
        sun_pos_old_icrs = get_body_barycentric('sun', hcrscoord.obstime)
        offset_icrf = sun_pos_icrs - sun_pos_old_icrs
    else:
        offset_icrf = sun_pos_icrs * 0  # preserves obstime shape

    # Add velocity if needed (at the HGS observation time)
    if has_differentials:
        vel_icrf = (sun_vel - earth_vel).represent_as(CartesianDifferential)
        offset_icrf = offset_icrf.with_differentials(vel_icrf)

    offset = offset_icrf.transform(total_matrix)
    return total_matrix, offset
예제 #6
0
def calculate_trip(depart, arrive, date):

    t = Time(date)
    solar_system_ephemeris.set('builtin')
    start = get_body_barycentric(depart, t)
    end = get_body_barycentric(arrive, t)

    distance = ((start.x - end.x)**2 + (start.y - end.y)**2 + (start.z - end.z)**2)**(1/2)
    return distance.to(u.km)
예제 #7
0
파일: ephemeris.py 프로젝트: PritishC/sunpy
def get_body_heliographic_stonyhurst(body, time='now', observer=None):
    """
    Return a `~sunpy.coordinates.frames.HeliographicStonyhurst` frame for the location of a
    solar-system body at a specified time.  The location can be corrected for light travel time
    to an observer.

    Parameters
    ----------
    body : `str`
        The solar-system body for which to calculate positions
    time : various
        Time to use as `~astropy.time.Time` or in a parse_time-compatible format
    observer : `~astropy.coordinates.SkyCoord`
        If None, the returned coordinate is the instantaneous or "true" location.
        If not None, the returned coordinate is the astrometric location (i.e., accounts for light
        travel time to the specified observer)

    Returns
    -------
    out : `~sunpy.coordinates.frames.HeliographicStonyhurst`
        Location of the solar-system body in the `~sunpy.coordinates.HeliographicStonyhurst` frame

    Notes
    -----
    There is no correction for aberration due to observer motion.  For a body close to the Sun in
    angular direction relative to the observer, the correction can be negligible because the
    apparent location of the body will shift in tandem with the Sun.
    """
    obstime = parse_time(time)

    if observer is None:
        body_icrs = get_body_barycentric(body, obstime)
    else:
        observer_icrs = SkyCoord(observer).icrs.cartesian

        # This implementation is modeled after Astropy's `_get_apparent_body_position`
        light_travel_time = 0.*u.s
        emitted_time = obstime
        delta_light_travel_time = 1.*u.s  # placeholder value
        while np.any(np.fabs(delta_light_travel_time) > 1.0e-8*u.s):
            body_icrs = get_body_barycentric(body, emitted_time)
            distance = (body_icrs - observer_icrs).norm()
            delta_light_travel_time = light_travel_time - distance / speed_of_light
            light_travel_time = distance / speed_of_light
            emitted_time = obstime - light_travel_time

        log.info(f"Apparent body location accounts for {light_travel_time.to('s').value:.2f}"
                  " seconds of light travel time")

    body_hgs = ICRS(body_icrs).transform_to(HGS(obstime=obstime))

    return body_hgs
예제 #8
0
def computeItteration(t):
    print(t)
    earth = get_body_barycentric('earth', t)
    ex.append(earth.x / u.km)
    ey.append(earth.y / u.km)

    moon = get_body_barycentric('moon', t)
    mx.append(moon.x / u.km)
    my.append(moon.y / u.km)

    sun = get_body_barycentric('sun', t)
    sx.append(sun.x / u.km)
    sy.append(sun.y / u.km)
예제 #9
0
def speed(planet, t1):
    dt = 1 * u.s
    t2 = t1 + dt

    c1 = SkyCoord(get_body_barycentric(planet, t1)).cartesian
    c2 = SkyCoord(get_body_barycentric(planet, t2)).cartesian

    vx = (c2.x.to('m') - c1.x.to('m')) / dt
    vy = (c2.y.to('m') - c1.y.to('m')) / dt
    vz = (c2.z.to('m') - c1.z.to('m')) / dt

    speed = np.sqrt(vx**2 + vy**2 + vz**2)
    return speed
예제 #10
0
파일: frames.py 프로젝트: egemenimre/satmad
def icrs_to_cb_crs(icrs_coord, cb_crs_frame):
    """Conversion from ICRS to Celestial Reference System of a Central Body."""

    if not u.m.is_equivalent(icrs_coord.cartesian.x.unit):
        raise u.UnitsError(
            _NEED_ORIGIN_HINT.format(icrs_coord.__class__.__name__))

    if icrs_coord.data.differentials:
        # Calculate the barycentric position and velocity (of a solar system body).
        # Uses default ephemeris
        r_icrs, v_icrs = get_body_barycentric_posvel(
            cb_crs_frame.body_name,
            cb_crs_frame.obstime,
            ephemeris=cb_crs_frame.ephemeris_type,
        )

        v_icrs = CartesianDifferential.from_cartesian(v_icrs)

        # Prepare final coord vector with velocity
        cb_crs_coord = (-r_icrs).with_differentials(-v_icrs)
    else:
        # Calculate the barycentric position ONLY (of a solar system body).
        # Uses default ephemeris. This is faster than the one above with velocities for
        # JPL ephemerides.
        cb_crs_coord = -get_body_barycentric(
            cb_crs_frame.body_name,
            cb_crs_frame.obstime,
            ephemeris=cb_crs_frame.ephemeris_type,
        )

    # Return transformation matrix (None) and translation vector (with velocities)
    return None, cb_crs_coord
예제 #11
0
def test_coord_get():

    # Test default (instance=None)
    obs = Helioprojective.observer
    assert obs is "earth"

    # Test get
    obstime = "2013-04-01"
    obs = Helioprojective(observer="earth", obstime=obstime).observer
    earth = get_earth(obstime)
    assert isinstance(obs, HeliographicStonyhurst)
    assert_quantity_allclose(obs.lon, earth.lon)
    assert_quantity_allclose(obs.lat, earth.lat)
    assert_quantity_allclose(obs.radius, earth.radius)

    # Test get
    obstime = "2013-04-01"
    obs = Helioprojective(obstime=obstime).observer
    earth = get_earth(obstime)
    assert isinstance(obs, HeliographicStonyhurst)
    assert_quantity_allclose(obs.lon, earth.lon)
    assert_quantity_allclose(obs.lat, earth.lat)
    assert_quantity_allclose(obs.radius, earth.radius)

    # Test get mars
    obstime = Time(parse_time("2013-04-01"))
    obs = Helioprojective(observer="mars", obstime=obstime).observer
    out_icrs = ICRS(get_body_barycentric("mars", obstime))
    mars = out_icrs.transform_to(HeliographicStonyhurst(obstime=obstime))

    assert isinstance(obs, HeliographicStonyhurst)
    assert_quantity_allclose(obs.lon, mars.lon)
    assert_quantity_allclose(obs.lat, mars.lat)
    assert_quantity_allclose(obs.radius, mars.radius)
예제 #12
0
def earth_ephemeris(t):
    """
    Calculate the ephemeris for the earth in the BCRS using astropy tools.
    
    NOTE: There are several versions of the solar system ephemeris available in astropy and others can be
    provided through a URL (see the documentation of astropy.coordinates.solar_system_ephemeris).
    Depending on the accuracy needed, employing  an ephemeris different from the default may be better.

    Parameters
    ----------
    
    t : array
        Barycentric Julian Year times at which to calculate the ephemeris.
        
    Returns
    -------

    Array of shape (3,t.size) representing the xyz components of the ephemeris at times t.

    Note: the units of angle should be radians and the units of time Julian years ('jyear'),
    while the distance unit is the AU.
    """
    times = Time(t, format='jyear', scale='tcb')  # 'tcb': Barycentric Coordinate Time (TCB)
    ephemeris = get_body_barycentric('earth', times)  # unit A.U.
    return np.vstack((ephemeris.x.value, ephemeris.y.value, ephemeris.z.value))
예제 #13
0
    def AstrometryFunc0(x, Delta1, Delta2, PMra, PMdec, pi):

        ras, decs, mjds = x
        years = (mjds - mjds[0]) * d2y

        bary0 = coords.get_body_barycentric('earth', Time(mjds, format='mjd'))

        if JPL:
            bary = bary0 / 1.496e8
        else:
            bary = bary0

        # Parallax factors
        Fac1 = (bary.x * np.sin(ras / d2a * np.pi / 180.) -
                bary.y * np.cos(ras / d2a * np.pi / 180.))
        Fac2 = bary.x * np.cos(ras/d2a *np.pi/180.) * np.sin(decs/d2a *np.pi/180.) + \
               bary.y * np.sin(ras/d2a *np.pi/180.) * np.sin(decs/d2a *np.pi/180.) - \
               bary.z * np.cos(decs/d2a *np.pi/180.)

        RAsend = Delta1 + PMra * years + pi * Fac1.value
        DECsend = Delta2 + PMdec * years + pi * Fac2.value

        if RA == True and DEC == False:
            return RAsend
        elif RA == False and DEC == True:
            return DECsend
        else:
            return np.concatenate([RAsend, DECsend]).flatten()
예제 #14
0
def roemer_delay(epoch, ecl_latitude, ecl_longitude, ephemeris='de432s'):
    """
    Computes the Roemer timing delay about the Solar System Barycentre at the 
    position the Earth, given a set of ecliptic coordinates for a given pulsar.

    Parameters
    ----------
    epoch : array_like, float 
        observation timestamp(s) where delay is evaluated, in MJD format.

    ecl_longitudeatitude : float 
        ecliptic latitude, in units of degrees.

    ecl_longitude = : float
        ecliptic longitude, in units of degrees.

    Returns
    -------
    delay: array_like, float
        time delay due to orbital motion of the Earth, in seconds.
    """

    # before computing anythin, set the ephemeris context to be value
    # supplied at the function call.
    solar_system_ephemeris.set(ephemeris)
    time = Time(epoch, format='mjd')

    # now comoute the required position vectors.
    r_earth = get_body_barycentric('earth', time)
    s_pulsar = pulsar_position_ecliptic(ecl_latitude, ecl_longitude)

    # finally, compute and return the delay.
    delay = r_earth.dot(s_pulsar).to(u.m) / c

    return delay
예제 #15
0
def astrometryfunc(x, Delta1, Delta2, PMra, PMdec, pi):
    """ Compute proper motion and parallax model for a set of ra/dec/mjd values."""
    # x: input list of central RA and DEC positions and array of MJDs
    # Delta1: initial dRA position
    # Delta2: initial dDEC position
    # PMra: proper motion in RA (arcsec/yr)
    # PMdec: proper motion in DEC (arcsec/yr)
    # pi: parallax (arcsec)

    ra0, dec0, mjds = x
    n = len(mjds)
    years = (mjds - mjds[0]) * d2y
    ras = np.zeros(n, np.float64) + ra0
    decs = np.zeros(n, np.float64) + dec0

    bary = coords.get_body_barycentric('earth', Time(mjds, format='mjd'))

    # Parallax factors
    Fac1 = (bary.x * np.sin(ras * np.pi / 180.) -
            bary.y * np.cos(ras * np.pi / 180.))
    Fac2 = bary.x * np.cos(ras*np.pi/180.) * np.sin(decs*np.pi/180.) + \
           bary.y * np.sin(ras*np.pi/180.) * np.sin(decs*np.pi/180.) - \
           bary.z * np.cos(decs*np.pi/180.)

    RAsend = Delta1 + PMra * years + pi * Fac1.value
    DECsend = Delta2 + PMdec * years + pi * Fac2.value

    return np.concatenate([RAsend, DECsend]).flatten()
예제 #16
0
def plot_solar_system(time, num_of_bodies=9, r_body=None):
    '''Plots the solar system in the x-y ecliptic frame, at a specified time.
        Inputs:
            time: astropy.Time object to get planetary positions
            num-of-planets:
        '''
    plt.style.use('dark_background')

    for i in range(num_of_bodies):
        position_eq = get_body_barycentric(bodies[i], time).get_xyz().value
        [x, y, z] = eq_to_ecl(position_eq)
        plt.plot(x, y, color=body_colors[bodies[i]], marker='o')
        plt.annotate(bodies[i][0].upper(), (x + .05, y))

    max_distance = (x**2 + y**2)**.5
    if not (r_body is None):
        r_au = r_body.get_xyz().to(u.au).value
        [x, y, z] = eq_to_ecl(r_au)
        print(x, y, z)
        plt.plot(x, y, color='r', marker='x')
        max_distance = max(max_distance, (x**2 + y**2))

    axis_distance = max_distance * 1.1
    plt.axis((-axis_distance, axis_distance, -axis_distance, axis_distance))
    plt.xlabel("x (AU)")
    plt.ylabel("y (AU)")
    plt.show()
예제 #17
0
def get_2d_positions(time):
    #time_now = Time(datetime.datetime.utcnow(), scale='utc')
    positions=[]
    body_ignore=['earth-moon-barycenter','moon','pluto']
    for body in solar_system_ephemeris.bodies:
        if body in body_ignore:
            continue
        pos = get_body_barycentric(body, time).xyz.to(u.au)
        positions.append(pos.value)

    positions=np.array(positions)

    points = np.transpose(positions-centroid(positions))
    normal = svd_plane_normal(points)

    a = normal
    b = np.array([1,0,plane((1,0),normal)])
    c = b/np.linalg.norm(b)
    b = np.cross(a,b)

    coord_transform = np.vstack([c,b,a])

    new_points = []
    for row in np.transpose(points):
        new_points.append(np.dot(coord_transform,row+centroid(positions)))

    new_points = np.array(new_points)

    return new_points
예제 #18
0
def test_coord_get():

    # Test default (instance=None)
    obs = Helioprojective.observer
    assert obs is "earth"

    # Test get
    obstime = "2013-04-01"
    obs = Helioprojective(observer="earth", obstime=obstime).observer
    earth = get_earth(obstime)
    assert isinstance(obs, HeliographicStonyhurst)
    assert_quantity_allclose(obs.lon, earth.lon)
    assert_quantity_allclose(obs.lat, earth.lat)
    assert_quantity_allclose(obs.radius, earth.radius)

    # Test get
    obstime = "2013-04-01"
    obs = Helioprojective(obstime=obstime).observer
    earth = get_earth(obstime)
    assert isinstance(obs, HeliographicStonyhurst)
    assert_quantity_allclose(obs.lon, earth.lon)
    assert_quantity_allclose(obs.lat, earth.lat)
    assert_quantity_allclose(obs.radius, earth.radius)

    # Test get mars
    obstime = Time(parse_time("2013-04-01"))
    obs = Helioprojective(observer="mars", obstime=obstime).observer
    out_icrs = ICRS(get_body_barycentric("mars", obstime))
    mars = out_icrs.transform_to(HeliographicStonyhurst(obstime=obstime))

    assert isinstance(obs, HeliographicStonyhurst)
    assert_quantity_allclose(obs.lon, mars.lon)
    assert_quantity_allclose(obs.lat, mars.lat)
    assert_quantity_allclose(obs.radius, mars.radius)
예제 #19
0
def test_hcrs_hgs_array_obstime():
    # Get the Earth location in HCRS at two times
    times = Time(['2017-01-01', '2017-06-01'])
    earth_hcrs = SkyCoord(get_body_barycentric('earth', times),
                          frame='icrs',
                          obstime=times).hcrs

    # Transform each time in separate calls (uses scalar obstime)
    earth_hgs_0 = earth_hcrs[0].transform_to(HeliographicStonyhurst)
    earth_hgs_1 = earth_hcrs[1].transform_to(HeliographicStonyhurst)

    # Transform both times in one call (uses array obstime)
    earth_hgs = earth_hcrs.transform_to(HeliographicStonyhurst)

    # Confirm that the two approaches produce the same results
    assert quantity_allclose(earth_hgs_0.lon,
                             earth_hgs[0].lon,
                             atol=1e-12 * u.deg)
    assert quantity_allclose(earth_hgs_0.lat, earth_hgs[0].lat, rtol=1e-10)
    assert quantity_allclose(earth_hgs_0.radius,
                             earth_hgs[0].radius,
                             rtol=1e-10)
    assert quantity_allclose(earth_hgs_1.lon,
                             earth_hgs[1].lon,
                             atol=1e-12 * u.deg)
    assert quantity_allclose(earth_hgs_1.lat, earth_hgs[1].lat, rtol=1e-10)
    assert quantity_allclose(earth_hgs_1.radius,
                             earth_hgs[1].radius,
                             rtol=1e-10)
예제 #20
0
    def _get_delta_annual(self):
        """
        calculates projected Earth positions required by annual parallax
        """
        index = (self.parameters.t_0_par, self.coords.ra.value,
                 self.coords.dec.value, tuple(self.times.tolist()))
        if index == Trajectory._get_delta_annual_last_index:
            return Trajectory._get_delta_annual_last
        if index in Trajectory._get_delta_annual_results:
            return Trajectory._get_delta_annual_results[index]
        time_ref = self.parameters.t_0_par

        velocity = utils.Utils.velocity_of_Earth(time_ref) / 1731.45683
        # We change units from km/s to AU/d.

        if not np.all(np.isfinite(self.times)):
            msg = "Some times have incorrect values: {:}".format(
                self.times[~np.isfinite(self.times)])
            raise ValueError(msg)

        position = get_body_barycentric(body='earth',
                                        time=Time(self.times,
                                                  format='jd',
                                                  scale='tdb'))
        position_ref = get_body_barycentric(body='earth',
                                            time=Time(time_ref,
                                                      format='jd',
                                                      scale='tdb'))
        # Seems that get_body_barycentric depends on time system, but there is
        # no way to set BJD part of BJD_TDB in astropy.Time(). The option
        # *format* above indicates if the first argument of Time() is
        # a float indicating JD or e.g., a string in the form
        # '1999-01-01T00:00:00.123' - this would be value 'fits'.
        # Hence, the user has to provide BJD times (or at least HJD).

        # Main calculation is in 2 lines below:
        delta_s = (position_ref.xyz.T - position.xyz.T).to(u.au).value
        delta_s += np.outer(self.times - time_ref, velocity)
        # and the results require projecting on the plane of the sky:
        out_n = np.dot(delta_s, self.coords.north_projected)
        out_e = np.dot(delta_s, self.coords.east_projected)

        out = {'N': out_n, 'E': out_e}
        Trajectory._get_delta_annual_results[index] = out
        Trajectory._get_delta_annual_last_index = index + tuple()
        Trajectory._get_delta_annual_last = out
        return out
예제 #21
0
def test_icrs_body_position_to_planetary_frame_yields_zeros(body, frame):
    with solar_system_ephemeris.set("builtin"):
        epoch = J2000
        vector = get_body_barycentric(body.name, epoch)

        vector_result = ICRS(vector).transform_to(frame(obstime=epoch)).represent_as(CartesianRepresentation)

    assert_quantity_allclose(vector_result.xyz, [0, 0, 0] * u.km, atol=1e-7 * u.km)
예제 #22
0
파일: app.py 프로젝트: cortex-labs/sol
def tick():
    count = 0

    while True:
        t = Time.now() + TimeDelta(86400 * count, format='sec')

        mercury = get_body_barycentric('Mercury', t)
        venus = get_body_barycentric('Venus', t)
        earth = get_body_barycentric('Earth', t)
        mars = get_body_barycentric('Mars', t)
        jupiter = get_body_barycentric('Jupiter', t)

        socketio.emit(
            'tick', {
                'mercury': {
                    'x': round(mercury.x.value / SCALE, 2),
                    'y': round(mercury.y.value / SCALE, 2),
                    'z': round(mercury.z.value / SCALE, 2),
                },
                'venus': {
                    'x': round(venus.x.value / SCALE, 2),
                    'y': round(venus.y.value / SCALE, 2),
                    'z': round(venus.z.value / SCALE, 2),
                },
                'earth': {
                    'x': round(earth.x.value / SCALE, 2),
                    'y': round(earth.y.value / SCALE, 2),
                    'z': round(earth.z.value / SCALE, 2),
                },
                'mars': {
                    'x': round(mars.x.value / SCALE, 2),
                    'y': round(mars.y.value / SCALE, 2),
                    'z': round(mars.z.value / SCALE, 2),
                },
                'jupiter': {
                    'x': round(jupiter.x.value / SCALE, 2),
                    'y': round(jupiter.y.value / SCALE, 2),
                    'z': round(jupiter.z.value / SCALE, 2),
                },
                't':
                str(t.to_datetime().replace(microsecond=0).isoformat()) + 'Z',
            })

        socketio.sleep(0.01)

        count += 1
예제 #23
0
def distance(position, destination, date=None):
    """Calculate the distance between two planets.

    Args:
        position: Planet the journey starts at.
        destination: Destination of the journey.
        date: Date the journey is started (defaults to current time).

    Returns:
        Distance in m.
    """

    if not date:
        date = dt.datetime.now()
    time = at.Time(date)
    return (ac.get_body_barycentric(position, time) -
            ac.get_body_barycentric(destination, time)).norm().to(au.m).value
예제 #24
0
def earth_distance(time='now'):
    """
    Return the distance between the Sun and the Earth at a specified time.

    Parameters
    ----------
    time : {parse_time_types}
        Time to use in a parse_time-compatible format

    Returns
    -------
    out : `~astropy.coordinates.Distance`
        The Sun-Earth distance
    """
    obstime = parse_time(time)
    vector = get_body_barycentric('earth', obstime) - get_body_barycentric('sun', obstime)
    return Distance(vector.norm())
예제 #25
0
def calculate_sun_earth_angles_rad(time_vector):
    """Compute the angle between the x axis and the Earth

    This function computes the angle on the plane of the Ecliptic
    (assuming to be the xy plane) between the Sun-Earth direction and
    the x axis. Depending on the type of the parameter `time_vector`,
    the result is computed differently:

    - If `time_vector` is a ``astropy.time.Time`` object, the angle is
      computed using the Barycentric Mean Ecliptic reference frame and
      the Ephemerides tables provided by AstroPy (slow but accurate)

    - Otherwise, `time_vector` is assumed to be a NumPy array of
      floats, and a simple circular motion with constant angular
      velocity is assumed. The angular velocity is
      ``YEARLY_OMEGA_SPIN_HZ``, which is equal to :math:`2π/T`, with T
      being the average duration of one year in seconds, and it is
      assumed that at time `t = 0` the angle is zero.

    """
    # This is the geometry of the problem: the Ecliptic plane is
    # supposed to be on the xy plane, with the Sun in the origin, and
    # we're looking for the angle θ in the figure:
    #
    #             ┌──────────────────────────────┐
    #           1 │⠀⠀⠀⠀⠀⠀⠀⢀⡠⠤⠒⠊⠉⠉⠉⡏⠉⠉⠉⠒⠤⢄⡀⠀⠀⠀⠀⠀⠀⠀│
    #             │⠀⠀⠀⠀⠀⡠⠊⠁⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠈⠓⢄⠀⠀⠀⠀⠀│
    #             │⠀⠀⠀⡰⠊⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⢆⠀⠀⠀│
    #             │⠀⢀⠜⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢲⡀⠀│
    #             │⢀⡎⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⣀⠔⠊⠁⢱⠀│
    #             │⡜⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⢀⡠⠒⠉⠀⠀⠀⠀⠀⢇│
    #             │⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⣀⠔⠊⠁⠀⠀θ⠀⠀⠀⠀⠀⢸│
    #   y [AU]    │⡧⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⡷⠭⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⢼│
    #             │⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇Sun⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸│
    #             │⢣⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡜│
    #             │⠈⢆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡰⠁│
    #             │⠀⠈⢢⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡴⠁⠀│
    #             │⠀⠀⠀⠱⢄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠜⠀⠀⠀│
    #             │⠀⠀⠀⠀⠀⠑⢄⡀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⢀⡤⠒⠁⠀⠀⠀⠀│
    #          -1 │⠀⠀⠀⠀⠀⠀⠀⠈⠑⠢⠤⣀⣀⣀⣀⣇⣀⣀⡠⠤⠔⠊⠁⠀⠀⠀⠀⠀⠀⠀│
    #             └──────────────────────────────┘
    #             -1                             1
    #                         x [AU]
    #
    # where of course θ points towards the Earth. The value of the
    # angle depends whether we're using proper MJD dates (in this
    # case, we need ephemeridis tables) or not: in the latter case we
    # just assume that at time 0 the angle θ is zero, and that the
    # Earth follows a uniform circular motion around the Sun with
    # frequency ω = 2πν = YEARLY_OMEGA_SPIN_HZ.

    if isinstance(time_vector, astropy.time.Time):
        pos = get_body_barycentric("earth", time_vector)
        coord = ICRS(pos).transform_to(BarycentricMeanEcliptic).cartesian
        return np.arctan2(coord.x.value, coord.y.value)
    else:
        return YEARLY_OMEGA_SPIN_HZ * time_vector
예제 #26
0
def test_planetary_icrs_frame_is_just_translation(body, frame):
    with solar_system_ephemeris.set("builtin"):
        epoch = J2000
        vector = CartesianRepresentation(x=100 * u.km, y=100 * u.km, z=100 * u.km)
        vector_result = frame(vector, obstime=epoch).transform_to(ICRS).represent_as(CartesianRepresentation)

        expected_result = get_body_barycentric(body.name, epoch) + vector

    assert_quantity_allclose(vector_result.xyz, expected_result.xyz)
예제 #27
0
 def get_barycentric(self, t, t0=None, tformat=None):
     if tformat is None:
         tformat = self.unitc.tname
     if tformat == 'jd' and t0 is None:
         t0 = 2451545  # jan 1 2000 in jd
     t_ = Time(t + t0, format=tformat)
     pos = get_body_barycentric(self.name, t_).xyz.to(
         self.unitc.dname).to_value()  # cartesian representation
     return pos
예제 #28
0
파일: scalar.py 프로젝트: s-m-e/poliastro
    def change_attractor(self, new_attractor, force=False):
        """Changes orbit attractor.

        Only changes from attractor to parent or the other way around are allowed.

        Parameters
        ----------
        new_attractor : poliastro.bodies.Body
            Desired new attractor.
        force : bool
            If `True`, changes attractor even if physically has no-sense.

        Returns
        -------
        ss: poliastro.twobody.orbit.Orbit
            Orbit with new attractor

        """
        if self.attractor == new_attractor:
            return self
        elif self.attractor == new_attractor.parent:  # "Sun -> Earth"
            r_soi = laplace_radius(new_attractor)
            barycentric_position = get_body_barycentric(new_attractor.name, self.epoch)
            # Transforming new_attractor's frame into frame of attractor
            new_attractor_r = (
                ICRS(barycentric_position)
                .transform_to(self.get_frame())
                .represent_as(CartesianRepresentation)
                .xyz
            )
            distance = norm(self.r - new_attractor_r)
        elif self.attractor.parent == new_attractor:  # "Earth -> Sun"
            r_soi = laplace_radius(self.attractor)
            distance = norm(self.r)
        else:
            raise ValueError("Cannot change to unrelated attractor")

        if distance > r_soi and not force:
            raise ValueError(
                "Orbit is out of new attractor's SOI. If required, use 'force=True'."
            )
        elif self.ecc < 1.0 and not force:
            raise ValueError("Orbit will never leave the SOI of its current attractor")
        else:
            warn(
                "Leaving the SOI of the current attractor",
                PatchedConicsWarning,
                stacklevel=2,
            )

        new_frame = get_frame(new_attractor, self.plane, obstime=self.epoch)
        coords = self.get_frame().realize_frame(
            self.represent_as(CartesianRepresentation, CartesianDifferential)
        )
        ss = Orbit.from_coords(new_attractor, coords.transform_to(new_frame))

        return ss
예제 #29
0
    def _get_delta_annual(self):
        """
        calculates projected Earth positions required by annual parallax
        """
        index = (self.parameters.t_0_par, hash(self.coords),
                 tuple(self.times.tolist()))
        if index == Trajectory._get_delta_annual_last_index:
            return Trajectory._get_delta_annual_last
        if index in Trajectory._get_delta_annual_results:
            return Trajectory._get_delta_annual_results[index]
        time_ref = self.parameters.t_0_par

        velocity = utils.Utils.velocity_of_Earth(time_ref) / 1731.45683
        # We change units from km/s to AU/d.

        if not np.all(np.isfinite(self.times)):
            msg = "Some times have incorrect values: {:}".format(
                self.times[~np.isfinite(self.times)])
            raise ValueError(msg)

        position = get_body_barycentric(body='earth',
                                        time=Time(self.times,
                                                  format='jd',
                                                  scale='tdb'))
        position_ref = get_body_barycentric(body='earth',
                                            time=Time(time_ref,
                                                      format='jd',
                                                      scale='tdb'))
        # Seems that get_body_barycentric depends on time system, but there is
        # no way to set BJD_TDB in astropy.Time().
        # Likewise, get_jd12 depends on time system.

        # Main calculation is in 2 lines below:
        delta_s = (position_ref.xyz.T - position.xyz.T).to(u.au).value
        delta_s += np.outer(self.times - time_ref, velocity)
        # and the results require projecting on the plane of the sky:
        out_n = np.dot(delta_s, self.coords.north_projected)
        out_e = np.dot(delta_s, self.coords.east_projected)

        out = {'N': out_n, 'E': out_e}
        Trajectory._get_delta_annual_results[index] = out
        Trajectory._get_delta_annual_last_index = index + tuple()
        Trajectory._get_delta_annual_last = out
        return out
예제 #30
0
def get_body_heliographic_stonyhurst(body, time='now', observer=None):
    """
    Return a `~sunpy.coordinates.frames.HeliographicStonyhurst` frame for the location of a
    solar-system body at a specified time.

    Parameters
    ----------
    body : `str`
        The solar-system body for which to calculate positions
    time : various
        Time to use as `~astropy.time.Time` or in a parse_time-compatible format
    observer : `~astropy.coordinates.SkyCoord`
        If not None, the returned coordinate is the apparent location (i.e., accounts for light
        travel time)

    Returns
    -------
    out : `~sunpy.coordinates.frames.HeliographicStonyhurst`
        Location of the solar-system body in the `~sunpy.coordinates.HeliographicStonyhurst` frame
    """
    obstime = parse_time(time)

    if observer is None:
        body_icrs = get_body_barycentric(body, obstime)
    else:
        observer_icrs = SkyCoord(observer).icrs.cartesian

        # This implementation is modeled after Astropy's `_get_apparent_body_position`
        light_travel_time = 0.*u.s
        emitted_time = obstime
        delta_light_travel_time = 1.*u.s  # placeholder value
        while np.any(np.fabs(delta_light_travel_time) > 1.0e-8*u.s):
            body_icrs = get_body_barycentric(body, emitted_time)
            distance = (body_icrs - observer_icrs).norm()
            delta_light_travel_time = light_travel_time - distance / speed_of_light
            light_travel_time = distance / speed_of_light
            emitted_time = obstime - light_travel_time

        log.info(f"Apparent body location accounts for {light_travel_time.to('s').value:.2f}"
                  " seconds of light travel time")

    body_hgs = ICRS(body_icrs).transform_to(HGS(obstime=obstime))

    return body_hgs
예제 #31
0
파일: utils.py 프로젝트: leigh2/dipfitter
def get_R(mjd):
    # R is the position vector of Earth
    # requires an mjd (or array of)
    # returns R, a three component array describing the position vector of Earth
    # in au
    R = get_body_barycentric('earth', Time(mjd, format='mjd', scale='tcb'))
    return np.array(
        [R.x.to(u.AU) / u.AU,
         R.y.to(u.AU) / u.AU,
         R.z.to(u.AU) / u.AU]).T
예제 #32
0
def test_icrs_body_position_to_planetary_frame_yields_zeros(body, frame):
    with solar_system_ephemeris.set("builtin"):
        epoch = J2000
        vector = get_body_barycentric(body.name, epoch)

        vector_result = (ICRS(vector).transform_to(
            frame(obstime=epoch)).represent_as(CartesianRepresentation))

    assert_quantity_allclose(vector_result.xyz, [0, 0, 0] * u.km,
                             atol=1e-7 * u.km)
예제 #33
0
파일: frames.py 프로젝트: tadeu/poliastro
def _ecliptic_to_icrs(from_coo, to_frame):
    # first un-precess from ecliptic to ICRS orientation
    rmat = _ecliptic_rotation_matrix()
    intermed_repr = from_coo.cartesian.transform(matrix_transpose(rmat))

    # now offset back to barycentric, which is the correct center for ICRS
    # get barycentric sun coordinate
    bary_sun_pos = get_body_barycentric("sun", from_coo.obstime)

    newrepr = intermed_repr + bary_sun_pos
    return to_frame.realize_frame(newrepr)
예제 #34
0
def _ecliptic_to_icrs(from_coo, to_frame):
    # first un-precess from ecliptic to ICRS orientation
    rmat = _ecliptic_rotation_matrix()
    intermed_repr = from_coo.cartesian.transform(matrix_transpose(rmat))

    # now offset back to barycentric, which is the correct center for ICRS
    # get barycentric sun coordinate
    bary_sun_pos = get_body_barycentric("sun", from_coo.obstime)

    newrepr = intermed_repr + bary_sun_pos
    return to_frame.realize_frame(newrepr)
예제 #35
0
def _icrs_to_ecliptic(from_coo, to_frame):
    # get barycentric sun coordinate
    bary_sun_pos = get_body_barycentric("sun", to_frame.obstime)

    # offset to heliocentric
    heliocart = from_coo.cartesian - bary_sun_pos

    # now compute the matrix to precess to the right orientation
    rmat = _ecliptic_rotation_matrix()

    newrepr = heliocart.transform(rmat)
    return to_frame.realize_frame(newrepr)
예제 #36
0
파일: frames.py 프로젝트: tadeu/poliastro
def _icrs_to_ecliptic(from_coo, to_frame):
    # get barycentric sun coordinate
    bary_sun_pos = get_body_barycentric("sun", to_frame.obstime)

    # offset to heliocentric
    heliocart = from_coo.cartesian - bary_sun_pos

    # now compute the matrix to precess to the right orientation
    rmat = _ecliptic_rotation_matrix()

    newrepr = heliocart.transform(rmat)
    return to_frame.realize_frame(newrepr)
예제 #37
0
 def plot_moon(self, t, satellite):
     clock = satellite.clock
     time_utc = clock.met_to_utc(t)
     earth_r = get_body_barycentric('earth', time_utc)
     moon_r = get_body_barycentric('moon', time_utc)
     r_e_m = moon_r - earth_r
     e = satellite.get_pos(t)
     r = -e * satellite.pos_unit - np.array(
         [r_e_m.x.value, r_e_m.y.value, r_e_m.z.value]) * u.km
     moon_point_d = cartesian_to_spherical(-r[0], -r[1], -r[2])
     self.plot(moon_point_d[2].deg,
               moon_point_d[1].deg,
               'o',
               color='#72777b',
               markersize=1.5 * self.size)
     self.text(moon_point_d[2].deg,
               moon_point_d[1].deg,
               'moon',
               size=self.size,
               va='center',
               ha='center')
예제 #38
0
def objPosVel2SSB(objname, t, ephem):
    """This function computes a solar system object position and velocity respect
    to solar system barycenter using astropy coordinates get_body_barycentric()
    method.
    Parameters
    ----------
    objname: str
        Solar system object name. Current support solar system bodies are listed in
        astropy.coordinates.olar_system_ephemeris.bodies attribution.
    t: Astropy.time.Time object
        Observation time in Astropy.time.Time object format.
    ephem: str
        The ephem to for computing solar system object position and velocity
    """
    ephem = ephem.lower()
    objname = objname.lower()
    # Use astropy to compute postion.
    try:
        pos = coor.get_body_barycentric(objname, t, ephemeris=ephem)
    except ValueError:
        pos = coor.get_body_barycentric(objname, t, ephemeris= kernel_link_base + "%s.bsp" % ephem)
    # Use jplephem to compute velocity.
    # TODO: Astropy 1.3 will have velocity calculation availble.
    kernel = SPK.open(datapath("%s.bsp" % ephem))
    # Compute vel from planet barycenter to solar system barycenter
    lcod = len(str(jpl_obj_code[objname]))
    tjd1 = t.tdb.jd1
    tjd2 = t.tdb.jd2
    # Planets with barycenter computing
    if lcod == 3:
        _, vel_pbary_ssb = kernel[0,jpl_obj_code[objname]/100].compute_and_differentiate(tjd1, tjd2)
        _, vel_p_pbary = kernel[jpl_obj_code[objname]/100,
                        jpl_obj_code[objname]].compute_and_differentiate(tjd1, tjd2)
        vel = vel_pbary_ssb + vel_p_pbary
    # Planets without barycenter computing
    else:
        _, vel = kernel[0,jpl_obj_code[objname]].compute_and_differentiate(tjd1, tjd2)
    return PosVel(pos.xyz, vel / SECS_PER_DAY * u.km/u.second, origin='ssb', obj=objname)
예제 #39
0
def get_jwst_position2(times, jwstpos, use_jpl_ephemeris=False):
    '''
    This returns the pair of relative positions from
    the barycenter and heliocenter to JWST in that order
    as a tuple of two arrays, each of shape (len(times), 3).
    '''

    t = Time(times, format="mjd", scale="tt")

    if use_jpl_ephemeris:
        from astropy.coordinates import solar_system_ephemeris
        solar_system_ephemeris.set('jpl')

    # Vectors from the solar-system barycenter to the center of the Earth.
    bary_earth = acoord.get_body_barycentric("earth", t)

    # Vectors from the solar-system barycenter to the center of the Sun.
    bary_sun = acoord.get_body_barycentric("sun", t)

    # Vectors from the center of the Sun to the center of the Earth.
    sun_earth = bary_earth - bary_sun

    # Convert to ordinary numpy arrays of 3-element vectors, in km.

    barysun_centerearth_pos = np.empty((len(t), 3), dtype=np.float64)
    barysun_centerearth_pos[:, 0] = bary_earth.x.si.value / 1000.
    barysun_centerearth_pos[:, 1] = bary_earth.y.si.value / 1000.
    barysun_centerearth_pos[:, 2] = bary_earth.z.si.value / 1000.

    centersun_centerearth_pos = np.empty((len(t), 3), dtype=np.float64)
    centersun_centerearth_pos[:, 0] = sun_earth.x.si.value / 1000.
    centersun_centerearth_pos[:, 1] = sun_earth.y.si.value / 1000.
    centersun_centerearth_pos[:, 2] = sun_earth.z.si.value / 1000.

    centerearth_jwst = jwstpos

    return (barysun_centerearth_pos + centerearth_jwst), \
            (centersun_centerearth_pos + centerearth_jwst)
예제 #40
0
def test_hcrs_hgs():
    # Get the current Earth location in HCRS
    now = Time(parse_time('now'))
    earth_hcrs = SkyCoord(get_body_barycentric('earth', now), frame='icrs', obstime=now).hcrs

    # Convert from HCRS to HGS
    earth_hgs = earth_hcrs.transform_to(HeliographicStonyhurst)

    # The HGS longitude of the Earth should be zero within numerical error
    assert quantity_allclose(earth_hgs.lon, 0*u.deg, atol=1e-12*u.deg)

    # The HGS latitude and radius should be within valid ranges
    assert quantity_allclose(earth_hgs.lat, 0*u.deg, atol=7.3*u.deg)
    assert quantity_allclose(earth_hgs.radius, 1*u.AU, atol=0.017*u.AU)
예제 #41
0
def test_hcrs_hgs():
    # Get the current Earth location in HCRS
    adate = parse_time('2015/05/01 01:13:00')
    earth_hcrs = SkyCoord(get_body_barycentric('earth', adate), frame='icrs', obstime=adate).hcrs

    # Convert from HCRS to HGS
    earth_hgs = earth_hcrs.transform_to(HeliographicStonyhurst)

    # The HGS longitude of the Earth should be zero within numerical error
    # Due to an issue with wrapping at +-360, we shift it to pass the test.
    assert quantity_allclose((earth_hgs.lon+1*u.deg) % (360*u.deg), 1*u.deg, atol=1e-12*u.deg)

    # The HGS latitude and radius should be within valid ranges
    assert quantity_allclose(earth_hgs.lat, 0*u.deg, atol=7.3*u.deg)
    assert quantity_allclose(earth_hgs.radius, 1*u.AU, atol=0.017*u.AU)
예제 #42
0
def test_hcrs_hgs_array_obstime():
    # Get the Earth location in HCRS at two times
    times = Time(['2017-01-01', '2017-06-01'])
    earth_hcrs = SkyCoord(get_body_barycentric('earth', times), frame='icrs', obstime=times).hcrs

    # Transform each time in separate calls (uses scalar obstime)
    earth_hgs_0 = earth_hcrs[0].transform_to(HeliographicStonyhurst)
    earth_hgs_1 = earth_hcrs[1].transform_to(HeliographicStonyhurst)

    # Transform both times in one call (uses array obstime)
    earth_hgs = earth_hcrs.transform_to(HeliographicStonyhurst)

    # Confirm that the two approaches produce the same results
    assert quantity_allclose(earth_hgs_0.lon, earth_hgs[0].lon, atol=1e-12*u.deg)
    assert quantity_allclose(earth_hgs_0.lat, earth_hgs[0].lat, rtol=1e-10)
    assert quantity_allclose(earth_hgs_0.radius, earth_hgs[0].radius, rtol=1e-10)
    assert quantity_allclose(earth_hgs_1.lon, earth_hgs[1].lon, atol=1e-12*u.deg)
    assert quantity_allclose(earth_hgs_1.lat, earth_hgs[1].lat, rtol=1e-10)
    assert quantity_allclose(earth_hgs_1.radius, earth_hgs[1].radius, rtol=1e-10)
예제 #43
0
파일: ephem.py 프로젝트: aarribas/poliastro
def build_ephem_interpolant(body, period, t_span, rtol=1e-5):
    h = (period * rtol).to(u.day).value
    t_span = ((t_span[0].to(u.day).value, t_span[1].to(u.day).value + 0.01))
    t_values = np.linspace(*t_span, int((t_span[1] - t_span[0]) / h))
    r_values = np.zeros((t_values.shape[0], 3))

    for i, t in enumerate(t_values):
        epoch = Time(t, format='jd', scale='tdb')

        r = get_body_barycentric(body.name, epoch)
        r = (ICRS(x=r.x, y=r.y, z=r.z, representation_type=CartesianRepresentation)
             .transform_to(GCRS(obstime=epoch))
             .represent_as(CartesianRepresentation)
             )

        r_values[i] = r.xyz.to(u.km)

    t_values = ((t_values - t_span[0]) * u.day).to(u.s).value
    return interp1d(t_values, r_values, kind='cubic', axis=0, assume_sorted=True)
예제 #44
0
    def to_icrs(planet_coo, _):
        # this is just an origin translation so without a distance it cannot go ahead
        if isinstance(planet_coo.data, UnitSphericalRepresentation):
            raise u.UnitsError(_NEED_ORIGIN_HINT.format(planet_coo.__class__.__name__))

        if planet_coo.data.differentials:
            bary_sun_pos, bary_sun_vel = get_body_barycentric_posvel(
                planet_coo.body.name, planet_coo.obstime
            )
            bary_sun_pos = bary_sun_pos.with_differentials(
                bary_sun_vel.represent_as(CartesianDifferential)
            )

        else:
            bary_sun_pos = get_body_barycentric(
                planet_coo.body.name, planet_coo.obstime
            )
            bary_sun_vel = None

        return None, bary_sun_pos
예제 #45
0
    def from_icrs(icrs_coo, planet_frame):
        # this is just an origin translation so without a distance it cannot go ahead
        if isinstance(icrs_coo.data, UnitSphericalRepresentation):
            raise u.UnitsError(_NEED_ORIGIN_HINT.format(icrs_coo.__class__.__name__))

        if icrs_coo.data.differentials:
            bary_sun_pos, bary_sun_vel = get_body_barycentric_posvel(
                planet_frame.body.name, planet_frame.obstime
            )
            # Beware! Negation operation is not supported for differentials
            bary_sun_pos = (-bary_sun_pos).with_differentials(
                -bary_sun_vel.represent_as(CartesianDifferential)
            )

        else:
            bary_sun_pos = -get_body_barycentric(
                planet_frame.body.name, planet_frame.obstime
            )
            bary_sun_vel = None

        return None, bary_sun_pos
예제 #46
0
def build_ephem_interpolant(body, period, t_span, rtol=1e-5):
    """Interpolates ephemerides data

       Parameters
       ----------
       body : Body
           Source body.
       period : ~astropy.units.Quantity
           Orbital period.
       t_span : list(~astropy.units.Quantity)
           Initial and final epochs.
       rtol : float, optional
           Relative tolerance. Controls the number of sampled data points,
           defaults to 1e-5.

       Returns
       -------
       intrp : ~scipy.interpolate.interpolate.interp1d
           Interpolated function.

    """
    h = (period * rtol).to(u.day).value
    t_span = (t_span[0].to(u.day).value, t_span[1].to(u.day).value + 0.01)
    t_values = np.linspace(*t_span, int((t_span[1] - t_span[0]) / h))
    r_values = np.zeros((t_values.shape[0], 3))

    for i, t in enumerate(t_values):
        epoch = Time(t, format="jd", scale="tdb")

        r = get_body_barycentric(body.name, epoch)
        r = (
            ICRS(x=r.x, y=r.y, z=r.z, representation_type=CartesianRepresentation)
            .transform_to(GCRS(obstime=epoch))
            .represent_as(CartesianRepresentation)
        )

        r_values[i] = r.xyz.to(u.km)

    t_values = ((t_values - t_span[0]) * u.day).to(u.s).value
    return interp1d(t_values, r_values, kind="cubic", axis=0, assume_sorted=True)
예제 #47
0
파일: ephemeris.py 프로젝트: Cadair/sunpy
def get_body_heliographic_stonyhurst(body, time='now'):
    """
    Return a `~sunpy.coordinates.frames.HeliographicStonyhurst` frame for the location of a
    solar-system body at a specified time.

    Parameters
    ----------
    body : `str`
        The solar-system body for which to calculate positions
    time : various
        Time to use as `~astropy.time.Time` or in a parse_time-compatible format

    Returns
    -------
    out : `~sunpy.coordinates.frames.HeliographicStonyhurst`
        Location of the solar-system body in the `~sunpy.coordinates.HeliographicStonyhurst` frame
    """
    obstime = parse_time(time)

    body_icrs = ICRS(get_body_barycentric(body, obstime))
    body_hgs = body_icrs.transform_to(HGS(obstime=obstime))

    return body_hgs