Esempio n. 1
0
 def inclination(self, new_inclination):
     previous_inclination = self._inclination
     rot_new_inc = rotation_matrix(previous_inclination - new_inclination,
                                   axis='x')
     for spot in self.spots:
         cartesian = CartesianRepresentation(
             x=spot.x, y=spot.y, z=spot.z).transform(rot_new_inc)
         spot.x = cartesian.x.value
         spot.y = cartesian.y.value
         spot.z = cartesian.z.value
     self._inclination = new_inclination
Esempio n. 2
0
def test_from_coord_fails_if_no_time_differential():
    pos = [30000, 0, 0] * u.km
    cartrep = CartesianRepresentation(*pos)

    # Method fails if coordinate instance doesn't contain a differential with
    # respect to time
    with pytest.raises(ValueError) as excinfo:
        Orbit.from_coords(Earth, SkyCoord(cartrep))
    assert (
        "ValueError: Coordinate instance doesn't have a differential with respect to time"
        in excinfo.exconly())
Esempio n. 3
0
 def _sample(self, time_values, method=mean_motion):
     # if use cowell, propagate to max_time and use other values as intermediate (dense output)
     if method == cowell:
         values, _ = cowell(self, (time_values - self.epoch).to(u.s).value)
         values = values * u.km
     else:
         values = np.zeros((len(time_values), 3)) * self.r.unit
         for ii, epoch in enumerate(time_values):
             rr = self.propagate(epoch, method).r
             values[ii] = rr
     return CartesianRepresentation(values, xyz_axis=1)
Esempio n. 4
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 goto(self, x, y=None):
     if isinstance(x, CartesianRepresentation):
         self._position3D = x
         x_km = self._position3D.x.to(units.kilometer).value
         y_km = self._position3D.y.to(units.kilometer).value
         super().goto(x_km, y_km)
     else:
         super().goto(x, y)
         x_km = super().xcor() * units.kilometer
         y_km = super().ycor() * units.kilometer
         self._position3D = CartesianRepresentation(x_km, y_km, self._position3D.z)
Esempio n. 6
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.
    **kwargs
        Extra kwargs for propagation method.

    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/circular 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."
        )

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

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

    return cartesian
Esempio n. 7
0
    def __init__(self, surface_area, radiance, mass):
        self.radiance = radiance  # power / area / solid angle
        self.surface_area = surface_area
        self.mass = mass

        self.t = 0*u.second

        try:
            self.loc = CartesianRepresentation([0, 0, 0]*u.m)
        except AttributeError:
            pass  # this is OK, because it's when a read-only loc is present
Esempio n. 8
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)
Esempio n. 9
0
def __getarray__(rotate=True, representation='Cylindrical', **kwargs):
    """ This function will create a 2D/3D array from the requested shape in
    kwargs['shape']. It can either return this array into cartesian,
    polar/cylindrical or spherical coordinates. Using the optional rotate
    keyword the array can also be rotated into the plane of the sky. This
    requires the position angle, 'PA', and the inclinatio, 'Incl'.

    Parameters
    ----------
    rotate : 'True' | 'False'
        This will either return the rotated or non-rotated array.
    representation : 'Cylindrical' | 'Cartesian' | 'Spherical'
        Representation to use for the returned array.
    Returns
    -------
    2 or 3 numpy arrays corresponding to the rho, phi, (z) array, the x, y, (z)
    array or the rho, lon, (lat array).
    """

    # create x, y ,and z arrays
    tshape = np.array(kwargs['shape'])
    shape = (tshape[-1], tshape[-2], np.max(tshape))
    Indices = np.indices(shape, dtype=float)

    # translate the array
    Indices[0] = Indices[0] - kwargs['par']['Xcen']
    Indices[1] = Indices[1] - kwargs['par']['Ycen']
    Indices[2] = Indices[2] - int(kwargs['shape'][2] / 2.)

    # make a cartesian representation for matrix rotation
    CarRep = CartesianRepresentation(Indices, unit=u.pix)

    if rotate:
        # rotation due to PA (NOTE different axis definition)
        CarRep = CarRep.transform(
            rm(kwargs['par']['PA'] + np.pi / 2, axis='z', unit=u.rad))

        # rotation due to inclination (NOTE different axis definition)
        CarRep = CarRep.transform(
            rm(kwargs['par']['Incl'], axis='x', unit=u.rad))
    else:
        # rotate by 90 degrees because of definition of PA
        CarRep = CarRep.transform(rm(np.pi / 2, axis='z', unit=u.rad))

    # the representation to use and the return values
    if representation is 'Cartesian':
        return CarRep.x.value, CarRep.y.value, CarRep.z.value
    elif representation is 'Cylindrical':
        Rep = CylindricalRepresentation.from_cartesian(CarRep)
        return Rep.rho.value, Rep.phi.value, Rep.z.value
    elif representation is 'Spherical':
        Rep = SphericalRepresentation.from_cartesian(CarRep)
        return Rep.distance.value, Rep.lon.value, Rep.lat.value
