Exemple #1
0
def test_actionConservation():

    #_____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')

    #_____Setup ActionAngle object and calculate actions (Staeckel approximation)_____
    aAS = actionAngleStaeckel(pot=pot, delta=Delta, c=True)
    jrs, lzs, jzs = aAS(o.R(ts), o.vR(ts), o.vT(ts), o.z(ts), o.vz(ts))

    assert numpy.all(numpy.fabs(jrs - jrs[0]) < 10.**-8.), \
        'Radial action is not conserved along orbit.'

    assert numpy.all(numpy.fabs(lzs - lzs[0]) < 10.**-8.), \
        'Angular momentum is not conserved along orbit.'

    assert numpy.all(numpy.fabs(jzs - jzs[0]) < 10.**-8.), \
        'Vertical action is not conserved along orbit.'

    return None
Exemple #2
0
def test_qdf():
    from galpy.df import quasiisothermaldf
    from galpy.potential import MWPotential2014
    from galpy.actionAngle import actionAngleStaeckel
    # Setup actionAngle instance for action calcs
    aAS= actionAngleStaeckel(pot=MWPotential2014,delta=0.45,
                             c=True)
    # Quasi-iso df w/ hr=1/3, hsr/z=1, sr(1)=0.2, sz(1)=0.1
    df= quasiisothermaldf(1./3.,0.2,0.1,1.,1.,aA=aAS,
                          pot=MWPotential2014)
    # Evaluate DF w/ R,vR,vT,z,vz
    df(0.9,0.1,0.8,0.05,0.02)
    assert numpy.fabs(df(0.9,0.1,0.8,0.05,0.02)-numpy.array([ 123.57158928])) < 10.**-4., 'qdf does not behave as expected'
    # Evaluate DF w/ Orbit instance, return ln
    from galpy.orbit import Orbit
    df(Orbit([0.9,0.1,0.8,0.05,0.02]),log=True)
    assert numpy.fabs(df(Orbit([0.9,0.1,0.8,0.05,0.02]),log=True)-numpy.array([ 4.81682066])) < 10.**-4., 'qdf does not behave as expected'
    # Evaluate DF marginalized over vz
    df.pvRvT(0.1,0.9,0.9,0.05)
    assert numpy.fabs(df.pvRvT(0.1,0.9,0.9,0.05)-23.273310451852243) < 10.**-4., 'qdf does not behave as expected'
    # Evaluate DF marginalized over vR,vT
    df.pvz(0.02,0.9,0.05)
    assert numpy.fabs(df.pvz(0.02,0.9,0.05)-50.949586235238172) < 10.**-4., 'qdf does not behave as expected'
    # Calculate the density
    df.density(0.9,0.05)
    assert numpy.fabs(df.density(0.9,0.05)-12.73725936526167) < 10.**-4., 'qdf does not behave as expected'
    # Estimate the DF's actual density scale length at z=0
    df.estimate_hr(0.9,0.)
    assert numpy.fabs(df.estimate_hr(0.9,0.)-0.322420336223) < 10.**-2., 'qdf does not behave as expected'
    # Estimate the DF's actual surface-density scale length
    df.estimate_hr(0.9,None)
    assert numpy.fabs(df.estimate_hr(0.9,None)-0.38059909132766462) < 10.**-4., 'qdf does not behave as expected'
    # Estimate the DF's density scale height
    df.estimate_hz(0.9,0.02)
    assert numpy.fabs(df.estimate_hz(0.9,0.02)-0.064836202345657207) < 10.**-4., 'qdf does not behave as expected'
    # Calculate the mean velocities
    df.meanvR(0.9,0.05), df.meanvT(0.9,0.05), 
    df.meanvz(0.9,0.05)
    assert numpy.fabs(df.meanvR(0.9,0.05)-3.8432265354618213e-18) < 10.**-4., 'qdf does not behave as expected'
    assert numpy.fabs(df.meanvT(0.9,0.05)-0.90840425173325279) < 10.**-4., 'qdf does not behave as expected'
    assert numpy.fabs(df.meanvz(0.9,0.05)+4.3579787517991084e-19) < 10.**-4., 'qdf does not behave as expected'
    # Calculate the velocity dispersions
    from numpy import sqrt
    sqrt(df.sigmaR2(0.9,0.05)), sqrt(df.sigmaz2(0.9,0.05))
    assert numpy.fabs(sqrt(df.sigmaR2(0.9,0.05))-0.22695537077102387) < 10.**-4., 'qdf does not behave as expected'
    assert numpy.fabs(sqrt(df.sigmaz2(0.9,0.05))-0.094215523962105044) < 10.**-4., 'qdf does not behave as expected'
    # Calculate the tilt of the velocity ellipsoid
    # 2017/10-28: CHANGED bc tilt now returns angle in rad, no longer in deg
    df.tilt(0.9,0.05)
    assert numpy.fabs(df.tilt(0.9,0.05)-2.5166061974413765/180.*numpy.pi) < 10.**-4., 'qdf does not behave as expected'
    # Calculate a higher-order moment of the velocity DF
    df.vmomentdensity(0.9,0.05,6.,2.,2.,gl=True)
    assert numpy.fabs(df.vmomentdensity(0.9,0.05,6.,2.,2.,gl=True)-0.0001591100892366438) < 10.**-4., 'qdf does not behave as expected'
    # Sample velocities at given R,z, check mean
    numpy.random.seed(1)
    vs= df.sampleV(0.9,0.05,n=500); mvt= numpy.mean(vs[:,1])
    assert numpy.fabs(numpy.mean(vs[:,0])) < 0.05 # vR
    assert numpy.fabs(mvt-df.meanvT(0.9,0.05)) < 0.01 #vT
    assert numpy.fabs(numpy.mean(vs[:,2])) < 0.05 # vz
    return None
def test_actionConservation():

    #_____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')

    #_____Setup ActionAngle object and calculate actions (Staeckel approximation)_____
    aAS = actionAngleStaeckel(pot=pot,delta=Delta,c=True)
    jrs,lzs,jzs = aAS(o.R(ts),o.vR(ts),o.vT(ts),o.z(ts),o.vz(ts))

    assert numpy.all(numpy.fabs(jrs - jrs[0]) < 10.**-8.), \
        'Radial action is not conserved along orbit.'

    assert numpy.all(numpy.fabs(lzs - lzs[0]) < 10.**-8.), \
        'Angular momentum is not conserved along orbit.'

    assert numpy.all(numpy.fabs(jzs - jzs[0]) < 10.**-8.), \
        'Vertical action is not conserved along orbit.'

    return None
def integrate_and_compare(orbit,
                          pot=MWPotential2014,
                          deltapot=MWPotential2014,
                          ts=None,
                          return_delta=False):
    delta = estimate_delta(orbit, pot=deltapot, ts=np.linspace(0., 20., 30))
    if not np.isfinite(delta):
        print('estimateDelta returned NaN - assuming 0.4')
        delta = 0.4
    if ts is None:
        Tp = np.fabs(azimuthal_period(orbit, pot=pot, delta=delta))
        if not np.isfinite(Tp):
            if return_delta:
                return [np.nan, np.nan, np.nan,
                        np.nan], [np.nan, np.nan, np.nan, np.nan], np.nan
            return [np.nan, np.nan, np.nan,
                    np.nan], [np.nan, np.nan, np.nan, np.nan]
    aAS = actionAngleStaeckel(pot=pot, delta=delta)
    ana_param = aAS.EccZmaxRperiRap(orbit)
    if ts is None:
        ts = np.arange(0., 20. * Tp, 0.01)
    orbit.integrate(ts, pot)
    int_param = [orbit.e(), orbit.zmax(), orbit.rperi(), orbit.rap()]
    if return_delta:
        return ana_param, int_param, delta
    return ana_param, int_param
Exemple #5
0
def test_actionAngleTorus_Staeckel_actions():
    from galpy.potential import KuzminKutuzovStaeckelPotential
    from galpy.actionAngle import actionAngleTorus, \
        actionAngleStaeckel
    delta = 1.2
    kp = KuzminKutuzovStaeckelPotential(normalize=1., Delta=delta)
    aAS = actionAngleStaeckel(pot=kp, delta=delta, c=True)
    tol = -3.
    aAT = actionAngleTorus(pot=kp, tol=tol)
    jr, jphi, jz = 0.075, 1.1, 0.05
    angler = numpy.array([0.])
    anglephi = numpy.array([numpy.pi])
    anglez = numpy.array([numpy.pi / 2.])
    # Calculate position from aAT
    RvR = aAT(jr, jphi, jz, angler, anglephi, anglez).T
    # Calculate actions from aAI
    ji = aAS(*RvR)
    djr = numpy.fabs((ji[0] - jr) / jr)
    dlz = numpy.fabs((ji[1] - jphi) / jphi)
    djz = numpy.fabs((ji[2] - jz) / jz)
    assert djr < 10.**tol, 'actionAngleTorus and actionAngleStaeckel applied to Staeckel potential disagree for Jr at %f%%' % (
        djr * 100.)
    assert dlz < 10.**tol, 'actionAngleTorus and actionAngleStaeckel applied to Staeckel potential disagree for Jr at %f%%' % (
        dlz * 100.)
    assert djz < 10.**tol, 'actionAngleTorus and actionAngleStaeckel applied to Staeckel potential disagree for Jr at %f%%' % (
        djz * 100.)
    return None
