def test_lsr_loopback(frame):
    xyz = CartesianRepresentation(1, 2, 3) * u.AU
    xyz = xyz.with_differentials(CartesianDifferential(4, 5, 6) * u.km / u.s)

    v_bary = CartesianDifferential(5, 10, 15) * u.km / u.s

    # Test that the loopback properly handles a change in v_bary
    from_coo = frame(xyz)  # default v_bary
    to_frame = frame(v_bary=v_bary)

    explicit_coo = from_coo.transform_to(ICRS()).transform_to(to_frame)
    implicit_coo = from_coo.transform_to(to_frame)

    # Confirm that the explicit transformation changes the velocity but not the position
    assert allclose(explicit_coo.cartesian.xyz,
                    from_coo.cartesian.xyz,
                    rtol=1e-10)
    assert not allclose(
        explicit_coo.velocity.d_xyz, from_coo.velocity.d_xyz, rtol=1e-10)

    # Confirm that the loopback matches the explicit transformation
    assert allclose(explicit_coo.cartesian.xyz,
                    implicit_coo.cartesian.xyz,
                    rtol=1e-10)
    assert allclose(explicit_coo.velocity.d_xyz,
                    implicit_coo.velocity.d_xyz,
                    rtol=1e-10)
def test_creation_cartesian():
    rep = CartesianRepresentation([10, 0., 0.] * u.pc)
    dif = CartesianDifferential([0, 100, 0.] * u.pc / u.Myr)
    rep = rep.with_differentials(dif)
    c = SkyCoord(rep)

    sdif = dif.represent_as(SphericalCosLatDifferential, rep)
    assert_quantity_allclose(c.pm_ra_cosdec, sdif.d_lon_coslat)
def test_creation_cartesian():
    rep = CartesianRepresentation([10, 0., 0.]*u.pc)
    dif = CartesianDifferential([0, 100, 0.]*u.pc/u.Myr)
    rep = rep.with_differentials(dif)
    c = SkyCoord(rep)

    sdif = dif.represent_as(SphericalCosLatDifferential, rep)
    assert_quantity_allclose(c.pm_ra_cosdec, sdif.d_lon_coslat)
Esempio n. 4
0
    def __call__(self, t):
        """
        Computes the interpolated coordinates at the given time(s).

        Parameters
        ----------
        t : Time
            Time or list of times where an interpolated coordinate is required

        Returns
        -------
        coords : SkyCoord
           A `SkyCoord` object with the requested coordinate(s), in the
           original frame

        Raises
        ------
        ValueError
            If the requested `t` value is out of bounds for the interpolator

        """
        if not self._interpolators_initialised:
            # Lazy init interpolators only when required
            self._init_interpolators()

        # **** get coords at requested time ****

        # compute raw r and v vectors and
        # fill Astropy cartesian vectors (with velocities if available)
        if t.isscalar:
            # there is a single time instance
            coords = CartesianRepresentation(self._compute_pos(t), copy=False)
            if self._has_velocity:
                v = CartesianDifferential(self._compute_vel(t), copy=False)
                coords = coords.with_differentials(v)
        else:
            # there is more than one time instance
            r = [self._compute_pos(time) for time in t]
            coords = CartesianRepresentation(np.asarray(r),
                                             unit=r[0].unit,
                                             copy=False,
                                             xyz_axis=1)

            if self._has_velocity:
                v = [self._compute_vel(time) for time in t]
                v = CartesianDifferential(np.asarray(v),
                                          unit=v[0].unit,
                                          copy=False,
                                          xyz_axis=1)
                coords = coords.with_differentials(v)

        return SkyCoord(
            coords,
            obstime=t,
            frame=self._frame_name,
            representation_type="cartesian",
            differential_type="cartesian",
        )
Esempio n. 5
0
    def setup(self):

        # Avoid top-level module import to make sure that the benchmarks are
        # compatible with versions of astropy that did not have this functionality.
        from astropy.coordinates import CartesianDifferential

        self.scalar_rep = CartesianRepresentation([1., 2, 3] * u.kpc)
        self.scalar_dif = CartesianDifferential([1, 2, 3.] * u.km / u.s)

        self.array_rep = CartesianRepresentation(np.ones((3, 1000)) * u.kpc)
        self.array_dif = CartesianDifferential(np.ones((3, 1000)) * u.km / u.s)
