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)
示例#2
0
def evolve_cluster_in_galaxy(options_file):
    opt = options_reader(options_file)

    timestep = opt.options['timestep']  # in Myr
    tend = opt.options['tend']  # in Myr
    times = np.arange(0.0, tend, timestep) | units.Myr

    cluster = oc_code(opt)
    cluster_code = cluster.code
    galaxy_code = gizmo_interface(opt)

    snap_reader = snapshot_reader(opt, galaxy_code)

    stars = cluster_code.particles.copy()

    if opt.options['axisymmetric']:
        import astropy.units as u
        import gala.dynamics as gd
        import gala.potential as gp

        pos = [opt.options['axi_Rinit'], 0, 0] * u.kpc
        vel = [0, 0, 0] * u.km / u.s
        mw = gp.MilkyWayPotential()
        phase = gd.PhaseSpacePosition(pos, vel)
        vc = mw.circular_velocity(phase).to_value(u.km / u.s) | units.kms

        stars = cluster_code.particles.copy()
        stars.x += opt.options['axi_Rinit'] | units.kpc
        stars.vy += vc
        stars.z += opt.options['axi_zinit'] | units.kpc

    channel = stars.new_channel_to(cluster_code.particles)
    channel.copy_attributes(["x", "y", "z", "vx", "vy", "vz"])

    system = Bridge(timestep=timestep, use_threading=False)
    system.add_system(cluster_code, (galaxy_code, ))
    system.add_system(galaxy_code)

    converter = cluster_code.unit_converter

    for i, t in enumerate(tqdm(times)):
        system.evolve_model(t, timestep=timestep | units.Myr)
        if not opt.options['axisymmetric']:
            cluster.clean_ejections(system)

        bound = system.particles.bound_subset(unit_converter=converter)
        bound_com = bound.center_of_mass().value_in(units.kpc)

        if not opt.options['axisymmetric']:
            galaxy_code.evolve_grid(bound_com)

        snap_reader.process_snapshot(system, galaxy_code, bound_com, i, t)

    snap_reader.finish_sim()

    cluster_code.stop()
示例#3
0
文件: test_mpi.py 项目: adrn/BarChaos
def cache_file():
    fn = path.join('/tmp/cache.hdf5')

    w0 = gd.PhaseSpacePosition(pos=np.random.random((3, 16)) * u.kpc,
                               vel=np.random.random((3, 16)) * u.m / u.s)
    with h5py.File(fn, 'w') as f:
        g = f.create_group('w0')
        w0.to_hdf5(g)

    return fn
示例#4
0
def cache_file(tmpdir_factory):
    fn = tmpdir_factory.mktemp('cache').join('cache.hdf5')

    w0 = gd.PhaseSpacePosition(pos=np.random.random((3, 16)) * u.kpc,
                               vel=np.random.random((3, 16)) * u.m / u.s)
    with h5py.File(fn, 'w') as f:
        g = f.create_group('w0')
        w0.to_hdf5(g)

    return str(fn)
示例#5
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)
示例#6
0
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
示例#7
0
def vary_potential():

    # the normal parameters for the potential and the Sgr dSph
    sag_mass = 1e8
    
    normal_mw_mass = 130.0075e10*u.Msun
    normal_mw_conc = 9.39
    normal_mw_rs = 18.927757889861788 * u.kpc

    # reads the coordinates from the file to w0
    w0 = int_sgr.read_file('centroid_part_1000', columns=[3, 4, 5, 6, 7, 8], skip_lines=[0])

    gvs = []

    m_ratios = [0.8, 0.9, 1.0, 1.1, 1.2]
    c_ratios =  [0.8, 0.9, 1.0, 1.1, 1.2]
    rs_ratios =  [0.8, 0.9, 1.0, 1.1, 1.2]

    # makes a potential using 80%, 90%, 100%, 110% and 120% of each of the normal potential parameters
    for m_ratio in m_ratios:
        for c_ratio in c_ratios:
            for rs_ratio in rs_ratios:
                # gets the current potential parameters
                curr_mass = normal_mw_mass * m_ratio
                curr_c = normal_mw_conc * c_ratio
                curr_rs = normal_mw_rs * rs_ratio
                print('Theta:',\
                      'mass =', curr_mass,\
                      'c =', curr_c,\
                      'rs =', curr_rs,\
                      )

                # creates the current potential object and uses it to integrate the particle orbits
                curr_pot = int_sgr.get_potential(total_mass=curr_mass, r_scale=curr_rs, mw_conc=curr_c)
                orbit, pot = int_sgr.integrate(w0, pot=curr_pot)

                # finds the center of mass of the particle distribution and integrates its orbit
                com_p, com_v, com_index = int_sgr.calc_com(w0)
                com_orbit,pot = int_sgr.integrate(gd.PhaseSpacePosition(pos=com_p, vel=com_v))

                # calculates the generalized variance of the particle distribution
                gv = int_sgr.calc_dps(sag_mass, orbit, curr_pot, com_orbit)
                print('Generalized Variance:', gv)

                gvs.append(gv)

    # prints the generalized variances calculated from the potential parameters
    np.set_printoptions(precision=3)
    print(np.reshape(gvs, [len(m_ratios), len(c_ratios), len(rs_ratios)]))
