def obs_to_galcen(ra, dec, dist, pmra, pmdec, rv, ro=_R0, vo=_v0, zo=_z0):
    vxvv = np.dstack([ra, dec, dist, pmra, pmdec, rv])[0]
    ra, dec = vxvv[:, 0], vxvv[:, 1]
    lb = bovy_coords.radec_to_lb(ra, dec, degree=True)
    pmra, pmdec = vxvv[:, 3], vxvv[:, 4]
    pmllpmbb = bovy_coords.pmrapmdec_to_pmllpmbb(pmra, pmdec, ra, dec, degree=True)
    d, vlos = vxvv[:, 2], vxvv[:, 5]
    rectgal = bovy_coords.sphergal_to_rectgal(lb[:, 0], lb[:, 1], d, vlos, pmllpmbb[:, 0], pmllpmbb[:, 1], degree=True)
    vsolar = np.array([-11.1, 245.7, 7.25])
    vsun = vsolar / vo
    X = rectgal[:, 0] / ro
    Y = rectgal[:, 1] / ro
    Z = rectgal[:, 2] / ro
    vx = rectgal[:, 3] / vo
    vy = rectgal[:, 4] / vo
    vz = rectgal[:, 5] / vo
    XYZ = np.dstack([X, Y, Z])[0]
    vxyz = np.dstack([vx, vy, vz])[0]
    Rpz = bovy_coords.XYZ_to_galcencyl(XYZ[:, 0], XYZ[:, 1], XYZ[:, 2], Zsun=zo / ro)
    vRvTvz = bovy_coords.vxvyvz_to_galcencyl(vxyz[:, 0], vxyz[:, 1], vxyz[:, 2], Rpz[:, 0], Rpz[:, 1], Rpz[:, 2],
                                             vsun=vsun,
                                             Xsun=1.,
                                             Zsun=zo / ro,
                                             galcen=True)

    return XYZ, vxyz, Rpz, vRvTvz
Ejemplo n.º 2
0
def test_sphergal_to_rectgal():
    l,b,d= 90.,0.,1.
    vr,pmll,pmbb= 10.,-20./4.74047,30./4.74047
    X,Y,Z,vx,vy,vz= bovy_coords.sphergal_to_rectgal(l,b,d,vr,pmll,pmbb,
                                                    degree=True)
    assert numpy.fabs(X-0.) < 10.**-10., 'sphergal_to_rectgal conversion did not work as expected'
    assert numpy.fabs(Y-1.) < 10.**-10., 'sphergal_to_rectgal conversion did not work as expected'
    assert numpy.fabs(Z-0.) < 10.**-10., 'sphergal_to_rectgal conversion did not work as expected'
    assert numpy.fabs(vx-20.) < 10.**-10., 'sphergal_to_rectgal conversion did not work as expected'
    assert numpy.fabs(vy-10.) < 10.**-10., 'sphergal_to_rectgal conversion did not work as expected'
    assert numpy.fabs(vz-30.) < 10.**-10., 'sphergal_to_rectgal conversion did not work as expected'
    #Also test for degree=False
    X,Y,Z,vx,vy,vz= bovy_coords.sphergal_to_rectgal(l/180.*numpy.pi,
                                                    b/180.*numpy.pi,
                                                    d,vr,pmll,pmbb,
                                                    degree=False)
    assert numpy.fabs(X-0.) < 10.**-10., 'sphergal_to_rectgal conversion did not work as expected'
    assert numpy.fabs(Y-1.) < 10.**-10., 'sphergal_to_rectgal conversion did not work as expected'
    assert numpy.fabs(Z-0.) < 10.**-10., 'sphergal_to_rectgal conversion did not work as expected'
    assert numpy.fabs(vx-20.) < 10.**-10., 'sphergal_to_rectgal conversion did not work as expected'
    assert numpy.fabs(vy-10.) < 10.**-10., 'sphergal_to_rectgal conversion did not work as expected'
    assert numpy.fabs(vz-30.) < 10.**-10., 'sphergal_to_rectgal conversion did not work as expected'
    #Also test for arrays
    os= numpy.ones(2)
    XYZvxvyvz= bovy_coords.sphergal_to_rectgal(os*l,os*b,os*d,
                                                    os*vr,os*pmll,os*pmbb,
                                                    degree=True)
    X= XYZvxvyvz[:,0]
    Y= XYZvxvyvz[:,1]
    Z= XYZvxvyvz[:,2]
    vx= XYZvxvyvz[:,3]
    vy= XYZvxvyvz[:,4]
    vz= XYZvxvyvz[:,5]
    assert numpy.all(numpy.fabs(X-0.) < 10.**-10.), 'sphergal_to_rectgal conversion did not work as expected'
    assert numpy.all(numpy.fabs(Y-1.) < 10.**-10.), 'sphergal_to_rectgal conversion did not work as expected'
    assert numpy.all(numpy.fabs(Z-0.) < 10.**-10.), 'sphergal_to_rectgal conversion did not work as expected'
    assert numpy.all(numpy.fabs(vx-20.) < 10.**-10.), 'sphergal_to_rectgal conversion did not work as expected'
    assert numpy.all(numpy.fabs(vy-10.) < 10.**-10.), 'sphergal_to_rectgal conversion did not work as expected'
    assert numpy.all(numpy.fabs(vz-30.) < 10.**-10.), 'sphergal_to_rectgal conversion did not work as expected'
    return None