Esempio n. 6
0
def propagation_engine(line1, line2, time_list):
    """Tests the interpolation accuracy for a given TLE."""

    # Init satellite object from the TLE
    sat = Satrec.twoline2rv(line1, line2)

    # ****** Generate the pos, vel vectors for each time instant ******

    # Run the propagation and init pos and vel vectors in TEME
    e, r_list, v_list = sat.sgp4_array(time_list.jd1, time_list.jd2)

    # Load the time, pos, vel info into astropy objects (shallow copied)
    vel_list = CartesianDifferential(v_list, unit=u.km / u.s, xyz_axis=1)
    pos_list = CartesianRepresentation(
        r_list, unit=u.km, xyz_axis=1
    ).with_differentials(vel_list)

    # trajectory in astropy
    traj_astropy = SkyCoord(
        pos_list,
        obstime=time_list,
        frame=TEME.name,
        representation_type="cartesian",
        differential_type="cartesian",
    )

    # Init trajectory in Trajectory object
    trajectory = Trajectory(traj_astropy)

    return {"traj": trajectory, "sat": sat}
Esempio n. 7
0
    def to_equatorial(fixed_coo, equatorial_frame):
        # TODO replace w/ something smart (Sun/Earth special cased)
        # assert fixed_coo.body == equatorial_frame.body

        r = fixed_coo.cartesian.xyz

        ra, dec, W = fixed_coo.rot_elements_at_epoch(fixed_coo.obstime)
        equatorial_frame._obstime = fixed_coo.obstime

        r = transform_vector(r, -W, "z")

        r_trans1 = transform_vector(r, -(90 * u.deg - dec), "x")
        r_f = transform_vector(r_trans1, -(90 * u.deg + ra), "z")

        if fixed_coo.data.differentials:
            v = fixed_coo.differentials["s"].d_xyz
            v = transform_vector(v, -W, "z")
            v_trans1 = transform_vector(v, -(90 * u.deg - dec), "x")
            v_f = transform_vector(v_trans1, -(90 * u.deg + ra), "z")

            data = CartesianRepresentation(
                r_f, differentials=CartesianDifferential(v_f))
        else:
            data = CartesianRepresentation(r_f)
        return equatorial_frame.realize_frame(data)
Esempio n. 8
0
def test_ephem_from_body_has_expected_properties(method, plane, FrameClass,
                                                 rtol):
    epochs = Time(
        [
            "2020-03-01 12:00:00", "2020-03-17 00:00:00.000",
            "2020-04-01 12:00:00.000"
        ],
        scale="tdb",
    )
    equatorial_coordinates = CartesianRepresentation(
        [
            (-1.40892271e08, 45067626.83900666, 19543510.68386639),
            (-1.4925067e08, 9130104.71634121, 3964948.59999307),
            (-1.46952333e08, -27413113.24215863, -11875983.21773582),
        ] * u.km,
        xyz_axis=1,
        differentials=CartesianDifferential(
            [
                (-10.14262131, -25.96929533, -11.25810932),
                (-2.28639444, -27.3906416, -11.87218591),
                (5.67814544, -26.84316701, -11.63720607),
            ] * (u.km / u.s),
            xyz_axis=1,
        ),
    )

    expected_coordinates = (
        ICRS(equatorial_coordinates).transform_to(FrameClass).represent_as(
            CartesianRepresentation, CartesianDifferential))

    earth = Ephem.from_body(Earth, epochs, plane=plane)
    coordinates = earth.sample(method=method)

    assert earth.epochs is epochs
    assert_coordinates_allclose(coordinates, expected_coordinates, rtol=rtol)
Esempio n. 9
0
def test_ephem_from_horizons_calls_horizons_with_correct_parameters(
    horizons_mock, attractor, location_str, plane, refplane_str
):
    unused_name = "Strange Object"
    unused_id_type = "id_type"
    epochs = Time(["2020-03-01 12:00:00"], scale="tdb")

    horizons_mock().vectors.return_value = {
        "x": [1] * u.au,
        "y": [0] * u.au,
        "z": [0] * u.au,
        "vx": [0] * (u.au / u.day),
        "vy": [1] * (u.au / u.day),
        "vz": [0] * (u.au / u.day),
    }
    expected_coordinates = CartesianRepresentation(
        [(1, 0, 0)] * u.au,
        xyz_axis=1,
        differentials=CartesianDifferential([(0, 1, 0)] * (u.au / u.day), xyz_axis=1),
    )

    ephem = Ephem.from_horizons(
        unused_name, epochs, attractor=attractor, plane=plane, id_type=unused_id_type
    )

    horizons_mock.assert_called_with(
        id=unused_name, location=location_str, epochs=epochs.jd, id_type=unused_id_type
    )
    horizons_mock().vectors.assert_called_once_with(refplane=refplane_str)

    coordinates = ephem.sample()

    assert_coordinates_allclose(coordinates, expected_coordinates)
