예제 #1
0
def test_estimateDelta():

    #_____initialize some KKSPot_____
    Delta = 1.0
    pot = KuzminKutuzovStaeckelPotential(ac=20., Delta=Delta, normalize=True)

    #_____initialize an orbit (twice)_____
    vxvv = [1., 0.1, 1.1, 0.01, 0.1]
    o = Orbit(vxvv=vxvv)

    #_____integrate the orbit with C_____
    ts = numpy.linspace(0, 101, 100)
    o.integrate(ts, pot, method='leapfrog_c')

    #____estimate Focal length Delta_____
    #for each time step individually:
    deltas_estimate = numpy.zeros(len(ts))
    for ii in range(len(ts)):
        deltas_estimate[ii] = estimateDeltaStaeckel(pot, o.R(ts[ii]),
                                                    o.z(ts[ii]))

    assert numpy.all(numpy.fabs(deltas_estimate - Delta) < 10.**-8), \
            'Focal length Delta estimated along the orbit is not constant.'

    #for all time steps together:
    delta_estimate = estimateDeltaStaeckel(pot, o.R(ts), o.z(ts))

    assert numpy.fabs(delta_estimate - Delta) < 10.**-8, \
            'Focal length Delta estimated from the orbit is not the same as the input focal length.'

    return None
예제 #2
0
def test_estimateDelta():

    #_____initialize some KKSPot_____
    Delta = 1.0
    pot = KuzminKutuzovStaeckelPotential(ac=20.,Delta=Delta,normalize=True)

    #_____initialize an orbit (twice)_____
    vxvv = [1.,0.1,1.1,0.01,0.1]
    o= Orbit(vxvv=vxvv)

    #_____integrate the orbit with C_____
    ts= numpy.linspace(0,101,100)
    o.integrate(ts,pot,method='leapfrog_c')


    #____estimate Focal length Delta_____
    #for each time step individually:
    deltas_estimate = numpy.zeros(len(ts))
    for ii in range(len(ts)):
        deltas_estimate[ii] = estimateDeltaStaeckel(pot,o.R(ts[ii]),o.z(ts[ii]))

    assert numpy.all(numpy.fabs(deltas_estimate - Delta) < 10.**-8), \
            'Focal length Delta estimated along the orbit is not constant.'

    #for all time steps together:
    delta_estimate = estimateDeltaStaeckel(pot,o.R(ts),o.z(ts))
    
    assert numpy.fabs(delta_estimate - Delta) < 10.**-8, \
            'Focal length Delta estimated from the orbit is not the same as the input focal length.'

    return None
예제 #3
0
def cluster_dynamics(cluster):
    orbits = []
    dist_dict = dict(cluster[2])
    for i in cluster[1]:
        ra = float(i[0])
        dec = float(i[1])
        dist = float(dist_dict[i[-1]])
        pmRA = float(i[2])
        pmDec = float(i[3])
        Vlos = float(i[4])
        #only attach where proper motions are available
        if dist != 0.0:
            if pmRA != 0.0:
                if pmDec != 0.0:
                    orbits.append(
                        Orbit(vxvv=[ra, dec, dist, pmRA, pmDec, Vlos],
                              radec=True,
                              ro=8.,
                              vo=220.,
                              solarmotion="schoenrich"))
    ts = np.linspace(0, 100, 10000)
    mwp = MWPotential2014
    print(len(orbits))
    #action angles yay!
    #the following gets confusing because we speak of "means" twice
    #we want the mean J over each individual orbit, but to measure the spread in the cluster
    #we compare to the mean of each J
    ro = 8
    vo = 220
    mean_js = np.array([])
    for o in orbits:
        try:
            o.integrate(ts, mwp, method='odeint')
            delta_o = estimateDeltaStaeckel(MWPotential2014, (o.R()) / ro,
                                            (o.z()) / vo)
            aAS = actionAngleStaeckel(pot=MWPotential2014, delta=delta_o)
            js_o = aAS((o.R()) / ro, (o.vR()) / vo, (o.vT()) / vo,
                       (o.z()) / ro, (o.vz()) / vo)
            #the next line isn't really needed unless js is actually a vector, for t = 0 it is not
            mean_o_js = np.array(
                [js_o[0].mean(), js_o[1].mean(), js_o[2].mean()])
            if mean_js.shape == (0, ):
                mean_js = mean_o_js
            else:
                mean_js = np.vstack([mean_js, mean_o_js])
        except:
            print("found unbound, discarded")
            #in this case the orbit is unbound -- this f***s up the whole thing I know
            pass
    print(mean_js.shape)
    #so for this cluster we have a 3 x cluster length array
    cluster_mean_js = np.array(
        [mean_js.T[0].mean(), mean_js.T[1].mean(), mean_js.T[2].mean()])
    #average_difference
    diffs = np.absolute((mean_js - cluster_mean_js)) / cluster_mean_js
    dynamics_summary = np.array(
        [diffs.T[0].mean(), diffs.T[1].mean(), diffs.T[2].mean()])
    return dynamics_summary
