def test_replace_units(self): H = gp.Hamiltonian(self.potential) H2 = gp.Hamiltonian(self.potential.replace_units(self.potential.units)) ww = [20., 10, 10, 0, 0.2, 0] w1 = H.integrate_orbit(ww, t=np.array([0, 1.]))[-1].w(galactic).T w2 = H2.integrate_orbit(ww, t=np.array([0, 1.]))[-1].w(galactic).T assert np.allclose(w1, w2)
def compute_orbit(icrs, dt=-0.1 * u.Myr, n_steps=50000): """Integrate the orbit.""" c_icrs = icrs.transform_to(gc_frame).cartesian object_phase_space = gd.PhaseSpacePosition( pos=c_icrs.xyz, vel=c_icrs.differentials['s'].d_xyz) return gp.Hamiltonian(pot).integrate_orbit(object_phase_space, dt=dt, n_steps=n_steps)
def get_hamiltonian(config_file=None): c = Config() c.load(config_file) pot = potential_no_bar.copy() pot['bar'] = get_bar_potential(config_file) Om = [0., 0., c.Omega] * u.km / u.s / u.kpc frame = gp.ConstantRotatingFrame(Omega=Om, units=galactic) return gp.Hamiltonian(potential=pot, frame=frame)
def make_perfect_stream(X_start=[-8.122, 0., 0.5], V_start=[-16., 0., -200.], dt=.00048, n_steps=10000, number_of_stars=1000, intrinsic_spread=None): pot = MilkyWayPotential() kpcMyr2kms = 977.951 / (u.kpc / u.Myr) w0 = gd.PhaseSpacePosition(pos=X_start * u.kpc, vel=V_start * u.km / u.s) orbit = gp.Hamiltonian(pot).integrate_orbit(w0, dt=dt, n_steps=n_steps) indices = np.random.randint(0, len(orbit.x), size=number_of_stars) orb_x = orbit.x[indices] / u.kpc orb_y = orbit.y[indices] / u.kpc orb_z = orbit.z[indices] / u.kpc orb_vx = orbit.v_x[indices] * kpcMyr2kms orb_vy = orbit.v_y[indices] * kpcMyr2kms orb_vz = orbit.v_z[indices] * kpcMyr2kms if intrinsic_spread != None: for i in range(len(orb_x)): z_pot_start = pot.value([orb_x[i], orb_y[i], orb_z[i] ])[0] * 978.5**2 / (u.kpc / u.Myr)**2 orb_z[i] += intrinsic_spread[0] * np.random.normal() z_pot_diff = pot.value([ orb_x[i], orb_y[i], orb_z[i] ])[0] * 978.5**2 / (u.kpc / u.Myr)**2 - z_pot_start orb_x[i] += intrinsic_spread[0] * np.random.normal() orb_y[i] += intrinsic_spread[0] * np.random.normal() orb_vx[i] += intrinsic_spread[1] * np.random.normal() orb_vy[i] += intrinsic_spread[1] * np.random.normal() # this last line adds dispersion to v_z, but in a way that counteracts # the change in vertical energy coming from the shift in height z orb_vz[i] = np.sign(orb_vz[i]) * np.sqrt( orb_vz[i]**2 - 2. * z_pot_diff) + intrinsic_spread[1] * np.random.normal() return np.transpose([orb_x, orb_y, orb_z, orb_vx, orb_vy, orb_vz]) # EXAMPLES: # this is stream S1 # xyzs = make_perfect_stream(X_start=[-8.122,0., 0.4], V_start=[-25., 0., -100.], dt=2.*2.*.00048, intrinsic_spread=[0.020, 1.], n_steps=4000) # np.savez('../GeneratedStreams/mock_stream_20-1000_slow', xyzs=xyzs) # this is stream S2 # xyzs = make_perfect_stream(X_start=[-8.122, -.6, -0.2], V_start=[0., 220., -50.], dt=2.*2.*.00048, intrinsic_spread=[0.020, 1.], n_steps=2700) # np.savez('../GeneratedStreams/mock_stream_20-1000_corotB', xyzs=xyzs) # this is stream S3 # xyzs = make_perfect_stream(X_start=[-8.122, -.3, 0.4], V_start=[-10., 200., -70.], dt=2.*.00048, intrinsic_spread=[0.020, 1.], n_steps=2500) # np.savez('../GeneratedStreams/mock_stream_20-1000_corotC', xyzs=xyzs) # this is stream S4 # xyzs = make_perfect_stream(X_start=[-7.835, -.3, 0.4], V_start=[-160., 160., -60.], dt=2.*.00048, intrinsic_spread=[0.020, 1.], n_steps=3800) # np.savez('../GeneratedStreams/mock_stream_20-1000_inclined', xyzs=xyzs)
def input_des(): """Compile stream input parameters for DES streams from Shipp+2018""" tin = Table.read('des_raw.txt', format='ascii.commented_header', delimiter=' ') tin.pprint() streams = tin['Name'] length = tin['Length'] * u.kpc r = tin['Rgal'] * u.kpc # get circular velocity ham = gp.Hamiltonian(gp.MilkyWayPotential()) xyz = np.array([r.value, np.zeros_like(r.value), np.zeros_like(r.value)]) * r.unit vcirc = ham.potential.circular_velocity(xyz) # get age M = vcirc**2 * r / G m = tin['Mprog'] * 1e4 * u.Msun age = ((tin['l'] * u.deg).to(u.radian).value / (2**(2 / 3) * (m / M)**(1 / 3) * np.sqrt(G * M / r**3))).to(u.Gyr) age = np.ones(np.size(length)) * 8 * u.Gyr # get subhalo density a = 0.678 r2 = 162.4 * u.kpc n = -1.9 m0 = 2.52e7 * u.Msun m1 = 1e6 * u.Msun m2 = 1e7 * u.Msun cdisk = 2.02e-13 * (u.kpc)**-3 * u.Msun**-1 nsub = cdisk * np.exp(-2 / a * ((r / r2)**a - 1)) * m0 / (n + 1) * ( (m2 / m0)**(n + 1) - (m1 / m0)**(n + 1)) # replace with actual LSST estimates tf = Table.read('min_depths_LSST.txt', format='ascii', delimiter=',') fcut = 1 - tf['col2'] t = Table([streams, length, age, r, vcirc, nsub, fcut], names=('name', 'length', 'age', 'rgal', 'vcirc', 'nsub', 'fcut')) t.write('DES_streams_LSST.fits', overwrite=True) tf = Table.read('min_depths_LSST10.txt', format='ascii', delimiter=',') fcut = 1 - tf['col2'] t = Table([streams, length, age, r, vcirc, nsub, fcut], names=('name', 'length', 'age', 'rgal', 'vcirc', 'nsub', 'fcut')) t.write('DES_streams_LSST10.fits', overwrite=True)
def integrate(w0,\ pot=gp.HernquistPotential(m=130.0075e10*u.Msun,c = 32.089, units=galactic),\ timestep = -10.67,\ ntimesteps = 250,\ verbose=False): # TODO orbit = None # define the orbit object in this scope if verbose: print('integrating ... ') start_time = time.time() orbit = gp.Hamiltonian(pot).integrate_orbit(w0, dt=timestep, n_steps=ntimesteps) orbit_time = time.time() - start_time print('done integrating') print('Length of integration: %1.3f' % orbit_time) else: orbit = gp.Hamiltonian(pot).integrate_orbit(w0, dt=timestep, n_steps=ntimesteps) return orbit, pot
def calculate_actions(w0, pot=gp.MilkyWayPotential(), dt=0.5, n_steps=10000, full_output=False): """ Approximate actions following https://github.com/adrn/gala/blob/master/docs/dynamics/actionangle.rst """ assert len(w0.shape) == 0 w = gp.Hamiltonian(pot).integrate_orbit(w0, dt=dt, n_steps=n_steps) toy_potential = gd.fit_isochrone(w) toy_actions, toy_angles, toy_freqs = toy_potential.action_angle(w) with warnings.catch_warnings(record=True): warnings.simplefilter("ignore") result = gd.find_actions(w, N_max=8, toy_potential=toy_potential) if full_output: return result, w return result["actions"]
def morphology(omega, m_b, release_every=1, n_particles=1, dt=-1, n_steps=6000): """ Takes the pattern speed (with units, in km/s/kpc), and release_every, which controls how often to release particles, and the bar mass m_b. Creates mock streams, returns RA, dec to be used for track calculation """ S = np.load('../data/Sn9l19m.npy') #expansion coeff. S = S[:2, :6, :6] w0 = gd.PhaseSpacePosition(pal5_c.transform_to(galcen_frame).cartesian) pot = gp.CCompositePotential() pot['disk'] = default_mw['disk'] pot['halo'] = default_mw['halo'] pot['bar'] = get_bar_model(Omega=omega, Snlm=S, m=m_b) frame = gp.ConstantRotatingFrame(Omega=[0, 0, -1] * omega, units=galactic) H = gp.Hamiltonian( pot, frame) #frame such that we're "moving" with respect to bar df = gd.FardalStreamDF(random_state=np.random.RandomState(42)) prog_pot = gp.PlummerPotential(pal5_M, 4 * u.pc, units=galactic) gen = gd.MockStreamGenerator(df=df, hamiltonian=H, progenitor_potential=prog_pot) # gen = gd.MockStreamGenerator(df=df, hamiltonian=H) stream_data, _ = gen.run(w0, pal5_M, dt=dt, n_steps=n_steps, release_every=release_every, n_particles=n_particles) cache_file = 'BarModels_RL{:d}_Mb{:.0e}_Om{:.1f}.hdf5'.format( release_every, m_b.value, omega.value) if path.exists(cache_file): os.unlink(cache_file) stream_data.to_hdf5(cache_file) sim_c = stream_data.to_coord_frame(coord.ICRS, galactocentric_frame=galcen_frame) return sim_c
######################################## # Set up progenitor initial conditions - syntax is a bit weird but I didn't come up with it! x, y, z, vx, vy, vz = [x_0, y_0, z_0, vx_0, vy_0, vz_0] # in kpc and km/s c_gc = coord.Galactocentric(x=x * u.kpc, y=y * u.kpc, z=z * u.kpc, v_x=vx * u.km / u.s, v_y=vy * u.km / u.s, v_z=vz * u.km / u.s) psp = gd.PhaseSpacePosition(pos=c_gc.data.xyz, vel=[vx, vy, vz] * u.km / u.s) orbit = gp.Hamiltonian(pot).integrate_orbit(psp, dt=-0.5 * u.Myr, n_steps=n_steps) #orbit.plot() ######################################## # Compute spray model, note that stream.plot() conveniently shows the results # Description of the method in https://ui.adsabs.harvard.edu/abs/2015MNRAS.452..301F/abstract or gala docs stream = fardal_stream(pot, orbit[::-1], prog_mass=M_progenitor * u.Msun, release_every=1) # Binning stream to a histogram that matches mock galaxy image s_binned = np.histogram2d(stream.z, stream.x,
vel=[new_vx_2, new_vy_2, new_vz_2] * (u.km / u.s)) all_x = [] all_y = [] all_z = [] # ** DYNAMICS ** steps_per_iter = 1 # time steps per orbit iteration timestep = 1.0 # time step in Myr end = 3000 # number of times to iterate orbits for i in range(end): # integrate orbit for galaxy 1 in potential 1 orbits1 = gp.Hamiltonian(pot1).integrate_orbit(new_ics1, dt=timestep, n_steps=steps_per_iter) new_ics1 = gd.PhaseSpacePosition(orbits1[-1].pos, orbits1[-1].vel) # integrate orbit for galaxy 2 in potential 1 orbits2 = gp.Hamiltonian(pot1).integrate_orbit(new_ics2, dt=timestep, n_steps=steps_per_iter) new_ics2 = gd.PhaseSpacePosition(orbits2[-1].pos, orbits2[-1].vel) # compute relative motion of galaxy 2 wrt galaxy 1 # positions x_coords2 = (orbits2[-1].pos.xyz.value[0]) * u.kpc x_mean2 = np.mean(x_coords2) y_coords2 = (orbits2[-1].pos.xyz.value[1]) * u.kpc y_mean2 = np.mean(y_coords2)
agama.setUnits(mass=1, length=1, velocity=1) # import the MW potential from gala bulge = agama.Potential(type='Dehnen', gamma=1, mass=5E9, scaleRadius=1.0) nucleus = agama.Potential(type='Dehnen', gamma=1, mass=1.71E09, scaleRadius=0.07) disk = agama.Potential(type='MiyamotoNagai', mass=6.80e+10, scaleRadius=3.0, scaleHeight=0.28) halo = agama.Potential(type='NFW', mass=5.4E11, scaleRadius=15.62) mwpot = agama.Potential(bulge, nucleus, disk, halo) af = agama.ActionFinder(mwpot, interp=False) pos_vel = np.array([8., 0., 0., 75., 150., 50.]) agama_act = af(pos_vel) # now do it for gala pot = gp.MilkyWayPotential() w0 = gd.PhaseSpacePosition(pos=[8, 0, 0.] * u.kpc, vel=[75, 150, 50.] * u.km / u.s) w = gp.Hamiltonian(pot).integrate_orbit(w0, dt=0.5, n_steps=10000) gala_act = gd.find_actions(w, N_max=8)