def test_qdf():
    from galpy.df import quasiisothermaldf
    from galpy.potential import MWPotential2014
    from galpy.actionAngle import actionAngleStaeckel
    # Setup actionAngle instance for action calcs
    aAS= actionAngleStaeckel(pot=MWPotential2014,delta=0.45,
                             c=True)
    # Quasi-iso df w/ hr=1/3, hsr/z=1, sr(1)=0.2, sz(1)=0.1
    df= quasiisothermaldf(1./3.,0.2,0.1,1.,1.,aA=aAS,
                          pot=MWPotential2014)
    # Evaluate DF w/ R,vR,vT,z,vz
    df(0.9,0.1,0.8,0.05,0.02)
    assert numpy.fabs(df(0.9,0.1,0.8,0.05,0.02)-numpy.array([ 123.57158928])) < 10.**-4., 'qdf does not behave as expected'
    # Evaluate DF w/ Orbit instance, return ln
    from galpy.orbit import Orbit
    df(Orbit([0.9,0.1,0.8,0.05,0.02]),log=True)
    assert numpy.fabs(df(Orbit([0.9,0.1,0.8,0.05,0.02]),log=True)-numpy.array([ 4.81682066])) < 10.**-4., 'qdf does not behave as expected'
    # Evaluate DF marginalized over vz
    df.pvRvT(0.1,0.9,0.9,0.05)
    assert numpy.fabs(df.pvRvT(0.1,0.9,0.9,0.05)-23.273310451852243) < 10.**-4., 'qdf does not behave as expected'
    # Evaluate DF marginalized over vR,vT
    df.pvz(0.02,0.9,0.05)
    assert numpy.fabs(df.pvz(0.02,0.9,0.05)-50.949586235238172) < 10.**-4., 'qdf does not behave as expected'
    # Calculate the density
    df.density(0.9,0.05)
    assert numpy.fabs(df.density(0.9,0.05)-12.73725936526167) < 10.**-4., 'qdf does not behave as expected'
    # Estimate the DF's actual density scale length at z=0
    df.estimate_hr(0.9,0.)
    assert numpy.fabs(df.estimate_hr(0.9,0.)-0.322420336223) < 10.**-2., 'qdf does not behave as expected'
    # Estimate the DF's actual surface-density scale length
    df.estimate_hr(0.9,None)
    assert numpy.fabs(df.estimate_hr(0.9,None)-0.38059909132766462) < 10.**-4., 'qdf does not behave as expected'
    # Estimate the DF's density scale height
    df.estimate_hz(0.9,0.02)
    assert numpy.fabs(df.estimate_hz(0.9,0.02)-0.064836202345657207) < 10.**-4., 'qdf does not behave as expected'
    # Calculate the mean velocities
    df.meanvR(0.9,0.05), df.meanvT(0.9,0.05), 
    df.meanvz(0.9,0.05)
    assert numpy.fabs(df.meanvR(0.9,0.05)-3.8432265354618213e-18) < 10.**-4., 'qdf does not behave as expected'
    assert numpy.fabs(df.meanvT(0.9,0.05)-0.90840425173325279) < 10.**-4., 'qdf does not behave as expected'
    assert numpy.fabs(df.meanvz(0.9,0.05)+4.3579787517991084e-19) < 10.**-4., 'qdf does not behave as expected'
    # Calculate the velocity dispersions
    from numpy import sqrt
    sqrt(df.sigmaR2(0.9,0.05)), sqrt(df.sigmaz2(0.9,0.05))
    assert numpy.fabs(sqrt(df.sigmaR2(0.9,0.05))-0.22695537077102387) < 10.**-4., 'qdf does not behave as expected'
    assert numpy.fabs(sqrt(df.sigmaz2(0.9,0.05))-0.094215523962105044) < 10.**-4., 'qdf does not behave as expected'
    # Calculate the tilt of the velocity ellipsoid
    df.tilt(0.9,0.05)
    assert numpy.fabs(df.tilt(0.9,0.05)-2.5166061974413765) < 10.**-4., 'qdf does not behave as expected'
    # Calculate a higher-order moment of the velocity DF
    df.vmomentdensity(0.9,0.05,6.,2.,2.,gl=True)
    assert numpy.fabs(df.vmomentdensity(0.9,0.05,6.,2.,2.,gl=True)-0.0001591100892366438) < 10.**-4., 'qdf does not behave as expected'
    # Sample velocities at given R,z, check mean
    numpy.random.seed(1)
    vs= df.sampleV(0.9,0.05,n=500); mvt= numpy.mean(vs[:,1])
    assert numpy.fabs(numpy.mean(vs[:,0])) < 0.05 # vR
    assert numpy.fabs(mvt-df.meanvT(0.9,0.05)) < 0.01 #vT
    assert numpy.fabs(numpy.mean(vs[:,2])) < 0.05 # vz
    return None
Exemple #7
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
Exemple #8
0
def test_actionAngleTorus_Staeckel_freqsAngles():
    from galpy.potential import KuzminKutuzovStaeckelPotential
    from galpy.actionAngle import actionAngleTorus, \
        actionAngleStaeckel
    delta = 1.2
    kp = KuzminKutuzovStaeckelPotential(normalize=1., Delta=delta)
    aAS = actionAngleStaeckel(pot=kp, delta=delta, c=True)
    tol = -3.
    aAT = actionAngleTorus(pot=kp, tol=tol)
    jr, jphi, jz = 0.075, 1.1, 0.05
    angler = numpy.array([0.1]) + numpy.linspace(0., numpy.pi, 101)
    angler = angler % (2. * numpy.pi)
    anglephi = numpy.array([numpy.pi]) + numpy.linspace(0., numpy.pi, 101)
    anglephi = anglephi % (2. * numpy.pi)
    anglez = numpy.array([numpy.pi / 2.]) + numpy.linspace(0., numpy.pi, 101)
    anglez = anglez % (2. * numpy.pi)
    # Calculate position from aAT
    RvRom = aAT.xvFreqs(jr, jphi, jz, angler, anglephi, anglez)
    # Calculate actions, frequencies, and angles from aAI
    ws = aAS.actionsFreqsAngles(*RvRom[0].T)
    dOr = numpy.fabs((ws[3] - RvRom[1]))
    dOp = numpy.fabs((ws[4] - RvRom[2]))
    dOz = numpy.fabs((ws[5] - RvRom[3]))
    dar = numpy.fabs((ws[6] - angler))
    dap = numpy.fabs((ws[7] - anglephi))
    daz = numpy.fabs((ws[8] - anglez))
    dar[dar > numpy.pi] -= 2. * numpy.pi
    dar[dar < -numpy.pi] += 2. * numpy.pi
    dap[dap > numpy.pi] -= 2. * numpy.pi
    dap[dap < -numpy.pi] += 2. * numpy.pi
    daz[daz > numpy.pi] -= 2. * numpy.pi
    daz[daz < -numpy.pi] += 2. * numpy.pi
    assert numpy.all(
        dOr < 10.**tol
    ), 'actionAngleTorus and actionAngleStaeckel applied to Staeckel potential disagree for Or at %f%%' % (
        numpy.nanmax(dOr) * 100.)
    assert numpy.all(
        dOp < 10.**tol
    ), 'actionAngleTorus and actionAngleStaeckel applied to Staeckel potential disagree for Ophi at %f%%' % (
        numpy.nanmax(dOp) * 100.)
    assert numpy.all(
        dOz < 10.**tol
    ), 'actionAngleTorus and actionAngleStaeckel applied to Staeckel potential disagree for Oz at %f%%' % (
        numpy.nanmax(dOz) * 100.)
    assert numpy.all(
        dar < 10.**tol
    ), 'actionAngleTorus and actionAngleStaeckel applied to Staeckel potential disagree for ar at %f' % (
        numpy.nanmax(dar))
    assert numpy.all(
        dap < 10.**tol
    ), 'actionAngleTorus and actionAngleStaeckel applied to Staeckel potential disagree for aphi at %f' % (
        numpy.nanmax(dap))
    assert numpy.all(
        daz < 10.**tol
    ), 'actionAngleTorus and actionAngleStaeckel applied to Staeckel potential disagree for az at %f' % (
        numpy.nanmax(daz))
    return None