Ejemplo n.º 3
0
def test_rectgal_to_sphergal():
    #Test that this is the inverse of sphergal_to_rectgal
    l,b,d= 90.,30.,1.
    vr,pmll,pmbb= 10.,-20.,30.
    X,Y,Z,vx,vy,vz= bovy_coords.sphergal_to_rectgal(l,b,d,vr,pmll,pmbb,
                                                    degree=True)
    lt,bt,dt,vrt,pmllt,pmbbt= bovy_coords.rectgal_to_sphergal(X,Y,Z,
                                                              vx,vy,vz,
                                                              degree=True)
    assert numpy.fabs(lt-l) < 10.**-10., 'rectgal_to_sphergal conversion did not work as expected'
    assert numpy.fabs(bt-b) < 10.**-10., 'rectgal_to_sphergal conversion did not work as expected'
    assert numpy.fabs(dt-d) < 10.**-10., 'rectgal_to_sphergal conversion did not work as expected'
    assert numpy.fabs(vrt-vr) < 10.**-10., 'rectgal_to_sphergal conversion did not work as expected'
    assert numpy.fabs(pmllt-pmll) < 10.**-10., 'rectgal_to_sphergal conversion did not work as expected'
    assert numpy.fabs(pmbbt-pmbb) < 10.**-10., 'rectgal_to_sphergal conversion did not work as expected'
    #Also test for degree=False
    lt,bt,dt,vrt,pmllt,pmbbt= bovy_coords.rectgal_to_sphergal(X,Y,Z,
                                                              vx,vy,vz,
                                                              degree=False)
    assert numpy.fabs(lt-l/180.*numpy.pi) < 10.**-10., 'rectgal_to_sphergal conversion did not work as expected'
    assert numpy.fabs(bt-b/180.*numpy.pi) < 10.**-10., 'rectgal_to_sphergal conversion did not work as expected'
    assert numpy.fabs(dt-d) < 10.**-10., 'rectgal_to_sphergal conversion did not work as expected'
    assert numpy.fabs(vrt-vr) < 10.**-10., 'rectgal_to_sphergal conversion did not work as expected'
    assert numpy.fabs(pmllt-pmll) < 10.**-10., 'rectgal_to_sphergal conversion did not work as expected'
    assert numpy.fabs(pmbbt-pmbb) < 10.**-10., 'rectgal_to_sphergal conversion did not work as expected'
    #Also test for arrays
    os= numpy.ones(2)
    lbdvrpmllpmbbt= bovy_coords.rectgal_to_sphergal(os*X,os*Y,os*Z,
                                                              os*vx,os*vy,
                                                              os*vz,
                                                              degree=True)
    lt= lbdvrpmllpmbbt[:,0]
    bt= lbdvrpmllpmbbt[:,1]
    dt= lbdvrpmllpmbbt[:,2]
    vrt= lbdvrpmllpmbbt[:,3]
    pmllt= lbdvrpmllpmbbt[:,4]
    pmbbt= lbdvrpmllpmbbt[:,5]
    assert numpy.all(numpy.fabs(lt-l) < 10.**-10.), 'rectgal_to_sphergal conversion did not work as expected'
    assert numpy.all(numpy.fabs(bt-b) < 10.**-10.), 'rectgal_to_sphergal conversion did not work as expected'
    assert numpy.all(numpy.fabs(dt-d) < 10.**-10.), 'rectgal_to_sphergal conversion did not work as expected'
    assert numpy.all(numpy.fabs(vrt-vr) < 10.**-10.), 'rectgal_to_sphergal conversion did not work as expected'
    assert numpy.all(numpy.fabs(pmllt-pmll) < 10.**-10.), 'rectgal_to_sphergal conversion did not work as expected'
    assert numpy.all(numpy.fabs(pmbbt-pmbb) < 10.**-10.), 'rectgal_to_sphergal conversion did not work as expected'    
    return None
