예제 #1
0
def gei_to_hme(geicoord, hmeframe):
    """
    Convert from Geocentric Earth Equatorial to Heliocentric Mean Ecliptic
    """
    if geicoord.obstime is None:
        raise ConvertError("To perform this transformation, the coordinate"
                           " frame needs a specified `obstime`.")

    # Use an intermediate frame of HME at the GEI observation time
    int_frame = HeliocentricMeanEcliptic(obstime=geicoord.obstime, equinox=geicoord.equinox)

    # 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

    # Rotate from Earth equatorial to ecliptic
    rot_matrix = _rotation_matrix_obliquity(int_frame.equinox)
    earth_object_int = geicoord.cartesian.transform(rot_matrix)

    # Find the Sun-object vector in the intermediate frame
    sun_object_int = sun_earth_int + earth_object_int
    int_coord = int_frame.realize_frame(sun_object_int)

    # Convert to the final frame through HCRS
    return int_coord.transform_to(HCRS(obstime=int_coord.obstime)).transform_to(hmeframe)
예제 #2
0
def test_hme_hee_sunspice():
    # Compare our HME->HEE transformation against SunSPICE
    # "HAE" is equivalent to Astropy's Heliocentric Mean Ecliptic, and defaults to J2000.0
    #
    # IDL> coord = [1.d, 0.d, 10.d]
    # IDL> convert_sunspice_lonlat, '2019-06-01', coord, 'HAE', 'HEE', /au, /degrees
    # IDL> print, coord
    #        1.0000000       110.01610       10.000300

    old = SkyCoord(0*u.deg, 10*u.deg, 1*u.AU, frame=HeliocentricMeanEcliptic(obstime='2019-06-01'))
    new = old.transform_to(HeliocentricEarthEcliptic)

    assert_quantity_allclose(new.lon, Longitude(110.01610*u.deg), atol=0.01*u.arcsec, rtol=0)
    assert_quantity_allclose(new.lat, 10.000300*u.deg, atol=0.01*u.arcsec, rtol=0)
    assert_quantity_allclose(new.distance, old.distance)

    # Transform from HAE precessed to the mean ecliptic of date instead of J2000.0
    # IDL> coord = [1.d, 0.d, 10.d]
    # IDL> convert_sunspice_lonlat, '2019-06-01', coord, 'HAE', 'HEE', /au, /degrees, /precess
    # IDL> print, coord
    #        1.0000000       109.74535       10.000070

    old = SkyCoord(0*u.deg, 10*u.deg, 1*u.AU, frame=HeliocentricMeanEcliptic(obstime='2019-06-01',
                                                                             equinox='2019-06-01'))
    new = old.transform_to(HeliocentricEarthEcliptic)

    assert_quantity_allclose(new.lon, Longitude(109.74535*u.deg), atol=0.05*u.arcsec, rtol=0)
    assert_quantity_allclose(new.lat, 10.000070*u.deg, atol=0.01*u.arcsec, rtol=0)
    assert_quantity_allclose(new.distance, old.distance)
