Example #1
0
    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)
Example #3
0
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)
Example #4
0
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)
Example #5
0
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)
Example #6
0
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
Example #7
0
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"]
Example #8
0
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
Example #9
0
########################################
# 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)
Example #11
0
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)