예제 #1
0
def get_rcsample():
    """
    NAME:
       get_rcsample
    PURPOSE:
       get the RC sample
    INPUT:
       None so far
    OUTPUT:
       sample
    HISTORY:
       2015-02-10 - Started - Bovy (IAS@KITP)
    """
    data = apread.rcsample()
    # Cut to statistical sample
    data = data[data['STAT'] == 1]
    # Add the M_H-based distances
    data = esutil.numpy_util.add_fields(data, [('RC_DIST_H', float),
                                               ('RC_DM_H', float),
                                               ('RC_GALR_H', float),
                                               ('RC_GALPHI_H', float),
                                               ('RC_GALZ_H', float)])
    rcd = rcdist()
    jk = data['J0'] - data['K0']
    z = isodist.FEH2Z(data['METALS'], zsolar=0.017)
    data['RC_DIST_H'] = rcd(jk, z, appmag=data['H0'], mh=True)
    data['RC_DM_H'] = 5. * numpy.log10(data['RC_DIST_H']) + 10.
    XYZ = bovy_coords.lbd_to_XYZ(data['GLON'],
                                 data['GLAT'],
                                 data['RC_DIST_H'],
                                 degree=True)
    R, phi, Z = bovy_coords.XYZ_to_galcencyl(XYZ[:, 0],
                                             XYZ[:, 1],
                                             XYZ[:, 2],
                                             Xsun=8.,
                                             Zsun=0.025)
    data['RC_GALR_H'] = R
    data['RC_GALPHI_H'] = phi
    data['RC_GALZ_H'] = Z
    # Add the average alpha/Fe
    data = esutil.numpy_util.add_fields(data, [('AVG_ALPHAFE', float)])
    data['AVG_ALPHAFE'] = avg_alphafe(data)
    # Apply -0.1 offset in [Fe/H]
    data[_FEHTAG] += -0.10
    # Remove locations outside of the Pan-STARRS dust map
    # In the Southern hemisphere
    data = data[data['LOCATION_ID'] != 4266]  #240,-18
    data = data[data['LOCATION_ID'] != 4331]  #5.5,-14.2
    data = data[data['LOCATION_ID'] != 4381]  #5.2,-12.2
    data = data[data['LOCATION_ID'] != 4332]  #1,-4
    data = data[data['LOCATION_ID'] != 4329]  #0,-5
    data = data[data['LOCATION_ID'] != 4351]  #0,-2
    data = data[data['LOCATION_ID'] != 4353]  #358,0
    data = data[data['LOCATION_ID'] != 4385]  #358.6,1.4
    # Close to the ecliptic pole where there's no data (is it the ecliptic pole?
    data = data[data['LOCATION_ID'] != 4528]  #120,30
    data = data[data['LOCATION_ID'] != 4217]  #123,22.4
    # Remove stars w/ DM < 8.49, because for standard candle RC, these cannot be in the sample
    data = data[data['RC_DM_H'] > 8.49]
    return data
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
예제 #3
0
def _setup_effvol(locations, effsel, distmods):
    # First restore the APOGEE selection function (assumed pre-computed)
    selectFile = '../savs/selfunc-nospdata.sav'
    if os.path.exists(selectFile):
        with open(selectFile, 'rb') as savefile:
            apo = pickle.load(savefile)
    # Now compute the necessary coordinate transformations
    ds = 10.**(distmods / 5 - 2.)
    Rgrid, phigrid, zgrid = [], [], []
    for loc in locations:
        lcen, bcen = apo.glonGlat(loc)
        XYZ = bovy_coords.lbd_to_XYZ(lcen * numpy.ones_like(ds),
                                     bcen * numpy.ones_like(ds),
                                     ds,
                                     degree=True)
        Rphiz = bovy_coords.XYZ_to_galcencyl(XYZ[:, 0],
                                             XYZ[:, 1],
                                             XYZ[:, 2],
                                             Xsun=define_rcsample._R0,
                                             Ysun=0.,
                                             Zsun=define_rcsample._Z0)
        Rgrid.append(Rphiz[0])
        phigrid.append(Rphiz[1])
        zgrid.append(Rphiz[2])
    Rgrid = numpy.array(Rgrid)
    phigrid = numpy.array(phigrid)
    zgrid = numpy.array(zgrid)
    # Also need to multiply in distance factors
    effsel *= numpy.tile(ds**3. * (distmods[1] - distmods[0]),
                         (effsel.shape[0], 1))
    return (effsel, Rgrid, phigrid, zgrid)
def force_pal5(pot: PotentialType,
               dpal5: float,
               ro: float = REFR0,
               vo: float = REFV0) -> Tuple[float]:
    """Return the force at Pal5.

    Parameters
    ----------
    pot: Potential, list
    dpal5: float
    ro, vo: float

    Return
    ------
    force: tuple
        [fx, fy, fz]

    """
    from galpy import potential
    from galpy.util import bovy_coords

    # First compute the location based on the distance
    l5, b5 = bovy_coords.radec_to_lb(229.018, -0.124, degree=True)
    X5, Y5, Z5 = bovy_coords.lbd_to_XYZ(l5, b5, dpal5, degree=True)
    R5, p5, Z5 = bovy_coords.XYZ_to_galcencyl(X5, Y5, Z5, Xsun=ro, Zsun=0.025)

    args: list = [pot, R5 / ro, Z5 / ro]
    kws: dict = {"phi": p5, "use_physical": True, "ro": ro, "vo": vo}

    return (
        potential.evaluateRforces(*args, **kws),
        potential.evaluatezforces(*args, **kws),
        potential.evaluatephiforces(*args, **kws),
    )
예제 #5
0
 def glon_wrapper(*args,**kwargs):
     if kwargs.pop('glon',False):
         XYZ= bovy_coords.lbd_to_XYZ(args[0],args[1],args[2],degree=False)
         R,phi,z= bovy_coords.XYZ_to_galcencyl(XYZ[:,0],XYZ[:,1],XYZ[:,2],
                                               Xsun=_R0,Zsun=_Zsun)
     else:
         R,phi,z= args[0],args[1],args[2]
     return func(R,phi,z,*args[3:],**kwargs)
예제 #6
0
def lbd_to_galcencyl(l, b, d, degree=True):
    xyz = bovy_coords.lbd_to_XYZ(l, b, d, degree=degree)
    Rphiz = bovy_coords.XYZ_to_galcencyl(xyz[:, 0],
                                         xyz[:, 1],
                                         xyz[:, 2],
                                         Xsun=1.,
                                         Zsun=0.)

    return (Rphiz[:, 0], Rphiz[:, 1], Rphiz[:, 2])
def force_pal5(pot,dpal5,ro,vo):
    """Return the force at Pal5"""
    # First compute the location based on the distance
    l5, b5= bovy_coords.radec_to_lb(229.018,-0.124,degree=True)
    X5,Y5,Z5= bovy_coords.lbd_to_XYZ(l5,b5,dpal5,degree=True)
    R5,p5,Z5= bovy_coords.XYZ_to_galcencyl(X5,Y5,Z5,Xsun=ro,Zsun=0.025)
    return (potential.evaluateRforces(pot,R5/ro,Z5/ro,phi=p5,
                                      use_physical=True,ro=ro,vo=vo),
            potential.evaluatezforces(pot,R5/ro,Z5/ro,phi=p5,
                                      use_physical=True,ro=ro,vo=vo),
            potential.evaluatephiforces(pot,R5/ro,Z5/ro,phi=p5,
                                        use_physical=True,ro=ro,vo=vo))
예제 #8
0
def test_coords():
    from galpy.util import bovy_coords
    ra, dec, dist = 161., 50., 8.5
    pmra, pmdec, vlos = -6.8, -10., -115.
    # Convert to Galactic and then to rect. Galactic
    ll, bb = bovy_coords.radec_to_lb(ra, dec, degree=True)
    pmll, pmbb = bovy_coords.pmrapmdec_to_pmllpmbb(pmra,
                                                   pmdec,
                                                   ra,
                                                   dec,
                                                   degree=True)
    X, Y, Z = bovy_coords.lbd_to_XYZ(ll, bb, dist, degree=True)
    vX, vY, vZ = bovy_coords.vrpmllpmbb_to_vxvyvz(vlos,
                                                  pmll,
                                                  pmbb,
                                                  X,
                                                  Y,
                                                  Z,
                                                  XYZ=True)
    # Convert to cylindrical Galactocentric
    # Assuming Sun's distance to GC is (8,0.025) in (R,z)
    R, phi, z = bovy_coords.XYZ_to_galcencyl(X, Y, Z, Xsun=8., Zsun=0.025)
    vR, vT, vz = bovy_coords.vxvyvz_to_galcencyl(vX,
                                                 vY,
                                                 vZ,
                                                 R,
                                                 phi,
                                                 Z,
                                                 vsun=[-10.1, 244., 6.7],
                                                 galcen=True)
    # 5/12/2016: test weakened, because improved galcen<->heliocen
    #            transformation has changed these, but still close
    print(R, phi, z, vR, vT, vz)
    assert numpy.fabs(R - 12.51328515156942
                      ) < 10.**-1., 'Coordinate transformation has changed'
    assert numpy.fabs(phi - 0.12177409073433249
                      ) < 10.**-1., 'Coordinate transformation has changed'
    assert numpy.fabs(z - 7.1241282354856228
                      ) < 10.**-1., 'Coordinate transformation has changed'
    assert numpy.fabs(vR - 78.961682923035966
                      ) < 10.**-1., 'Coordinate transformation has changed'
    assert numpy.fabs(vT + 241.49247772351964
                      ) < 10.**-1., 'Coordinate transformation has changed'
    assert numpy.fabs(vz + 102.83965442188689
                      ) < 10.**-1., 'Coordinate transformation has changed'
    return None