示例#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
示例#9
0
def plot_dps():
    # the parameters for the Sgr dSph
    sag_mass = 1e8
    
    # reads the coordinates from the file to w0
    w0 = int_sgr.read_file('centroid_part_1000', columns=[3, 4, 5, 6, 7, 8], skip_lines=[0])

    # integrates the orbits with initial conditions w0
    orbit, pot = int_sgr.integrate(w0)

    # finds the center of mass of the particle distribution and integrates its orbit
    com_p, com_v, com_index = int_sgr.calc_com(w0)
    com_orbit,pot = int_sgr.integrate(gd.PhaseSpacePosition(pos=com_p, vel=com_v))

    # calculates the generalized variance of the particle distribution in verbose mode, and displays the dps plot
    gv = int_sgr.calc_dps(sag_mass, orbit, pot, com_orbit, \
                          ylims = [0.2, 400], plot_title = 'Example Dps Plot', show_plot=True, verbose=True)
    print('Generalized Variance:', gv)
示例#10
0
    def get_orbit_gal(self, p, dt=0.5 * u.Myr, n_steps=500):
        kw = {'l': self.l0 * _units['l']}
        for k in _units:
            if k == 'l':
                continue
            kw[k] = p[k] * _units[k]
        c = coord.Galactic(**kw)

        # TODO: why is astropy so slow here?
        # cart = c.transform_to(gc_frame)
        # cart = cart.cartesian
        w0 = gd.PhaseSpacePosition(fast_to_galcen(c, self.galcen_frame))
        pot = self.get_potential(p)

        orbit = pot.integrate_orbit(w0, dt=dt, n_steps=n_steps)
        model_gal = orbit.to_coord_frame(
            coord.Galactic, galactocentric_frame=self.galcen_frame)
        return model_gal
示例#11
0
def get_orbit():
    """"""
    t_impact, M, rs, bnorm, bx, vnorm, vx = impact_params()

    # load one orbital point
    pos = np.load('../data/log_orbit.npy')
    phi1, phi2, d, pm1, pm2, vr = pos

    c = gc.GD1(phi1=phi1 * u.deg,
               phi2=phi2 * u.deg,
               distance=d * u.kpc,
               pm_phi1_cosphi2=pm1 * u.mas / u.yr,
               pm_phi2=pm2 * u.mas / u.yr,
               radial_velocity=vr * u.km / u.s)
    w0 = gd.PhaseSpacePosition(c.transform_to(gc_frame).cartesian)

    # best-fitting orbit
    dt = 0.5 * u.Myr
    n_steps = 120
    wangle = 180 * u.deg

    # integrate back in time
    fit_orbit = ham.integrate_orbit(w0, dt=dt, n_steps=n_steps)

    prog_phi0 = -20 * u.deg

    model_gd1 = fit_orbit.to_coord_frame(gc.GD1, galactocentric_frame=gc_frame)
    prog_i = np.abs(model_gd1.phi1.wrap_at(180 * u.deg) - prog_phi0).argmin()
    prog_w0 = fit_orbit[prog_i]

    dt_orbit = 0.5 * u.Myr
    nstep_impact = np.int64(t_impact / dt_orbit)
    prog_orbit = ham.integrate_orbit(prog_w0,
                                     dt=-dt_orbit,
                                     t1=0 * u.Myr,
                                     t2=-3 * u.Gyr)
    #impact_orbit = prog_orbit[nstep_impact:]
    #impact_orbit = impact_orbit[::-1]
    prog_orbit = prog_orbit[::-1]

    #print(nstep_impact, impact_orbit)

    return prog_orbit
示例#12
0
def rv_to_3d_isotropic(r, v):
    """Given radii and velocity magnitudes, generate a set of 6D initial
    conditions by assuming isotropy.

    Parameters
    ----------
    r : quantity_like [length]
        Radii.
    v : quantity_like [speed]
        Velocity magnidues.
    """

    phi = np.random.uniform(0, 2*np.pi, size=r.size) * u.radian
    theta = np.arccos(2*np.random.uniform(size=r.size) - 1) * u.radian
    sph = coord.PhysicsSphericalRepresentation(phi=phi, theta=theta, r=r)
    xyz = sph.represent_as(coord.CartesianRepresentation).xyz

    phi = np.random.uniform(0, 2*np.pi, size=r.size) * u.radian
    theta = np.arccos(2*np.random.uniform(size=r.size) - 1) * u.radian
    v_sph = coord.PhysicsSphericalRepresentation(phi=phi, theta=theta,
                                                 r=np.ones_like(v.value)*u.one)
    v_xyz = v * v_sph.represent_as(coord.CartesianRepresentation).xyz

    return gd.PhaseSpacePosition(pos=xyz, vel=v_xyz)