Esempio n. 10
0
    def obsgeo_to_frame(obsgeo, obstime):
        """
        Convert a WCS obsgeo property into an `~builtin_frames.ITRS` coordinate frame.

        Parameters
        ----------
        obsgeo : array-like
            A shape ``(6, )`` array representing ``OBSGEO-[XYZ], OBSGEO-[BLH]`` as
            returned by ``WCS.wcs.obsgeo``.

        obstime : time-like
            The time assiociated with the coordinate, will be passed to
            `~.builtin_frames.ITRS` as the obstime keyword.

        Returns
        -------
        `~.builtin_frames.ITRS`
            An `~.builtin_frames.ITRS` coordinate frame
            representing the coordinates.

        Notes
        -----

        The obsgeo array as accessed on a `.WCS` object is a length 6 numpy array
        where the first three elements are the coordinate in a cartesian
        representation and the second 3 are the coordinate in a spherical
        representation.

        This function priorities reading the cartesian coordinates, and will only
        read the spherical coordinates if the cartesian coordinates are either all
        zero or any of the cartesian coordinates are non-finite.

        In the case where both the spherical and cartesian coordinates have some
        non-finite values the spherical coordinates will be returned with the
        non-finite values included.

        """
        if (obsgeo is None or len(obsgeo) != 6
                or np.all(np.array(obsgeo) == 0)
                or np.all(~np.isfinite(obsgeo))):  # NOQA
            raise ValueError(
                f"Can not parse the 'obsgeo' location ({obsgeo}). "
                "obsgeo should be a length 6 non-zero, finite numpy array")

        # If the cartesian coords are zero or have NaNs in them use the spherical ones
        if np.all(obsgeo[:3] == 0) or np.any(~np.isfinite(obsgeo[:3])):
            data = SphericalRepresentation(*(obsgeo[3:] * (u.deg, u.deg, u.m)))

        # Otherwise we assume the cartesian ones are valid
        else:
            data = CartesianRepresentation(*obsgeo[:3] * u.m)

        return ITRS(data, obstime=obstime)
Esempio n. 11
0
    def to_cartesian(self):
        """Generate a Cartesian representation from a Geodetic one

        Returns
        -------
        CartesianRepresentation
            The Cartesian coordinates corresponding to this representation
        """
        d1, m1 = 1 / u.deg, 1 / u.m
        ecef = turtle.ecef_from_geodetic(self.latitude * d1,
                                         self.longitude * d1, self.height * m1)
        if ecef.size == 3:
            return CartesianRepresentation(ecef[0] * u.m,
                                           ecef[1] * u.m,
                                           ecef[2] * u.m,
                                           copy=False)
        else:
            return CartesianRepresentation(ecef[:, 0] * u.m,
                                           ecef[:, 1] * u.m,
                                           ecef[:, 2] * u.m,
                                           copy=False)
Esempio n. 12
0
 def altaz_interpolate(self, time):
     """Interpolate pointing for a given time."""
     t_new = time.mjd
     t = self.time.mjd
     xyz = self.altaz.cartesian
     x_new = scipy.interpolate.interp1d(t, xyz.x)(t_new)
     y_new = scipy.interpolate.interp1d(t, xyz.y)(t_new)
     z_new = scipy.interpolate.interp1d(t, xyz.z)(t_new)
     xyz_new = CartesianRepresentation(x_new, y_new, z_new)
     altaz_frame = AltAz(obstime=time, location=self.location)
     return SkyCoord(
         xyz_new, frame=altaz_frame, unit="deg", representation_type="unitspherical"
     )
