Example #1
0
def fk4_to_fk4_no_e(fk4coord, fk4noeframe):
    # Extract cartesian vector
    rep = fk4coord.cartesian

    # Find distance (for re-normalization)
    d_orig = rep.norm()
    rep /= d_orig

    # Apply E-terms of aberration. Note that this depends on the equinox (not
    # the observing time/epoch) of the coordinates. See issue #1496 for a
    # discussion of this.
    eterms_a = CartesianRepresentation(
        u.Quantity(fk4_e_terms(fk4coord.equinox), u.dimensionless_unscaled,
                   copy=False), copy=False)
    rep = rep - eterms_a + eterms_a.dot(rep) * rep

    # Find new distance (for re-normalization)
    d_new = rep.norm()

    # Renormalize
    rep *= d_orig / d_new

    # now re-cast into an appropriate Representation, and precess if need be
    if isinstance(fk4coord.data, UnitSphericalRepresentation):
        rep = rep.represent_as(UnitSphericalRepresentation)

    # if no obstime was given in the new frame, use the old one for consistency
    newobstime = fk4coord._obstime if fk4noeframe._obstime is None else fk4noeframe._obstime

    fk4noe = FK4NoETerms(rep, equinox=fk4coord.equinox, obstime=newobstime)
    if fk4coord.equinox != fk4noeframe.equinox:
        # precession
        fk4noe = fk4noe.transform_to(fk4noeframe)
    return fk4noe
Example #2
0
def _sun_north_angle_to_z(frame):
    """
    Return the angle between solar north and the Z axis of the provided frame's coordinate system
    and observation time.
    """
    # Find the Sun center in HGS at the frame's observation time(s)
    sun_center_repr = SphericalRepresentation(0*u.deg, 0*u.deg, 0*u.km)
    # The representation is repeated for as many times as are in obstime prior to transformation
    sun_center = SkyCoord(sun_center_repr._apply('repeat', frame.obstime.size),
                          frame=HGS, obstime=frame.obstime)

    # Find the Sun north in HGS at the frame's observation time(s)
    # Only a rough value of the solar radius is needed here because, after the cross product,
    #   only the direction from the Sun center to the Sun north pole matters
    sun_north_repr = SphericalRepresentation(0*u.deg, 90*u.deg, 690000*u.km)
    # The representation is repeated for as many times as are in obstime prior to transformation
    sun_north = SkyCoord(sun_north_repr._apply('repeat', frame.obstime.size),
                         frame=HGS, obstime=frame.obstime)

    # Find the Sun center and Sun north in the frame's coordinate system
    sky_normal = sun_center.transform_to(frame).data.to_cartesian()
    sun_north = sun_north.transform_to(frame).data.to_cartesian()

    # Use cross products to obtain the sky projections of the two vectors (rotated by 90 deg)
    sun_north_in_sky = sun_north.cross(sky_normal)
    z_in_sky = CartesianRepresentation(0, 0, 1).cross(sky_normal)

    # Normalize directional vectors
    sky_normal /= sky_normal.norm()
    sun_north_in_sky /= sun_north_in_sky.norm()
    z_in_sky /= z_in_sky.norm()

    # Calculate the signed angle between the two projected vectors
    cos_theta = sun_north_in_sky.dot(z_in_sky)
    sin_theta = sun_north_in_sky.cross(z_in_sky).dot(sky_normal)
    angle = np.arctan2(sin_theta, cos_theta).to('deg')

    # If there is only one time, this function's output should be scalar rather than array
    if angle.size == 1:
        angle = angle[0]

    return Angle(angle)
Example #3
0
def _rotation_matrix_hgs_to_hci(obstime):
    """
    Return the rotation matrix from HGS to HCI at the same observation time
    """
    z_axis = CartesianRepresentation(0, 0, 1) * u.m
    if not obstime.isscalar:
        z_axis = z_axis._apply('repeat', obstime.size)

    # Get the ecliptic pole in HGS
    ecliptic_pole = HeliocentricMeanEcliptic(z_axis,
                                             obstime=obstime,
                                             equinox=_J2000)
    ecliptic_pole_hgs = ecliptic_pole.transform_to(
        HeliographicStonyhurst(obstime=obstime))

    # Rotate the ecliptic pole to the -YZ plane, which aligns the solar ascending node with the X
    # axis
    rot_matrix = _rotation_matrix_reprs_to_xz_about_z(
        ecliptic_pole_hgs.cartesian)
    xz_to_yz_matrix = rotation_matrix(-90 * u.deg, 'z')

    return xz_to_yz_matrix @ rot_matrix
Example #4
0
def altaz_to_enu(altaz_coo, enu_frame):
    '''Defines the transformation between AltAz and the ENU frame.
    AltAz usually has units attached but ENU does not require units 
    if it specifies a direction.'''
    is_directional = (isinstance(altaz_coo.data, UnitSphericalRepresentation)
                      or altaz_coo.cartesian.x.unit == u.one)

    if is_directional:
        rep = CartesianRepresentation(x=altaz_coo.cartesian.y,
                                      y=altaz_coo.cartesian.x,
                                      z=altaz_coo.cartesian.z,
                                      copy=False)
    else:
        location_altaz = ITRS(
            *enu_frame.location.to_geocentric()).transform_to(
                AltAz(location=enu_frame.location, obstime=enu_frame.obstime))
        rep = CartesianRepresentation(
            x=altaz_coo.cartesian.y - location_altaz.cartesian.y,
            y=altaz_coo.cartesian.x - location_altaz.cartesian.x,
            z=altaz_coo.cartesian.z - location_altaz.cartesian.z,
            copy=False)
    return enu_frame.realize_frame(rep)