Esempio n. 10
0
    def _reference_frame_from_tree(cls, node, ctx):
        from astropy.units import Quantity
        from astropy.io.misc.asdf.tags.unit.quantity import QuantityType
        from astropy.coordinates import ICRS, CartesianRepresentation

        version = cls.version
        reference_frame = node['reference_frame']
        reference_frame_name = reference_frame['type']

        frame_cls = cls._get_reference_frame_mapping()[reference_frame_name]

        frame_kwargs = {}
        for name in frame_cls.get_frame_attr_names().keys():
            val = reference_frame.get(name)
            if val is not None:
                if name in ['obsgeoloc', 'obsgeovel']:
                    x = QuantityType.from_tree(val[0], ctx)
                    y = QuantityType.from_tree(val[1], ctx)
                    z = QuantityType.from_tree(val[2], ctx)
                    val = CartesianRepresentation(x, y, z)
                elif name == 'galcen_v_sun':
                    from astropy.coordinates import CartesianDifferential
                    d_x = QuantityType.from_tree(val[0], ctx)
                    d_y = QuantityType.from_tree(val[1], ctx)
                    d_z = QuantityType.from_tree(val[2], ctx)
                    val = CartesianDifferential(d_x, d_y, d_z)
                else:
                    val = yamlutil.tagged_tree_to_custom_tree(val, ctx)
                frame_kwargs[name] = val
        has_ra_and_dec = reference_frame.get('galcen_dec') and \
            reference_frame.get('galcen_ra')

        return frame_cls(**frame_kwargs)
Esempio n. 11
0
def propagate(orbit, time_of_flight, *, method=mean_motion, rtol=1e-10, **kwargs):
    """Propagate an orbit some time and return the result.

    """
    time_of_flight = np.atleast_1d(time_of_flight)
    rr, vv = method(
        orbit.attractor.k, orbit.r, orbit.v, time_of_flight, rtol=rtol, **kwargs
    )

    # TODO: Turn these into unit tests
    assert rr.ndim == 2
    assert vv.ndim == 2

    cartesian = CartesianRepresentation(
        rr, differentials=CartesianDifferential(vv, xyz_axis=1), xyz_axis=1
    )

    # If the frame supports obstime, set the time values
    kwargs = {}
    if "obstime" in orbit.frame.frame_attributes:
        kwargs["obstime"] = orbit.epoch + time_of_flight
    else:
        warn(
            "Frame {} does not support 'obstime', time values were not returned".format(
                orbit.frame.__class__
            )
        )

    # Use of a protected method instead of frame.realize_frame
    # because the latter does not let the user choose the representation type
    # in one line despite its parameter names, see
    # https://github.com/astropy/astropy/issues/7784
    return orbit.frame._replicate(cartesian, representation_type="cartesian", **kwargs)
Esempio n. 12
0
def transform_to_galactic(icrs_coords):
    """
    For the input astrometry plus radial velocity in the ICRS system calculate the barycentric Galactic
    coordinates as well as Galactocentric coordinates.

    Parameters
    ----------

    icrs_coords: astropy.coordinates.ICRS
        ICRS instance constructed from the 5-parameter Gaia DR2 astrometry and the radial velocity.

    Returns
    -------

    Galactic and Galactocentric objects containing the astrometry in Galactic coordinates, the
    galactocentric Cartesian coordinates, and the galactocentric cylindrical coordinates.
    """

    galactic_coords = icrs_coords.transform_to(Galactic())
    sun_motion = CartesianDifferential(_Usun, _vc + _Vsun, _Wsun)
    galactocentric_cartesian = icrs_coords.transform_to(
        Galactocentric(galcen_distance=_Rsun,
                       z_sun=_zsun,
                       galcen_v_sun=sun_motion))
    galactocentric_cartesian.set_representation_cls(base='cartesian')
    galactocentric_cylindrical = icrs_coords.transform_to(
        Galactocentric(galcen_distance=_Rsun,
                       z_sun=_zsun,
                       galcen_v_sun=sun_motion))
    galactocentric_cylindrical.set_representation_cls(base='cylindrical')

    return galactic_coords, galactocentric_cartesian, galactocentric_cylindrical