Esempio n. 13
0
    def from_equatorial(equatorial_coo, fixed_frame):
        # TODO replace w/ something smart (Sun/Earth special cased)
        # assert equatorial_coo.body == fixed_frame.body

        r = equatorial_coo.cartesian.xyz

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

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

        if equatorial_coo.data.differentials:
            v = equatorial_coo.data.differentials["s"].d_xyz
            v_trans1 = transform_vector(v, (90 * u.deg + ra), "z")
            v_f = transform_vector(v_trans1, (90 * u.deg - dec), "x")
            v_f = transform_vector(v_f, W, "z")
            data = CartesianRepresentation(
                r_f, differentials=CartesianDifferential(v_f))
        else:
            data = CartesianRepresentation(r_f)
        return fixed_frame.realize_frame(data)
def test_observer_init_rv_behavior():
    """
    Test basic initialization behavior or observer/target and redshift/rv
    """

    # Start off by specifying the radial velocity only
    sc_init = SpectralCoord([4000, 5000] * u.AA,
                            radial_velocity=100 * u.km / u.s)
    assert sc_init.observer is None
    assert sc_init.target is None
    assert_quantity_allclose(sc_init.radial_velocity, 100 * u.km / u.s)

    # Next, set the observer, and check that the radial velocity hasn't changed
    with pytest.warns(AstropyUserWarning,
                      match='No velocity defined on frame'):
        sc_init.observer = ICRS(
            CartesianRepresentation([0 * u.km, 0 * u.km, 0 * u.km]))
    assert sc_init.observer is not None
    assert_quantity_allclose(sc_init.radial_velocity, 100 * u.km / u.s)

    # Setting the target should now cause the original radial velocity to be
    # dropped in favor of the automatically computed one
    sc_init.target = SkyCoord(CartesianRepresentation(
        [1 * u.km, 0 * u.km, 0 * u.km]),
                              frame='icrs',
                              radial_velocity=30 * u.km / u.s)
    assert sc_init.target is not None
    assert_quantity_allclose(sc_init.radial_velocity, 30 * u.km / u.s)

    # The observer can only be set if originally None - now that it isn't
    # setting it again should fail
    with pytest.raises(ValueError, match='observer has already been set'):
        sc_init.observer = GCRS(
            CartesianRepresentation([0 * u.km, 1 * u.km, 0 * u.km]))

    # And similarly, changing the target should not be possible
    with pytest.raises(ValueError, match='target has already been set'):
        sc_init.target = GCRS(
            CartesianRepresentation([0 * u.km, 1 * u.km, 0 * u.km]))
Esempio n. 15
0
def test_regression_6697():
    """
    Test for regression of a bug in get_gcrs_posvel that introduced errors at the 1m/s level.

    Comparison data is derived from calculation in PINT
    https://github.com/nanograv/PINT/blob/master/pint/erfautils.py
    """
    pint_vels = CartesianRepresentation(*(348.63632871, -212.31704928, -0.60154936), unit=u.m/u.s)
    location = EarthLocation(*(5327448.9957829, -1718665.73869569,  3051566.90295403), unit=u.m)
    t = Time(2458036.161966612, format='jd')
    obsgeopos, obsgeovel = location.get_gcrs_posvel(t)
    delta = (obsgeovel-pint_vels).norm()
    assert delta < 1*u.cm/u.s