def plot_aagrid(plotfilename1,plotfilename2):
    #Setup orbit
    E, Lz= -1.25, 0.6
    o= Orbit([0.8,0.3,Lz/0.8,0.,numpy.sqrt(2.*(E-evalPot(0.8,0.,MWPotential2014)-(Lz/0.8)**2./2.-0.3**2./2.)),0.])
    delta= 0.434
    #Integrate the orbit, setup Staeckel already to calculate the period
    aAS= actionAngleStaeckel(pot=MWPotential2014,delta=delta,c=True)
    orbt= 2.*numpy.pi/aAS.actionsFreqs(o)[4]  
    norb= 5.
    nt= 501
    ts= numpy.linspace(0.,norb*orbt,nt)
    o.integrate(ts,MWPotential2014,method='symplec4_c')
    #First do adiabatic
    aAA= actionAngleAdiabatic(pot=MWPotential2014,gamma=1.,c=True)
    aAAG= actionAngleAdiabaticGrid(pot=MWPotential2014,gamma=1.,c=True,
                                   nR=31,nEz=31,nEr=51,nLz=51)
    jfa= aAA(o.R(ts),o.vR(ts),o.vT(ts),o.z(ts),o.vz(ts),o.phi(ts))
    jfag= aAAG(o.R(ts),o.vR(ts),o.vT(ts),o.z(ts),o.vz(ts),o.phi(ts))
    #First do adiabatic
    #aAS already setup
    aASG= actionAngleStaeckelGrid(pot=MWPotential2014,delta=delta,c=True,
                                  nE=51,npsi=51,nLz=51)
    jfs= aAS(o.R(ts),o.vR(ts),o.vT(ts),o.z(ts),o.vz(ts),o.phi(ts))
    jfsg= aASG(o.R(ts),o.vR(ts),o.vT(ts),o.z(ts),o.vz(ts),o.phi(ts))
    bovy_plot.bovy_print()
    line1= bovy_plot.bovy_plot(jfa[0],jfa[2],'r.',
                               xrange=[0.045,0.055],
                               yrange=[0.0075,0.011],
                               xlabel=r'$J_R$',ylabel=r'$J_z$',zorder=2)
    line2= bovy_plot.bovy_plot(jfag[0],jfag[2],'rx',overplot=True,zorder=1)
    bovy_plot.bovy_plot(jfs[0],jfs[2],'k,',overplot=True)
    pyplot.legend((line1[0],line2[0]),
                  (r'$\mathrm{\texttt{actionAngleAdiabatic}}$',
                   r'$\mathrm{\texttt{actionAngleAdiabaticGrid}}$',),
                  loc='upper right',#bbox_to_anchor=(.91,.375),
                  numpoints=1,
                  prop={'size':14},
                  frameon=False)
    bovy_plot.bovy_end_print(plotfilename1)
    #Zoom of Staeckel
    line1= bovy_plot.bovy_plot(jfs[0],jfs[2],'k.',
                               xrange=[0.05025,0.05145],
                               yrange=[0.0086,0.00933],
                               xlabel=r'$J_R$',ylabel=r'$J_z$')
    line2= bovy_plot.bovy_plot(jfsg[0],jfsg[2],'kx',overplot=True)
    pyplot.legend((line1[0],line2[0]),
                  (r'$\mathrm{\texttt{actionAngleStaeckel}}$',
                   r'$\mathrm{\texttt{actionAngleStaeckelGrid}}$',),
                  loc='upper right',#bbox_to_anchor=(.91,.375),
                  numpoints=1,
                  prop={'size':14},
                  frameon=False)
    bovy_plot.bovy_end_print(plotfilename2)
    return None
def azimuthal_period(orbit, pot=MWPotential2014, delta=0.375):
    ''' 
    find the azimuthal period of an orbit using a given estimate of delta
    '''
    aAS = actionAngleStaeckel(pot=pot, delta=delta)
    _, _, _, _, Op, _ = aAS.actionsFreqs(
        orbit)  # computes actions/freqs, only need azimuthal
    if Op == 9999.99:
        return np.nan
    Tp = 2. * numpy.pi / Op
    return Tp
Exemple #11
0
def test_call_diffinoutputs():
    qdf= quasiisothermaldf(1./4.,0.2,0.1,1.,1.,
                           pot=MWPotential,aA=aAS,cutcounter=True)
    #when specifying rg etc., first get these from a previous output
    val, trg, tkappa, tnu, tOmega= qdf((0.03,0.9,0.02),_return_freqs=True)
    #First check that just supplying these again works
    assert numpy.fabs(val-qdf((0.03,0.9,0.02),rg=trg,kappa=tkappa,nu=tnu,
                              Omega=tOmega)) < 10.**-8., 'qdf calls w/ rg, and frequencies specified and w/ not specified do not agrees'
    #Also calculate the frequencies
    assert numpy.fabs(val-qdf((0.03,0.9,0.02),rg=trg,
                              kappa=epifreq(MWPotential,trg),
                              nu=verticalfreq(MWPotential,trg),
                              Omega=omegac(MWPotential,trg))) < 10.**-8., 'qdf calls w/ rg, and frequencies specified and w/ not specified do not agrees'
    #Also test _return_actions
    val, jr,lz,jz= qdf(0.9,0.1,0.95,0.1,0.08,_return_actions=True)
    assert numpy.fabs(val-qdf((jr,lz,jz))) < 10.**-8., 'qdf call w/ R,vR,... and actions specified do not agree'
    acs= aAS(0.9,0.1,0.95,0.1,0.08)
    assert numpy.fabs(acs[0]-jr) < 10.**-8., 'direct calculation of jr and that returned from qdf.__call__ does not agree'
    assert numpy.fabs(acs[1]-lz) < 10.**-8., 'direct calculation of lz and that returned from qdf.__call__ does not agree'
    assert numpy.fabs(acs[2]-jz) < 10.**-8., 'direct calculation of jz and that returned from qdf.__call__ does not agree'
    #Test unbound orbits
    #Find unbound orbit, new qdf s.t. we can get UnboundError (only with 
    taAS= actionAngleStaeckel(pot=MWPotential,c=False,delta=0.5)
    qdfnc= quasiisothermaldf(1./4.,0.2,0.1,1.,1.,
                             pot=MWPotential,
                             aA=taAS,
                             cutcounter=True)
    from galpy.actionAngle import UnboundError
    try: acs= taAS(0.9,10.,-20.,0.1,10.)
    except UnboundError: pass
    else: 
        print(acs)
        raise AssertionError('Test orbit in qdf that is supposed to be unbound is not')
    assert qdfnc(0.9,10.,-20.,0.1,10.) < 10.**-10., 'unbound orbit does not return qdf equal to zero'
    #Test negative lz
    assert qdf((0.03,-0.1,0.02)) < 10.**-8., 'qdf w/ cutcounter=True and negative lz does not return 0'
    assert qdf((0.03,-0.1,0.02),log=True) <= numpy.finfo(numpy.dtype(numpy.float64)).min+1., 'qdf w/ cutcounter=True and negative lz does not return 0'
    #Test func
    val= qdf((0.03,0.9,0.02))
    fval= qdf((0.03,0.9,0.02),func=lambda x,y,z: numpy.sin(x)*numpy.cos(y)\
                  *numpy.exp(z))
    assert numpy.fabs(val*numpy.sin(0.03)*numpy.cos(0.9)*numpy.exp(0.02)-
                      fval) < 10.**-8, 'qdf __call__ w/ func does not work as expected'  
    lfval= qdf((0.03,0.9,0.02),func=lambda x,y,z: numpy.sin(x)*numpy.cos(y)\
                   *numpy.exp(z),log=True)
    assert numpy.fabs(numpy.log(val)+numpy.log(numpy.sin(0.03)\
                                                   *numpy.cos(0.9)\
                                                   *numpy.exp(0.02))-
                      lfval) < 10.**-8, 'qdf __call__ w/ func does not work as expected'
    return None
def calc_actions(snapfile=None):
    #Directories
    snapdir= 'snaps/'
    basefilename= snapfile.split('.')[0]
    nsnap= len(glob.glob(os.path.join(snapdir,basefilename+'_*.dat')))
    print "Processing %i snapshots ..." % nsnap
    #Setup potential
    lp= potential.LogarithmicHaloPotential(normalize=1.,q=0.9)
    if False:
        aA= actionAngleStaeckel(pot=lp,delta=1.20,c=True)
        snapaadir= 'snaps_aas/'
    else:
        aA= actionAngleIsochroneApprox(pot=lp,b=0.8)
        snapaadir= 'snaps_aai/'
    #Run each snapshot
    if True:
        calcThese= []
        for ii in range(nsnap):
            csvfilename= os.path.join(snapaadir,basefilename+'_aa_%s.dat' % str(ii).zfill(5))
            if os.path.exists(csvfilename):
                #Don't recalculate those that have already been calculated
                nstart= int(subprocess.check_output(['wc','-l',csvfilename]).split(' ')[0])
                if nstart < 10000:
                    calcThese.append(ii)
            else:
                calcThese.append(ii)
        nsnap= len(calcThese)
    if len(calcThese) == 0:
        print "All done with everything ..."
        return None
    args= (aA,snapdir,basefilename,snapaadir)
    print "Using %i cpus ..." % (numpy.amin([64,nsnap,
                                             multiprocessing.cpu_count()]))
    dummy= multi.parallel_map((lambda x: indiv_calc_actions(x,
                                                            *args)),
                              calcThese,
#                              range(nsnap),
                              numcores=numpy.amin([64,nsnap,
                                                      multiprocessing.cpu_count()]))
    return None
Exemple #13
0
def calc_actions(R_kpc, phi_rad, z_kpc, vR_kms, vT_kms, vz_kms, verbose=False):
    _REFR0 = 8.  # [kpc]  --> galpy length unit
    _REFV0 = 220.  # [km/s] --> galpy velocity unit

    R = np.array([R_kpc, 8.1]) / _REFR0  # Galactocentric radius
    vR = np.array([vR_kms, 0.]) / _REFV0  # radial velocity
    phi = np.array([phi_rad, 0.])  # Galactocentric azimuth angle
    # (not needed for actions in axisymmetric potential)
    vT = np.array([vT_kms, 230.]) / _REFV0  # tangential velocity
    z = np.array([z_kpc, 0.1]) / _REFR0  # height above plane
    vz = np.array([vz_kms, 0.]) / _REFV0  # vertical velocity

    # delta = focal length of confocal coordinate system
    # Use C code (for speed)
    aAS = actionAngleStaeckel(pot=pot, delta=0.45, c=True)

    jR, lz, jz = aAS(R, vR, vT, z, vz)
    if verbose:
        print("Radial action J_R = ", jR[0]*_REFR0*_REFV0, "\t kpc km/s")
        print("Angular momentum L_z = ", lz[0]*_REFR0*_REFV0, "\t kpc km/s")
        print("Vertical action J_z = ", jz[0]*_REFR0*_REFV0, "\t kpc km/s")
    return jR[0]*_REFR0*_REFV0, lz[0]*_REFR0*_REFV0, jz[0]*_REFR0*_REFV0,