예제 #9
0
def Rphizgrid(apo,distmods):
    """
    Generates a grid of R, phi, z for each location in apo at the distance moduli supplied
    """
    ds = 10**(distmods/5.-2.)
    Rgrid = np.zeros((len(apo._locations),len(ds)))
    phigrid = np.zeros((len(apo._locations),len(ds)))
    zgrid = np.zeros((len(apo._locations),len(ds)))
    for i in range(len(apo._locations)):
        glon,glat = apo.glonGlat(apo._locations[i])
        glon = np.ones(len(ds))*glon[0]
        glat = np.ones(len(ds))*glat[0]
        xyz = bovy_coords.lbd_to_XYZ(glon,glat,ds, degree=True)
        rphiz = bovy_coords.XYZ_to_galcencyl(xyz[:,0], xyz[:,1], xyz[:,2], Xsun=8., Zsun=0.02)
        Rgrid[i] = rphiz[:,0]
        phigrid[i] = rphiz[:,1]
        zgrid[i] = rphiz[:,2]
    return Rgrid, phigrid, zgrid
예제 #10
0
def _calc_lnprob(loc, nls, nbs, ds, distmods, H0, densfunc):
    lcen, bcen = apo.glonGlat(loc)
    rad = apo.radius(loc)
    ls = numpy.linspace(lcen - rad, lcen + rad, nls)
    bs = numpy.linspace(bcen - rad, bcen + rad, nbs)
    # Tile these
    tls = numpy.tile(ls, (len(ds), len(bs), 1))
    tbs = numpy.swapaxes(numpy.tile(bs, (len(ds), len(ls), 1)), 1, 2)
    tds = numpy.tile(ds, (len(ls), len(bs), 1)).T
    XYZ = bovy_coords.lbd_to_XYZ(tls.flatten(),
                                 tbs.flatten(),
                                 tds.flatten(),
                                 degree=True)
    Rphiz = bovy_coords.XYZ_to_galcencyl(XYZ[:, 0],
                                         XYZ[:, 1],
                                         XYZ[:, 2],
                                         Xsun=define_rcsample._R0,
                                         Ysun=0.,
                                         Zsun=define_rcsample._Z0)
    # Evaluate probability density
    tH = numpy.tile(distmods.T, (1, len(ls), len(bs), 1))[0].T
    for ii in range(tH.shape[1]):
        for jj in range(tH.shape[2]):
            try:
                tH[:, ii, jj] += dmap(ls[jj], bs[ii], ds)
            except (IndexError, TypeError, ValueError):
                try:
                    tH[:, ii, jj] += dmapg15(ls[jj], bs[ii], ds)
                except IndexError:  # assume zero outside
                    pass
    tH = tH.flatten() + H0[0]
    ps= densfunc(Rphiz[0],Rphiz[1],Rphiz[2])*apo(loc,tH)\
        *numpy.fabs(numpy.cos(tbs.flatten()/180.*numpy.pi))\
        *tds.flatten()**3.
    return numpy.log(numpy.reshape(ps,(len(distmods),nbs,nls))\
                         +10.**-8.)
예제 #11
0
def calc_normalisation(params,
                       nbin,
                       iso_grid,
                       fehbin=[-0.1, 0.0],
                       agebin=[1., 3.],
                       loggcut=[1.8, 3.0],
                       teffcut=[4000, 5000],
                       type='brokenexpflare',
                       verbose=True,
                       fitIndx=None,
                       weights='padova',
                       distance_cut=False,
                       lowermass=None):
    #first get the values necessary from the isochrone grid
    #make a mask for giant stars (+ J-K cut)
    if teffcut == None:
        giants = (iso_grid[:, 3] >= loggcut[0]) & (
            iso_grid[:, 3] < loggcut[1]) & (iso_grid[:, 5] > 0.5)
    else:
        giants = (iso_grid[:, 3] >= loggcut[0]) & (
            iso_grid[:, 3] < loggcut[1]) & (iso_grid[:, 5] > 0.5) & (
                10**iso_grid[:, 7] >= teffcut[0]) & (10**iso_grid[:, 7] <
                                                     teffcut[1])
    #make a mask for the age and feh bin
    if agebin == None:
        bin = (10**iso_grid[:,0] >= 0.)&(10**iso_grid[:,0] < 13.)&\
             (Z2FEH(iso_grid[:,1]) >= fehbin[0])&(Z2FEH(iso_grid[:,1]) < fehbin[1])
    else:
        bin = (10**iso_grid[:,0] >= agebin[0])&(10**iso_grid[:,0] < agebin[1])&\
             (Z2FEH(iso_grid[:,1]) >= fehbin[0])&(Z2FEH(iso_grid[:,1]) < fehbin[1])

    if lowermass != None:
        giants *= iso_grid[:, 2] >= lowermass
        bin *= iso_grid[:, 2] >= lowermass
    if len(iso_grid[:, 0][bin]) < 1:
        fehs = np.unique(Z2FEH(iso_grid[:, 1]))
        cfehbin = fehbin[0] + ((fehbin[1] - fehbin[0]) / 2)
        feh_offsets = np.fabs(fehs - cfehbin)
        ind = np.argmin(feh_offsets)
        cfeh = fehs[ind]
        bin = (10**iso_grid[:,0] >= agebin[0])&(10**iso_grid[:,0] < agebin[1])&\
          (Z2FEH(iso_grid[:,1]) == cfeh)
    #find the average giant mass
    mass = iso_grid[:, 2]
    if weights == 'padova':
        weight = iso_grid[:, 6] * (10**iso_grid[:, 0] / iso_grid[:, 1])
    if weights == 'basti':
        weight = iso_grid[:, 6]
    av_mass = np.sum(mass[giants & bin] * weight[giants & bin]) / np.sum(
        weight[giants & bin])
    #find the ratio between giants and the total stellar pop. for this bin
    mass_total = mass[bin]
    weight_total = weight[bin]
    mass_bin = mass[giants & bin]
    weight_bin = weight[giants & bin]
    m_ratio = np.sum(mass_bin * weight_bin) / np.sum(mass_total * weight_total)
    #now compute and sum the rate for this density function
    #load the raw selection function
    selectFile = '../savs/selfunc-nospdata.sav'
    if os.path.exists(selectFile):
        with open(selectFile, 'rb') as savefile:
            apo = pickle.load(savefile)
    #load the effective selection function
        if agebin == None:
            with open(
                    '../essf/maps/essf_rgb_green15_modelmh_feh' +
                    str(round(fehbin[0], 1)) + '.sav', 'rb') as savefile:
                locations = pickle.load(savefile)
                effsel = pickle.load(savefile)
                distmods = pickle.load(savefile)
            with open(
                    '../essf/maps/essf_rgb_marshall06_modelmh_feh' +
                    str(round(fehbin[0], 1)) + '.sav', 'rb') as savefile:
                mlocations = pickle.load(savefile)
                meffsel = pickle.load(savefile)
                mdistmods = pickle.load(savefile)
    if agebin != None:
        if agebin[0] < 1.:
            with open(
                    '../essf/maps/essf_rgb_green15_modelmh_feh' +
                    str(round(fehbin[0], 1)) + '_age' + str(round(1.0, 1)) +
                    '.sav', 'rb') as savefile:
                locations = pickle.load(savefile)
                effsel = pickle.load(savefile)
                distmods = pickle.load(savefile)
            with open(
                    '../essf/maps/essf_rgb_marshall06_modelmh_feh' +
                    str(round(fehbin[0], 1)) + '_age' + str(round(1.0, 1)) +
                    '.sav', 'rb') as savefile:
                mlocations = pickle.load(savefile)
                meffsel = pickle.load(savefile)
                mdistmods = pickle.load(savefile)
        if agebin[0] > 0.9:
            with open(
                    '../essf/maps/essf_rgb_green15_modelmh_feh' +
                    str(round(fehbin[0], 1)) + '_age' +
                    str(round(agebin[0], 1)) + '.sav', 'rb') as savefile:
                locations = pickle.load(savefile)
                effsel = pickle.load(savefile)
                distmods = pickle.load(savefile)
            with open(
                    '../essf/maps/essf_rgb_marshall06_modelmh_feh' +
                    str(round(fehbin[0], 1)) + '_age' +
                    str(round(agebin[0], 1)) + '.sav', 'rb') as savefile:
                mlocations = pickle.load(savefile)
                meffsel = pickle.load(savefile)
                mdistmods = pickle.load(savefile)

    # Fill in regions not covered by Marshall map
    meffsel[meffsel < -0.5] = effsel[meffsel < -0.5]
    if fitIndx is None:
        fitIndx = numpy.ones(len(mlocations), dtype='bool')  #True-betwDiskIndx
    locations, effsel, distmods = np.array(mlocations)[fitIndx], np.array(
        meffsel)[fitIndx], mdistmods
    #get the density function and set it up to find the normalisation (surfdens=True)
    rdensfunc = _setup_densfunc(type)
    densfunc = lambda x: rdensfunc(x, None, None, params=params, surfdens=True)
    #evaluate surface density at R0 for the density normalisation (always 1. if R_b > R0)
    R0 = densprofiles._R0
    Rb = np.exp(params[3])
    dens_norm = densfunc(densprofiles._R0)
    #set up the density function again with surfdens=False for the rate calculation
    rdensfunc = _setup_densfunc(type)
    densfunc = lambda x, y, z: rdensfunc(
        x, y, z, params=params, surfdens=False)
    ds = 10.**(distmods / 5. - 2.)
    #imply the distance cut if distance_cut == True
    if distance_cut == True:
        distmods = distmods[ds <= 3.]
        ds = ds[ds <= 3.]
        effsel = effsel[:, :len(ds)]
    #Compute the grid of R, phi and Z for each location
    Rgrid, phigrid, zgrid = [], [], []
    for loc in locations:
        lcen, bcen = apo.glonGlat(loc)
        XYZ = bovy_coords.lbd_to_XYZ(lcen * numpy.ones_like(ds),
                                     bcen * numpy.ones_like(ds),
                                     ds,
                                     degree=True)
        Rphiz = bovy_coords.XYZ_to_galcencyl(XYZ[:, 0],
                                             XYZ[:, 1],
                                             XYZ[:, 2],
                                             Xsun=define_rgbsample._R0,
                                             Zsun=define_rgbsample._Z0)
        Rgrid.append(Rphiz[:, 0])
        phigrid.append(Rphiz[:, 1])
        zgrid.append(Rphiz[:, 2])
    Rgrid = numpy.array(Rgrid)
    phigrid = numpy.array(phigrid)
    zgrid = numpy.array(zgrid)
    # Now compute rate(R) for each location and combine
    effsel *= numpy.tile(
        ds**2. * (distmods[1] - distmods[0]) * (ds * np.log(10) / 5.),
        (effsel.shape[0], 1))
    tdens = densfunc(Rgrid, phigrid, zgrid) / dens_norm
    rate = tdens * effsel
    sumrate = np.sum(rate)
    #calculate normalisation N(R0)
    norm = (nbin / sumrate)
    #convert units (Kpc^2 > pc^2, deg > rad etc)
    norm *= 1e-6 * (180 / np.pi)**2
    #compute mass in bin using values from isochrones
    bin_mass = (norm * av_mass) / m_ratio
    if verbose == True:
        print bin_mass
    return bin_mass, norm, m_ratio, (av_mass * 1e-6 *
                                     (180 / np.pi)**2) / (sumrate * m_ratio)