def gcrs_to_icrs(gcrs_coo, icrs_frame):
    srepr = gcrs_coo.represent_as(SphericalRepresentation)
    gcrs_ra = srepr.lon.to_value(u.radian)
    gcrs_dec = srepr.lat.to_value(u.radian)

    # set up the astrometry context for ICRS<->GCRS and then convert to BCRS
    # coordinate direction
    obs_pv = pav2pv(
        gcrs_coo.obsgeoloc.get_xyz(xyz_axis=-1).to_value(u.m),
        gcrs_coo.obsgeovel.get_xyz(xyz_axis=-1).to_value(u.m / u.s))

    jd1, jd2 = get_jd12(gcrs_coo.obstime, 'tdb')

    earth_pv, earth_heliocentric = prepare_earth_position_vel(gcrs_coo.obstime)
    astrom = erfa.apcs(jd1, jd2, obs_pv, earth_pv, earth_heliocentric)

    i_ra, i_dec = aticq(gcrs_ra, gcrs_dec, astrom)

    if gcrs_coo.data.get_name(
    ) == 'unitspherical' or gcrs_coo.data.to_cartesian().x.unit == u.one:
        # if no distance, just use the coordinate direction to yield the
        # infinite-distance/no parallax answer
        newrep = UnitSphericalRepresentation(lat=u.Quantity(i_dec,
                                                            u.radian,
                                                            copy=False),
                                             lon=u.Quantity(i_ra,
                                                            u.radian,
                                                            copy=False),
                                             copy=False)
    else:
        # When there is a distance, apply the parallax/offset to the SSB as the
        # last step - ensures round-tripping with the icrs_to_gcrs transform

        # the distance in intermedrep is *not* a real distance as it does not
        # include the offset back to the SSB
        intermedrep = SphericalRepresentation(lat=u.Quantity(i_dec,
                                                             u.radian,
                                                             copy=False),
                                              lon=u.Quantity(i_ra,
                                                             u.radian,
                                                             copy=False),
                                              distance=srepr.distance,
                                              copy=False)

        astrom_eb = CartesianRepresentation(astrom['eb'],
                                            unit=u.au,
                                            xyz_axis=-1,
                                            copy=False)
        newrep = intermedrep + astrom_eb

    return icrs_frame.realize_frame(newrep)
Example #6
0
File: fk4.py Project: zonca/astropy
def fk4_no_e_to_fk4(fk4noecoord, fk4frame):
    # first precess, if necessary
    if fk4noecoord.equinox != fk4frame.equinox:
        fk4noe_w_fk4equinox = FK4NoETerms(equinox=fk4frame.equinox,
                                          obstime=fk4noecoord.obstime)
        fk4noecoord = fk4noecoord.transform_to(fk4noe_w_fk4equinox)

    # Extract cartesian vector
    rep = fk4noecoord.cartesian

    # Find distance (for re-normalization)
    d_orig = rep.norm()
    rep /= d_orig

    # Apply E-terms of aberration. Note that this depends on the equinox (not
    # the observing time/epoch) of the coordinates. See issue #1496 for a
    # discussion of this.
    eterms_a = CartesianRepresentation(u.Quantity(fk4_e_terms(
        fk4noecoord.equinox),
                                                  u.dimensionless_unscaled,
                                                  copy=False),
                                       copy=False)

    rep0 = rep.copy()
    for _ in range(10):
        rep = (eterms_a + rep0) / (1. + eterms_a.dot(rep))

    # Find new distance (for re-normalization)
    d_new = rep.norm()

    # Renormalize
    rep *= d_orig / d_new

    # now re-cast into an appropriate Representation, and precess if need be
    if isinstance(fk4noecoord.data, UnitSphericalRepresentation):
        rep = rep.represent_as(UnitSphericalRepresentation)

    return fk4frame.realize_frame(rep)
Example #7
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
    # (The additional transpose operations are to handle both scalar and array obstime situations)
    hgs_x_axis_detilt = CartesianRepresentation((sun_earth_detilt.xyz.T * [1, 1, 0]).T)

    # The above vector, which is in the Sun's equatorial plane, is also the X axis of HGS
    x_axis = CartesianRepresentation(1, 0, 0)
    if hgsframe.obstime.isscalar:
        rot_matrix = _make_rotation_matrix_from_reprs(hgs_x_axis_detilt, x_axis)
    else:
        rot_matrix_list = [_make_rotation_matrix_from_reprs(vect, x_axis) for vect in hgs_x_axis_detilt]
        rot_matrix = np.stack(rot_matrix_list)

    return matrix_product(rot_matrix, _SUN_DETILT_MATRIX)
Example #8
0
def gse_to_hee(gsecoord, heeframe):
    """
    Convert from Geocentric Solar Ecliptic to Heliocentric Earth Ecliptic
    """
    # First transform the GSE coord to the HEE obstime
    int_coord = _transform_obstime(gsecoord, heeframe.obstime)

    if int_coord.obstime is None:
        raise ConvertError("To perform this transformation, the coordinate"
                           " frame needs a specified `obstime`.")

    # Import here to avoid a circular import
    from .sun import earth_distance

    # Find the Sun-object vector in the intermediate frame
    earth_sun_int = earth_distance(int_coord.obstime) * CartesianRepresentation(1, 0, 0)
    sun_object_int = int_coord.cartesian - earth_sun_int

    # Flip the vector in X and Y, but leave Z untouched
    # (The additional transpose operations are to handle both scalar and array inputs)
    newrepr = CartesianRepresentation((sun_object_int.xyz.T * [-1, -1, 1]).T)

    return heeframe._replicate(newrepr, obstime=int_coord.obstime)