예제 #3
0
def test_hme_gei_sunspice():
    # Compare our HME->GEI transformation against SunSPICE
    # "HAE" is equivalent to Astropy's Heliocentric Mean Ecliptic, and defaults to J2000.0
    #
    # IDL> coord = [1.d, 120.d, 10.d]
    # IDL> convert_sunspice_lonlat, '2019-06-01', coord, 'HAE', 'GEI', /au, /degrees
    # IDL> print, coord
    #        1.8197210       95.230617       28.830109

    old = SkyCoord(120*u.deg, 10*u.deg, 1*u.AU,
                   frame=HeliocentricMeanEcliptic(obstime='2019-06-01'))
    new = old.transform_to(GeocentricEarthEquatorial)

    assert_quantity_allclose(new.lon, Longitude(95.230617*u.deg), atol=0.01*u.arcsec, rtol=0)
    assert_quantity_allclose(new.lat, 28.830109*u.deg, atol=0.05*u.arcsec, rtol=0)
    assert_quantity_allclose(new.distance, 1.8197210*u.AU)

    # Transform from HAE precessed to the mean ecliptic of date instead of J2000.0
    # IDL> coord = [1.d, 120.d, 10.d]
    # IDL> convert_sunspice_lonlat, '2019-06-01', coord, 'HAE', 'GEI', /au, /degrees, /precess
    # IDL> print, coord
    #        1.8217103       95.079030       28.827750

    old = SkyCoord(120*u.deg, 10*u.deg, 1*u.AU,
                   frame=HeliocentricMeanEcliptic(obstime='2019-06-01', equinox='2019-06-01'))
    new = old.transform_to(GeocentricEarthEquatorial(equinox=_J2000))

    assert_quantity_allclose(new.lon, Longitude(95.079030*u.deg), atol=0.05*u.arcsec, rtol=0)
    assert_quantity_allclose(new.lat, 28.827750*u.deg, atol=0.05*u.arcsec, rtol=0)
    assert_quantity_allclose(new.distance, 1.8217103*u.AU)
예제 #4
0
def hee_to_hme(heecoord, hmeframe):
    """
    Convert from Heliocentric Earth Ecliptic to Heliocentric Mean Ecliptic
    """
    int_frame = HeliocentricMeanEcliptic(obstime=heecoord.obstime, equinox=heecoord.obstime)

    # Rotate the HEE coord to the intermediate frame
    total_matrix = matrix_transpose(_rotation_matrix_hme_to_hee(int_frame))
    int_repr = heecoord.cartesian.transform(total_matrix)
    int_coord = int_frame.realize_frame(int_repr)

    # Convert to the HME frame through HCRS
    return int_coord.transform_to(HCRS).transform_to(hmeframe)
예제 #5
0
def test_hgs_hcrs():
    # This test checks the HGS->HCRS transformation by transforming from HGS to
    # HeliocentricMeanEcliptic (HME).  It will fail if there are errors in Astropy's
    # HCRS->ICRS or ICRS->HME transformations.

    # Use published HGS coordinates in the Astronomical Almanac (2013), pages C6-C7
    obstime = Time('2013-01-28')
    earth_hgs = SkyCoord(0 * u.deg,
                         -5.73 * u.deg,
                         0.9848139 * u.AU,
                         frame=HeliographicStonyhurst,
                         obstime=obstime)

    # Transform to HME at observation-time equinox
    earth_hme = earth_hgs.transform_to(
        HeliocentricMeanEcliptic(equinox=obstime))

    # Validate against published values from the Astronomical Almanac (2013), page C6 per page E2
    # The dominant source of inaccuracy is the limited precision of the published B0 used above
    assert quantity_allclose(earth_hme.lon,
                             Angle('308d13m30.51s') - 180 * u.deg,
                             atol=5 * u.arcsec)
    assert quantity_allclose(earth_hme.lat,
                             -Angle('-0.27s'),
                             atol=10 * u.arcsec)
    assert quantity_allclose(earth_hme.distance,
                             0.9848139 * u.AU,
                             atol=5e-7 * u.AU)
