def test_gcrs_altaz():
    """
    Check GCRS<->AltAz transforms for round-tripping.  Has multiple paths
    """
    from astropy.coordinates import EarthLocation

    ra, dec, _ = randomly_sample_sphere(1)
    gcrs = GCRS(ra=ra[0], dec=dec[0], obstime='J2000')

    # check array times sure N-d arrays work
    times = Time(np.linspace(2456293.25, 2456657.25, 51) * u.day,
                 format='jd', scale='utc')

    loc = EarthLocation(lon=10 * u.deg, lat=80. * u.deg)
    aaframe = AltAz(obstime=times, location=loc)

    aa1 = gcrs.transform_to(aaframe)
    aa2 = gcrs.transform_to(ICRS).transform_to(CIRS).transform_to(aaframe)
    aa3 = gcrs.transform_to(ITRS).transform_to(CIRS).transform_to(aaframe)

    # make sure they're all consistent
    assert_allclose(aa1.alt, aa2.alt)
    assert_allclose(aa1.az, aa2.az)
    assert_allclose(aa1.alt, aa3.alt)
    assert_allclose(aa1.az, aa3.az)
Exemplo n.º 2
0
def eci2el(x,y,z,dt):
    """
    Convert Earth-Centered Inertial (ECI) cartesian coordinates to ITRS for astropy EarthLocation object.

    Inputs :
    x = ECI X-coordinate 
    y = ECI Y-coordinate 
    z = ECI Z-coordinate 
    dt = UTC time (datetime object)
    """

    from astropy.coordinates import GCRS, ITRS, EarthLocation, CartesianRepresentation
    import astropy.units as u
    
    # convert datetime object to astropy time object
    tt=Time(dt,format='datetime')

    # Read the coordinates in the Geocentric Celestial Reference System
    gcrs = GCRS(CartesianRepresentation(x=x, y=y,z=z), obstime=tt)

    # Convert it to an Earth-fixed frame
    itrs = gcrs.transform_to(ITRS(obstime=tt))

    el = EarthLocation.from_geocentric(itrs.x, itrs.y, itrs.z) 

    return el
Exemplo n.º 3
0
    def earth_location_itrf(self, time=None):
        '''Return Fermi spacecraft location in ITRF coordinates'''

        if self.tt2tdb_mode.lower().startswith('none'):
            log.warning('Using location=None for TT to TDB conversion')
            return None
        elif self.tt2tdb_mode.lower().startswith('geo'):
            log.warning('Using location geocenter for TT to TDB conversion')
            return EarthLocation.from_geocentric(0.0*u.m,0.0*u.m,0.0*u.m)
        elif self.tt2tdb_mode.lower().startswith('spacecraft'):
            # First, interpolate Earth-Centered Inertial (ECI) geocentric
            # location from orbit file.
            # These are inertial coordinates aligned with ICRS, called GCRS
            # <http://docs.astropy.org/en/stable/api/astropy.coordinates.GCRS.html>
            pos_gcrs =  GCRS(CartesianRepresentation(self.X(time.tt.mjd)*u.m,
                                                     self.Y(time.tt.mjd)*u.m,
                                                     self.Z(time.tt.mjd)*u.m),
                             obstime=time)

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

            # Return geocentric ITRS coordinates as an EarthLocation object
            return pos_ITRS.earth_location
        else:
            log.error('Unknown tt2tdb_mode %s, using None', self.tt2tdb_mode)
            return None
def test_gcrs_icrs_moonish(testframe):
    """
    check that something like the moon goes to about the right distance from the
    ICRS origin when starting from GCRS
    """
    moonish = GCRS(MOONDIST_CART, obstime=testframe.obstime)
    moonicrs = moonish.transform_to(ICRS)

    assert 0.97*u.au < moonicrs.distance < 1.03*u.au
def test_gcrs_altaz_moonish(testframe):
    """
    Sanity-check that an object resembling the moon goes to the right place with
    a GCRS->AltAz transformation
    """
    moon = GCRS(MOONDIST_CART, obstime=testframe.obstime)

    moonaa = moon.transform_to(testframe)

    # now check that the distance change is similar to earth radius
    assert 1000*u.km < np.abs(moonaa.distance - moon.distance).to(u.au) < 7000*u.km

    # now check that it round-trips
    moon2 = moonaa.transform_to(moon)
    assert_allclose(moon.cartesian.xyz, moon2.cartesian.xyz)
def test_gcrs_altaz_bothroutes(testframe):
    """
    Repeat of both the moonish and sunish tests above to make sure the two
    routes through the coordinate graph are consistent with each other
    """
    sun = get_sun(testframe.obstime)
    sunaa_viaicrs = sun.transform_to(ICRS).transform_to(testframe)
    sunaa_viaitrs = sun.transform_to(ITRS(obstime=testframe.obstime)).transform_to(testframe)

    moon = GCRS(MOONDIST_CART, obstime=testframe.obstime)
    moonaa_viaicrs = moon.transform_to(ICRS).transform_to(testframe)
    moonaa_viaitrs = moon.transform_to(ITRS(obstime=testframe.obstime)).transform_to(testframe)

    assert_allclose(sunaa_viaicrs.cartesian.xyz, sunaa_viaitrs.cartesian.xyz)
    assert_allclose(moonaa_viaicrs.cartesian.xyz, moonaa_viaitrs.cartesian.xyz)