예제 #12
0
def lbd_to_galcencyl(l,b,d,degree=True):   
    xyz=bovy_coords.lbd_to_XYZ(l,b,d,degree=degree) ## These are in physical units, DUMB DUMB DUMB!!!
    Rphiz=bovy_coords.XYZ_to_galcencyl(xyz[:,0]/ro,xyz[:,1]/ro,xyz[:,2]/ro,Xsun=1.,Zsun=0.) 
    return (Rphiz[:,0]*ro,Rphiz[:,1],Rphiz[:,2]*ro)
예제 #13
0
def action(ra_deg, dec_deg, d_kpc, pm_ra_masyr, pm_dec_masyr, v_los_kms,
           verbose=False):
    """
    parameters:
    ----------
    ra_deg: (float)
        RA in degrees.
    dec_deg: (float)
        Dec in degress.
    d_kpc: (float)
        Distance in kpc.
    pm_ra_masyr: (float)
        RA proper motion in mas/yr.
    pm_decmasyr: (float)
        Dec proper motion in mas/yr.
    v_los_kms: (float)
        RV in kms.
    returns:
    ------
    R_kpc, phi_rad, z_kpc, vR_kms, vT_kms, vz_kms
    jR: (float)
        Radial action.
    lz: (float)
        Vertical ang mom.
    jz: (float)
        Vertical action.
    """
    ra_rad = ra_deg * (np.pi / 180.)  # RA [rad]
    dec_rad = dec_deg * (np.pi / 180.)  # dec [rad]

    # Galactocentric position of the Sun:
    X_gc_sun_kpc = 8.  # [kpc]
    Z_gc_sun_kpc = 0.025  # [kpc]

    # Galactocentric velocity of the Sun:
    vX_gc_sun_kms = -9.58  # = -U              [kms]
    vY_gc_sun_kms = 10.52 + 220.  # = V+v_circ(R_Sun) [kms]
    vZ_gc_sun_kms = 7.01  # = W               [kms]

    # a. convert spatial coordinates (ra,dec,d) to (R,z,phi)

    # (ra,dec) --> Galactic coordinates (l,b):
    lb = bovy_coords.radec_to_lb(ra_rad, dec_rad, degree=False, epoch=2000.0)
    # l_rad = lb[:, 0]
    # b_rad = lb[:, 1]
    l_rad = lb[0]
    b_rad = lb[1]

    # (l,b,d) --> Galactocentric cartesian coordinates (x,y,z):
    xyz = bovy_coords.lbd_to_XYZ(l_rad, b_rad, d_kpc, degree=False)
    # x_kpc = xyz[:, 0]
    # y_kpc = xyz[:, 1]
    # z_kpc = xyz[:, 2]
    x_kpc = xyz[0]
    y_kpc = xyz[1]
    z_kpc = xyz[2]

    # (x,y,z) --> Galactocentric cylindrical coordinates (R,z,phi):
    Rzphi = bovy_coords.XYZ_to_galcencyl(x_kpc, y_kpc, z_kpc,
                                         Xsun=X_gc_sun_kpc, Zsun=Z_gc_sun_kpc)
    # R_kpc = Rzphi[:, 0]
    # phi_rad = Rzphi[:, 1]
    # z_kpc = Rzphi[:, 2]
    R_kpc = Rzphi[0]
    phi_rad = Rzphi[1]
    z_kpc = Rzphi[2]

    # b. convert velocities (pm_ra,pm_dec,vlos) to (vR,vz,vT)

    # (pm_ra,pm_dec) --> (pm_l,pm_b):
    pmlpmb = bovy_coords.pmrapmdec_to_pmllpmbb(pm_ra_masyr, pm_dec_masyr,
                                               ra_rad, dec_rad, degree=False,
                                               epoch=2000.0)
    # pml_masyr = pmlpmb[:, 0]
    # pmb_masyr = pmlpmb[:, 1]
    pml_masyr = pmlpmb[0]
    pmb_masyr = pmlpmb[1]

    # (v_los,pm_l,pm_b) & (l,b,d) --> (vx,vy,vz):
    vxvyvz = bovy_coords.vrpmllpmbb_to_vxvyvz(v_los_kms, pml_masyr, pmb_masyr,
                                              l_rad, b_rad, d_kpc, XYZ=False,
                                              degree=False)
    # vx_kms = vxvyvz[:, 0]
    # vy_kms = vxvyvz[:, 1]
    # vz_kms = vxvyvz[:, 2]
    vx_kms = vxvyvz[0]
    vy_kms = vxvyvz[1]
    vz_kms = vxvyvz[2]

    # (vx,vy,vz) & (x,y,z) --> (vR,vT,vz):
    vRvTvZ = bovy_coords.vxvyvz_to_galcencyl(vx_kms, vy_kms, vz_kms, R_kpc,
                                             phi_rad, z_kpc,
                                             vsun=[vX_gc_sun_kms,
                                                   vY_gc_sun_kms,
                                                   vZ_gc_sun_kms],
                                             galcen=True)
    # vR_kms = vRvTvZ[:, 0]
    # vT_kms = vRvTvZ[:, 1]
    # vz_kms = vRvTvZ[:, 2]
    vR_kms = vRvTvZ[0]
    vT_kms = vRvTvZ[1]
    vz_kms = vRvTvZ[2]

    if verbose:
        print("R = ", R_kpc, "\t kpc")
        print("phi = ", phi_rad, "\t rad")
        print("z = ", z_kpc, "\t kpc")
        print("v_R = ", vR_kms, "\t km/s")
        print("v_T = ", vT_kms, "\t km/s")
        print("v_z = ", vz_kms, "\t km/s")

    jR, lz, jz = calc_actions(R_kpc, phi_rad, z_kpc, vR_kms, vT_kms, vz_kms)

    return R_kpc, phi_rad, z_kpc, vR_kms, vT_kms, vz_kms, jR, lz, jz