Esempio n. 16
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. 17
0
def ecef_to_eci(r: np.ndarray, time: Time) -> np.ndarray:
    """
    Converts coordinates in Earth Centered Earth Initial frame to Earth Centered Initial.
    :param r: position of satellite in ECEF frame. Units [km]
    :param time: Time of observation
    """
    itrs = ITRS(CartesianRepresentation(r[0] * u.km, r[1] * u.km, r[2] * u.km),
                obstime=time)
    gcrs = itrs.transform_to(GCRS(obstime=time))
    x_eci = gcrs.cartesian.x.value
    y_eci = gcrs.cartesian.y.value
    z_eci = gcrs.cartesian.z.value
    return np.array([x_eci, y_eci, z_eci])
    def setup(self):
        self.t1 = Time("2013-02-02T23:00")
        self.t2 = Time("2013-08-02T23:00")
        self.tarr = Time(["2013-02-02T23:00", "2013-08-02T23:00"])

        self.sun_icrs_scalar = ICRS(ra=244.52984668 * u.deg,
                                    dec=-22.36943723 * u.deg,
                                    distance=406615.66347377 * u.km)
        # array of positions corresponds to times in `tarr`
        self.sun_icrs_arr = ICRS(ra=[244.52989062, 271.40976248] * u.deg,
                                 dec=[-22.36943605, -25.07431079] * u.deg,
                                 distance=[406615.66347377, 375484.13558956] *
                                 u.km)

        # corresponding HCRS positions
        self.sun_hcrs_t1 = HCRS(CartesianRepresentation([0.0, 0.0, 0.0] *
                                                        u.km),
                                obstime=self.t1)
        twod_rep = CartesianRepresentation(
            [[0.0, 0.0], [0.0, 0.0], [0.0, 0.0]] * u.km)
        self.sun_hcrs_tarr = HCRS(twod_rep, obstime=self.tarr)
        self.tolerance = 5 * u.km
Esempio n. 19
0
def eci_to_ecef(r: np.ndarray, time: Time) -> np.ndarray:
    """
    Converts coordinates in Earth Centered Inertial frame to Earth Centered Earth Fixed.
    :param r: position of satellite in ECI frame. Units [km]
    :param time: Time of observation
    """
    gcrs = GCRS(CartesianRepresentation(r[0] * u.km, r[1] * u.km, r[2] * u.km),
                obstime=time)
    itrs = gcrs.transform_to(ITRS(obstime=time))
    x_ecef = itrs.x.value
    y_ecef = itrs.y.value
    z_ecef = itrs.z.value
    return np.array([x_ecef, y_ecef, z_ecef])
Esempio n. 20
0
    def __init__(self,
                 spots=None,
                 u1=0.4987,
                 u2=0.1772,
                 r=1,
                 radius_threshold=0.1,
                 rotation_period=25 * u.day):
        """
        The star is assumed to have stellar inclination 90 deg (equator-on).

        Parameters
        ----------
        u1 : float (optional)
            Quadratic limb-darkening parameter, linear term
        u2 : float (optional)
            Quadratic limb-darkening parameter, quadratic term
        r : float (optional)
            Stellar radius (default is unity)
        radius_threshold : float (optional)
            If all spots are smaller than this radius, use the analytic solution
            to compute the stellar centroid, otherwise use the numerical
            solution.
        spots : list (optional)
            List of spots on this star.
        rotation_period : `~astropy.units.Quantity`
            Stellar rotation period [default = 25 d].
        contrast : float (optional)
            Spot contrast relative to photosphere. Default is ``c=0.7``
        """
        if spots is None:
            spots = []
        self.spots = spots

        self.spots_cartesian = CartesianRepresentation(
            x=[spot.cartesian.x for spot in spots],
            y=[spot.cartesian.y for spot in spots],
            z=[spot.cartesian.z for spot in spots])
        self.spots_r = np.array([spot.r for spot in spots])
        self.spot_contrasts = np.array([spot.contrast for spot in spots])
        self.x = 0
        self.y = 0
        self.r = r
        self.u1 = u1
        self.u2 = u2
        self.radius_threshold = radius_threshold
        self.rotations_applied = 0 * u.deg
        self.rotation_period = rotation_period
        self.inclination = 90 * u.deg
        self.unspotted_flux = (
            2 * np.pi *
            quad(lambda r: r * self.limb_darkening_normed(r), 0, self.r)[0])