def estimate_orbit_params(orbit, pot=MWPotential2014, delta=0.375, c=True):
    '''
    use the staeckel approximation to estimate orbital parameters for an orbit
    '''
    try:
        if not c:
            aASS = actionAngleStaeckelSingle(orbit, pot=pot, delta=delta)
            umin, umax = aASS.calcUminUmax()
            vmin = aASS.calcVmin()
            rperi = bovy_coords.uv_to_Rz(umin,
                                         numpy.pi / 2.,
                                         delta=aASS._delta)[0]
            rap_tmp, zmax = bovy_coords.uv_to_Rz(umax, vmin, delta=aASS._delta)
            rap = numpy.sqrt(rap_tmp**2. + zmax**2.)
            e = (rap - rperi) / (rap + rperi)
            return [rperi, rap, zmax, e]
        else:
            aAS = actionAngleStaeckel(pot=pot, delta=delta)
            e, zmax, rperi, rap = aAS.EccZmaxRperiRap(orbit)
            return [rperi, rap, zmax, e]
    except UnboundError:
        return [np.nan, np.nan, np.nan, np.nan]
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
Exemple #16
0
def test_actionAngleTorus_Staeckel_freqsAngles():
    from galpy.potential import KuzminKutuzovStaeckelPotential
    from galpy.actionAngle import actionAngleTorus, \
        actionAngleStaeckel
    delta= 1.2
    kp= KuzminKutuzovStaeckelPotential(normalize=1.,Delta=delta)
    aAS= actionAngleStaeckel(pot=kp,delta=delta,c=True)
    tol= -3.
    aAT= actionAngleTorus(pot=kp,tol=tol)
    jr,jphi,jz= 0.075,1.1,0.05
    angler= numpy.array([0.1])+numpy.linspace(0.,numpy.pi,101)
    angler= angler % (2.*numpy.pi)
    anglephi= numpy.array([numpy.pi])+numpy.linspace(0.,numpy.pi,101)
    anglephi= anglephi % (2.*numpy.pi)
    anglez= numpy.array([numpy.pi/2.])+numpy.linspace(0.,numpy.pi,101)
    anglez= anglez % (2.*numpy.pi)
    # Calculate position from aAT
    RvRom= aAT.xvFreqs(jr,jphi,jz,angler,anglephi,anglez)
    # Calculate actions, frequencies, and angles from aAI
    ws= aAS.actionsFreqsAngles(*RvRom[0].T)
    dOr= numpy.fabs((ws[3]-RvRom[1]))
    dOp= numpy.fabs((ws[4]-RvRom[2]))
    dOz= numpy.fabs((ws[5]-RvRom[3]))
    dar= numpy.fabs((ws[6]-angler))
    dap= numpy.fabs((ws[7]-anglephi))
    daz= numpy.fabs((ws[8]-anglez))
    dar[dar > numpy.pi]-= 2.*numpy.pi
    dar[dar < -numpy.pi]+= 2.*numpy.pi
    dap[dap > numpy.pi]-= 2.*numpy.pi
    dap[dap < -numpy.pi]+= 2.*numpy.pi
    daz[daz > numpy.pi]-= 2.*numpy.pi
    daz[daz < -numpy.pi]+= 2.*numpy.pi
    assert numpy.all(dOr < 10.**tol), 'actionAngleTorus and actionAngleStaeckel applied to Staeckel potential disagree for Or at %f%%' % (numpy.nanmax(dOr)*100.)
    assert numpy.all(dOp < 10.**tol), 'actionAngleTorus and actionAngleStaeckel applied to Staeckel potential disagree for Ophi at %f%%' % (numpy.nanmax(dOp)*100.) 
    assert numpy.all(dOz < 10.**tol), 'actionAngleTorus and actionAngleStaeckel applied to Staeckel potential disagree for Oz at %f%%' % (numpy.nanmax(dOz)*100.)
    assert numpy.all(dar < 10.**tol), 'actionAngleTorus and actionAngleStaeckel applied to Staeckel potential disagree for ar at %f' % (numpy.nanmax(dar))
    assert numpy.all(dap < 10.**tol), 'actionAngleTorus and actionAngleStaeckel applied to Staeckel potential disagree for aphi at %f' % (numpy.nanmax(dap))
    assert numpy.all(daz < 10.**tol), 'actionAngleTorus and actionAngleStaeckel applied to Staeckel potential disagree for az at %f' % (numpy.nanmax(daz))
    return None
Exemple #17
0
def test_actionAngleTorus_Staeckel_actions():
    from galpy.potential import KuzminKutuzovStaeckelPotential
    from galpy.actionAngle import actionAngleTorus, \
        actionAngleStaeckel
    delta= 1.2
    kp= KuzminKutuzovStaeckelPotential(normalize=1.,Delta=delta)
    aAS= actionAngleStaeckel(pot=kp,delta=delta,c=True)
    tol= -3.
    aAT= actionAngleTorus(pot=kp,tol=tol)
    jr,jphi,jz= 0.075,1.1,0.05
    angler= numpy.array([0.])
    anglephi= numpy.array([numpy.pi])
    anglez= numpy.array([numpy.pi/2.])
    # Calculate position from aAT
    RvR= aAT(jr,jphi,jz,angler,anglephi,anglez).T
    # Calculate actions from aAI
    ji= aAS(*RvR)
    djr= numpy.fabs((ji[0]-jr)/jr)
    dlz= numpy.fabs((ji[1]-jphi)/jphi)
    djz= numpy.fabs((ji[2]-jz)/jz)
    assert djr < 10.**tol, 'actionAngleTorus and actionAngleStaeckel applied to Staeckel potential disagree for Jr at %f%%' % (djr*100.)
    assert dlz < 10.**tol, 'actionAngleTorus and actionAngleStaeckel applied to Staeckel potential disagree for Jr at %f%%' % (dlz*100.) 
    assert djz < 10.**tol, 'actionAngleTorus and actionAngleStaeckel applied to Staeckel potential disagree for Jr at %f%%' % (djz*100.)
    return None
def calc_progenitor_actions(savefilename):
    # Setup potential
    lp = potential.LogarithmicHaloPotential(normalize=1.0, q=0.9)
    # Setup orbit
    x, z, y, vx, vz, vy = -11.63337239, -10.631736273934635, -20.76235661, -128.8281653, 79.172383882274971, 42.88727925
    R, phi, z = bovy_coords.rect_to_cyl(x, y, z)
    vR, vT, vz = bovy_coords.rect_to_cyl_vec(vx, vy, vz, R, phi, z, cyl=True)
    R /= 8.0
    z /= 8.0
    vR /= 220.0
    vT /= 220.0
    vz /= 220.0
    o = Orbit([R, vR, vT, z, vz, phi])
    ts = numpy.linspace(0.0, 5.125 * 220.0 / 8.0, 1313)  # times of the snapshots
    o.integrate(ts, lp, method="dopr54_c")
    if "aas" in savefilename:
        aA = actionAngleStaeckel(pot=lp, delta=1.20, c=True)
    else:
        aA = actionAngleIsochroneApprox(pot=lp, b=0.8)
    # Now calculate actions, frequencies, and angles for all positions
    Rs = o.R(ts)
    vRs = o.vR(ts)
    vTs = o.vT(ts)
    zs = o.z(ts)
    vzs = o.vz(ts)
    phis = o.phi(ts)
    csvfile = open(savefilename, "wb")
    writer = csv.writer(csvfile, delimiter=",")
    for ii in range(len(ts)):
        acfs = aA.actionsFreqsAngles(Rs[ii], vRs[ii], vTs[ii], zs[ii], vzs[ii], phis[ii])
        writer.writerow(
            [acfs[0][0], acfs[1][0], acfs[2][0], acfs[3][0], acfs[4][0], acfs[5][0], acfs[6][0], acfs[7][0], acfs[8][0]]
        )
        csvfile.flush()
    csvfile.close()
    return None