예제 #14
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)
예제 #15
0
def make_rcsample(parser):
    options, args = parser.parse_args()
    savefilename = options.savefilename
    if savefilename is None:
        #Create savefilename if not given
        savefilename = os.path.join(
            appath._APOGEE_DATA, 'rcsample_' + appath._APOGEE_REDUX + '.fits')
        print("Saving to %s ..." % savefilename)
    #Read the base-sample
    data = apread.allStar(adddist=_ADDHAYDENDIST, rmdups=options.rmdups)
    #Remove a bunch of fields that we do not want to keep
    data = esutil.numpy_util.remove_fields(data, [
        'TARGET_ID', 'FILE', 'AK_WISE', 'SFD_EBV', 'SYNTHVHELIO_AVG',
        'SYNTHVSCATTER', 'SYNTHVERR', 'SYNTHVERR_MED', 'RV_TEFF', 'RV_LOGG',
        'RV_FEH', 'RV_ALPHA', 'RV_CARB', 'RV_CCFWHM', 'RV_AUTOFWHM',
        'SYNTHSCATTER', 'STABLERV_CHI2', 'STABLERV_RCHI2',
        'STABLERV_CHI2_PROB', 'CHI2_THRESHOLD', 'APSTAR_VERSION',
        'ASPCAP_VERSION', 'RESULTS_VERSION', 'WASH_M', 'WASH_M_ERR', 'WASH_T2',
        'WASH_T2_ERR', 'DDO51', 'DDO51_ERR', 'IRAC_3_6', 'IRAC_3_6_ERR',
        'IRAC_4_5', 'IRAC_4_5_ERR', 'IRAC_5_8', 'IRAC_5_8_ERR', 'IRAC_8_0',
        'IRAC_8_0_ERR', 'WISE_4_5', 'WISE_4_5_ERR', 'TARG_4_5', 'TARG_4_5_ERR',
        'WASH_DDO51_GIANT_FLAG', 'WASH_DDO51_STAR_FLAG', 'REDUCTION_ID',
        'SRC_H', 'PM_SRC'
    ])
    # More
    if appath._APOGEE_REDUX.lower() == 'l33':
        data = esutil.numpy_util.remove_fields(data, [
            'GAIA_SOURCE_ID', 'GAIA_PARALLAX', 'GAIA_PARALLAX_ERROR',
            'GAIA_PMRA', 'GAIA_PMRA_ERROR', 'GAIA_PMDEC', 'GAIA_PMDEC_ERROR',
            'GAIA_PHOT_G_MEAN_MAG', 'GAIA_PHOT_BP_MEAN_MAG',
            'GAIA_PHOT_RP_MEAN_MAG', 'GAIA_RADIAL_VELOCITY',
            'GAIA_RADIAL_VELOCITY_ERROR', 'GAIA_R_EST', 'GAIA_R_LO',
            'GAIA_R_HI', 'TEFF_SPEC', 'LOGG_SPEC'
        ])
    if not appath._APOGEE_REDUX.lower() == 'current' \
            and not 'l3' in appath._APOGEE_REDUX \
            and int(appath._APOGEE_REDUX[1:]) < 500:
        data = esutil.numpy_util.remove_fields(data, ['ELEM'])
    #Select red-clump stars
    jk = data['J0'] - data['K0']
    z = isodist.FEH2Z(data['METALS'], zsolar=0.017)
    if 'l31' in appath._APOGEE_REDUX:
        logg = data['LOGG']
    elif 'l30' in appath._APOGEE_REDUX:
        logg = data['LOGG']
    elif appath._APOGEE_REDUX.lower() == 'current' \
            or int(appath._APOGEE_REDUX[1:]) > 600:
        if False:
            #Use my custom logg calibration that's correct for the RC
            logg = (1. - 0.042) * data['FPARAM'][:, paramIndx('logg')] - 0.213
            lowloggindx = data['FPARAM'][:, paramIndx('logg')] < 1.
            logg[lowloggindx] = data['FPARAM'][lowloggindx,
                                               paramIndx('logg')] - 0.255
            hiloggindx = data['FPARAM'][:, paramIndx('logg')] > 3.8
            logg[hiloggindx] = data['FPARAM'][hiloggindx,
                                              paramIndx('logg')] - 0.3726
        else:
            #Use my custom logg calibration that's correct on average
            logg = (1. + 0.03) * data['FPARAM'][:, paramIndx('logg')] - 0.37
            lowloggindx = data['FPARAM'][:, paramIndx('logg')] < 1.
            logg[lowloggindx] = data['FPARAM'][lowloggindx,
                                               paramIndx('logg')] - 0.34
            hiloggindx = data['FPARAM'][:, paramIndx('logg')] > 3.8
            logg[hiloggindx] = data['FPARAM'][hiloggindx,
                                              paramIndx('logg')] - 0.256
    else:
        logg = data['LOGG']
    indx= (jk < 0.8)*(jk >= 0.5)\
        *(z <= 0.06)\
        *(z <= rcmodel.jkzcut(jk,upper=True))\
        *(z >= rcmodel.jkzcut(jk))\
        *(logg >= rcmodel.loggteffcut(data['TEFF'],z,upper=False))\
        *(logg+0.1*('l31' in appath._APOGEE_REDUX
                    or 'l33' in appath._APOGEE_REDUX) \
              <= rcmodel.loggteffcut(data['TEFF'],z,upper=True))
    data = data[indx]
    #Add more aggressive flag cut
    data = esutil.numpy_util.add_fields(data, [('ADDL_LOGG_CUT', numpy.int32)])
    data['ADDL_LOGG_CUT'] = (
        (data['TEFF'] - 4800.) / 1000. + 2.75) > data['LOGG']
    if options.loggcut:
        data = data[data['ADDL_LOGG_CUT'] == 1]
    print("Making catalog of %i objects ..." % len(data))
    #Add distances
    data = esutil.numpy_util.add_fields(data, [('RC_DIST', float),
                                               ('RC_DM', float),
                                               ('RC_GALR', float),
                                               ('RC_GALPHI', float),
                                               ('RC_GALZ', float)])
    rcd = rcmodel.rcdist()
    jk = data['J0'] - data['K0']
    z = isodist.FEH2Z(data['METALS'], zsolar=0.017)
    data['RC_DIST'] = rcd(jk, z, appmag=data['K0']) * options.distfac
    data['RC_DM'] = 5. * numpy.log10(data['RC_DIST']) + 10.
    XYZ = bovy_coords.lbd_to_XYZ(data['GLON'],
                                 data['GLAT'],
                                 data['RC_DIST'],
                                 degree=True)
    RphiZ = bovy_coords.XYZ_to_galcencyl(XYZ[:, 0],
                                         XYZ[:, 1],
                                         XYZ[:, 2],
                                         Xsun=8.15,
                                         Zsun=0.0208)
    R = RphiZ[:, 0]
    phi = RphiZ[:, 1]
    Z = RphiZ[:, 2]
    data['RC_GALR'] = R
    data['RC_GALPHI'] = phi
    data['RC_GALZ'] = Z
    #Save
    fitswrite(savefilename, data, clobber=True)
    # Add Tycho-2 matches
    if options.tyc2:
        data = esutil.numpy_util.add_fields(data, [('TYC2MATCH', numpy.int32),
                                                   ('TYC1', numpy.int32),
                                                   ('TYC2', numpy.int32),
                                                   ('TYC3', numpy.int32)])
        data['TYC2MATCH'] = 0
        data['TYC1'] = -1
        data['TYC2'] = -1
        data['TYC3'] = -1
        # Write positions
        posfilename = tempfile.mktemp('.csv', dir=os.getcwd())
        resultfilename = tempfile.mktemp('.csv', dir=os.getcwd())
        with open(posfilename, 'w') as csvfile:
            wr = csv.writer(csvfile, delimiter=',', quoting=csv.QUOTE_MINIMAL)
            wr.writerow(['RA', 'DEC'])
            for ii in range(len(data)):
                wr.writerow([data[ii]['RA'], data[ii]['DEC']])
        # Send to CDS for matching
        result = open(resultfilename, 'w')
        try:
            subprocess.check_call([
                'curl', '-X', 'POST', '-F', 'request=xmatch', '-F',
                'distMaxArcsec=2', '-F', 'RESPONSEFORMAT=csv', '-F',
                'cat1=@%s' % os.path.basename(posfilename), '-F', 'colRA1=RA',
                '-F', 'colDec1=DEC', '-F', 'cat2=vizier:Tycho2',
                'http://cdsxmatch.u-strasbg.fr/xmatch/api/v1/sync'
            ],
                                  stdout=result)
        except subprocess.CalledProcessError:
            os.remove(posfilename)
            if os.path.exists(resultfilename):
                result.close()
                os.remove(resultfilename)
        result.close()
        # Directly match on input RA
        ma = numpy.loadtxt(resultfilename,
                           delimiter=',',
                           skiprows=1,
                           usecols=(1, 2, 7, 8, 9))
        iis = numpy.arange(len(data))
        mai = [iis[data['RA'] == ma[ii, 0]][0] for ii in range(len(ma))]
        data['TYC2MATCH'][mai] = 1
        data['TYC1'][mai] = ma[:, 2]
        data['TYC2'][mai] = ma[:, 3]
        data['TYC3'][mai] = ma[:, 4]
        os.remove(posfilename)
        os.remove(resultfilename)
    if not options.nostat:
        #Determine statistical sample and add flag
        apo = apogee.select.apogeeSelect()
        statIndx = apo.determine_statistical(data)
        mainIndx = apread.mainIndx(data)
        data = esutil.numpy_util.add_fields(data, [('STAT', numpy.int32),
                                                   ('INVSF', float)])
        data['STAT'] = 0
        data['STAT'][statIndx * mainIndx] = 1
        for ii in range(len(data)):
            if (statIndx * mainIndx)[ii]:
                data['INVSF'][ii] = 1. / apo(data['LOCATION_ID'][ii],
                                             data['H'][ii])
            else:
                data['INVSF'][ii] = -1.
    if options.nopm:
        fitswrite(savefilename, data, clobber=True)
        return None
    data = _add_proper_motions(data, savefilename)
    # Save
    fitswrite(savefilename, data, clobber=True)
    return None