예제 #4
0
def estimate_delta(orbit,
                   ts=numpy.linspace(0., 20., 1001),
                   pot=MWPotential2014):
    '''
    estimate delta for a given orbit instance
    '''
    orbit.integrate(ts, pot, method='symplec4_c')

    return estimateDeltaStaeckel(pot, orbit.R(ts), orbit.z(ts))
예제 #5
0
def test_staeckel_fudge_delta():
    import galpy.potential as galpy_pot
    from galpy.actionAngle import estimateDeltaStaeckel

    ro = 8.1 * u.kpc
    vo = 229 * u.km / u.s

    paired_potentials = []

    # Miyamoto-Nagai
    potential = gp.MiyamotoNagaiPotential(m=6e10 * u.Msun,
                                          a=3 * u.kpc,
                                          b=0.3 * u.kpc,
                                          units=galactic)
    amp = (G * potential.parameters['m']).to_value(vo**2 * ro)
    a = potential.parameters['a'].to_value(ro)
    b = potential.parameters['b'].to_value(ro)
    galpy_potential = galpy_pot.MiyamotoNagaiPotential(amp=amp,
                                                       a=a,
                                                       b=b,
                                                       ro=ro,
                                                       vo=vo)
    paired_potentials.append((potential, galpy_potential))

    # Hernquist
    potential = gp.HernquistPotential(m=6e10 * u.Msun,
                                      c=0.3 * u.kpc,
                                      units=galactic)
    amp = (G * potential.parameters['m']).to_value(vo**2 * ro)
    a = potential.parameters['c'].to_value(ro)
    galpy_potential = galpy_pot.HernquistPotential(amp=amp, a=a, ro=ro, vo=vo)
    paired_potentials.append((potential, galpy_potential))

    # NFW
    potential = gp.NFWPotential(m=6e11 * u.Msun,
                                r_s=15.6 * u.kpc,
                                units=galactic)
    amp = (G * potential.parameters['m']).to_value(vo**2 * ro)
    a = potential.parameters['r_s'].to_value(ro)
    galpy_potential = galpy_pot.NFWPotential(amp=amp, a=a, ro=ro, vo=vo)
    paired_potentials.append((potential, galpy_potential))

    # TEST:
    N = 1024
    rnd = np.random.default_rng(42)
    w = PhaseSpacePosition(pos=rnd.uniform(-10, 10, size=(3, N)) * u.kpc,
                           vel=rnd.uniform(-100, 100, size=(3, N)) * u.km /
                           u.s)

    R = w.cylindrical.rho.to_value(ro)
    z = w.z.to_value(ro)

    for p, galpy_p in paired_potentials:
        galpy_deltas = estimateDeltaStaeckel(galpy_p, R, z, no_median=True)
        gala_deltas = get_staeckel_fudge_delta(p, w).value
        print(p, np.allclose(gala_deltas, galpy_deltas))
        assert np.allclose(gala_deltas, galpy_deltas, atol=1e-6)
예제 #6
0
def calc_delta_MWPotential2014(savefilename,plotfilename):
    Lmin, Lmax= 0.01, 10.
    if not os.path.exists(savefilename):
        #Setup grid
        nL, nE= 101,101
        Ls= 10.**numpy.linspace(numpy.log10(Lmin),numpy.log10(Lmax),nL)
        #Integration times
        ts= numpy.linspace(0.,20.,1001)
        deltas= numpy.empty((nL,nE))
        Einf= evalPot(10.**12.,0.,MWPotential2014)
        print Einf
        for ii in range(nL):
            #Calculate Ec
            Rc= rl(MWPotential2014,Ls[ii])
            print ii, "Rc = ", Rc*8.
            Ec= evalPot(Rc,0.,MWPotential2014)+0.5*Ls[ii]**2./Rc**2.
            Es= Ec+(Einf-Ec)*10.**numpy.linspace(-2.,0.,nE)
            for jj in range(nE):
                #Setup an orbit with this energy and angular momentum
                Er= 2.*(Es[jj]-Ec) #Random energy times 2 = vR^2 + vz^2
                vR= numpy.sqrt(4./5.*Er)
                vz= numpy.sqrt(1./5.*Er)
                o= Orbit([Rc,vR,Ls[ii]/Rc,0.,vz,0.])
                o.integrate(ts,MWPotential2014,method='symplec4_c')
                deltas[ii,jj]= estimateDeltaStaeckel(o.R(ts),o.z(ts),
                                                     pot=MWPotential2014)
        #Save
        save_pickles(savefilename,deltas)
    else:
        savefile= open(savefilename,'rb')
        deltas= pickle.load(savefile)
        savefile.close()
    #Plot
    print numpy.nanmax(deltas)
    bovy_plot.bovy_print()
    bovy_plot.bovy_dens2d(deltas.T,origin='lower',cmap='jet',
                          xrange=[numpy.log10(Lmin),numpy.log10(Lmax)],
                          yrange=[-2,0.],
                          xlabel=r'$\log_{10} L$',
                          ylabel=r'$\log_{10}\left(\frac{E-E_c(L)}{E(\infty)-E_c(L)}\right)$',
                          colorbar=True,shrink=0.78,
                          zlabel=r'$\mathrm{Approximate\ focal\ length}$',
#                          interpolation='nearest',
                          vmin=0.,vmax=0.6)
    bovy_plot.bovy_end_print(plotfilename)
    return None
