Пример #1
0
    def reference_plane(self, time):
        """Compute the orbit at specified times in the two-body barycentric
        frame aligned with the reference plane coordinate system (XYZ).

        Parameters
        ----------
        time : array_like, `astropy.time.Time`
            Array of times as barycentric MJD values, or an Astropy
            `~astropy.time.Time` object containing the times to evaluate at.
        """

        xyz = self.orbital_plane(time)
        vxyz = xyz.differentials['s']
        xyz = xyz.without_differentials()

        # Construct rotation matrix to take the orbit from the orbital plane
        # system (xyz) to the reference plane system (XYZ):
        R1 = rotation_matrix(-self.omega, axis='z')
        R2 = rotation_matrix(self.i, axis='x')
        R3 = rotation_matrix(self.Omega, axis='z')
        Rot = matrix_product(R3, R2, R1)

        # Rotate to the reference plane system
        XYZ = coord.CartesianRepresentation(matrix_product(Rot, xyz.xyz))
        VXYZ = coord.CartesianDifferential(matrix_product(Rot, vxyz.d_xyz))
        XYZ = XYZ.with_differentials(VXYZ)

        kw = dict()
        if self.barycenter is not None:
            kw['origin'] = self.barycenter.origin
        return ReferencePlaneFrame(XYZ, **kw)
Пример #2
0
def reference_to_greatcircle(reference_frame, greatcircle_frame):
    """Convert a reference coordinate to a great circle frame."""

    # Define rotation matrices along the position angle vector, and
    # relative to the origin.
    pole = greatcircle_frame.pole.transform_to(coord.ICRS)
    ra0 = greatcircle_frame.ra0

    R_rot = rotation_matrix(greatcircle_frame.rotation, 'z')

    if np.isnan(ra0):
        R2 = rotation_matrix(pole.dec, 'y')
        R1 = rotation_matrix(pole.ra, 'z')
        R = matrix_product(R2, R1)

    else:
        xaxis = np.array([np.cos(ra0), np.sin(ra0), 0.])
        zaxis = pole.cartesian.xyz.value
        xaxis[2] = -(zaxis[0] * xaxis[0] +
                     zaxis[1] * xaxis[1]) / zaxis[2]  # what?
        xaxis = xaxis / np.sqrt(np.sum(xaxis**2))
        yaxis = np.cross(zaxis, xaxis)
        R = np.stack((xaxis, yaxis, zaxis))

    return matrix_product(R_rot, R)
Пример #3
0
def _get_matrix_vectors(gal_frame, inverse=False):
    """
    Utility function: use the ``inverse`` argument to get the inverse transformation, matrix and
    offsets to go from external galaxy frame to ICRS.
    """
    # this is based on the astropy Galactocentric class code
    # shorthand
    gcf = gal_frame

    # rotation matrix to align x(ICRS) with the vector to the galaxy center
    mat0 = np.array([[0., 1., 0.],
                     [0., 0., 1.],
                     [1., 0., 0.]])   # relabel axes so x points in RA, y in dec, z away from us
    mat1 = rotation_matrix(-gcf.gal_coord.dec, 'y')
    mat2 = rotation_matrix(gcf.gal_coord.ra, 'z')

    # construct transformation matrix and use it
    R = matrix_product(mat0, mat1, mat2)

    # Now define translation by distance to galaxy center - best defined in current sky coord system defined by R
    translation = r.CartesianRepresentation(gcf.gal_distance * [0., 0., 1.])

    # Now rotate galaxy to right orientation
    pa_rot = rotation_matrix(-gcf.PA, 'z')
    inc_rot = rotation_matrix(gcf.inclination, 'y')
    H = matrix_product(inc_rot, pa_rot)

    # compute total matrices
    A = matrix_product(H, R)

    # Now we transform the translation vector between sky-aligned and galaxy-aligned frames
    offset = -translation.transform(H)

    if inverse:
        # the inverse of a rotation matrix is a transpose, which is much faster
        #   and more stable to compute
        A = matrix_transpose(A)
        offset = (-offset).transform(A)
        # galvel is given in sky-aligned coords, need to transform to ICRS, so use R transpose
        R = matrix_transpose(R)
        offset_v = r.CartesianDifferential.from_cartesian(
            (gcf.galvel_heliocentric).to_cartesian().transform(R))
        offset = offset.with_differentials(offset_v)

    else:
        # galvel is given in sky-aligned coords, need to transform to gal frame, so use H
        offset_v = r.CartesianDifferential.from_cartesian(
            (-gcf.galvel_heliocentric).to_cartesian().transform(H))
        offset = offset.with_differentials(offset_v)

    return A, offset
Пример #4
0
def fk4_to_gal(fk4coords, galframe):
    mat1 = rotation_matrix(180 - Galactic._lon0_B1950.degree, 'z')
    mat2 = rotation_matrix(90 - Galactic._ngp_B1950.dec.degree, 'y')
    mat3 = rotation_matrix(Galactic._ngp_B1950.ra.degree, 'z')
    matprec = fk4coords._precession_matrix(fk4coords.equinox, EQUINOX_B1950)

    return matrix_product(mat1, mat2, mat3, matprec)
