def correct_pm0(ra, dec, pmra, pmdec, dist, vlsr=vlsr0, vz=0): """Corrects the proper motion for the speed of the Sun Arguments: ra - RA in deg dec -- Declination in deg pmra -- pm in RA in mas/yr pmdec -- pm in declination in mas/yr dist -- distance in kpc Returns: (pmra,pmdec) the tuple with the proper motions corrected for the Sun's motion """ C = acoo.ICRS(ra=ra * auni.deg, dec=dec * auni.deg, radial_velocity=0 * auni.km / auni.s, distance=dist * auni.kpc, pm_ra_cosdec=pmra * auni.mas / auni.year, pm_dec=pmdec * auni.mas / auni.year) kw = dict(galcen_v_sun=acoo.CartesianDifferential( np.array([11.1, vlsr + 12.24, vz + 7.25]) * auni.km / auni.s)) frame = acoo.Galactocentric(**kw) Cg = C.transform_to(frame) Cg1 = acoo.Galactocentric(x=Cg.x, y=Cg.y, z=Cg.z, v_x=Cg.v_x * 0, v_y=Cg.v_y * 0, v_z=Cg.v_z * 0, **kw) C1 = Cg1.transform_to(acoo.ICRS()) return ((C.pm_ra_cosdec - C1.pm_ra_cosdec).to_value(auni.mas / auni.year), (C.pm_dec - C1.pm_dec).to_value(auni.mas / auni.year))
def correct_vel(ra, dec, vel, vlsr=vlsr0): """Corrects the proper motion for the speed of the Sun Arguments: ra - RA in deg dec -- Declination in deg pmra -- pm in RA in mas/yr pmdec -- pm in declination in mas/yr dist -- distance in kpc Returns: (pmra,pmdec) the tuple with the proper motions corrected for the Sun's motion """ C = acoo.ICRS(ra=ra * auni.deg, dec=dec * auni.deg, radial_velocity=vel * auni.km / auni.s, distance=np.ones_like(vel) * auni.kpc, pm_ra_cosdec=np.zeros_like(vel) * auni.mas / auni.year, pm_dec=np.zeros_like(vel) * auni.mas / auni.year) #frame = acoo.Galactocentric (galcen_vsun = np.array([ 11.1, vlsr+12.24, 7.25])*auni.km/auni.s) kw = dict(galcen_v_sun=acoo.CartesianDifferential( np.array([11.1, vlsr + 12.24, 7.25]) * auni.km / auni.s)) frame = acoo.Galactocentric(**kw) Cg = C.transform_to(frame) Cg1 = acoo.Galactocentric(x=Cg.x, y=Cg.y, z=Cg.z, v_x=Cg.v_x * 0, v_y=Cg.v_y * 0, v_z=Cg.v_z * 0, **kw) C1 = Cg1.transform_to(acoo.ICRS) return np.asarray(((C.radial_velocity - C1.radial_velocity) / (auni.km / auni.s)).decompose())
def generate_formation_snapshot(t): """""" orbit = get_orbit() ind = orbit.t <= t orbit = orbit[ind] np.random.seed(49382) t_disrupt = -300 * u.Myr minit = 7e4 mfin = 1e3 nrelease = 1 prog_orbit = orbit if np.size(orbit.t) > 1: n_times = (prog_orbit.t < t_disrupt).sum() prog_mass = np.linspace(minit, mfin, n_times) prog_mass = np.concatenate( (prog_mass, np.zeros(len(prog_orbit.t) - n_times))) * u.Msun model = mockstream.dissolved_fardal_stream(ham, prog_orbit, prog_mass=prog_mass, t_disrupt=t_disrupt, release_every=nrelease) c = coord.Galactocentric(x=model.x, y=model.y, z=model.z) else: c = coord.Galactocentric(x=orbit.x, y=orbit.y, z=orbit.z) return (orbit, c)
def correct_pm0(ra, dec, pmra, pmdec, dist): """Corrects the proper motion for the speed of the Sun Arguments: ra - RA in deg dec -- Declination in deg pmra -- pm in RA in mas/yr pmdec -- pm in declination in mas/yr dist -- distance in kpc Returns: (pmra,pmdec) the tuple with the proper motions corrected for the Sun's motion """ C = acoo.ICRS(ra=ra * auni.deg, dec=dec * auni.deg, radial_velocity=0 * auni.km / auni.s, distance=dist * auni.kpc, pm_ra_cosdec=pmra * auni.mas / auni.year, pm_dec=pmdec * auni.mas / auni.year) frame = acoo.Galactocentric(**GCPARAMS) Cg = C.transform_to(frame) Cg1 = acoo.Galactocentric(x=Cg.x, y=Cg.y, z=Cg.z, v_x=Cg.v_x * 0, v_y=Cg.v_y * 0, v_z=Cg.v_z * 0, **GCPARAMS) C1 = Cg1.transform_to(acoo.ICRS()) return ((C.pm_ra_cosdec - C1.pm_ra_cosdec).to_value(auni.mas / auni.year), (C.pm_dec - C1.pm_dec).to_value(auni.mas / auni.year))
def correct_vel(ra, dec, vel, vlsr=None): """Corrects the proper motion for the speed of the Sun Arguments: ra - RA in deg dec -- Declination in deg pmra -- pm in RA in mas/yr pmdec -- pm in declination in mas/yr dist -- distance in kpc Returns: (pmra,pmdec) the tuple with the proper motions corrected for the Sun's motion """ if vlsr is not None: print('WARNING vlsr is ignored') C = acoo.ICRS(ra=ra * auni.deg, dec=dec * auni.deg, radial_velocity=vel * auni.km / auni.s, distance=np.ones_like(vel) * auni.kpc, pm_ra_cosdec=np.zeros_like(vel) * auni.mas / auni.year, pm_dec=np.zeros_like(vel) * auni.mas / auni.year) frame = acoo.Galactocentric(**GCPARAMS) Cg = C.transform_to(frame) Cg1 = acoo.Galactocentric(x=Cg.x, y=Cg.y, z=Cg.z, v_x=Cg.v_x * 0, v_y=Cg.v_y * 0, v_z=Cg.v_z * 0, **GCPARAMS) C1 = Cg1.transform_to(acoo.ICRS()) return np.asarray(((C.radial_velocity - C1.radial_velocity) / (auni.km / auni.s)).decompose())
def test___init__(self): """Test method ``__init__``.""" # -------------------------- # default self.obj( rvs=self.rvs, c_err=self.c_err, method="Gaussian", representation_type="cartesian", ) # -------------------------- # explicitly None obj = self.obj( rvs=self.rvs, c_err=self.c_err, method="Gaussian", frame=None, representation_type="cartesian", ) assert isinstance(obj.frame, UnFrame) assert obj.representation_type is coord.CartesianRepresentation assert "method" not in obj.params # -------------------------- # iter for frame, rep_type in ( # instance ( coord.Galactocentric(), coord.CartesianRepresentation((1, 2, 3)), ), # class (coord.Galactocentric, coord.CartesianRepresentation), # str ("galactocentric", "cartesian"), ): obj = self.obj( rvs=self.rvs, c_err=self.c_err, method="Gaussian", frame=frame, representation_type=rep_type, ) assert obj.frame == coord.Galactocentric(), frame assert (obj.representation_type == coord.CartesianRepresentation ), rep_type assert "method" not in obj.params
def test_frames(tmpdir): frames = [ cf.CelestialFrame(reference_frame=coord.ICRS()), cf.CelestialFrame(reference_frame=coord.FK5( equinox=time.Time('2010-01-01'))), cf.CelestialFrame(reference_frame=coord.FK4( equinox=time.Time('2010-01-01'), obstime=time.Time('2015-01-01'))), cf.CelestialFrame(reference_frame=coord.FK4NoETerms( equinox=time.Time('2010-01-01'), obstime=time.Time('2015-01-01'))), cf.CelestialFrame(reference_frame=coord.Galactic()), cf.CelestialFrame( reference_frame=coord.Galactocentric(galcen_distance=5.0 * u.m, galcen_ra=45 * u.deg, galcen_dec=1 * u.rad, z_sun=3 * u.pc, roll=3 * u.deg)), cf.CelestialFrame( reference_frame=coord.GCRS(obstime=time.Time('2010-01-01'), obsgeoloc=[1, 3, 2000] * u.pc, obsgeovel=[2, 1, 8] * (u.m / u.s))), cf.CelestialFrame(reference_frame=coord.CIRS( obstime=time.Time('2010-01-01'))), cf.CelestialFrame(reference_frame=coord.ITRS( obstime=time.Time('2022-01-03'))), cf.CelestialFrame(reference_frame=coord.PrecessedGeocentric( obstime=time.Time('2010-01-01'), obsgeoloc=[1, 3, 2000] * u.pc, obsgeovel=[2, 1, 8] * (u.m / u.s))) ] tree = {'frames': frames} helpers.assert_roundtrip_tree(tree, tmpdir)
def get_galactocentric2019(): """ References ---------- Galactic center sky position: - `Reid & Brunthaler (2004) <https://ui.adsabs.harvard.edu/abs/2004ApJ...616..872R/abstract>`_ Galactic center distance: - `GRAVITY collaboration (2018) <https://ui.adsabs.harvard.edu/abs/2018A%26A...615L..15G/abstract>`_ Solar velocity: - `Drimmel & Poggio (2018) <https://ui.adsabs.harvard.edu/abs/2018RNAAS...2d.210D/abstract>`_ - `Reid & Brunthaler (2004) <https://ui.adsabs.harvard.edu/abs/2004ApJ...616..872R/abstract>`_ - `GRAVITY collaboration (2018) <https://ui.adsabs.harvard.edu/abs/2018A%26A...615L..15G/abstract>`_ Solar height above midplane: - `Bennett & Bovy (2019) <https://ui.adsabs.harvard.edu/abs/2019MNRAS.482.1417B/abstract>`_ Returns ------- galcen_frame : `~astropy.coordinates.Galactocentric` The modern (2019) Galactocentric reference frame. """ with coord.galactocentric_frame_defaults.set('v4.0'): galcen = coord.Galactocentric() return galcen
def get_galactocentric2019(): """ References ---------- Galactic center sky position: - `Reid & Brunthaler (2004) <https://ui.adsabs.harvard.edu/abs/2004ApJ...616..872R/abstract>`_ Galactic center distance: - `GRAVITY collaboration (2018) <https://ui.adsabs.harvard.edu/abs/2018A%26A...615L..15G/abstract>`_ Solar velocity: - `Drimmel & Poggio (2018) <https://ui.adsabs.harvard.edu/abs/2018RNAAS...2d.210D/abstract>`_ - `Reid & Brunthaler (2004) <https://ui.adsabs.harvard.edu/abs/2004ApJ...616..872R/abstract>`_ - `GRAVITY collaboration (2018) <https://ui.adsabs.harvard.edu/abs/2018A%26A...615L..15G/abstract>`_ Solar height above midplane: - `Bennett & Bovy (2019) <https://ui.adsabs.harvard.edu/abs/2019MNRAS.482.1417B/abstract>`_ Returns ------- galcen_frame : `~astropy.coordinates.Galactocentric` The modern (2019) Galactocentric reference frame. """ rsun = 8.122 * u.kpc vsun = coord.CartesianDifferential([12.9, 245.6, 7.78] * u.km / u.s) zsun = 20.8 * u.pc return coord.Galactocentric(galcen_distance=rsun, galcen_v_sun=vsun, z_sun=zsun)
def get_gc_frame(): v_sun = coord.CartesianDifferential([11.1, 250, 7.25] * u.km / u.s) #gc_frame = coord.Galactocentric(galcen_distance=8.3*u.kpc, # z_sun=0*u.pc, # galcen_v_sun=v_sun) gc_frame = coord.Galactocentric() return gc_frame
def test_convert_vel_to_pm(): # Set up Solar position and motion. sun_xyz = [-8.122, 0, 0] * u.kpc sun_vxyz = [12.9, 245.6, 7.78] * u.km / u.s galcen_frame = coord.Galactocentric(galcen_distance=np.abs(sun_xyz[0]), galcen_v_sun=sun_vxyz, z_sun=0 * u.pc) # Rotation matrix from Galactocentric to ICRS R_gal, _ = get_matrix_vectors(galcen_frame, inverse=True) c = coord.SkyCoord(ra=61.342 * u.deg, dec=17 * u.deg, distance=3 * u.kpc, pm_ra_cosdec=4.2 * u.mas / u.yr, pm_dec=-7.2 * u.mas / u.yr, radial_velocity=17 * u.km / u.s) test_galcen = c.transform_to(galcen_frame) test_pm, test_rv = av.get_icrs_from_galactocentric( test_galcen.data.xyz, test_galcen.velocity.d_xyz, R_gal, sun_xyz, sun_vxyz) assert u.allclose(test_pm[0], c.pm_ra_cosdec) assert u.allclose(test_pm[1], c.pm_dec) assert u.allclose(test_rv, c.radial_velocity)
def ref_frame(): vLSR= [0., 240.,0] * (u.km / u.s) # from Reid et al 2014 v_sun = [11.1, 12.24, 7.25] * (u.km / u.s) # [vx, vy, vz] from Schonrich (2012) gc_frame = coord.Galactocentric(galcen_distance = 8340*u.pc,galcen_v_sun=vLSR+v_sun,z_sun=27*u.pc) # z-sun from Chen et al. 2001, galcen_distance from Reid et al 2014 return gc_frame
def rv_to_gsr(c, v_sun=None): """Transform a barycentric radial velocity to the Galactic Standard of Rest (GSR). The input radial velocity must be passed in as a Parameters ---------- c : `~astropy.coordinates.BaseCoordinateFrame` subclass instance The radial velocity, associated with a sky coordinates, to be transformed. v_sun : `~astropy.units.Quantity`, optional The 3D velocity of the solar system barycenter in the GSR frame. Defaults to the same solar motion as in the `~astropy.coordinates.Galactocentric` frame. Returns ------- v_gsr : `~astropy.units.Quantity` The input radial velocity transformed to a GSR frame. """ if v_sun is None: v_sun = coord.Galactocentric().galcen_v_sun.to_cartesian() gal = c.transform_to(coord.Galactic) cart_data = gal.data.to_cartesian() unit_vector = cart_data / cart_data.norm() v_proj = v_sun.dot(unit_vector) return c.radial_velocity + v_proj
def cartesianize_coordinates(self, array): """ convert arrays of cylindrical ( spherical if a Spherical distribution is chosen ) coordinates to cartesian ones. It exploits :mod:`astropy` routines. """ return coord.Galactocentric(array)
def perturber_orbit(): """""" pkl = pickle.load(open('../data/fiducial_at_encounter.pkl', 'rb')) xsub = pkl['xsub'] vsub = pkl['vsub'] c = coord.Galactocentric(x=xsub[0], y=xsub[1], z=xsub[2], v_x=vsub[0], v_y=vsub[1], v_z=vsub[2]) w0 = gd.PhaseSpacePosition(c.transform_to(gc_frame).cartesian) dt_orbit = 0.5 * u.Myr orbit_rr = ham.integrate_orbit(w0, dt=-dt_orbit, t2=-0.5 * 495 * u.Myr, t1=0 * u.Myr) winit = orbit_rr.w()[:, -1] orbit = ham.integrate_orbit(winit, dt=dt_orbit, t1=0 * u.Myr, t2=1.5 * 495 * u.Myr) return orbit
def load_nominal_apogee(filename, zlim=2*u.kpc, vlim=75*u.km/u.s, teff_lim=[4000., 6500]*u.K, logg_lim=[-0.5, 3.5], parallax_snr_lim=10): """TODO: duplicated code!""" # read data and cut g = GaiaData(filename) g = g[np.isfinite(g.parallax_error) & (g.parallax > 0.*u.mas)] if parallax_snr_lim is not None: plx_snr = g.parallax / g.parallax_error g = g[plx_snr > parallax_snr_lim] g = g[(g.TEFF > teff_lim[0].value) & (g.TEFF < teff_lim[1].value)] g = g[(g.LOGG > logg_lim[0]) & (g.LOGG < logg_lim[1])] # make coordinates c = g.get_skycoord(radial_velocity=g.VHELIO_AVG * u.km/u.s) galcen = c.transform_to(coord.Galactocentric(z_sun=0*u.pc)) zs = galcen.z.to(u.pc) vs = galcen.v_z.to(u.km/u.s) # trim on coordinates inbox = (zs / zlim) ** 2 + (vs / vlim) ** 2 < 1. g = g[inbox] galcen = galcen[inbox] return g, galcen
def test_reflex(): c = coord.SkyCoord(ra=162 * u.deg, dec=-17 * u.deg, distance=172 * u.pc, pm_ra_cosdec=-11 * u.mas / u.yr, pm_dec=4 * u.mas / u.yr, radial_velocity=110 * u.km / u.s) c2 = reflex_correct(c) c3 = reflex_correct(c, coord.Galactocentric(z_sun=0 * u.pc))
def plain_model(): """Unperturbed model of GD-1""" np.random.seed(143531) t_impact, M, rs, bnorm, bx, vnorm, vx = impact_params() dt_orbit = 0.5 * u.Myr nstep_impact = np.int64(t_impact / dt_orbit) prog_orbit = get_orbit() wangle = 180 * u.deg t_disrupt = -300 * u.Myr minit = 7e4 mfin = 1e3 nrelease = 1 n_times = (prog_orbit.t < t_disrupt).sum() prog_mass = np.linspace(minit, mfin, n_times) prog_mass = np.concatenate( (prog_mass, np.zeros(len(prog_orbit.t) - n_times))) * u.Msun # stream model at the present model = mockstream.dissolved_fardal_stream( ham, prog_orbit, prog_mass=prog_mass, t_disrupt=t_disrupt, release_every=nrelease, snapshot_filename='../data/model_unperturbed.h5') # angular coordinates r = np.sqrt(model.x**2 + model.y**2 + model.z**2) theta = np.arccos(model.z / r) phi = coord.Angle(np.arctan2(model.y, model.x)).wrap_at(0 * u.deg) # sky coordinates c = coord.Galactocentric(x=model.x, y=model.y, z=model.z) ceq = c.transform_to(coord.ICRS) cgd = c.transform_to(gc.GD1) plt.close() fig, ax = plt.subplots(3, 1, figsize=(8, 8)) plt.sca(ax[0]) plt.plot(model.y, model.z, 'k.', ms=1) plt.plot(model.y[::2], model.z[::2], 'r.', ms=1) plt.sca(ax[1]) #plt.plot(phi, theta, 'k.', ms=1) plt.plot(ceq.ra, ceq.dec, 'k.', ms=1) plt.plot(ceq.ra[::2], ceq.dec[::2], 'r.', ms=1) plt.sca(ax[2]) plt.plot(cgd.phi1.wrap_at(180 * u.deg), cgd.phi2, 'k.', ms=1) plt.plot(cgd.phi1[::2].wrap_at(180 * u.deg), cgd.phi2[::2], 'r.', ms=1) plt.tight_layout()
def test_density(self): """Test method ``density``.""" # --------------- # when there isn't a frame with pytest.raises(TypeError, match="must have a frame."): self.subclass.density(self.potential, self.points) # --------------- # basic points, values = self.subclass.density( self.potential, self.points.data, ) # the points are unchanged assert points is self.points.data # check data types assert isinstance(points, coord.BaseRepresentation) # and on the values assert u.allclose(values, [0.0, 0.0, 0.0] * u.solMass / u.pc ** 3) # --------------- # frame # test the different inputs for frame in ( coord.Galactocentric, coord.Galactocentric(), "galactocentric", ): points, values = self.subclass.density( self.potential, self.points, frame=frame, ) assert isinstance(points, coord.SkyCoord) assert isinstance(points.frame, resolve_framelike(frame).__class__) assert u.allclose(values, [0.0, 0.0, 0.0] * u.solMass / u.pc ** 3) # TODO! test the specific values # --------------- # representation_type points, values = self.subclass.density( self.potential, self.points, frame=self.points.frame.replicate_without_data(), representation_type=coord.CartesianRepresentation, ) assert isinstance(points, coord.SkyCoord) assert isinstance(points.frame, self.frame) assert isinstance(points.data, coord.CartesianRepresentation) assert u.allclose(values, [0.0, 0.0, 0.0] * u.solMass / u.pc ** 3)
def generate_start_time(t_impact=0.495 * u.Gyr, graph=False): """Generate fiducial model at t_impact after the impact""" # impact parameters M = 0 * 5e6 * u.Msun rs = 10 * u.pc # impact parameters Tenc = 0.01 * u.Gyr dt = 0.05 * u.Myr # potential parameters potential = 3 Vh = 225 * u.km / u.s q = 1 * u.Unit(1) rhalo = 0 * u.pc par_pot = np.array([Vh.si.value, q.value, rhalo.si.value]) pkl = pickle.load(open('../data/fiducial_at_start.pkl', 'rb')) model = pkl['model'] xsub = pkl['xsub'] vsub = pkl['vsub'] # generate perturbed stream model potential_perturb = 2 par_perturb = np.array([0 * M.si.value, rs.si.value, 0, 0, 0]) x1, x2, x3, v1, v2, v3 = interact.general_interact( par_perturb, xsub.si.value, vsub.si.value, Tenc.si.value, t_impact.si.value, dt.si.value, par_pot, potential, potential_perturb, model.x.si.value, model.y.si.value, model.z.si.value, model.v_x.si.value, model.v_y.si.value, model.v_z.si.value) stream = {} stream['x'] = (np.array([x1, x2, x3]) * u.m).to(u.pc) stream['v'] = (np.array([v1, v2, v3]) * u.m / u.s).to(u.km / u.s) c = coord.Galactocentric(x=stream['x'][0], y=stream['x'][1], z=stream['x'][2], v_x=stream['v'][0], v_y=stream['v'][1], v_z=stream['v'][2], **gc_frame_dict) cg = c.transform_to(gc.GD1) wangle = 180 * u.deg if graph: plt.close() plt.figure(figsize=(10, 5)) plt.plot(cg.phi1.wrap_at(180 * u.deg), cg.phi2, 'k.', ms=1) plt.xlim(-80, 0) plt.ylim(-10, 10) plt.tight_layout() return cg
def setup(self): with tempfile.NamedTemporaryFile(mode='w+b') as temp: temp.write(_txt.encode('utf-8')) temp.flush() temp.seek(0) self.data = np.genfromtxt(temp, names=True, skip_header=1) # This should make the transformations more compatible g = coord.Galactic(l=0 * u.deg, b=0 * u.deg).transform_to(coord.ICRS) self.galcen_frame = coord.Galactocentric(galcen_coord=g, z_sun=0 * u.kpc)
def test___call__(self): """Test method ``__call__``.""" # --------------- # basic points, values = self.inst(self.points.data) # check data types assert isinstance(points, self.inst.frame.__class__) # and on the values assert isinstance(values, u.Quantity) assert values.unit == u.km**2 / u.s**2 # TODO! test the specific values # --------------- # with a frame points, values = self.inst(self.points) # check data types assert isinstance(points, coord.SkyCoord) assert isinstance(points.frame, self.inst.frame.__class__) # and on the values assert isinstance(values, u.Quantity) assert values.unit == u.km**2 / u.s**2 # TODO! test the specific values # --------------- # can't pass frame # test the different inputs with pytest.raises(TypeError, match="multiple values for keyword"): points, values = self.inst( self.points, frame=coord.Galactocentric(), ) # --------------- # representation_type points, values = self.inst( self.points, representation_type=coord.CartesianRepresentation, ) assert points is not self.points assert isinstance(points, coord.SkyCoord) assert isinstance(points.frame, self.inst.frame.__class__) assert isinstance(points.data, coord.CartesianRepresentation) assert isinstance(values, u.Quantity) assert values.unit == u.km**2 / u.s**2
def reflex_correct(coords): """ https://gala-astro.readthedocs.io/en/latest/_modules/gala/coordinates/reflex.html#reflex_correct """ galactocentric_frame = coord.Galactocentric() c = coord.SkyCoord(coords) v_sun = galactocentric_frame.galcen_v_sun observed = c.transform_to(galactocentric_frame) rep = observed.cartesian.without_differentials() rep = rep.with_differentials(observed.cartesian.differentials['s'] + v_sun) fr = galactocentric_frame.realize_frame(rep).transform_to(c.frame) return coord.SkyCoord(fr)
def pmlb_solar_correction(l, b, dist, pml, pmb, vsun=(11.1, 12.2, 7.25), vlsr=235, vrad=0): vsun=np.array(vsun) vsun[1]=vsun[1]+vlsr c = coord.SkyCoord(l=l*u.deg, b=b*u.deg, distance=dist*u.kpc, pm_l_cosb=pml*u.mas/u.yr, pm_b=pmb*u.mas/u.yr, radial_velocity=0*u.km/u.s, frame='galactic') vsun = coord.CartesianDifferential(vsun*u.km/u.s) gc_frame = coord.Galactocentric(galcen_v_sun=vsun, z_sun=0*u.kpc) ccorr=gala.reflex_correct(c,gc_frame) return ccorr.pm_l_cosb.value, ccorr.pm_b.value
def test_reflex(): c = coord.SkyCoord(ra=162 * u.deg, dec=-17 * u.deg, distance=172 * u.pc, pm_ra_cosdec=-11 * u.mas / u.yr, pm_dec=4 * u.mas / u.yr, radial_velocity=110 * u.km / u.s) # First, test execution but don't validate reflex_correct(c) with coord.galactocentric_frame_defaults.set('v4.0'): reflex_correct(c, coord.Galactocentric(z_sun=0 * u.pc)) # Reflext correct the observed, Reid & Brunthaler (2004) Sgr A* measurements # and make sure the corrected velocity is close to zero # https://ui.adsabs.harvard.edu/abs/2004ApJ...616..872R/abstract # also using # https://ui.adsabs.harvard.edu/abs/2018RNAAS...2d.210D/abstract # https://ui.adsabs.harvard.edu/abs/2018A%26A...615L..15G/abstract vsun = coord.CartesianDifferential([12.9, 245.6, 7.78] * u.km / u.s) with coord.galactocentric_frame_defaults.set('v4.0'): galcen_fr = coord.Galactocentric(galcen_distance=8.122 * u.kpc, galcen_v_sun=vsun, z_sun=20.8 * u.pc) sgr_Astar_obs = coord.SkyCoord(ra=galcen_fr.galcen_coord.ra, dec=galcen_fr.galcen_coord.dec, distance=galcen_fr.galcen_distance, pm_ra_cosdec=-3.151 * u.mas / u.yr, pm_dec=-5.547 * u.mas / u.yr, radial_velocity=-12.9 * u.km / u.s) new_c = reflex_correct(sgr_Astar_obs, galcen_fr) assert u.allclose(new_c.pm_ra_cosdec, 0 * u.mas / u.yr, atol=1e-2 * u.mas / u.yr) assert u.allclose(new_c.pm_dec, 0 * u.mas / u.yr, atol=1e-2 * u.mas / u.yr) assert u.allclose(new_c.radial_velocity, 0 * u.km / u.s, atol=1e-1 * u.km / u.s)
def plot_fullorbit(): """""" orbit = get_orbit() ind = orbit.t < -2.2 * u.Gyr orbit = orbit[ind] t_disrupt = -300 * u.Myr minit = 7e4 mfin = 1e3 nrelease = 1 prog_orbit = orbit n_times = (prog_orbit.t < t_disrupt).sum() prog_mass = np.linspace(minit, mfin, n_times) prog_mass = np.concatenate( (prog_mass, np.zeros(len(prog_orbit.t) - n_times))) * u.Msun model = mockstream.dissolved_fardal_stream(ham, prog_orbit, prog_mass=prog_mass, t_disrupt=t_disrupt, release_every=nrelease) # sky coordinates c = coord.Galactocentric(x=model.x, y=model.y, z=model.z) plt.close() fig = plt.figure(figsize=(16, 9)) fig.add_subplot(111, position=[0, 0, 1, 1]) #plt.plot(orbit.y[0], orbit.z[0], 'ro') pdisk = mpl.patches.Ellipse((0, 0), 30, 0.3, color='orange') patch = plt.gca().add_patch(pdisk) plt.plot(-8.3, 0, '*', color='darkorange', ms=30) plt.plot(orbit.x[-1], orbit.z[-1], 'ko', ms=10) plt.plot(orbit.x, orbit.z, 'k-', alpha=0.3) plt.plot(c.x, c.z, 'k.', ms=4, alpha=0.1) plt.text(0.05, 0.9, '{:4.0f} million years'.format( (orbit.t[-1] - orbit.t[0]).to(u.Myr).value), transform=plt.gca().transAxes, fontsize=20) dx = 30 dy = dx * 9 / 16 plt.xlim(-dx, dx) plt.ylim(-dy, dy) plt.gca().axis('off') plt.gca().tick_params(labelbottom=False, labelleft=False)
def to_coord_frame(self, frame, galactocentric_frame=None, **kwargs): """ Transform the orbit from Galactocentric, cartesian coordinates to Heliocentric coordinates in the specified Astropy coordinate frame. Parameters ---------- frame : :class:`~astropy.coordinates.BaseCoordinateFrame` The class or frame instance specifying the desired output frame. For example, :class:`~astropy.coordinates.ICRS`. galactocentric_frame : :class:`~astropy.coordinates.Galactocentric` This is the assumed frame that the position and velocity of this object are in. The ``Galactocentric`` instand should have parameters specifying the position and motion of the sun in the Galactocentric frame, but no data. Returns ------- c : :class:`~astropy.coordinates.BaseCoordinateFrame` An instantiated coordinate frame containing the positions and velocities from this object transformed to the specified coordinate frame. """ if self.ndim != 3: raise ValueError("Can only change representation for " "ndim=3 instances.") if galactocentric_frame is None: galactocentric_frame = coord.Galactocentric() if 'vcirc' in kwargs or 'vlsr' in kwargs: import warnings warnings.warn( "Instead of passing in 'vcirc' and 'vlsr', specify " "these parameters to the input Galactocentric frame " "using the `galcen_v_sun` argument.", DeprecationWarning) pos_keys = list(self.pos_components.keys()) vel_keys = list(self.vel_components.keys()) if (getattr(self, pos_keys[0]).unit == u.one or getattr(self, vel_keys[0]).unit == u.one): raise u.UnitConversionError("Position and velocity must have " "dimensioned units to convert to a " "coordinate frame.") # first we need to turn the position into a Galactocentric instance gc_c = galactocentric_frame.realize_frame( self.pos.with_differentials(self.vel)) c = gc_c.transform_to(frame) return c
def backintegrate( icrs = coord.SkyCoord(ra=coord.Angle('17h 20m 12.4s'), dec=coord.Angle('+57° 54′ 55″'), distance=76*u.kpc, pm_ra_cosdec=0.0569*u.mas/u.yr, pm_dec=-0.1673*u.mas/u.yr, radial_velocity=-291*u.km/u.s), dt=-0.1*u.Myr, n_steps=int(1e3), outpath=None ): """ Note: this is a thin wrapper to Gala's "integrate_orbit" method. Args: icrs (SkyCoord). Default is Draco. Note however that you can pass many ICRS coordinates to a coord.SkyCoord instance, via a construct like: ``` icrs_samples = coord.SkyCoord(ra=ra, dec=dec, distance=dist, pm_ra_cosdec=pm_ra_cosdec, pm_dec=pm_dec, radial_velocity=rv) ``` where ra, dec, etc are correctly unit-ed arrays. dt (Quantity): timestep. (Default: 1e5 yr) n_steps (int): how many steps. (Default: 1e3, so total 1e8 years back). outpath (str): if passed, makes a plot of the orbit here. Returns: gala orbit object. """ # Transform the measured values to a Galactocentric reference frame so we # can integrate an orbit in our Milky Way model. gc_frame = coord.Galactocentric() # Transform the mean observed kinematics to this frame. galcen = icrs.transform_to(gc_frame) # Turn the `Galactocentric` object into orbital initial conditions, and # integrate. Timestep: 0.5 Myr, and integrate back for 1e4 steps (5 Gyr). w0 = gd.PhaseSpacePosition(galcen.data) orbit = potential.integrate_orbit(w0, dt=dt, n_steps=n_steps) if isinstance(outpath, str): fig = orbit.plot() savefig(fig, outpath) return orbit
def main(): # function that opens galactic_potential = "PII" back_path = "../the_orbits/backward" forward_path = "../the_orbits/forward" stream_name = "fimbulthul" interval_fname = "../outputs/" + stream_name + ".json" out_directory = "../output_stream_to_cluster/" fp = open(interval_fname, "r+") interval = json.load(fp) # cheeck to see if there are any matches if "matches" in interval.keys(): # now see if there are any matches if (type(interval["matches"]) is dict): matched_clusters = list(interval['matches'].keys()) # now only get the clusters where we have the data files common_clusters, _nothing = my_gf.match_cluster_list_to_data_directory(\ matched_clusters,back_path,stream_or_backwardorbit="backwardorbits") # put our inteval object into the proper units interval['LONG'] *= u.degree interval['LAT'] *= u.degree interval['PMB'] *= u.mas / u.year interval['PML_COSB'] *= u.mas / u.year interval['D'] *= 1000 * u.pc for cluster in common_clusters: print(cluster) # do a plot for each cluster and save it t,x,y,z,vx,vy,vz = my_gf.concatenate_back_and_forward_orbit(\ cluster, back_path, forward_path) galacto_centric = coord.Galactocentric(x=x, y=y, z=z, v_x=vx, v_y=vy, v_z=vz) # transform to galactic coordinates galactic_coordinates = galacto_centric.transform_to( coord.Galactic) my_lon_coords = galactic_coordinates.l.wrap_at(180 * u.degree) constraint_criteran = extract_intersection(\ t, my_lon_coords, galactic_coordinates, interval) all_points_criteran = (interval["time"][0] < t) &\ (t < interval["time"][1]) fig = do_plot(stream_name, cluster, interval, all_points_criteran, constraint_criteran,\ my_lon_coords, galactic_coordinates, GDR2=True, dot_size=0.5) print("Saving {:s}-{:s}".format(stream_name, cluster)) save_figure(stream_name, cluster, out_directory, fig) else: print("No matches reported for {:s}".format(stream_name)) else: print("Run Matches on {:s}".format(stream_name))
def pmradec_solar_correction(ra, dec, dist, pmra, pmdec,vsun=(11.1, 12.2, 7.25),vlsr=235, vrad=0): vsun=np.array(vsun) vsun[1]=vsun[1]+vlsr c = coord.SkyCoord(ra=ra*u.deg, dec=dec*u.deg, distance=dist*u.kpc, pm_ra_cosdec=pmra*u.mas/u.yr, pm_dec=pmdec*u.mas/u.yr, radial_velocity=0*u.km/u.s) vsun = coord.CartesianDifferential(vsun*u.km/u.s) gc_frame = coord.Galactocentric(galcen_v_sun=vsun, z_sun=0*u.kpc) ccorr=gala.reflex_correct(c,gc_frame) return ccorr.pm_ra_cosdec.value, ccorr.pm_dec.value