Ejemplo n.º 4
0
    def __init__(self,vxvv=None,uvw=False,lb=False,
                 radec=False,vo=235.,ro=8.5,zo=0.025,
                 solarmotion='hogg'):
        """
        NAME:

           __init__

        PURPOSE:

           Initialize an Orbit instance

        INPUT:

           vxvv - initial conditions 
                  3D can be either

              1) in Galactocentric cylindrical coordinates [R,vR,vT(,z,vz,phi)]

              2) [ra,dec,d,mu_ra, mu_dec,vlos] in [deg,deg,kpc,mas/yr,mas/yr,km/s] (all J2000.0; mu_ra = mu_ra * cos dec)

              3) [ra,dec,d,U,V,W] in [deg,deg,kpc,km/s,km/s,kms]

              4) (l,b,d,mu_l, mu_b, vlos) in [deg,deg,kpc,mas/yr,mas/yr,km/s) (all J2000.0; mu_l = mu_l * cos b)

              5) [l,b,d,U,V,W] in [deg,deg,kpc,km/s,km/s,kms]

           4) and 5) also work when leaving out b and mu_b/W

        OPTIONAL INPUTS:

           radec - if True, input is 2) (or 3) above

           uvw - if True, velocities are UVW

           lb - if True, input is 4) or 5) above

           vo - circular velocity at ro

           ro - distance from vantage point to GC (kpc)

           zo - offset toward the NGP of the Sun wrt the plane (kpc)

           solarmotion - 'hogg' or 'dehnen', or 'schoenrich', or value in 
           [-U,V,W]

        OUTPUT:

           instance

        HISTORY:

           2010-07-20 - Written - Bovy (NYU)

        """
        if isinstance(solarmotion,str) and solarmotion.lower() == 'hogg':
            vsolar= nu.array([-10.1,4.0,6.7])/vo
        elif isinstance(solarmotion,str) and solarmotion.lower() == 'dehnen':
            vsolar= nu.array([-10.,5.25,7.17])/vo
        elif isinstance(solarmotion,str) \
                and solarmotion.lower() == 'schoenrich':
            vsolar= nu.array([-11.1,12.24,7.25])/vo
        else:
            vsolar= nu.array(solarmotion)/vo           
        if radec or lb:
            if radec:
                l,b= coords.radec_to_lb(vxvv[0],vxvv[1],degree=True)
            elif len(vxvv) == 4:
                l, b= vxvv[0], 0.
            else:
                l,b= vxvv[0],vxvv[1]
            if uvw:
                X,Y,Z= coords.lbd_to_XYZ(l,b,vxvv[2],degree=True)
                vx= vxvv[3]
                vy= vxvv[4]
                vz= vxvv[5]
            else:
                if radec:
                    pmll, pmbb= coords.pmrapmdec_to_pmllpmbb(vxvv[3],vxvv[4],
                                                             vxvv[0],vxvv[1],
                                                             degree=True)
                    d, vlos= vxvv[2], vxvv[5]
                elif len(vxvv) == 4:
                    pmll, pmbb= vxvv[2], 0.
                    d, vlos= vxvv[1], vxvv[3]
                else:
                    pmll, pmbb= vxvv[3], vxvv[4]
                    d, vlos= vxvv[2], vxvv[5]
                X,Y,Z,vx,vy,vz= coords.sphergal_to_rectgal(l,b,d,
                                                           vlos,pmll, pmbb,
                                                           degree=True)
            X/= ro
            Y/= ro
            Z/= ro
            vx/= vo
            vy/= vo
            vz/= vo
            vsun= nu.array([0.,1.,0.,])+vsolar
            R, phi, z= coords.XYZ_to_galcencyl(X,Y,Z,Zsun=zo/ro)
            vR, vT,vz= coords.vxvyvz_to_galcencyl(vx,vy,vz,
                                                  R,phi,z,
                                                  vsun=vsun,galcen=True)
            if lb and len(vxvv) == 4: vxvv= [R,vR,vT,phi]
            else: vxvv= [R,vR,vT,z,vz,phi]
        self.vxvv= vxvv
        if len(vxvv) == 2:
            self._orb= linearOrbit(vxvv=vxvv)
        elif len(vxvv) == 3:
            self._orb= planarROrbit(vxvv=vxvv)
        elif len(vxvv) == 4:
            self._orb= planarOrbit(vxvv=vxvv)
        elif len(vxvv) == 5:
            self._orb= RZOrbit(vxvv=vxvv)
        elif len(vxvv) == 6:
            self._orb= FullOrbit(vxvv=vxvv)