예제 #7
0
def params_along_orbit(orbit, ts, pot=MWPotential2014, delta=0.375):
    '''
    estimate the orbit parameters along an orbit
    '''
    orbit.integrate(ts, pot, method='symplec4_c')
    Rs = orbit.R(ts)
    vRs = orbit.vR(ts)
    vTs = orbit.vT(ts)
    zs = orbit.z(ts)
    vzs = orbit.vz(ts)
    phis = orbit.phi(ts)
    aAS = actionAngleStaeckel(pot=pot, delta=delta)
    if delta == 'along':
        delta = estimateDeltaStaeckel(pot, Rs, zs, no_median=True)
    es, zms, rps, ras = aAS.EccZmaxRperiRap(Rs,
                                            vRs,
                                            vTs,
                                            zs,
                                            vzs,
                                            phis,
                                            delta=delta)
    return es, zms, rps, ras
def process_single(i):
    vxvv = [ra[i], dec[i], distance[i], pmra[i], pmdec[i], rv[i]]
    if not np.all(np.isfinite(vxvv)) or not np.all(np.isfinite(covariance[i])):
        return np.ones(56) * np.nan
    samp = np.random.multivariate_normal(vxvv, covariance[i], size=1000)
    if not (np.all(samp[:, 1] < 90.) & np.all(samp[:, 1] > -90.)):
        return np.ones(56) * np.nan

    os = Orbit(np.array([
        samp[:, 0], samp[:, 1], samp[:, 2], samp[:, 3], samp[:, 4], samp[:, 5]
    ]).T,
               radec=True,
               ro=_R0,
               vo=_v0,
               zo=_z0,
               solarmotion=[-11.1, 25.7, 7.25])

    sXYZ = np.dstack([os.x(), os.y(), os.z()])[0] / _R0
    sRpz = np.dstack([os.R() / _R0, os.phi(), os.z() / _R0])[0]
    svRvTvz = np.dstack([os.vR(), os.vT(), os.vz()])[0] / _v0

    deltas = estimateDeltaStaeckel(MWPotential2014,
                                   np.median(sRpz[:, 0]),
                                   np.median(sRpz[:, 2]),
                                   no_median=True)
    aAS = actionAngleStaeckel(pot=MWPotential2014, delta=np.mean(deltas))
    e, zmax, rperi, rap = aAS.EccZmaxRperiRap(sRpz[:, 0],
                                              svRvTvz[:, 0],
                                              svRvTvz[:, 1],
                                              sRpz[:, 2],
                                              svRvTvz[:, 2],
                                              sRpz[:, 1],
                                              delta=deltas)
    tcov = np.cov(np.dstack([e, zmax, rperi, rap])[0].T)
    errs = np.sqrt(np.diag(tcov))
    e_zmax_corr = tcov[0, 1] / (errs[0] * errs[1])
    e_rperi_corr = tcov[0, 2] / (errs[0] * errs[2])
    e_rap_corr = tcov[0, 3] / (errs[0] * errs[3])
    zmax_rperi_corr = tcov[1, 2] / (errs[1] * errs[2])
    zmax_rap_corr = tcov[1, 3] / (errs[1] * errs[3])
    rperi_rap_corr = tcov[2, 3] / (errs[2] * errs[3])
    e_err, zmax_err, rperi_err, rap_err = errs
    action = np.array(
        aAS.actionsFreqsAngles(sRpz[:, 0], svRvTvz[:, 0], svRvTvz[:, 1],
                               sRpz[:, 2], svRvTvz[:, 2], sRpz[:, 1]))
    tcov_after_action = np.cov(action)
    errs = np.sqrt(np.diag(tcov_after_action))
    jr_lz_corr = tcov_after_action[0, 1] / (errs[0] * errs[1])
    jr_jz_corr = tcov_after_action[0, 2] / (errs[0] * errs[2])
    lz_jz_corr = tcov_after_action[1, 2] / (errs[1] * errs[2])
    jr_err, lz_err, jz_err, or_err, op_err, oz_err, tr_err, tphi_err, tz_err = errs

    Rc = np.array([rl(MWPotential2014, lz) for lz in action[1]]) * _R0
    Ec = (evaluatePotentials(MWPotential2014, Rc, 0.) + 0.5 *
          (action[1])**2. / Rc**2.) * _v0**2
    E = os.E(pot=MWPotential2014)

    # galactocentric coord and vel uncertainty
    galcen_tcov = np.cov(np.dstack([sRpz[:, 0], sRpz[:, 1], sRpz[:, 2]])[0].T)
    galcen_errs = np.sqrt(np.diag(galcen_tcov))
    galr_err, galphi_err, galz_err = galcen_errs

    galcenv_tcov = np.cov(
        np.dstack([svRvTvz[:, 0], svRvTvz[:, 1], svRvTvz[:, 2]])[0].T)
    galcenv_errs = np.sqrt(np.diag(galcenv_tcov))
    galvr_err, galvt_err, galvz_err = galcenv_errs

    galvr_galvt_corr = galcenv_tcov[0, 1] / (galcenv_errs[0] * galcenv_errs[1])
    galvr_galvz_corr = galcenv_tcov[0, 2] / (galcenv_errs[0] * galcenv_errs[2])
    galvt_galvz_corr = galcenv_tcov[1, 2] / (galcenv_errs[1] * galcenv_errs[2])

    # galr mean to avoid issue near GC, error propagation
    x_mean = np.nanmean(sXYZ[:, 0])
    y_mean = np.nanmean(sXYZ[:, 1])
    x_err = np.nanstd(sXYZ[:, 0])
    y_err = np.nanstd(sXYZ[:, 1])
    x_err_percentage = x_err / np.nanmean(sXYZ[:, 0])
    y_err_percentage = y_err / np.nanmean(sXYZ[:, 1])
    x2_err = (x_mean**2) * (2 * x_err_percentage)
    y2_err = (y_mean**2) * (2 * y_err_percentage)
    galr = np.sqrt(x_mean**2 + y_mean**2)
    galr2_err = np.sqrt(x2_err**2 + y2_err**2)
    galr2_err_percentage = galr2_err / (galr**2)
    galr_err = galr * (0.5 * galr2_err_percentage)

    # galphi mean to avoid issue near GC, error propagation
    galphi = np.arctan2(y_mean, x_mean)
    galphi_err_x = (
        y_mean /
        (x_mean**2 + y_mean**2)) * x_err  # error propagation from x_mean
    galphi_err_y = (
        -x_mean /
        (x_mean**2 + y_mean**2)) * y_err  # error propagation from y_mean
    galphi_err = np.sqrt(galphi_err_x**2 + galphi_err_y**2)  # add them up

    return np.nanmean(e), \
           e_err, \
           np.nanmean(zmax) * _R0, \
           zmax_err * _R0, \
           np.nanmean(rperi) * _R0, \
           rperi_err * _R0, \
           np.nanmean(rap) * _R0, \
           rap_err * _R0, \
           e_zmax_corr, \
           e_rperi_corr, \
           e_rap_corr, \
           zmax_rperi_corr, \
           zmax_rap_corr, \
           rperi_rap_corr, \
           np.nanmean(action[0]) * _R0 * _v0, \
           jr_err * _R0 * _v0, \
           np.nanmean(action[1]) * _R0 * _v0, \
           lz_err * _R0 * _v0, \
           np.nanmean(action[2]) * _R0 * _v0, \
           jz_err * _R0 * _v0, \
           jr_lz_corr, \
           jr_jz_corr, \
           lz_jz_corr, \
           np.nanmean(action[3]) * _freq, or_err * _freq, \
           np.nanmean(action[4]) * _freq, op_err * _freq, \
           np.nanmean(action[5]) * _freq, oz_err * _freq, \
           np.nanmean(action[6]), \
           tr_err, \
           np.nanmean(action[7]), \
           tphi_err, \
           np.nanmean(action[8]), \
           tz_err, \
           np.nanmean(Rc), \
           np.nanstd(Rc), \
           np.nanmean(E), \
           np.nanstd(E), \
           np.nanmean(E - Ec), \
           np.nanstd(E - Ec), \
           galr * _R0, \
           galphi, \
           np.nanmean(sRpz[:, 2]) * _R0, \
           np.nanmean(svRvTvz[:, 0]) * _v0, \
           np.nanmean(svRvTvz[0, 1]) * _v0, \
           np.nanmean(svRvTvz[:, 2]) * _v0, \
           galr_err * _R0, \
           galphi_err, \
           galz_err * _R0, \
           galvr_err * _v0, \
           galvt_err * _v0, \
           galvz_err * _v0, \
           galvr_galvt_corr, \
           galvr_galvz_corr, \
           galvt_galvz_corr