예제 #6
0
def test_hgs_hcrs_sunspice():
    # Compare our HGS->HCRS transformation against SunSPICE by transforming beyond it
    # "HEQ" is another name for HEEQ, which is equivalent to Heliographic Stonyhurst
    # "HAE" is equivalent to Astropy's Heliocentric Mean Ecliptic, and defaults to J2000.0
    #
    # IDL> coord = [1.d, 0.d, 10.d]
    # IDL> convert_sunspice_lonlat, '2019-06-01', coord, 'HEQ', 'HAE', /au, /degrees
    # IDL> print, coord
    #        1.0000000      -108.65371       10.642778

    old = SkyCoord(0*u.deg, 10*u.deg, 1*u.AU, frame=HeliographicStonyhurst(obstime='2019-06-01'))
    new = old.transform_to(HeliocentricMeanEcliptic)

    assert_quantity_allclose(new.lon, Longitude(-108.65371*u.deg), atol=0.1*u.arcsec, rtol=0)
    assert_quantity_allclose(new.lat, 10.642778*u.deg, atol=0.1*u.arcsec, rtol=0)
    assert_quantity_allclose(new.distance, old.radius)

    # Transform to HAE precessed to the mean ecliptic of date instead of J2000.0
    # IDL> coord = [1.d, 0.d, 10.d]
    # IDL> convert_sunspice_lonlat, '2019-06-01', coord, 'HEQ', 'HAE', /precess, /au, /degrees
    # IDL> print, coord
    #        1.0000000      -108.38240       10.640314

    new = old.transform_to(HeliocentricMeanEcliptic(equinox='2019-06-01'))

    assert_quantity_allclose(new.lon, Longitude(-108.38240*u.deg), atol=0.1*u.arcsec, rtol=0)
    assert_quantity_allclose(new.lat, 10.640314*u.deg, atol=0.1*u.arcsec, rtol=0)
    assert_quantity_allclose(new.distance, old.radius)
예제 #7
0
def hme_to_gei(hmecoord, geiframe):
    """
    Convert from Heliocentric Mean Ecliptic to Geocentric Earth Equatorial
    """
    if geiframe.obstime is None:
        raise ConvertError("To perform this transformation, the coordinate"
                           " frame needs a specified `obstime`.")

    # Use an intermediate frame of HME at the GEI observation time, through HCRS
    int_frame = HeliocentricMeanEcliptic(obstime=geiframe.obstime,
                                         equinox=geiframe.equinox)
    int_coord = hmecoord.transform_to(
        HCRS(obstime=int_frame.obstime)).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

    # Rotate from ecliptic to Earth equatorial
    rot_matrix = matrix_transpose(_rotation_matrix_obliquity(
        int_frame.equinox))
    newrepr = earth_object_int.transform(rot_matrix)

    return geiframe.realize_frame(newrepr)
예제 #8
0
def test_observer_not_hgs_astropy(oca):
    observer = HeliocentricMeanEcliptic(0*u.deg, 0*u.deg, 1*u.AU, obstime='2001-01-01')
    result, converted = oca.convert_input(observer)

    assert isinstance(result, HeliographicStonyhurst)
    assert result.obstime == observer.obstime
    assert converted
예제 #9
0
def hee_to_hme(heecoord, hmeframe):
    """
    Convert from Heliocentric Earth Ecliptic to Heliocentric Mean Ecliptic
    """
    if heecoord.obstime is None:
        raise ConvertError("To perform this transformation, the coordinate"
                           " frame needs a specified `obstime`.")

    int_frame = HeliocentricMeanEcliptic(obstime=heecoord.obstime, equinox=heecoord.obstime)

    # Rotate the HEE coord to the intermediate frame
    total_matrix = matrix_transpose(_rotation_matrix_hme_to_hee(int_frame))
    int_repr = heecoord.cartesian.transform(total_matrix)
    int_coord = int_frame.realize_frame(int_repr)

    # Convert to the HME frame through HCRS
    return int_coord.transform_to(HCRS(obstime=int_coord.obstime)).transform_to(hmeframe)
예제 #10
0
def rot_hme():
    return (HeliocentricMeanEcliptic,
            RotatedSunFrame(lon=1 * u.deg,
                            lat=2 * u.deg,
                            distance=3 * u.AU,
                            base=HeliocentricMeanEcliptic(
                                obstime='2001-01-01', equinox='2001-01-01'),
                            duration=4 * u.day))
예제 #11
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
예제 #12
0
def hme_to_hee(hmecoord, heeframe):
    """
    Convert from Heliocentric Mean Ecliptic to Heliocentric Earth Ecliptic
    """
    # Convert to the HME frame with mean equinox of date at the HEE obstime, through HCRS
    int_frame = HeliocentricMeanEcliptic(obstime=heeframe.obstime, equinox=heeframe.obstime)
    int_coord = hmecoord.transform_to(HCRS).transform_to(int_frame)

    # Rotate the intermediate coord to the HEE frame
    total_matrix = _rotation_matrix_hme_to_hee(int_frame)
    newrepr = int_coord.cartesian.transform(total_matrix)

    return heeframe.realize_frame(newrepr)