Ejemplo n.º 5
0
    def __init__(self,
                 vxvv=None,
                 uvw=False,
                 lb=False,
                 radec=False,
                 vo=235.,
                 ro=8.5,
                 zo=0.025,
                 solarmotion='hogg'):
        """
        NAME:

           __init__

        PURPOSE:

           Initialize an Orbit instance

        INPUT:

           vxvv - initial conditions 
                  3D can be either

              1) in Galactocentric cylindrical coordinates [R,vR,vT(,z,vz,phi)]

              2) [ra,dec,d,mu_ra, mu_dec,vlos] in [deg,deg,kpc,mas/yr,mas/yr,km/s] (all J2000.0; mu_ra = mu_ra * cos dec)

              3) [ra,dec,d,U,V,W] in [deg,deg,kpc,km/s,km/s,kms]

              4) (l,b,d,mu_l, mu_b, vlos) in [deg,deg,kpc,mas/yr,mas/yr,km/s) (all J2000.0; mu_l = mu_l * cos b)

              5) [l,b,d,U,V,W] in [deg,deg,kpc,km/s,km/s,kms]

           4) and 5) also work when leaving out b and mu_b/W

        OPTIONAL INPUTS:

           radec - if True, input is 2) (or 3) above

           uvw - if True, velocities are UVW

           lb - if True, input is 4) or 5) above

           vo - circular velocity at ro

           ro - distance from vantage point to GC (kpc)

           zo - offset toward the NGP of the Sun wrt the plane (kpc)

           solarmotion - 'hogg' or 'dehnen', or 'schoenrich', or value in 
           [-U,V,W]

        OUTPUT:

           instance

        HISTORY:

           2010-07-20 - Written - Bovy (NYU)

        """
        if isinstance(solarmotion, str) and solarmotion.lower() == 'hogg':
            vsolar = nu.array([-10.1, 4.0, 6.7]) / vo
        elif isinstance(solarmotion, str) and solarmotion.lower() == 'dehnen':
            vsolar = nu.array([-10., 5.25, 7.17]) / vo
        elif isinstance(solarmotion,str) \
                and solarmotion.lower() == 'schoenrich':
            vsolar = nu.array([-11.1, 12.24, 7.25]) / vo
        else:
            vsolar = nu.array(solarmotion) / vo
        if radec or lb:
            if radec:
                l, b = coords.radec_to_lb(vxvv[0], vxvv[1], degree=True)
            elif len(vxvv) == 4:
                l, b = vxvv[0], 0.
            else:
                l, b = vxvv[0], vxvv[1]
            if uvw:
                X, Y, Z = coords.lbd_to_XYZ(l, b, vxvv[2], degree=True)
                vx = vxvv[3]
                vy = vxvv[4]
                vz = vxvv[5]
            else:
                if radec:
                    pmll, pmbb = coords.pmrapmdec_to_pmllpmbb(vxvv[3],
                                                              vxvv[4],
                                                              vxvv[0],
                                                              vxvv[1],
                                                              degree=True)
                    d, vlos = vxvv[2], vxvv[5]
                elif len(vxvv) == 4:
                    pmll, pmbb = vxvv[2], 0.
                    d, vlos = vxvv[1], vxvv[3]
                else:
                    pmll, pmbb = vxvv[3], vxvv[4]
                    d, vlos = vxvv[2], vxvv[5]
                X, Y, Z, vx, vy, vz = coords.sphergal_to_rectgal(l,
                                                                 b,
                                                                 d,
                                                                 vlos,
                                                                 pmll,
                                                                 pmbb,
                                                                 degree=True)
            X /= ro
            Y /= ro
            Z /= ro
            vx /= vo
            vy /= vo
            vz /= vo
            vsun = nu.array([
                0.,
                1.,
                0.,
            ]) + vsolar
            R, phi, z = coords.XYZ_to_galcencyl(X, Y, Z, Zsun=zo / ro)
            vR, vT, vz = coords.vxvyvz_to_galcencyl(vx,
                                                    vy,
                                                    vz,
                                                    R,
                                                    phi,
                                                    z,
                                                    vsun=vsun,
                                                    galcen=True)
            if lb and len(vxvv) == 4: vxvv = [R, vR, vT, phi]
            else: vxvv = [R, vR, vT, z, vz, phi]
        self.vxvv = vxvv
        if len(vxvv) == 2:
            self._orb = linearOrbit(vxvv=vxvv)
        elif len(vxvv) == 3:
            self._orb = planarROrbit(vxvv=vxvv)
        elif len(vxvv) == 4:
            self._orb = planarOrbit(vxvv=vxvv)
        elif len(vxvv) == 5:
            self._orb = RZOrbit(vxvv=vxvv)
        elif len(vxvv) == 6:
            self._orb = FullOrbit(vxvv=vxvv)