Пример #5
0
def fk4_to_gal(fk4coords, galframe):
    mat1 = rotation_matrix(180 - Galactic._lon0_B1950.degree, 'z')
    mat2 = rotation_matrix(90 - Galactic._ngp_B1950.dec.degree, 'y')
    mat3 = rotation_matrix(Galactic._ngp_B1950.ra.degree, 'z')
    matprec = fk4coords._precession_matrix(fk4coords.equinox, EQUINOX_B1950)

    return matrix_product(mat1, mat2, mat3, matprec)
Пример #6
0
def hcrs_to_hgs(hcrscoord, hgsframe):
    """
    Convert from HCRS to Heliographic Stonyhurst (HGS).

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

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

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

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

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

    return matrix_product(rot_matrix, _SUN_DETILT_MATRIX)
Пример #7
0
def reference_to_skyoffset_matrix(skyoffset_frame):
    """Make rotation matrix from reference frame and a skyoffset frame.

    this function is useful after using astropy to make a rotation matrix
    *modified from reference_to_skyoffset function in astropy

    Parameters
    ----------
    skyoffset_frame : SkyCoord frame
        the rotated frame
        note: SkyCoords are compatible

    Returns
    -------
    R : numpy array
        a 3d rotation matrix

    """
    origin = skyoffset_frame.origin.spherical

    mat1 = rotation_matrix(-skyoffset_frame.rotation, "x")
    mat2 = rotation_matrix(-origin.lat, "y")
    mat3 = rotation_matrix(origin.lon, "z")

    R = matrix_product(mat1, mat2, mat3)
    return R
Пример #8
0
def gcrs_to_geosolarecliptic(gcrs_coo, to_frame):

    if not to_frame.obstime.isscalar:
        raise ValueError(
            "To perform this transformation the obstime Attribute must be a scalar."
        )

    _earth_orbit_perpen_point_gcrs = UnitSphericalRepresentation(
        lon=0 * u.deg,
        lat=(90 * u.deg - _obliquity_rotation_value(to_frame.obstime)))

    _earth_detilt_matrix = _make_rotation_matrix_from_reprs(
        _earth_orbit_perpen_point_gcrs, CartesianRepresentation(0, 0, 1))

    sun_pos_gcrs = get_body("sun", to_frame.obstime).cartesian
    earth_pos_gcrs = get_body("earth", to_frame.obstime).cartesian
    sun_earth = sun_pos_gcrs - earth_pos_gcrs

    sun_earth_detilt = sun_earth.transform(_earth_detilt_matrix)

    # Earth-Sun Line in Geocentric Solar Ecliptic Frame
    x_axis = CartesianRepresentation(1, 0, 0)

    rot_matrix = _make_rotation_matrix_from_reprs(sun_earth_detilt, x_axis)

    return matrix_product(rot_matrix, _earth_detilt_matrix)
Пример #9
0
def hcrs_to_hgs(hcrscoord, hgsframe):
    """
    Convert from HCRS to Heliographic Stonyhurst (HGS).

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

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

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

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

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

    return matrix_product(rot_matrix, _SUN_DETILT_MATRIX)
Пример #10
0
def gcrs_to_geosolarecliptic(gcrs_coo, to_frame):

    if not to_frame.obstime.isscalar:
        raise ValueError(
            "To perform this transformation the obstime Attribute must be a scalar."
        )

    _earth_orbit_perpen_point_gcrs = UnitSphericalRepresentation(
        lon=0 * u.deg, lat=(90 * u.deg - _obliquity_rotation_value(to_frame.obstime))
    )

    _earth_detilt_matrix = _make_rotation_matrix_from_reprs(
        _earth_orbit_perpen_point_gcrs, CartesianRepresentation(0, 0, 1)
    )

    sun_pos_gcrs = get_body("sun", to_frame.obstime).cartesian
    earth_pos_gcrs = get_body("earth", to_frame.obstime).cartesian
    sun_earth = sun_pos_gcrs - earth_pos_gcrs

    sun_earth_detilt = sun_earth.transform(_earth_detilt_matrix)

    # Earth-Sun Line in Geocentric Solar Ecliptic Frame
    x_axis = CartesianRepresentation(1, 0, 0)

    rot_matrix = _make_rotation_matrix_from_reprs(sun_earth_detilt, x_axis)

    return matrix_product(rot_matrix, _earth_detilt_matrix)