def test_gcrs_cirs():
    """
    Check GCRS<->CIRS transforms for round-tripping.  More complicated than the
    above two because it's multi-hop
    """
    ra, dec, _ = randomly_sample_sphere(200)
    gcrs = GCRS(ra=ra, dec=dec, obstime='J2000')
    gcrs6 = GCRS(ra=ra, dec=dec, obstime='J2006')

    gcrs2 = gcrs.transform_to(CIRS).transform_to(gcrs)
    gcrs6_2 = gcrs6.transform_to(CIRS).transform_to(gcrs)

    assert_allclose(gcrs.ra, gcrs2.ra)
    assert_allclose(gcrs.dec, gcrs2.dec)
    assert not allclose(gcrs.ra, gcrs6_2.ra)
    assert not allclose(gcrs.dec, gcrs6_2.dec)

    # now try explicit intermediate pathways and ensure they're all consistent
    gcrs3 = gcrs.transform_to(ITRS).transform_to(CIRS).transform_to(ITRS).transform_to(gcrs)
    assert_allclose(gcrs.ra, gcrs3.ra)
    assert_allclose(gcrs.dec, gcrs3.dec)

    gcrs4 = gcrs.transform_to(ICRS).transform_to(CIRS).transform_to(ICRS).transform_to(gcrs)
    assert_allclose(gcrs.ra, gcrs4.ra)
    assert_allclose(gcrs.dec, gcrs4.dec)
def test_gcrs_itrs():
    """
    Check basic GCRS<->ITRS transforms for round-tripping.
    """
    ra, dec, _ = randomly_sample_sphere(200)
    gcrs = GCRS(ra=ra, dec=dec, obstime='J2000')
    gcrs6 = GCRS(ra=ra, dec=dec, obstime='J2006')

    gcrs2 = gcrs.transform_to(ITRS).transform_to(gcrs)
    gcrs6_2 = gcrs6.transform_to(ITRS).transform_to(gcrs)

    assert_allclose(gcrs.ra, gcrs2.ra)
    assert_allclose(gcrs.dec, gcrs2.dec)
    assert not allclose(gcrs.ra, gcrs6_2.ra)
    assert not allclose(gcrs.dec, gcrs6_2.dec)

    # also try with the cartesian representation
    gcrsc = gcrs.realize_frame(gcrs.data)
    gcrsc.representation_type = CartesianRepresentation
    gcrsc2 = gcrsc.transform_to(ITRS).transform_to(gcrsc)
    assert_allclose(gcrsc.spherical.lon.deg, gcrsc2.ra.deg)
    assert_allclose(gcrsc.spherical.lat, gcrsc2.dec)
def test_precessed_geocentric():
    assert PrecessedGeocentric().equinox.jd == Time('J2000', scale='utc').jd

    gcrs_coo = GCRS(180*u.deg, 2*u.deg, distance=10000*u.km)
    pgeo_coo = gcrs_coo.transform_to(PrecessedGeocentric)
    assert np.abs(gcrs_coo.ra - pgeo_coo.ra) > 10*u.marcsec
    assert np.abs(gcrs_coo.dec - pgeo_coo.dec) > 10*u.marcsec
    assert_allclose(gcrs_coo.distance, pgeo_coo.distance)

    gcrs_roundtrip = pgeo_coo.transform_to(GCRS)
    assert_allclose(gcrs_coo.ra, gcrs_roundtrip.ra)
    assert_allclose(gcrs_coo.dec, gcrs_roundtrip.dec)
    assert_allclose(gcrs_coo.distance, gcrs_roundtrip.distance)

    pgeo_coo2 = gcrs_coo.transform_to(PrecessedGeocentric(equinox='B1850'))
    assert np.abs(gcrs_coo.ra - pgeo_coo2.ra) > 1.5*u.deg
    assert np.abs(gcrs_coo.dec - pgeo_coo2.dec) > 0.5*u.deg
    assert_allclose(gcrs_coo.distance, pgeo_coo2.distance)

    gcrs2_roundtrip = pgeo_coo2.transform_to(GCRS)
    assert_allclose(gcrs_coo.ra, gcrs2_roundtrip.ra)
    assert_allclose(gcrs_coo.dec, gcrs2_roundtrip.dec)
    assert_allclose(gcrs_coo.distance, gcrs2_roundtrip.distance)
Exemplo n.º 10
0
    def gen_trajectory(self, tle, interval):
        """
        Generates the trajectory (time and coordinate information) for the given
        interval with the internal stepsize.
        Parameters
        ----------
        tle : TLE
            Two-Line-Element initial orbit information (TEME mean orbital elements)
        interval : TimeInterval
            Time interval for which the ephemeris will be generated
        Returns
        -------
        Trajectory
            The output trajectory (in `GCRS`)
        """

        # ****** Generate the pos, vel vectors for each time instant ******

        # generate the output timelist
        time_list = self._generate_time_list(interval)

        # Run the propagation and init pos and vel vectors in TEME
        e, r_list, v_list = tle.satrec.sgp4_array(time_list.jd1, time_list.jd2)

        # Load the time, pos, vel info into astropy objects (shallow copied)
        rv_list_teme = CartesianRepresentation(
            r_list, unit=u.km, xyz_axis=1
        ).with_differentials(CartesianDifferential(v_list, unit=u.km / u.s, xyz_axis=1))

        rv_list_gcrs = TEME(
            rv_list_teme,
            obstime=time_list,
            representation_type="cartesian",
            differential_type="cartesian",
        ).transform_to(GCRS(obstime=time_list))

        # trajectory in astropy
        traj_astropy = SkyCoord(
            rv_list_gcrs,
            obstime=time_list,
            frame="gcrs",
            representation_type="cartesian",
            differential_type="cartesian",
        )

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

        return trajectory