def process_single(i):
    vxvv = [ra[i], dec[i], distance[i], pmra[i], pmdec[i], rv[i]]
    if not np.all(np.isfinite(vxvv)) or not np.all(np.isfinite(covariance[i])):
        return np.ones(56) * np.nan
    samp = np.random.multivariate_normal(vxvv, covariance[i], size=1000)
    if not (np.all(samp[:, 1] < 90.) & np.all(samp[:, 1] > -90.)):
        return np.ones(56) * np.nan
    sXYZ, svxyz, sRpz, svRvTvz = obs_to_galcen(samp[:, 0],
                                               samp[:, 1],
                                               samp[:, 2],
                                               samp[:, 3],
                                               samp[:, 4],
                                               samp[:, 5],
                                               ro=_R0,
                                               vo=_v0,
                                               zo=_z0)
    deltas = estimateDeltaStaeckel(MWPotential2014, np.median(sRpz[:, 0]), np.median(sRpz[:, 2]), no_median=True)
    aAS = actionAngleStaeckel(pot=MWPotential2014, delta=np.mean(deltas))
    e, zmax, rperi, rap = aAS.EccZmaxRperiRap(sRpz[:, 0],
                                              svRvTvz[:, 0],
                                              svRvTvz[:, 1],
                                              sRpz[:, 2],
                                              svRvTvz[:, 2],
                                              sRpz[:, 1], delta=deltas)
    tcov = np.cov(np.dstack([e, zmax, rperi, rap])[0].T)
    errs = np.sqrt(np.diag(tcov))
    e_zmax_corr = tcov[0, 1] / (errs[0] * errs[1])
    e_rperi_corr = tcov[0, 2] / (errs[0] * errs[2])
    e_rap_corr = tcov[0, 3] / (errs[0] * errs[3])
    zmax_rperi_corr = tcov[1, 2] / (errs[1] * errs[2])
    zmax_rap_corr = tcov[1, 3] / (errs[1] * errs[3])
    rperi_rap_corr = tcov[2, 3] / (errs[2] * errs[3])
    e_err, zmax_err, rperi_err, rap_err = errs
    action = np.array(
        aAS.actionsFreqsAngles(sRpz[:, 0], svRvTvz[:, 0], svRvTvz[:, 1], sRpz[:, 2], svRvTvz[:, 2], sRpz[:, 1]))
    tcov_after_action = np.cov(action)
    errs = np.sqrt(np.diag(tcov_after_action))
    jr_lz_corr = tcov_after_action[0, 1] / (errs[0] * errs[1])
    jr_jz_corr = tcov_after_action[0, 2] / (errs[0] * errs[2])
    lz_jz_corr = tcov_after_action[1, 2] / (errs[1] * errs[2])
    jr_err, lz_err, jz_err, or_err, op_err, oz_err, tr_err, tphi_err, tz_err = errs

    Rc = np.array([rl(MWPotential2014, lz) for lz in action[1]]) * _R0
    Ec = (evaluatePotentials(MWPotential2014, Rc, 0.) + 0.5 * (action[1]) ** 2. / Rc ** 2.) * _v0 ** 2
    E = (evaluatePotentials(MWPotential2014, sRpz[:, 0], sRpz[:, 2], phi=sRpz[:, 1]) + np.sum(svRvTvz ** 2 / 2.,
                                                                                              axis=1)) * _v0 ** 2

    # galactocentric coord and vel uncertainty
    galcen_tcov = np.cov(np.dstack([sRpz[:, 0], sRpz[:, 1], sRpz[:, 2]])[0].T)
    galcen_errs = np.sqrt(np.diag(galcen_tcov))
    galr_err, galphi_err, galz_err = galcen_errs

    galcenv_tcov = np.cov(np.dstack([svRvTvz[:, 0], svRvTvz[:, 1], svRvTvz[:, 2]])[0].T)
    galcenv_errs = np.sqrt(np.diag(galcenv_tcov))
    galvr_err, galvt_err, galvz_err = galcenv_errs

    galvr_galvt_corr = galcenv_tcov[0, 1] / (galcenv_errs[0] * galcenv_errs[1])
    galvr_galvz_corr = galcenv_tcov[0, 2] / (galcenv_errs[0] * galcenv_errs[2])
    galvt_galvz_corr = galcenv_tcov[1, 2] / (galcenv_errs[1] * galcenv_errs[2])

    return np.nanmean(e), e_err, np.nanmean(zmax) * _R0, zmax_err * _R0, np.nanmean(
        rperi) * _R0, rperi_err * _R0, np.nanmean(rap) * _R0, rap_err * _R0, \
           e_zmax_corr, e_rperi_corr, e_rap_corr, zmax_rperi_corr, zmax_rap_corr, rperi_rap_corr, \
           np.nanmean(action[0]) * _R0 * _v0, jr_err * _R0 * _v0, np.nanmean(
        action[1]) * _R0 * _v0, lz_err * _R0 * _v0, np.nanmean(action[2]) * _R0 * _v0, jz_err * _R0 * _v0, \
           jr_lz_corr, jr_jz_corr, lz_jz_corr, \
           np.nanmean(action[3]) * _freq, or_err * _freq, np.nanmean(action[4]) * _freq, op_err * _freq, np.nanmean(
        action[5]) * _freq, oz_err * _freq, \
           np.nanmean(action[6]), tr_err, np.nanmean(action[7]), tphi_err, np.nanmean(action[8]), tz_err, \
           np.nanmean(Rc), np.nanstd(Rc), np.nanmean(E), np.nanstd(E), np.nanmean(E - Ec), np.nanstd(
        E - Ec), \
           np.nanmean(sRpz[:, 0]) * _R0, \
           np.nanmean(sRpz[:, 1]), \
           np.nanmean(sRpz[:, 2]) * _R0, \
           np.nanmean(svRvTvz[:, 0]) * _v0, \
           np.nanmean(svRvTvz[0, 1]) * _v0, \
           np.nanmean(svRvTvz[:, 2]) * _v0, \
           galr_err * _R0, \
           galphi_err, \
           galz_err * _R0, \
           galvr_err * _v0, \
           galvt_err * _v0, \
           galvz_err * _v0, \
           galvr_galvt_corr, \
           galvr_galvz_corr, \
           galvt_galvz_corr