Пример #11
0
def get_transform_matrix(from_frame, to_frame):
    """Compose sequential matrix transformations (static or dynamic) to get a
    single transformation matrix from a given path through the Astropy
    transformation machinery.

    Parameters
    ----------
    from_frame : `~astropy.coordinates.BaseCoordinateFrame` subclass
        The *class* or instance of the frame you're transforming from.
    to_frame : `~astropy.coordinates.BaseCoordinateFrame` subclass
        The class or instance of the frame you're transforming to.
    """
    if isinstance(from_frame, coord.BaseCoordinateFrame):
        from_frame_cls = from_frame.__class__
    else:
        from_frame_cls = from_frame

    if isinstance(to_frame, coord.BaseCoordinateFrame):
        to_frame_cls = to_frame.__class__
    else:
        to_frame_cls = to_frame

    path, distance = coord.frame_transform_graph.find_shortest_path(
        from_frame_cls, to_frame_cls)

    matrices = []
    currsys = from_frame
    for p in path[1:]:  # first element is fromsys so we skip it
        if isinstance(currsys, coord.BaseCoordinateFrame):
            currsys_cls = currsys.__class__
        else:
            currsys_cls = currsys
            currsys = currsys_cls()

        trans = coord.frame_transform_graph._graph[currsys_cls][p]

        if isinstance(to_frame, p):
            p = to_frame

        if isinstance(trans, coord.DynamicMatrixTransform):
            M = trans.matrix_func(currsys, p)
        elif isinstance(trans, coord.StaticMatrixTransform):
            M = trans.matrix
        else:
            raise ValueError("Transform path contains a '{0}': cannot "
                             "be composed into a single transformation "
                             "matrix.".format(trans.__class__.__name__))

        matrices.append(M)
        currsys = p

    M = None
    for Mi in reversed(matrices):
        if M is None:
            M = Mi
        else:
            M = matrix_product(M, Mi)

    return M
Пример #12
0
def fk5_to_gal(fk5coord, galframe):
    # need precess to J2000 first
    pmat = fk5coord._precession_matrix(fk5coord.equinox, EQUINOX_J2000)
    mat1 = rotation_matrix(180 - Galactic._lon0_J2000.degree, 'z')
    mat2 = rotation_matrix(90 - Galactic._ngp_J2000.dec.degree, 'y')
    mat3 = rotation_matrix(Galactic._ngp_J2000.ra.degree, 'z')

    return matrix_product(mat1, mat2, mat3, pmat)
Пример #13
0
def fk5_to_gal(fk5coord, galframe):
    # need precess to J2000 first
    pmat = fk5coord._precession_matrix(fk5coord.equinox, EQUINOX_J2000)
    mat1 = rotation_matrix(180 - Galactic._lon0_J2000.degree, 'z')
    mat2 = rotation_matrix(90 - Galactic._ngp_J2000.dec.degree, 'y')
    mat3 = rotation_matrix(Galactic._ngp_J2000.ra.degree, 'z')

    return matrix_product(mat1, mat2, mat3, pmat)
Пример #14
0
def reference_to_skyoffset_matrix(
    lon: T.Union[float, u.Quantity],
    lat: T.Union[float, u.Quantity],
    rotation: T.Union[float, u.Quantity],
) -> T.Sequence:
    """Convert a reference coordinate to an sky offset frame [astropy].

    Cartesian to Cartesian matrix transform.

    Parameters
    ----------
    lon : float or |AngleType| or |Quantity| instance
        For ICRS, the right ascension.
        If float, assumed degrees.
    lat : |AngleType| or |Quantity| instance
        For ICRS, the declination.
        If float, assumed degrees.
    rotation : |AngleType| or |Quantity| instance
        The final rotation of the frame about the ``origin``. The sign of
        the rotation is the left-hand rule.  That is, an object at a
        particular position angle in the un-rotated system will be sent to
        the positive latitude (z) direction in the final frame.
        If float, assumed degrees.

    Returns
    -------
    ndarray
        (3x3) matrix. rotates reference Cartesian to skyoffset Cartesian.

    See Also
    --------
    :func:`~astropy.coordinates.builtin.skyoffset.reference_to_skyoffset`

    References
    ----------
    .. [astropy] Astropy Collaboration, Robitaille, T., Tollerud, E.,
        Greenfield, P., Droettboom, M., Bray, E., Aldcroft, T., Davis,
        M., Ginsburg, A., Price-Whelan, A., Kerzendorf, W., Conley, A.,
        Crighton, N., Barbary, K., Muna, D., Ferguson, H., Grollier, F.,
        Parikh, M., Nair, P., Unther, H., Deil, C., Woillez, J.,
        Conseil, S., Kramer, R., Turner, J., Singer, L., Fox, R.,
        Weaver, B., Zabalza, V., Edwards, Z., Azalee Bostroem, K.,
        Burke, D., Casey, A., Crawford, S., Dencheva, N., Ely, J.,
        Jenness, T., Labrie, K., Lim, P., Pierfederici, F., Pontzen, A.,
        Ptak, A., Refsdal, B., Servillat, M., & Streicher, O. (2013).
        Astropy: A community Python package for astronomy.
        Astronomy and Astrophysics, 558, A33.

    """
    # Define rotation matrices along the position angle vector, and
    # relative to the origin.
    mat1 = rotation_matrix(-rotation, "x")
    mat2 = rotation_matrix(-lat, "y")
    mat3 = rotation_matrix(lon, "z")

    M = matrix_product(mat1, mat2, mat3)

    return M