def run_gala_orbit(pos_sat, vel_sat, pos_tp, vel_tp):
    """
    Specify units in ICs
    """
    ## GALA set up

    # Design gala potential using Nbody and a test particle

    # Present-day position/velocity in inertial frame moving with instantaneous
    # Milky Way velocity:
    w0_mw = gd.PhaseSpacePosition(
        pos=[0, 0, 0] * u.kpc,
        vel=[0, 0, 0] * u.km / u.s,
    )
    pot_mw = gp.HernquistPotential(m=Mhost * u.Msun,
                                   c=1 * u.kpc,
                                   units=galactic)

    # Values from Vasiliev et al. 2020
    w0_lmc = gd.PhaseSpacePosition(
        pos=pos_sat,
        vel=vel_sat,
    )

    w0_test = gd.PhaseSpacePosition(
        pos=pos_tp,
        vel=vel_tp,
    )

    pot_lmc = gp.HernquistPotential(m=Msat * u.Msun,
                                    c=1 * u.kpc,
                                    units=galactic)

    w0 = gd.combine((w0_mw, w0_lmc, w0_test))
    nbody = gd.DirectNBody(w0, [pot_mw, pot_lmc, None])

    w1 = gd.combine((w0_lmc, w0_test))
    isolated = gd.DirectNBody(w1, [pot_lmc, None])

    # Full : Host - Satellite - test particle
    orbits = nbody.integrate_orbit(dt=dt * u.Gyr,
                                   t1=tmin * u.Gyr,
                                   t2=tmax * u.Gyr)

    # Orbit quantities full orbit
    pos_halo = np.array([orbits.xyz[:, :, 0].to(u.kpc).value])[0]
    pos_sat = np.array([orbits.xyz[:, :, 1].to(u.kpc).value])[0]
    pos_tp = np.array([orbits.xyz[:, :, 2].to(u.kpc).value])[0]

    vel_halo = np.array([orbits.v_xyz[:, :, 0].to(u.km / u.s).value])[0]
    vel_sat = np.array([orbits.v_xyz[:, :, 1].to(u.km / u.s).value])[0]
    vel_tp = np.array([orbits.v_xyz[:, :, 2].to(u.km / u.s).value])[0]

    r_halo = (np.sum(orbits.xyz[:, :, 0]**2, axis=0))**0.5
    r_sat = (np.sum(orbits.xyz[:, :, 1]**2, axis=0))**0.5
    r_tp = (np.sum(orbits.xyz[:, :, 2]**2, axis=0))**0.5

    v_halo = (np.sum(orbits.v_xyz[:, :, 0].to(u.km / u.s).value**2,
                     axis=0))**0.5
    v_sat = (np.sum(orbits.v_xyz[:, :, 1].to(u.km / u.s).value**2,
                    axis=0))**0.5
    v_tp = (np.sum(orbits.v_xyz[:, :, 2].to(u.km / u.s).value**2, axis=0))**0.5

    rtp_r2_sat = np.sum((np.array(orbits.xyz[:, :, 2].to(u.kpc).value -
                                  orbits.xyz[:, :, 1].to(u.kpc).value))**2,
                        axis=0)**0.5
    vtp_r2_sat = np.sum(
        (np.array(orbits.v_xyz[:, :, 2].to(u.km / u.s).value -
                  orbits.v_xyz[:, :, 1].to(u.km / u.s).value))**2,
        axis=0)**0.5

    return [pos_halo, vel_halo], [pos_sat, vel_sat], [pos_tp, vel_tp]