예제 #13
0
def hme_to_hee(hmecoord, heeframe):
    """
    Convert from Heliocentric Mean Ecliptic to Heliocentric Earth Ecliptic
    """
    if heeframe.obstime is None:
        raise ConvertError("To perform this transformation, the coordinate"
                           " frame needs a specified `obstime`.")

    # Convert to the HME frame with mean equinox of date at the HEE obstime, through HCRS
    int_frame = HeliocentricMeanEcliptic(obstime=heeframe.obstime, equinox=heeframe.obstime)
    int_coord = hmecoord.transform_to(HCRS(obstime=hmecoord.obstime)).transform_to(int_frame)

    # Rotate the intermediate coord to the HEE frame
    total_matrix = _rotation_matrix_hme_to_hee(int_frame)
    newrepr = int_coord.cartesian.transform(total_matrix)

    return heeframe.realize_frame(newrepr)
예제 #14
0
def test_ephemerides():
    """
    We test that using different ephemerides gives very similar results
    for transformations
    """
    t = Time("2014-12-25T07:00")
    moon = SkyCoord(
        GCRS(318.10579159 * u.deg,
             -11.65281165 * u.deg,
             365042.64880308 * u.km,
             obstime=t))

    icrs_frame = ICRS()
    hcrs_frame = HCRS(obstime=t)
    ecl_frame = HeliocentricMeanEcliptic(equinox=t)
    cirs_frame = CIRS(obstime=t)

    moon_icrs_builtin = moon.transform_to(icrs_frame)
    moon_hcrs_builtin = moon.transform_to(hcrs_frame)
    moon_helioecl_builtin = moon.transform_to(ecl_frame)
    moon_cirs_builtin = moon.transform_to(cirs_frame)

    with solar_system_ephemeris.set('jpl'):
        moon_icrs_jpl = moon.transform_to(icrs_frame)
        moon_hcrs_jpl = moon.transform_to(hcrs_frame)
        moon_helioecl_jpl = moon.transform_to(ecl_frame)
        moon_cirs_jpl = moon.transform_to(cirs_frame)

    # most transformations should differ by an amount which is
    # non-zero but of order milliarcsecs
    sep_icrs = moon_icrs_builtin.separation(moon_icrs_jpl)
    sep_hcrs = moon_hcrs_builtin.separation(moon_hcrs_jpl)
    sep_helioecl = moon_helioecl_builtin.separation(moon_helioecl_jpl)
    sep_cirs = moon_cirs_builtin.separation(moon_cirs_jpl)

    assert_allclose([sep_icrs, sep_hcrs, sep_helioecl],
                    0.0 * u.deg,
                    atol=10 * u.mas)
    assert all(sep > 10 * u.microarcsecond
               for sep in (sep_icrs, sep_hcrs, sep_helioecl))

    # CIRS should be the same
    assert_allclose(sep_cirs, 0.0 * u.deg, atol=1 * u.microarcsecond)
예제 #15
0
def true_longitude(t='now'):
    """
    Returns the Sun's true geometric longitude, referred to the mean equinox of date.  No
    corrections for nutation or aberration are included.

    Parameters
    ----------
    t : {parse_time_types}
        Time to use in a parse-time-compatible format
    """
    time = parse_time(t)

    # Calculate Earth's true geometric longitude and add 180 degrees for the Sun's longitude.
    # This approach is used because Astropy's GeocentricMeanEcliptic includes aberration.
    earth = SkyCoord(0*u.deg, 0*u.deg, 0*u.AU, frame='gcrs', obstime=time)
    coord = earth.transform_to(HeliocentricMeanEcliptic(equinox=time))
    lon = coord.lon + 180*u.deg

    return Longitude(lon)