Пример #15
0
 def _create_matrix(self, phi, theta, psi, axes_order):
     matrices = []
     for angle, axis in zip([phi, theta, psi], axes_order):
         if isinstance(angle, u.Quantity):
             angle = angle.value
         angle = angle.item()
         matrices.append(rotation_matrix(angle, axis, unit=u.rad))
     result = matrix_product(*matrices[::-1])
     return result
Пример #16
0
def reference_to_skyoffset(reference_frame, telescope_frame):
    """Convert a reference coordinate to an sky offset frame."""

    # Define rotation matrices along the position angle vector, and
    # relative to the origin.
    origin = telescope_frame.origin.spherical
    mat1 = rotation_matrix(-origin.lat, 'y')
    mat2 = rotation_matrix(origin.lon, 'z')
    return matrix_product(mat1, mat2)
Пример #17
0
 def _create_matrix(self, phi, theta, psi, axes_order):
     matrices = []
     for angle, axis in zip([phi, theta, psi], axes_order):
         if isinstance(angle, u.Quantity):
             angle = angle.value
         angle = angle.item()
         matrices.append(rotation_matrix(angle, axis, unit=u.rad))
     result = matrix_product(*matrices[::-1])
     return result
Пример #18
0
def _true_ecliptic_rotation_matrix(equinox):
    # This code calls pnm06a from ERFA, which retrieves the precession
    # matrix (including frame bias) according to the IAU 2006 model, and
    # including the nutation. This family of systems is less popular
    # (see https://github.com/astropy/astropy/pull/6508).
    jd1, jd2 = get_jd12(equinox, 'tt')
    rnpb = erfa.pnm06a(jd1, jd2)
    obl = erfa.obl06(jd1, jd2)*u.radian
    return matrix_product(rotation_matrix(obl, 'x'), rnpb)
Пример #19
0
def reference_to_skyoffset(reference_frame, telescope_frame):
    """Convert a reference coordinate to an sky offset frame."""

    # Define rotation matrices along the position angle vector, and
    # relative to the origin.
    origin = telescope_frame.origin.spherical
    mat1 = rotation_matrix(-origin.lat, "y")
    mat2 = rotation_matrix(origin.lon, "z")
    return matrix_product(mat1, mat2)
Пример #20
0
def reference_to_skyoffset(reference_frame, telescope_frame):
    '''Convert a reference coordinate to an sky offset frame.'''

    # Define rotation matrices along the position angle vector, and
    # relative to the telescope_pointing.
    telescope_pointing = telescope_frame.telescope_pointing.spherical
    mat1 = rotation_matrix(-telescope_pointing.lat, 'y')
    mat2 = rotation_matrix(telescope_pointing.lon, 'z')
    return matrix_product(mat1, mat2)
Пример #21
0
def reference_to_greatcircle(reference_frame, greatcircle_frame):
    """Convert a reference coordinate to a great circle frame."""

    # Define rotation matrices along the position angle vector, and
    # relative to the origin.
    pole = greatcircle_frame.pole.transform_to(coord.ICRS())
    ra0 = greatcircle_frame.ra0
    center = greatcircle_frame.center
    R_rot = rotation_matrix(greatcircle_frame.rotation, 'z')

    if not np.isnan(ra0) and np.abs(pole.dec.value) > 1e-15:
        zaxis = pole.cartesian.xyz.value
        xaxis = np.array([np.cos(ra0), np.sin(ra0), 0.])
        if np.abs(zaxis[2]) >= 1e-15:
            xaxis[2] = -(zaxis[0] * xaxis[0] + zaxis[1] * xaxis[1]) / zaxis[2]
        else:
            xaxis[2] = 0.
        xaxis = xaxis / np.sqrt(np.sum(xaxis**2))

        yaxis = np.cross(zaxis, xaxis)
        yaxis = yaxis / np.sqrt(np.sum(yaxis**2))

        R = np.stack((xaxis, yaxis, zaxis))

    elif center is not None:
        R1 = rotation_matrix(pole.ra, 'z')
        R2 = rotation_matrix(90 * u.deg - pole.dec, 'y')
        Rtmp = matrix_product(R2, R1)

        rot = center.cartesian.transform(Rtmp)
        rot_lon = rot.represent_as(coord.UnitSphericalRepresentation).lon
        R3 = rotation_matrix(rot_lon, 'z')
        R = matrix_product(R3, R2, R1)

    else:
        if not np.isnan(ra0) and np.abs(pole.dec.value) < 1e-15:
            warn("Ignoring input ra0 because the pole is along dec=0",
                 RuntimeWarning)

        R1 = rotation_matrix(pole.ra, 'z')
        R2 = rotation_matrix(90 * u.deg - pole.dec, 'y')
        R = matrix_product(R2, R1)

    return matrix_product(R_rot, R)