def icrs_to_cirs(icrs_coo, cirs_frame):
    # first set up the astrometry context for ICRS<->CIRS
    jd1, jd2 = get_jd12(cirs_frame.obstime, 'tt')
    x, y, s = get_cip(jd1, jd2)
    earth_pv, earth_heliocentric = prepare_earth_position_vel(
        cirs_frame.obstime)
    # erfa.apci requests TDB but TT can be used instead of TDB without any significant impact on accuracy
    astrom = erfa.apci(jd1, jd2, earth_pv, earth_heliocentric, x, y, s)

    if icrs_coo.data.get_name(
    ) == 'unitspherical' or icrs_coo.data.to_cartesian().x.unit == u.one:
        # if no distance, just do the infinite-distance/no parallax calculation
        usrepr = icrs_coo.represent_as(UnitSphericalRepresentation)
        i_ra = usrepr.lon.to_value(u.radian)
        i_dec = usrepr.lat.to_value(u.radian)
        cirs_ra, cirs_dec = atciqz(i_ra, i_dec, astrom)

        newrep = UnitSphericalRepresentation(lat=u.Quantity(cirs_dec,
                                                            u.radian,
                                                            copy=False),
                                             lon=u.Quantity(cirs_ra,
                                                            u.radian,
                                                            copy=False),
                                             copy=False)
    else:
        # When there is a distance,  we first offset for parallax to get the
        # astrometric coordinate direction and *then* run the ERFA transform for
        # no parallax/PM. This ensures reversibility and is more sensible for
        # inside solar system objects
        astrom_eb = CartesianRepresentation(astrom['eb'],
                                            unit=u.au,
                                            xyz_axis=-1,
                                            copy=False)
        newcart = icrs_coo.cartesian - astrom_eb

        srepr = newcart.represent_as(SphericalRepresentation)
        i_ra = srepr.lon.to_value(u.radian)
        i_dec = srepr.lat.to_value(u.radian)
        cirs_ra, cirs_dec = atciqz(i_ra, i_dec, astrom)

        newrep = SphericalRepresentation(lat=u.Quantity(cirs_dec,
                                                        u.radian,
                                                        copy=False),
                                         lon=u.Quantity(cirs_ra,
                                                        u.radian,
                                                        copy=False),
                                         distance=srepr.distance,
                                         copy=False)

    return cirs_frame.realize_frame(newrep)
def observed_to_icrs(observed_coo, icrs_frame):
    # if the data are UnitSphericalRepresentation, we can skip the distance calculations
    is_unitspherical = (isinstance(observed_coo.data,
                                   UnitSphericalRepresentation)
                        or observed_coo.cartesian.x.unit == u.one)

    usrepr = observed_coo.represent_as(UnitSphericalRepresentation)
    lon = usrepr.lon.to_value(u.radian)
    lat = usrepr.lat.to_value(u.radian)

    if isinstance(observed_coo, AltAz):
        # the 'A' indicates zen/az inputs
        coord_type = 'A'
        lat = PIOVER2 - lat
    else:
        coord_type = 'H'

    # first set up the astrometry context for ICRS<->CIRS at the observed_coo time
    astrom = erfa_astrom.get().apco(observed_coo)

    # Topocentric CIRS
    cirs_ra, cirs_dec = erfa.atoiq(coord_type, lon, lat, astrom) << u.radian
    if is_unitspherical:
        srepr = SphericalRepresentation(cirs_ra, cirs_dec, 1, copy=False)
    else:
        srepr = SphericalRepresentation(lon=cirs_ra,
                                        lat=cirs_dec,
                                        distance=observed_coo.distance,
                                        copy=False)

    # BCRS (Astrometric) direction to source
    bcrs_ra, bcrs_dec = aticq(srepr, astrom) << u.radian

    # Correct for parallax to get ICRS representation
    if is_unitspherical:
        icrs_srepr = UnitSphericalRepresentation(bcrs_ra, bcrs_dec, copy=False)
    else:
        icrs_srepr = SphericalRepresentation(lon=bcrs_ra,
                                             lat=bcrs_dec,
                                             distance=observed_coo.distance,
                                             copy=False)
        observer_icrs = CartesianRepresentation(astrom['eb'],
                                                unit=u.au,
                                                xyz_axis=-1,
                                                copy=False)
        newrepr = icrs_srepr.to_cartesian() + observer_icrs
        icrs_srepr = newrepr.represent_as(SphericalRepresentation)

    return icrs_frame.realize_frame(icrs_srepr)
Example #11
0
File: fk4.py Project: zonca/astropy
def fk4_to_fk4_no_e(fk4coord, fk4noeframe):
    # Extract cartesian vector
    rep = fk4coord.cartesian

    # Find distance (for re-normalization)
    d_orig = rep.norm()
    rep /= d_orig

    # Apply E-terms of aberration. Note that this depends on the equinox (not
    # the observing time/epoch) of the coordinates. See issue #1496 for a
    # discussion of this.
    eterms_a = CartesianRepresentation(u.Quantity(fk4_e_terms(
        fk4coord.equinox),
                                                  u.dimensionless_unscaled,
                                                  copy=False),
                                       copy=False)
    rep = rep - eterms_a + eterms_a.dot(rep) * rep

    # Find new distance (for re-normalization)
    d_new = rep.norm()

    # Renormalize
    rep *= d_orig / d_new

    # now re-cast into an appropriate Representation, and precess if need be
    if isinstance(fk4coord.data, UnitSphericalRepresentation):
        rep = rep.represent_as(UnitSphericalRepresentation)

    # if no obstime was given in the new frame, use the old one for consistency
    newobstime = fk4coord._obstime if fk4noeframe._obstime is None else fk4noeframe._obstime

    fk4noe = FK4NoETerms(rep, equinox=fk4coord.equinox, obstime=newobstime)
    if fk4coord.equinox != fk4noeframe.equinox:
        # precession
        fk4noe = fk4noe.transform_to(fk4noeframe)
    return fk4noe
