def test_lsr_loopback(frame): xyz = CartesianRepresentation(1, 2, 3) * u.AU xyz = xyz.with_differentials(CartesianDifferential(4, 5, 6) * u.km / u.s) v_bary = CartesianDifferential(5, 10, 15) * u.km / u.s # Test that the loopback properly handles a change in v_bary from_coo = frame(xyz) # default v_bary to_frame = frame(v_bary=v_bary) explicit_coo = from_coo.transform_to(ICRS()).transform_to(to_frame) implicit_coo = from_coo.transform_to(to_frame) # Confirm that the explicit transformation changes the velocity but not the position assert allclose(explicit_coo.cartesian.xyz, from_coo.cartesian.xyz, rtol=1e-10) assert not allclose( explicit_coo.velocity.d_xyz, from_coo.velocity.d_xyz, rtol=1e-10) # Confirm that the loopback matches the explicit transformation assert allclose(explicit_coo.cartesian.xyz, implicit_coo.cartesian.xyz, rtol=1e-10) assert allclose(explicit_coo.velocity.d_xyz, implicit_coo.velocity.d_xyz, rtol=1e-10)
def test_creation_cartesian(): rep = CartesianRepresentation([10, 0., 0.] * u.pc) dif = CartesianDifferential([0, 100, 0.] * u.pc / u.Myr) rep = rep.with_differentials(dif) c = SkyCoord(rep) sdif = dif.represent_as(SphericalCosLatDifferential, rep) assert_quantity_allclose(c.pm_ra_cosdec, sdif.d_lon_coslat)
def test_creation_cartesian(): rep = CartesianRepresentation([10, 0., 0.]*u.pc) dif = CartesianDifferential([0, 100, 0.]*u.pc/u.Myr) rep = rep.with_differentials(dif) c = SkyCoord(rep) sdif = dif.represent_as(SphericalCosLatDifferential, rep) assert_quantity_allclose(c.pm_ra_cosdec, sdif.d_lon_coslat)
def __call__(self, t): """ Computes the interpolated coordinates at the given time(s). Parameters ---------- t : Time Time or list of times where an interpolated coordinate is required Returns ------- coords : SkyCoord A `SkyCoord` object with the requested coordinate(s), in the original frame Raises ------ ValueError If the requested `t` value is out of bounds for the interpolator """ if not self._interpolators_initialised: # Lazy init interpolators only when required self._init_interpolators() # **** get coords at requested time **** # compute raw r and v vectors and # fill Astropy cartesian vectors (with velocities if available) if t.isscalar: # there is a single time instance coords = CartesianRepresentation(self._compute_pos(t), copy=False) if self._has_velocity: v = CartesianDifferential(self._compute_vel(t), copy=False) coords = coords.with_differentials(v) else: # there is more than one time instance r = [self._compute_pos(time) for time in t] coords = CartesianRepresentation(np.asarray(r), unit=r[0].unit, copy=False, xyz_axis=1) if self._has_velocity: v = [self._compute_vel(time) for time in t] v = CartesianDifferential(np.asarray(v), unit=v[0].unit, copy=False, xyz_axis=1) coords = coords.with_differentials(v) return SkyCoord( coords, obstime=t, frame=self._frame_name, representation_type="cartesian", differential_type="cartesian", )
def setup(self): # Avoid top-level module import to make sure that the benchmarks are # compatible with versions of astropy that did not have this functionality. from astropy.coordinates import CartesianDifferential self.scalar_rep = CartesianRepresentation([1., 2, 3] * u.kpc) self.scalar_dif = CartesianDifferential([1, 2, 3.] * u.km / u.s) self.array_rep = CartesianRepresentation(np.ones((3, 1000)) * u.kpc) self.array_dif = CartesianDifferential(np.ones((3, 1000)) * u.km / u.s)
def propagation_engine(line1, line2, time_list): """Tests the interpolation accuracy for a given TLE.""" # Init satellite object from the TLE sat = Satrec.twoline2rv(line1, line2) # ****** Generate the pos, vel vectors for each time instant ****** # Run the propagation and init pos and vel vectors in TEME e, r_list, v_list = sat.sgp4_array(time_list.jd1, time_list.jd2) # Load the time, pos, vel info into astropy objects (shallow copied) vel_list = CartesianDifferential(v_list, unit=u.km / u.s, xyz_axis=1) pos_list = CartesianRepresentation( r_list, unit=u.km, xyz_axis=1 ).with_differentials(vel_list) # trajectory in astropy traj_astropy = SkyCoord( pos_list, obstime=time_list, frame=TEME.name, representation_type="cartesian", differential_type="cartesian", ) # Init trajectory in Trajectory object trajectory = Trajectory(traj_astropy) return {"traj": trajectory, "sat": sat}
def to_equatorial(fixed_coo, equatorial_frame): # TODO replace w/ something smart (Sun/Earth special cased) # assert fixed_coo.body == equatorial_frame.body r = fixed_coo.cartesian.xyz ra, dec, W = fixed_coo.rot_elements_at_epoch(fixed_coo.obstime) equatorial_frame._obstime = fixed_coo.obstime r = transform_vector(r, -W, "z") r_trans1 = transform_vector(r, -(90 * u.deg - dec), "x") r_f = transform_vector(r_trans1, -(90 * u.deg + ra), "z") if fixed_coo.data.differentials: v = fixed_coo.differentials["s"].d_xyz v = transform_vector(v, -W, "z") v_trans1 = transform_vector(v, -(90 * u.deg - dec), "x") v_f = transform_vector(v_trans1, -(90 * u.deg + ra), "z") data = CartesianRepresentation( r_f, differentials=CartesianDifferential(v_f)) else: data = CartesianRepresentation(r_f) return equatorial_frame.realize_frame(data)
def test_ephem_from_body_has_expected_properties(method, plane, FrameClass, rtol): epochs = Time( [ "2020-03-01 12:00:00", "2020-03-17 00:00:00.000", "2020-04-01 12:00:00.000" ], scale="tdb", ) equatorial_coordinates = CartesianRepresentation( [ (-1.40892271e08, 45067626.83900666, 19543510.68386639), (-1.4925067e08, 9130104.71634121, 3964948.59999307), (-1.46952333e08, -27413113.24215863, -11875983.21773582), ] * u.km, xyz_axis=1, differentials=CartesianDifferential( [ (-10.14262131, -25.96929533, -11.25810932), (-2.28639444, -27.3906416, -11.87218591), (5.67814544, -26.84316701, -11.63720607), ] * (u.km / u.s), xyz_axis=1, ), ) expected_coordinates = ( ICRS(equatorial_coordinates).transform_to(FrameClass).represent_as( CartesianRepresentation, CartesianDifferential)) earth = Ephem.from_body(Earth, epochs, plane=plane) coordinates = earth.sample(method=method) assert earth.epochs is epochs assert_coordinates_allclose(coordinates, expected_coordinates, rtol=rtol)
def test_ephem_from_horizons_calls_horizons_with_correct_parameters( horizons_mock, attractor, location_str, plane, refplane_str ): unused_name = "Strange Object" unused_id_type = "id_type" epochs = Time(["2020-03-01 12:00:00"], scale="tdb") horizons_mock().vectors.return_value = { "x": [1] * u.au, "y": [0] * u.au, "z": [0] * u.au, "vx": [0] * (u.au / u.day), "vy": [1] * (u.au / u.day), "vz": [0] * (u.au / u.day), } expected_coordinates = CartesianRepresentation( [(1, 0, 0)] * u.au, xyz_axis=1, differentials=CartesianDifferential([(0, 1, 0)] * (u.au / u.day), xyz_axis=1), ) ephem = Ephem.from_horizons( unused_name, epochs, attractor=attractor, plane=plane, id_type=unused_id_type ) horizons_mock.assert_called_with( id=unused_name, location=location_str, epochs=epochs.jd, id_type=unused_id_type ) horizons_mock().vectors.assert_called_once_with(refplane=refplane_str) coordinates = ephem.sample() assert_coordinates_allclose(coordinates, expected_coordinates)
def _reference_frame_from_tree(cls, node, ctx): from astropy.units import Quantity from astropy.io.misc.asdf.tags.unit.quantity import QuantityType from astropy.coordinates import ICRS, CartesianRepresentation version = cls.version reference_frame = node['reference_frame'] reference_frame_name = reference_frame['type'] frame_cls = cls._get_reference_frame_mapping()[reference_frame_name] frame_kwargs = {} for name in frame_cls.get_frame_attr_names().keys(): val = reference_frame.get(name) if val is not None: if name in ['obsgeoloc', 'obsgeovel']: x = QuantityType.from_tree(val[0], ctx) y = QuantityType.from_tree(val[1], ctx) z = QuantityType.from_tree(val[2], ctx) val = CartesianRepresentation(x, y, z) elif name == 'galcen_v_sun': from astropy.coordinates import CartesianDifferential d_x = QuantityType.from_tree(val[0], ctx) d_y = QuantityType.from_tree(val[1], ctx) d_z = QuantityType.from_tree(val[2], ctx) val = CartesianDifferential(d_x, d_y, d_z) else: val = yamlutil.tagged_tree_to_custom_tree(val, ctx) frame_kwargs[name] = val has_ra_and_dec = reference_frame.get('galcen_dec') and \ reference_frame.get('galcen_ra') return frame_cls(**frame_kwargs)
def propagate(orbit, time_of_flight, *, method=mean_motion, rtol=1e-10, **kwargs): """Propagate an orbit some time and return the result. """ time_of_flight = np.atleast_1d(time_of_flight) rr, vv = method( orbit.attractor.k, orbit.r, orbit.v, time_of_flight, rtol=rtol, **kwargs ) # TODO: Turn these into unit tests assert rr.ndim == 2 assert vv.ndim == 2 cartesian = CartesianRepresentation( rr, differentials=CartesianDifferential(vv, xyz_axis=1), xyz_axis=1 ) # If the frame supports obstime, set the time values kwargs = {} if "obstime" in orbit.frame.frame_attributes: kwargs["obstime"] = orbit.epoch + time_of_flight else: warn( "Frame {} does not support 'obstime', time values were not returned".format( orbit.frame.__class__ ) ) # Use of a protected method instead of frame.realize_frame # because the latter does not let the user choose the representation type # in one line despite its parameter names, see # https://github.com/astropy/astropy/issues/7784 return orbit.frame._replicate(cartesian, representation_type="cartesian", **kwargs)
def transform_to_galactic(icrs_coords): """ For the input astrometry plus radial velocity in the ICRS system calculate the barycentric Galactic coordinates as well as Galactocentric coordinates. Parameters ---------- icrs_coords: astropy.coordinates.ICRS ICRS instance constructed from the 5-parameter Gaia DR2 astrometry and the radial velocity. Returns ------- Galactic and Galactocentric objects containing the astrometry in Galactic coordinates, the galactocentric Cartesian coordinates, and the galactocentric cylindrical coordinates. """ galactic_coords = icrs_coords.transform_to(Galactic()) sun_motion = CartesianDifferential(_Usun, _vc + _Vsun, _Wsun) galactocentric_cartesian = icrs_coords.transform_to( Galactocentric(galcen_distance=_Rsun, z_sun=_zsun, galcen_v_sun=sun_motion)) galactocentric_cartesian.set_representation_cls(base='cartesian') galactocentric_cylindrical = icrs_coords.transform_to( Galactocentric(galcen_distance=_Rsun, z_sun=_zsun, galcen_v_sun=sun_motion)) galactocentric_cylindrical.set_representation_cls(base='cylindrical') return galactic_coords, galactocentric_cartesian, galactocentric_cylindrical
def icrs_to_cb_crs(icrs_coord, cb_crs_frame): """Conversion from ICRS to Celestial Reference System of a Central Body.""" if not u.m.is_equivalent(icrs_coord.cartesian.x.unit): raise u.UnitsError( _NEED_ORIGIN_HINT.format(icrs_coord.__class__.__name__)) if icrs_coord.data.differentials: # Calculate the barycentric position and velocity (of a solar system body). # Uses default ephemeris r_icrs, v_icrs = get_body_barycentric_posvel( cb_crs_frame.body_name, cb_crs_frame.obstime, ephemeris=cb_crs_frame.ephemeris_type, ) v_icrs = CartesianDifferential.from_cartesian(v_icrs) # Prepare final coord vector with velocity cb_crs_coord = (-r_icrs).with_differentials(-v_icrs) else: # Calculate the barycentric position ONLY (of a solar system body). # Uses default ephemeris. This is faster than the one above with velocities for # JPL ephemerides. cb_crs_coord = -get_body_barycentric( cb_crs_frame.body_name, cb_crs_frame.obstime, ephemeris=cb_crs_frame.ephemeris_type, ) # Return transformation matrix (None) and translation vector (with velocities) return None, cb_crs_coord
def to_equatorial(fixed_coo, equatorial_frame): assert fixed_coo.body == equatorial_frame.body r = fixed_coo.data.xyz v = fixed_coo.data.differentials["s"].d_xyz ra, dec, W = fixed_coo.rot_elements_at_epoch(fixed_coo.obstime) r = transform_vector(r, -W, "z") v = transform_vector(v, -W, "z") r_trans1 = transform_vector(r, -(90 * u.deg - dec), "x") r_trans2 = transform_vector(r_trans1, -(90 * u.deg + ra), "z") v_trans1 = transform_vector(v, -(90 * u.deg - dec), "x") v_trans2 = transform_vector(v_trans1, -(90 * u.deg + ra), "z") icrs_frame_pos_coord, icrs_frame_vel_coord = get_body_barycentric_posvel( fixed_coo.body.name, time=fixed_coo.obstime) r_f = icrs_frame_pos_coord.xyz + r_trans2 v_f = icrs_frame_vel_coord.xyz + v_trans2 data = CartesianRepresentation( r_f, differentials=CartesianDifferential(v_f)) return equatorial_frame.realize_frame(data)
def attach_zero_velocities(coord): """ Set the differentials to be stationary on a coordinate object. """ coord_diffs = CartesianDifferential(u.Quantity([0, 0, 0] * KMS)) new_data = coord.cartesian.with_differentials(coord_diffs) return coord.realize_frame(new_data)
def from_equatorial(equatorial_coo, fixed_frame): assert equatorial_coo.body == fixed_frame.body r = equatorial_coo.data.xyz v = equatorial_coo.data.differentials["s"].d_xyz ra, dec, W = fixed_frame.rot_elements_at_epoch(equatorial_coo.obstime) icrs_frame_pos_coord, icrs_frame_vel_coord = get_body_barycentric_posvel( equatorial_coo.body.name, time=equatorial_coo.obstime) r_trans1 = r - icrs_frame_pos_coord.xyz r_trans2 = transform_vector(r_trans1, (90 * u.deg + ra), "z") r_f = transform_vector(r_trans2, (90 * u.deg - dec), "x") v_trans1 = v - icrs_frame_vel_coord.xyz v_trans2 = transform_vector(v_trans1, (90 * u.deg + ra), "z") v_f = transform_vector(v_trans2, (90 * u.deg - dec), "x") r_f = transform_vector(r_f, W, "z") v_f = transform_vector(v_f, W, "z") data = CartesianRepresentation( r_f, differentials=CartesianDifferential(v_f)) return fixed_frame.realize_frame(data)
def test_orbit_creation_using_frame_obj(attractor, frame, obstime): vel = [0, 2, 0] * u.km / u.s cartdiff = CartesianDifferential(*vel) pos = [30000, 0, 0] * u.km cartrep = CartesianRepresentation(*pos, differentials=cartdiff) coord = frame(cartrep, obstime=obstime) o = Orbit.from_coords(attractor, coord) inertial_frame_at_body_centre = get_frame(attractor, Planes.EARTH_EQUATOR, obstime=coord.obstime) coord_transformed_to_irf = coord.transform_to( inertial_frame_at_body_centre) pos_transformed_to_irf = coord_transformed_to_irf.cartesian.xyz vel_transformed_to_irf = coord_transformed_to_irf.cartesian.differentials[ "s"].d_xyz assert_quantity_allclose(o.r, pos_transformed_to_irf, atol=1e-5 * u.km) assert_quantity_allclose(o.v, vel_transformed_to_irf, atol=1e-5 * u.km / u.s)
def tirs_to_teme(tirs_coord, teme_frame): # TIRS to TEME basic rotation matrix teme_to_pef_mat = rotation_matrix(_gmst82_angle(tirs_coord.obstime), axis="z") pef_to_teme_mat = teme_to_pef_mat.transpose() # rotate position vector: TIRS to TEME r_teme = tirs_coord.cartesian.transform(pef_to_teme_mat) # Check for velocity - skip velocity transform if not present if tirs_coord.data.differentials: # prepare rotation offset: w x r_TIRS wxr = CartesianRepresentation(_w).cross(tirs_coord.cartesian) # add rotation offset and then do the velocity rotation v_teme = (tirs_coord.velocity.to_cartesian() + wxr).transform(pef_to_teme_mat) v_teme = CartesianDifferential.from_cartesian(v_teme) # Prepare final coord vector with velocity teme_coord = r_teme.with_differentials(v_teme) else: # Prepare final coord vector without velocity teme_coord = r_teme # Add coord data to the existing frame return teme_frame.realize_frame(teme_coord)
def propagate(orbit, time_of_flight, *, method=farnocchia, rtol=1e-10, **kwargs): """Propagate an orbit some time and return the result. Parameters ---------- orbit : ~poliastro.twobody.Orbit Orbit object to propagate. time_of_flight : ~astropy.time.TimeDelta Time of propagation. method : callable, optional Propagation method, default to farnocchia. rtol : float, optional Relative tolerance, default to 1e-10. Returns ------- astropy.coordinates.CartesianRepresentation Propagation coordinates. """ # Check if propagator fulfills orbit requirements if orbit.ecc < 1.0 and method not in ELLIPTIC_PROPAGATORS: raise ValueError( "Can not use an parabolic/hyperbolic propagator for elliptical orbits." ) elif orbit.ecc == 1.0 and method not in PARABOLIC_PROPAGATORS: raise ValueError( "Can not use an elliptic/hyperbolic propagator for parabolic orbits." ) elif orbit.ecc > 1.0 and method not in HYPERBOLIC_PROPAGATORS: raise ValueError( "Can not use an elliptic/parabolic propagator for hyperbolic orbits." ) else: pass rr, vv = method(orbit.attractor.k, orbit.r, orbit.v, time_of_flight.reshape(-1).to(u.s), rtol=rtol, **kwargs) # TODO: Turn these into unit tests assert rr.ndim == 2 assert vv.ndim == 2 cartesian = CartesianRepresentation(rr, differentials=CartesianDifferential( vv, xyz_axis=1), xyz_axis=1) return cartesian
def _run_propagation(self, init_coords, time_list): """Solves the ODE or runs the actual propagation. Parameters ---------- init_coords : SkyCoord Initial coordinates (the first value is used) time_list : Time Time list for outputs Returns ------- SkyCoord The output coordinates corresponding to `time_list` """ # generate the time list since epoch (in seconds) t_list_epoch = (time_list - time_list[0]).to_value(u.s) # concat the init vector rv_init = [ *init_coords.cartesian.without_differentials().xyz.to_value(u.km), *init_coords.velocity.d_xyz.to_value(u.km / u.s), ] solver = solve_ivp( _ode_diff_eqns, (t_list_epoch[0], t_list_epoch[-1]), rv_init, method=self._solver_type.value, dense_output=True, rtol=self.rtol, atol=self.atol, ) r_list = np.empty((3, len(t_list_epoch))) v_list = np.empty((3, len(t_list_epoch))) # Fill the raw output data i = 0 for t in t_list_epoch: rv = solver.sol(t) r_list[:, i] = rv[:3] v_list[:, i] = rv[3:] i = i + 1 # Load the time, pos, vel info into astropy objects (shallow copied) rv_list = CartesianRepresentation( r_list, unit=u.km).with_differentials( CartesianDifferential(v_list, unit=u.km / u.s)) coords_list = SkyCoord( rv_list, obstime=time_list, frame=GCRS, representation_type="cartesian", differential_type="cartesian", copy=False, ) return coords_list
def test_teme_itrf(): """ Test case transform from TEME to ITRF. Test case derives from example on appendix C of Vallado, Crawford, Hujsak & Kelso (2006). See https://celestrak.com/publications/AIAA/2006-6753/AIAA-2006-6753-Rev2.pdf """ v_itrf = CartesianDifferential(-3.225636520, -2.872451450, 5.531924446, unit=u.km / u.s) p_itrf = CartesianRepresentation(-1033.479383, 7901.2952740, 6380.35659580, unit=u.km, differentials={'s': v_itrf}) t = Time("2004-04-06T07:51:28.386") teme = ITRS(p_itrf, obstime=t).transform_to(TEME(obstime=t)) v_teme = CartesianDifferential(-4.746131487, 0.785818041, 5.531931288, unit=u.km / u.s) p_teme = CartesianRepresentation(5094.18016210, 6127.64465050, 6380.34453270, unit=u.km, differentials={'s': v_teme}) assert_allclose(teme.cartesian.without_differentials().xyz, p_teme.without_differentials().xyz, atol=30 * u.cm) assert_allclose(teme.cartesian.differentials['s'].d_xyz, p_teme.differentials['s'].d_xyz, atol=1.0 * u.cm / u.s) # test round trip itrf = teme.transform_to(ITRS(obstime=t)) assert_allclose(itrf.cartesian.without_differentials().xyz, p_itrf.without_differentials().xyz, atol=100 * u.cm) assert_allclose(itrf.cartesian.differentials['s'].d_xyz, p_itrf.differentials['s'].d_xyz, atol=1 * u.cm / u.s)
def 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 number of steps (forced to rounded up int) no_of_steps = np.ceil((interval.duration / self.stepsize).decompose()) # make sure there are enough elements for interpolation if no_of_steps < Trajectory.reqd_min_elements(): no_of_steps = Trajectory.reqd_min_elements() # time list time_list = interval.start + self.stepsize * np.arange(0, no_of_steps) time_list.format = "isot" # ****** Generate the pos, vel vectors for each time instant ****** # Run the propagation and init pos and vel vectors in TEME e, r_list, v_list = 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
def _reference_frame_from_tree(cls, node, ctx): from astropy.units import Quantity from astropy.io.misc.asdf.tags.unit.quantity import QuantityType from astropy.coordinates import ICRS, CartesianRepresentation version = cls.version reference_frame = node['reference_frame'] reference_frame_name = reference_frame['type'] frame_cls = cls._get_reference_frame_mapping()[reference_frame_name] frame_kwargs = {} for name in frame_cls.get_frame_attr_names().keys(): val = reference_frame.get(name) if val is not None: # These are deprecated fields that must be handled as a special # case for older versions of the schema if name in ['galcen_ra', 'galcen_dec']: continue # There was no schema for quantities in v1.0.0 if name in ['galcen_distance', 'roll', 'z_sun' ] and version == '1.0.0': val = Quantity(val[0], unit=val[1]) # These fields are known to be CartesianRepresentations if name in ['obsgeoloc', 'obsgeovel']: if version == '1.0.0': unit = val[1] x = Quantity(val[0][0], unit=unit) y = Quantity(val[0][1], unit=unit) z = Quantity(val[0][2], unit=unit) else: x = QuantityType.from_tree(val[0], ctx) y = QuantityType.from_tree(val[1], ctx) z = QuantityType.from_tree(val[2], ctx) val = CartesianRepresentation(x, y, z) elif name == 'galcen_v_sun': from astropy.coordinates import CartesianDifferential # This field only exists since v1.1.0, and it only uses # CartesianDifferential after v1.3.3 d_x = QuantityType.from_tree(val[0], ctx) d_y = QuantityType.from_tree(val[1], ctx) d_z = QuantityType.from_tree(val[2], ctx) val = CartesianDifferential(d_x, d_y, d_z) else: val = yamlutil.tagged_tree_to_custom_tree(val, ctx) frame_kwargs[name] = val has_ra_and_dec = reference_frame.get('galcen_dec') and \ reference_frame.get('galcen_ra') if version == '1.0.0' and has_ra_and_dec: # Convert deprecated ra and dec fields into galcen_coord galcen_dec = reference_frame['galcen_dec'] galcen_ra = reference_frame['galcen_ra'] dec = Quantity(galcen_dec[0], unit=galcen_dec[1]) ra = Quantity(galcen_ra[0], unit=galcen_ra[1]) frame_kwargs['galcen_coord'] = ICRS(dec=dec, ra=ra) return frame_cls(**frame_kwargs)
def propagate(orbit, time_of_flight, *, method=mean_motion, rtol=1e-10, **kwargs): """Propagate an orbit some time and return the result. Parameters ---------- orbit : ~poliastro.twobody.Orbit Orbit object to propagate. time_of_flight : ~astropy.time.TimeDelta Time of propagation. method : callable, optional Propagation method, default to mean_motion. rtol : float, optional Relative tolerance, default to 1e-10. Returns ------- astropy.coordinates.CartesianRepresentation Propagation coordinates. """ # Check if propagator fulfills orbit requirements if orbit.ecc < 1.0 and method not in ELLIPTIC_PROPAGATORS: raise ValueError( "Can not use an parabolic/hyperbolic propagator for elliptical orbits." ) elif orbit.ecc == 1.0 and method not in PARABOLIC_PROPAGATORS: raise ValueError( "Can not use an elliptic/hyperbolic propagator for parabolic orbits." ) elif orbit.ecc > 1.0 and method not in HYPERBOLIC_PROPAGATORS: raise ValueError( "Can not use an elliptic/parabolic propagator for hyperbolic orbits." ) else: pass # Use the highest precision we can afford # np.atleast_1d does not work directly on TimeDelta objects jd1 = np.atleast_1d(time_of_flight.jd1) jd2 = np.atleast_1d(time_of_flight.jd2) time_of_flight = time.TimeDelta(jd1, jd2, format="jd", scale=time_of_flight.scale) rr, vv = method( orbit.attractor.k, orbit.r, orbit.v, time_of_flight.to(u.s), rtol=rtol, **kwargs ) # TODO: Turn these into unit tests assert rr.ndim == 2 assert vv.ndim == 2 cartesian = CartesianRepresentation( rr, differentials=CartesianDifferential(vv, xyz_axis=1), xyz_axis=1 ) return cartesian
def coordinates(): return CartesianRepresentation( [(1, 0, 0), (0.9, 0.1, 0), (0.8, 0.2, 0), (0.7, 0.3, 0)] * u.au, xyz_axis=1, differentials=CartesianDifferential( [(0, 1, 0), (-0.1, 0.9, 0), (-0.2, 0.8, 0), (-0.3, 0.7, 0)] * (u.au / u.day), xyz_axis=1, ), )
def test_from_coord_if_coord_is_not_of_shape_zero(): pos = [0, 1, 0] vel = [1, 0, 0] cartdiff = CartesianDifferential([vel] * u.km / u.s, xyz_axis=1) cartrep = CartesianRepresentation([pos] * u.km, differentials=cartdiff, xyz_axis=1) coords = GCRS(cartrep, representation_type=CartesianRepresentation, obstime=J2000) ss = Orbit.from_coords(Earth, coords) assert_quantity_allclose(ss.r, pos * u.km, rtol=1e-5) assert_quantity_allclose(ss.v, vel * u.km / u.s, rtol=1e-5)
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()
def get_coord_list(self, time_list, velocity=False, ephemeris="builtin"): """ Computes the set of positions (and velocities, if requested) of the Celestial Body in the `ICRS` frame. Any further frame transformations can then be carried out. Default ephemeris is `builtin`, though it cannot compute the velocity for the Moon. Ephemeris can also be `jpl`, where the default implementation in Astropy is used. Be warned that the first time this is called, a large file has to be downloaded. Parameters ---------- time_list : `~astropy.time.Time` List of times where position output is requested velocity : bool True if velocities are of the celestial body is also requested ephemeris : str, optional Ephemeris to use. By default, use the one set with ``astropy.coordinates.solar_system_ephemeris.set`` Returns ------- SkyCoord Set of cartesian positions (and velocities) in a `SkyCoord` object """ if velocity: r, v = get_body_barycentric_posvel(self.name, time_list, ephemeris=ephemeris) v_body = CartesianDifferential(v.xyz) r_body = r.with_differentials(v_body) coord_list = SkyCoord( r_body.with_differentials(v_body), obstime=time_list, frame="icrs", representation_type="cartesian", differential_type="cartesian", ) else: coord_list = SkyCoord( get_body_barycentric(self.name, time_list, ephemeris=ephemeris), obstime=time_list, frame="icrs", representation_type="cartesian", differential_type="cartesian", ) return coord_list
def test_regression_8924(): """This checks that the ValueError in BaseRepresentation._re_represent_differentials is raised properly """ # A case where the representation has a 's' differential, but we try to # re-represent only with an 's2' differential rep = CartesianRepresentation(1, 2, 3, unit=u.kpc) dif = CartesianDifferential(4, 5, 6, u.km/u.s) rep = rep.with_differentials(dif) with pytest.raises(ValueError): rep._re_represent_differentials(CylindricalRepresentation, {'s2': CylindricalDifferential})
def gen_trajectory(self, tle, interval, **kwargs): """ 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 kwargs No keywords defined 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
def test_from_coord_fails_for_multiple_positions(obstime): cartdiff = CartesianDifferential([[0, 1, 0], [-0.1, 0.9, 0]] * u.km / u.s, xyz_axis=1) cartrep = CartesianRepresentation([[1, 0, 0], [0.9, 0.1, 0]] * u.km, differentials=cartdiff, xyz_axis=1) coords = GCRS(cartrep, representation_type=CartesianRepresentation, obstime=obstime) with pytest.raises(ValueError) as excinfo: Orbit.from_coords(Earth, coords) assert ( "ValueError: Coordinate instance must represents exactly 1 position, found: 2" in excinfo.exconly())