Пример #22
0
def get_matrix_vectors(galactocentric_frame, inverse=False):
    """
    Use the ``inverse`` argument to get the inverse transformation, matrix and
    offsets to go from Galactocentric to ICRS.
    """
    # shorthand
    gcf = galactocentric_frame

    # rotation matrix to align x(ICRS) with the vector to the Galactic center
    mat1 = rotation_matrix(-gcf.galcen_coord.dec, 'y')
    mat2 = rotation_matrix(gcf.galcen_coord.ra, 'z')
    # extra roll away from the Galactic x-z plane
    mat0 = rotation_matrix(gcf.get_roll0() - gcf.roll, 'x')

    # construct transformation matrix and use it
    R = matrix_product(mat0, mat1, mat2)

    # Now need to translate by Sun-Galactic center distance around x' and
    # rotate about y' to account for tilt due to Sun's height above the plane
    translation = r.CartesianRepresentation(gcf.galcen_distance * [1., 0., 0.])
    z_d = gcf.z_sun / gcf.galcen_distance
    H = rotation_matrix(-np.arcsin(z_d), 'y')

    # compute total matrices
    A = matrix_product(H, R)

    # Now we re-align the translation vector to account for the Sun's height
    # above the midplane
    offset = -translation.transform(H)

    if inverse:
        # the inverse of a rotation matrix is a transpose, which is much faster
        #   and more stable to compute
        A = matrix_transpose(A)
        offset = (-offset).transform(A)
        offset_v = r.CartesianDifferential.from_cartesian(
            (-gcf.galcen_v_sun).to_cartesian().transform(A))
        offset = offset.with_differentials(offset_v)

    else:
        offset = offset.with_differentials(gcf.galcen_v_sun)

    return A, offset
Пример #23
0
    def reference_to_skyoffset(reference_frame, skyoffset_frame):
        """Convert a reference coordinate to an sky offset frame."""

        # Define rotation matrices along the position angle vector, and
        # relative to the origin.
        origin = skyoffset_frame.origin.spherical
        mat1 = rotation_matrix(-skyoffset_frame.rotation, 'x')
        mat2 = rotation_matrix(-origin.lat, 'y')
        mat3 = rotation_matrix(origin.lon, 'z')
        return matrix_product(mat1, mat2, mat3)
Пример #24
0
def aligned3D_to_projected(X, Y, Z, inc):
    XYZ = np.array([X.to('pc').value,
                    Y.to('pc').value,
                    Z.to('pc').value]) * u.pc
    M = rotate(inc)
    xyz = matrix_product(M, XYZ)
    x = xyz[0, :]
    y = xyz[1, :]
    z = xyz[2, :]
    return x, y, z
Пример #25
0
def fk4_no_e_to_fk5(fk4noecoord, fk5frame):
    # Correction terms for FK4 being a rotating system
    B = _fk4_B_matrix(fk4noecoord.obstime)

    # construct both precession matricies - if the equinoxes are B1950 and
    # J2000, these are just identity matricies
    pmat1 = fk4noecoord._precession_matrix(fk4noecoord.equinox, EQUINOX_B1950)
    pmat2 = fk5frame._precession_matrix(EQUINOX_J2000, fk5frame.equinox)

    return matrix_product(pmat2, B, pmat1)
Пример #26
0
def cylin_to_aligned3D_vels(vR, vphi, vz, phi):
    M = np.array([[np.cos(phi), -np.sin(phi), 0],
                  [np.sin(phi), np.cos(phi), 0], [0, 0, 1]])
    vR, vphi, vz = np.atleast_1d(vR), np.atleast_1d(vphi), np.atleast_1d(vz)
    v_cylin = np.array(
        [vR.to('km/s').value,
         vphi.to('km/s').value,
         vz.to('km/s').value])
    v_cartesian = matrix_product(M, v_cylin)
    return v_cartesian * u.km / u.s
Пример #27
0
def fk4_no_e_to_fk5(fk4noecoord, fk5frame):
    # Correction terms for FK4 being a rotating system
    B = _fk4_B_matrix(fk4noecoord.obstime)

    # construct both precession matricies - if the equinoxes are B1950 and
    # J2000, these are just identity matricies
    pmat1 = fk4noecoord._precession_matrix(fk4noecoord.equinox, EQUINOX_B1950)
    pmat2 = fk5frame._precession_matrix(EQUINOX_J2000, fk5frame.equinox)

    return matrix_product(pmat2, B, pmat1)
Пример #28
0
def _mean_ecliptic_rotation_matrix(equinox):
    # This code calls pmat06 from ERFA, which retrieves the precession
    # matrix (including frame bias) according to the IAU 2006 model, but
    # leaves out the nutation. This matches what ERFA does in the ecm06
    # function and also brings the results closer to what other libraries
    # give (see https://github.com/astropy/astropy/pull/6508).
    jd1, jd2 = get_jd12(equinox, 'tt')
    rbp = erfa.pmat06(jd1, jd2)
    obl = erfa.obl06(jd1, jd2)*u.radian
    return matrix_product(rotation_matrix(obl, 'x'), rbp)