Esempio n. 13
0
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
Esempio n. 14
0
    def to_equatorial(fixed_coo, equatorial_frame):
        assert fixed_coo.body == equatorial_frame.body

        r = fixed_coo.data.xyz
        v = fixed_coo.data.differentials["s"].d_xyz

        ra, dec, W = fixed_coo.rot_elements_at_epoch(fixed_coo.obstime)

        r = transform_vector(r, -W, "z")
        v = transform_vector(v, -W, "z")

        r_trans1 = transform_vector(r, -(90 * u.deg - dec), "x")
        r_trans2 = transform_vector(r_trans1, -(90 * u.deg + ra), "z")

        v_trans1 = transform_vector(v, -(90 * u.deg - dec), "x")
        v_trans2 = transform_vector(v_trans1, -(90 * u.deg + ra), "z")

        icrs_frame_pos_coord, icrs_frame_vel_coord = get_body_barycentric_posvel(
            fixed_coo.body.name, time=fixed_coo.obstime)

        r_f = icrs_frame_pos_coord.xyz + r_trans2
        v_f = icrs_frame_vel_coord.xyz + v_trans2

        data = CartesianRepresentation(
            r_f, differentials=CartesianDifferential(v_f))
        return equatorial_frame.realize_frame(data)
Esempio n. 15
0
def attach_zero_velocities(coord):
    """
    Set the differentials to be stationary on a coordinate object.
    """
    coord_diffs = CartesianDifferential(u.Quantity([0, 0, 0] * KMS))
    new_data = coord.cartesian.with_differentials(coord_diffs)
    return coord.realize_frame(new_data)
Esempio n. 16
0
    def from_equatorial(equatorial_coo, fixed_frame):
        assert equatorial_coo.body == fixed_frame.body

        r = equatorial_coo.data.xyz
        v = equatorial_coo.data.differentials["s"].d_xyz

        ra, dec, W = fixed_frame.rot_elements_at_epoch(equatorial_coo.obstime)

        icrs_frame_pos_coord, icrs_frame_vel_coord = get_body_barycentric_posvel(
            equatorial_coo.body.name, time=equatorial_coo.obstime)

        r_trans1 = r - icrs_frame_pos_coord.xyz
        r_trans2 = transform_vector(r_trans1, (90 * u.deg + ra), "z")
        r_f = transform_vector(r_trans2, (90 * u.deg - dec), "x")

        v_trans1 = v - icrs_frame_vel_coord.xyz
        v_trans2 = transform_vector(v_trans1, (90 * u.deg + ra), "z")
        v_f = transform_vector(v_trans2, (90 * u.deg - dec), "x")

        r_f = transform_vector(r_f, W, "z")
        v_f = transform_vector(v_f, W, "z")

        data = CartesianRepresentation(
            r_f, differentials=CartesianDifferential(v_f))
        return fixed_frame.realize_frame(data)
Esempio n. 17
0
def test_orbit_creation_using_frame_obj(attractor, frame, obstime):
    vel = [0, 2, 0] * u.km / u.s
    cartdiff = CartesianDifferential(*vel)

    pos = [30000, 0, 0] * u.km
    cartrep = CartesianRepresentation(*pos, differentials=cartdiff)

    coord = frame(cartrep, obstime=obstime)
    o = Orbit.from_coords(attractor, coord)

    inertial_frame_at_body_centre = get_frame(attractor,
                                              Planes.EARTH_EQUATOR,
                                              obstime=coord.obstime)

    coord_transformed_to_irf = coord.transform_to(
        inertial_frame_at_body_centre)

    pos_transformed_to_irf = coord_transformed_to_irf.cartesian.xyz
    vel_transformed_to_irf = coord_transformed_to_irf.cartesian.differentials[
        "s"].d_xyz

    assert_quantity_allclose(o.r, pos_transformed_to_irf, atol=1e-5 * u.km)
    assert_quantity_allclose(o.v,
                             vel_transformed_to_irf,
                             atol=1e-5 * u.km / u.s)
Esempio n. 18
0
def tirs_to_teme(tirs_coord, teme_frame):
    # TIRS to TEME basic rotation matrix
    teme_to_pef_mat = rotation_matrix(_gmst82_angle(tirs_coord.obstime), axis="z")
    pef_to_teme_mat = teme_to_pef_mat.transpose()

    # rotate position vector: TIRS to TEME
    r_teme = tirs_coord.cartesian.transform(pef_to_teme_mat)

    # Check for velocity - skip velocity transform if not present
    if tirs_coord.data.differentials:
        # prepare rotation offset: w x r_TIRS
        wxr = CartesianRepresentation(_w).cross(tirs_coord.cartesian)

        # add rotation offset and then do the velocity rotation
        v_teme = (tirs_coord.velocity.to_cartesian() + wxr).transform(pef_to_teme_mat)
        v_teme = CartesianDifferential.from_cartesian(v_teme)

        # Prepare final coord vector with velocity
        teme_coord = r_teme.with_differentials(v_teme)
    else:
        # Prepare final coord vector without velocity
        teme_coord = r_teme

    # Add coord data to the existing frame
    return teme_frame.realize_frame(teme_coord)