Ejemplo n.º 6
0
def calc_eccentricity(args, options):
    table = os.path.join(args[0],'table2.dat')
    readme = os.path.join(args[0],'ReadMe')
    dierickx = ascii.read(table, readme=readme)
    vxvv = np.dstack([dierickx['RAdeg'], dierickx['DEdeg'], dierickx['Dist']/1e3, dierickx['pmRA'], dierickx['pmDE'], dierickx['HRV']])[0]
    ro, vo, zo = 8., 220., 0.025
    ra, dec= vxvv[:,0], vxvv[:,1]
    lb= bovy_coords.radec_to_lb(ra,dec,degree=True)
    pmra, pmdec= vxvv[:,3], vxvv[:,4]
    pmllpmbb= bovy_coords.pmrapmdec_to_pmllpmbb(pmra,pmdec,ra,dec,degree=True)
    d, vlos= vxvv[:,2], vxvv[:,5]
    rectgal= bovy_coords.sphergal_to_rectgal(lb[:,0],lb[:,1],d,vlos,pmllpmbb[:,0], pmllpmbb[:,1],degree=True)
    vsolar= np.array([-10.1,4.0,6.7])
    vsun= np.array([0.,1.,0.,])+vsolar/vo
    X = rectgal[:,0]/ro
    Y = rectgal[:,1]/ro
    Z = rectgal[:,2]/ro
    vx = rectgal[:,3]/vo
    vy = rectgal[:,4]/vo
    vz = rectgal[:,5]/vo
    vsun= np.array([0.,1.,0.,])+vsolar/vo
    Rphiz= bovy_coords.XYZ_to_galcencyl(X,Y,Z,Zsun=zo/ro)
    vRvTvz= bovy_coords.vxvyvz_to_galcencyl(vx,vy,vz,Rphiz[:,0],Rphiz[:,1],Rphiz[:,2],vsun=vsun,Xsun=1.,Zsun=zo/ro,galcen=True)
    #do the integration and individual analytic estimate for each object
    ts= np.linspace(0.,20.,10000)
    lp= LogarithmicHaloPotential(normalize=1.)
    e_ana = numpy.zeros(len(vxvv))
    e_int = numpy.zeros(len(vxvv))
    print('Performing orbit integration and analytic parameter estimates for Dierickx et al. sample...')
    for i in tqdm(range(len(vxvv))):
        try:
            orbit = Orbit(vxvv[i], radec=True, vo=220., ro=8.)
            e_ana[i] = orbit.e(analytic=True, pot=lp, c=True)
        except UnboundError:
            e_ana[i] = np.nan
        orbit.integrate(ts, lp)
        e_int[i] = orbit.e(analytic=False)
    fig = plt.figure()
    fig.set_size_inches(1.5*columnwidth, 1.5*columnwidth)
    plt.scatter(e_int, e_ana,  s=1, color='Black', lw=0.)
    plt.xlabel(r'$\mathrm{galpy\ integrated}\ e$')
    plt.ylabel(r'$\mathrm{galpy\ analytic}\ e$')
    plt.xlim(0.,1.)
    plt.ylim(0.,1.)
    fig.tight_layout()
    plt.savefig(os.path.join(args[0],'dierickx-integratedeanalytice.png'), format='png', dpi=200)
    fig = plt.figure()
    fig.set_size_inches(1.5*columnwidth, 1.5*columnwidth)
    plt.hist(e_int, bins=30)
    plt.xlim(0.,1.)
    plt.xlabel(r'$\mathrm{galpy}\ e$')
    fig.tight_layout()
    plt.savefig(os.path.join(args[0], 'dierickx-integratedehist.png'), format='png', dpi=200)
    fig = plt.figure()
    fig.set_size_inches(1.5*columnwidth, 1.5*columnwidth)
    plt.scatter(dierickx['e'], e_int,  s=1, color='Black', lw=0.)
    plt.xlabel(r'$\mathrm{Dierickx\ et\ al.}\ e$')
    plt.ylabel(r'$\mathrm{galpy\ integrated}\ e$')
    plt.xlim(0.,1.)
    plt.ylim(0.,1.)
    fig.tight_layout()
    plt.savefig(os.path.join(args[0],'dierickx-integratedee.png'), format='png', dpi=200)
    fig = plt.figure()
    fig.set_size_inches(1.5*columnwidth, 1.5*columnwidth)
    plt.scatter(dierickx['e'], e_ana,  s=1, color='Black', lw=0.)
    plt.xlabel(r'$\mathrm{Dierickx\ et\ al.}\ e$')
    plt.ylabel(r'$\mathrm{galpy\ estimated}\ e$')
    plt.xlim(0.,1.)
    plt.ylim(0.,1.)
    fig.tight_layout()
    plt.savefig(os.path.join(args[0],'dierickx-analyticee.png'), format='png', dpi=200)
    arr = numpy.recarray(len(e_ana), dtype=[('analytic_e', float), ('integrated_e', float)])
    arr['analytic_e'] = e_ana
    arr['integrated_e'] = e_int
    with open(os.path.join(args[0],'eccentricities.dat'), 'w') as file:
        pickle.dump(arr, file)
        file.close()