Пример #29
0
def get_matrix_vectors(galactocentric_frame, inverse=False):
    """
    Use the ``inverse`` argument to get the inverse transformation, matrix and
    offsets to go from Galactocentric to ICRS.
    """
    # shorthand
    gcf = galactocentric_frame

    # rotation matrix to align x(ICRS) with the vector to the Galactic center
    mat1 = rotation_matrix(-gcf.galcen_coord.dec, 'y')
    mat2 = rotation_matrix(gcf.galcen_coord.ra, 'z')
    # extra roll away from the Galactic x-z plane
    mat0 = rotation_matrix(gcf.get_roll0() - gcf.roll, 'x')

    # construct transformation matrix and use it
    R = matrix_product(mat0, mat1, mat2)

    # Now need to translate by Sun-Galactic center distance around x' and
    # rotate about y' to account for tilt due to Sun's height above the plane
    translation = r.CartesianRepresentation(gcf.galcen_distance * [1., 0., 0.])
    z_d = gcf.z_sun / gcf.galcen_distance
    H = rotation_matrix(-np.arcsin(z_d), 'y')

    # compute total matrices
    A = matrix_product(H, R)

    # Now we re-align the translation vector to account for the Sun's height
    # above the midplane
    offset = -translation.transform(H)

    if inverse:
        # the inverse of a rotation matrix is a transpose, which is much faster
        #   and more stable to compute
        A = matrix_transpose(A)
        offset = (-offset).transform(A)
        offset_v = r.CartesianDifferential.from_cartesian(
            (-gcf.galcen_v_sun).to_cartesian().transform(A))
        offset = offset.with_differentials(offset_v)

    else:
        offset = offset.with_differentials(gcf.galcen_v_sun)

    return A, offset
Пример #30
0
def cb_crs_to_cb_j2000_eq(cb_crs_coord, _):
    """Conversion from Celestial Reference System of a Central Body
    to its Local Equatorial at J2000 Epoch Reference System."""

    ra, dec, w = celestial_body_rot_params(None, cb_crs_coord.body_name)

    body_crs_to_body_eq = matrix_product(
        rotation_matrix(90 * u.deg - dec, "x"),
        rotation_matrix(90 * u.deg + ra, "z"))

    return body_crs_to_body_eq
Пример #31
0
def fk5_to_fk4_no_e(fk5coord, fk4noeframe):
    # Get transposed version of the rotating correction terms... so with the
    # transpose this takes us from FK5/J200 to FK4/B1950
    B = matrix_transpose(_fk4_B_matrix(fk4noeframe.obstime))

    # construct both precession matricies - if the equinoxes are B1950 and
    # J2000, these are just identity matricies
    pmat1 = fk5coord._precession_matrix(fk5coord.equinox, EQUINOX_J2000)
    pmat2 = fk4noeframe._precession_matrix(EQUINOX_B1950, fk4noeframe.equinox)

    return matrix_product(pmat2, B, pmat1)
Пример #32
0
def body_crs_to_body_eq_matrix(obstime, body_name):
    """Computes the rotation matrix from Celestial Body CRS to
    Local Equatorial True-of-Date Reference System."""
    ra, dec, w = celestial_body_rot_params(obstime, body_name)

    body_crs_to_body_eq = matrix_product(
        rotation_matrix(90 * u.deg - dec, "x"),
        rotation_matrix(90 * u.deg + ra, "z"),
    )

    return body_crs_to_body_eq
Пример #33
0
def fk5_to_fk4_no_e(fk5coord, fk4noeframe):
    # Get transposed version of the rotating correction terms... so with the
    # transpose this takes us from FK5/J200 to FK4/B1950
    B = matrix_transpose(_fk4_B_matrix(fk4noeframe.obstime))

    # construct both precession matricies - if the equinoxes are B1950 and
    # J2000, these are just identity matricies
    pmat1 = fk5coord._precession_matrix(fk5coord.equinox, EQUINOX_J2000)
    pmat2 = fk4noeframe._precession_matrix(EQUINOX_B1950, fk4noeframe.equinox)

    return matrix_product(pmat2, B, pmat1)
Пример #34
0
def _ecliptic_rotation_matrix(equinox):
    # This code calls pmat06 from ERFA, which retrieves the precession
    # matrix (including frame bias) according to the IAU 2006 model, but
    # leaves out the nutation. This matches what ERFA does in the ecm06
    # function and also brings the results closer to what other libraries
    # give (see https://github.com/astropy/astropy/pull/6508). However,
    # notice that this makes the name "TrueEcliptic" misleading, and might
    # be changed in the future (discussion in the same pull request)
    jd1, jd2 = get_jd12(equinox, 'tt')
    rbp = erfa.pmat06(jd1, jd2)
    obl = erfa.obl06(jd1, jd2) * u.radian
    return matrix_product(rotation_matrix(obl, 'x'), rbp)
Пример #35
0
def _ecliptic_rotation_matrix(equinox):
    # This code calls pmat06 from ERFA, which retrieves the precession
    # matrix (including frame bias) according to the IAU 2006 model, but
    # leaves out the nutation. This matches what ERFA does in the ecm06
    # function and also brings the results closer to what other libraries
    # give (see https://github.com/astropy/astropy/pull/6508). However,
    # notice that this makes the name "TrueEcliptic" misleading, and might
    # be changed in the future (discussion in the same pull request)
    jd1, jd2 = get_jd12(equinox, 'tt')
    rbp = erfa.pmat06(jd1, jd2)
    obl = erfa.obl06(jd1, jd2)*u.radian
    return matrix_product(rotation_matrix(obl, 'x'), rbp)