Exemplo n.º 11
0
    def test_horizontal(self):
        """Test `Coordinate.horizontal`.

        Notes
        -----
        Test cases generated using the `Astropy` Python package.
        """

        from astropy.coordinates import SkyCoord, ITRS, GCRS, EarthLocation, AltAz
        from astropy import units as u
        from astropy import time

        # Set up observer location.
        lat, lon = 52.1579, -106.6702
        loc = EarthLocation.from_geodetic(lon * u.deg, lat * u.deg)

        # Prepare time and position information.
        times = time.Time(self.times + self.offset, format="jd")
        x, y, z = self.GCRS.T

        # Define coordinate frames.
        gcrs = GCRS(obstime=times)
        itrs = ITRS(obstime=times)
        altaz = AltAz(obstime=times, location=loc)

        # Convert between frames.
        gcrsCoor = SkyCoord(x=x,
                            y=y,
                            z=z,
                            unit='km',
                            frame=gcrs,
                            representation_type='cartesian')
        itrsCoor = gcrsCoor.transform_to(itrs)
        altazCoor = itrsCoor.transform_to(altaz)

        # Get validation data.
        itrsData = np.transpose(np.array([itrsCoor.x, itrsCoor.y, itrsCoor.z]))
        alt = altazCoor.alt.degree
        az = altazCoor.az.degree

        # Get Celest results.
        coor = Coordinate(itrsData, "itrs", self.times, self.offset)
        groundPos = GroundPosition(lat, lon)
        calc_alt, calc_az = coor.horizontal(groundPos)

        for i in range(calc_alt.size):
            with self.subTest(i=i):
                self.assertAlmostEqual(alt[i], calc_alt[i], delta=0.25)
                self.assertAlmostEqual(az[i], calc_az[i], delta=7.5)
Exemplo n.º 12
0
    def earth_location_itrf(self, time=None):
        '''Return NICER spacecraft location in ITRF coordinates'''

        if self.tt2tdb_mode.lower().startswith('none'):
            return None
        elif self.tt2tdb_mode.lower().startswith('geo'):
            return EarthLocation.from_geocentric(0.0*u.m,0.0*u.m,0.0*u.m)
        elif self.tt2tdb_mode.lower().startswith('spacecraft'):
            # First, interpolate ECI geocentric location from orbit file.
            # These are inertial coorinates aligned with ICRF
            pos_gcrs =  GCRS(CartesianRepresentation(self.X(time.tt.mjd)*u.m,
                                                     self.Y(time.tt.mjd)*u.m,
                                                     self.Z(time.tt.mjd)*u.m),
                             obstime=time)

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

            # Return geocentric ITRS coordinates as an EarthLocation object
            return pos_ITRS.earth_location
        else:
            log.error('Unknown tt2tdb_mode %s, using None', self.tt2tdb_mode)
            return None
def ecef2eci(time, r_ecef, v_ecef, init_gps_weeknum):
    """Returns a tuple of position and velocity in ECI"""
    coord_ecef = ITRS(x=r_ecef[0] * u.m,
                      y=r_ecef[1] * u.m,
                      z=r_ecef[2] * u.m,
                      v_x=v_ecef[0] * u.m / u.s,
                      v_y=v_ecef[1] * u.m / u.s,
                      v_z=v_ecef[2] * u.m / u.s,
                      representation_type=CartesianRepresentation,
                      differential_type=CartesianDifferential,
                      obstime=time2astropyTime(time, init_gps_weeknum))
    coord_eci = coord_ecef.transform_to(
        GCRS(obstime=time2astropyTime(time, init_gps_weeknum)))
    return (coord_eci.cartesian.xyz.to_value(u.m),
            coord_eci.velocity.d_xyz.to_value(u.m / u.s))
Exemplo n.º 14
0
    def earth_location_itrf(self, time=None):
        '''Return NuSTAR spacecraft location in ITRF coordinates'''

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

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

            # Return geocentric ITRS coordinates as an EarthLocation object
            return pos_ITRS.earth_location
        else:
            log.error('Unknown tt2tdb_mode %s, using None' % self.tt2tdb_mode)
            return None
Exemplo n.º 15
0
    def _from_raw_to_ITRS(self, raw_xyz, raw_obstime):
        """Converts raw coordinates to ITRS ones

        Parameters
        ----------
        raw_xyz: array
            A collection of rwa position coordinates
        raw_obstime: array
            Associated observation time

        Returns
        -------
        itrs_xyz: ~astropy.coordinates.ITRS
            A collection of coordinates in ITRS frame

        """

        # Build GCRS and ITRS coordinates
        gcrs_xyz = GCRS(raw_xyz,
                        obstime=raw_obstime,
                        representation_type=CartesianRepresentation)
        itrs_xyz = gcrs_xyz.transform_to(ITRS(obstime=raw_obstime))

        return itrs_xyz
Exemplo n.º 16
0
def test_gcrs_altaz():
    """
    Check GCRS<->AltAz transforms for round-tripping.  Has multiple paths
    """
    from astropy.coordinates import EarthLocation

    ra, dec, _ = randomly_sample_sphere(1)
    gcrs = GCRS(ra=ra[0], dec=dec[0], obstime='J2000')

    # check array times sure N-d arrays work
    times = Time(np.linspace(2456293.25, 2456657.25, 51) * u.day, format='jd')

    loc = EarthLocation(lon=10 * u.deg, lat=80. * u.deg)
    aaframe = AltAz(obstime=times, location=loc)

    aa1 = gcrs.transform_to(aaframe)
    aa2 = gcrs.transform_to(ICRS()).transform_to(CIRS()).transform_to(aaframe)
    aa3 = gcrs.transform_to(ITRS()).transform_to(CIRS()).transform_to(aaframe)

    # make sure they're all consistent
    assert_allclose(aa1.alt, aa2.alt)
    assert_allclose(aa1.az, aa2.az)
    assert_allclose(aa1.alt, aa3.alt)
    assert_allclose(aa1.az, aa3.az)
Exemplo n.º 17
0
 def setup_class(cls):
     cls.loc = loc = EarthLocation.from_geodetic(
         np.linspace(0, 360, 6) * u.deg,
         np.linspace(-90, 90, 6) * u.deg, 100 * u.m)
     cls.obstime = obstime = Time(np.linspace(2000, 2010, 6),
                                  format='jyear')
     # Get comparison via a full transformation.  We do not use any methods
     # of EarthLocation, since those depend on the fast transform.
     loc_itrs = ITRS(loc.x, loc.y, loc.z, obstime=obstime)
     zeros = np.broadcast_to(0. * (u.km / u.s), (3, ) + loc_itrs.shape,
                             subok=True)
     loc_itrs.data.differentials['s'] = CartesianDifferential(zeros)
     loc_gcrs_cart = loc_itrs.transform_to(GCRS(obstime=obstime)).cartesian
     cls.obsgeoloc = loc_gcrs_cart.without_differentials()
     cls.obsgeovel = loc_gcrs_cart.differentials['s'].to_cartesian()