Exemple #19
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
def plot_liouville(plotfilename):
    E, Lz= -1.25, 0.6
    aAS= actionAngleStaeckel(pot=MWPotential2014,c=True,delta=0.5)
    #planarOrbit w/ the same energy
    o= Orbit([0.8,numpy.sqrt(2.*(E-evalPot(0.8,0.,MWPotential2014)-(Lz/0.8)**2./2.)),Lz/0.8,0.])
    #For the orbital period
    fo= Orbit([0.8,numpy.sqrt(2.*(E-evalPot(0.8,0.,MWPotential2014)-(Lz/0.8)**2./2.)),Lz/0.8,0.,0.001,0.])
    orbt= 2.*numpy.pi/aAS.actionsFreqs(fo)[4]
    norb= 200.
    nt= 20001
    ts= numpy.linspace(0.,norb*orbt,nt)
    start= time.time()
    integrator= 'dopr54_c'
    o.integrate_dxdv([1.,0.,0.,0.],ts,MWPotential2014,
                     method=integrator,
                     rectIn=True,rectOut=True)
    dx= o.getOrbit_dxdv()[:,:]
    o.integrate_dxdv([0.,1.,0.,0.],ts,MWPotential2014,
                     method=integrator,
                     rectIn=True,rectOut=True)
    dy= o.getOrbit_dxdv()[:,:]
    o.integrate_dxdv([0.,0.,1.,0.],ts,MWPotential2014,
                     method=integrator,
                     rectIn=True,rectOut=True)
    dvx= o.getOrbit_dxdv()[:,:]
    o.integrate_dxdv([0.,0.,0.,1.],ts,MWPotential2014,
                     method=integrator,
                     rectIn=True,rectOut=True)
    dvy= o.getOrbit_dxdv()[:,:]
    print integrator, time.time()-start
    #Calculate Jacobian
    jacs= numpy.array([numpy.linalg.det(numpy.array([dx[ii],dy[ii],
                                                     dvx[ii],dvy[ii]])) for ii in range(nt)])
    breakt= 8.
    pts= list(ts[ts < breakt])
    pts.extend(list((ts[ts >= breakt])[::10]))
    pts= numpy.array(pts)
    pjacs= list(jacs[ts < breakt])
    pjacs.extend(list((jacs[ts >= breakt])[::10]))
    pjacs= numpy.array(pjacs)
    print integrator, numpy.mean(jacs)-1.
    bovy_plot.bovy_print(fig_width=3.25,fig_height=4.5)
    pyplot.subplot(4,1,4)
    bovy_plot.bovy_plot(pts/orbt,numpy.fabs(pjacs-1.),color='k',
                        loglog=True,gcf=True,
                        xrange=[0.5,norb],
                        yrange=[10.**-12.,10.**0.],
                        xlabel=r'$\mathrm{Number\ of\ orbital\ periods}$')
    bovy_plot.bovy_text(r'$\texttt{dopr54\_c}$',
                        top_left=True,size=14.)
    bovy_plot.bovy_text(0.1,10.**44.5,
                        r'$|\mathrm{Determinant\ of\ volume\ transformation}-1|$',
                        fontsize=16.,
                        rotation='vertical')
    ax= pyplot.gca()
    ax.xaxis.set_major_formatter(ticker.FormatStrFormatter(r'$%0.f$'))
    ax.yaxis.set_ticks([10.**-12.,10.**-8.,10.**-4.,1.])
    nullfmt   = NullFormatter()         # no labels
    other_integrators= ['odeint',
                        'rk4_c','rk6_c']
    for ii,integrator in enumerate(other_integrators):
        start= time.time()
        o.integrate_dxdv([1.,0.,0.,0.],ts,MWPotential2014,
                         method=integrator,
                         rectIn=True,rectOut=True)
        dx= o.getOrbit_dxdv()[:,:]
        o.integrate_dxdv([0.,1.,0.,0.],ts,MWPotential2014,
                         method=integrator,
                         rectIn=True,rectOut=True)
        dy= o.getOrbit_dxdv()[:,:]
        o.integrate_dxdv([0.,0.,1.,0.],ts,MWPotential2014,
                         method=integrator,
                         rectIn=True,rectOut=True)
        dvx= o.getOrbit_dxdv()[:,:]
        o.integrate_dxdv([0.,0.,0.,1.],ts,MWPotential2014,
                         method=integrator,
                         rectIn=True,rectOut=True)
        dvy= o.getOrbit_dxdv()[:,:]
        print integrator, time.time()-start
        jacs= numpy.array([numpy.linalg.det(numpy.array([dx[jj],dy[jj],
                                                         dvx[jj],dvy[jj]])) for jj in range(nt)])
        pts= list(ts[ts < breakt])
        pts.extend(list((ts[ts >= breakt])[::10]))
        pts= numpy.array(pts)
        pjacs= list(jacs[ts < breakt])
        pjacs.extend(list((jacs[ts >= breakt])[::10]))
        pjacs= numpy.array(pjacs)
        print integrator, numpy.mean(jacs)-1.
        pyplot.subplot(4,1,ii+1)
        if integrator == 'odeint':
            yrange=[10.**-8.,10.**4.]
            yticks= [10.**-8.,10.**-4.,1.,10.**4.]
        else:
            yrange=[10.**-12.,10.**0.]
            yticks= [10.**-12.,10.**-8.,10.**-4.,1.]
        bovy_plot.bovy_plot(pts/orbt,numpy.fabs(pjacs-1.),color='k',
                            loglog=True,gcf=True,
                            xrange=[0.5,norb],
                            yrange=yrange)
        thisax= pyplot.gca()
        thisax.xaxis.set_major_formatter(nullfmt)
        thisax.yaxis.set_ticks(yticks)
        bovy_plot.bovy_text(r'$\texttt{%s}$' % (integrator.replace('_','\_')),
                            top_left=True,size=14.)
    bovy_plot.bovy_end_print(plotfilename)
    return None
    final_vrs.append(f_vrs)
    final_vts.append(f_vts)
    final_vzs.append(f_vzs)
    final_distance.append(f_dista)
    f_ra = z.ra(-ts)[-1]
    f_dec = z.dec(-ts)[-1]
    final_ra.append(f_ra)
    final_dec.append(f_dec)
    f_pmra = z.pmra(-ts)[-1]
    f_pmdec = z.pmdec(-ts)[-1]
    final_pmra.append(f_pmra)
    final_pmdec.append(f_pmdec)

aAS = actionAngleStaeckel(pot=MWPotential2014,
                          delta=0.45,
                          c=True,
                          ro=8,
                          vo=220)

jr, lz, jz = aAS(fr * units.kpc, final_vrs * units.km / units.s,
                 final_vts * units.km / units.s, fz * units.kpc,
                 final_vzs * units.km / units.s)
#jr_om, lz_om, jz_om = aAS(r_omegaa*units.kpc,vr_omegaa*units.km/units.s,vt_omegaa*units.km/units.s,z_omegaa*units.kpc,vz_omegaa*units.km/units.s)
jr_om = o.jr()
lz_om = o.jp()
jz_om = o.jz()
#plotting velocity dispersions:

disp_vr = final_vrs - (o.vR(ts)[0] * np.ones(num_stars))
disp_vt = final_vts - (o.vT(ts)[0] * np.ones(num_stars))
disp_vz = final_vzs - (o.vz(ts)[0] * np.ones(num_stars))
Exemple #22
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
Exemple #23
0
cs.representation_type = 'cylindrical'
cs.differential_type = 'cylindrical'

rho = cs.rho.to(u.kpc)
phi = cs.phi.to(u.rad)
z = cs.z.to(u.kpc)
vr = cs.d_rho.to(u.km/u.s)
# v_phi is in mas/yr so we compute it in km/s
vp = 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)

# Initialise
aAS = actionAngleStaeckel(
        pot=mw,
        delta=0.45,
        c=True,
        r0=R0.value,
        v0=V0.value
        )

jr, lz, jz = aAS(rho, vr, vp, z, vz)
jr *= R0.value * V0.value
lz *= R0.value * V0.value
jz *= R0.value * V0.value

# Compute quantiles
medrho, stdm_rho, stdp_rho = compute_quantiles(rho)
medphi, stdm_phi, stdp_phi = compute_quantiles(phi)
medz, stdm_z, stdp_z = compute_quantiles(z)
medvr, stdm_vr, stdp_vr = compute_quantiles(vr)
medvp, stdm_vp, stdp_vp = compute_quantiles(vp)
Exemple #24
0
from amuse.lab import *
from galpy.df import quasiisothermaldf, dehnendf
from galpy.potential import MWPotential2014, to_amuse
from galpy.util import bovy_conversion
from galpy.actionAngle import actionAngleStaeckel

import numpy as np

aAS = actionAngleStaeckel(pot=MWPotential2014, delta=0.45, c=True)
qdfS = quasiisothermaldf(1./3., 0.2, 0.1, 1., 1., pot=MWPotential2014, aA=aAS, cutcounter=True)
dfc = dehnendf(beta=0.)

'''
sample from Dehnen distribution function to get cylindrical coordinates
where |r| <= 1.0 kpc
'''

nsamples = 4000
o = dfc.sample(n=nsamples, returnOrbit=True, nphi=1, rrange=[0.0, 1.0])

rvals_spherical = [ e.R() for e in o ]
thetavals_spherical = [ np.arccos(1 - 2*np.random.random()) for i in range(nsamples) ]