Пример #36
0
def body_crs_to_body_fixed_matrix(obstime, body_name):
    """Computes the rotation matrix from Celestial Body CRS to
    Body Fixed Reference System."""
    ra, dec, w = celestial_body_rot_params(obstime, body_name)

    body_crs_to_body_fixed = matrix_product(
        rotation_matrix(w, "z"),
        rotation_matrix(90 * u.deg - dec, "x"),
        rotation_matrix(90 * u.deg + ra, "z"),
    )

    return body_crs_to_body_fixed
Пример #37
0
def projected_to_aligned3D(x, y, z, inc):
    unit = x.unit
    x = x.to(unit)
    y = y.to(unit)
    z = z.to(unit)
    xyz = np.array([x.value, y.value, z.value]) * unit
    M = rotate(inc).T
    XYZ = matrix_product(M, xyz)
    X = XYZ[0, :]
    Y = XYZ[1, :]
    Z = XYZ[2, :]
    return X, Y, Z
def icrs_to_arbpole(icrs_coord, arbpole_frame):

    roll = arbpole_frame.roll
    pole = arbpole_frame.pole

    # Align z(new) with direction to M31
    mat1 = rotation_matrix(-pole.dec, 'y')
    mat2 = rotation_matrix(pole.ra, 'z')
    mat3 = rotation_matrix(roll, 'z')
    mat4 = rotation_matrix(90 * u.degree, 'y')
    R = matrix_product(mat4, mat1, mat2, mat3)

    return R
Пример #39
0
def _icrs_to_fk5_matrix():
    """
    B-matrix from USNO circular 179.  Used by the ICRS->FK5 transformation
    functions.
    """

    eta0 = -19.9 / 3600000.
    xi0 = 9.1 / 3600000.
    da0 = -22.9 / 3600000.

    m1 = rotation_matrix(-eta0, 'x')
    m2 = rotation_matrix(xi0, 'y')
    m3 = rotation_matrix(da0, 'z')

    return matrix_product(m1, m2, m3)
Пример #40
0
def _rotation_matrix_hme_to_hee(hmeframe):
    """
    Return the rotation matrix from HME to HEE at the same observation time
    """
    # Get the Sun-Earth vector
    sun_earth = HCRS(_sun_earth_icrf(hmeframe.obstime), obstime=hmeframe.obstime)
    sun_earth_hme = sun_earth.transform_to(hmeframe).cartesian

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

    # Tilt the rotated Sun-Earth vector so that it is aligned with the X axis
    tilt_matrix = _rotation_matrix_reprs_to_reprs(sun_earth_hme.transform(rot_matrix),
                                                  CartesianRepresentation(1, 0, 0))

    return matrix_product(tilt_matrix, rot_matrix)
Пример #41
0
def get_transform_matrix(from_frame, to_frame):
    """Compose sequential matrix transformations (static or dynamic) to get a
    single transformation matrix from a given path through the Astropy
    transformation machinery.

    Parameters
    ----------
    from_frame : `~astropy.coordinates.BaseCoordinateFrame` subclass
        The *class* of the frame you're transforming from.
    to_frame : `~astropy.coordinates.BaseCoordinateFrame` subclass
        The *class* of the frame you're transfrorming to.
    """
    path, distance = coord.frame_transform_graph.find_shortest_path(
        from_frame, to_frame)

    matrices = []
    currsys = from_frame
    for p in path[1:]:  # first element is fromsys so we skip it
        trans = coord.frame_transform_graph._graph[currsys][p]
        if isinstance(trans, coord.DynamicMatrixTransform):
            M = trans.matrix_func(currsys(), p)
        elif isinstance(trans, coord.StaticMatrixTransform):
            M = trans.matrix
        else:
            raise ValueError("Transform path contains a '{0}': cannot "
                             "be composed into a single transformation "
                             "matrix.".format(trans.__class__.__name__))

        matrices.append(M)
        currsys = p

    M = None
    for Mi in reversed(matrices):
        if M is None:
            M = Mi
        else:
            M = matrix_product(M, Mi)

    return M
Пример #42
0
def _rotate_polygon(lon, lat, lon0, lat0):
    """
    Given a polygon with vertices defined by (lon, lat), rotate the polygon
    such that the North pole of the spherical coordinates is now at (lon0,
    lat0). Therefore, to end up with a polygon centered on (lon0, lat0), the
    polygon should initially be drawn around the North pole.
    """

    # Create a representation object
    polygon = UnitSphericalRepresentation(lon=lon, lat=lat)

    # Determine rotation matrix to make it so that the circle is centered
    # on the correct longitude/latitude.
    m1 = rotation_matrix(-(0.5 * np.pi * u.radian - lat0), axis='y')
    m2 = rotation_matrix(-lon0, axis='z')
    transform_matrix = matrix_product(m2, m1)

    # Apply 3D rotation
    polygon = polygon.to_cartesian()
    polygon = polygon.transform(transform_matrix)
    polygon = UnitSphericalRepresentation.from_cartesian(polygon)

    return polygon.lon, polygon.lat