Exemplo n.º 18
0
def geoTopoVector(longitude, latitude, elevation, jd):

    loc = EarthLocation(longitude, latitude, elevation)

    time = Time(jd, scale='utc', format='jd')
    itrs = loc.get_itrs(obstime=time)
    gcrs = itrs.transform_to(GCRS(obstime=time))

    r = gcrs.cartesian

    # convert from m to km
    x = r.x.value / 1000.0
    y = r.y.value / 1000.0
    z = r.z.value / 1000.0

    return x, y, z
def test_icrs_gcrscirs_sunish(testframe):
    """
    check that the ICRS barycenter goes to about the right distance from various
    ~geocentric frames (other than testframe)
    """
    # slight offset to avoid divide-by-zero errors
    icrs = ICRS(0*u.deg, 0*u.deg, distance=10*u.km)

    gcrs = icrs.transform_to(GCRS(obstime=testframe.obstime))
    assert (EARTHECC - 1)*u.au < gcrs.distance.to(u.au) < (EARTHECC + 1)*u.au

    cirs = icrs.transform_to(CIRS(obstime=testframe.obstime))
    assert (EARTHECC - 1)*u.au < cirs.distance.to(u.au) < (EARTHECC + 1)*u.au

    itrs = icrs.transform_to(ITRS(obstime=testframe.obstime))
    assert (EARTHECC - 1)*u.au < itrs.spherical.distance.to(u.au) < (EARTHECC + 1)*u.au
Exemplo n.º 20
0
def test_j2000_to_gcrs():
    """Check the coordinate transform accuracy."""
    # test_frame = "GCRS"
    allowable_pos_diff = 800 * u.mm
    allowable_vel_diff = 0.36 * u.mm / u.s

    rv_gcrs = rv_j2000_true.transform_to(GCRS(obstime=time))

    r_diff = pos_err(rv_gcrs, rv_gcrs_true)
    v_diff = vel_err(rv_gcrs, rv_gcrs_true)

    # print(f"r {test_frame} diff      :  {r_diff}")
    # print(f"v {test_frame} diff      :  {v_diff}")

    assert approx(r_diff.value, abs=allowable_pos_diff.value) == 0.0
    assert approx(v_diff.value, abs=allowable_vel_diff.value) == 0.0
Exemplo n.º 21
0
def TEME2ECI_pos(Pos_TEME, t):

    T = Time(t, format='jd', scale='utc')

    dist_vect = norm(Pos_TEME, axis=0)
    ra_vect = np.arctan2(Pos_TEME[1], Pos_TEME[0])
    dec_vect = np.arcsin(Pos_TEME[2] / dist_vect)

    Pos_TEME_SC = PrecessedGeocentric(ra=ra_vect * u.rad,
                                      dec=dec_vect * u.rad,
                                      distance=dist_vect * u.m,
                                      equinox=T,
                                      obstime=T)
    Pos_ECI_SC = Pos_TEME_SC.transform_to(GCRS(obstime=T))
    Pos_ECI = np.vstack(Pos_ECI_SC.cartesian.xyz.value)

    return Pos_ECI
def ecef2eci(x, y, z, dt):
    """This function takes a position in the ECEF coordinate system [m] and datetime.object [utc] and returns it 
    in ECI-J2000 [m]."""

    #

    # Input

    # x = ECEF X-coordinate (m)

    # y = ECEF Y-coordinate (m)

    # z = ECEF Z-coordinate (m)

    # dt = UTC time (datetime object)

    #

    #

    # Output

    #

    # convert datetime object to astropy time object

    tt = time.Time(dt, format="datetime")

    # Read the coordinates in the Earth-fixed frame

    itrs = ITRS(
        CartesianRepresentation(x=x * units.m, y=y * units.m, z=z * units.m), obstime=tt
    )

    # Convert it to  Geocentric Celestial Reference System

    # gcrs = itrs.transform_to(itrs(obstime=tt))
    gcrs = itrs.transform_to(GCRS(obstime=tt))

    x = gcrs.cartesian.x.to_value()

    y = gcrs.cartesian.y.to_value()

    z = gcrs.cartesian.z.to_value()

    return x, y, z
Exemplo n.º 23
0
def test_skycoord_transforms():
    # An EarthLocation object should still get copied over
    # under transformations.

    eloc = EarthLocation.from_geodetic(0.0, 10.0)
    coords = ltest.get_catalog()

    altaz = coords.transform_to(AltAz(location=eloc, obstime=Time.now()))

    assert altaz.location == eloc

    gcrs = altaz.transform_to(GCRS())

    assert gcrs.location == eloc

    icrs = altaz.transform_to(ICRS())

    assert icrs.location == eloc
Exemplo n.º 24
0
def HCI2ECI_pos(Pos_HCI, t):

    # Position & velocity relative to the sun
    T = Time(t, format='jd', scale='utc')

    Pos_HCRS = HCI2HCRS(Pos_HCI)
    # TODO. HARD: had to remove it
    #Vel_HCRS_rel = HCI2HCRS(Vel_HCI - EarthVelocity(t))

    Pos_HCRS_SC = HCRS(x=Pos_HCRS[0] * u.m,
                       y=Pos_HCRS[1] * u.m,
                       z=Pos_HCRS[2] * u.m,
                       representation='cartesian',
                       obstime=T)
    Pos_ECI = np.vstack(
        Pos_HCRS_SC.transform_to(GCRS(obstime=T)).cartesian.xyz.value)

    return Pos_ECI