def obs_to_galcen(ra,
                  dec,
                  dist,
                  pmra,
                  pmdec,
                  rv,
                  pmra_err,
                  pmdec_err,
                  pmra_pmdec_corr,
                  dist_err,
                  rv_err,
                  return_cov=True,
                  verbose=True,
                  return_rphiz=True,
                  ro=8.,
                  vo=220.,
                  zo=0.025,
                  parallax=False):
    vxvv = np.dstack([ra, dec, dist, pmra, pmdec, rv])[0]
    ra, dec = vxvv[:, 0], vxvv[:, 1]
    lb = bovy_coords.radec_to_lb(ra, dec, degree=True)
    pmra, pmdec = vxvv[:, 3], vxvv[:, 4]
    pmllpmbb = bovy_coords.pmrapmdec_to_pmllpmbb(pmra,
                                                 pmdec,
                                                 ra,
                                                 dec,
                                                 degree=True)
    d, vlos = vxvv[:, 2], vxvv[:, 5]
    if parallax:
        d = 1. / d
    rectgal = bovy_coords.sphergal_to_rectgal(lb[:, 0],
                                              lb[:, 1],
                                              d,
                                              vlos,
                                              pmllpmbb[:, 0],
                                              pmllpmbb[:, 1],
                                              degree=True)
    vsolar = np.array([-10.1, 4.0, 6.7])
    vsun = np.array([
        0.,
        1.,
        0.,
    ]) + vsolar / vo
    X = rectgal[:, 0] / ro
    Y = rectgal[:, 1] / ro
    Z = rectgal[:, 2] / ro
    vx = rectgal[:, 3] / vo
    vy = rectgal[:, 4] / vo
    vz = rectgal[:, 5] / vo
    XYZ = np.dstack([X, Y, Z])[0]
    vxyz = np.dstack([vx, vy, vz])[0]
    if return_rphiz:
        Rpz = bovy_coords.XYZ_to_galcencyl(XYZ[:, 0],
                                           XYZ[:, 1],
                                           XYZ[:, 2],
                                           Zsun=zo / ro)
        vRvTvz = bovy_coords.vxvyvz_to_galcencyl(vxyz[:, 0],
                                                 vxyz[:, 1],
                                                 vxyz[:, 2],
                                                 Rpz[:, 0],
                                                 Rpz[:, 1],
                                                 Rpz[:, 2],
                                                 vsun=vsun,
                                                 Xsun=1.,
                                                 Zsun=zo / ro,
                                                 galcen=True)
    if return_cov == True:
        cov_pmradec = np.empty([len(pmra_err), 2, 2])
        cov_pmradec[:, 0, 0] = pmra_err**2
        cov_pmradec[:, 1, 1] = pmdec_err**2
        cov_pmradec[:, 0, 1] = pmra_pmdec_corr * pmra_err * pmdec_err
        cov_pmradec[:, 1, 0] = pmra_pmdec_corr * pmra_err * pmdec_err
        if verbose:
            print('propagating covariance in pmra pmdec -> pmll pmbb')
        cov_pmllbb = bovy_coords.cov_pmrapmdec_to_pmllpmbb(cov_pmradec,
                                                           vxvv[:, 0],
                                                           vxvv[:, 1],
                                                           degree=True,
                                                           epoch='J2015')
        if verbose:
            print('propagating covariance in pmll pmbb -> vx vy vz')
        cov_vxyz = bovy_coords.cov_dvrpmllbb_to_vxyz(vxvv[:, 2], dist_err,
                                                     rv_err, pmllpmbb[:, 0],
                                                     pmllpmbb[:,
                                                              1], cov_pmllbb,
                                                     lb[:, 0], lb[:, 1])
        if not return_rphiz:
            return XYZ, vxyz, cov_vxyz

        if verbose:
            print('propagating covariance in vx vy vz -> vR vT vz')
        cov_galcencyl = bovy_coords.cov_vxyz_to_galcencyl(cov_vxyz,
                                                          Rpz[:, 1],
                                                          Xsun=1.,
                                                          Zsun=zo / ro)
        return XYZ, vxyz, cov_vxyz, Rpz, vRvTvz, cov_galcencyl
    if not return_rphiz:
        return XYZ, vxyz
    return XYZ, vxyz, Rpz, vRvTvz