Esempio n. 21
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
def test_icrs_altaz_moonish(testframe):
    """
    Check that something expressed in *ICRS* as being moon-like goes to the
    right AltAz distance
    """
    # we use epv00 instead of get_sun because get_sun includes aberration
    earth_pv_helio, earth_pv_bary = erfa.epv00(*get_jd12(testframe.obstime, 'tdb'))
    earth_icrs_xyz = earth_pv_bary[0]*u.au
    moonoffset = [0, 0, MOONDIST.value]*MOONDIST.unit
    moonish_icrs = ICRS(CartesianRepresentation(earth_icrs_xyz + moonoffset))
    moonaa = moonish_icrs.transform_to(testframe)

    # now check that the distance change is similar to earth radius
    assert 1000*u.km < np.abs(moonaa.distance - MOONDIST).to(u.au) < 7000*u.km
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. 24
0
class EigenFrame(BaseCoordinateFrame):
    """A coordinate frame that has its axes aligned with the principal
    components of a cloud of points."""

    e_x = CartesianRepresentationAttribute(default=CartesianRepresentation(
        1, 0, 0, unit=dimensionless_unscaled),
                                           unit=dimensionless_unscaled)
    e_y = CartesianRepresentationAttribute(default=CartesianRepresentation(
        0, 1, 0, unit=dimensionless_unscaled),
                                           unit=dimensionless_unscaled)
    e_z = CartesianRepresentationAttribute(default=CartesianRepresentation(
        0, 0, 1, unit=dimensionless_unscaled),
                                           unit=dimensionless_unscaled)

    default_representation = CartesianRepresentation

    @classmethod
    def for_coords(cls, coords):
        """Create a coordinate frame that has its axes aligned with the
        principal components of a cloud of points.

        Parameters
        ----------
        coords : astropy.cordinates.SkyCoord
            A cloud of points

        Returns
        -------
        frame : EigenFrame
            A new coordinate frame
        """
        obj = cls()
        v = coords.icrs.cartesian.xyz.value
        _, R = np.linalg.eigh(np.dot(v, v.T))
        R = R[:, ::-1]  # Order by descending eigenvalue
        e_x, e_y, e_z = CartesianRepresentation(R, unit=dimensionless_unscaled)
        return cls(e_x=e_x, e_y=e_y, e_z=e_z)
def test_shift_to_rest_star_withobserver():
    rv = -8.3283011 * u.km / u.s
    rest_line_wls = [5007, 6563] * u.AA

    obstime = time.Time('2018-12-13 9:00')
    eloc = get_greenwich_earthlocation()
    obs = eloc.get_gcrs(obstime)  # always built-in, no download required
    acen = SkyCoord(ra=219.90085 * u.deg,
                    dec=-60.83562 * u.deg,
                    frame='icrs',
                    distance=4.37 * u.lightyear)
    # Note that above the rv is missing from the SkyCoord.
    # That's intended, as it will instead be set in the `SpectralCoord`.  But
    # the SpectralCoord machinery should yield something comparable to test_
    # spectral_coord_alphacen

    with pytest.warns(AstropyUserWarning,
                      match='No velocity defined on frame'):
        observed_spc = SpectralCoord(rest_line_wls * (rv / c + 1),
                                     observer=obs,
                                     target=acen)

    rest_spc = observed_spc.to_rest()
    assert_quantity_allclose(rest_spc, rest_line_wls)

    with pytest.warns(AstropyUserWarning,
                      match='No velocity defined on frame'):
        barycentric_spc = observed_spc._change_observer_to(
            ICRS(CartesianRepresentation([0, 0, 0] * u.au)))
    baryrest_spc = barycentric_spc.to_rest()
    assert quantity_allclose(baryrest_spc, rest_line_wls)

    # now make sure the change the barycentric shift did is comparable to the
    # offset rv_correction produces
    # barytarg = SkyCoord(barycentric_spc.target.frame)  # should be this but that doesn't work for unclear reasons
    barytarg = SkyCoord(barycentric_spc.target.data.without_differentials(),
                        frame=barycentric_spc.target.realize_frame(None))
    vcorr = barytarg.radial_velocity_correction(kind='barycentric',
                                                obstime=obstime,
                                                location=eloc)

    drv = baryrest_spc.radial_velocity - observed_spc.radial_velocity

    # note this probably will not work on the first try, but it's ok if this is
    # "good enough", where good enough is estimated below.  But that could be
    # adjusted if we think that's too agressive of a precision target for what
    # the machinery can handle
    # with pytest.raises(AssertionError):
    assert_quantity_allclose(vcorr, drv, atol=10 * u.m / u.s)