rvals_cylindrical = [ rvals_spherical[i]*np.sin(thetavals_spherical[i]) for i in range(nsamples) ]
phivals_cylindrical = 2*np.pi * np.random.random(nsamples)
zvals_cylindrical = [ rvals_spherical[i]*np.cos(thetavals_spherical[i]) for i in range(nsamples) ]

    
#using Staeckel
aAS = actionAngleStaeckel(pot=MWPotential2014, delta=0.45, c=True)
qdfS = quasiisothermaldf(1./3., 0.2, 0.1, 1., 1., pot=MWPotential2014, aA=aAS, cutcounter=True)
Exemple #25
0
def icrs_to_EccZmaxRperiRap(ra: tuple,
                            dec: tuple,
                            d: tuple,
                            pmra: tuple,
                            pmdec: tuple,
                            rv: tuple,
                            ro: float = None,
                            vo: float = None,
                            nsamples: int = 100000) -> tuple:
    """ Converts ICRS coordinates and their Gaussian uncertainties for a star
    in the Milky War into eccentricity, maximum height above the plane, 
    pericentre, and apocentre with uncertainties.
    
    Parameters:
        
        ra - RA with uncertainty, given as a tuple of the form (RA, RA_ERR).
        Can be Quantity, otherwise given in degrees.
         
        dec - Dec with uncertainty, given as a tuple of the form 
        (DEC, DEC_ERR). Can be Quantity, otherwise given in degrees.
        
        d - Distance with uncertainty, given as a tuple of the form (D, D_ERR).
        Can be Quantity, otherwise given in kpc.
        
        pmra - Proper motion in RA with uncertainty, given as a tuple of the 
        form (PMRA, PMRA_ERR). Can be Quantity, otherwise given in mas/yr.
    
        pmdec - Proper motion in Dec with uncertainty, given as a tuple of the 
        form (PMDEC, PMDEC_ERR). Can be Quantity, otherwise given in mas/yr.
    
        rv - Radial velocity with uncertainty, given as a tuple of the form
        (RV, RV_ERR). Can be Quantity, otherwise given in km/s.
        
        ro (optional) - Distance scale. Can be Quantity, otherwise given in
        kpc. If provided with vo, activates output in physical units.
        
        vo (optional) - Velocity scale. Can be Quantity, otherwise given in 
        km/s. If provided with ro, activates output in physical units.
        
        nsamples (optional) - Number of samples for the Monte Carlo method.
    
    Returns:
        
        (e, zmax, rperi, rap), each a tuple of the form (VALUE, VALUE_ERR).
        If ro and vo are provided, distances are returned in kpc. Otherwise
        returns galpy natural units.
    """
    # Convert each value and its error into astropy Quantities
    ra_val, ra_err = u.Quantity(ra, u.deg)
    dec_val, dec_err = u.Quantity(dec, u.deg)
    d_val, d_err = u.Quantity(d, u.kpc)
    pmra_val, pmra_err = u.Quantity(pmra, u.mas / u.yr)
    pmdec_val, pmdec_err = u.Quantity(pmdec, u.mas / u.yr)
    rv_val, rv_err = u.Quantity(rv, u.km / u.s)

    # Get parameters for a 6D normal distribution to sample
    mean = np.array([
        ra_val.value, dec_val.value, d_val.value, pmra_val.value,
        pmdec_val.value, rv_val.value
    ])
    cov = np.diag([
        ra_err.value, dec_err.value, d_err.value, pmra_err.value,
        pmdec_err.value, rv_err.value
    ])

    # Sample the normal distribution
    samples = np.random.multivariate_normal(mean, cov, size=nsamples)
    ra_samples = samples[:, 0] * u.deg
    dec_samples = samples[:, 1] * u.deg
    d_samples = samples[:, 2] * u.kpc
    pmra_samples = samples[:, 3] * (u.mas / u.yr)
    pmdec_samples = samples[:, 4] * (u.mas / u.yr)
    rv_samples = samples[:, 5] * (u.km / u.s)

    coords = SkyCoord(frame="icrs",
                      ra=ra_samples,
                      dec=dec_samples,
                      distance=d_samples,
                      pm_ra_cosdec=pmra_samples,
                      pm_dec=pmdec_samples,
                      radial_velocity=rv_samples)

    # Convert to galactocentric frame
    gal_coords = coords.transform_to("galactocentric")
    gal_coords.representation_type = "cylindrical"

    # Convert each value into consistent units
    R = gal_coords.rho.to(u.kpc)
    phi = gal_coords.phi.to(u.deg)
    z = gal_coords.z.to(u.kpc)
    vR = gal_coords.d_rho.to(u.km / u.s)
    vT = (gal_coords.d_phi * R).to(u.km / u.s,
                                   equivalencies=u.dimensionless_angles())
    vz = gal_coords.d_z.to(u.km / u.s)

    # Calculate EccZmaxRperiRap
    aAS = actionAngleStaeckel(pot=MWPotential2014, delta=0.4, ro=ro, vo=vo)
    orbit_vals = aAS.EccZmaxRperiRap(R, vR, vT, z, vz, phi)

    # Get the mean and standard deviation of the samples
    ecc_val, zmax_val, rperi_val, rap_val = np.mean(orbit_vals, axis=1)
    ecc_err, zmax_err, rperi_err, rap_err = np.std(orbit_vals, axis=1)

    return ((ecc_val, ecc_err), (zmax_val, zmax_err), (rperi_val, rperi_err),
            (rap_val, rap_err))
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
Exemple #27
0
    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:
        #problem with this orbit (probs unbound)
Exemple #28
0
def plot_hrhrvshr(options,args):
    """Plot hr^out/hr^in as a function of hr for various sr"""
    if len(args) == 0.:
        print "Must provide a savefilename ..."
        print "Returning ..."
        return None
    if os.path.exists(args[0]):
        #Load
        savefile= open(args[0],'rb')
        plotthis= pickle.load(savefile)
        hrs= pickle.load(savefile)
        srs= pickle.load(savefile)
        savefile.close()
    else:
        #Grid of models to test
        hrs= numpy.linspace(options.hrmin,options.hrmax,options.nhr)
        srs= numpy.linspace(options.srmin,options.srmax,options.nsr)
        #Tile
        hrs= numpy.tile(hrs,(options.nsr,1)).T
        srs= numpy.tile(srs,(options.nhr,1))
        plotthis= numpy.zeros((options.nhr,options.nsr))
        #Setup potential and aA
        poptions= setup_options(None)
        #poptions.potential= 'dpdiskplhalofixbulgeflatwgasalt'
        #params= [0.,0.,0.,0.,0.,0.,-1.16315,1.,-3.,0.4,0.]
        poptions.potential= 'btii'
        params= None
        #pot= MWPotential
        pot= setup_potential(params,poptions,1)
        if options.aAmethod.lower() == 'staeckel':
            aA= actionAngleStaeckel(pot=pot,delta=0.45,c=True)
        else:
            aA=actionAngleAdiabaticGrid(pot=pot,nR=16,nEz=16,nEr=31,nLz=31,
                                        zmax=1.,Rmax=5.)
        for ii in range(options.nhr):
            for jj in range(options.nsr):
                qdf= quasiisothermaldf(hrs[ii,jj]/8.,srs[ii,jj]/220.,
                                       srs[ii,jj]/numpy.sqrt(3.)/220.,
                                       7./8.,1.,
                                       pot=pot,aA=aA)
                plotthis[ii,jj]= qdf.estimate_hr(1.,z=0.8/8.,
                                                 dR=0.33,
                                                 gl=True)/hrs[ii,jj]*8.
                print ii*options.nsr+jj+1, options.nsr*options.nhr, \
                    hrs[ii,jj], srs[ii,jj], plotthis[ii,jj]
        #Save
        save_pickles(args[0],plotthis,hrs,srs)
    #Now plot
    bovy_plot.bovy_print(fig_width=6.,
                         text_fontsize=20.,
                         legend_fontsize=24.,
                         xtick_labelsize=18.,
                         ytick_labelsize=18.,
                         axes_labelsize=24.)
    indx= 0
    lines= []
    colors= [cm.jet(ii/float(options.nsr-1.)*1.+0.) for ii in range(options.nsr)]
    lss= ['-' for ii in range(options.nsr)]#,'--','-.','..']
    labels= []
    lines.append(bovy_plot.bovy_plot(hrs[:,indx],plotthis[:,indx],
                                     color=colors[indx],ls=lss[indx],
                                     xrange=[0.5,5.5],
                                     yrange=[0.,2.],
                                     xlabel=r'$h^{\mathrm{in}}_R\ \mathrm{at}\ 8\,\mathrm{kpc}$',
                                     ylabel=r'$h^{\mathrm{out}}_R / h^{\mathrm{in}}_R$'))
    labels.append(r'$\sigma_R = %.0f \,\mathrm{km\,s}^{-1}$' % srs[0,indx])
    for indx in range(1,options.nsr):
        lines.append(bovy_plot.bovy_plot(hrs[:,indx],plotthis[:,indx],
                                         color=colors[indx],ls=lss[indx],
                                         overplot=True))
        labels.append(r'$\sigma_R = %.0f \,\mathrm{km\,s}^{-1}$' % srs[0,indx])
    """
    #Legend
    pyplot.legend(lines,#(line1[0],line2[0],line3[0],line4[0]),
                  labels,#(r'$v_{bc} = 0$',
#                   r'$v_{bc} = 1\,\sigma_{bc}$',
#                   r'$v_{bc} = 2\,\sigma_{bc}$',
#                   r'$v_{bc} = 3\,\sigma_{bc}$'),
                  loc='lower right',#bbox_to_anchor=(.91,.375),
                  numpoints=2,
                  prop={'size':14},
                  frameon=False)
    """
     #Add colorbar
    map = cm.ScalarMappable(cmap=cm.jet)
    map.set_array(srs[0,:])
    map.set_clim(vmin=numpy.amin(srs[0,:]),vmax=numpy.amax(srs[0,:]))
    cbar= pyplot.colorbar(map,fraction=0.15)
    cbar.set_clim(numpy.amin(srs[0,:]),numpy.amax(srs[0,:]))
    cbar.set_label(r'$\sigma_R \,(\mathrm{km\,s}^{-1})$')
    bovy_plot.bovy_end_print(options.plotfilename)