예제 #10
0
    delta = (delta_x**2 + delta_y**2 + delta_z**2)**0.5
    plt.semilogy(sun.time(ts), delta*1000)



#action angles portion:
#actionanglesAdiabatic for MWpotential2014
#if we want it for comparison:
#aAA_sun = actionAngleAdiabatic(pot=MWPotential2014)
#js_aaa_sun = aAA_sun(sun.R(ts),sun.vR(ts),sun.vT(ts),sun.z(ts),sun.vz(ts))
#

#convert into natural shit
ro = 8
vo = 220
delta_sun = estimateDeltaStaeckel(MWPotential2014,(sun.R(ts))/ro, (sun.z(ts))/vo)
aAS_sun = actionAngleStaeckel(pot=MWPotential2014,delta = delta_sun)
js_sun = aAS_sun((sun.R())/ro,(sun.vR())/vo,(sun.vT())/vo,(sun.z())/ro,(sun.vz())/vo)
mean_js = np.array([js_sun[0].mean(), js_sun[1].mean(), js_sun[2].mean()])

print("going for the big fella")
for o in orbits:
    try:
        #quick method: only first instance
        delta_o = estimateDeltaStaeckel(MWPotential2014,(o.R(ts))/ro,(o.z(ts))/ro)
    #    plt.plot(js[0] - js_sun[0], ts)
        aAS = actionAngleStaeckel(pot=MWPotential2014,delta = delta_o)
        js_o = aAS((o.R())/ro,(o.vR())/vo,(o.vT())/vo,(o.z())/ro,(o.vz())/vo)
        mean_o_js = np.array([js_o[0].mean(), js_o[1].mean(), js_o[2].mean()])
        mean_js = np.vstack([mean_js, mean_o_js])
    except:
예제 #11
0
def computeKinematics(ra,
                      dec,
                      dist,
                      pm_ra,
                      pm_dec,
                      rv,
                      R0=8.,
                      Z0=20.,
                      V0=240.,
                      Vlsd=[11.1, 12.24, 7.25]):
    '''
    Compute kinematics

    Parameters
    ----------
    ra : float
        Right ascension of the star (in degree)
    dec : float
        Declination of the star (in degree)
    dist : float
        Distance to the star (in kpc)
    pm_ra : float
        Proper motion in right ascension * cos(dec) (in mas/yr)
    pm_dec : float
        Proper motion in declination (in mas/yr)
    rv : float
        Radial velocity (km/s)
    R0 : float
        Radial distance of the Sun from the Galactic center (in kpc)
    Z0 : float
        Height of the Sun above the Galactic plane (in pc)
    V0 : float
        Rotational velocity of the Sun (in km/s)
    Vlsd : list
        Velocity of the Sun w.r.t the local standard of rest (in km/s)

    Return
    ------
    pos : array
        Position in galactocentric cylindrical coordinate 
    vel : array
        Velocity in galactocentric cylindrical coordinate
    act : array
        Action in galactocentric cylindrical coordinate
    orb : array
        Orbital parameters (maximum height and eccentricity) 
    '''
    #-----------------------------------------------------------------------------------------

    # Tranform to galactocentric cylindrical coordinate
    v_sun = coord.CartesianDifferential([Vlsd[0], V0 + Vlsd[1], Vlsd[2]] *
                                        u.km / u.s)
    cs = coord.SkyCoord(ra=ra * u.deg,
                        dec=dec * u.deg,
                        distance=dist * u.kpc,
                        pm_ra_cosdec=pm_ra * u.mas / u.yr,
                        pm_dec=pm_dec * u.mas / u.yr,
                        radial_velocity=rv * u.km / u.s,
                        galcen_distance=R0 * u.kpc,
                        galcen_v_sun=v_sun,
                        z_sun=Z0 * u.pc)
    gc = coord.Galactocentric(galcen_distance=R0 * u.kpc,
                              galcen_v_sun=v_sun,
                              z_sun=Z0 * u.pc)
    cs = cs.transform_to(gc)
    cs.representation_type = 'cylindrical'
    cs.differential_type = 'cylindrical'

    # Position in cylindrical coordinate
    rho, phi, z = cs.rho.to(u.kpc), cs.phi.to(u.rad), cs.z.to(u.kpc)
    pos = np.zeros(1,
                   dtype={
                       'names': ['rho', 'phi', 'z'],
                       'formats': [float, float, float]
                   })
    pos['rho'][0], pos['phi'][0], pos['z'][0] = rho.value, phi.value, z.value

    # Velocity in cylindrical coordinate
    vrho = cs.d_rho.to(u.km / u.s)
    vphi = (cs.d_phi.to(u.mas / u.yr).value * 4.74047 *
            cs.rho.to(u.kpc).value * u.km / u.s)
    vz = cs.d_z.to(u.km / u.s)
    vel = np.zeros(1,
                   dtype={
                       'names': ['rho', 'phi', 'z'],
                       'formats': [float, float, float]
                   })
    vel['rho'][0], vel['phi'][0], vel['z'][
        0] = vrho.value, vphi.value, vz.value

    # Compute actions
    delta = estimateDeltaStaeckel(mw, rho, z)
    aAS = actionAngleStaeckel(pot=mw,
                              delta=delta,
                              c=True,
                              ro=R0 * u.kpc,
                              vo=V0 * u.km / u.s)
    jrho, jphi, jz = aAS(rho, vrho, vphi, z, vz, fixed_quad=True)
    act = np.zeros(1,
                   dtype={
                       'names': ['rho', 'phi', 'z'],
                       'formats': [float, float, float]
                   })
    act['rho'][0], act['phi'][0], act['z'][
        0] = jrho.value, jphi.value, jz.value

    # Compute maximum height and eccentricity
    o = Orbit([rho, vrho, vphi, z, vz], ro=R0 * u.kpc, vo=V0 * u.km / u.s)
    np.seterr(over='raise')
    zmax, ecc = -1., -1.
    try:
        zmax = o.zmax(pot=mw, delta=delta, analytic=True, type='staeckel')
    except FloatingPointError:
        pass
    try:
        ecc = o.e(pot=mw, delta=delta, analytic=True, type='staeckel')
    except FloatingPointError:
        pass
    orb = np.zeros(1,
                   dtype={
                       'names': ['zmax', 'ecc'],
                       'formats': [float, float]
                   })
    orb['zmax'][0], orb['ecc'][0] = zmax.value, ecc

    return pos, vel, act, orb