예제 #16
0
def make_rcsample(parser):
    options, args = parser.parse_args()
    savefilename = options.savefilename
    if savefilename is None:
        #Create savefilename if not given
        savefilename = os.path.join(
            appath._APOGEE_DATA, 'rcsample_' + appath._APOGEE_REDUX + '.fits')
        print("Saving to %s ..." % savefilename)
    #Read the base-sample
    data = apread.allStar(adddist=_ADDHAYDENDIST, rmdups=options.rmdups)
    #Remove a bunch of fields that we do not want to keep
    data = esutil.numpy_util.remove_fields(data, [
        'TARGET_ID', 'FILE', 'AK_WISE', 'SFD_EBV', 'SYNTHVHELIO_AVG',
        'SYNTHVSCATTER', 'SYNTHVERR', 'SYNTHVERR_MED', 'RV_TEFF', 'RV_LOGG',
        'RV_FEH', 'RV_ALPHA', 'RV_CARB', 'RV_CCFWHM', 'RV_AUTOFWHM',
        'SYNTHSCATTER', 'STABLERV_CHI2', 'STABLERV_RCHI2',
        'STABLERV_CHI2_PROB', 'CHI2_THRESHOLD', 'APSTAR_VERSION',
        'ASPCAP_VERSION', 'RESULTS_VERSION', 'WASH_M', 'WASH_M_ERR', 'WASH_T2',
        'WASH_T2_ERR', 'DDO51', 'DDO51_ERR', 'IRAC_3_6', 'IRAC_3_6_ERR',
        'IRAC_4_5', 'IRAC_4_5_ERR', 'IRAC_5_8', 'IRAC_5_8_ERR', 'IRAC_8_0',
        'IRAC_8_0_ERR', 'WISE_4_5', 'WISE_4_5_ERR', 'TARG_4_5', 'TARG_4_5_ERR',
        'WASH_DDO51_GIANT_FLAG', 'WASH_DDO51_STAR_FLAG', 'REDUCTION_ID',
        'SRC_H', 'PM_SRC'
    ])
    if not appath._APOGEE_REDUX.lower() == 'current' \
            and not 'l30' in appath._APOGEE_REDUX \
            and int(appath._APOGEE_REDUX[1:]) < 500:
        data = esutil.numpy_util.remove_fields(data, ['ELEM'])
    #Select red-clump stars
    jk = data['J0'] - data['K0']
    z = isodist.FEH2Z(data['METALS'], zsolar=0.017)
    if 'l30' in appath._APOGEE_REDUX:
        logg = data['LOGG']
    elif appath._APOGEE_REDUX.lower() == 'current' \
            or int(appath._APOGEE_REDUX[1:]) > 600:
        from apogee.tools import paramIndx
        if False:
            #Use my custom logg calibration that's correct for the RC
            logg = (1. - 0.042) * data['FPARAM'][:, paramIndx('logg')] - 0.213
            lowloggindx = data['FPARAM'][:, paramIndx('logg')] < 1.
            logg[lowloggindx] = data['FPARAM'][lowloggindx,
                                               paramIndx('logg')] - 0.255
            hiloggindx = data['FPARAM'][:, paramIndx('logg')] > 3.8
            logg[hiloggindx] = data['FPARAM'][hiloggindx,
                                              paramIndx('logg')] - 0.3726
        else:
            #Use my custom logg calibration that's correct on average
            logg = (1. + 0.03) * data['FPARAM'][:, paramIndx('logg')] - 0.37
            lowloggindx = data['FPARAM'][:, paramIndx('logg')] < 1.
            logg[lowloggindx] = data['FPARAM'][lowloggindx,
                                               paramIndx('logg')] - 0.34
            hiloggindx = data['FPARAM'][:, paramIndx('logg')] > 3.8
            logg[hiloggindx] = data['FPARAM'][hiloggindx,
                                              paramIndx('logg')] - 0.256
    else:
        logg = data['LOGG']
    indx= (jk < 0.8)*(jk >= 0.5)\
        *(z <= 0.06)\
        *(z <= rcmodel.jkzcut(jk,upper=True))\
        *(z >= rcmodel.jkzcut(jk))\
        *(logg >= rcmodel.loggteffcut(data['TEFF'],z,upper=False))\
        *(logg <= rcmodel.loggteffcut(data['TEFF'],z,upper=True))
    data = data[indx]
    #Add more aggressive flag cut
    data = esutil.numpy_util.add_fields(data, [('ADDL_LOGG_CUT', numpy.int32)])
    data['ADDL_LOGG_CUT'] = (
        (data['TEFF'] - 4800.) / 1000. + 2.75) > data['LOGG']
    if options.loggcut:
        data = data[data['ADDL_LOGG_CUT'] == 1]
    print("Making catalog of %i objects ..." % len(data))
    #Add distances
    data = esutil.numpy_util.add_fields(data, [('RC_DIST', float),
                                               ('RC_DM', float),
                                               ('RC_GALR', float),
                                               ('RC_GALPHI', float),
                                               ('RC_GALZ', float)])
    rcd = rcmodel.rcdist()
    jk = data['J0'] - data['K0']
    z = isodist.FEH2Z(data['METALS'], zsolar=0.017)
    data['RC_DIST'] = rcd(jk, z, appmag=data['K0']) * options.distfac
    data['RC_DM'] = 5. * numpy.log10(data['RC_DIST']) + 10.
    XYZ = bovy_coords.lbd_to_XYZ(data['GLON'],
                                 data['GLAT'],
                                 data['RC_DIST'],
                                 degree=True)
    R, phi, Z = bovy_coords.XYZ_to_galcencyl(XYZ[:, 0],
                                             XYZ[:, 1],
                                             XYZ[:, 2],
                                             Xsun=8.,
                                             Zsun=0.025)
    data['RC_GALR'] = R
    data['RC_GALPHI'] = phi
    data['RC_GALZ'] = Z
    #Save
    fitsio.write(savefilename, data, clobber=True)
    # Add Tycho-2 matches
    if options.tyc2:
        data = esutil.numpy_util.add_fields(data, [('TYC2MATCH', numpy.int32),
                                                   ('TYC1', numpy.int32),
                                                   ('TYC2', numpy.int32),
                                                   ('TYC3', numpy.int32)])
        data['TYC2MATCH'] = 0
        data['TYC1'] = -1
        data['TYC2'] = -1
        data['TYC3'] = -1
        # Write positions
        posfilename = tempfile.mktemp('.csv', dir=os.getcwd())
        resultfilename = tempfile.mktemp('.csv', dir=os.getcwd())
        with open(posfilename, 'w') as csvfile:
            wr = csv.writer(csvfile, delimiter=',', quoting=csv.QUOTE_MINIMAL)
            wr.writerow(['RA', 'DEC'])
            for ii in range(len(data)):
                wr.writerow([data[ii]['RA'], data[ii]['DEC']])
        # Send to CDS for matching
        result = open(resultfilename, 'w')
        try:
            subprocess.check_call([
                'curl', '-X', 'POST', '-F', 'request=xmatch', '-F',
                'distMaxArcsec=2', '-F', 'RESPONSEFORMAT=csv', '-F',
                'cat1=@%s' % os.path.basename(posfilename), '-F', 'colRA1=RA',
                '-F', 'colDec1=DEC', '-F', 'cat2=vizier:Tycho2',
                'http://cdsxmatch.u-strasbg.fr/xmatch/api/v1/sync'
            ],
                                  stdout=result)
        except subprocess.CalledProcessError:
            os.remove(posfilename)
            if os.path.exists(resultfilename):
                result.close()
                os.remove(resultfilename)
        result.close()
        # Directly match on input RA
        ma = numpy.loadtxt(resultfilename,
                           delimiter=',',
                           skiprows=1,
                           usecols=(1, 2, 7, 8, 9))
        iis = numpy.arange(len(data))
        mai = [iis[data['RA'] == ma[ii, 0]][0] for ii in range(len(ma))]
        data['TYC2MATCH'][mai] = 1
        data['TYC1'][mai] = ma[:, 2]
        data['TYC2'][mai] = ma[:, 3]
        data['TYC3'][mai] = ma[:, 4]
        os.remove(posfilename)
        os.remove(resultfilename)
    if not options.nostat:
        #Determine statistical sample and add flag
        apo = apogee.select.apogeeSelect()
        statIndx = apo.determine_statistical(data)
        mainIndx = apread.mainIndx(data)
        data = esutil.numpy_util.add_fields(data, [('STAT', numpy.int32),
                                                   ('INVSF', float)])
        data['STAT'] = 0
        data['STAT'][statIndx * mainIndx] = 1
        for ii in range(len(data)):
            if (statIndx * mainIndx)[ii]:
                data['INVSF'][ii] = 1. / apo(data['LOCATION_ID'][ii],
                                             data['H'][ii])
            else:
                data['INVSF'][ii] = -1.
    if options.nopm:
        fitsio.write(savefilename, data, clobber=True)
        return None
    #Get proper motions, in a somewhat roundabout way
    pmfile = savefilename.split('.')[0] + '_pms.fits'
    if os.path.exists(pmfile):
        pmdata = fitsio.read(pmfile, 1)
    else:
        pmdata = numpy.recarray(
            len(data),
            formats=['f8', 'f8', 'f8', 'f8', 'f8', 'f8', 'i4'],
            names=[
                'RA', 'DEC', 'PMRA', 'PMDEC', 'PMRA_ERR', 'PMDEC_ERR',
                'PMMATCH'
            ])
        # Write positions, again ...
        posfilename = tempfile.mktemp('.csv', dir=os.getcwd())
        resultfilename = tempfile.mktemp('.csv', dir=os.getcwd())
        with open(posfilename, 'w') as csvfile:
            wr = csv.writer(csvfile, delimiter=',', quoting=csv.QUOTE_MINIMAL)
            wr.writerow(['RA', 'DEC'])
            for ii in range(len(data)):
                wr.writerow([data[ii]['RA'], data[ii]['DEC']])
        # Send to CDS for matching
        result = open(resultfilename, 'w')
        try:
            subprocess.check_call([
                'curl', '-X', 'POST', '-F', 'request=xmatch', '-F',
                'distMaxArcsec=4', '-F', 'RESPONSEFORMAT=csv', '-F',
                'cat1=@%s' % os.path.basename(posfilename), '-F', 'colRA1=RA',
                '-F', 'colDec1=DEC', '-F', 'cat2=vizier:UCAC4',
                'http://cdsxmatch.u-strasbg.fr/xmatch/api/v1/sync'
            ],
                                  stdout=result)
        except subprocess.CalledProcessError:
            os.remove(posfilename)
            if os.path.exists(resultfilename):
                result.close()
                os.remove(resultfilename)
        result.close()
        # Match back and only keep the closest one
        ma = numpy.loadtxt(resultfilename,
                           delimiter=',',
                           skiprows=1,
                           converters={
                               15: lambda s: float(s.strip() or -9999),
                               16: lambda s: float(s.strip() or -9999),
                               17: lambda s: float(s.strip() or -9999),
                               18: lambda s: float(s.strip() or -9999)
                           },
                           usecols=(4, 5, 15, 16, 17, 18))
        h = esutil.htm.HTM()
        m1, m2, d12 = h.match(data['RA'],
                              data['DEC'],
                              ma[:, 0],
                              ma[:, 1],
                              4. / 3600.,
                              maxmatch=1)
        pmdata['PMMATCH'] = 0
        pmdata['RA'] = data['RA']
        pmdata['DEC'] = data['DEC']
        pmdata['PMMATCH'][m1] = 1
        pmdata['PMRA'][m1] = ma[m2, 2]
        pmdata['PMDEC'][m1] = ma[m2, 3]
        pmdata['PMRA_ERR'][m1] = ma[m2, 4]
        pmdata['PMDEC_ERR'][m1] = ma[m2, 5]
        pmdata['PMMATCH'][(pmdata['PMRA'] == -9999) \
                          +(pmdata['PMDEC'] == -9999) \
                          +(pmdata['PMRA_ERR'] == -9999) \
                          +(pmdata['PMDEC_ERR'] == -9999)]= 0
        fitsio.write(pmfile, pmdata, clobber=True)
        #To make sure we're using the same format below
        pmdata = fitsio.read(pmfile, 1)
        os.remove(posfilename)
        os.remove(resultfilename)
    #Match proper motions
    try:  #These already exist currently, but may not always exist
        data = esutil.numpy_util.remove_fields(data, ['PMRA', 'PMDEC'])
    except ValueError:
        pass
    data = esutil.numpy_util.add_fields(data, [('PMRA', numpy.float),
                                               ('PMDEC', numpy.float),
                                               ('PMRA_ERR', numpy.float),
                                               ('PMDEC_ERR', numpy.float),
                                               ('PMMATCH', numpy.int32)])
    data['PMMATCH'] = 0
    h = esutil.htm.HTM()
    m1, m2, d12 = h.match(pmdata['RA'],
                          pmdata['DEC'],
                          data['RA'],
                          data['DEC'],
                          2. / 3600.,
                          maxmatch=1)
    data['PMRA'][m2] = pmdata['PMRA'][m1]
    data['PMDEC'][m2] = pmdata['PMDEC'][m1]
    data['PMRA_ERR'][m2] = pmdata['PMRA_ERR'][m1]
    data['PMDEC_ERR'][m2] = pmdata['PMDEC_ERR'][m1]
    data['PMMATCH'][m2] = pmdata['PMMATCH'][m1].astype(numpy.int32)
    pmindx = data['PMMATCH'] == 1
    data['PMRA'][True - pmindx] = -9999.99
    data['PMDEC'][True - pmindx] = -9999.99
    data['PMRA_ERR'][True - pmindx] = -9999.99
    data['PMDEC_ERR'][True - pmindx] = -9999.99
    #Calculate Galactocentric velocities
    data = esutil.numpy_util.add_fields(data, [('GALVR', numpy.float),
                                               ('GALVT', numpy.float),
                                               ('GALVZ', numpy.float)])
    lb = bovy_coords.radec_to_lb(data['RA'], data['DEC'], degree=True)
    XYZ = bovy_coords.lbd_to_XYZ(lb[:, 0],
                                 lb[:, 1],
                                 data['RC_DIST'],
                                 degree=True)
    pmllpmbb = bovy_coords.pmrapmdec_to_pmllpmbb(data['PMRA'],
                                                 data['PMDEC'],
                                                 data['RA'],
                                                 data['DEC'],
                                                 degree=True)
    vxvyvz = bovy_coords.vrpmllpmbb_to_vxvyvz(data['VHELIO_AVG'],
                                              pmllpmbb[:, 0],
                                              pmllpmbb[:, 1],
                                              lb[:, 0],
                                              lb[:, 1],
                                              data['RC_DIST'],
                                              degree=True)
    vR, vT, vZ = bovy_coords.vxvyvz_to_galcencyl(
        vxvyvz[:, 0],
        vxvyvz[:, 1],
        vxvyvz[:, 2],
        8. - XYZ[:, 0],
        XYZ[:, 1],
        XYZ[:, 2] + 0.025,
        vsun=[-11.1, 30.24 * 8.,
              7.25])  #Assumes proper motion of Sgr A* and R0=8 kpc, zo= 25 pc
    data['GALVR'] = vR
    data['GALVT'] = vT
    data['GALVZ'] = vZ
    data['GALVR'][True - pmindx] = -9999.99
    data['GALVT'][True - pmindx] = -9999.99
    data['GALVZ'][True - pmindx] = -9999.99
    #Get PPMXL proper motions, in a somewhat roundabout way
    pmfile = savefilename.split('.')[0] + '_pms_ppmxl.fits'
    if os.path.exists(pmfile):
        pmdata = fitsio.read(pmfile, 1)
    else:
        pmdata = numpy.recarray(
            len(data),
            formats=['f8', 'f8', 'f8', 'f8', 'f8', 'f8', 'i4'],
            names=[
                'RA', 'DEC', 'PMRA', 'PMDEC', 'PMRA_ERR', 'PMDEC_ERR',
                'PMMATCH'
            ])
        # Write positions, again ...
        posfilename = tempfile.mktemp('.csv', dir=os.getcwd())
        resultfilename = tempfile.mktemp('.csv', dir=os.getcwd())
        with open(posfilename, 'w') as csvfile:
            wr = csv.writer(csvfile, delimiter=',', quoting=csv.QUOTE_MINIMAL)
            wr.writerow(['RA', 'DEC'])
            for ii in range(len(data)):
                wr.writerow([data[ii]['RA'], data[ii]['DEC']])
        # Send to CDS for matching
        result = open(resultfilename, 'w')
        try:
            subprocess.check_call([
                'curl', '-X', 'POST', '-F', 'request=xmatch', '-F',
                'distMaxArcsec=4', '-F', 'RESPONSEFORMAT=csv', '-F',
                'cat1=@%s' % os.path.basename(posfilename), '-F', 'colRA1=RA',
                '-F', 'colDec1=DEC', '-F', 'cat2=vizier:PPMXL',
                'http://cdsxmatch.u-strasbg.fr/xmatch/api/v1/sync'
            ],
                                  stdout=result)
        except subprocess.CalledProcessError:
            os.remove(posfilename)
            if os.path.exists(resultfilename):
                result.close()
                os.remove(resultfilename)
        result.close()
        # Match back and only keep the closest one
        ma = numpy.loadtxt(resultfilename,
                           delimiter=',',
                           skiprows=1,
                           converters={
                               15: lambda s: float(s.strip() or -9999),
                               16: lambda s: float(s.strip() or -9999),
                               17: lambda s: float(s.strip() or -9999),
                               18: lambda s: float(s.strip() or -9999)
                           },
                           usecols=(4, 5, 15, 16, 19, 20))
        h = esutil.htm.HTM()
        m1, m2, d12 = h.match(data['RA'],
                              data['DEC'],
                              ma[:, 0],
                              ma[:, 1],
                              4. / 3600.,
                              maxmatch=1)
        pmdata['PMMATCH'] = 0
        pmdata['RA'] = data['RA']
        pmdata['DEC'] = data['DEC']
        pmdata['PMMATCH'][m1] = 1
        pmdata['PMRA'][m1] = ma[m2, 2]
        pmdata['PMDEC'][m1] = ma[m2, 3]
        pmdata['PMRA_ERR'][m1] = ma[m2, 4]
        pmdata['PMDEC_ERR'][m1] = ma[m2, 5]
        pmdata['PMMATCH'][(pmdata['PMRA'] == -9999) \
                          +(pmdata['PMDEC'] == -9999) \
                          +(pmdata['PMRA_ERR'] == -9999) \
                          +(pmdata['PMDEC_ERR'] == -9999)]= 0
        fitsio.write(pmfile, pmdata, clobber=True)
        #To make sure we're using the same format below
        pmdata = fitsio.read(pmfile, 1)
        os.remove(posfilename)
        os.remove(resultfilename)
    #Match proper motions to ppmxl
    data = esutil.numpy_util.add_fields(data,
                                        [('PMRA_PPMXL', numpy.float),
                                         ('PMDEC_PPMXL', numpy.float),
                                         ('PMRA_ERR_PPMXL', numpy.float),
                                         ('PMDEC_ERR_PPMXL', numpy.float),
                                         ('PMMATCH_PPMXL', numpy.int32)])
    data['PMMATCH_PPMXL'] = 0
    h = esutil.htm.HTM()
    m1, m2, d12 = h.match(pmdata['RA'],
                          pmdata['DEC'],
                          data['RA'],
                          data['DEC'],
                          2. / 3600.,
                          maxmatch=1)
    data['PMRA_PPMXL'][m2] = pmdata['PMRA'][m1]
    data['PMDEC_PPMXL'][m2] = pmdata['PMDEC'][m1]
    data['PMRA_ERR_PPMXL'][m2] = pmdata['PMRA_ERR'][m1]
    data['PMDEC_ERR_PPMXL'][m2] = pmdata['PMDEC_ERR'][m1]
    data['PMMATCH_PPMXL'][m2] = pmdata['PMMATCH'][m1].astype(numpy.int32)
    pmindx = data['PMMATCH_PPMXL'] == 1
    data['PMRA_PPMXL'][True - pmindx] = -9999.99
    data['PMDEC_PPMXL'][True - pmindx] = -9999.99
    data['PMRA_ERR_PPMXL'][True - pmindx] = -9999.99
    data['PMDEC_ERR_PPMXL'][True - pmindx] = -9999.99
    #Calculate Galactocentric velocities
    data = esutil.numpy_util.add_fields(data, [('GALVR_PPMXL', numpy.float),
                                               ('GALVT_PPMXL', numpy.float),
                                               ('GALVZ_PPMXL', numpy.float)])
    lb = bovy_coords.radec_to_lb(data['RA'], data['DEC'], degree=True)
    XYZ = bovy_coords.lbd_to_XYZ(lb[:, 0],
                                 lb[:, 1],
                                 data['RC_DIST'],
                                 degree=True)
    pmllpmbb = bovy_coords.pmrapmdec_to_pmllpmbb(data['PMRA_PPMXL'],
                                                 data['PMDEC_PPMXL'],
                                                 data['RA'],
                                                 data['DEC'],
                                                 degree=True)
    vxvyvz = bovy_coords.vrpmllpmbb_to_vxvyvz(data['VHELIO_AVG'],
                                              pmllpmbb[:, 0],
                                              pmllpmbb[:, 1],
                                              lb[:, 0],
                                              lb[:, 1],
                                              data['RC_DIST'],
                                              degree=True)
    vR, vT, vZ = bovy_coords.vxvyvz_to_galcencyl(
        vxvyvz[:, 0],
        vxvyvz[:, 1],
        vxvyvz[:, 2],
        8. - XYZ[:, 0],
        XYZ[:, 1],
        XYZ[:, 2] + 0.025,
        vsun=[-11.1, 30.24 * 8.,
              7.25])  #Assumes proper motion of Sgr A* and R0=8 kpc, zo= 25 pc
    data['GALVR_PPMXL'] = vR
    data['GALVT_PPMXL'] = vT
    data['GALVZ_PPMXL'] = vZ
    data['GALVR_PPMXL'][True - pmindx] = -9999.99
    data['GALVT_PPMXL'][True - pmindx] = -9999.99
    data['GALVZ_PPMXL'][True - pmindx] = -9999.99
    #Save
    fitsio.write(savefilename, data, clobber=True)
    return None