Exemple #29
0
def test_get_physical():
    #Test that the get_physical function returns the right scaling parameters
    from galpy.util.bovy_conversion import get_physical
    # Potential and variations thereof
    from galpy.potential import MWPotential2014, DehnenBarPotential
    dp = DehnenBarPotential
    assert numpy.fabs(
        get_physical(MWPotential2014[0]).get('ro') - 8.
    ) < 1e-10, 'get_physical does not return the correct unit conversion parameter for a Potential'
    assert numpy.fabs(
        get_physical(MWPotential2014[0]).get('vo') - 220.
    ) < 1e-10, 'get_physical does not return the correct unit conversion parameter for a Potential'
    ro, vo = 9., 230.
    dp = DehnenBarPotential(ro=ro, vo=vo)
    assert numpy.fabs(
        get_physical(dp).get('ro') - ro
    ) < 1e-10, 'get_physical does not return the correct unit conversion parameter for a Potential'
    assert numpy.fabs(
        get_physical(dp).get('vo') - vo
    ) < 1e-10, 'get_physical does not return the correct unit conversion parameter for a Potential'
    assert numpy.fabs(
        get_physical(MWPotential2014).get('ro') - 8.
    ) < 1e-10, 'get_physical does not return the correct unit conversion parameter for a Potential'
    assert numpy.fabs(
        get_physical(MWPotential2014).get('vo') - 220.
    ) < 1e-10, 'get_physical does not return the correct unit conversion parameter for a Potential'
    assert numpy.fabs(
        get_physical(MWPotential2014 + dp).get('ro') - 8.
    ) < 1e-10, 'get_physical does not return the correct unit conversion parameter for a Potential'
    assert numpy.fabs(
        get_physical(MWPotential2014 + dp).get('vo') - 220.
    ) < 1e-10, 'get_physical does not return the correct unit conversion parameter for a Potential'
    assert numpy.fabs(
        get_physical(MWPotential2014 + dp).get('ro') - 8.
    ) < 1e-10, 'get_physical does not return the correct unit conversion parameter for a Potential'
    assert numpy.fabs(
        get_physical(MWPotential2014 + dp).get('vo') - 220.
    ) < 1e-10, 'get_physical does not return the correct unit conversion parameter for a Potential'
    # Orbits
    from galpy.orbit import Orbit
    ro, vo = 10., 210.
    o = Orbit(ro=ro, vo=vo)
    assert numpy.fabs(
        get_physical(o).get('ro') - ro
    ) < 1e-10, 'get_physical does not return the correct unit conversion parameter for an Orbit'
    assert numpy.fabs(
        get_physical(o).get('vo') - vo
    ) < 1e-10, 'get_physical does not return the correct unit conversion parameter for an Orbit'
    # even though one shouldn't do this, let's test a list
    assert numpy.fabs(
        get_physical([o, o]).get('ro') - ro
    ) < 1e-10, 'get_physical does not return the correct unit conversion parameter for an Orbit'
    assert numpy.fabs(
        get_physical([o, o]).get('vo') - vo
    ) < 1e-10, 'get_physical does not return the correct unit conversion parameter for an Orbit'
    # actionAngle
    from galpy.actionAngle import actionAngleStaeckel
    aAS = actionAngleStaeckel(pot=MWPotential2014, delta=0.45)
    assert numpy.fabs(
        get_physical(aAS).get('ro') - 8.
    ) < 1e-10, 'get_physical does not return the correct unit conversion parameter for an actionAngle instance'
    assert numpy.fabs(
        get_physical(aAS).get('vo') - 220.
    ) < 1e-10, 'get_physical does not return the correct unit conversion parameter for an actionAngle instance'
    # This doesn't make much sense, but let's test...
    ro, vo = 19., 130.
    dp = DehnenBarPotential(ro=ro, vo=vo)
    aAS = actionAngleStaeckel(pot=dp, delta=0.45, ro=ro, vo=vo)
    assert numpy.fabs(
        get_physical(aAS).get('ro') - ro
    ) < 1e-10, 'get_physical does not return the correct unit conversion parameter for an actionAngle instance'
    assert numpy.fabs(
        get_physical(aAS).get('vo') - vo
    ) < 1e-10, 'get_physical does not return the correct unit conversion parameter for an actionAngle instance'
    # DF
    from galpy.df import quasiisothermaldf
    aAS = actionAngleStaeckel(pot=MWPotential2014, delta=0.45)
    qdf = quasiisothermaldf(1. / 3.,
                            0.2,
                            0.1,
                            1.,
                            1.,
                            aA=aAS,
                            pot=MWPotential2014)
    assert numpy.fabs(
        get_physical(qdf).get('ro') - 8.
    ) < 1e-10, 'get_physical does not return the correct unit conversion parameter for a DF instance'
    assert numpy.fabs(
        get_physical(qdf).get('vo') - 220.
    ) < 1e-10, 'get_physical does not return the correct unit conversion parameter for a DF instance'
    # non-standard ro,vo
    from galpy.potential import MiyamotoNagaiPotential
    ro, vo = 4., 330.
    mp = MiyamotoNagaiPotential(a=0.5, b=0.1, ro=ro, vo=vo)
    aAS = actionAngleStaeckel(pot=mp, delta=0.45, ro=ro, vo=vo)
    qdf = quasiisothermaldf(1. / 3.,
                            0.2,
                            0.1,
                            1.,
                            1.,
                            aA=aAS,
                            pot=mp,
                            ro=ro,
                            vo=vo)
    assert numpy.fabs(
        get_physical(qdf).get('ro') - ro
    ) < 1e-10, 'get_physical does not return the correct unit conversion parameter for a DF instance'
    assert numpy.fabs(
        get_physical(qdf).get('vo') - vo
    ) < 1e-10, 'get_physical does not return the correct unit conversion parameter for a DF instance'
    return None
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
Exemple #31
0
print('Reference frame:')
print('R_GC = '+str(r_galactic_centre)+' (McMillan, 2017, MNRAS, 465, 76)')
print('phi_GC = '+str(0*u.rad))
print('z_GC = '+str(z_galactic_plane)+' (Bland-Hawthorn & Gerhard, 2016, ARA&A, 54, 529)')

v_total_sun = (np.tan(6.379*u.mas)*r_galactic_centre/u.yr).to(u.km/u.s) # pm_l by Reid & Brunthaler 2004, ApJ, 616, 872
print('V_total_sun: = '+"{:.2f}".format(v_total_sun)+' (Reid & Brunthaler 2004, ApJ, 616, 872)')
v_peculiar = [11.1, 15.17, 7.25]*u.km/u.s # U and W from Schoenrich, Binney, Dehnen, 2010, MNRAS, 403, 1829, V so that V = V_total-V_sun
print('V_peculiar = ',(v_peculiar),' (U and W from Schoenrich, Binney, Dehnen, 2010, MNRAS, 403, 1829)')
print('V-component of V_peculiar = 15.17 km/s, instead of 12.24 km/s by Schoenrich et al. (2010), for matching v_circular')
v_circular = np.round(v_total_sun-v_peculiar[1],1)
print('V_circular = ',(v_circular),' (McMillan, 2017, MNRAS, 465, 76)')

aAS = actionAngleStaeckel(
        pot   = pot,        #potential                                                                                                                                                                      
        delta = 0.45,       #focal length of confocal coordinate system                                                                                                                            
        c     = True        #use C code (for speed)                                                                                                                                                         
        )

#(RA = 17:45:37.224 h:m:s, Dec = −28:56:10.23 deg) (Reid& Brunthaler 2004)


# ### Let's get the Solar values

# In[ ]:


calculate_sun = True

if calculate_sun:
    sun = dict()
Exemple #32
0
# Tests of the quasiisothermaldf module
from __future__ import print_function, division
import numpy
#fiducial setup uses these
from galpy.potential import MWPotential, vcirc, omegac, epifreq, verticalfreq
from galpy.actionAngle import actionAngleAdiabatic, actionAngleStaeckel
from galpy.df import quasiisothermaldf
aAA= actionAngleAdiabatic(pot=MWPotential,c=True)
aAS= actionAngleStaeckel(pot=MWPotential,c=True,delta=0.5)

def test_meanvR_adiabatic_gl():
    qdf= quasiisothermaldf(1./4.,0.2,0.1,1.,1.,
                           pot=MWPotential,aA=aAA,cutcounter=True)
    #In the mid-plane
    assert numpy.fabs(qdf.meanvR(0.9,0.,gl=True)) < 0.01, "qdf's meanvr is not equal to zero for adiabatic approx."
    #higher up
    assert numpy.fabs(qdf.meanvR(0.9,0.2,gl=True)) < 0.01, "qdf's meanvr is not equal to zero for adiabatic approx."
    assert numpy.fabs(qdf.meanvR(0.9,-0.25,gl=True)) < 0.01, "qdf's meanvr is not equal to zero for adiabatic approx."
    return None

def test_meanvR_adiabatic_mc():
    numpy.random.seed(1)
    qdf= quasiisothermaldf(1./4.,0.2,0.1,1.,1.,
                           pot=MWPotential,aA=aAA,cutcounter=True)
    #In the mid-plane
    assert numpy.fabs(qdf.meanvR(0.9,0.,mc=True)) < 0.01, "qdf's meanvr is not equal to zero for adiabatic approx."
    #higher up
    assert numpy.fabs(qdf.meanvR(0.9,0.2,mc=True)) < 0.05, "qdf's meanvr is not equal to zero for adiabatic approx."
    assert numpy.fabs(qdf.meanvR(0.9,-0.25,mc=True)) < 0.05, "qdf's meanvr is not equal to zero for adiabatic approx."
    return None
import numpy as np
from scipy.special import logsumexp
from galpy.potential import MWPotential2014
from galpy.actionAngle import actionAngleStaeckel
from galpy.df import quasiisothermaldf

aAS= actionAngleStaeckel(delta=0.4,pot=MWPotential2014,c=True)

_R0 = 8.
_z0 = 0.025

def gaussian_1d(v_R, v_z, R, z, med_z, params=[30.]):
    sigmaR = params[0]
    vo = 0.
    A_R = (1./(sigmaR*np.sqrt(2*np.pi)))
    E_R = (-(v_R-vo)**2)/(2*sigmaR**2)
    p = A_R*np.exp(E_R)
    logp = np.log(p)
    logp = np.sum(logp[np.isfinite(logp)])
    return logp

def gaussian_fixedv0(v_R, v_z, R, z, med_z, params=[np.log10(30.),np.log10(30.),0.1]):
    sigmaR, sigmaz, contfrac = params
    sigmaR, sigmaz = 10**sigmaR, 10**sigmaz
    vo = 0.
    contA = (contfrac)*(1./(100*np.sqrt(2*np.pi)))
    contE_R = (-(v_R-vo)**2/(2*100**2))
    contE_z = (-(v_z-vo)**2/(2*100**2))
    A_R = (1-contfrac)*(1./(sigmaR*np.sqrt(2*np.pi)))
    A_z = (1-contfrac)*(1./(sigmaz*np.sqrt(2*np.pi)))
    E_R = (-(v_R-vo)**2)/(2*sigmaR**2)