Esempio n. 19
0
def propagate(orbit,
              time_of_flight,
              *,
              method=farnocchia,
              rtol=1e-10,
              **kwargs):
    """Propagate an orbit some time and return the result.

    Parameters
    ----------
    orbit : ~poliastro.twobody.Orbit
        Orbit object to propagate.
    time_of_flight : ~astropy.time.TimeDelta
        Time of propagation.
    method : callable, optional
        Propagation method, default to farnocchia.
    rtol : float, optional
        Relative tolerance, default to 1e-10.

    Returns
    -------
    astropy.coordinates.CartesianRepresentation
        Propagation coordinates.

    """

    # Check if propagator fulfills orbit requirements
    if orbit.ecc < 1.0 and method not in ELLIPTIC_PROPAGATORS:
        raise ValueError(
            "Can not use an parabolic/hyperbolic propagator for elliptical orbits."
        )
    elif orbit.ecc == 1.0 and method not in PARABOLIC_PROPAGATORS:
        raise ValueError(
            "Can not use an elliptic/hyperbolic propagator for parabolic orbits."
        )
    elif orbit.ecc > 1.0 and method not in HYPERBOLIC_PROPAGATORS:
        raise ValueError(
            "Can not use an elliptic/parabolic propagator for hyperbolic orbits."
        )
    else:
        pass

    rr, vv = method(orbit.attractor.k,
                    orbit.r,
                    orbit.v,
                    time_of_flight.reshape(-1).to(u.s),
                    rtol=rtol,
                    **kwargs)

    # TODO: Turn these into unit tests
    assert rr.ndim == 2
    assert vv.ndim == 2

    cartesian = CartesianRepresentation(rr,
                                        differentials=CartesianDifferential(
                                            vv, xyz_axis=1),
                                        xyz_axis=1)

    return cartesian
    def _run_propagation(self, init_coords, time_list):
        """Solves the ODE or runs the actual propagation.

        Parameters
        ----------
        init_coords : SkyCoord
            Initial coordinates (the first value is used)
        time_list : Time
            Time list for outputs
        Returns
        -------
        SkyCoord
            The output coordinates corresponding to `time_list`
        """

        # generate the time list since epoch (in seconds)
        t_list_epoch = (time_list - time_list[0]).to_value(u.s)

        # concat the init vector
        rv_init = [
            *init_coords.cartesian.without_differentials().xyz.to_value(u.km),
            *init_coords.velocity.d_xyz.to_value(u.km / u.s),
        ]

        solver = solve_ivp(
            _ode_diff_eqns,
            (t_list_epoch[0], t_list_epoch[-1]),
            rv_init,
            method=self._solver_type.value,
            dense_output=True,
            rtol=self.rtol,
            atol=self.atol,
        )

        r_list = np.empty((3, len(t_list_epoch)))
        v_list = np.empty((3, len(t_list_epoch)))
        # Fill the raw output data
        i = 0
        for t in t_list_epoch:
            rv = solver.sol(t)
            r_list[:, i] = rv[:3]
            v_list[:, i] = rv[3:]
            i = i + 1

        # Load the time, pos, vel info into astropy objects (shallow copied)
        rv_list = CartesianRepresentation(
            r_list, unit=u.km).with_differentials(
                CartesianDifferential(v_list, unit=u.km / u.s))

        coords_list = SkyCoord(
            rv_list,
            obstime=time_list,
            frame=GCRS,
            representation_type="cartesian",
            differential_type="cartesian",
            copy=False,
        )
        return coords_list
Esempio n. 21
0
def test_teme_itrf():
    """
    Test case transform from TEME to ITRF.

    Test case derives from example on appendix C of Vallado, Crawford, Hujsak & Kelso (2006).
    See https://celestrak.com/publications/AIAA/2006-6753/AIAA-2006-6753-Rev2.pdf
    """
    v_itrf = CartesianDifferential(-3.225636520,
                                   -2.872451450,
                                   5.531924446,
                                   unit=u.km / u.s)
    p_itrf = CartesianRepresentation(-1033.479383,
                                     7901.2952740,
                                     6380.35659580,
                                     unit=u.km,
                                     differentials={'s': v_itrf})
    t = Time("2004-04-06T07:51:28.386")

    teme = ITRS(p_itrf, obstime=t).transform_to(TEME(obstime=t))
    v_teme = CartesianDifferential(-4.746131487,
                                   0.785818041,
                                   5.531931288,
                                   unit=u.km / u.s)
    p_teme = CartesianRepresentation(5094.18016210,
                                     6127.64465050,
                                     6380.34453270,
                                     unit=u.km,
                                     differentials={'s': v_teme})

    assert_allclose(teme.cartesian.without_differentials().xyz,
                    p_teme.without_differentials().xyz,
                    atol=30 * u.cm)

    assert_allclose(teme.cartesian.differentials['s'].d_xyz,
                    p_teme.differentials['s'].d_xyz,
                    atol=1.0 * u.cm / u.s)

    # test round trip
    itrf = teme.transform_to(ITRS(obstime=t))
    assert_allclose(itrf.cartesian.without_differentials().xyz,
                    p_itrf.without_differentials().xyz,
                    atol=100 * u.cm)
    assert_allclose(itrf.cartesian.differentials['s'].d_xyz,
                    p_itrf.differentials['s'].d_xyz,
                    atol=1 * u.cm / u.s)