def dat_to_galcen(
        dat,
        return_cov=True,
        return_rphiz=True,
        verbose=False,
        ro=8.,
        vo=220.,
        zo=0.025,
        keys=['ra', 'dec', 'BPG_meandist', 'pmra', 'pmdec', 'VHELIO_AVG'],
        cov_keys=[
            'pmra_error', 'pmdec_error', 'pmra_pmdec_corr', 'BPG_diststd',
            'VERR'
        ],
        parallax=False):
    vxvv = np.dstack([dat[keys[i]] for i in range(len(keys))])[0]
    ra, dec = vxvv[:, 0], vxvv[:, 1]
    lb = bovy_coords.radec_to_lb(ra, dec, degree=True)
    pmra, pmdec = vxvv[:, 3], vxvv[:, 4]
    pmllpmbb = bovy_coords.pmrapmdec_to_pmllpmbb(pmra,
                                                 pmdec,
                                                 ra,
                                                 dec,
                                                 degree=True)
    d, vlos = vxvv[:, 2], vxvv[:, 5]
    if parallax:
        d = 1. / d
    rectgal = bovy_coords.sphergal_to_rectgal(lb[:, 0],
                                              lb[:, 1],
                                              d,
                                              vlos,
                                              pmllpmbb[:, 0],
                                              pmllpmbb[:, 1],
                                              degree=True)
    vsolar = np.array([-11.1, 245.6,
                       7.25])  #use SBD10 vR and vZ and SGR proper motion vT
    vsun = np.array([
        0.,
        0.,
        0.,
    ]) + vsolar / vo
    X = rectgal[:, 0] / ro
    Y = rectgal[:, 1] / ro
    Z = rectgal[:, 2] / ro
    vx = rectgal[:, 3] / vo
    vy = rectgal[:, 4] / vo
    vz = rectgal[:, 5] / vo
    XYZ = np.dstack([X, Y, Z])[0]
    vxyz = np.dstack([vx, vy, vz])[0]
    if return_rphiz:
        Rpz = bovy_coords.XYZ_to_galcencyl(XYZ[:, 0],
                                           XYZ[:, 1],
                                           XYZ[:, 2],
                                           Zsun=zo / ro)
        vRvTvz = bovy_coords.vxvyvz_to_galcencyl(vxyz[:, 0],
                                                 vxyz[:, 1],
                                                 vxyz[:, 2],
                                                 Rpz[:, 0],
                                                 Rpz[:, 1],
                                                 Rpz[:, 2],
                                                 vsun=vsun,
                                                 Xsun=1.,
                                                 Zsun=zo / ro,
                                                 galcen=True)
    if return_cov == True:
        cov_pmradec = np.array([[[
            dat[cov_keys[0]][i]**2,
            dat[cov_keys[2]][i] * dat[cov_keys[0]][i] * dat[cov_keys[1]][i]
        ],
                                 [
                                     dat[cov_keys[2]][i] *
                                     dat[cov_keys[0]][i] * dat[cov_keys[1]][i],
                                     dat[cov_keys[1]][i]**2
                                 ]] for i in range(len(dat))])
        if verbose:
            print('propagating covariance in pmra pmdec -> pmll pmbb')
        cov_pmllbb = bovy_coords.cov_pmrapmdec_to_pmllpmbb(cov_pmradec,
                                                           vxvv[:, 0],
                                                           vxvv[:, 1],
                                                           degree=True,
                                                           epoch='J2015')
        if verbose:
            print('propagating covariance in pmll pmbb -> vx vy vz')
        cov_vxyz = bovy_coords.cov_dvrpmllbb_to_vxyz(vxvv[:,
                                                          2], dat[cov_keys[3]],
                                                     dat[cov_keys[4]],
                                                     pmllpmbb[:,
                                                              0], pmllpmbb[:,
                                                                           1],
                                                     cov_pmllbb, lb[:,
                                                                    0], lb[:,
                                                                           1])
        if not return_rphiz:
            return XYZ, vxyz, cov_vxyz

        if verbose:
            print('propagating covariance in vx vy vz -> vR vT vz')
        cov_galcencyl = bovy_coords.cov_vxyz_to_galcencyl(cov_vxyz,
                                                          Rpz[:, 1],
                                                          Xsun=1.,
                                                          Zsun=zo / ro)
        return XYZ, vxyz, cov_vxyz, Rpz, vRvTvz, cov_galcencyl
    if not return_rphiz:
        return XYZ, vxyz
    return XYZ, vxyz, Rpz, vRvTvz