Exemplo n.º 25
0
def test_j2000_roundtrip():
    """Check whether transforming to a coord and then
    transforming back yields the same output."""
    # test_frame = "J2000"
    allowable_pos_diff = 1.5e-6 * u.mm
    allowable_vel_diff = 1.0e-9 * u.mm / u.s

    rv_gcrs = rv_j2000_true.transform_to(GCRS(obstime=time))
    rv_j2000_from_gcrs = rv_gcrs.transform_to(J2000(obstime=time))

    r_diff = pos_err(rv_j2000_from_gcrs, rv_j2000_true)
    v_diff = vel_err(rv_j2000_from_gcrs, rv_j2000_true)

    # print(f"r {test_frame} diff      :  {r_diff}")
    # print(f"v {test_frame} diff      :  {v_diff}")

    assert approx(r_diff.value, abs=allowable_pos_diff.value) == 0.0
    assert approx(v_diff.value, abs=allowable_vel_diff.value) == 0.0
Exemplo n.º 26
0
    def from_body_ephem(cls, body, epoch=None):
        """Return osculating `Orbit` of a body at a given time.

        """
        # TODO: https://github.com/poliastro/poliastro/issues/445
        if not epoch:
            epoch = time.Time.now().tdb
        elif epoch.scale != "tdb":
            epoch = epoch.tdb
            warn(
                "Input time was converted to scale='tdb' with value "
                f"{epoch.tdb.value}. Use Time(..., scale='tdb') instead.",
                TimeScaleWarning,
            )
        try:
            r, v = get_body_barycentric_posvel(body.name, epoch)
        except KeyError:
            raise RuntimeError(
                """To compute the position and velocity of the Moon and Pluto use the JPL ephemeris:

>>> from astropy.coordinates import solar_system_ephemeris
>>> solar_system_ephemeris.set('jpl')
""")
        if body == Moon:
            # TODO: The attractor is in fact the Earth-Moon Barycenter
            icrs_cart = r.with_differentials(
                v.represent_as(CartesianDifferential))
            gcrs_cart = (ICRS(icrs_cart).transform_to(
                GCRS(obstime=epoch)).represent_as(CartesianRepresentation))
            ss = cls.from_vectors(
                Earth,
                gcrs_cart.xyz.to(u.km),
                gcrs_cart.differentials["s"].d_xyz.to(u.km / u.day),
                epoch,
            )

        else:
            # TODO: The attractor is not really the Sun, but the Solar System
            # Barycenter
            ss = cls.from_vectors(Sun, r.xyz.to(u.km), v.xyz.to(u.km / u.day),
                                  epoch)
            ss._frame = ICRS()  # Hack!

        return ss
Exemplo n.º 27
0
def build_ephem_interpolant(body, period, t_span, rtol=1e-5):
    """Interpolates ephemerides data

    Parameters
    ----------
    body : Body
        Source body.
    period : ~astropy.units.Quantity
        Orbital period.
    t_span : list(~astropy.units.Quantity)
        Initial and final epochs.
    rtol : float, optional
        Relative tolerance. Controls the number of sampled data points,
        defaults to 1e-5.

    Returns
    -------
    intrp : ~scipy.interpolate.interpolate.interp1d
        Interpolated function.

    """
    h = (period * rtol).to(u.day).value
    t_span = (t_span[0].to(u.day).value, t_span[1].to(u.day).value + 0.01)
    t_values = np.linspace(*t_span, int(
        (t_span[1] - t_span[0]) / h))  # type: ignore
    r_values = np.zeros((t_values.shape[0], 3))

    for i, t in enumerate(t_values):
        epoch = Time(t, format="jd", scale="tdb")

        r = get_body_barycentric(body.name, epoch)
        r = (ICRS(
            x=r.x, y=r.y, z=r.z,
            representation_type=CartesianRepresentation).transform_to(
                GCRS(obstime=epoch)).represent_as(CartesianRepresentation))

        r_values[i] = r.xyz.to(u.km)

    t_values = ((t_values - t_span[0]) * u.day).to(u.s).value
    return interp1d(t_values,
                    r_values,
                    kind="cubic",
                    axis=0,
                    assume_sorted=True)
Exemplo n.º 28
0
def test_icrs_gcrs(icoo):
    """
    Check ICRS<->GCRS for consistency
    """
    gcrscoo = icoo.transform_to(gcrs_frames[0])  # uses the default time
    # first do a round-tripping test
    icoo2 = gcrscoo.transform_to(ICRS())
    assert_allclose(icoo.distance, icoo2.distance)
    assert_allclose(icoo.ra, icoo2.ra)
    assert_allclose(icoo.dec, icoo2.dec)
    assert isinstance(icoo2.data, icoo.data.__class__)

    # now check that a different time yields different answers
    gcrscoo2 = icoo.transform_to(gcrs_frames[1])
    assert not allclose(gcrscoo.ra, gcrscoo2.ra, rtol=1e-8, atol=1e-10 * u.deg)
    assert not allclose(
        gcrscoo.dec, gcrscoo2.dec, rtol=1e-8, atol=1e-10 * u.deg)

    # now check that the cirs self-transform works as expected
    gcrscoo3 = gcrscoo.transform_to(gcrs_frames[0])  # should be a no-op
    assert_allclose(gcrscoo.ra, gcrscoo3.ra)
    assert_allclose(gcrscoo.dec, gcrscoo3.dec)

    gcrscoo4 = gcrscoo.transform_to(gcrs_frames[1])  # should be different
    assert not allclose(gcrscoo4.ra, gcrscoo.ra, rtol=1e-8, atol=1e-10 * u.deg)
    assert not allclose(
        gcrscoo4.dec, gcrscoo.dec, rtol=1e-8, atol=1e-10 * u.deg)

    gcrscoo5 = gcrscoo4.transform_to(
        gcrs_frames[0])  # should be back to the same
    assert_allclose(gcrscoo.ra, gcrscoo5.ra, rtol=1e-8, atol=1e-10 * u.deg)
    assert_allclose(gcrscoo.dec, gcrscoo5.dec, rtol=1e-8, atol=1e-10 * u.deg)

    # also make sure that a GCRS with a different geoloc/geovel gets a different answer
    # roughly a moon-like frame
    gframe3 = GCRS(obsgeoloc=[385000., 0, 0] * u.km,
                   obsgeovel=[1, 0, 0] * u.km / u.s)
    gcrscoo6 = icoo.transform_to(gframe3)  # should be different
    assert not allclose(gcrscoo.ra, gcrscoo6.ra, rtol=1e-8, atol=1e-10 * u.deg)
    assert not allclose(
        gcrscoo.dec, gcrscoo6.dec, rtol=1e-8, atol=1e-10 * u.deg)
    icooviag3 = gcrscoo6.transform_to(ICRS())  # and now back to the original
    assert_allclose(icoo.ra, icooviag3.ra)
    assert_allclose(icoo.dec, icooviag3.dec)