Esempio n. 26
0
def validate_GCRF_to_ITRF(r_vec, v_vec):

    # Compute for the norm of position and velocity vectors
    r_norm, v_norm = [norm(vec) for vec in [r_vec, v_vec]]
    R = Earth_poliastro.R.to(u.m).value

    # Correction factor to normalize position and velocity vectors
    k_r = R / r_norm if r_norm != 0 else 1.00
    k_v = 1 / v_norm if v_norm != 0 else 1.00

    # Make a position vector who's norm is equal to the body's radius. Make a
    # unitary velocity vector. Units are in [m] and [m / s].
    rx, ry, rz = [float(k_r * r_i) for r_i in r_vec]
    vx, vy, vz = [float(k_v * v_i) for v_i in v_vec]

    # orekit: build r_vec and v_vec wrt inertial body frame
    xyz_orekit = Vector3D(rx, ry, rz)
    uvw_orekit = Vector3D(vx, vy, vz)
    coords_GCRF_orekit = TimeStampedPVCoordinates(J2000_OREKIT, xyz_orekit,
                                                  uvw_orekit)

    # orekit: build conversion between GCRF and ITRF
    GCRF_TO_ITRF_OREKIT = GCRF_FRAME_OREKIT.getTransformTo(
        ITRF_FRAME_OREKIT,
        J2000_OREKIT,
    )

    # orekit: convert from GCRF to ITRF using previous built conversion
    coords_ITRF_orekit = (GCRF_TO_ITRF_OREKIT.transformPVCoordinates(
        coords_GCRF_orekit).getPosition().toArray())
    coords_ITRF_orekit = np.asarray(coords_ITRF_orekit) * u.m

    # poliastro: build r_vec and v_vec wrt GCRF
    xyz_poliastro = CartesianRepresentation(rx * u.m, ry * u.m, rz * u.m)
    coords_GCRS_poliastro = GCRS_poliastro(xyz_poliastro)

    # poliastro: convert from inertial to fixed frame at given epoch
    coords_ITRS_poliastro = (coords_GCRS_poliastro.transform_to(
        ITRS_poliastro(
            obstime=J2000_POLIASTRO)).represent_as(CartesianRepresentation).xyz
                             )

    # Check position conversion
    assert_quantity_allclose(
        coords_ITRS_poliastro,
        coords_ITRF_orekit,
        atol=1e-3 * u.m,
        rtol=1e-2,
    )
Esempio n. 27
0
def test_orbit_represent_as_produces_correct_data():
    r = [1e09, -4e09, -1e09] * u.km
    v = [5e00, -1e01, -4e00] * u.km / u.s

    ss = Orbit.from_vectors(Sun, r, v)

    expected_result = CartesianRepresentation(
        *r, differentials=CartesianDifferential(*v))

    result = ss.represent_as(CartesianRepresentation)

    # We can't directly compare the objects, see https://github.com/astropy/astropy/issues/7793
    assert (result.xyz == expected_result.xyz).all()
    assert (result.differentials["s"].d_xyz ==
            expected_result.differentials["s"].d_xyz).all()
Esempio n. 28
0
def test_velocity_hgs_hgc():
    # Construct a simple HGS coordinate with zero velocity
    obstime = Time(['2019-01-01', '2019-04-01', '2019-07-01', '2019-10-01'])
    pos = CartesianRepresentation(1, 0, 0)*u.AU
    vel = CartesianDifferential(0, 0, 0)*u.km/u.s
    loc = (pos.with_differentials(vel))._apply('repeat', obstime.size)
    coord = SkyCoord(HeliographicStonyhurst(loc, obstime=obstime))

    # The induced velocity in HGC should be entirely longitudinal, and approximately equal to one
    # full rotation every mean synodic period (27.2753 days)
    new = coord.heliographic_carrington
    new_vel = new.data.differentials['s'].represent_as(SphericalDifferential, new.data)
    assert_quantity_allclose(new_vel.d_lon, -360*u.deg / (27.27253*u.day), rtol=1e-2)
    assert_quantity_allclose(new_vel.d_lat, 0*u.deg/u.s)
    assert_quantity_allclose(new_vel.d_distance, 0*u.km/u.s, atol=1e-7*u.km/u.s)
Esempio n. 29
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())
def test_galactocentric_loopback(to_frame):
    xyz = CartesianRepresentation(1, 2, 3) * u.pc

    from_coo = Galactocentric(xyz)

    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 position
    assert not allclose(
        explicit_coo.cartesian.xyz, from_coo.cartesian.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)