示例#14
0
def ln_likelihood(p,
                  phi1,
                  pot,
                  data,
                  data_units,
                  frame_comp_names,
                  extra_var,
                  plot=False):
    phi2, dist, pm1, pm2, rv, *other_p = p
    lnMhalo, halo_c, lnMdisk = other_p

    # M_pal5 = np.exp(lnM)
    # if not 8e3 < M_pal5 < 4e5:
    #     return -np.inf

    if not 25 < lnMhalo < 29:
        return -np.inf
    if not 0.8 < halo_c < 1.2:
        return -np.inf

    if not 23 < lnMdisk < 28:
        return -np.inf

    pot = gp.MilkyWayPotential(halo=dict(m=np.exp(lnMhalo), c=halo_c),
                               disk=dict(m=np.exp(lnMdisk)))

    # galcen_frame = coord.Galactocentric(galcen_distance=8.1*u.kpc,
    #                                     galcen_v_sun=coord.CartesianDifferential([vx, vy, vz]*u.km/u.s))

    c = gc.Pal5PriceWhelan18(phi1=phi1,
                             phi2=phi2 * data_units['phi2'],
                             distance=dist * u.kpc,
                             pm_phi1_cosphi2=pm1 * u.mas / u.yr,
                             pm_phi2=pm2 * u.mas / u.yr,
                             radial_velocity=rv * u.km / u.s)
    w0 = gd.PhaseSpacePosition(c.transform_to(galcen_frame).data)

    # Integrate the orbit and generate the stream - set these parameters!:
    gen = ms.MockStreamGenerator(df, mw, progenitor_potential=pal5_pot)

    stream, _ = gen.run(w0,
                        2e4 * u.Msun,
                        dt=-1 * u.Myr,
                        n_steps=3000,
                        release_every=5)
    stream_c = stream.to_coord_frame(gc.Pal5PriceWhelan18,
                                     galactocentric_frame=galcen_frame)

    tracks, stds = get_stream_track(
        stream_c,
        frame_comp_names,
        phi1_bins=phi1_bins,
        phi1_lim=phi1_lim,
        # phi1_binsize=1.5*u.deg,
        units=data_units)

    if plot:
        fig, axes = plt.subplots(5, 1, figsize=(8, 12), sharex=True)

        grid = np.linspace(phi1_lim[0].value, phi1_lim[1].value, 1024)
        for i, name in enumerate(frame_comp_names[1:]):
            ax = axes[i]

            ax.plot(data['phi1'][data[name] != 0],
                    data[name][data[name] != 0],
                    marker='o',
                    ls='none',
                    color='k',
                    ms=4)

            ax.plot(stream_c.phi1.wrap_at(180 * u.deg).degree,
                    getattr(stream_c, name).value,
                    marker='o',
                    ls='none',
                    color='tab:blue',
                    ms=2,
                    alpha=0.4,
                    zorder=-100)

            ax.plot(grid,
                    tracks[name](grid),
                    marker='',
                    color='tab:orange',
                    alpha=0.5)

            ax.set_ylabel(name, fontsize=12)

        ax.set_xlim(phi1_lim.value)
        axes[0].set_ylim(-1.5, 3)
        axes[1].set_ylim(15, 25)
        axes[2].set_ylim(2, 5.5)
        axes[3].set_ylim(-1, 2)
        axes[4].set_ylim(-75, -20)
        fig.tight_layout()
        fig.set_facecolor('w')

        # -- residuals --
        fig, axes = plt.subplots(5, 1, figsize=(8, 12), sharex=True)

        grid = np.linspace(phi1_lim[0].value, phi1_lim[1].value, 1024)
        for i, name in enumerate(frame_comp_names[1:]):
            ax = axes[i]

            ivar = get_ivar(data[name + '_ivar'], extra_var[name])
            ax.errorbar(data['phi1'][ivar > 0.],
                        data[name][ivar > 0] -
                        tracks[name](data['phi1'][ivar > 0.]),
                        yerr=1 / np.sqrt(ivar[ivar > 0.]),
                        marker='o',
                        ls='none',
                        color='k',
                        ecolor='#aaaaaa')
            ax.axhline(0.)
            ax.set_ylabel(name, fontsize=12)

        ax.set_xlim(phi1_lim.value)
        axes[0].set_ylim(-1, 1)
        axes[1].set_ylim(-4, 4)
        axes[2].set_ylim(-2, 2)
        axes[3].set_ylim(-2, 2)
        axes[4].set_ylim(-10, 10)
        axes[0].set_title('Residuals')
        fig.tight_layout()
        fig.set_facecolor('w')

    lls = []
    for name in frame_comp_names[1:]:  # skip phi1
        ivar = get_ivar(data[name + '_ivar'],
                        stds[name](data['phi1'])**2 + extra_var[name])
        ll = ln_normal_ivar(tracks[name](data['phi1']), data[name], ivar)
        ll[~np.isfinite(ll)] = np.nan
        lls.append(ll)

    return np.nansum(lls, axis=0).sum()
示例#15
0
STwvel = STtable['wvel']
STFe = STtable['feh']
STMgFe = STtable['[MgI]'] - STtable['feh']

STgd = GaiaData(STtable)

gaiadata = GaiaData(APOKASCtable)

rsun = 8 * u.kpc
zsun = 0.025 * u.kpc
vsun = [11.1, 232.24, 7.25] * u.km/u.s
gc_frame = coord.Galactocentric(galcen_distance=rsun, galcen_v_sun=coord.CartesianDifferential(*vsun), z_sun=zsun)

sc = gaiadata.skycoord
STsc = STgd.skycoord
APOKASCdyn = gd.PhaseSpacePosition(sc.transform_to(gc_frame).cartesian)
STdyn = gd.PhaseSpacePosition(STsc.transform_to(gc_frame).cartesian)