Exemplo n.º 29
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)
Exemplo n.º 30
0
def test_propagation(init_tle_vgd):
    # init TLE
    tle = init_tle_vgd

    # init SGP4
    sgp4 = SGP4Propagator()

    #  Propagate 3 days into future
    time = tle.epoch + 3.0 * u.day
    rv_gcrs = sgp4.propagate(tle, time)

    # print(rv_gcrs)

    # Generate truth values
    # Vallado IAU-76/FK5 - pg.234
    v_j2000_true = CartesianDifferential(
        [-2.233348094, -4.110136162, -3.157394074], unit=u.km / u.s
    )
    r_j2000_true = CartesianRepresentation(
        [-9059.9413786, 4659.6972000, 813.9588875], unit=u.km
    )

    rv_j2000_true = J2000(
        r_j2000_true.with_differentials(v_j2000_true),
        obstime=time,
        representation_type="cartesian",
        differential_type="cartesian",
    )

    rv_gcrs_true = SkyCoord(
        rv_j2000_true.transform_to(GCRS(obstime=time)),
        representation_type="cartesian",
        differential_type="cartesian",
    )

    r_diff, v_diff = rv_diff(rv_gcrs, rv_gcrs_true)

    # print(r_diff.to(u.mm))
    # print(v_diff.to(u.mm / u.s))

    assert r_diff.to(u.mm) < 1700 * u.mm
    assert v_diff.to(u.mm / u.s) < 0.88 * u.mm / u.s
def test_tete_transforms():
    """
    We test the TETE transforms for proper behaviour here.

    The TETE transforms are tested for accuracy against JPL Horizons in
    test_solar_system.py. Here we are looking to check for consistency and
    errors in the self transform.
    """
    loc = EarthLocation.from_geodetic("-22°57'35.1", "-67°47'14.1", 5186*u.m)
    time = Time('2020-04-06T00:00')
    p, v = loc.get_gcrs_posvel(time)

    gcrs_frame = GCRS(obstime=time, obsgeoloc=p, obsgeovel=v)
    moon = SkyCoord(169.24113968*u.deg, 10.86086666*u.deg, 358549.25381755*u.km, frame=gcrs_frame)

    tete_frame = TETE(obstime=time, location=loc)
    # need to set obsgeoloc/vel explicity or skycoord behaviour over-writes
    tete_geo = TETE(obstime=time, location=EarthLocation(*([0, 0, 0]*u.km)))

    # test self-transform by comparing to GCRS-TETE-ITRS-TETE route
    tete_coo1 = moon.transform_to(tete_frame)
    tete_coo2 = moon.transform_to(tete_geo)
    assert_allclose(tete_coo1.separation_3d(tete_coo2), 0*u.mm, atol=1*u.mm)

    # test TETE-ITRS transform by comparing GCRS-CIRS-ITRS to GCRS-TETE-ITRS
    itrs1 = moon.transform_to(CIRS()).transform_to(ITRS())
    itrs2 = moon.transform_to(TETE()).transform_to(ITRS())
    assert_allclose(itrs1.separation_3d(itrs2), 0*u.mm, atol=1*u.mm)

    # test round trip GCRS->TETE->GCRS
    new_moon = moon.transform_to(TETE()).transform_to(moon)
    assert_allclose(new_moon.separation_3d(moon), 0*u.mm, atol=1*u.mm)

    # test round trip via ITRS
    tete_rt = tete_coo1.transform_to(ITRS(obstime=time)).transform_to(tete_coo1)
    assert_allclose(tete_rt.separation_3d(tete_coo1), 0*u.mm, atol=1*u.mm)

    # ensure deprecated routine remains consistent
    # make sure test raises warning!
    with pytest.warns(AstropyDeprecationWarning, match='The use of'):
        tete_alt = _apparent_position_in_true_coordinates(moon)
    assert_allclose(tete_coo1.separation_3d(tete_alt), 0*u.mm, atol=100*u.mm)
Exemplo n.º 32
0
    def propagate(tle, time):
        """
        Computes the coordinates at the target `time` using the source `TLE` mean
        orbital elements.

        Parameters
        ----------
        tle : TLE
            Mean orbital elements (Two-Line-Element)
        time : Time
            Target time for propagation

        Returns
        -------
        coords : SkyCoord
            Coordinates at target time (in `GCRS`)

        Raises
        ------
        SGP4GeneralError
            Errors in SGP4 propagation
        SGP4SatDecayedError
            Satellite coordinates at required coordinates are below decay altitude.
        """
        # compute coords at time
        e, r, v = tle.satrec.sgp4(time.utc.jd1, time.utc.jd2)

        # check error code
        SGP4Propagator.__handle_err_code(e)

        v_teme = CartesianDifferential(np.asarray(v), unit=u.km / u.s)
        r_teme = CartesianRepresentation(np.asarray(r), unit=u.km)
        rv_gcrs = TEME(r_teme.with_differentials(v_teme),
                       obstime=time).transform_to(GCRS(obstime=time))

        return SkyCoord(
            rv_gcrs,
            representation_type="cartesian",
            differential_type="cartesian",
        )