예제 #12
0
def action_analysis(cls):
    try:
        fd = open("data/db_9cl_orbits_good.pkl", "rb")
        all_orbits = cp.load(fd)
        fd.close()
    except:
        ucac_dict = ucac_pms()
        position_dict = grab_other_spatials(cls)[0]
        distance_dict = grab_other_spatials(cls)[1]
        all_orbits = []
        for cl in cls:
            cluster_orbits = []
            for star in cl:
                try:
                    ra = float(position_dict[star][0])
                    dec = float(position_dict[star][1])
                    dist = float(distance_dict[star])
                    pmRA = float(ucac_dict[star][0])
                    pmDec = float(ucac_dict[star][2])
                    Vlos = float(position_dict[star][2])
                    #only attach where proper motions are available
                    if ucac_dict[star][-1] == '1':
                        cluster_orbits.append(Orbit(vxvv=[ra,dec,dist,pmRA,pmDec,Vlos],radec=True,ro=8.,vo=220., solarmotion = "schoenrich"))
                except:
                    print("bad egg, spitting out")
                    continue
                #only attach where proper motions are available
            all_orbits.append(cluster_orbits)
            print("ticking: ", len(all_orbits))
        fd = open("data/db_9cl_orbits_good.pkl", "wb")
        cp.dump(all_orbits, fd)
        fd.close()
    
    ts = np.linspace(0,100,10000)
    mwp= MWPotential2014
    #action angles yay!
    #the following gets confusing because we speak of "means" twice
    #we want the mean J over each individual orbit, but to measure the spread in the cluster
    #we compare to the mean of each J
    ro = 8
    vo = 220
    all_actions = []
    fig = 1
    for cluster_orbits in all_orbits:
        all_js = np.array([])
        for o in cluster_orbits:
            o.integrate(ts,mwp,method='odeint')