APOKASCrad = APOKASCdyn.represent_as('cylindrical').rho.to(u.kpc).value
STrad = STdyn.represent_as('cylindrical').rho.to(u.kpc).value

APOKASCz = APOKASCdyn.represent_as('cylindrical').z.to(u.kpc).value
STz = STdyn.represent_as('cylindrical').z.to(u.kpc).value

#process
Jr = np.sqrt(Jr)
Lz = Lz/(8. * 220.)
vvel = vvel - 220.

STJr = np.sqrt(STJr)
STLz = STLz/(8. * 220.)
示例#16
0
                          dec=0 * u.deg,
                          distance=6 * u.kpc,
                          pm_ra_cosdec=0.009 * u.mas / u.yr,
                          pm_dec=0.009 * u.mas / u.yr,
                          radial_velocity=0.1 * u.km / u.s)

# Start by transforming 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=-0.5 * u.Myr, n_steps=10000)

fig = orbit.plot()
fig.savefig('../results/test_results/sandbox_gala_integration.png')

print(orbit.pericenter(), orbit.apocenter(), orbit.eccentricity())

# Now we’ll sample from the error distribution over the distance, proper
# motions, and radial velocity, compute orbits, and plot distributions of mean
# pericenter and apocenter:
n_samples = 32
dist = np.random.normal(icrs.distance.value, icrs_err.distance.value,
                        n_samples) * icrs.distance.unit