Exemplo n.º 33
0
    def from_body_ephem(cls, body, epoch=None):
        """Return osculating `Orbit` of a body at a given time.

        """
        # TODO: https://github.com/poliastro/poliastro/issues/445
        if not epoch:
            epoch = time.Time.now().tdb
        elif epoch.scale != "tdb":
            epoch = epoch.tdb
            warn(
                "Input time was converted to scale='tdb' with value "
                "{}. Use Time(..., scale='tdb') instead.".format(
                    epoch.tdb.value),
                TimeScaleWarning,
            )

        r, v = get_body_barycentric_posvel(body.name, epoch)

        if body == Moon:
            # TODO: The attractor is in fact the Earth-Moon Barycenter
            icrs_cart = r.with_differentials(
                v.represent_as(CartesianDifferential))
            gcrs_cart = (ICRS(icrs_cart).transform_to(
                GCRS(obstime=epoch)).represent_as(CartesianRepresentation))
            ss = cls.from_vectors(
                Earth,
                gcrs_cart.xyz.to(u.km),
                gcrs_cart.differentials["s"].d_xyz.to(u.km / u.day),
                epoch,
            )

        else:
            # TODO: The attractor is not really the Sun, but the Solar System
            # Barycenter
            ss = cls.from_vectors(Sun, r.xyz.to(u.km), v.xyz.to(u.km / u.day),
                                  epoch)
            ss._frame = ICRS()  # Hack!

        return ss
Exemplo n.º 34
0
def test_get_skycoord():
    m31 = SkyCoord(10.6847083 * u.deg, 41.26875 * u.deg)
    m31_with_distance = SkyCoord(10.6847083 * u.deg, 41.26875 * u.deg,
                                 780 * u.kpc)
    subaru = Observer.at_site('subaru')
    time = Time("2016-01-22 12:00")
    pos, vel = subaru.location.get_gcrs_posvel(time)
    gcrs_frame = GCRS(obstime=Time("2016-01-22 12:00"),
                      obsgeoloc=pos,
                      obsgeovel=vel)
    m31_gcrs = m31.transform_to(gcrs_frame)
    m31_gcrs_with_distance = m31_with_distance.transform_to(gcrs_frame)

    coo = get_skycoord(m31)
    assert coo.is_equivalent_frame(ICRS())
    with pytest.raises(TypeError) as exc_info:
        len(coo)

    coo = get_skycoord([m31])
    assert coo.is_equivalent_frame(ICRS())
    assert len(coo) == 1

    coo = get_skycoord([m31, m31_gcrs])
    assert coo.is_equivalent_frame(ICRS())
    assert len(coo) == 2

    coo = get_skycoord([m31_with_distance, m31_gcrs_with_distance])
    assert coo.is_equivalent_frame(ICRS())
    assert len(coo) == 2

    coo = get_skycoord(
        [m31, m31_gcrs, m31_gcrs_with_distance, m31_with_distance])
    assert coo.is_equivalent_frame(ICRS())
    assert len(coo) == 4

    coo = get_skycoord([m31_gcrs, m31_gcrs_with_distance])
    assert coo.is_equivalent_frame(m31_gcrs.frame)
    assert len(coo) == 2
Exemplo n.º 35
0
def test_init_cart():
    """Tests the cartesian initialisation convenience method."""

    rv_gcrs_true_sky = SkyCoord(rv_gcrs_true)

    # easy init
    rv_gcrs_0 = init_pvt(GCRS, time, r_gcrs_true, v_gcrs_true)

    # init with str frame name (should be lowercase letters)
    rv_gcrs_1 = init_pvt("GCRS", time, r_gcrs_true, v_gcrs_true)

    # init without velocity
    rv_gcrs_2 = init_pvt(GCRS, time, r_gcrs_true, copy=False)

    assert rv_gcrs_0 == rv_gcrs_true_sky
    assert rv_gcrs_1 == rv_gcrs_true_sky
    assert rv_gcrs_2 == SkyCoord(
        GCRS(
            r_gcrs_true,
            obstime=time,
            representation_type="cartesian",
            differential_type="cartesian",
        ))
Exemplo n.º 36
0
def build_ephem_interpolant(body, period, t_span, rtol=1e-5):
    h = (period * rtol).to(u.day).value
    t_span = (t_span[0].to(u.day).value, t_span[1].to(u.day).value + 0.01)
    t_values = np.linspace(*t_span, int((t_span[1] - t_span[0]) / h))
    r_values = np.zeros((t_values.shape[0], 3))

    for i, t in enumerate(t_values):
        epoch = Time(t, format="jd", scale="tdb")

        r = get_body_barycentric(body.name, epoch)
        r = (ICRS(
            x=r.x, y=r.y, z=r.z,
            representation_type=CartesianRepresentation).transform_to(
                GCRS(obstime=epoch)).represent_as(CartesianRepresentation))

        r_values[i] = r.xyz.to(u.km)

    t_values = ((t_values - t_span[0]) * u.day).to(u.s).value
    return interp1d(t_values,
                    r_values,
                    kind="cubic",
                    axis=0,
                    assume_sorted=True)