Example #12
0
def fk4_no_e_to_fk4(fk4noecoord, fk4frame):
    # first precess, if necessary
    if fk4noecoord.equinox != fk4frame.equinox:
        fk4noe_w_fk4equinox = FK4NoETerms(equinox=fk4frame.equinox,
                                          obstime=fk4noecoord.obstime)
        fk4noecoord = fk4noecoord.transform_to(fk4noe_w_fk4equinox)

    # Extract cartesian vector
    rep = fk4noecoord.cartesian

    # Find distance (for re-normalization)
    d_orig = rep.norm()
    rep /= d_orig

    # Apply E-terms of aberration. Note that this depends on the equinox (not
    # the observing time/epoch) of the coordinates. See issue #1496 for a
    # discussion of this.
    eterms_a = CartesianRepresentation(
        u.Quantity(fk4_e_terms(fk4noecoord.equinox), u.dimensionless_unscaled,
                   copy=False), copy=False)

    rep0 = rep.copy()
    for _ in range(10):
        rep = (eterms_a + rep0) / (1. + eterms_a.dot(rep))

    # Find new distance (for re-normalization)
    d_new = rep.norm()

    # Renormalize
    rep *= d_orig / d_new

    # now re-cast into an appropriate Representation, and precess if need be
    if isinstance(fk4noecoord.data, UnitSphericalRepresentation):
        rep = rep.represent_as(UnitSphericalRepresentation)

    return fk4frame.realize_frame(rep)
Example #13
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)
Example #14
0
def gcrs_to_hcrs(gcrs_coo, hcrs_frame):

    if np.any(gcrs_coo.obstime != hcrs_frame.obstime):
        # if they GCRS obstime and HCRS obstime are not the same, we first
        # have to move to a GCRS where they are.
        frameattrs = gcrs_coo.get_frame_attr_names()
        frameattrs['obstime'] = hcrs_frame.obstime
        gcrs_coo = gcrs_coo.transform_to(GCRS(**frameattrs))

    srepr = gcrs_coo.represent_as(SphericalRepresentation)
    gcrs_ra = srepr.lon.to_value(u.radian)
    gcrs_dec = srepr.lat.to_value(u.radian)

    # set up the astrometry context for ICRS<->GCRS and then convert to ICRS
    # coordinate direction
    astrom = erfa_astrom.get().apcs(gcrs_coo)
    i_ra, i_dec = aticq(gcrs_ra, gcrs_dec, astrom)

    # convert to Quantity objects
    i_ra = u.Quantity(i_ra, u.radian, copy=False)
    i_dec = u.Quantity(i_dec, u.radian, copy=False)
    if gcrs_coo.data.get_name() == 'unitspherical' or gcrs_coo.data.to_cartesian().x.unit == u.one:
        # if no distance, just use the coordinate direction to yield the
        # infinite-distance/no parallax answer
        newrep = UnitSphericalRepresentation(lat=i_dec, lon=i_ra, copy=False)
    else:
        # When there is a distance, apply the parallax/offset to the
        # Heliocentre as the last step to ensure round-tripping with the
        # hcrs_to_gcrs transform

        # Note that the distance in intermedrep is *not* a real distance as it
        # does not include the offset back to the Heliocentre
        intermedrep = SphericalRepresentation(lat=i_dec, lon=i_ra,
                                              distance=srepr.distance,
                                              copy=False)

        # astrom['eh'] and astrom['em'] contain Sun to observer unit vector,
        # and distance, respectively. Shapes are (X) and (X,3), where (X) is the
        # shape resulting from broadcasting the shape of the times object
        # against the shape of the pv array.
        # broadcast em to eh and scale eh
        eh = astrom['eh'] * astrom['em'][..., np.newaxis]
        eh = CartesianRepresentation(eh, unit=u.au, xyz_axis=-1, copy=False)

        newrep = intermedrep.to_cartesian() + eh

    return hcrs_frame.realize_frame(newrep)
def cirs_to_icrs(cirs_coo, icrs_frame):
    srepr = cirs_coo.represent_as(SphericalRepresentation)
    cirs_ra = srepr.lon.to_value(u.radian)
    cirs_dec = srepr.lat.to_value(u.radian)

    # set up the astrometry context for ICRS<->cirs and then convert to
    # astrometric coordinate direction
    jd1, jd2 = get_jd12(cirs_coo.obstime, 'tt')
    x, y, s = get_cip(jd1, jd2)
    earth_pv, earth_heliocentric = prepare_earth_position_vel(cirs_coo.obstime)
    # erfa.apci requests TDB but TT can be used instead of TDB without any significant impact on accuracy
    astrom = erfa.apci(jd1, jd2, earth_pv, earth_heliocentric, x, y, s)
    i_ra, i_dec = aticq(cirs_ra, cirs_dec, astrom)

    if cirs_coo.data.get_name(
    ) == 'unitspherical' or cirs_coo.data.to_cartesian().x.unit == u.one:
        # if no distance, just use the coordinate direction to yield the
        # infinite-distance/no parallax answer
        newrep = UnitSphericalRepresentation(lat=u.Quantity(i_dec,
                                                            u.radian,
                                                            copy=False),
                                             lon=u.Quantity(i_ra,
                                                            u.radian,
                                                            copy=False),
                                             copy=False)
    else:
        # When there is a distance, apply the parallax/offset to the SSB as the
        # last step - ensures round-tripping with the icrs_to_cirs transform

        # the distance in intermedrep is *not* a real distance as it does not
        # include the offset back to the SSB
        intermedrep = SphericalRepresentation(lat=u.Quantity(i_dec,
                                                             u.radian,
                                                             copy=False),
                                              lon=u.Quantity(i_ra,
                                                             u.radian,
                                                             copy=False),
                                              distance=srepr.distance,
                                              copy=False)

        astrom_eb = CartesianRepresentation(astrom['eb'],
                                            unit=u.au,
                                            xyz_axis=-1,
                                            copy=False)
        newrep = intermedrep + astrom_eb

    return icrs_frame.realize_frame(newrep)