pm_ra_cosdec = np.random.normal(icrs.pm_ra_cosdec.value,
示例#17
0
print(sttable['source_id'][0])

# for the montecarlo loop later
cov = gaiadata.get_cov()
meanvals = [
    gaiadata.ra.value, gaiadata.dec.value, gaiadata.parallax.value,
    gaiadata.pmra.value, gaiadata.pmdec.value, gaiadata.radial_velocity.value
]
meanvals = list(map(list, zip(*meanvals)))  # transpose

nentries = len(sttable)

# convert to galactocentric coordinates
sc = gaiadata.skycoord
scdyn = gd.PhaseSpacePosition(sc.transform_to(gc_frame).cartesian)
""" 
compute u, v, w
"""

distgalcenter = np.sqrt(scdyn.pos.x * scdyn.pos.x + scdyn.pos.y * scdyn.pos.y +
                        scdyn.pos.z * scdyn.pos.z)
cylndvel = scdyn.vel.represent_as(coord.CylindricalDifferential,
                                  base=scdyn.pos)
#rvel = cylndvel.d_rho.to(u.km / u.s)
uvel = -cylndvel.d_rho.to(u.km / u.s).value
vvel = -(distgalcenter * cylndvel.d_phi).to(
    u.km / u.s, equivalencies=u.dimensionless_angles()).value
#zvel = cylndvel.d_z.to(u.km/u.s)
wvel = cylndvel.d_z.to(u.km / u.s).value
"""
示例#18
0
textwidth = 7.10000594991
columnwidth = 3.35224200913

tb_c = ['#4e79a7', '#f28e2b', '#e15759', '#76b7b2', '#59a14f',
        '#edc948', '#b07aa1', '#ff9da7', '#9c755f', '#bab0ac']

Rsolar = 8.2

#cluster min, max mass
mc_min = 100
mc_max = 10000
mc_list = np.linspace(mc_min, mc_max, 1000)

# find mass enclosed within Rsolar
mw = gp.MilkyWayPotential()
q = gd.PhaseSpacePosition(pos=[Rsolar, 0, 0] * u.kpc, vel=[0, 0, 0] * u.km/u.s)
M_enclosed = float(mw.mass_enclosed(q).to_value(u.Msun))

dJzJz_target = np.power(mc_list / M_enclosed, 1/3)

# load in results
fname_list = ['thin', 'thick']
name_list = ['thin-disk', 'thick-disk']

def zoffset_gen(offlist, dJzJz):
    interp = interp1d(offlist, dJzJz)

    def to_minimize(off, target):
        return np.abs(interp(float(off)) - target)

    offlist_target = []
c1 = 1.0
c2 = -1.0
w1 = 1.0
w2 = 1.0

# Milky Way and Andromeda
M_MW = 1.0E11 * u.Msun
M_AND = 1.23E12 * u.Msun
SIZE_MW = 36.8  # kpc
SIZE_AND = 33.7  # kpc
MW_AND_DIST = 778.0 / sqrt(3)
MW_AND_VEL = -110.0 / sqrt(3)

POT_MW = gp.MilkyWayPotential()
POT_AND = gp.HernquistPotential(M_AND.value, 0, units=galactic)
ICS_MW = gd.PhaseSpacePosition(pos=[0, 0, 0] * u.kpc,
                               vel=[0, 0, 0] * u.km / u.s)
ICS_AND = gd.PhaseSpacePosition(
    pos=[MW_AND_DIST, MW_AND_DIST, MW_AND_DIST] * u.kpc,
    vel=[MW_AND_VEL, MW_AND_VEL, MW_AND_VEL] * (u.km / u.s))

# Lörg and Smøl Magellanic Clouds
M_LORG = 1.0E10 * u.M_sun
SIZE_LORG = 4.3  # u.kpc
MW_LORG_DIST = 49.97  # wrt MW, in kpc
MW_LORG_VEL = 321.0  # wrt MW, in km/s

POT_LORG = gp.HernquistPotential(M_LORG.value, 0, units=galactic)
ICS_LORG = gd.PhaseSpacePosition(
    pos=[MW_LORG_DIST, MW_LORG_DIST, MW_LORG_DIST] * u.kpc,
    vel=[-MW_LORG_VEL, 0, 0] * (u.km / u.s))
示例#20
0
def fiducial_at_start():
    """Create fiducial model at the beginning of the movie"""

    np.random.seed(143531)
    t_impact = 2 * 0.495 * u.Gyr

    # load one orbital point
    pos = np.load('../data/log_orbit.npy')
    phi1, phi2, d, pm1, pm2, vr = pos

    c = gc.GD1(phi1=phi1 * u.deg,
               phi2=phi2 * u.deg,
               distance=d * u.kpc,
               pm_phi1_cosphi2=pm1 * u.mas / u.yr,
               pm_phi2=pm2 * u.mas / u.yr,
               radial_velocity=vr * u.km / u.s)
    w0 = gd.PhaseSpacePosition(c.transform_to(gc_frame).cartesian)

    # best-fitting orbit
    dt = 0.5 * u.Myr
    n_steps = 120
    wangle = 180 * u.deg

    # integrate back in time
    fit_orbit = ham.integrate_orbit(w0, dt=dt, n_steps=n_steps)

    prog_phi0 = -20 * u.deg

    model_gd1 = fit_orbit.to_coord_frame(gc.GD1, galactocentric_frame=gc_frame)
    prog_i = np.abs(model_gd1.phi1.wrap_at(180 * u.deg) - prog_phi0).argmin()
    prog_w0 = fit_orbit[prog_i]

    dt_orbit = 0.5 * u.Myr
    nstep_impact = np.int64((t_impact / dt_orbit).decompose())
    #prog_orbit = ham.integrate_orbit(prog_w0, dt=-dt_orbit, t1=0*u.Myr, t2=-3*u.Gyr)
    prog_orbit = ham.integrate_orbit(prog_w0,
                                     dt=-dt_orbit,
                                     t1=0 * u.Myr,
                                     t2=-3 * u.Gyr)
    impact_orbit = prog_orbit[nstep_impact:]
    impact_orbit = impact_orbit[::-1]
    prog_orbit = prog_orbit[::-1]

    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
    model_present = mockstream.dissolved_fardal_stream(ham,
                                                       prog_orbit,
                                                       prog_mass=prog_mass,
                                                       t_disrupt=t_disrupt,
                                                       release_every=nrelease)

    n_steps_disrupt = int(abs(t_disrupt / (prog_orbit.t[1] - prog_orbit.t[0])))
    model_present = model_present[:-2 * n_steps_disrupt]

    model_gd1 = model_present.to_coord_frame(gc.GD1,
                                             galactocentric_frame=gc_frame)
    ind_gap = np.where((model_gd1.phi1.wrap_at(wangle) > -43 * u.deg)
                       & (model_gd1.phi1.wrap_at(wangle) < -33 * u.deg))[0]

    n_times = (impact_orbit.t < t_disrupt).sum()
    prog_mass = np.linspace(minit, mfin, n_times)
    prog_mass = np.concatenate(
        (prog_mass, np.zeros(len(impact_orbit.t) - n_times))) * u.Msun
    model = mockstream.dissolved_fardal_stream(ham,
                                               impact_orbit,
                                               prog_mass=prog_mass,
                                               t_disrupt=t_disrupt,
                                               release_every=nrelease)

    n_steps_disrupt = int(
        abs(t_disrupt / (impact_orbit.t[1] - impact_orbit.t[0])))
    model = model[:-2 * n_steps_disrupt]

    xsub = np.ones(3) * u.kpc
    vsub = np.ones(3) * u.km / u.s

    outdict = {'model': model, 'xsub': xsub, 'vsub': vsub}
    pickle.dump(outdict, open('../data/fiducial_at_start.pkl', 'wb'))
示例#21
0
def get_gccoo_w0(coo):
    gc_frame = get_gc_frame()
    gccoo = coo.transform_to(gc_frame)
    w0 = gd.PhaseSpacePosition(gccoo.data)
    return gccoo, w0
示例#22
0
## Adding halo to potential now that mock galaxy image is in place
pot['halo'] = gp.NFWPotential(m=10E11, r_s=25 * u.kpc, units=galactic)

########################################
# 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
示例#23
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)
示例#24
0
plt.legend(loc='best')
# -

# The SCF potential object acts like any other `gala.potential` object, meaning
# we can, e.g., plot density or potential contours:

# +
grid = np.linspace(-8, 8, 128)

fig, axes = plt.subplots(1, 2, figsize=(10, 5), sharex=True, sharey=True)
_ = pot_flat.plot_contours((grid, grid, 0), ax=axes[0])
axes[0].set_xlabel('$x$')
axes[0].set_ylabel('$y$')

_ = pot_flat.plot_contours((grid, 0, grid), ax=axes[1])
axes[1].set_xlabel('$x$')
axes[1].set_ylabel('$z$')

for ax in axes:
    ax.set_aspect('equal')
# -

# And numerically integrate orbits by passing in initial conditions and
# integration parameters:

w0 = gd.PhaseSpacePosition(pos=[3.5, 0, 1], vel=[0, 0.4, 0.05])

orbit_flat = pot_flat.integrate_orbit(w0, dt=1., n_steps=5000)
_ = orbit_flat.plot()
示例#25
0
def sample_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),
    icrs_err = coord.SkyCoord(ra=0*u.deg, dec=0*u.deg, distance=6*u.kpc,
                              pm_ra_cosdec=0.009*u.mas/u.yr,
                              pm_dec=0.009*u.mas/u.yr,
                              radial_velocity=0.1*u.km/u.s)
):
    """
    Sample from the error distribution over the distance, proper motions, and
    radial velocity, compute orbits, and plot distributions of mean pericenter
    and apocenter
    """

    n_samples = 32
    dist = np.random.normal(icrs.distance.value, icrs_err.distance.value,
                            n_samples) * icrs.distance.unit

    pm_ra_cosdec = np.random.normal(icrs.pm_ra_cosdec.value,
                                    icrs_err.pm_ra_cosdec.value,
                                    n_samples) * icrs.pm_ra_cosdec.unit

    pm_dec = np.random.normal(icrs.pm_dec.value,
                              icrs_err.pm_dec.value,
                              n_samples) * icrs.pm_dec.unit

    rv = np.random.normal(icrs.radial_velocity.value, icrs_err.radial_velocity.value,
                          n_samples) * icrs.radial_velocity.unit

    ra = np.full(n_samples, icrs.ra.degree) * u.degree
    dec = np.full(n_samples, icrs.dec.degree) * u.degree

    icrs_samples = coord.SkyCoord(ra=ra, dec=dec, distance=dist,
                                  pm_ra_cosdec=pm_ra_cosdec,
                                  pm_dec=pm_dec, radial_velocity=rv)

    galcen_samples = icrs_samples.transform_to(gc_frame)

    w0_samples = gd.PhaseSpacePosition(galcen_samples.data)
    orbit_samples = potential.integrate_orbit(w0_samples, dt=-1*u.Myr, n_steps=4000)

    pers = orbit_samples.pericenter(approximate=True)
    apos = orbit_samples.apocenter(approximate=True)
    eccs = orbit_samples.eccentricity(approximate=True)

    plt.close('all')
    fig, axes = plt.subplots(1, 3, figsize=(12, 4))

    axes[0].hist(pers.to_value(u.kpc), bins='auto')
    axes[0].set_xlabel('pericenter [kpc]')

    axes[1].hist(apos.to_value(u.kpc), bins='auto')
    axes[1].set_xlabel('apocenter [kpc]')

    axes[2].hist(eccs.value, bins='auto')
    axes[2].set_xlabel('eccentricity')
    fig.savefig('../results/test_results/sandbox_gala_sampling.png')
示例#26
0
    """
  icrs_err = coord.ICRS(ra=0*u.deg, dec=0*u.deg, distance=6*u.kpc,
                      pm_ra_cosdec=0.009*u.mas/u.yr,
                      pm_dec=0.009*u.mas/u.yr,
                      radial_velocity=0.1*u.km/u.s)

  """

    v_sun = coord.CartesianDifferential([0, 0, 0] * 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 = icrs.transform_to(gc_frame)

    w0 = gd.PhaseSpacePosition(gc.data)

    if (star["Ba_only_candidate"] == 'true'
            and star["Ba_Sr_candidate"] == 'false'):

        Ba_velx.append(w0.v_x.to(u.km / u.s).value)
        Ba_vely.append(w0.v_y.to(u.km / u.s).value)
        Ba_velz.append(w0.v_z.to(u.km / u.s).value)
        Ba_y.append(np.sqrt(Ba_velx[-1]**2 + Ba_velz[-1]**2))

    if (star["Sr_only_candidate"] == 'true'
            and star["Ba_Sr_candidate"] == 'false'):

        Sr_velx.append(w0.v_x.to(u.km / u.s).value)
        Sr_vely.append(w0.v_y.to(u.km / u.s).value)
        Sr_velz.append(w0.v_z.to(u.km / u.s).value)
示例#27
0
def fiducial_at_encounter():
    """Create fiducial model at the time of encounter"""

    np.random.seed(143531)

    t_impact = 0.495 * u.Gyr
    bnorm = 15 * u.pc
    bx = 6 * u.pc
    vnorm = 250 * u.km / u.s
    vx = -25 * u.km / u.s

    # load one orbital point
    pos = np.load('../data/log_orbit.npy')
    phi1, phi2, d, pm1, pm2, vr = pos

    c = gc.GD1(phi1=phi1 * u.deg,
               phi2=phi2 * u.deg,
               distance=d * u.kpc,
               pm_phi1_cosphi2=pm1 * u.mas / u.yr,
               pm_phi2=pm2 * u.mas / u.yr,
               radial_velocity=vr * u.km / u.s)
    w0 = gd.PhaseSpacePosition(c.transform_to(gc_frame).cartesian)

    # best-fitting orbit
    dt = 0.5 * u.Myr
    n_steps = 120
    wangle = 180 * u.deg

    # integrate back in time
    fit_orbit = ham.integrate_orbit(w0, dt=dt, n_steps=n_steps)

    prog_phi0 = -20 * u.deg

    model_gd1 = fit_orbit.to_coord_frame(gc.GD1, galactocentric_frame=gc_frame)
    prog_i = np.abs(model_gd1.phi1.wrap_at(180 * u.deg) - prog_phi0).argmin()
    prog_w0 = fit_orbit[prog_i]

    dt_orbit = 0.5 * u.Myr
    nstep_impact = np.int64((t_impact / dt_orbit).decompose())
    #prog_orbit = ham.integrate_orbit(prog_w0, dt=-dt_orbit, t1=0*u.Myr, t2=-3*u.Gyr)
    prog_orbit = ham.integrate_orbit(prog_w0,
                                     dt=-dt_orbit,
                                     t1=0 * u.Myr,
                                     t2=-3 * u.Gyr)
    impact_orbit = prog_orbit[nstep_impact:]
    impact_orbit = impact_orbit[::-1]
    prog_orbit = prog_orbit[::-1]

    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
    model_present = mockstream.dissolved_fardal_stream(ham,
                                                       prog_orbit,
                                                       prog_mass=prog_mass,
                                                       t_disrupt=t_disrupt,
                                                       release_every=nrelease)

    n_steps_disrupt = int(abs(t_disrupt / (prog_orbit.t[1] - prog_orbit.t[0])))
    model_present = model_present[:-2 * n_steps_disrupt]

    model_gd1 = model_present.to_coord_frame(gc.GD1,
                                             galactocentric_frame=gc_frame)
    ind_gap = np.where((model_gd1.phi1.wrap_at(wangle) > -43 * u.deg)
                       & (model_gd1.phi1.wrap_at(wangle) < -33 * u.deg))[0]

    n_times = (impact_orbit.t < t_disrupt).sum()
    prog_mass = np.linspace(minit, mfin, n_times)
    prog_mass = np.concatenate(
        (prog_mass, np.zeros(len(impact_orbit.t) - n_times))) * u.Msun
    model = mockstream.dissolved_fardal_stream(ham,
                                               impact_orbit,
                                               prog_mass=prog_mass,
                                               t_disrupt=t_disrupt,
                                               release_every=nrelease)

    n_steps_disrupt = int(
        abs(t_disrupt / (impact_orbit.t[1] - impact_orbit.t[0])))
    model = model[:-2 * n_steps_disrupt]

    Nstar = np.shape(model)[0]
    ivalid = ind_gap < Nstar
    ind_gap = ind_gap[ivalid]

    xgap = np.median(model.xyz[:, ind_gap], axis=1)
    vgap = np.median(model.v_xyz[:, ind_gap], axis=1)

    ########################
    # Perturber at encounter

    i = np.array([1, 0, 0], dtype=float)
    j = np.array([0, 1, 0], dtype=float)
    k = np.array([0, 0, 1], dtype=float)

    # find positional plane
    bi = np.cross(j, vgap)
    bi = bi / np.linalg.norm(bi)

    bj = np.cross(vgap, bi)
    bj = bj / np.linalg.norm(bj)

    # pick b
    by = np.sqrt(bnorm**2 - bx**2)
    b = bx * bi + by * bj
    xsub = xgap + b

    # find velocity plane
    vi = np.cross(vgap, b)
    vi = vi / np.linalg.norm(vi)

    vj = np.cross(b, vi)
    vj = vj / np.linalg.norm(vj)

    # pick v
    vy = np.sqrt(vnorm**2 - vx**2)
    vsub = vx * vi + vy * vj

    outdict = {'model': model, 'xsub': xsub, 'vsub': vsub}
    pickle.dump(outdict, open('../data/fiducial_at_encounter.pkl', 'wb'))