Esempio n. 22
0
    def gen_trajectory(self, tle, interval):
        """
        Generates the trajectory (time and coordinate information) for the given
        interval with the internal stepsize.
        Parameters
        ----------
        tle : TLE
            Two-Line-Element initial orbit information (TEME mean orbital elements)
        interval : TimeInterval
            Time interval for which the ephemeris will be generated
        Returns
        -------
        Trajectory
            The output trajectory (in `GCRS`)
        """

        # generate number of steps (forced to rounded up int)
        no_of_steps = np.ceil((interval.duration / self.stepsize).decompose())

        # make sure there are enough elements for interpolation
        if no_of_steps < Trajectory.reqd_min_elements():
            no_of_steps = Trajectory.reqd_min_elements()

        # time list
        time_list = interval.start + self.stepsize * np.arange(0, no_of_steps)
        time_list.format = "isot"

        # ****** Generate the pos, vel vectors for each time instant ******

        # Run the propagation and init pos and vel vectors in TEME
        e, r_list, v_list = tle.satrec.sgp4_array(time_list.jd1, time_list.jd2)

        # Load the time, pos, vel info into astropy objects (shallow copied)
        rv_list_teme = CartesianRepresentation(
            r_list, unit=u.km, xyz_axis=1).with_differentials(
                CartesianDifferential(v_list, unit=u.km / u.s, xyz_axis=1))

        rv_list_gcrs = TEME(
            rv_list_teme,
            obstime=time_list,
            representation_type="cartesian",
            differential_type="cartesian",
        ).transform_to(GCRS(obstime=time_list))

        # trajectory in astropy
        traj_astropy = SkyCoord(
            rv_list_gcrs,
            obstime=time_list,
            frame="gcrs",
            representation_type="cartesian",
            differential_type="cartesian",
        )

        # Init trajectory in Trajectory object
        trajectory = Trajectory(traj_astropy)

        return trajectory
Esempio n. 23
0
    def _reference_frame_from_tree(cls, node, ctx):
        from astropy.units import Quantity
        from astropy.io.misc.asdf.tags.unit.quantity import QuantityType
        from astropy.coordinates import ICRS, CartesianRepresentation

        version = cls.version
        reference_frame = node['reference_frame']
        reference_frame_name = reference_frame['type']

        frame_cls = cls._get_reference_frame_mapping()[reference_frame_name]

        frame_kwargs = {}
        for name in frame_cls.get_frame_attr_names().keys():
            val = reference_frame.get(name)
            if val is not None:
                # These are deprecated fields that must be handled as a special
                # case for older versions of the schema
                if name in ['galcen_ra', 'galcen_dec']:
                    continue
                # There was no schema for quantities in v1.0.0
                if name in ['galcen_distance', 'roll', 'z_sun'
                            ] and version == '1.0.0':
                    val = Quantity(val[0], unit=val[1])
                # These fields are known to be CartesianRepresentations
                if name in ['obsgeoloc', 'obsgeovel']:
                    if version == '1.0.0':
                        unit = val[1]
                        x = Quantity(val[0][0], unit=unit)
                        y = Quantity(val[0][1], unit=unit)
                        z = Quantity(val[0][2], unit=unit)
                    else:
                        x = QuantityType.from_tree(val[0], ctx)
                        y = QuantityType.from_tree(val[1], ctx)
                        z = QuantityType.from_tree(val[2], ctx)
                    val = CartesianRepresentation(x, y, z)
                elif name == 'galcen_v_sun':
                    from astropy.coordinates import CartesianDifferential
                    # This field only exists since v1.1.0, and it only uses
                    # CartesianDifferential after v1.3.3
                    d_x = QuantityType.from_tree(val[0], ctx)
                    d_y = QuantityType.from_tree(val[1], ctx)
                    d_z = QuantityType.from_tree(val[2], ctx)
                    val = CartesianDifferential(d_x, d_y, d_z)
                else:
                    val = yamlutil.tagged_tree_to_custom_tree(val, ctx)
                frame_kwargs[name] = val
        has_ra_and_dec = reference_frame.get('galcen_dec') and \
            reference_frame.get('galcen_ra')
        if version == '1.0.0' and has_ra_and_dec:
            # Convert deprecated ra and dec fields into galcen_coord
            galcen_dec = reference_frame['galcen_dec']
            galcen_ra = reference_frame['galcen_ra']
            dec = Quantity(galcen_dec[0], unit=galcen_dec[1])
            ra = Quantity(galcen_ra[0], unit=galcen_ra[1])
            frame_kwargs['galcen_coord'] = ICRS(dec=dec, ra=ra)
        return frame_cls(**frame_kwargs)
