Ejemplo n.º 1
0
def cross(a, b):
    """
    Compute cross product of two CartesianRepresentations.

    Parameters
    ----------
    a : `CartesianRepresentation`
        First CartesianRepresentation, e.g directions to earth
    b : `CartesianRepresentation`
        Second CartesianRepresentation, e.g directions of tiles

    Returns
    -------
    cross_product : `CartesianRepresentation`
        array of cross products. If `a` has shape (N, M) and `b` has shape (K,L)
        returned Quantity has shape (N, M, K, L)
    """
    # since the data can be n-dimensional, reshape
    # to a 2-d (3, N) array
    xyz_a, xyz_b = a.xyz, b.xyz
    orig_shape_a = xyz_a.shape
    orig_shape_b = xyz_b.shape
    xyz_a = xyz_a.reshape((3, xyz_a.size // 3))
    xyz_b = xyz_b.reshape((3, xyz_b.size // 3))

    # take the cross product
    cross_product = np.cross(xyz_a[:, :, np.newaxis], xyz_b,
                             axisa=0, axisb=0, axisc=0)
    cross_product_unit = xyz_a.unit * xyz_b.unit
    cross_product = u.Quantity(cross_product, unit=cross_product_unit)

    cartrep = CartesianRepresentation(cross_product)
    return cartrep.reshape(orig_shape_a[1:] + orig_shape_b[1:])
Ejemplo n.º 2
0
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)
Ejemplo n.º 3
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)
Ejemplo n.º 4
0
def test_plot_ephem_different_plane_raises_error():
    unused_epochs = Time.now().reshape(-1)
    unused_coordinates = CartesianRepresentation(
        [(1, 0, 0)] * u.au,
        xyz_axis=1,
        differentials=CartesianDifferential([(0, 1, 0)] * (u.au / u.day),
                                            xyz_axis=1),
    )

    op = StaticOrbitPlotter(plane=Planes.EARTH_ECLIPTIC)
    op.set_attractor(Sun)
    op.set_body_frame(Earth)
    with pytest.raises(ValueError) as excinfo:
        op.plot_ephem(
            Ephem(unused_epochs, unused_coordinates, Planes.EARTH_EQUATOR))

    assert (
        "sample the ephemerides using a different plane or create a new plotter"
        in excinfo.exconly())
Ejemplo n.º 5
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 = interp1d(t, xyz.x)(t_new)
        y_new = interp1d(t, xyz.y)(t_new)
        z_new = interp1d(t, xyz.z)(t_new)
        xyz_new = CartesianRepresentation(x_new, y_new, z_new)
        altaz_frame = AltAz(obstime=time, location=self.location)

        # FIXME: an API change in Astropy in 3.1 broke this
        # See https://github.com/gammapy/gammapy/pull/1906
        if astropy_version >= "3.1":
            kwargs = {"representation_type": "unitspherical"}
        else:
            kwargs = {"representation": "unitspherical"}

        return SkyCoord(xyz_new, frame=altaz_frame, unit="deg", **kwargs)
Ejemplo n.º 6
0
    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.coordinates.SkyCoord`
            A cloud of points

        Returns
        -------
        frame : `EigenFrame`
            A new coordinate frame
        """
        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)
Ejemplo n.º 7
0
def test_hgs_hcc_sunspice():
    # Compare our HGS->HCC transformation against SunSPICE
    # "HEQ" is another name for HEEQ, which is equivalent to Heliographic Stonyhurst
    # "HGRTN" is equivalent to our Heliocentric, but with the axes permuted
    # SunSPICE, like us, assumes an Earth observer if not explicitly specified
    #
    # IDL> coord = [7d5, 8d5, 9d5]
    # IDL> convert_sunspice_coord, '2019-06-01', coord, 'HEQ', 'HGRTN'
    # Assuming Earth observation
    # IDL> print, coord
    #        688539.32       800000.00       908797.89

    old = SkyCoord(CartesianRepresentation([7e5, 8e5, 9e5]*u.km),
                   frame=HeliographicStonyhurst(obstime='2019-06-01'))
    new = old.heliocentric

    assert_quantity_allclose(new.x, 800000.00*u.km, atol=1e-2*u.km)
    assert_quantity_allclose(new.y, 908797.89*u.km, atol=1e-2*u.km)
    assert_quantity_allclose(new.z, 688539.32*u.km, atol=1e-2*u.km)
Ejemplo n.º 8
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 init_pvt(self._frame_name, t, coords)
Ejemplo n.º 9
0
    def represent_as(self, representation):
        """Converts the orbit to a specific representation.

        .. versionadded:: 0.11.0

        Parameters
        ----------
        representation : ~astropy.coordinates.BaseRepresentation
            Representation object to use. It must be a class, not an instance.

        Examples
        --------
        >>> from poliastro.examples import iss
        >>> from astropy.coordinates import CartesianRepresentation, SphericalRepresentation
        >>> iss.represent_as(CartesianRepresentation)
        <CartesianRepresentation (x, y, z) in km
            (859.07256, -4137.20368, 5295.56871)
         (has differentials w.r.t.: 's')>
        >>> iss.represent_as(CartesianRepresentation).xyz
        <Quantity [  859.07256, -4137.20368,  5295.56871] km>
        >>> iss.represent_as(CartesianRepresentation).differentials['s']
        <CartesianDifferential (d_x, d_y, d_z) in km / s
            (7.37289205, 2.08223573, 0.43999979)>
        >>> iss.represent_as(CartesianRepresentation).differentials['s'].d_xyz
        <Quantity [7.37289205, 2.08223573, 0.43999979] km / s>
        >>> iss.represent_as(SphericalRepresentation)
        <SphericalRepresentation (lon, lat, distance) in (rad, rad, km)
            (4.91712525, 0.89732339, 6774.76995296)
         (has differentials w.r.t.: 's')>

        """
        # As we do not know the differentials, we first convert to cartesian,
        # then let the frame represent_as do the rest
        # TODO: Perhaps this should be public API as well?
        cartesian = CartesianRepresentation(
            *self.r, differentials=CartesianDifferential(*self.v))
        # See the propagate function for reasoning about the usage of a
        # protected method
        coords = self.frame._replicate(cartesian,
                                       representation_type="cartesian")

        return coords.represent_as(representation)
Ejemplo n.º 10
0
def _interpolate_sinc(epochs, reference_epochs, coordinates):
    def _interp_1d(arr):
        return _sinc_interp(arr, reference_epochs.jd, epochs.jd)

    xyz_unit = coordinates.xyz.unit
    d_xyz_unit = coordinates.differentials["s"].d_xyz.unit

    x = _interp_1d(coordinates.x.value) * xyz_unit
    y = _interp_1d(coordinates.y.value) * xyz_unit
    z = _interp_1d(coordinates.z.value) * xyz_unit

    d_x = _interp_1d(coordinates.differentials["s"].d_x.value) * d_xyz_unit
    d_y = _interp_1d(coordinates.differentials["s"].d_y.value) * d_xyz_unit
    d_z = _interp_1d(coordinates.differentials["s"].d_z.value) * d_xyz_unit

    return CartesianRepresentation(x,
                                   y,
                                   z,
                                   differentials=CartesianDifferential(
                                       d_x, d_y, d_z))
Ejemplo n.º 11
0
def test_orbit_creation_using_skycoord(attractor):
    vel = [0, 2, 0] * u.km / u.s
    cartdiff = CartesianDifferential(*vel)

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

    coord = SkyCoord(cartrep, frame="icrs")
    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 (o.r == pos_transformed_to_irf).all()
    assert (o.v == vel_transformed_to_irf).all()
Ejemplo n.º 12
0
    def _create_coord_from_offset(observer, radial_velocity):
        """
        Generates a default target or observer from a provided observer or
        target with an offset defined such as to create the provided radial
        velocity.

        Parameters
        ----------
        observer : `~astropy.coordinates.BaseCoordinateFrame` or `~astropy.coordinates.SkyCoord`
            Observer frame off which to base the target frame.
        radial_velocity : `~astropy.units.Quantity`
            Radial velocity used to calculate appropriate offsets between
            provided observer and generated target.

        Returns
        -------
        target : `~astropy.coordinates.BaseCoordinateFrame` or `~astropy.coordinates.SkyCoord`
            Generated target frame.
        """

        # The generated observer or target will be set up along the same y and z
        # coordinates as the target or observer, but offset along the x direction

        observer_icrs = observer.transform_to(ICRS)

        d = observer_icrs.cartesian.norm()
        drep = CartesianRepresentation(
            [DEFAULT_DISTANCE.to(d.unit), 0 * d.unit, 0 * d.unit])

        obs_vel = observer_icrs.cartesian.differentials['s']

        target = (observer_icrs.cartesian.without_differentials() +
                  drep).with_differentials(
                      CartesianDifferential([
                          _relativistic_velocity_addition(
                              obs_vel.d_x, radial_velocity),
                          obs_vel.d_y.to(radial_velocity.unit),
                          obs_vel.d_z.to(radial_velocity.unit)
                      ]))

        return observer_icrs.realize_frame(target)
Ejemplo n.º 13
0
def teme_to_tirs(teme_coord, tirs_frame):
    # TEME to TIRS basic rotation matrix
    teme_to_pef_mat = rotation_matrix(_gmst82_angle(teme_coord.obstime),
                                      axis='z')

    # rotate position vector: TEME to TIRS
    r_tirs = teme_coord.cartesian.transform(teme_to_pef_mat)

    # prepare rotation offset: w x r_TIRS
    wxr = CartesianRepresentation(_w).cross(r_tirs)

    # do the velocity rotation and then add rotation offset
    v_tirs = teme_coord.velocity.to_cartesian().transform(
        teme_to_pef_mat) - wxr
    v_tirs = CartesianDifferential.from_cartesian(v_tirs)

    # Prepare final coord vector with velocity
    tirs_coord = r_tirs.with_differentials(v_tirs)

    # Add coord data to the existing frame
    return tirs_frame.realize_frame(tirs_coord)
def translate(cls, translation_vector):
    """
    Apply a coordinate translation.

    Parameters
    ----------
    cls : astropy.coordinates.CartesianRepresentation
        Equivalent to the 'self' argument for methods.

    translation_vector : astropy.units.Quantity, with dimensions of length
        3-vector by which to translate.

    Returns
    -------
    out : astropy.coordinates.CartesianRepresentation
        A new CartesianRepresentation instance with translation applied.
    """

    return CartesianRepresentation(cls.__class__.get_xyz(cls) +
                                   translation_vector.reshape(3, 1),
                                   differentials=cls.differentials)
Ejemplo n.º 15
0
def test_orbit_creation_using_frame_obj(attractor, frame, obstime):
    vel = [0, 2, 0] * u.km / u.s
    cartdiff = CartesianDifferential(*vel)

    pos = [30_000, 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)
Ejemplo n.º 16
0
    def _sample(self, time_values, method=mean_motion):
        positions = method(self, time_values.to(u.s).value)

        data = CartesianRepresentation(positions[0] * u.km, xyz_axis=1)

        # If the frame supports obstime, set the time values
        kwargs = {}
        if "obstime" in self.frame.frame_attributes:
            kwargs["obstime"] = self.epoch + time_values
        else:
            warn(
                "Frame {} does not support 'obstime', time values were not returned".format(
                    self.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 self.frame._replicate(data, representation_type="cartesian", **kwargs)
Ejemplo n.º 17
0
def test_from_orbit_has_desired_properties(method, rtol):
    epochs = Time(
        [
            "2020-02-01 12:00:00",
            "2020-02-13 12:00:00",
            "2020-03-04 12:00:00",
            "2020-03-17 12:00:00",
        ]
    )
    expected_coordinates = CartesianRepresentation(
        [
            (336.77109079, -1447.38211842, -743.72094119),
            (-1133.43957703, 449.41297342, 3129.10416554),
            (201.42480053, -1978.64139325, -287.25776291),
            (-1084.94556884, -1713.5357774, 3298.72284309),
        ]
        * u.km,
        xyz_axis=1,
        differentials=CartesianDifferential(
            [
                (-2.68502706, -14.85798508, 9.66683585),
                (1.36841306, 7.30080155, -4.88822441),
                (-3.46999908, -10.04899184, 11.19715233),
                (-1.46069855, 5.88696886, 3.28112281),
            ]
            * (u.km / u.s),
            xyz_axis=1,
        ),
    )

    r = [-1000, -2000, 3100] * u.km
    v = [-1.836, 5.218, 4.433] * u.km / u.s
    orb = Orbit.from_vectors(Earth, r, v)

    unused_plane = Planes.EARTH_EQUATOR
    ephem = Ephem.from_orbit(orbit=orb, epochs=epochs, plane=unused_plane)
    coordinates = ephem.sample()

    assert ephem.epochs is epochs
    assert_coordinates_allclose(coordinates, expected_coordinates, rtol=rtol)
Ejemplo 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)

    # 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)

    # Add coord data to the existing frame
    return teme_frame.realize_frame(teme_coord)
Ejemplo n.º 19
0
    def _target_from_observer(observer, radial_velocity):
        """
        Generates a default target from a provided observer with an offset
        defined such as to create the provided radial velocity.

        Parameters
        ----------
        observer : `~astropy.coordinates.BaseCoordinateFrame` or `~astropy.coordinates.SkyCoord`
            Observer frame off which to base the target frame.
        radial_velocity : `~astropy.units.Quantity`
            Radial velocity used to calculate appropriate offsets between
            provided observer and generated target.

        Returns
        -------
        target : `~astropy.coordinates.BaseCoordinateFrame` or `~astropy.coordinates.SkyCoord`
            Generated target frame.
        """
        observer = SpectralCoord._validate_coordinate(observer)
        observer_icrs = observer.transform_to(ICRS)

        d = observer_icrs.cartesian.norm()
        drep = CartesianRepresentation(
            [DEFAULT_DISTANCE.to(d.unit), 0 * d.unit, 0 * d.unit])

        obs_vel = observer_icrs.cartesian.differentials['s']
        tot_rv = radial_velocity  # + observer_icrs.radial_velocity

        target = (observer_icrs.cartesian.without_differentials() +
                  drep).with_differentials(
                      CartesianDifferential([
                          obs_vel.d_x + tot_rv,
                          obs_vel.d_y.to(tot_rv.unit),
                          obs_vel.d_z.to(tot_rv.unit)
                      ]))

        target = observer_icrs.realize_frame(target)

        return target
Ejemplo n.º 20
0
def nominal_to_altaz(altaz_coord,norm_coord):
    """
    Transformation from astropy AltAz system to nominal system

    Parameters
    ----------
    altaz_coord: AltAz system
    norm_coord: nominal system

    Returns
    -------
    nominal Coordinates
    """
    alt_norm,az_norm = norm_coord.array_direction
    az = altaz_coord.az
    alt = altaz_coord.alt
    x,y = altaz_to_offset(az,alt,az_norm,alt_norm)
    x=x*u.rad
    y=y*u.rad
    representation = CartesianRepresentation(x.to(u.deg),y.to(u.deg),0*u.deg)

    return norm_coord.realize_frame(representation)
Ejemplo n.º 21
0
    def rotate(self, angle):
        """
        Rotate the star, by moving the spots.

        Parameters
        ----------
        angle : `~astropy.units.Quantity`

        """
        remove_is = rotation_matrix(-self.inclination, axis='x')
        rotate = rotation_matrix(angle, axis='z')
        add_is = rotation_matrix(self.inclination, axis='x')

        transform_matrix = matrix_product(remove_is, rotate, add_is)

        for spot in self.spots:
            cartesian = CartesianRepresentation(
                x=spot.x, y=spot.y, z=spot.z).transform(transform_matrix)
            spot.x = cartesian.x.value
            spot.y = cartesian.y.value
            spot.z = cartesian.z.value
        self.rotations_applied += angle
Ejemplo n.º 22
0
def select_tidal_annulus(w0,\
                    ann_low = 0.0,\
                    ann_high = 0.5,\
                    sat_mass=1e8,\
                    mw_mass=130.0075e10,\
                    mw_c=32.089):
    com_p, com_v, com_index = calc_com(w0)


    distances_to_com =\
        np.linalg.norm((w0.pos - CartesianRepresentation(com_p)).xyz, axis=0)

    tidal_radius = r_tidal(sat_mass, mw_mass, mw_c, np.linalg.norm(com_p))

    selected_indices = []

    for p_index in range(len(distances_to_com)):
        curr_dist = distances_to_com[p_index]
        if (ann_low * tidal_radius) <= curr_dist < (ann_high * tidal_radius):
            selected_indices.append(p_index)

    return w0[selected_indices]
Ejemplo n.º 23
0
def telescope_to_camera(telescope_coord, camera_frame):
    '''
    Transformation between TelescopeFrame and CameraFrame

    Is called when a SkyCoord is transformed from TelescopeFrame into CameraFrame
    '''
    x_pos = telescope_coord.delta_alt
    y_pos = telescope_coord.delta_az
    # reverse the rotation applied to get to this system
    rot = -camera_frame.rotation

    if rot.value == 0.0:  # if no rotation applied save a few cycles
        x_rotated = x_pos
        y_rotated = y_pos
    else:  # or else rotate all positions around the camera centre
        cosrot = np.cos(rot)
        sinrot = np.sin(rot)
        x_rotated = x_pos * cosrot - y_pos * sinrot
        y_rotated = x_pos * sinrot + y_pos * cosrot

    focal_length = camera_frame.focal_length

    # this assumes an equidistant mapping function of the telescope optics
    # or a small angle approximation of most other mapping functions
    # this could be replaced by actually defining the mapping function
    # as an Attribute of `CameraFrame` that maps f(theta, focal_length) -> r,
    # where theta is the angle to the optical axis and r is the distance
    # to the camera center in the focal plane
    x_rotated = x_rotated.to_value(u.rad) * focal_length
    y_rotated = y_rotated.to_value(u.rad) * focal_length

    representation = CartesianRepresentation(
        x_rotated,
        y_rotated,
        0 * u.m
    )

    return camera_frame.realize_frame(representation)
Ejemplo n.º 24
0
    def interpolate(self, epochs, reference_epochs, coordinates):
        xyz_unit = coordinates.xyz.unit
        d_xyz_unit = coordinates.differentials["s"].d_xyz.unit

        result_xyz = (
            spline_interp(
                coordinates.xyz.value, reference_epochs.jd, epochs.jd, kind=self._kind
            )
            << xyz_unit
        )
        result_d_xyz = (
            spline_interp(
                coordinates.differentials["s"].d_xyz.value,
                reference_epochs.jd,
                epochs.jd,
                kind=self._kind,
            )
            << d_xyz_unit
        )

        return CartesianRepresentation(
            result_xyz, differentials=CartesianDifferential(result_d_xyz)
        )
Ejemplo n.º 25
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 = init_pvt(TEME, time_list, pos_list)

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

    return {"traj": trajectory, "sat": sat}
Ejemplo n.º 26
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)
def test_regression_6300():
    """Check that importing old frame attribute names from astropy.coordinates
    still works. See comments at end of #6300
    """
    from astropy.utils.exceptions import AstropyDeprecationWarning
    from astropy.coordinates import CartesianRepresentation
    from astropy.coordinates import (TimeFrameAttribute,
                                     QuantityFrameAttribute,
                                     CartesianRepresentationFrameAttribute)

    with catch_warnings() as found_warnings:
        attr = TimeFrameAttribute(default=Time("J2000"))

        for w in found_warnings:
            if issubclass(w.category, AstropyDeprecationWarning):
                break
        else:
            assert False, "Deprecation warning not raised"

    with catch_warnings() as found_warnings:
        attr = QuantityFrameAttribute(default=5 * u.km)

        for w in found_warnings:
            if issubclass(w.category, AstropyDeprecationWarning):
                break
        else:
            assert False, "Deprecation warning not raised"

    with catch_warnings() as found_warnings:
        attr = CartesianRepresentationFrameAttribute(
            default=CartesianRepresentation([5, 6, 7] * u.kpc))

        for w in found_warnings:
            if issubclass(w.category, AstropyDeprecationWarning):
                break
        else:
            assert False, "Deprecation warning not raised"
Ejemplo n.º 28
0
def _interpolate_splines(epochs,
                         reference_epochs,
                         coordinates,
                         *,
                         kind="cubic"):
    xyz_unit = coordinates.xyz.unit
    d_xyz_unit = coordinates.differentials["s"].d_xyz.unit

    # TODO: Avoid building interpolant every time?
    # Does it have a performance impact?
    interpolant_xyz = interp1d(reference_epochs.jd,
                               coordinates.xyz.value,
                               kind=kind)
    interpolant_d_xyz = interp1d(
        reference_epochs.jd,
        coordinates.differentials["s"].d_xyz.value,
        kind=kind,
    )

    result_xyz = interpolant_xyz(epochs.jd) * xyz_unit
    result_d_xyz = interpolant_d_xyz(epochs.jd) * d_xyz_unit

    return CartesianRepresentation(
        result_xyz, differentials=CartesianDifferential(result_d_xyz))
Ejemplo n.º 29
0
def test_array_coordinates_creation():
    """
    Test creating coordinates from arrays.
    """
    c = ICRS(np.array([1, 2])*u.deg, np.array([3, 4])*u.deg)
    assert not c.ra.isscalar

    with pytest.raises(ValueError):
        c = ICRS(np.array([1, 2])*u.deg, np.array([3, 4, 5])*u.deg)
    with pytest.raises(ValueError):
        c = ICRS(np.array([1, 2, 4, 5])*u.deg, np.array([[3, 4], [5, 6]])*u.deg)

    # make sure cartesian initialization also works
    cart = CartesianRepresentation(x=[1., 2.]*u.kpc, y=[3., 4.]*u.kpc, z=[5., 6.]*u.kpc)
    c = ICRS(cart)

    # also ensure strings can be arrays
    c = SkyCoord(['1d0m0s', '2h02m00.3s'], ['3d', '4d'])

    # but invalid strings cannot
    with pytest.raises(ValueError):
        c = SkyCoord(Angle(['10m0s', '2h02m00.3s']), Angle(['3d', '4d']))
    with pytest.raises(ValueError):
        c = SkyCoord(Angle(['1d0m0s', '2h02m00.3s']), Angle(['3x', '4d']))
Ejemplo n.º 30
0
    def earth_location_itrf(self, time=None):
        '''Return NuSTAR spacecraft location in ITRF coordinates'''

        if self.tt2tdb_mode.lower().startswith('pint'):
            # log.warning('Using location=None for TT to TDB conversion')
            return None
        elif self.tt2tdb_mode.lower().startswith('astropy'):
            # First, interpolate ECI geocentric location from orbit file.
            # These are inertial coorinates aligned with ICRF
            log.warning('Performing GCRS to ITRS transformation')
            pos_gcrs =  GCRS(CartesianRepresentation(self.X(time.tt.mjd)*u.m,
                                                     self.Y(time.tt.mjd)*u.m,
                                                     self.Z(time.tt.mjd)*u.m),
                             obstime=time)

            # Now transform ECI (GCRS) to ECEF (ITRS)
            # By default, this uses the WGS84 ellipsoid
            pos_ITRS = pos_gcrs.transform_to(ITRS(obstime=time))

            # Return geocentric ITRS coordinates as an EarthLocation object
            return pos_ITRS.earth_location
        else:
            log.error('Unknown tt2tdb_mode %s, using None' % self.tt2tdb_mode)
            return None
Ejemplo n.º 31
0
def telescope_to_nominal(tel_coord,norm_frame):
    """
    Coordinate transformation from telescope frame to nominal frame

    Parameters
    ----------
    tel_coord: TelescopeFrame system
    norm_frame: NominalFrame system

    Returns
    -------
    NominalFrame coordinates
    """
    alt_tel,az_tel = tel_coord.pointing_direction
    alt_norm,az_norm = norm_frame.array_direction

    alt_trans,az_trans = offset_to_altaz(tel_coord.x,tel_coord.y,az_tel,alt_tel)
    x,y = altaz_to_offset(az_trans,alt_trans,az_norm,alt_norm)
    x = x*u.rad
    y = y*u.rad

    representation = CartesianRepresentation(x.to(tel_coord.x.unit),y.to(tel_coord.x.unit),0*tel_coord.x.unit)

    return norm_frame.realize_frame(representation)
Ejemplo n.º 32
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)
Ejemplo n.º 33
0
def telescope_to_camera(telescope_coord, camera_frame):
    """
    Transformation between TelescopeFrame and CameraFrame

    Parameters
    ----------
    telescope_coord: `astropy.coordinates.SkyCoord`
        TelescopeFrame system
    camera_frame: `astropy.coordinates.SkyCoord`
        CameraFrame system

    Returns
    -------
    CameraFrame Coordinates
    """
    x_pos = telescope_coord.cartesian.x
    y_pos = telescope_coord.cartesian.y
    # reverse the rotation applied to get to this system
    rot = camera_frame.rotation * -1

    if rot == 0:  # if no rotation applied save a few cycles
        x_rotated = x_pos
        y_rotated = y_pos
    else:  # or else rotate all positions around the camera centre
        x_rotated = x_pos * cos(rot) - y_pos * sin(rot)
        y_rotated = x_pos * sin(rot) + y_pos * cos(rot)

    focal_length = camera_frame.focal_length
    # Remove distance units here as we are using small angle approx
    x_rotated = x_rotated.to(u.rad) * (focal_length / u.m)
    y_rotated = y_rotated.to(u.rad) * (focal_length / u.m)

    representation = CartesianRepresentation(x_rotated.value * u.m,
                                             y_rotated.value * u.m, 0 * u.m)

    return camera_frame.realize_frame(representation)
Ejemplo n.º 34
0
def add_oriented_radecs(elvis_tab, hostidx=0, targetidx=1,
                        target_coord=SkyCoord(0*u.deg, 0*u.deg),
                        earth_distance=8.5*u.kpc, earth_vrot=220*u.km/u.s,
                        roll_angle=0*u.deg):
    """
    Computes a spherical coordinate system centered on the `hostidx` halo,
    re-oriented so that `targetidx` is at the `target_coord` coordinate
    location.

    Note that this adds columns 'host<n>_*' to
    `elvis_tab`, and will *overwrite* them if  they already exist.
    """
    if hasattr(target_coord, 'spherical'):
        target_lat = target_coord.spherical.lat
        target_lon = target_coord.spherical.lon
    else:
        target_lat = target_coord.lat
        target_lon = target_coord.lon

    def offset_repr(rep, vector, newrep=None):
        if newrep is None:
            newrep = rep.__class__
        newxyz = rep.to_cartesian().xyz + vector.reshape(3, 1)
        return CartesianRepresentation(newxyz).represent_as(newrep)

    def rotate_repr(rep, matrix, newrep=None):
        if newrep is None:
            newrep = rep.__class__
        newxyz = np.dot(matrix.view(np.ndarray), rep.to_cartesian().xyz)
        return CartesianRepresentation(newxyz).represent_as(newrep)

    rep = CartesianRepresentation(elvis_tab['X'], elvis_tab['Y'], elvis_tab['Z'])
    # first we offset the catalog to have its origin at host
    rep = offset_repr(rep, -rep.xyz[:, hostidx])

    # now rotate so that host1 is along the z-axis, and apply the arbitrary roll angle
    usph = rep.represent_as(UnitSphericalRepresentation)
    M1 = rotation_matrix(usph.lon[targetidx], 'z')
    M2 = rotation_matrix(90*u.deg-usph.lat[targetidx], 'y')
    M3 = rotation_matrix(roll_angle, 'z')
    Mfirst = M3*M2*M1
    rep = rotate_repr(rep, Mfirst)

    # now determine the location of the earth in this system
    # need diagram to explain this, but it uses SSA formula
    theta = target_coord.separation(galactic_center)  # target to GC angle
    D = rep.z[targetidx]  # distance to the target host
    R = earth_distance
    # srho = (R/D) * np.sin(theta)
    # sdelta_p = (srho * np.cos(theta) + (1 - srho**2)**0.5)
    # sdelta_m = (srho * np.cos(theta) - (1 - srho**2)**0.5)
    d1, d2 = R * np.cos(theta), (D**2 - (R * np.sin(theta))**2)**0.5
    dp, dm = d1 + d2, d1 - d2
    sdelta = (dp/D) * np.sin(theta)

    x = R * sdelta
    z = R * (1-sdelta**2)**0.5
    earth_location = u.Quantity([x, 0*u.kpc, z])

    # now offset to put earth at the origin
    rep = offset_repr(rep, -earth_location)
    sph = rep.represent_as(SphericalRepresentation)

    # rotate to put the target at its correct spot
    # first sent the target host to 0,0
    M1 = rotation_matrix(sph[targetidx].lon, 'z')
    M2 = rotation_matrix(-sph[targetidx].lat, 'y')
    # now rotate from origin to target lat,lon
    M3 = rotation_matrix(target_lat, 'y')
    M4 = rotation_matrix(-target_lon, 'z')
    Mmiddle = M4*M3*M2*M1
    rep = rotate_repr(rep, Mmiddle)

    # now one more rotation about the target to stick the GC in the right place
    def tomin(ang, inrep=rep[hostidx], axis=rep[targetidx].xyz, target=galactic_center.icrs):
        newr = rotate_repr(inrep, rotation_matrix(ang[0]*u.deg, axis))
        return ICRS(newr).separation(target).radian
    rot_angle = optimize.minimize(tomin, np.array(0).ravel(), method='Nelder-Mead')['x'][0]
    Mlast = rotation_matrix(rot_angle*u.deg, rep[targetidx].xyz)
    rep = rotate_repr(rep, Mlast)

    sph = rep.represent_as(SphericalRepresentation)
    elvis_tab['host{}_lat'.format(hostidx)] = sph.lat.to(u.deg)
    elvis_tab['host{}_lon'.format(hostidx)] = sph.lon.to(u.deg)
    elvis_tab['host{}_dist'.format(hostidx)] = sph.distance

    # now compute  velocities
    # host galactocentric
    dvxg = u.Quantity((elvis_tab['Vx'])-elvis_tab['Vx'][hostidx])
    dvyg = u.Quantity((elvis_tab['Vy'])-elvis_tab['Vy'][hostidx])
    dvzg = u.Quantity((elvis_tab['Vz'])-elvis_tab['Vz'][hostidx])

    earth_location_in_xyz = np.dot(Mfirst.T, earth_location)
    dxg = elvis_tab['X'] - elvis_tab['X'][0] - earth_location_in_xyz[0]
    dyg = elvis_tab['Y'] - elvis_tab['Y'][0] - earth_location_in_xyz[0]
    dzg = elvis_tab['Z'] - elvis_tab['Z'][0] - earth_location_in_xyz[0]
    vrg = (dvxg*dxg + dvyg*dyg + dvzg*dzg) * (dxg**2+dyg**2+dzg**2)**-0.5
    elvis_tab['host{}_galvr'.format(hostidx)] = vrg.to(u.km/u.s)

    # "vLSR-like"
    # first figure out the rotation direction
    earth_rotdir = SkyCoord(90*u.deg, 0*u.deg, frame='galactic').icrs

    #now apply the component from that everywhere
    offset_angle = earth_rotdir.separation(ICRS(sph))
    vrlsr = vrg - earth_vrot*np.cos(offset_angle)

    elvis_tab['host{}_vrlsr'.format(hostidx)] = vrlsr.to(u.km/u.s)