Example #16
0
def hcc_to_hpc(helioccoord, heliopframe):
    """
    Convert from Heliocentric Cartesian to Helioprojective Cartesian.
    """
    # Loopback transform HCC coord to obstime and observer of HPC frame
    int_frame = Heliocentric(obstime=heliopframe.obstime, observer=heliopframe.observer)
    int_coord = helioccoord.transform_to(int_frame)

    # Shift the origin from the Sun to the observer
    distance = int_coord.observer.radius
    newrepr = int_coord.cartesian - CartesianRepresentation(0*u.m, 0*u.m, distance)

    # Permute/swap axes from HCC to HPC equivalent Cartesian
    newrepr = newrepr.transform(_matrix_hcc_to_hpc())

    # Explicitly represent as spherical because external code (e.g., wcsaxes) expects it
    return heliopframe.realize_frame(newrepr.represent_as(SphericalRepresentation))
Example #17
0
def icrs_to_gcrs(icrs_coo, gcrs_frame):
    # first set up the astrometry context for ICRS<->GCRS. There are a few steps...
    # get the position and velocity arrays for the observatory.  Need to
    # have xyz in last dimension, and pos/vel in one-but-last.
    # (Note could use np.stack once our minimum numpy version is >=1.10.)
    obs_pv = erfa.pav2pv(
        gcrs_frame.obsgeoloc.get_xyz(xyz_axis=-1).to_value(u.m),
        gcrs_frame.obsgeovel.get_xyz(xyz_axis=-1).to_value(u.m/u.s))

    # find the position and velocity of earth
    jd1, jd2 = get_jd12(gcrs_frame.obstime, 'tdb')
    earth_pv, earth_heliocentric = prepare_earth_position_vel(gcrs_frame.obstime)

    # get astrometry context object, astrom.
    astrom = erfa.apcs(jd1, jd2, obs_pv, earth_pv, earth_heliocentric)

    if icrs_coo.data.get_name() == 'unitspherical' or icrs_coo.data.to_cartesian().x.unit == u.one:
        # if no distance, just do the infinite-distance/no parallax calculation
        usrepr = icrs_coo.represent_as(UnitSphericalRepresentation)
        i_ra = usrepr.lon.to_value(u.radian)
        i_dec = usrepr.lat.to_value(u.radian)
        gcrs_ra, gcrs_dec = atciqz(i_ra, i_dec, astrom)

        newrep = UnitSphericalRepresentation(lat=u.Quantity(gcrs_dec, u.radian, copy=False),
                                             lon=u.Quantity(gcrs_ra, u.radian, copy=False),
                                             copy=False)
    else:
        # When there is a distance,  we first offset for parallax to get the
        # BCRS coordinate direction and *then* run the ERFA transform for no
        # parallax/PM. This ensures reversibility and is more sensible for
        # inside solar system objects
        astrom_eb = CartesianRepresentation(astrom['eb'], unit=u.au,
                                            xyz_axis=-1, copy=False)
        newcart = icrs_coo.cartesian - astrom_eb

        srepr = newcart.represent_as(SphericalRepresentation)
        i_ra = srepr.lon.to_value(u.radian)
        i_dec = srepr.lat.to_value(u.radian)
        gcrs_ra, gcrs_dec = atciqz(i_ra, i_dec, astrom)

        newrep = SphericalRepresentation(lat=u.Quantity(gcrs_dec, u.radian, copy=False),
                                         lon=u.Quantity(gcrs_ra, u.radian, copy=False),
                                         distance=srepr.distance, copy=False)

    return gcrs_frame.realize_frame(newrep)
Example #18
0
def hgs_to_hcc(heliogcoord, heliocframe):
    """
    Convert from Heliographic Stonyhurst to Heliocentric Cartesian.
    """
    # Import moved here from top of file to lessen the impact of issue #2580
    # TODO: Revert this.
    from astropy.tests.helper import quantity_allclose
    hglon = heliogcoord.lon
    hglat = heliogcoord.lat
    r = heliogcoord.radius
    if r.unit is u.one and quantity_allclose(r, 1 * u.one):
        r = np.ones_like(r)
        r *= RSUN_METERS

    if not isinstance(heliocframe.observer, BaseCoordinateFrame):
        raise ConvertError("Cannot transform heliographic coordinates to "
                           "heliocentric coordinates for observer '{}' "
                           "without `obstime` being specified.".format(
                               heliocframe.observer))

    l0_rad = heliocframe.observer.lon.to(u.rad)
    b0_deg = heliocframe.observer.lat

    lon = np.deg2rad(hglon)
    lat = np.deg2rad(hglat)

    cosb = np.cos(b0_deg.to(u.rad))
    sinb = np.sin(b0_deg.to(u.rad))

    lon = lon - l0_rad

    cosx = np.cos(lon)
    sinx = np.sin(lon)
    cosy = np.cos(lat)
    siny = np.sin(lat)

    x = r * cosy * sinx
    y = r * (siny * cosb - cosy * cosx * sinb)
    zz = r * (siny * sinb + cosy * cosx * cosb)

    representation = CartesianRepresentation(x.to(u.km), y.to(u.km),
                                             zz.to(u.km))

    return heliocframe.realize_frame(representation)
Example #19
0
def test_czml_add_trajectory_raises_error_for_groundtrack_show():
    start_epoch = iss.epoch
    end_epoch = iss.epoch + molniya.period

    sample_points = 10

    x = u.Quantity([1.0, 2.0, 3.0], u.m)
    y = u.Quantity([4.0, 5.0, 6.0], u.m)
    z = u.Quantity([7.0, 8.0, 9.0], u.m)
    positions = CartesianRepresentation(x, y, z)

    time = ["2010-01-01T05:00:00", "2010-01-01T05:00:30", "2010-01-01T05:01:00"]
    epochs = Time(time, format="isot")

    extractor = CZMLExtractor(start_epoch, end_epoch, sample_points)

    with pytest.raises(NotImplementedError) as excinfo:
        extractor.add_trajectory(positions, epochs, groundtrack_show=True)
    assert "Ground tracking for trajectory not implemented yet" in excinfo.exconly()