Esempio n. 24
0
def propagate(orbit, time_of_flight, *, method=mean_motion, rtol=1e-10, **kwargs):
    """Propagate an orbit some time and return the result.

    Parameters
    ----------
    orbit : ~poliastro.twobody.Orbit
        Orbit object to propagate.
    time_of_flight : ~astropy.time.TimeDelta
        Time of propagation.
    method : callable, optional
        Propagation method, default to mean_motion.
    rtol : float, optional
        Relative tolerance, default to 1e-10.

    Returns
    -------
    astropy.coordinates.CartesianRepresentation
        Propagation coordinates.

    """

    # Check if propagator fulfills orbit requirements
    if orbit.ecc < 1.0 and method not in ELLIPTIC_PROPAGATORS:
        raise ValueError(
            "Can not use an parabolic/hyperbolic propagator for elliptical orbits."
        )
    elif orbit.ecc == 1.0 and method not in PARABOLIC_PROPAGATORS:
        raise ValueError(
            "Can not use an elliptic/hyperbolic propagator for parabolic orbits."
        )
    elif orbit.ecc > 1.0 and method not in HYPERBOLIC_PROPAGATORS:
        raise ValueError(
            "Can not use an elliptic/parabolic propagator for hyperbolic orbits."
        )
    else:
        pass

    # Use the highest precision we can afford
    # np.atleast_1d does not work directly on TimeDelta objects
    jd1 = np.atleast_1d(time_of_flight.jd1)
    jd2 = np.atleast_1d(time_of_flight.jd2)
    time_of_flight = time.TimeDelta(jd1, jd2, format="jd", scale=time_of_flight.scale)

    rr, vv = method(
        orbit.attractor.k, orbit.r, orbit.v, time_of_flight.to(u.s), rtol=rtol, **kwargs
    )

    # TODO: Turn these into unit tests
    assert rr.ndim == 2
    assert vv.ndim == 2

    cartesian = CartesianRepresentation(
        rr, differentials=CartesianDifferential(vv, xyz_axis=1), xyz_axis=1
    )

    return cartesian
Esempio n. 25
0
def coordinates():
    return CartesianRepresentation(
        [(1, 0, 0), (0.9, 0.1, 0), (0.8, 0.2, 0), (0.7, 0.3, 0)] * u.au,
        xyz_axis=1,
        differentials=CartesianDifferential(
            [(0, 1, 0), (-0.1, 0.9, 0), (-0.2, 0.8, 0),
             (-0.3, 0.7, 0)] * (u.au / u.day),
            xyz_axis=1,
        ),
    )
Esempio n. 26
0
def test_from_coord_if_coord_is_not_of_shape_zero():
    pos = [0, 1, 0]
    vel = [1, 0, 0]
    cartdiff = CartesianDifferential([vel] * u.km / u.s, xyz_axis=1)
    cartrep = CartesianRepresentation([pos] * u.km, differentials=cartdiff, xyz_axis=1)
    coords = GCRS(cartrep, representation_type=CartesianRepresentation, obstime=J2000)

    ss = Orbit.from_coords(Earth, coords)

    assert_quantity_allclose(ss.r, pos * u.km, rtol=1e-5)
    assert_quantity_allclose(ss.v, vel * u.km / u.s, rtol=1e-5)
 def setup_class(cls):
     cls.loc = loc = EarthLocation.from_geodetic(
         np.linspace(0, 360, 6)*u.deg, np.linspace(-90, 90, 6)*u.deg, 100*u.m)
     cls.obstime = obstime = Time(np.linspace(2000, 2010, 6), format='jyear')
     # Get comparison via a full transformation.  We do not use any methods
     # of EarthLocation, since those depend on the fast transform.
     loc_itrs = ITRS(loc.x, loc.y, loc.z, obstime=obstime)
     zeros = np.broadcast_to(0. * (u.km / u.s), (3,) + loc_itrs.shape, subok=True)
     loc_itrs.data.differentials['s'] = CartesianDifferential(zeros)
     loc_gcrs_cart = loc_itrs.transform_to(GCRS(obstime=obstime)).cartesian
     cls.obsgeoloc = loc_gcrs_cart.without_differentials()
     cls.obsgeovel = loc_gcrs_cart.differentials['s'].to_cartesian()