def test_gcrs_itrs():
    """
    Check basic GCRS<->ITRS transforms for round-tripping.
    """
    ra, dec, _ = randomly_sample_sphere(200)
    gcrs = GCRS(ra=ra, dec=dec, obstime='J2000')
    gcrs6 = GCRS(ra=ra, dec=dec, obstime='J2006')

    gcrs2 = gcrs.transform_to(ITRS).transform_to(gcrs)
    gcrs6_2 = gcrs6.transform_to(ITRS).transform_to(gcrs)

    assert_allclose(gcrs.ra, gcrs2.ra)
    assert_allclose(gcrs.dec, gcrs2.dec)
    assert not allclose(gcrs.ra, gcrs6_2.ra)
    assert not allclose(gcrs.dec, gcrs6_2.dec)

    # also try with the cartesian representation
    gcrsc = gcrs.realize_frame(gcrs.data)
    gcrsc.representation_type = CartesianRepresentation
    gcrsc2 = gcrsc.transform_to(ITRS).transform_to(gcrsc)
    assert_allclose(gcrsc.spherical.lon.deg, gcrsc2.ra.deg)
    assert_allclose(gcrsc.spherical.lat, gcrsc2.dec)
Exemplo n.º 38
0
def test_gcrs_itrs():
    """
    Check basic GCRS<->ITRS transforms for round-tripping.
    """
    usph = golden_spiral_grid(200)
    gcrs = GCRS(usph, obstime='J2000')
    gcrs6 = GCRS(usph, obstime='J2006')

    gcrs2 = gcrs.transform_to(ITRS()).transform_to(gcrs)
    gcrs6_2 = gcrs6.transform_to(ITRS()).transform_to(gcrs)

    assert_allclose(gcrs.ra, gcrs2.ra)
    assert_allclose(gcrs.dec, gcrs2.dec)
    # these should be different:
    assert not allclose(gcrs.ra, gcrs6_2.ra, rtol=1e-8)
    assert not allclose(gcrs.dec, gcrs6_2.dec, rtol=1e-8)

    # also try with the cartesian representation
    gcrsc = gcrs.realize_frame(gcrs.data)
    gcrsc.representation_type = CartesianRepresentation
    gcrsc2 = gcrsc.transform_to(ITRS()).transform_to(gcrsc)
    assert_allclose(gcrsc.spherical.lon, gcrsc2.ra)
    assert_allclose(gcrsc.spherical.lat, gcrsc2.dec)
Exemplo n.º 39
0
def test_precessed_geocentric():
    assert PrecessedGeocentric().equinox.jd == Time('J2000').jd

    gcrs_coo = GCRS(180 * u.deg, 2 * u.deg, distance=10000 * u.km)
    pgeo_coo = gcrs_coo.transform_to(PrecessedGeocentric())
    assert np.abs(gcrs_coo.ra - pgeo_coo.ra) > 10 * u.marcsec
    assert np.abs(gcrs_coo.dec - pgeo_coo.dec) > 10 * u.marcsec
    assert_allclose(gcrs_coo.distance, pgeo_coo.distance)

    gcrs_roundtrip = pgeo_coo.transform_to(GCRS())
    assert_allclose(gcrs_coo.ra, gcrs_roundtrip.ra)
    assert_allclose(gcrs_coo.dec, gcrs_roundtrip.dec)
    assert_allclose(gcrs_coo.distance, gcrs_roundtrip.distance)

    pgeo_coo2 = gcrs_coo.transform_to(PrecessedGeocentric(equinox='B1850'))
    assert np.abs(gcrs_coo.ra - pgeo_coo2.ra) > 1.5 * u.deg
    assert np.abs(gcrs_coo.dec - pgeo_coo2.dec) > 0.5 * u.deg
    assert_allclose(gcrs_coo.distance, pgeo_coo2.distance)

    gcrs2_roundtrip = pgeo_coo2.transform_to(GCRS())
    assert_allclose(gcrs_coo.ra, gcrs2_roundtrip.ra)
    assert_allclose(gcrs_coo.dec, gcrs2_roundtrip.dec)
    assert_allclose(gcrs_coo.distance, gcrs2_roundtrip.distance)
Exemplo n.º 40
0
    assert_allclose(cirsnod.ra, cirsnod3.ra)
    assert_allclose(cirsnod.dec, cirsnod3.dec)

    cirsnod4 = cirsnod.transform_to(cframe2)  # should be different
    assert not allclose(cirsnod4.ra, cirsnod.ra, rtol=1e-8)
    assert not allclose(cirsnod4.dec, cirsnod.dec, rtol=1e-8)

    cirsnod5 = cirsnod4.transform_to(cframe1)  # should be back to the same
    assert_allclose(cirsnod.ra, cirsnod5.ra)
    assert_allclose(cirsnod.dec, cirsnod5.dec)


usph = golden_spiral_grid(200)
dist = np.linspace(0.5, 1, len(usph)) * u.pc
icrs_coords = [ICRS(usph), ICRS(usph.lon, usph.lat, distance=dist)]
gcrs_frames = [GCRS(), GCRS(obstime=Time('J2005'))]


@pytest.mark.parametrize('icoo', icrs_coords)
def test_icrs_gcrs(icoo):
    """
    Check ICRS<->GCRS for consistency
    """
    gcrscoo = icoo.transform_to(gcrs_frames[0])  # uses the default time
    # first do a round-tripping test
    icoo2 = gcrscoo.transform_to(ICRS())
    assert_allclose(icoo.distance, icoo2.distance)
    assert_allclose(icoo.ra, icoo2.ra)
    assert_allclose(icoo.dec, icoo2.dec)
    assert isinstance(icoo2.data, icoo.data.__class__)
Exemplo n.º 41
0
def test_gcrs_itrs_cartesian_repr():
    # issue 6436: transformation failed if coordinate representation was
    # Cartesian
    gcrs = GCRS(CartesianRepresentation((859.07256, -4137.20368,  5295.56871),
                                        unit='km'), representation_type='cartesian')
    gcrs.transform_to(ITRS)
Exemplo n.º 42
0
def test_regression_8138():
    sc = SkyCoord(1*u.deg, 2*u.deg)
    newframe = GCRS()
    sc2 = sc.transform_to(newframe)
    assert newframe.is_equivalent_frame(sc2.frame)