def calc_eccentricity(args, options):
    table = os.path.join(args[0], 'table2.dat')
    readme = os.path.join(args[0], 'ReadMe')
    dierickx = ascii.read(table, readme=readme)
    vxvv = np.dstack([
        dierickx['RAdeg'], dierickx['DEdeg'], dierickx['Dist'] / 1e3,
        dierickx['pmRA'], dierickx['pmDE'], dierickx['HRV']
    ])[0]
    ro, vo, zo = 8., 220., 0.025
    ra, dec = vxvv[:, 0], vxvv[:, 1]
    lb = bovy_coords.radec_to_lb(ra, dec, degree=True)
    pmra, pmdec = vxvv[:, 3], vxvv[:, 4]
    pmllpmbb = bovy_coords.pmrapmdec_to_pmllpmbb(pmra,
                                                 pmdec,
                                                 ra,
                                                 dec,
                                                 degree=True)
    d, vlos = vxvv[:, 2], vxvv[:, 5]
    rectgal = bovy_coords.sphergal_to_rectgal(lb[:, 0],
                                              lb[:, 1],
                                              d,
                                              vlos,
                                              pmllpmbb[:, 0],
                                              pmllpmbb[:, 1],
                                              degree=True)
    vsolar = np.array([-10.1, 4.0, 6.7])
    vsun = np.array([
        0.,
        1.,
        0.,
    ]) + vsolar / vo
    X = rectgal[:, 0] / ro
    Y = rectgal[:, 1] / ro
    Z = rectgal[:, 2] / ro
    vx = rectgal[:, 3] / vo
    vy = rectgal[:, 4] / vo
    vz = rectgal[:, 5] / vo
    vsun = np.array([
        0.,
        1.,
        0.,
    ]) + vsolar / vo
    Rphiz = bovy_coords.XYZ_to_galcencyl(X, Y, Z, Zsun=zo / ro)
    vRvTvz = bovy_coords.vxvyvz_to_galcencyl(vx,
                                             vy,
                                             vz,
                                             Rphiz[:, 0],
                                             Rphiz[:, 1],
                                             Rphiz[:, 2],
                                             vsun=vsun,
                                             Xsun=1.,
                                             Zsun=zo / ro,
                                             galcen=True)
    #do the integration and individual analytic estimate for each object
    ts = np.linspace(0., 20., 10000)
    lp = LogarithmicHaloPotential(normalize=1.)
    e_ana = numpy.zeros(len(vxvv))
    e_int = numpy.zeros(len(vxvv))
    print(
        'Performing orbit integration and analytic parameter estimates for Dierickx et al. sample...'
    )
    for i in tqdm(range(len(vxvv))):
        try:
            orbit = Orbit(vxvv[i], radec=True, vo=220., ro=8.)
            e_ana[i] = orbit.e(analytic=True, pot=lp, c=True)
        except UnboundError:
            e_ana[i] = np.nan
        orbit.integrate(ts, lp)
        e_int[i] = orbit.e(analytic=False)
    fig = plt.figure()
    fig.set_size_inches(1.5 * columnwidth, 1.5 * columnwidth)
    plt.scatter(e_int, e_ana, s=1, color='Black', lw=0.)
    plt.xlabel(r'$\mathrm{galpy\ integrated}\ e$')
    plt.ylabel(r'$\mathrm{galpy\ analytic}\ e$')
    plt.xlim(0., 1.)
    plt.ylim(0., 1.)
    fig.tight_layout()
    plt.savefig(os.path.join(args[0], 'dierickx-integratedeanalytice.png'),
                format='png',
                dpi=200)
    fig = plt.figure()
    fig.set_size_inches(1.5 * columnwidth, 1.5 * columnwidth)
    plt.hist(e_int, bins=30)
    plt.xlim(0., 1.)
    plt.xlabel(r'$\mathrm{galpy}\ e$')
    fig.tight_layout()
    plt.savefig(os.path.join(args[0], 'dierickx-integratedehist.png'),
                format='png',
                dpi=200)
    fig = plt.figure()
    fig.set_size_inches(1.5 * columnwidth, 1.5 * columnwidth)
    plt.scatter(dierickx['e'], e_int, s=1, color='Black', lw=0.)
    plt.xlabel(r'$\mathrm{Dierickx\ et\ al.}\ e$')
    plt.ylabel(r'$\mathrm{galpy\ integrated}\ e$')
    plt.xlim(0., 1.)
    plt.ylim(0., 1.)
    fig.tight_layout()
    plt.savefig(os.path.join(args[0], 'dierickx-integratedee.png'),
                format='png',
                dpi=200)
    fig = plt.figure()
    fig.set_size_inches(1.5 * columnwidth, 1.5 * columnwidth)
    plt.scatter(dierickx['e'], e_ana, s=1, color='Black', lw=0.)
    plt.xlabel(r'$\mathrm{Dierickx\ et\ al.}\ e$')
    plt.ylabel(r'$\mathrm{galpy\ estimated}\ e$')
    plt.xlim(0., 1.)
    plt.ylim(0., 1.)
    fig.tight_layout()
    plt.savefig(os.path.join(args[0], 'dierickx-analyticee.png'),
                format='png',
                dpi=200)
    arr = numpy.recarray(len(e_ana),
                         dtype=[('analytic_e', float),
                                ('integrated_e', float)])
    arr['analytic_e'] = e_ana
    arr['integrated_e'] = e_int
    with open(os.path.join(args[0], 'eccentricities.dat'), 'w') as file:
        pickle.dump(arr, file)
        file.close()