Пример #43
0
Файл: sgr.py Проект: adrn/gala
        r = super().represent_as(base, s=s, in_frame_units=in_frame_units)
        r.lon.wrap_angle = self._default_wrap_angle
        return r
    represent_as.__doc__ = coord.BaseCoordinateFrame.represent_as.__doc__

# Define the Euler angles (from Law & Majewski 2010)
phi = (180+3.75) * u.degree
theta = (90-13.46) * u.degree
psi = (180+14.111534) * u.degree

# Generate the rotation matrix using the x-convention (see Goldstein)
D = rotation_matrix(phi, "z")
C = rotation_matrix(theta, "x")
B = rotation_matrix(psi, "z")
A = np.diag([1.,1.,-1.])
R = matrix_product(A, B, C, D)

# Galactic to Sgr coordinates
@frame_transform_graph.transform(coord.StaticMatrixTransform, coord.Galactic,
                                 SagittariusLaw10)
def galactic_to_sgr():
    """ Compute the transformation from Galactic spherical to
        heliocentric Sagittarius coordinates.
    """
    return R

# Sgr to Galactic coordinates
@frame_transform_graph.transform(coord.StaticMatrixTransform, SagittariusLaw10,
                                 coord.Galactic)
def sgr_to_galactic():
    """ Compute the transformation from heliocentric Sagittarius coordinates to
Пример #44
0
        r = super().represent_as(base, s=s, in_frame_units=in_frame_units)
        r.lon.wrap_angle = self._default_wrap_angle
        return r
    represent_as.__doc__ = coord.BaseCoordinateFrame.represent_as.__doc__


# Define the Euler angles
phi = 128.79 * u.degree
theta = 54.39 * u.degree
psi = 90.70 * u.degree

# Generate the rotation matrix using the x-convention (see Goldstein)
D = rotation_matrix(phi, "z")
C = rotation_matrix(theta, "x")
B = rotation_matrix(psi, "z")
R = matrix_product(B, C, D)

@frame_transform_graph.transform(coord.StaticMatrixTransform, coord.Galactic,
                                 OrphanNewberg10)
def galactic_to_orp():
    """ Compute the transformation from Galactic spherical to
        heliocentric Orphan coordinates.
    """
    return R

# Oph to Galactic coordinates
@frame_transform_graph.transform(coord.StaticMatrixTransform, OrphanNewberg10,
                                 coord.Galactic)
def oph_to_galactic():
    """ Compute the transformation from heliocentric Orphan coordinates to
        spherical Galactic.
Пример #45
0
def gal_to_mag():
    mat1 = rotation_matrix(57.275785782128686*u.deg, 'z')
    mat2 = rotation_matrix(90*u.deg - MagellanicStreamNidever08._ngp.b, 'y')
    mat3 = rotation_matrix(MagellanicStreamNidever08._ngp.l, 'z')

    return matrix_product(mat1, mat2, mat3)
Пример #46
0
# the new system. Because the transformation to the Sagittarius coordinate
# system is just a spherical rotation from Galactic coordinates, we'll just
# define a function that returns this matrix. We'll start by constructing the
# transformation matrix using pre-deteremined Euler angles and the
# ``rotation_matrix`` helper function:

SGR_PHI = (180 + 3.75) * u.degree # Euler angles (from Law & Majewski 2010)
SGR_THETA = (90 - 13.46) * u.degree
SGR_PSI = (180 + 14.111534) * u.degree

# Generate the rotation matrix using the x-convention (see Goldstein)
D = rotation_matrix(SGR_PHI, "z")
C = rotation_matrix(SGR_THETA, "x")
B = rotation_matrix(SGR_PSI, "z")
A = np.diag([1.,1.,-1.])
SGR_MATRIX = matrix_product(A, B, C, D)

##############################################################################
# Since we already constructed the transformation (rotation) matrix above, and
# the inverse of a rotation matrix is just its transpose, the required
# transformation functions are very simple:

@frame_transform_graph.transform(coord.StaticMatrixTransform, coord.Galactic, Sagittarius)
def galactic_to_sgr():
    """ Compute the transformation matrix from Galactic spherical to
        heliocentric Sgr coordinates.
    """
    return SGR_MATRIX

##############################################################################
# The decorator ``@frame_transform_graph.transform(coord.StaticMatrixTransform,
Пример #47
0
def gal_to_supergal():
    mat1 = rotation_matrix(90, 'z')
    mat2 = rotation_matrix(90 - Supergalactic._nsgp_gal.b.degree, 'y')
    mat3 = rotation_matrix(Supergalactic._nsgp_gal.l.degree, 'z')
    return matrix_product(mat1, mat2, mat3)