Exemple #34
0
def plot_szszvssz(options,args):
    """Plot sz^out/sz^in as a function of sz for various hr"""
    if len(args) == 0.:
        print "Must provide a savefilename ..."
        print "Returning ..."
        return None
    if os.path.exists(args[0]):
        #Load
        savefile= open(args[0],'rb')
        plotthis= pickle.load(savefile)
        szs= pickle.load(savefile)
        hrs= pickle.load(savefile)
        savefile.close()
    else:
        #Grid of models to test
        if options.subtype.lower() == 'sr':
            szs= numpy.linspace(options.srmin,options.srmax,options.nsz)
        else:
            szs= numpy.linspace(options.szmin,options.szmax,options.nsz)
        hrs= numpy.linspace(options.hrmin,options.hrmax,options.nhr)
        #Tile
        szs= numpy.tile(szs,(options.nhr,1)).T
        hrs= numpy.tile(hrs,(options.nsz,1))
        plotthis= numpy.zeros((options.nsz,options.nhr))
        #Setup potential and aA
        poptions= setup_options(None)
        #poptions.potential= 'dpdiskplhalofixbulgeflatwgasalt'
        #params= [0.,0.,0.,0.,0.,0.,-1.16315,1.,-3.,0.4,0.]
        poptions.potential= 'btii'
        params= None
        #pot= MWPotential
        pot= setup_potential(params,poptions,1)
        if options.aAmethod.lower() == 'staeckel':
            aA= actionAngleStaeckel(pot=pot,delta=0.45,c=True)
        else:
            aA=actionAngleAdiabaticGrid(pot=pot,nR=16,nEz=16,nEr=31,nLz=31,
                                        zmax=1.,Rmax=5.)
        for ii in range(options.nsz):
            for jj in range(options.nhr):
                if options.subtype.lower() == 'sr':
                    qdf= quasiisothermaldf(hrs[ii,jj]/8.,
                                           szs[ii,jj]/220.,
                                           szs[ii,jj]/220./numpy.sqrt(3.),
                                           7./8.,1.,
                                           pot=pot,aA=aA)
                else:
                    qdf= quasiisothermaldf(hrs[ii,jj]/8.,
                                           szs[ii,jj]/220.*numpy.sqrt(3.),
                                           szs[ii,jj]/220.,
                                           7./8.,1.,
                                           pot=pot,aA=aA)
                if options.subtype.lower() == 'sr':
                    plotthis[ii,jj]= numpy.sqrt(qdf.sigmaR2(1.,0.8/8.,
                                                            gl=True))/szs[ii,jj]*220.
                else:
                    plotthis[ii,jj]= numpy.sqrt(qdf.sigmaz2(1.,0.8/8.,
                                                        gl=True))/szs[ii,jj]*220.
                print ii*options.nhr+jj+1, options.nhr*options.nsz, \
                    szs[ii,jj], hrs[ii,jj], plotthis[ii,jj]
        #Save
        save_pickles(args[0],plotthis,szs,hrs)
    #Now plot
    bovy_plot.bovy_print(fig_width=6.,
                         text_fontsize=20.,
                         legend_fontsize=24.,
                         xtick_labelsize=18.,
                         ytick_labelsize=18.,
                         axes_labelsize=24.)
    indx= 0
    lines= []
    colors= [cm.jet(ii/float(options.nhr-1.)*1.+0.) for ii in range(options.nhr)]
    lss= ['-' for ii in range(options.nhr)]#,'--','-.','..']
    labels= []
    if options.subtype.lower() == 'sr':
        lines.append(bovy_plot.bovy_plot(szs[:,indx],plotthis[:,indx],
                                         color=colors[indx],ls=lss[indx],
                                         xrange=[10.,85.],
                                         yrange=[0.8,1.5],
                                         xlabel=r'$\sigma^{\mathrm{in}}_R\ \mathrm{at}\ R = 8\,\mathrm{kpc}$',
                                         ylabel=r'$\sigma^{\mathrm{out}}_R / \sigma^{\mathrm{in}}_R$'))
    else:
        lines.append(bovy_plot.bovy_plot(szs[:,indx],plotthis[:,indx],
                                         color=colors[indx],ls=lss[indx],
                                         xrange=[10.,115.],
                                         yrange=[0.5,1.2],
                                         xlabel=r'$\sigma^{\mathrm{in}}_Z\ \mathrm{at}\ R = 8\,\mathrm{kpc}$',
                                         ylabel=r'$\sigma^{\mathrm{out}}_Z / \sigma^{\mathrm{in}}_Z$'))
    for indx in range(1,options.nhr):
        lines.append(bovy_plot.bovy_plot(szs[:,indx],plotthis[:,indx],
                                         color=colors[indx],ls=lss[indx],
                                         overplot=True))
     #Add colorbar
    map = cm.ScalarMappable(cmap=cm.jet)
    map.set_array(hrs[0,:])
    map.set_clim(vmin=numpy.amin(hrs[0,:]),vmax=numpy.amax(hrs[0,:]))
    cbar= pyplot.colorbar(map,fraction=0.15)
    cbar.set_clim(numpy.amin(hrs[0,:]),numpy.amax(hrs[0,:]))
    cbar.set_label(r'$h_R\, (\mathrm{kpc})$')
    bovy_plot.bovy_end_print(options.plotfilename)
Exemple #35
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
Exemple #36
0
def plot_hzszq(options,args):
    """Plot sz,hz, q"""
    if len(args) == 0.:
        print "Must provide a savefilename ..."
        print "Returning ..."
        return None
    nqs, nszs, nhzs= 31, 51, 51
    #nqs, nszs, nhzs= 5,5,5
    if os.path.exists(args[0]):
        #Load
        savefile= open(args[0],'rb')
        hzs= pickle.load(savefile)
        szs= pickle.load(savefile)
        qs= pickle.load(savefile)
        savefile.close()
    else:
        qs= numpy.linspace(0.5,1.,nqs)
        szs= numpy.linspace(15.,50.,nszs)
        hzs= numpy.zeros((nqs,nszs))
        for ii in range(nqs):
            print "Working on potential %i / %i ..." % (ii+1,nqs)
            #Setup potential
            lp= LogarithmicHaloPotential(normalize=1.,q=qs[ii])
            if options.aAmethod.lower() == 'staeckel':
                aA= actionAngleStaeckel(pot=lp,delta=0.45,c=True)
            else:
                aA=actionAngleAdiabaticGrid(pot=pot,nR=16,nEz=16,nEr=31,nLz=31,
                                            zmax=1.,Rmax=5.)
            for jj in range(nszs):
                qdf= quasiisothermaldf(options.hr/8.,2.*szs[jj]/220.,
                                       szs[jj]/220.,7./8.,7./8.,pot=lp,
                                       aA=aA,cutcounter=True)    
                hzs[ii,jj]= qdf.estimate_hz(1.,z=0.125)
        #Save
        save_pickles(args[0],hzs,szs,qs)
    #Re-sample
    hzsgrid= numpy.linspace(50.,1500.,nhzs)/8000.
    qs2d= numpy.zeros((nhzs,nszs))
    for ii in range(nszs):
        interpQ= interpolate.UnivariateSpline(hzs[:,ii],qs,k=3)
        qs2d[:,ii]= interpQ(hzsgrid)
        qs2d[(hzsgrid < hzs[0,ii]),ii]= numpy.nan
        qs2d[(hzsgrid > hzs[-1,ii]),ii]= numpy.nan
    #Now plot
    bovy_plot.bovy_print(fig_width=6.,
                         text_fontsize=20.,
                         legend_fontsize=24.,
                         xtick_labelsize=18.,
                         ytick_labelsize=18.,
                         axes_labelsize=24.)
    bovy_plot.bovy_dens2d(qs2d.T,origin='lower',cmap='jet',
                          interpolation='gaussian',
#                          interpolation='nearest',
                          ylabel=r'$\sigma_z\ [\mathrm{km\,s}^{-1}]$',
                          xlabel=r'$h_z\ [\mathrm{pc}]$',
                          zlabel=r'$\mathrm{flattening}\ q$',
                          yrange=[szs[0],szs[-1]],
                          xrange=[8000.*hzsgrid[0],8000.*hzsgrid[-1]],
#                          vmin=0.5,vmax=1.,
                           contours=False,
                           colorbar=True,shrink=0.78)
    _OVERPLOTMAPS= True
    if _OVERPLOTMAPS:
        fehs= monoAbundanceMW.fehs()
        afes= monoAbundanceMW.afes()
        npops= len(fehs)
        mapszs= []
        maphzs= []
        for ii in range(npops):
            thissz, thiserr= monoAbundanceMW.sigmaz(fehs[ii],afes[ii],err=True)
            if thiserr/thissz > 0.1:
                continue
            thishz, thiserr= monoAbundanceMW.hz(fehs[ii],afes[ii],err=True)
            if thiserr/thishz > 0.1:
                continue
            mapszs.append(thissz)
            maphzs.append(thishz)
        mapszs= numpy.array(mapszs)
        maphzs= numpy.array(maphzs)
        bovy_plot.bovy_plot(maphzs,mapszs,'ko',overplot=True,mfc='none',mew=1.5)
    bovy_plot.bovy_text(r'$h_R = %i\,\mathrm{kpc}$' % int(options.hr),
                        bottom_right=True)
    bovy_plot.bovy_end_print(options.plotfilename)