#            plt.plot(o.R(ts), o.z(ts))
            try:
                delta_o = estimateDeltaStaeckel(MWPotential2014,(o.R(ts))/ro,(o.z(ts))/ro)
                aAS = actionAngleStaeckel(pot=MWPotential2014,delta = delta_o)
                js_o = aAS((o.R())/ro,(o.vR())/vo,(o.vT())/vo,(o.z())/ro,(o.vz())/vo)
#                delta_b = estimateBIsochrone(MWPotential2014, (o.R(ts))/ro,(o.z(ts))/ro)
#                delta_b = delta_b[1]
#                aAIA = actionAngleIsochroneApprox(pot=MWPotential2014,b = delta_b)
#                js_o = aAIA((o.R())/ro,(o.vR())/vo,(o.vT())/vo,(o.z())/ro,(o.vz())/vo, nonaxi = True)
#                print(js_o)
                if all_js.shape == (0,):
                    all_js = js_o
                else:
                    all_js = np.vstack([all_js, js_o])
            except:
                print("found unbound, discarded")    
        print(np.array(all_js).shape)
        all_actions.append(all_js)
#        plt.xlabel("R distance (kpc)")
#        plt.ylabel("z distance (kpc)")
#        plt.xlim(0, 20)
#        plt.ylim(-5, 5)
#        plt.title("Cluster " + str(fig)+ " Rz" + " Orbits")
#        fn = open("dbcl_" + str(fig) + "_Rz" + ".png", "wb")
#        plt.savefig("dbcl_" + str(fig) + "_Rz" + ".png")
#        fn.close()
#        plt.close()
        fig += 1
    return all_actions
예제 #13
0
    def compute_AA(self, potential, dt=0.01 * u.Myr, AAi=None, method='S'):
        '''
            Compute action angle coordinates for a propagated orbit.
        '''
        from galpy.orbit import Orbit

        if (AAi is None):
            AAi = range(self.size)

        AAi = np.atleast_1d(AAi)
        # Integration time step
        self.dt = dt
        nsteps = np.ceil((self.tflight / self.dt).to('1').value)
        nsteps[nsteps < 100] = 100

        # Initialize position in cylindrical coords
        rho = self.r0 * np.sin(self.theta0)
        z = self.r0 * np.cos(self.theta0)
        phi = self.phi0

        #... and velocity
        vR = self.v0 * np.sin(self.thetav0) * np.cos(self.phiv0)
        vT = self.v0 * np.sin(self.thetav0) * np.sin(self.phiv0)
        vz = self.v0 * np.cos(self.thetav0)

        # Initialize empty arrays to save orbit data and integration steps
        self.orbits = [None] * self.size
        AA = [np.zeros((3, int(nsteps[i]))) for i in AAi]
        if (method != 'S'):
            from galpy.actionAngle import actionAngleIsochroneApprox, actionAngleAdiabatic
            aAA = actionAngleIsochroneApprox(pot=potential,
                                             c=True,
                                             ro=8.,
                                             vo=220.)
        else:
            from galpy.actionAngle import estimateDeltaStaeckel, actionAngleStaeckel

        k = 0
        for i in AAi:
            ts = np.linspace(0, 1, nsteps[i]) * self.tflight[i]

            self.orbits[i] = Orbit(
                vxvv=[rho[i], vR[i], vT[i], z[i], vz[i], phi[i]],
                solarmotion=self.solarmotion)
            self.orbits[i].integrate(ts, potential, method='dopr54_c')

            if (method == 'S'):
                delta = estimateDeltaStaeckel(potential,
                                              self.orbits[i].R(ts) * u.kpc,
                                              self.orbits[i].z(ts) * u.kpc)
                aAA = actionAngleStaeckel(pot=potential,
                                          c=True,
                                          ro=8.,
                                          vo=220.,
                                          delta=delta)

            AA[k] = aAA(self.orbits[i].R(ts) * u.kpc,
                        self.orbits[i].vR(ts) * u.km / u.s,
                        self.orbits[i].vT(ts) * u.km / u.s,
                        self.orbits[i].z(ts) * u.kpc,
                        self.orbits[i].vz(ts) * u.km / u.s)
            #AA[k] = aAA(self.orbits[i].R(ts)/8, self.orbits[i].vR(ts)/220, self.orbits[i].vT(ts)/220, self.orbits[i].z(ts)/8, self.orbits[i].vz(ts)/220)
            k += 1

        return AA