Example #20
0
def test_czml_raises_error_if_length_of_points_and_epochs_not_same():
    start_epoch = iss.epoch
    end_epoch = iss.epoch + molniya.period

    sample_points = 10
    color = [255, 255, 0]

    x = u.Quantity([1.0, 2.0, 3.0], u.m)
    y = u.Quantity([4.0, 5.0, 6.0], u.m)
    z = u.Quantity([7.0, 8.0, 9.0], u.m)
    positions = CartesianRepresentation(x, y, z)

    time = ["2010-01-01T05:00:00", "2010-01-01T05:00:30"]
    epochs = Time(time, format="isot")
    extractor = CZMLExtractor(start_epoch, end_epoch, sample_points)

    with pytest.raises(ValueError) as excinfo:
        extractor.add_trajectory(positions, epochs, label_text="Test", path_color=color)
    assert "Number of Points and Epochs must be equal." in excinfo.exconly()
Example #21
0
def _transform_cartesian(representation, matrix):

    # Get xyz once since it's an expensive operation
    xyz = representation.xyz

    # Since the underlying data can be n-dimensional, reshape to a
    # 2-dimensional (3, N) array.
    vec = xyz.reshape((3, xyz.size // 3))

    # Do the transformation
    vec_new = np.dot(np.asarray(matrix), vec)

    # Reshape to preserve the original shape
    subshape = xyz.shape[1:]
    x = vec_new[0].reshape(subshape)
    y = vec_new[1].reshape(subshape)
    z = vec_new[2].reshape(subshape)

    # Make a new representation and return
    return CartesianRepresentation(x, y, z)
Example #22
0
def hee_to_gse(heecoord, gseframe):
    """
    Convert from Heliocentric Earth Ecliptic to Geocentric Solar Ecliptic
    """
    # Use an intermediate frame of HEE at the GSE observation time
    int_frame = HeliocentricEarthEcliptic(obstime=gseframe.obstime)
    int_coord = heecoord.transform_to(int_frame)

    # Get the Sun-Earth vector in the intermediate frame
    sun_earth = HCRS(_sun_earth_icrf(int_frame.obstime), obstime=int_frame.obstime)
    sun_earth_int = sun_earth.transform_to(int_frame).cartesian

    # Find the Earth-object vector in the intermediate frame
    earth_object_int = int_coord.cartesian - sun_earth_int

    # Flip the vector in X and Y, but leave Z untouched
    # (The additional transpose operations are to handle both scalar and array inputs)
    newrepr = CartesianRepresentation((earth_object_int.xyz.T * [-1, -1, 1]).T)

    return gseframe.realize_frame(newrepr)
Example #23
0
def test_czml_add_trajectory(expected_doc_add_trajectory):
    start_epoch = iss.epoch
    end_epoch = iss.epoch + molniya.period

    sample_points = 10
    color = [255, 255, 0]

    x = u.Quantity([1.0, 2.0, 3.0], u.m)
    y = u.Quantity([4.0, 5.0, 6.0], u.m)
    z = u.Quantity([7.0, 8.0, 9.0], u.m)
    positions = CartesianRepresentation(x, y, z)

    time = ["2010-01-01T05:00:00", "2010-01-01T05:00:30", "2010-01-01T05:01:00"]
    epochs = Time(time, format="isot")

    extractor = CZMLExtractor(start_epoch, end_epoch, sample_points)

    extractor.add_trajectory(positions, epochs, label_text="Test", path_color=color)

    assert repr(extractor.packets) == expected_doc_add_trajectory
Example #24
0
def hgs_to_hcc(heliogcoord, heliocframe):
    """
    Convert from Heliographic Stonyhurst to Heliocentric Cartesian.
    """
    hglon = heliogcoord.spherical.lon
    hglat = heliogcoord.spherical.lat
    r = heliogcoord.spherical.distance
    if r.unit is u.one and u.allclose(r, 1 * u.one):
        r = np.ones_like(r)
        r *= RSUN_METERS

    if not isinstance(heliocframe.observer, BaseCoordinateFrame):
        raise ConvertError("Cannot transform heliographic coordinates to "
                           "heliocentric coordinates for observer '{}' "
                           "without `obstime` being specified.".format(
                               heliocframe.observer))

    l0_rad = heliocframe.observer.lon.to(u.rad)
    b0_deg = heliocframe.observer.lat

    lon = np.deg2rad(hglon)
    lat = np.deg2rad(hglat)

    cosb = np.cos(b0_deg.to(u.rad))
    sinb = np.sin(b0_deg.to(u.rad))

    lon = lon - l0_rad

    cosx = np.cos(lon)
    sinx = np.sin(lon)
    cosy = np.cos(lat)
    siny = np.sin(lat)

    x = r * cosy * sinx
    y = r * (siny * cosb - cosy * cosx * sinb)
    zz = r * (siny * sinb + cosy * cosx * cosb)

    representation = CartesianRepresentation(x.to(u.km), y.to(u.km),
                                             zz.to(u.km))

    return heliocframe.realize_frame(representation)
Example #25
0
def hgs_to_hcc(heliogcoord, heliocframe):
    """
    Convert from Heliographic Stonyhurst to Heliograpic Carrington.
    """
    hglon = heliogcoord.lon
    hglat = heliogcoord.lat
    r = heliogcoord.radius.to(u.m)

    if heliocframe.obstime is None:
        heliocframe._obstime = heliogcoord.obstime

    if not isinstance(heliocframe.observer, BaseCoordinateFrame):
        raise ConvertError("Cannot transform heliographic coordinates to "
                           "heliocentric coordinates for observer '{}' "
                           "without `obstime` being specified.".format(
                               heliocframe.observer))

    l0_rad = heliocframe.observer.lon.to(u.rad)
    b0_deg = heliocframe.observer.lat

    lon = np.deg2rad(hglon)
    lat = np.deg2rad(hglat)

    cosb = np.cos(b0_deg.to(u.rad))
    sinb = np.sin(b0_deg.to(u.rad))

    lon = lon - l0_rad

    cosx = np.cos(lon)
    sinx = np.sin(lon)
    cosy = np.cos(lat)
    siny = np.sin(lat)

    x = r * cosy * sinx
    y = r * (siny * cosb - cosy * cosx * sinb)
    zz = r * (siny * sinb + cosy * cosx * cosb)

    representation = CartesianRepresentation(x.to(u.km), y.to(u.km),
                                             zz.to(u.km))

    return heliocframe.realize_frame(representation)
def gcrs_to_icrs(gcrs_coo, icrs_frame):
    # set up the astrometry context for ICRS<->GCRS and then convert to BCRS
    # coordinate direction
    astrom = erfa_astrom.get().apcs(gcrs_coo)

    srepr = gcrs_coo.represent_as(SphericalRepresentation)
    i_ra, i_dec = aticq(srepr.without_differentials(), astrom)

    if gcrs_coo.data.get_name(
    ) == 'unitspherical' or gcrs_coo.data.to_cartesian().x.unit == u.one:
        # if no distance, just use the coordinate direction to yield the
        # infinite-distance/no parallax answer
        newrep = UnitSphericalRepresentation(lat=u.Quantity(i_dec,
                                                            u.radian,
                                                            copy=False),
                                             lon=u.Quantity(i_ra,
                                                            u.radian,
                                                            copy=False),
                                             copy=False)
    else:
        # When there is a distance, apply the parallax/offset to the SSB as the
        # last step - ensures round-tripping with the icrs_to_gcrs transform

        # the distance in intermedrep is *not* a real distance as it does not
        # include the offset back to the SSB
        intermedrep = SphericalRepresentation(lat=u.Quantity(i_dec,
                                                             u.radian,
                                                             copy=False),
                                              lon=u.Quantity(i_ra,
                                                             u.radian,
                                                             copy=False),
                                              distance=srepr.distance,
                                              copy=False)

        astrom_eb = CartesianRepresentation(astrom['eb'],
                                            unit=u.au,
                                            xyz_axis=-1,
                                            copy=False)
        newrep = intermedrep + astrom_eb

    return icrs_frame.realize_frame(newrep)
def icrs_to_gcrs(icrs_coo, gcrs_frame):
    # first set up the astrometry context for ICRS<->GCRS.
    astrom = erfa_astrom.get().apcs(gcrs_frame)

    if icrs_coo.data.get_name(
    ) == 'unitspherical' or icrs_coo.data.to_cartesian().x.unit == u.one:
        # if no distance, just do the infinite-distance/no parallax calculation
        srepr = icrs_coo.represent_as(SphericalRepresentation)
        gcrs_ra, gcrs_dec = atciqz(srepr.without_differentials(), astrom)

        newrep = UnitSphericalRepresentation(lat=u.Quantity(gcrs_dec,
                                                            u.radian,
                                                            copy=False),
                                             lon=u.Quantity(gcrs_ra,
                                                            u.radian,
                                                            copy=False),
                                             copy=False)
    else:
        # When there is a distance,  we first offset for parallax to get the
        # BCRS coordinate direction and *then* run the ERFA transform for no
        # parallax/PM. This ensures reversibility and is more sensible for
        # inside solar system objects
        astrom_eb = CartesianRepresentation(astrom['eb'],
                                            unit=u.au,
                                            xyz_axis=-1,
                                            copy=False)
        newcart = icrs_coo.cartesian - astrom_eb

        srepr = newcart.represent_as(SphericalRepresentation)
        gcrs_ra, gcrs_dec = atciqz(srepr.without_differentials(), astrom)

        newrep = SphericalRepresentation(lat=u.Quantity(gcrs_dec,
                                                        u.radian,
                                                        copy=False),
                                         lon=u.Quantity(gcrs_ra,
                                                        u.radian,
                                                        copy=False),
                                         distance=srepr.distance,
                                         copy=False)

    return gcrs_frame.realize_frame(newrep)
Example #28
0
def hpc_to_hcc(heliopcoord, heliocframe):
    """
    Convert from Helioprojective Cartesian to Heliocentric Cartesian.
    """
    heliopcoord = heliopcoord.calculate_distance()
    x = np.deg2rad(heliopcoord.Tx)
    y = np.deg2rad(heliopcoord.Ty)

    cosx = np.cos(x)
    sinx = np.sin(x)
    cosy = np.cos(y)
    siny = np.sin(y)

    rx = (heliopcoord.distance.to(u.m)) * cosy * sinx
    ry = (heliopcoord.distance.to(u.m)) * siny
    rz = (heliopcoord.D0.to(
        u.m)) - (heliopcoord.distance.to(u.m)) * cosy * cosx

    representation = CartesianRepresentation(rx.to(u.km), ry.to(u.km),
                                             rz.to(u.km))
    return heliocframe.realize_frame(representation)
Example #29
0
 def load(self, filename):
     super(Solution, self).load(filename)
     f = h5py.File(filename, 'r')
     try:
         obstime = at.Time(f['TCI'].attrs['obstime'],
                           format='gps',
                           scale='tai')
         fixtime = at.Time(f['TCI'].attrs['fixtime'],
                           format='gps',
                           scale='tai')
         location = ac.ITRS().realize_frame(
             CartesianRepresentation(*(f['TCI'].attrs['location'] * au.km)))
         phase = ac.SkyCoord(*(f['TCI'].attrs['phase'] * au.deg),
                             frame='icrs')
         pointing_frame = Pointing(location=location,
                                   obstime=obstime,
                                   phase=phase,
                                   fixtime=fixtime)
     except:
         pointing_frame = None
     f.close()
     self.__init__(pointing_frame=pointing_frame)
def icrs_to_observed(icrs_coo, observed_frame):
    # if the data are UnitSphericalRepresentation, we can skip the distance calculations
    is_unitspherical = (isinstance(icrs_coo.data, UnitSphericalRepresentation)
                        or icrs_coo.cartesian.x.unit == u.one)
    # first set up the astrometry context for ICRS<->observed
    astrom = erfa_astrom.get().apco(observed_frame)

    # correct for parallax to find BCRS direction from observer (as in erfa.pmpx)
    if is_unitspherical:
        srepr = icrs_coo.spherical
    else:
        observer_icrs = CartesianRepresentation(astrom['eb'],
                                                unit=u.au,
                                                xyz_axis=-1,
                                                copy=False)
        srepr = (icrs_coo.cartesian -
                 observer_icrs).represent_as(SphericalRepresentation)

    # convert to topocentric CIRS
    cirs_ra, cirs_dec = atciqz(srepr, astrom)

    # now perform observed conversion
    if isinstance(observed_frame, AltAz):
        lon, zen, _, _, _ = erfa.atioq(cirs_ra, cirs_dec, astrom)
        lat = PIOVER2 - zen
    else:
        _, _, lon, lat, _ = erfa.atioq(cirs_ra, cirs_dec, astrom)

    if is_unitspherical:
        obs_srepr = UnitSphericalRepresentation(lon << u.radian,
                                                lat << u.radian,
                                                copy=False)
    else:
        obs_srepr = SphericalRepresentation(lon << u.radian,
                                            lat << u.radian,
                                            srepr.distance,
                                            copy=False)
    return observed_frame.realize_frame(obs_srepr)
Example #31
0
def hpc_to_hcc(heliopcoord, heliocframe):
    """
    Convert from Helioprojective Cartesian to Heliocentric Cartesian.
    """
    if not isinstance(heliopcoord.observer, BaseCoordinateFrame):
        raise ConvertError("Cannot transform helioprojective coordinates to "
                           "heliocentric coordinates for observer '{}' "
                           "without `obstime` being specified.".format(heliopcoord.observer))

    heliopcoord = heliopcoord.calculate_distance()

    # Permute/swap axes from HPC equivalent Cartesian to HCC
    newrepr = heliopcoord.cartesian.transform(matrix_transpose(_matrix_hcc_to_hpc()))

    # Shift the origin from the observer to the Sun
    distance = heliocframe.observer.radius
    newrepr += CartesianRepresentation(0*u.m, 0*u.m, distance)

    # Complete the conversion of HPC to HCC at the obstime and observer of the HPC coord
    int_coord = Heliocentric(newrepr, obstime=heliopcoord.obstime, observer=heliopcoord.observer)

    # Loopback transform HCC as needed
    return int_coord.transform_to(heliocframe)
Example #32
0
def hpc_to_hcc(heliopcoord, heliocframe):
    """
    Convert from Helioprojective Cartesian to Heliocentric Cartesian.
    """
    if not _observers_are_equal(heliopcoord.observer, heliocframe.observer):
        raise ConvertError(
            "Cannot directly transform helioprojective coordinates to "
            "heliocentric coordinates for different "
            "observers {} and {}. See discussion in this GH issue: "
            "https://github.com/sunpy/sunpy/issues/2712. Try converting to "
            "an intermediate heliographic Stonyhurst frame.".format(
                heliopcoord.observer, heliocframe.observer))

    if not isinstance(heliopcoord.observer, BaseCoordinateFrame):
        raise ConvertError("Cannot transform helioprojective coordinates to "
                           "heliocentric coordinates for observer '{}' "
                           "without `obstime` being specified.".format(
                               heliopcoord.observer))

    heliopcoord = heliopcoord.calculate_distance()
    x = np.deg2rad(heliopcoord.Tx)
    y = np.deg2rad(heliopcoord.Ty)

    cosx = np.cos(x)
    sinx = np.sin(x)
    cosy = np.cos(y)
    siny = np.sin(y)

    rx = (heliopcoord.distance.to(u.m)) * cosy * sinx
    ry = (heliopcoord.distance.to(u.m)) * siny
    rz = (heliopcoord.observer.radius.to(
        u.m)) - (heliopcoord.distance.to(u.m)) * cosy * cosx

    representation = CartesianRepresentation(rx.to(u.km), ry.to(u.km),
                                             rz.to(u.km))
    return heliocframe.realize_frame(representation)
Example #33
0
def hpc_to_hcc(heliopcoord, heliocframe):
    """
    Convert from Helioprojective Cartesian to Heliocentric Cartesian.
    """
    _check_observer_defined(heliopcoord)
    _check_observer_defined(heliocframe)

    heliopcoord = heliopcoord.make_3d()

    # Permute/swap axes from HPC equivalent Cartesian to HCC
    newrepr = heliopcoord.cartesian.transform(matrix_transpose(_matrix_hcc_to_hpc()))

    # Transform the HPC observer (in HGS) to the HPC obstime in case it's different
    observer = _transform_obstime(heliopcoord.observer, heliopcoord.obstime)

    # Shift the origin from the observer to the Sun
    distance = observer.radius
    newrepr += CartesianRepresentation(0*u.m, 0*u.m, distance)

    # Complete the conversion of HPC to HCC at the obstime and observer of the HPC coord
    int_coord = Heliocentric(newrepr, obstime=observer.obstime, observer=observer)

    # Loopback transform HCC as needed
    return int_coord.transform_to(heliocframe)