예제 #17
0
def predict_spacedist(params,
                      locations,effsel,distmods,
                      type='exp',
                      coord='Z'):
    """
    NAME:
       predict_spacedist
    PURPOSE:
       predict the spatial distribution
    INPUT:
       params - parameters of the density profile
       locations - locations of the APOGEE effective selection function to consider
       effsel - array (nloc,nD) of the effective selection function, includes area of the field
       distmods - grid of distance moduli on which the effective selection function is pre-computed
       type= ('exp') type of density profile to fit      
       coord= ('dm', 'X', or 'Z')
    OUTPUT:
       (R,model(R))
    HISTORY:
       2015-03-26 - Written - Bovy (IAS)
    """
    if coord.lower() == 'x':
        # Grid in X
        Xs= numpy.linspace(0.,20.,301)
    elif coord.lower() == 'z':
        # Grid in X
        Xs= numpy.linspace(0.,20.,301)
    elif coord.lower() == 'dm':
        # Grid in X
        Xs= numpy.linspace(7.,15.5,301)
    # Setup the density function
    rdensfunc= _setup_densfunc(type)
    densfunc= lambda x,y,z: rdensfunc(x,y,z,params=params)
    # Restore the APOGEE selection function (assumed pre-computed)
    selectFile= '../savs/selfunc-nospdata.sav'
    if os.path.exists(selectFile):
        with open(selectFile,'rb') as savefile:
            apo= pickle.load(savefile)
    # Now compute the necessary coordinate transformations
    ds= 10.**(distmods/5-2.)
    Rgrid, phigrid, zgrid, Xgrid= [], [], [], []
    for loc in locations:
        lcen, bcen= apo.glonGlat(loc)
        XYZ= bovy_coords.lbd_to_XYZ(lcen*numpy.ones_like(ds),
                                    bcen*numpy.ones_like(ds),
                                    ds,
                                    degree=True)
        Rphiz= bovy_coords.XYZ_to_galcencyl(XYZ[:,0],XYZ[:,1],XYZ[:,2],
                                            Xsun=define_rcsample._R0,
                                            Ysun=0.,
                                            Zsun=define_rcsample._Z0)
        Rgrid.append(Rphiz[0])
        phigrid.append(Rphiz[1])
        zgrid.append(Rphiz[2])
        Xgrid.append(Rphiz[0]*numpy.cos(Rphiz[1]))
    Rgrid= numpy.array(Rgrid)
    phigrid= numpy.array(phigrid)
    zgrid= numpy.array(zgrid)
    Xgrid= numpy.array(Xgrid)
    # Now compute rate(R) for each location and combine
    effsel*= numpy.tile(ds**3.*(distmods[1]-distmods[0]),(effsel.shape[0],1))
    tdens= densfunc(Rgrid,phigrid,zgrid)
    rate= tdens*effsel
    out= numpy.zeros((len(locations),len(Xs)))
    for ii in range(len(locations)):
        if coord.lower() == 'x':
            # Jacobian
            tjac= numpy.fabs((numpy.roll(distmods,-1)-distmods)/\
                                 (numpy.roll(Xgrid[ii],-1)-Xgrid[ii]))
            tjac[-1]= tjac[-2]
            tXs= Xgrid[ii,rate[ii] > 0.]
        elif coord.lower() == 'z':
            # Jacobian
            tjac= numpy.fabs((numpy.roll(distmods,-1)-distmods)/\
                                 (numpy.roll(zgrid[ii],-1)-zgrid[ii]))
            tjac[-1]= tjac[-2]
            tXs= zgrid[ii,rate[ii] > 0.]
        elif coord.lower() == 'dm':
            # Jacobian
            tjac= numpy.ones_like(Xs)
            tXs= distmods[rate[ii] > 0.]
        sindx= numpy.argsort(tXs)
        tXs= tXs[sindx]
        trate= rate[ii,rate[ii] > 0.][sindx]
        tjac= tjac[rate[ii] > 0.][sindx]
        ipthis= numpy.log(trate*tjac+10.**-8.)
        baseline= numpy.polynomial.Polynomial.fit(tXs,ipthis,4)
        ipthis= ipthis/baseline(tXs)
        sp= interpolate.InterpolatedUnivariateSpline(tXs,ipthis,k=3)
        tindx= (Xs >= numpy.amin(tXs))\
            *(Xs <= numpy.amax(tXs))
        out[ii,tindx]= (numpy.exp(sp(Xs[tindx])*baseline(Xs[tindx]))-10.**-8.)
    out[numpy.isinf(out)]= 0.
    return (Xs,out.sum(axis=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()
예제 #19
0
def calc_actions(ra_deg, dec_deg, d_kpc, pm_ra_masyr, pm_dec_masyr, v_los_kms):
    ra_rad = ra_deg * (np.pi / 180.)  # RA [rad]
    dec_rad = dec_deg * (np.pi / 180.)  # dec [rad]

    # Galactocentric position of the Sun:
    X_gc_sun_kpc = 8.  # [kpc]
    Z_gc_sun_kpc = 0.025  # [kpc]

    # Galactocentric velocity of the Sun:
    vX_gc_sun_kms = -9.58  # = -U              [kms]
    vY_gc_sun_kms = 10.52 + 220.  # = V+v_circ(R_Sun) [kms]
    vZ_gc_sun_kms = 7.01  # = W               [kms]

    # a. convert spatial coordinates (ra,dec,d) to (R,z,phi)

    # (ra,dec) --> Galactic coordinates (l,b):
    lb = bovy_coords.radec_to_lb(ra_rad, dec_rad, degree=False, epoch=2000.0)
    l_rad = lb[:, 0]
    b_rad = lb[:, 1]

    # (l,b,d) --> Galactocentric cartesian coordinates (x,y,z):
    xyz = bovy_coords.lbd_to_XYZ(l_rad, b_rad, d_kpc, degree=False)
    x_kpc = xyz[:, 0]
    y_kpc = xyz[:, 1]
    z_kpc = xyz[:, 2]

    # (x,y,z) --> Galactocentric cylindrical coordinates (R,z,phi):
    Rzphi = bovy_coords.XYZ_to_galcencyl(x_kpc,
                                         y_kpc,
                                         z_kpc,
                                         Xsun=X_gc_sun_kpc,
                                         Zsun=Z_gc_sun_kpc)
    R_kpc = Rzphi[:, 0]
    phi_rad = Rzphi[:, 1]
    z_kpc = Rzphi[:, 2]

    # b. convert velocities (pm_ra,pm_dec,vlos) to (vR,vz,vT)

    # (pm_ra,pm_dec) --> (pm_l,pm_b):
    pmlpmb = bovy_coords.pmrapmdec_to_pmllpmbb(pm_ra_masyr,
                                               pm_dec_masyr,
                                               ra_rad,
                                               dec_rad,
                                               degree=False,
                                               epoch=2000.0)
    pml_masyr = pmlpmb[:, 0]
    pmb_masyr = pmlpmb[:, 1]

    # (v_los,pm_l,pm_b) & (l,b,d) --> (vx,vy,vz):
    vxvyvz = bovy_coords.vrpmllpmbb_to_vxvyvz(v_los_kms,
                                              pml_masyr,
                                              pmb_masyr,
                                              l_rad,
                                              b_rad,
                                              d_kpc,
                                              XYZ=False,
                                              degree=False)
    vx_kms = vxvyvz[:, 0]
    vy_kms = vxvyvz[:, 1]
    vz_kms = vxvyvz[:, 2]

    # (vx,vy,vz) & (x,y,z) --> (vR,vT,vz):
    vRvTvZ = bovy_coords.vxvyvz_to_galcencyl(
        vx_kms,
        vy_kms,
        vz_kms,
        R_kpc,
        phi_rad,
        z_kpc,
        vsun=[vX_gc_sun_kms, vY_gc_sun_kms, vZ_gc_sun_kms],
        galcen=True)
    vR_kms = vRvTvZ[:, 0]
    vT_kms = vRvTvZ[:, 1]
    vz_kms = vRvTvZ[:, 2]

    print("R = ", R_kpc, "\t kpc")
    print("phi = ", phi_rad, "\t rad")
    print("z = ", z_kpc, "\t kpc")
    print("v_R = ", vR_kms, "\t km/s")
    print("v_T = ", vT_kms, "\t km/s")
    print("v_z = ", vz_kms, "\t km/s")
    return vz_kms
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
예제 #21
0
def generate(locations,
             type='exp',
             sample='lowlow',
             extmap='green15',
             nls=101,
             nmock=1000,
             H0=-1.49,
             _dmapg15=None,
             ncpu=1):
    """
    NAME:
       generate
    PURPOSE:
       generate mock data following a given density
    INPUT:
       locations - locations to be included in the sample
       type= ('exp') type of density profile to sample from
       sample= ('lowlow') for selecting mock parameters
       extmap= ('green15') extinction map to use ('marshall06' and others use Green15 to fill in unobserved regions)
       nls= (101) number of longitude bins to use for each field
       nmock= (1000) number of mock data points to generate
       H0= (-1.49) absolute magnitude (can be array w/ sampling spread)
       ncpu= (1) number of cpus to use to compute the probability
    OUTPUT:
       mockdata recarray with tags 'RC_GALR_H', 'RC_GALPHI_H', 'RC_GALZ_H'
    HISTORY:
       2015-04-03 - Written - Bovy (IAS)
    """
    if isinstance(H0, float): H0 = [H0]
    # Setup the density function and its initial parameters
    rdensfunc = fitDens._setup_densfunc(type)
    mockparams = _setup_mockparams_densfunc(type, sample)
    densfunc = lambda x, y, z: rdensfunc(x, y, z, params=mockparams)
    # Setup the extinction map
    global dmap
    global dmapg15
    if _dmapg15 is None: dmapg15 = mwdust.Green15(filter='2MASS H')
    else: dmapg15 = _dmapg15
    if isinstance(extmap, mwdust.DustMap3D.DustMap3D):
        dmap = extmap
    elif extmap.lower() == 'green15':
        dmap = dmapg15
    elif extmap.lower() == 'marshall06':
        dmap = mwdust.Marshall06(filter='2MASS H')
    elif extmap.lower() == 'sale14':
        dmap = mwdust.Sale14(filter='2MASS H')
    elif extmap.lower() == 'drimmel03':
        dmap = mwdust.Drimmel03(filter='2MASS H')
    # Use brute-force rejection sampling to make no approximations
    # First need to estimate the max probability to use in rejection;
    # Loop through all locations and compute sampling probability on grid in
    # (l,b,D)
    # First restore the APOGEE selection function (assumed pre-computed)
    global apo
    selectFile = '../savs/selfunc-nospdata.sav'
    if os.path.exists(selectFile):
        with open(selectFile, 'rb') as savefile:
            apo = pickle.load(savefile)
    # Now compute the necessary coordinate transformations and evaluate the
    # maximum probability
    distmods = numpy.linspace(7., 15.5, 301)
    ds = 10.**(distmods / 5 - 2.)
    nbs = nls
    lnprobs = numpy.empty((len(locations), len(distmods), nbs, nls))
    radii = []
    lcens, bcens = [], []
    lnprobs = multi.parallel_map(lambda x: _calc_lnprob(
        locations[x], nls, nbs, ds, distmods, H0, densfunc),
                                 range(len(locations)),
                                 numcores=numpy.amin([
                                     len(locations),
                                     multiprocessing.cpu_count(), ncpu
                                 ]))
    lnprobs = numpy.array(lnprobs)
    for ll, loc in enumerate(locations):
        lcen, bcen = apo.glonGlat(loc)
        rad = apo.radius(loc)
        radii.append(rad)  # save for later
        lcens.append(lcen[0])
        bcens.append(bcen[0])
    maxp = (numpy.exp(numpy.nanmax(lnprobs)) -
            10.**-8.) * 1.1  # Just to be sure
    # Now generate mock data using rejection sampling
    nout = 0
    arlocations = numpy.array(locations)
    arradii = numpy.array(radii)
    arlcens = numpy.array(lcens)
    arbcens = numpy.array(bcens)
    out = numpy.recarray((nmock, ),
                         dtype=[('RC_DIST_H', 'f8'), ('RC_DM_H', 'f8'),
                                ('RC_GALR_H', 'f8'), ('RC_GALPHI_H', 'f8'),
                                ('RC_GALZ_H', 'f8')])
    while nout < nmock:
        nnew = 2 * (nmock - nout)
        # nnew new locations
        locIndx = numpy.floor(
            numpy.random.uniform(size=nnew) * len(locations)).astype('int')
        newlocations = arlocations[locIndx]
        # Point within these locations
        newds_coord = numpy.random.uniform(size=nnew)
        newds= 10.**((newds_coord*(numpy.amax(distmods)-numpy.amin(distmods))\
            +numpy.amin(distmods))/5.-2.)
        newdls_coord = numpy.random.uniform(size=nnew)
        newdls= newdls_coord*2.*arradii[locIndx]\
            -arradii[locIndx]
        newdbs_coord = numpy.random.uniform(size=nnew)
        newdbs= newdbs_coord*2.*arradii[locIndx]\
            -arradii[locIndx]
        newr2s = newdls**2. + newdbs**2.
        keepIndx = newr2s < arradii[locIndx]**2.
        newlocations = newlocations[keepIndx]
        newds_coord = newds_coord[keepIndx]
        newdls_coord = newdls_coord[keepIndx]
        newdbs_coord = newdbs_coord[keepIndx]
        newds = newds[keepIndx]
        newdls = newdls[keepIndx]
        newdbs = newdbs[keepIndx]
        newls = newdls + arlcens[locIndx][keepIndx]
        newbs = newdbs + arbcens[locIndx][keepIndx]
        # Reject?
        tps = numpy.zeros_like(newds)
        for nloc in list(set(newlocations)):
            lindx = newlocations == nloc
            pindx = arlocations == nloc
            coord = numpy.array([
                newds_coord[lindx] * (len(distmods) - 1.),
                newdbs_coord[lindx] * (nbs - 1.),
                newdls_coord[lindx] * (nls - 1.)
            ])
            tps[lindx]= \
                numpy.exp(ndimage.interpolation.map_coordinates(\
                    lnprobs[pindx][0],
                    coord,cval=-10.,
                    order=1))-10.**-8.
        XYZ = bovy_coords.lbd_to_XYZ(newls, newbs, newds, degree=True)
        Rphiz = bovy_coords.XYZ_to_galcencyl(XYZ[:, 0],
                                             XYZ[:, 1],
                                             XYZ[:, 2],
                                             Xsun=define_rcsample._R0,
                                             Ysun=0.,
                                             Zsun=define_rcsample._Z0)
        testp = numpy.random.uniform(size=len(newds)) * maxp
        keepIndx = tps > testp
        if numpy.sum(keepIndx) > nmock - nout:
            rangeIndx = numpy.zeros(len(keepIndx), dtype='int')
            rangeIndx[keepIndx] = numpy.arange(numpy.sum(keepIndx))
            keepIndx *= (rangeIndx < nmock - nout)
        out['RC_DIST_H'][nout:nout + numpy.sum(keepIndx)] = newds[keepIndx]
        out['RC_DM_H'][nout:nout+numpy.sum(keepIndx)]= newds_coord[keepIndx]*(numpy.amax(distmods)-numpy.amin(distmods))\
            +numpy.amin(distmods)
        out['RC_GALR_H'][nout:nout + numpy.sum(keepIndx)] = Rphiz[0][keepIndx]
        out['RC_GALPHI_H'][nout:nout +
                           numpy.sum(keepIndx)] = Rphiz[1][keepIndx]
        out['RC_GALZ_H'][nout:nout + numpy.sum(keepIndx)] = Rphiz[2][keepIndx]
        nout = nout + numpy.sum(keepIndx)
    return (out, lnprobs)
예제 #22
0
def get_rgbsample(loggcut=[1.8, 3.0],
                  teffcut=[0, 10000],
                  add_ages=False,
                  agetype='Martig',
                  apply_corrections=False,
                  distance_correction=False,
                  verbose=False):
    """
	Get a clean sample of dr12 APOGEE data with Michael Haydens distances
	---
	INPUT:
		None
	OUTPUT:
		Clean rgb sample with added distances
	HISTORY:
		Started - Mackereth 02/06/16 
	"""
    #get the allStar catalogue using apogee python (exlude all bad flags etc)
    allStar = apread.allStar(rmcommissioning=True,
                             exclude_star_bad=True,
                             exclude_star_warn=True,
                             main=True,
                             ak=True,
                             adddist=False)
    #cut to a 'sensible' logg range (giants which are not too high on the RGB)
    allStar = allStar[(allStar['LOGG'] > loggcut[0])
                      & (allStar['LOGG'] < loggcut[1]) &
                      (allStar['TEFF'] > teffcut[0]) &
                      (allStar['TEFF'] < teffcut[1])]
    if verbose == True:
        print str(
            len(allStar
                )) + ' Stars before Distance catalogue join (after Log(g) cut)'
    #load the distance VAC
    dists = fits.open(catpath + 'DR12_DIST_R-GC.fits')[1].data
    #convert to astropy Table
    allStar_tab = Table(data=allStar)
    dists_tab = Table(data=dists)
    #join table
    tab = join(allStar_tab,
               dists_tab,
               keys='APOGEE_ID',
               uniq_col_name='{col_name}{table_name}',
               table_names=['', '2'])
    data = tab.as_array()
    data = esutil.numpy_util.add_fields(data, [('M_J', float), ('M_H', float),
                                               ('M_K', float),
                                               ('MH50_DIST', float),
                                               ('MH50_GALR', float),
                                               ('MH50_GALZ', float),
                                               ('MH50_GALPHI', float),
                                               ('AVG_ALPHAFE', float)])
    data['MH50_DIST'] = (10**((data['HAYDEN_DISTMOD_50'] + 5) / 5)) / 1e3

    if distance_correction == True:
        data['MH50_DIST'] *= 1.05
    XYZ = bovy_coords.lbd_to_XYZ(data['GLON'],
                                 data['GLAT'],
                                 data['MH50_DIST'],
                                 degree=True)
    RphiZ = bovy_coords.XYZ_to_galcencyl(XYZ[:, 0],
                                         XYZ[:, 1],
                                         XYZ[:, 2],
                                         Xsun=8.,
                                         Zsun=0.025)
    data['MH50_GALR'] = RphiZ[:, 0]
    data['MH50_GALPHI'] = RphiZ[:, 1]
    data['MH50_GALZ'] = RphiZ[:, 2]
    data['M_J'] = data['J0'] - data['HAYDEN_DISTMOD_50']
    data['M_H'] = data['H0'] - data['HAYDEN_DISTMOD_50']
    data['M_K'] = data['K0'] - data['HAYDEN_DISTMOD_50']
    data['AVG_ALPHAFE'] = avg_alphafe_dr12(data)
    data[_FEHTAG] += -0.1
    #remove locations not in the apogee selection function (FIND OUT WHATS UP HERE)
    data = data[np.in1d(data['LOCATION_ID'], apo.list_fields())]
    # Remove locations outside of the Pan-STARRS dust map
    # In the Southern hemisphere
    data = data[data['LOCATION_ID'] != 4266]  #240,-18
    data = data[data['LOCATION_ID'] != 4331]  #5.5,-14.2
    data = data[data['LOCATION_ID'] != 4381]  #5.2,-12.2
    data = data[data['LOCATION_ID'] != 4332]  #1,-4
    data = data[data['LOCATION_ID'] != 4329]  #0,-5
    data = data[data['LOCATION_ID'] != 4351]  #0,-2
    data = data[data['LOCATION_ID'] != 4353]  #358,0
    data = data[data['LOCATION_ID'] != 4385]  #358.6,1.4
    # Close to the ecliptic pole where there's no data (is it the ecliptic pole?
    data = data[data['LOCATION_ID'] != 4528]  #120,30
    data = data[data['LOCATION_ID'] != 4217]  #123,22.4
    #remove any non-finite magnitudes
    data = data[np.isfinite(data['M_H'])]
    if verbose == True:
        print str(len(
            data)) + ' Stars with distance measures (and in good fields...)'
    if add_ages == True:
        if agetype == 'Martig':
            ages = fits.open(catpath + 'DR12_martigages_vizier.fits')[1].data
            idtag = '2MASS_ID'
        if agetype == 'Cannon':
            ages = fits.open(catpath + 'RGB_Cannon_Ages.fits')[1].data
            ages = esutil.numpy_util.add_fields(ages, [('Age', float)])
            ages['Age'] = np.exp(ages['ln_age'])
            idtag = 'ID'
        ages_tab = Table(data=ages)
        ages_tab.rename_column(idtag, 'APOGEE_ID')
        tab = join(ages_tab,
                   data,
                   keys='APOGEE_ID',
                   uniq_col_name='{col_name}{table_name}',
                   table_names=['', '2'])
        allStar_full = tab.as_array()
        data = allStar_full
        if verbose == True:
            print str(len(data)) + ' Stars with ages'
    if apply_corrections == True:
        #martig1 = np.genfromtxt(catpath+'martig2016_table1.txt', dtype=None, names=True, skip_header=2)
        martig1 = fits.open(catpath + 'martig_table1.fits')
        fit = lowess(np.log10(martig1['Age_out']), np.log10(martig1['Age_in']))
        xs = np.linspace(-0.3, 1.2, 100)
        xsinterpolate = interp1d(xs, xs)
        fys = fit[:, 0] - xsinterpolate(fit[:, 1])
        interp = UnivariateSpline(fit[:, 1], fys)
        corr_age = np.log10(data['Age']) + (interp(np.log10(data['Age'])))
        corr_age = 10**corr_age
        data['Age'] = corr_age
    return data
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