Esempio n. 28
0
    def get_coord_list(self, time_list, velocity=False, ephemeris="builtin"):
        """
        Computes the set of positions (and velocities, if requested) of the Celestial
        Body in the `ICRS` frame. Any further frame transformations can then be carried
        out.

        Default ephemeris is `builtin`, though it cannot compute the velocity for
        the Moon. Ephemeris can also be `jpl`, where the default implementation in
        Astropy is used. Be warned that the first time this is called, a large file
        has to be downloaded.

        Parameters
        ----------
        time_list : `~astropy.time.Time`
            List of times where position output is requested
        velocity : bool
            True if velocities are of the celestial body is also requested
        ephemeris : str, optional
            Ephemeris to use.  By default, use the one set with
            ``astropy.coordinates.solar_system_ephemeris.set``

        Returns
        -------
        SkyCoord
            Set of cartesian positions (and velocities) in a `SkyCoord` object

        """
        if velocity:
            r, v = get_body_barycentric_posvel(self.name,
                                               time_list,
                                               ephemeris=ephemeris)
            v_body = CartesianDifferential(v.xyz)
            r_body = r.with_differentials(v_body)

            coord_list = SkyCoord(
                r_body.with_differentials(v_body),
                obstime=time_list,
                frame="icrs",
                representation_type="cartesian",
                differential_type="cartesian",
            )

        else:
            coord_list = SkyCoord(
                get_body_barycentric(self.name, time_list,
                                     ephemeris=ephemeris),
                obstime=time_list,
                frame="icrs",
                representation_type="cartesian",
                differential_type="cartesian",
            )

        return coord_list
Esempio n. 29
0
def test_regression_8924():
    """This checks that the ValueError in
    BaseRepresentation._re_represent_differentials is raised properly
    """
    # A case where the representation has a 's' differential, but we try to
    # re-represent only with an 's2' differential
    rep = CartesianRepresentation(1, 2, 3, unit=u.kpc)
    dif = CartesianDifferential(4, 5, 6, u.km/u.s)
    rep = rep.with_differentials(dif)

    with pytest.raises(ValueError):
        rep._re_represent_differentials(CylindricalRepresentation,
                                        {'s2': CylindricalDifferential})
Esempio n. 30
0
    def gen_trajectory(self, tle, interval, **kwargs):
        """
        Generates the trajectory (time and coordinate information) for the given
        interval with the internal stepsize.
        Parameters
        ----------
        tle : TLE
            Two-Line-Element initial orbit information (TEME mean orbital elements)
        interval : TimeInterval
            Time interval for which the ephemeris will be generated
        kwargs
            No keywords defined
        Returns
        -------
        Trajectory
            The output trajectory (in `GCRS`)
        """

        # ****** Generate the pos, vel vectors for each time instant ******

        # generate the output timelist
        time_list = self._generate_time_list(interval)

        # Run the propagation and init pos and vel vectors in TEME
        e, r_list, v_list = tle.satrec.sgp4_array(time_list.jd1, time_list.jd2)

        # Load the time, pos, vel info into astropy objects (shallow copied)
        rv_list_teme = CartesianRepresentation(
            r_list, unit=u.km, xyz_axis=1
        ).with_differentials(CartesianDifferential(v_list, unit=u.km / u.s, xyz_axis=1))

        rv_list_gcrs = TEME(
            rv_list_teme,
            obstime=time_list,
            representation_type="cartesian",
            differential_type="cartesian",
        ).transform_to(GCRS(obstime=time_list))

        # trajectory in astropy
        traj_astropy = SkyCoord(
            rv_list_gcrs,
            obstime=time_list,
            frame="gcrs",
            representation_type="cartesian",
            differential_type="cartesian",
        )

        # Init trajectory in Trajectory object
        trajectory = Trajectory(traj_astropy)

        return trajectory
Esempio n. 31
0
def test_from_coord_fails_for_multiple_positions(obstime):
    cartdiff = CartesianDifferential([[0, 1, 0], [-0.1, 0.9, 0]] * u.km / u.s,
                                     xyz_axis=1)
    cartrep = CartesianRepresentation([[1, 0, 0], [0.9, 0.1, 0]] * u.km,
                                      differentials=cartdiff,
                                      xyz_axis=1)
    coords = GCRS(cartrep,
                  representation_type=CartesianRepresentation,
                  obstime=obstime)

    with pytest.raises(ValueError) as excinfo:
        Orbit.from_coords(Earth, coords)
    assert (
        "ValueError: Coordinate instance must represents exactly 1 position, found: 2"
        in excinfo.exconly())