Exemplo n.º 1
0
def sky_coords(cluster):
    """Get the sky coordinates of every star in the cluster

    Parameters
    ----------
    cluster : class
        StarCluster

    Returns
    -------
    ra,dec,d0,pmra,pmdec,vr0 : float
      on-sky positions and velocities of cluster stars
      
    History
    -------
    2018 - Written - Webb (UofT)
    """
    origin0 = cluster.origin

    if origin0 != "galaxy":
        cluster.to_galaxy()

    x0, y0, z0 = bovy_coords.galcenrect_to_XYZ(cluster.x,
                                               cluster.y,
                                               cluster.z,
                                               Xsun=8.0,
                                               Zsun=0.025).T
    vx0, vy0, vz0 = bovy_coords.galcenrect_to_vxvyvz(
        cluster.vx,
        cluster.vy,
        cluster.vz,
        Xsun=8.0,
        Zsun=0.025,
        vsun=[-11.1, 244.0, 7.25],
    ).T

    l0, b0, d0 = bovy_coords.XYZ_to_lbd(x0, y0, z0, degree=True).T
    ra, dec = bovy_coords.lb_to_radec(l0, b0, degree=True).T

    vr0, pmll0, pmbb0 = bovy_coords.vxvyvz_to_vrpmllpmbb(vx0,
                                                         vy0,
                                                         vz0,
                                                         l0,
                                                         b0,
                                                         d0,
                                                         degree=True).T
    pmra, pmdec = bovy_coords.pmllpmbb_to_pmrapmdec(pmll0,
                                                    pmbb0,
                                                    l0,
                                                    b0,
                                                    degree=True).T

    if origin0 == "centre":
        cluster.to_centre()
    elif origin0 == "cluster":
        cluster.to_cluster()

    return ra, dec, d0, pmra, pmdec, vr0
Exemplo n.º 2
0
def sky_coords(cluster):
    """
    NAME:

       sky_coords

    PURPOSE:

       Get the sky coordinates of every star in the cluster

    INPUT:

       cluster - a StarCluster-class object

    OUTPUT:

       ra,dec,d0,pmra,pmdec,vr0

    HISTORY:

       2018 - Written - Webb (UofT)

    """
    origin0 = cluster.origin

    if origin0 != "galaxy":
        cluster.to_galaxy()

    x0, y0, z0 = bovy_coords.galcenrect_to_XYZ(
        cluster.x, cluster.y, cluster.z, Xsun=8.0, Zsun=0.025
    ).T
    vx0, vy0, vz0 = bovy_coords.galcenrect_to_vxvyvz(
        cluster.vx,
        cluster.vy,
        cluster.vz,
        Xsun=8.0,
        Zsun=0.025,
        vsun=[-11.1, 244.0, 7.25],
    ).T

    l0, b0, d0 = bovy_coords.XYZ_to_lbd(x0, y0, z0, degree=True).T
    ra, dec = bovy_coords.lb_to_radec(l0, b0, degree=True).T

    vr0, pmll0, pmbb0 = bovy_coords.vxvyvz_to_vrpmllpmbb(
        vx0, vy0, vz0, l0, b0, d0, degree=True
    ).T
    pmra, pmdec = bovy_coords.pmllpmbb_to_pmrapmdec(pmll0, pmbb0, l0, b0, degree=True).T

    if origin0 == "centre":
        cluster.to_centre()
    elif origin0 == "cluster":
        cluster.to_cluster()

    return ra, dec, d0, pmra, pmdec, vr0
Exemplo n.º 3
0
def test_vxvyvz_to_vrpmllpmbb():
    vx,vy,vz= -20.*4.74047,10.,-10.*4.74047
    X,Y,Z= 0.,1.,0.
    vrpmllpmbb= bovy_coords.vxvyvz_to_vrpmllpmbb(vx,vy,vz,X,Y,Z,
                                                 XYZ=True)
    assert numpy.fabs(vrpmllpmbb[0]-10.) < 10.**-10., 'vxvyvz_to_vrpmllpmbb conversion did not work as expected'
    assert numpy.fabs(vrpmllpmbb[1]-20.) < 10.**-10., 'vxvyvz_to_vrpmllpmbb conversion did not work as expected'
    assert numpy.fabs(vrpmllpmbb[2]+10.) < 10.**-10., 'vxvyvz_to_vrpmllpmbb conversion did not work as expected'
    # also try with degree=True (that shouldn't fail!)
    vrpmllpmbb= bovy_coords.vxvyvz_to_vrpmllpmbb(vx,vy,vz,X,Y,Z,
                                                 XYZ=True,
                                                 degree=True)
    assert numpy.fabs(vrpmllpmbb[0]-10.) < 10.**-10., 'vxvyvz_to_vrpmllpmbb conversion did not work as expected'
    assert numpy.fabs(vrpmllpmbb[1]-20.) < 10.**-10., 'vxvyvz_to_vrpmllpmbb conversion did not work as expected'
    assert numpy.fabs(vrpmllpmbb[2]+10.) < 10.**-10., 'vxvyvz_to_vrpmllpmbb conversion did not work as expected'
    # also for lbd
    vrpmllpmbb= bovy_coords.vxvyvz_to_vrpmllpmbb(vx,vy,vz,90.,0.,1.,
                                                 XYZ=False,degree=True)
    assert numpy.fabs(vrpmllpmbb[0]-10.) < 10.**-10., 'vxvyvz_to_vrpmllpmbb conversion did not work as expected'
    assert numpy.fabs(vrpmllpmbb[1]-20.) < 10.**-10., 'vxvyvz_to_vrpmllpmbb conversion did not work as expected'
    assert numpy.fabs(vrpmllpmbb[2]+10.) < 10.**-10., 'vxvyvz_to_vrpmllpmbb conversion did not work as expected'
    # also for lbd, not in degree
    vrpmllpmbb= bovy_coords.vxvyvz_to_vrpmllpmbb(vx,vy,vz,numpy.pi/2.,0.,1.,
                                                 XYZ=False,degree=False)
    assert numpy.fabs(vrpmllpmbb[0]-10.) < 10.**-10., 'vxvyvz_to_vrpmllpmbb conversion did not work as expected'
    assert numpy.fabs(vrpmllpmbb[1]-20.) < 10.**-10., 'vxvyvz_to_vrpmllpmbb conversion did not work as expected'
    assert numpy.fabs(vrpmllpmbb[2]+10.) < 10.**-10., 'vxvyvz_to_vrpmllpmbb conversion did not work as expected'
    # and for arrays
    os= numpy.ones(2)
    vrpmllpmbb= bovy_coords.vxvyvz_to_vrpmllpmbb(os*vx,os*vy,os*vz,
                                                 os*numpy.pi/2.,os*0.,os,
                                                 XYZ=False,degree=False)
    assert numpy.all(numpy.fabs(vrpmllpmbb[:,0]-10.) < 10.**-10.), 'vxvyvz_to_vrpmllpmbb conversion did not work as expected'
    assert numpy.all(numpy.fabs(vrpmllpmbb[:,1]-20.) < 10.**-10.), 'vxvyvz_to_vrpmllpmbb conversion did not work as expected'
    assert numpy.all(numpy.fabs(vrpmllpmbb[:,2]+10.) < 10.**-10.), 'vxvyvz_to_vrpmllpmbb conversion did not work as expected'
    return None
Exemplo n.º 4
0
def xyzuvw_to_skycoord(xyzuvw_in, solarmotion='schoenrich', reverse_x_sign=True):
    """Converts XYZUVW with respect to the LSR or the sun
    to RAdeg, DEdeg, plx, pmra, pmdec, RV
    
    Parameters
    ----------
    xyzuvw_in:
        XYZUVW with respect to the LSR.
        
    solarmotion: string
        The reference of assumed solar motion. "schoenrich" or None if inputs are already 
        relative to the sun.
        
    reverse_x_sign: bool
        Do we reverse the sign of the X co-ordinate? This is needed for dealing with 
        galpy sign conventions.

    TODO: not working at all... fix this
    """
    if solarmotion==None:
        xyzuvw_sun = np.zeros(6)
    elif solarmotion=='schoenrich':
        xyzuvw_sun = [0,0,25,11.1,12.24,7.25]
    else:
        raise UserWarning
        
    #Make coordinates relative to sun
    xyzuvw = xyzuvw_in - xyzuvw_sun
    
    #Special for the sun itself...
    #FIXME: This seems like a hack. 
    #if (np.sum(xyzuvw**2) < 1) and solarmotion != None:
    #    return [0,0,1e5, 0,0,0]
    
    #Find l, b and distance.
    #!!! WARNING: the X-coordinate may have to be reversed here, just like everywhere else, 
    #because of the convention in Orbit.x(), which doesn't seem to match X.
    if reverse_x_sign:
        lbd = bovy_coords.XYZ_to_lbd(-xyzuvw[0]/1e3, xyzuvw[1]/1e3, xyzuvw[2]/1e3, degree=True)
    else:
        lbd = bovy_coords.XYZ_to_lbd(xyzuvw[0]/1e3, xyzuvw[1]/1e3, xyzuvw[2]/1e3, degree=True)
    radec = bovy_coords.lb_to_radec(lbd[0], lbd[1], degree=True)
    vrpmllpmbb = bovy_coords.vxvyvz_to_vrpmllpmbb(xyzuvw[3],xyzuvw[4], xyzuvw[5],\
                    lbd[0],lbd[1],lbd[2], degree=True)
    pmrapmdec = bovy_coords.pmllpmbb_to_pmrapmdec(vrpmllpmbb[1],vrpmllpmbb[2],lbd[0],lbd[1],degree=True)
    return [radec[0], radec[1], 1.0/lbd[2], pmrapmdec[0], pmrapmdec[1], vrpmllpmbb[0]]
Exemplo n.º 5
0
def convertHelioCentricToRADEC(xyzuvw_hc, kpc=False):
    """
    Generate astrometry values from cartesian coordinates centred on sun

    Parameters
    ----------
    xyzuvw_hc : [6] array
        [kpc, kpc, kpc, km/s, km/s, km/s]

    Returns
    -------
    astrometry : [6] array
        [RA, DEC, pi, pm_ra, pm_dec, vr]
    """
    #    if not kpc:
    #        xyzuvw_hc = xyzuvw_hc.copy()
    #        xyzuvw_hc[:3] /= 1e3
    logging.debug("Positions is: {}".format(xyzuvw_hc[:3]))
    logging.debug("Velocity is: {}".format(xyzuvw_hc[3:]))
    lbdist = convertHelioCentricTolbdist(xyzuvw_hc)
    radec = bovy_coords.lb_to_radec(lbdist[0], lbdist[1], degree=True)
    vrpmllpmbb = bovy_coords.vxvyvz_to_vrpmllpmbb(xyzuvw_hc[3],
                                                  xyzuvw_hc[4],
                                                  xyzuvw_hc[5],
                                                  lbdist[0],
                                                  lbdist[1],
                                                  lbdist[2],
                                                  degree=True)
    pmrapmdec = bovy_coords.pmllpmbb_to_pmrapmdec(vrpmllpmbb[1],
                                                  vrpmllpmbb[2],
                                                  lbdist[0],
                                                  lbdist[1],
                                                  degree=True)
    return [
        radec[0], radec[1], 1.0 / lbdist[2], pmrapmdec[0], pmrapmdec[1],
        vrpmllpmbb[0]
    ]
Exemplo n.º 6
0
def comove_coords(t, lit_gaia):
    ###could add other outputs like Vr, pred, in addition to sep,sep3d,and Vtan off
    ra = t.target_df.squeeze()['ra'] * u.deg
    dec = t.target_df.squeeze()['dec'] * u.deg
    distance = (1000.0 / t.target_df.squeeze()['parallax']) * u.pc
    radvel = t.target_df.squeeze(
    )['dr2_radial_velocity'] * u.kilometer / u.second
    pmra = t.target_df.squeeze()['pmra'] * u.mas / u.year
    pmdec = t.target_df.squeeze()['pmdec'] * u.mas / u.year



    Pcoord = SkyCoord( ra=ra, dec=dec, \
                      distance=distance, frame='icrs' , \
                      radial_velocity=radvel , \
                      pm_ra_cosdec= pmra , pm_dec= pmdec )

    # # Query Gaia with search radius and parallax cut
    # # Note, a cut on parallax_error was added because searches at low galactic latitude
    # # return an overwhelming number of noisy sources that scatter into the search volume - ALK 20210325
    # print('Querying Gaia for neighbors')
    # if (searchradpc < Pcoord.distance):
    #     sqltext = "SELECT * FROM gaiaedr3.gaia_source WHERE CONTAINS( \
    #         POINT('ICRS',gaiaedr3.gaia_source.ra,gaiaedr3.gaia_source.dec), \
    #         CIRCLE('ICRS'," + str(Pcoord.ra.value) +","+ str(Pcoord.dec.value) +","+ str(searchraddeg.value) +"))\
    #         =1 AND parallax>" + str(minpar.value) + " AND parallax_error<0.5;"
    # if (searchradpc >= Pcoord.distance):
    #     sqltext = "SELECT * FROM gaiaedr3.gaia_source WHERE parallax>" + str(minpar.value) + " AND parallax_error<0.5;"
    #     print('Note, using all-sky search')
    # if verbose == True:
    #     print(sqltext)
    #     print()

    # job = Gaia.launch_job_async(sqltext , dump_to_file=False)
    # r = job.get_results()

    # if verbose == True: print('Number of records: ',len(r['ra']))

    # # Construct coordinates array for all stars returned in cone search

    # gaiacoord = SkyCoord( ra=r['ra'] , dec=r['dec'] , distance=(1000.0/r['parallax'])*u.parsec , \
    #                      frame='icrs' , \
    #                      pm_ra_cosdec=r['pmra'] , pm_dec=r['pmdec'] )

    lit_sc = SkyCoord(
        ra=lit_gaia.ra.to_numpy(dtype='float') * u.deg,
        dec=lit_gaia.dec.to_numpy(dtype='float') * u.deg,
        pm_ra_cosdec=lit_gaia.pmra.to_numpy(dtype='float') * u.mas / u.yr,
        pm_dec=lit_gaia.pmdec.to_numpy(dtype='float') * u.mas / u.yr,
        distance=u.pc * (1000. / lit_gaia.parallax.to_numpy(dtype='float')))

    sep = lit_sc.separation(Pcoord)  #in degrees
    sep3d = lit_sc.separation_3d(Pcoord)  #in parsec

    Pllbb = bc.radec_to_lb(Pcoord.ra.value, Pcoord.dec.value, degree=True)
    Ppmllpmbb = bc.pmrapmdec_to_pmllpmbb( Pcoord.pm_ra_cosdec.value , Pcoord.pm_dec.value , \
                                         Pcoord.ra.value , Pcoord.dec.value , degree=True )
    Pvxvyvz   = bc.vrpmllpmbb_to_vxvyvz(Pcoord.radial_velocity.value , Ppmllpmbb[0] , Ppmllpmbb[1] , \
                                   Pllbb[0] , Pllbb[1] , Pcoord.distance.value/1000.0 , XYZ=False , degree=True)

    Gllbb = bc.radec_to_lb(lit_sc.ra.value, lit_sc.dec.value, degree=True)
    Gxyz = bc.lbd_to_XYZ(Gllbb[:, 0],
                         Gllbb[:, 1],
                         lit_sc.distance / 1000.0,
                         degree=True)
    Gvrpmllpmbb = bc.vxvyvz_to_vrpmllpmbb( \
                    Pvxvyvz[0]*np.ones(len(Gxyz[:,0])) , Pvxvyvz[1]*np.ones(len(Gxyz[:,1])) , Pvxvyvz[2]*np.ones(len(Gxyz[:,2])) , \
                    Gxyz[:,0] , Gxyz[:,1] , Gxyz[:,2] , XYZ=True)
    Gpmrapmdec = bc.pmllpmbb_to_pmrapmdec(Gvrpmllpmbb[:, 1],
                                          Gvrpmllpmbb[:, 2],
                                          Gllbb[:, 0],
                                          Gllbb[:, 1],
                                          degree=True)

    # Code in case I want to do chi^2 cuts someday
    Gvtanerr = 1.0 * np.ones(len(Gxyz[:, 0]))
    Gpmerr = Gvtanerr * 206265000.0 * 3.154e7 / (lit_sc.distance.value *
                                                 3.086e13)

    Gchi2 = ((Gpmrapmdec[:, 0] - lit_sc.pm_ra_cosdec.value)**2 +
             (Gpmrapmdec[:, 1] - lit_sc.pm_dec.value)**2)**0.5
    vtanoff = Gchi2 / Gpmerr  #this is reported Vtan,off(km/s)

    ##vr pred
    vr_pred = Gvrpmllpmbb[:, 0]

    #create results dataframe
    res = pd.DataFrame(
        data={
            'tic': lit_gaia.tic.to_numpy(dtype='str'),
            'designation': lit_gaia.designation.to_numpy(dtype='str'),
            'ra': lit_sc.ra.value,
            'dec': lit_sc.dec.value,
            'sep2D(deg)': sep.value,
            'sep3D(pc)': sep3d.value,
            'Vtan,off(km/s)': vtanoff,
            'Vr,pred(km/s)': vr_pred
        })

    return (res)
Exemplo n.º 7
0
def xyzuvw_to_skycoord(xyzuvw_in,
                       solarmotion='schoenrich',
                       reverse_x_sign=True):
    """Converts XYZUVW with respect to the LSR or the sun
    to RAdeg, DEdeg, plx, pmra, pmdec, RV
    
    Parameters
    ----------
    xyzuvw_in:
        XYZUVW with respect to the LSR.
        
    solarmotion: string
        The reference of assumed solar motion. "schoenrich" or None if inputs are already 
        relative to the sun.
        
    reverse_x_sign: bool
        Do we reverse the sign of the X co-ordinate? This is needed for dealing with 
        galpy sign conventions.

    TODO: not working at all... fix this
    """
    if solarmotion == None:
        xyzuvw_sun = np.zeros(6)
    elif solarmotion == 'schoenrich':
        xyzuvw_sun = [0, 0, 25, 11.1, 12.24, 7.25]
    else:
        raise UserWarning

    #Make coordinates relative to sun
    xyzuvw = xyzuvw_in - xyzuvw_sun

    #Special for the sun itself...
    #FIXME: This seems like a hack.
    #if (np.sum(xyzuvw**2) < 1) and solarmotion != None:
    #    return [0,0,1e5, 0,0,0]

    #Find l, b and distance.
    #!!! WARNING: the X-coordinate may have to be reversed here, just like everywhere else,
    #because of the convention in Orbit.x(), which doesn't seem to match X.
    if reverse_x_sign:
        lbd = bovy_coords.XYZ_to_lbd(-xyzuvw[0] / 1e3,
                                     xyzuvw[1] / 1e3,
                                     xyzuvw[2] / 1e3,
                                     degree=True)
    else:
        lbd = bovy_coords.XYZ_to_lbd(xyzuvw[0] / 1e3,
                                     xyzuvw[1] / 1e3,
                                     xyzuvw[2] / 1e3,
                                     degree=True)
    radec = bovy_coords.lb_to_radec(lbd[0], lbd[1], degree=True)
    vrpmllpmbb = bovy_coords.vxvyvz_to_vrpmllpmbb(xyzuvw[3],xyzuvw[4], xyzuvw[5],\
                    lbd[0],lbd[1],lbd[2], degree=True)
    pmrapmdec = bovy_coords.pmllpmbb_to_pmrapmdec(vrpmllpmbb[1],
                                                  vrpmllpmbb[2],
                                                  lbd[0],
                                                  lbd[1],
                                                  degree=True)
    return [
        radec[0], radec[1], 1.0 / lbd[2], pmrapmdec[0], pmrapmdec[1],
        vrpmllpmbb[0]
    ]
Exemplo n.º 8
0
def fakeDFData(binned,qdf,ii,params,fehs,afes,options,
               rmin,rmax,
               platelb,
               grmin,grmax,
               fehrange,
               colordist,
               fehdist,feh,sf,
               mapfehs,mapafes,
               ro=None,vo=None,
               ndata=None,#If set, supersedes binned, only to be used w/ returnlist=True
               returnlist=False): #last one useful for pixelFitDF normintstuff
    if ro is None:
        ro= get_ro(params,options)
    if vo is None:
        vo= get_vo(params,options,len(fehs))
    thishr= qdf.estimate_hr(1.,z=0.125)*_REFR0*ro #qdf._hr*_REFR0*ro
    thishz= qdf.estimate_hz(1.,z=0.125)*_REFR0*ro
    if thishr < 0.: thishr= 10. #Probably close to flat
    if thishz  < 0.1: thishz= 0.2
    thissr= qdf._sr*_REFV0*vo
    thissz= qdf._sz*_REFV0*vo
    thishsr= qdf._hsr*_REFR0*ro
    thishsz= qdf._hsz*_REFR0*ro
    if True:
        if options.aAmethod.lower() == 'staeckel':
            #Make everything 10% larger
            thishr*= 1.2
            thishz*= 1.2
            thishsr*= 1.2
            thishsz*= 1.2
            thissr*= 2.
            thissz*= 2.
        else:
            #Make everything 20% larger
            thishr*= 1.2
            thishz*= 1.2
            thishsr*= 1.2
            thishsz*= 1.2
            thissr*= 2.
            thissz*= 2.
    #Find nearest mono-abundance bin that has a measurement
    abindx= numpy.argmin((fehs[ii]-mapfehs)**2./0.01 \
                             +(afes[ii]-mapafes)**2./0.0025)
    #Calculate the r-distribution for each plate
    nrs= 1001
    ngr, nfeh= 11, 11 #BOVY: INCREASE?
    tgrs= numpy.linspace(grmin,grmax,ngr)
    tfehs= numpy.linspace(fehrange[0]+0.00001,fehrange[1]-0.00001,nfeh)
    #Calcuate FeH and gr distriutions
    fehdists= numpy.zeros(nfeh)
    for jj in range(nfeh): fehdists[jj]= fehdist(tfehs[jj])
    fehdists= numpy.cumsum(fehdists)
    fehdists/= fehdists[-1]
    colordists= numpy.zeros(ngr)
    for jj in range(ngr): colordists[jj]= colordist(tgrs[jj])
    colordists= numpy.cumsum(colordists)
    colordists/= colordists[-1]
    rs= numpy.linspace(rmin,rmax,nrs)
    rdists= numpy.zeros((len(sf.plates),nrs,ngr,nfeh))
    #outlier model that we want to sample (not the one to aid in the sampling)
    srhalo= _SRHALO/vo/_REFV0
    sphihalo= _SPHIHALO/vo/_REFV0
    szhalo= _SZHALO/vo/_REFV0
    logoutfrac= numpy.log(get_outfrac(params,ii,options))
    loghalodens= numpy.log(ro*outDens(1.,0.,None))
    #Calculate surface(R=1.) for relative outlier normalization
    logoutfrac+= numpy.log(qdf.surfacemass_z(1.,ngl=options.ngl))
    if options.mcout:
        fidoutfrac= get_outfrac(params,ii,options)
        rdistsout= numpy.zeros((len(sf.plates),nrs,ngr,nfeh))
    lagoutfrac= 0.15 #.0000000000000000000000001 #seems good
    #Setup density model
    use_real_dens= True
    if use_real_dens:
        #nrs, nzs= 101, 101
        nrs, nzs= 64, 64
        thisRmin, thisRmax= 4./_REFR0, 15./_REFR0
        thiszmin, thiszmax= 0., .8
        Rgrid= numpy.linspace(thisRmin,thisRmax,nrs)
        zgrid= numpy.linspace(thiszmin,thiszmax,nzs)
        surfgrid= numpy.empty((nrs,nzs))
        for ll in range(nrs):
            for jj in range(nzs):
                sys.stdout.write('\r'+"Working on grid-point %i/%i" % (jj+ll*nzs+1,nzs*nrs))
                sys.stdout.flush()
                surfgrid[ll,jj]= qdf.density(Rgrid[ll],zgrid[jj],
                                             nmc=options.nmcv,
                                             ngl=options.ngl)
        sys.stdout.write('\r'+_ERASESTR+'\r')
        sys.stdout.flush()
        if _SURFSUBTRACTEXPON:
            Rs= numpy.tile(Rgrid,(nzs,1)).T
            Zs= numpy.tile(zgrid,(nrs,1))
            ehr= qdf.estimate_hr(1.,z=0.125)
#            ehz= qdf.estimate_hz(1.,zmin=0.5,zmax=0.7)#Get large z behavior right
            ehz= qdf.estimate_hz(1.,z=0.125)
            surfInterp= interpolate.RectBivariateSpline(Rgrid,zgrid,
                                                        numpy.log(surfgrid)
                                                        +Rs/ehr+numpy.fabs(Zs)/ehz,
                                                        kx=3,ky=3,
                                                        s=0.)
#                                                        s=10.*float(nzs*nrs))
        else:
            surfInterp= interpolate.RectBivariateSpline(Rgrid,zgrid,
                                                        numpy.log(surfgrid),
                                                        kx=3,ky=3,
                                                        s=0.)
#                                                        s=10.*float(nzs*nrs))
        if _SURFSUBTRACTEXPON:
            compare_func= lambda x,y,du: numpy.exp(surfInterp.ev(x/ro/_REFR0,numpy.fabs(y)/ro/_REFR0)-x/ro/_REFR0/ehr-numpy.fabs(y)/ehz/ro/_REFR0)
        else:
            compare_func= lambda x,y,du: numpy.exp(surfInterp.ev(x/ro/_REFR0,numpy.fabs(y)/ro/_REFR0))
    else:
        compare_func= lambda x,y,z: fidDens(x,y,thishr,thishz,z)
    for jj in range(len(sf.plates)):
        p= sf.plates[jj]
        sys.stdout.write('\r'+"Working on plate %i (%i/%i)" % (p,jj+1,len(sf.plates)))
        sys.stdout.flush()
        rdists[jj,:,:,:]= _predict_rdist_plate(rs,
                                               compare_func,
                                               None,rmin,rmax,
                                               platelb[jj,0],platelb[jj,1],
                                               grmin,grmax,
                                               fehrange[0],fehrange[1],feh,
                                               colordist,
                                               fehdist,sf,sf.plates[jj],
                                               dontmarginalizecolorfeh=True,
                                               ngr=ngr,nfeh=nfeh)
        if options.mcout:
            rdistsout[jj,:,:,:]= _predict_rdist_plate(rs,
                                                      lambda x,y,z: outDens(x,y,z),
                                                      None,rmin,rmax,
                                                      platelb[jj,0],platelb[jj,1],
                                                      grmin,grmax,
                                                      fehrange[0],fehrange[1],feh,
                                                      colordist,
                                                      fehdist,sf,sf.plates[jj],
                                                      dontmarginalizecolorfeh=True,
                                                      ngr=ngr,nfeh=nfeh)
    sys.stdout.write('\r'+_ERASESTR+'\r')
    sys.stdout.flush()
    numbers= numpy.sum(rdists,axis=3)
    numbers= numpy.sum(numbers,axis=2)
    numbers= numpy.sum(numbers,axis=1)
    numbers= numpy.cumsum(numbers)
    if options.mcout:
        totfid= numbers[-1]
    numbers/= numbers[-1]
    rdists= numpy.cumsum(rdists,axis=1)
    for ll in range(len(sf.plates)):
        for jj in range(ngr):
            for kk in range(nfeh):
                rdists[ll,:,jj,kk]/= rdists[ll,-1,jj,kk]
    if options.mcout:
        numbersout= numpy.sum(rdistsout,axis=3)
        numbersout= numpy.sum(numbersout,axis=2)
        numbersout= numpy.sum(numbersout,axis=1)
        numbersout= numpy.cumsum(numbersout)
        totout= fidoutfrac*numbersout[-1]
        totnumbers= totfid+totout
        totfid/= totnumbers
        totout/= totnumbers
        if _DEBUG:
            print totfid, totout
        numbersout/= numbersout[-1]
        rdistsout= numpy.cumsum(rdistsout,axis=1)
        for ll in range(len(sf.plates)):
            for jj in range(ngr):
                for kk in range(nfeh):
                    rdistsout[ll,:,jj,kk]/= rdistsout[ll,-1,jj,kk]
    #Now sample
    thisout= []
    newrs= []
    newls= []
    newbs= []
    newplate= []
    newgr= []
    newfeh= []
    newds= []
    newzs= []
    newvas= []
    newRs= []
    newphi= []
    newvr= []
    newvt= []
    newvz= []
    newlogratio= []
    newfideval= []
    newqdfeval= []
    newpropeval= []
    if ndata is None:
        thisdata= binned(fehs[ii],afes[ii])
        thisdataIndx= binned.callIndx(fehs[ii],afes[ii])
        ndata= len(thisdata)
    #First sample from spatial density
    for ll in range(ndata):
        #First sample a plate
        ran= numpy.random.uniform()
        kk= 0
        while numbers[kk] < ran: kk+= 1
        #Also sample a FeH and a color
        ran= numpy.random.uniform()
        ff= 0
        while fehdists[ff] < ran: ff+= 1
        ran= numpy.random.uniform()
        cc= 0
        while colordists[cc] < ran: cc+= 1
        #plate==kk, feh=ff,color=cc; now sample from the rdist of this plate
        ran= numpy.random.uniform()
        jj= 0
        if options.mcout and numpy.random.uniform() < totout: #outlier
            while rdistsout[kk,jj,cc,ff] < ran: jj+= 1
            thisoutlier= True
        else:
            while rdists[kk,jj,cc,ff] < ran: jj+= 1
            thisoutlier= False
        #r=jj
        newrs.append(rs[jj])
        newls.append(platelb[kk,0])
        newbs.append(platelb[kk,1])
        newplate.append(sf.plates[kk])
        newgr.append(tgrs[cc])
        newfeh.append(tfehs[ff])
        dist= _ivezic_dist(tgrs[cc],rs[jj],tfehs[ff])
        newds.append(dist)
        #calculate R,z
        XYZ= bovy_coords.lbd_to_XYZ(platelb[kk,0],platelb[kk,1],
                                    dist,degree=True)
        R= ((_REFR0-XYZ[0])**2.+XYZ[1]**2.)**(0.5)
        newRs.append(R)
        phi= numpy.arcsin(XYZ[1]/R)
        if (_REFR0-XYZ[0]) < 0.:
            phi= numpy.pi-phi
        newphi.append(phi)
        z= XYZ[2]+_ZSUN
        newzs.append(z)
    newrs= numpy.array(newrs)
    newls= numpy.array(newls)
    newbs= numpy.array(newbs)
    newplate= numpy.array(newplate)
    newgr= numpy.array(newgr)
    newfeh= numpy.array(newfeh)
    newds= numpy.array(newds)
    newRs= numpy.array(newRs)
    newzs= numpy.array(newzs)
    newphi= numpy.array(newphi)
    #Add mock velocities
    newvr= numpy.empty_like(newrs)
    newvt= numpy.empty_like(newrs)
    newvz= numpy.empty_like(newrs)
    use_sampleV= True
    if use_sampleV:
        for kk in range(ndata):
            newv= qdf.sampleV(newRs[kk]/_REFR0,newzs[kk]/_REFR0,n=1)
            newvr[kk]= newv[0,0]*_REFV0*vo
            newvt[kk]= newv[0,1]*_REFV0*vo
            newvz[kk]= newv[0,2]*_REFV0*vo
    else:
        accept_v= numpy.zeros(ndata,dtype='bool')
        naccept= numpy.sum(accept_v)
        sigz= thissz*numpy.exp(-(newRs-_REFR0)/thishsz)
        sigr= thissr*numpy.exp(-(newRs-_REFR0)/thishsr)
        va= numpy.empty_like(newrs)
        sigphi= numpy.empty_like(newrs)
        maxqdf= numpy.empty_like(newrs)
        nvt= 101
        tvt= numpy.linspace(0.1,1.2,nvt)
        for kk in range(ndata):
            #evaluate qdf for vt
            pvt= qdf(newRs[kk]/ro/_REFR0+numpy.zeros(nvt),
                     numpy.zeros(nvt),
                     tvt,
                     newzs[kk]/ro/_REFR0+numpy.zeros(nvt),
                     numpy.zeros(nvt),log=True)
            pvt_maxindx= numpy.argmax(pvt)
            va[kk]= (1.-tvt[pvt_maxindx])*_REFV0*vo
            if options.aAmethod.lower() == 'adiabaticgrid' and options.flatten >= 0.9:
                maxqdf[kk]= pvt[pvt_maxindx]+numpy.log(250.)
            elif options.aAmethod.lower() == 'adiabaticgrid' and options.flatten >= 0.8:
                maxqdf[kk]= pvt[pvt_maxindx]+numpy.log(250.)
            else:
                maxqdf[kk]= pvt[pvt_maxindx]+numpy.log(40.)
            sigphi[kk]= _REFV0*vo*4.*numpy.sqrt(numpy.sum(numpy.exp(pvt)*tvt**2.)/numpy.sum(numpy.exp(pvt))-(numpy.sum(numpy.exp(pvt)*tvt)/numpy.sum(numpy.exp(pvt)))**2.)
        ntries= 0
        ngtr1= 0
        while naccept < ndata:
            sys.stdout.write('\r %i %i %i \r' % (ntries,naccept,ndata))
            sys.stdout.flush()
            #print ntries, naccept, ndata
            ntries+= 1
            accept_v_comp= True-accept_v
            prop_vr= numpy.random.normal(size=ndata)*sigr
            prop_vt= numpy.random.normal(size=ndata)*sigphi+vo*_REFV0-va
            prop_vz= numpy.random.normal(size=ndata)*sigz
            qoverp= numpy.zeros(ndata)-numpy.finfo(numpy.dtype(numpy.float64)).max
            qoverp[accept_v_comp]= (qdf(newRs[accept_v_comp]/ro/_REFR0,
                                        prop_vr[accept_v_comp]/vo/_REFV0,
                                        prop_vt[accept_v_comp]/vo/_REFV0,
                                        newzs[accept_v_comp]/ro/_REFR0,
                                        prop_vz[accept_v_comp]/vo/_REFV0,log=True)
                                    -maxqdf[accept_v_comp] #normalize max to 1
                                    -(-0.5*(prop_vr[accept_v_comp]**2./sigr[accept_v_comp]**2.+prop_vz[accept_v_comp]**2./sigz[accept_v_comp]**2.+(prop_vt[accept_v_comp]-_REFV0*vo+va[accept_v_comp])**2./sigphi[accept_v_comp]**2.)))
            if numpy.any(qoverp > 0.):
                ngtr1+= numpy.sum((qoverp > 0.))
                if ngtr1 > 5:
                    qindx= (qoverp > 0.)
                    print naccept, ndata, newRs[qindx], newzs[qindx], prop_vr[qindx], va[qindx], sigphi[qindx], prop_vt[qindx], prop_vz[qindx], qoverp[qindx]
                    raise RuntimeError("max qoverp = %f > 1, but shouldn't be" % (numpy.exp(numpy.amax(qoverp))))
            accept_these= numpy.log(numpy.random.uniform(size=ndata))
            #print accept_these, (accept_these < qoverp)
            accept_these= (accept_these < qoverp)        
            newvr[accept_these]= prop_vr[accept_these]
            newvt[accept_these]= prop_vt[accept_these]
            newvz[accept_these]= prop_vz[accept_these]
            accept_v[accept_these]= True
            naccept= numpy.sum(accept_v)
        sys.stdout.write('\r'+_ERASESTR+'\r')
        sys.stdout.flush()
    """
    ntot= 0
    nsamples= 0
    itt= 0
    fracsuccess= 0.
    fraccomplete= 0.
    while fraccomplete < 1.:
        if itt == 0:
            nthis= numpy.amax([ndata,_NMIN])
        else:
            nthis= int(numpy.ceil((1-fraccomplete)/fracsuccess*ndata))
        itt+= 1
        count= 0
        while count < nthis:
            count+= 1
            sigz= thissz*numpy.exp(-(R-_REFR0)/thishsz)
            sigr= thissr*numpy.exp(-(R-_REFR0)/thishsr)
            sigphi= sigr #/numpy.sqrt(2.) #BOVY: FOR NOW
            #Estimate asymmetric drift
            va= sigr**2./2./_REFV0/vo\
                *(-.5+R*(1./thishr+2./thishsr))+10.*numpy.fabs(z)
            newvas.append(va)
            if options.mcout and thisoutlier:
                #Sample from outlier gaussian
                newvz.append(numpy.random.normal()*_SZHALOFAKE*2.)
                newvr.append(numpy.random.normal()*_SRHALOFAKE*2.)
                newvt.append(numpy.random.normal()*_SPHIHALOFAKE*2.)
            elif numpy.random.uniform() < lagoutfrac:
                #Sample from lagging gaussian
                newvz.append(numpy.random.normal()*_SZHALOFAKE)
                newvr.append(numpy.random.normal()*_SRHALOFAKE)
                newvt.append(numpy.random.normal()*_SPHIHALOFAKE*2.+_REFV0*vo/4.)
            else:
                #Sample from disk gaussian
                newvz.append(numpy.random.normal()*sigz)
                newvr.append(numpy.random.normal()*sigr)
                newvt.append(numpy.random.normal()*sigphi+_REFV0*vo-va)
            newlogratio= list(newlogratio)
            fidlogeval= numpy.log(1.-lagoutfrac)\
                     -numpy.log(sigr)-numpy.log(sigphi)-numpy.log(sigz)-0.5*(newvr[-1]**2./sigr**2.+newvz[-1]**2./sigz**2.+(newvt[-1]-_REFV0*vo+va)**2./sigphi**2.)
            lagoutlogeval= numpy.log(lagoutfrac)\
                     -numpy.log(_SRHALOFAKE)\
                     -numpy.log(_SPHIHALOFAKE*2.)\
                     -numpy.log(_SZHALOFAKE)\
                     -0.5*(newvr[-1]**2./_SRHALOFAKE**2.+newvz[-1]**2./_SZHALOFAKE**2.+(newvt[-1]-_REFV0*vo/4.)**2./_SPHIHALOFAKE**2./4.)
            if use_real_dens:
                fidlogeval+= numpy.log(compare_func(R,z,None)[0])
                lagoutlogeval+= numpy.log(compare_func(R,z,None)[0])
            else:
                fidlogeval+= numpy.log(fidDens(R,z,thishr,thishz,None))
                lagoutlogeval+= numpy.log(fidDens(R,z,thishr,thishz,None))
            newfideval.append(fidlogeval)
            if options.mcout:
                fidoutlogeval= numpy.log(fidoutfrac)\
                    +numpy.log(outDens(R,z,None))\
                    -numpy.log(_SRHALOFAKE*2.)\
                    -numpy.log(_SPHIHALOFAKE*2.)\
                    -numpy.log(_SZHALOFAKE*2.)\
                    -0.5*(newvr[-1]**2./_SRHALOFAKE**2./4.+newvz[-1]**2./_SZHALOFAKE**2./4.+newvt[-1]**2./_SPHIHALOFAKE**2./4.)
                newpropeval.append(logsumexp([fidoutlogeval,fidlogeval,
                                              lagoutlogeval]))
            else:
                newpropeval.append(logsumexp([lagoutlogeval,fidlogeval]))
            qdflogeval= qdf(R/ro/_REFR0,newvr[-1]/vo/_REFV0,newvt[-1]/vo/_REFV0,z/ro/_REFR0,newvz[-1]/vo/_REFV0,log=True)
            if isinstance(qdflogeval,(list,numpy.ndarray)):
                qdflogeval= qdflogeval[0]
            if options.mcout:
                outlogeval= logoutfrac+loghalodens\
                    -numpy.log(srhalo)-numpy.log(sphihalo)-numpy.log(szhalo)\
                    -0.5*((newvr[-1]/vo/_REFV0)**2./srhalo**2.+(newvz[-1]/vo/_REFV0)**2./szhalo**2.+(newvt[-1]/vo/_REFV0)**2./sphihalo**2.)\
                    -1.5*numpy.log(2.*numpy.pi)
                newqdfeval.append(logsumexp([qdflogeval,outlogeval]))
            else:
                newqdfeval.append(qdflogeval)
            newlogratio.append(qdflogeval
                               -newpropeval[-1])#logsumexp([fidlogeval,fidoutlogeval]))
        newlogratio= numpy.array(newlogratio)
        thisnewlogratio= copy.copy(newlogratio)
        maxnewlogratio= numpy.amax(thisnewlogratio)
        if False:
            argsort_thisnewlogratio= numpy.argsort(thisnewlogratio)[::-1]
            thisnewlogratio-= thisnewlogratio[argsort_thisnewlogratio[2]] #3rd largest
        else:
            thisnewlogratio-= numpy.amax(thisnewlogratio)
        thisnewratio= numpy.exp(thisnewlogratio)
        if len(thisnewratio.shape) > 1 and thisnewratio.shape[1] == 1:
            thisnewratio= numpy.reshape(thisnewratio,(thisnewratio.shape[0]))
        #Rejection sample
        accept= numpy.random.uniform(size=len(thisnewratio))
        accept= (accept < thisnewratio)
        fraccomplete= float(numpy.sum(accept))/ndata
        fracsuccess= float(numpy.sum(accept))/len(thisnewratio)
        if _DEBUG:
            print fraccomplete, fracsuccess, ndata
            print numpy.histogram(thisnewratio,bins=16)
            indx= numpy.argmax(thisnewratio)
            print numpy.array(newvr)[indx], \
                numpy.array(newvt)[indx], \
                numpy.array(newvz)[indx], \
                numpy.array(newrs)[indx], \
                numpy.array(newds)[indx], \
                numpy.array(newls)[indx], \
                numpy.array(newbs)[indx], \
                numpy.array(newfideval)[indx]
            bovy_plot.bovy_print()
            bovy_plot.bovy_plot(numpy.array(newvt),
                                numpy.exp(numpy.array(newqdfeval)),'b,',
                                xrange=[-300.,500.],yrange=[0.,1.])
            bovy_plot.bovy_plot(newvt,
                                numpy.exp(numpy.array(newpropeval+maxnewlogratio)),
                                'g,',
                                overplot=True)
            bovy_plot.bovy_plot(numpy.array(newvt),
                                numpy.exp(numpy.array(newlogratio-maxnewlogratio)),
                                'b,',
                                xrange=[-300.,500.],
                                #                            xrange=[0.,20.],
                                #                            xrange=[0.,3.],
                                #                            xrange=[6.,9.],
                                yrange=[0.001,1.],semilogy=True)
            bovy_plot.bovy_end_print('/home/bovy/public_html/segue-local/test.png')
    #Now collect the samples
    newrs= numpy.array(newrs)[accept][0:ndata]
    newls= numpy.array(newls)[accept][0:ndata]
    newbs= numpy.array(newbs)[accept][0:ndata]
    newplate= numpy.array(newplate)[accept][0:ndata]
    newgr= numpy.array(newgr)[accept][0:ndata]
    newfeh= numpy.array(newfeh)[accept][0:ndata]
    newvr= numpy.array(newvr)[accept][0:ndata]
    newvt= numpy.array(newvt)[accept][0:ndata]
    newvz= numpy.array(newvz)[accept][0:ndata]
    newphi= numpy.array(newphi)[accept][0:ndata]
    newds= numpy.array(newds)[accept][0:ndata]
    newqdfeval= numpy.array(newqdfeval)[accept][0:ndata]
    """
    vx, vy, vz= bovy_coords.galcencyl_to_vxvyvz(newvr,newvt,newvz,newphi,
                                                vsun=[_VRSUN,_VTSUN,_VZSUN])
    vrpmllpmbb= bovy_coords.vxvyvz_to_vrpmllpmbb(vx,vy,vz,newls,newbs,newds,
                                                 XYZ=False,degree=True)
    pmrapmdec= bovy_coords.pmllpmbb_to_pmrapmdec(vrpmllpmbb[:,1],
                                                 vrpmllpmbb[:,2],
                                                 newls,newbs,
                                                 degree=True)
    #Dump everything for debugging the coordinate transformation
    from galpy.util import save_pickles
    save_pickles('dump.sav',
                 newds,newls,newbs,newphi,
                 newvr,newvt,newvz,
                 vx, vy, vz,
                 vrpmllpmbb,
                 pmrapmdec)
    if returnlist:
        out= []
        for ii in range(ndata):
            out.append([newrs[ii],
                        newgr[ii],
                        newfeh[ii],
                        newls[ii],
                        newbs[ii],
                        newplate[ii],
                        newds[ii],
                        False, #outlier?
                        vrpmllpmbb[ii,0],
                        vrpmllpmbb[ii,1],
                        vrpmllpmbb[ii,2]])#,
#                        newqdfeval[ii]])
        return out
    #Load into data
    binned.data.feh[thisdataIndx]= newfeh
    oldgr= thisdata.dered_g-thisdata.dered_r
    oldr= thisdata.dered_r
    if options.noerrs:
        binned.data.dered_r[thisdataIndx]= newrs
    else:
        binned.data.dered_r[thisdataIndx]= newrs\
            +numpy.random.normal(size=numpy.sum(thisdataIndx))\
            *ivezic_dist_gr(oldgr,0., #g-r is all that counts
                            binned.data.feh[thisdataIndx],
                            dg=binned.data[thisdataIndx].g_err,
                            dr=binned.data[thisdataIndx].r_err,
                            dfeh=binned.data[thisdataIndx].feh_err,
                            return_error=True,
                            _returndmr=True)
    binned.data.dered_r[(binned.data.dered_r >= rmax)]= rmax #tweak to make sure everything stays within the observed range
    if False:
        binned.data.dered_r[(binned.data.dered_r <= rmin)]= rmin
    binned.data.dered_g[thisdataIndx]= oldgr+binned.data[thisdataIndx].dered_r
    #Also change plate and l and b
    binned.data.plate[thisdataIndx]= newplate
    radec= bovy_coords.lb_to_radec(newls,newbs,degree=True)
    binned.data.ra[thisdataIndx]= radec[:,0]
    binned.data.dec[thisdataIndx]= radec[:,1]
    binned.data.l[thisdataIndx]= newls
    binned.data.b[thisdataIndx]= newbs
    if options.noerrs:
        binned.data.vr[thisdataIndx]= vrpmllpmbb[:,0]
        binned.data.pmra[thisdataIndx]= pmrapmdec[:,0]
        binned.data.pmdec[thisdataIndx]= pmrapmdec[:,1]
    else:
        binned.data.vr[thisdataIndx]= vrpmllpmbb[:,0]+numpy.random.normal(size=numpy.sum(thisdataIndx))*binned.data.vr_err[thisdataIndx]
        binned.data.pmra[thisdataIndx]= pmrapmdec[:,0]+numpy.random.normal(size=numpy.sum(thisdataIndx))*binned.data.pmra_err[thisdataIndx]
        binned.data.pmdec[thisdataIndx]= pmrapmdec[:,1]+numpy.random.normal(size=numpy.sum(thisdataIndx))*binned.data.pmdec_err[thisdataIndx]
    return binned
Exemplo n.º 9
0
def findfriends(targname,radial_velocity,velocity_limit=5.0,search_radius=25.0,rvcut=5.0,radec=[None,None],output_directory = None,showplots=False,verbose=False,DoGALEX=True,DoWISE=True,DoROSAT=True):
    
    radvel= radial_velocity * u.kilometer / u.second
    
    if output_directory == None:
        outdir = './' + targname.replace(" ", "") + '_friends/'
    else: 
        outdir = output_directory
    if os.path.isdir(outdir) == True:
        print('Output directory ' + outdir +' Already Exists!!')
        print('Either Move it, Delete it, or input a different [output_directory] Please!')
        return
    os.mkdir(outdir)
    
    if velocity_limit < 0.00001 : 
        print('input velocity_limit is too small, try something else')
        print('velocity_limit: ' + str(velocity_limit))
    if search_radius < 0.0000001:
        print('input search_radius is too small, try something else')
        print('search_radius: ' + str(search_radius))
     
    # Search parameters
    vlim=velocity_limit * u.kilometer / u.second
    searchradpc=search_radius * u.parsec

    if (radec[0] != None) & (radec[1] != None):
        usera,usedec = radec[0],radec[1]
    else:  ##use the target name to get simbad ra and dec.
        print('Asking Simbad for RA and DEC')
        result_table = Simbad.query_object(targname)
        usera,usedec = result_table['RA'][0],result_table['DEC'][0]
    
    if verbose == True:
        print('Target name: ',targname)
        print('Coordinates: ' + str(usera) +' '+str(usedec))
        print()

    c = SkyCoord( ra=usera , dec=usedec , unit=(u.hourangle, u.deg) , frame='icrs')
    if verbose == True: print(c)

    # Find precise coordinates and distance from Gaia, define search radius and parallax cutoff
    print('Asking Gaia for precise coordinates')
    sqltext = "SELECT * FROM gaiaedr3.gaia_source WHERE CONTAINS( \
               POINT('ICRS',gaiaedr3.gaia_source.ra,gaiaedr3.gaia_source.dec), \
               CIRCLE('ICRS'," + str(c.ra.value) +","+ str(c.dec.value) +","+ str(6.0/3600.0) +"))=1;"
    job = Gaia.launch_job_async(sqltext , dump_to_file=False)
    Pgaia = job.get_results()
    if verbose == True:
        print(sqltext)
        print()
        print(Pgaia['source_id','ra','dec','phot_g_mean_mag','parallax','ruwe'].pprint_all())
        print()

    minpos = Pgaia['phot_g_mean_mag'].tolist().index(min(Pgaia['phot_g_mean_mag']))
    Pcoord = SkyCoord( ra=Pgaia['ra'][minpos]*u.deg , dec=Pgaia['dec'][minpos]*u.deg , \
                      distance=(1000.0/Pgaia['parallax'][minpos])*u.parsec , frame='icrs' , \
                      radial_velocity=radvel , \
                      pm_ra_cosdec=Pgaia['pmra'][minpos]*u.mas/u.year , pm_dec=Pgaia['pmdec'][minpos]*u.mas/u.year )

    searchraddeg = np.arcsin(searchradpc/Pcoord.distance).to(u.deg)
    minpar = (1000.0 * u.parsec) / (Pcoord.distance + searchradpc) * u.mas
    if verbose == True:
        print(Pcoord)
        print()
        print('Search radius in deg: ',searchraddeg)
        print('Minimum parallax: ',minpar)


    # Query Gaia with search radius and parallax cut
    # Note, a cut on parallax_error was added because searches at low galactic latitude 
    # return an overwhelming number of noisy sources that scatter into the search volume - ALK 20210325
    print('Querying Gaia for neighbors')

    Pllbb     = bc.radec_to_lb(Pcoord.ra.value , Pcoord.dec.value , degree=True)
    if ( np.abs(Pllbb[1]) > 10.0): plxcut = max( 0.5 , (1000.0/Pcoord.distance.value/10.0) )
    else: plxcut = 0.5
    print('Parallax cut: ',plxcut)

    if (searchradpc < Pcoord.distance):
        sqltext = "SELECT * FROM gaiaedr3.gaia_source WHERE CONTAINS( \
            POINT('ICRS',gaiaedr3.gaia_source.ra,gaiaedr3.gaia_source.dec), \
            CIRCLE('ICRS'," + str(Pcoord.ra.value) +","+ str(Pcoord.dec.value) +","+ str(searchraddeg.value) +"))\
            =1 AND parallax>" + str(minpar.value) + " AND parallax_error<" + str(plxcut) + ";"
    if (searchradpc >= Pcoord.distance):
        sqltext = "SELECT * FROM gaiaedr3.gaia_source WHERE parallax>" + str(minpar.value) + " AND parallax_error<" + str(plxcut) + ";"
        print('Note, using all-sky search')
    if verbose == True:
        print(sqltext)
        print()

    job = Gaia.launch_job_async(sqltext , dump_to_file=False)
    r = job.get_results()
   
    if verbose == True: print('Number of records: ',len(r['ra']))


    # Construct coordinates array for all stars returned in cone search

    gaiacoord = SkyCoord( ra=r['ra'] , dec=r['dec'] , distance=(1000.0/r['parallax'])*u.parsec , \
                         frame='icrs' , \
                         pm_ra_cosdec=r['pmra'] , pm_dec=r['pmdec'] )

    sep = gaiacoord.separation(Pcoord)
    sep3d = gaiacoord.separation_3d(Pcoord)

    if verbose == True:
        print('Printing angular separations in degrees as sanity check')
        print(sep.degree)



    Pllbb     = bc.radec_to_lb(Pcoord.ra.value , Pcoord.dec.value , degree=True)
    Ppmllpmbb = bc.pmrapmdec_to_pmllpmbb( Pcoord.pm_ra_cosdec.value , Pcoord.pm_dec.value , \
                                         Pcoord.ra.value , Pcoord.dec.value , degree=True )
    Pvxvyvz   = bc.vrpmllpmbb_to_vxvyvz(Pcoord.radial_velocity.value , Ppmllpmbb[0] , Ppmllpmbb[1] , \
                                   Pllbb[0] , Pllbb[1] , Pcoord.distance.value/1000.0 , XYZ=False , degree=True)

    if verbose == True:
        print('Science Target Name: ',targname)
        print('Science Target RA/DEC: ',Pcoord.ra.value,Pcoord.dec.value)
        print('Science Target Galactic Coordinates: ',Pllbb)
        print('Science Target UVW: ',Pvxvyvz)
        print()

    Gllbb = bc.radec_to_lb(gaiacoord.ra.value , gaiacoord.dec.value , degree=True)
    Gxyz = bc.lbd_to_XYZ( Gllbb[:,0] , Gllbb[:,1] , gaiacoord.distance/1000.0 , degree=True)
    Gvrpmllpmbb = bc.vxvyvz_to_vrpmllpmbb( \
                    Pvxvyvz[0]*np.ones(len(Gxyz[:,0])) , Pvxvyvz[1]*np.ones(len(Gxyz[:,1])) , Pvxvyvz[2]*np.ones(len(Gxyz[:,2])) , \
                    Gxyz[:,0] , Gxyz[:,1] , Gxyz[:,2] , XYZ=True)
    Gpmrapmdec = bc.pmllpmbb_to_pmrapmdec( Gvrpmllpmbb[:,1] , Gvrpmllpmbb[:,2] , Gllbb[:,0] , Gllbb[:,1] , degree=True)

    # Code in case I want to do chi^2 cuts someday
    Gvtanerr = 1.0 * np.ones(len(Gxyz[:,0]))
    Gpmerr = Gvtanerr * 206265000.0 * 3.154e7 / (gaiacoord.distance.value * 3.086e13)


    Gchi2 = ( (Gpmrapmdec[:,0]-gaiacoord.pm_ra_cosdec.value)**2 + (Gpmrapmdec[:,1]-gaiacoord.pm_dec.value)**2 )**0.5
    Gchi2 = Gchi2 / Gpmerr
    if verbose == True:
        print('Predicted PMs if comoving:')
        print(Gpmrapmdec , "\n")
        print('Actual PMRAs from Gaia:')
        print(gaiacoord.pm_ra_cosdec.value , "\n")
        print('Actual PMDECs from Gaia:')
        print(gaiacoord.pm_dec.value , "\n")
        print('Predicted PM errors:')
        print(Gpmerr , "\n")
        print('Chi^2 values:')
        print(Gchi2)


    # Query external list(s) of RVs

    zz = np.where( (sep3d.value < searchradpc.value) & (Gchi2 < vlim.value) )
    yy = zz[0][np.argsort(sep3d[zz])]
    
    RV    = np.empty(np.array(r['ra']).size)
    RVerr = np.empty(np.array(r['ra']).size)
    RVsrc = np.array([ '                             None' for x in range(np.array(r['ra']).size) ])
    RV[:]    = np.nan
    RVerr[:] = np.nan

    print('Populating RV table')
    for x in range(0 , np.array(yy).size):
        if np.isnan(r['dr2_radial_velocity'][yy[x]]) == False:        # First copy over DR2 RVs
            RV[yy[x]]    = r['dr2_radial_velocity'][yy[x]]
            RVerr[yy[x]] = r['dr2_radial_velocity_error'][yy[x]]
            RVsrc[yy[x]] = 'Gaia DR2'
    if os.path.isfile('LocalRV.csv'):
        with open('LocalRV.csv') as csvfile:                          # Now check for a local RV that would supercede
            readCSV = csv.reader(csvfile, delimiter=',')
            for row in readCSV:
                ww = np.where(r['designation'] == row[0])[0]
                if (np.array(ww).size == 1):
                    RV[ww]    = row[2]
                    RVerr[ww] = row[3]
                    RVsrc[ww] = row[4]
                    if verbose == True: 
                        print('Using stored RV: ',row)
                        print(r['ra','dec','phot_g_mean_mag'][ww])
                        print(RV[ww])
                        print(RVerr[ww])
                        print(RVsrc[ww])



    # Create Gaia CMD plot

    mamajek  = np.loadtxt(datapath+'/sptGBpRp.txt')
    pleiades = np.loadtxt(datapath+'/PleGBpRp.txt')
    tuchor   = np.loadtxt(datapath+'/TucGBpRp.txt')
    usco     = np.loadtxt(datapath+'/UScGBpRp.txt')
    chai     = np.loadtxt(datapath+'/ChaGBpRp.txt')

    zz = np.where( (sep3d.value < searchradpc.value) & (Gchi2 < vlim.value) & (np.isnan(r['bp_rp']) == False) ) # Note, this causes an error because NaNs
    yy = zz[0][np.argsort(sep3d[zz])]
    zz2= np.where( (sep3d.value < searchradpc.value) & (Gchi2 < vlim.value) & (sep.degree > 0.00001) & \
                 (r['phot_bp_rp_excess_factor'] < (1.3 + 0.06*r['bp_rp']**2)) & \
                 (np.isnan(r['bp_rp']) == False) )                                                              # Note, this causes an error because NaNs
    yy2= zz2[0][np.argsort((-Gchi2)[zz2])]


    figname=outdir + targname.replace(" ", "") + "cmd.png"
    if verbose == True: print(figname)

    fig,ax1 = plt.subplots(figsize=(12,8))

    ax1.axis([ math.floor(min(r['bp_rp'][zz])) , \
               math.ceil(max(r['bp_rp'][zz])), \
               math.ceil(max((r['phot_g_mean_mag'][zz] - (5.0*np.log10(gaiacoord.distance[zz].value)-5.0))))+1, \
               math.floor(min((r['phot_g_mean_mag'][zz] - (5.0*np.log10(gaiacoord.distance[zz].value)-5.0))))-1 ] )
    ax1.set_xlabel(r'$B_p-R_p$ (mag)' , fontsize=16)
    ax1.set_ylabel(r'$M_G$ (mag)' , fontsize=16)
    ax1.tick_params(axis='both',which='major',labelsize=12)

    ax2 = ax1.twiny()
    ax2.set_xlim(ax1.get_xlim())
    spttickvals = np.array([ -0.037 , 0.377 , 0.782 , 0.980 , 1.84 , 2.50 , 3.36 , 4.75 ])
    sptticklabs = np.array([ 'A0' , 'F0' , 'G0' , 'K0' , 'M0' , 'M3' , 'M5' , 'M7' ])
    xx = np.where( (spttickvals >= math.floor(min(r['bp_rp'][zz]))) & (spttickvals <= math.ceil(max(r['bp_rp'][zz]))) )[0]
    ax2.set_xticks(spttickvals[xx])
    ax2.set_xticklabels( sptticklabs[xx] )
    ax2.set_xlabel('SpT' , fontsize=16, labelpad=15)
    ax2.tick_params(axis='both',which='major',labelsize=12)

    ax1.plot(    chai[:,1] ,     chai[:,0]  , zorder=1 , label='Cha-I (0-5 Myr)')
    ax1.plot(    usco[:,1] ,     usco[:,0]  , zorder=2 , label='USco (11 Myr)')
    ax1.plot(  tuchor[:,1] ,   tuchor[:,0]  , zorder=3 , label='Tuc-Hor (40 Myr)')
    ax1.plot(pleiades[:,1] , pleiades[:,0]  , zorder=4 , label='Pleiades (125 Myr)')
    ax1.plot( mamajek[:,2] ,  mamajek[:,1]  , zorder=5 , label='Mamajek MS')

    for x in range(0 , np.array(yy2).size):
        msize  = (17-12.0*(sep3d[yy2[x]].value/searchradpc.value))**2
        mcolor = Gchi2[yy2[x]]
        medge  = 'black'
        mzorder= 7
        if (r['ruwe'][yy2[x]] < 1.2):
            mshape='o'
        if (r['ruwe'][yy2[x]] >= 1.2):
            mshape='s'
        if (np.isnan(rvcut) == False): 
            if (np.isnan(RV[yy2[x]])==False) & (np.abs(RV[yy2[x]]-Gvrpmllpmbb[yy2[x],0]) > rvcut):
                mshape='+'
                mcolor='black'
                mzorder=6
            if (np.isnan(RV[yy2[x]])==False) & (np.abs(RV[yy2[x]]-Gvrpmllpmbb[yy2[x],0]) <= rvcut):
                medge='blue'

        ccc = ax1.scatter(r['bp_rp'][yy2[x]] , (r['phot_g_mean_mag'][yy2[x]] - (5.0*np.log10(gaiacoord.distance[yy2[x]].value)-5.0)) , \
                s=msize , c=mcolor , marker=mshape , edgecolors=medge , zorder=mzorder , \
                vmin=0.0 , vmax=vlim.value , cmap='cubehelix' , label='_nolabel' )

    temp1 = ax1.scatter([] , [] , c='white' , edgecolors='black', marker='o' , s=12**2 , label = 'RUWE < 1.2')
    temp2 = ax1.scatter([] , [] , c='white' , edgecolors='black', marker='s' , s=12**2 , label = 'RUWE >= 1.2')
    temp3 = ax1.scatter([] , [] , c='white' , edgecolors='blue' , marker='o' , s=12**2 , label = 'RV Comoving')
    temp4 = ax1.scatter([] , [] , c='black' , marker='+' , s=12**2 , label = 'RV Outlier')

    ax1.plot(r['bp_rp'][yy[0]] , (r['phot_g_mean_mag'][yy[0]] - (5.0*np.log10(gaiacoord.distance[yy[0]].value)-5.0)) , \
             'rx' , markersize=18 , mew=3 , markeredgecolor='red' , zorder=10 , label=targname)

    ax1.arrow( 1.3 , 2.5 , 0.374, 0.743 , length_includes_head=True , head_width=0.07 , head_length = 0.10 )
    ax1.text(  1.4 , 2.3, r'$A_V=1$' , fontsize=12)



    ax1.legend(fontsize=11)
    cb = plt.colorbar(ccc , ax=ax1)
    cb.set_label(label='Velocity Difference (km/s)',fontsize=14)
    plt.savefig(figname , bbox_inches='tight', pad_inches=0.2 , dpi=200)
    if showplots == True: plt.show()
    plt.close('all')


    # Create PM plot


    zz2= np.where( (sep3d.value < searchradpc.value) & (Gchi2 < vlim.value) & (sep.degree > 0.00001) )
    yy2= zz2[0][np.argsort((-Gchi2)[zz2])]
    zz3= np.where( (sep3d.value < searchradpc.value) & (sep.degree > 0.00001) )

    figname=outdir + targname.replace(" ", "") + "pmd.png"

    fig,ax1 = plt.subplots(figsize=(12,8))

    ax1.axis([ (max(r['pmra'][zz2]) + 0.05*np.ptp(r['pmra'][zz2]) ) , \
           (min(r['pmra'][zz2]) - 0.05*np.ptp(r['pmra'][zz2]) ) , \
           (min(r['pmdec'][zz2])- 0.05*np.ptp(r['pmra'][zz2]) ) , \
           (max(r['pmdec'][zz2])+ 0.05*np.ptp(r['pmra'][zz2]) ) ] )
    ax1.tick_params(axis='both',which='major',labelsize=16)

    if  ((max(r['pmra'][zz2]) + 0.05*np.ptp(r['pmra'][zz2])) > 0.0) & \
            ((min(r['pmra'][zz2]) - 0.05*np.ptp(r['pmra'][zz2])) < 0.0) & \
            ((min(r['pmdec'][zz2])- 0.05*np.ptp(r['pmra'][zz2])) < 0.0) & \
            ((max(r['pmdec'][zz2])+ 0.05*np.ptp(r['pmra'][zz2])) > 0.0):
        ax1.plot( [0.0,0.0] , [-1000.0,1000.0] , 'k--' , linewidth=1 )
        ax1.plot( [-1000.0,1000.0] , [0.0,0.0] , 'k--' , linewidth=1 )

    ax1.errorbar( (r['pmra'][yy2]) , (r['pmdec'][yy2]) , \
            yerr=(r['pmdec_error'][yy2]) , xerr=(r['pmra_error'][yy2]) , fmt='none' , ecolor='k' )

    ax1.scatter( (r['pmra'][zz3]) , (r['pmdec'][zz3]) , \
              s=(0.5)**2 , marker='o' , c='black' , zorder=2 , label='Field' )

    for x in range(0 , np.array(yy2).size):
        msize  = (17-12.0*(sep3d[yy2[x]].value/searchradpc.value))**2
        mcolor = Gchi2[yy2[x]]
        medge  = 'black'
        mzorder= 7
        if (r['ruwe'][yy2[x]] < 1.2):
            mshape='o'
        if (r['ruwe'][yy2[x]] >= 1.2):
            mshape='s'
        if (np.isnan(rvcut) == False): 
            if (np.isnan(RV[yy2[x]])==False) & (np.abs(RV[yy2[x]]-Gvrpmllpmbb[yy2[x],0]) > rvcut):
                mshape='+'
                mcolor='black'
                mzorder=6
            if (np.isnan(RV[yy2[x]])==False) & (np.abs(RV[yy2[x]]-Gvrpmllpmbb[yy2[x],0]) <= rvcut):
                medge='blue'
        ccc = ax1.scatter(r['pmra'][yy2[x]] , r['pmdec'][yy2[x]] , \
                s=msize , c=mcolor , marker=mshape , edgecolors=medge , zorder=mzorder , \
                vmin=0.0 , vmax=vlim.value , cmap='cubehelix' , label='_nolabel' )

    temp1 = ax1.scatter([] , [] , c='white' , edgecolors='black', marker='o' , s=12**2 , label = 'RUWE < 1.2')
    temp2 = ax1.scatter([] , [] , c='white' , edgecolors='black', marker='s' , s=12**2 , label = 'RUWE >= 1.2')
    temp3 = ax1.scatter([] , [] , c='white' , edgecolors='blue' , marker='o' , s=12**2 , label = 'RV Comoving')
    temp4 = ax1.scatter([] , [] , c='black' , marker='+' , s=12**2 , label = 'RV Outlier')

    ax1.plot( Pgaia['pmra'][minpos] , Pgaia['pmdec'][minpos] , \
         'rx' , markersize=18 , mew=3 , markeredgecolor='red' , zorder=3 , label=targname)

    ax1.set_xlabel(r'$\mu_{RA}$ (mas/yr)' , fontsize=22 , labelpad=10)
    ax1.set_ylabel(r'$\mu_{DEC}$ (mas/yr)' , fontsize=22 , labelpad=10)
    ax1.legend(fontsize=12)

    cb = plt.colorbar(ccc , ax=ax1)
    cb.set_label(label='Tangential Velocity Difference (km/s)',fontsize=18 , labelpad=10)
    plt.savefig(figname , bbox_inches='tight', pad_inches=0.2 , dpi=200)
    if showplots == True: plt.show()
    plt.close('all')


    # Create RV plot

    zz2= np.where( (sep3d.value < searchradpc.value) & (Gchi2 < vlim.value) & (sep.degree > 0.00001) & \
             (np.isnan(RV) == False) )
    yy2= zz2[0][np.argsort((-Gchi2)[zz2])]

    zz3= np.where( (sep3d.value < searchradpc.value) & (Gchi2 < vlim.value) & (sep.degree > 0.00001) & \
             (np.isnan(RV) == False) & (np.isnan(r['phot_g_mean_mag']) == False) & \
             (np.abs(RV-Gvrpmllpmbb[:,0]) < 20.0) ) # Just to set Y axis

    fig,ax1 = plt.subplots(figsize=(12,8))
    ax1.axis([ -20.0 , +20.0, \
           max( np.append( np.array(r['phot_g_mean_mag'][zz3] - (5.0*np.log10(gaiacoord.distance[zz3].value)-5.0)) ,  0.0 )) + 0.3 , \
           min( np.append( np.array(r['phot_g_mean_mag'][zz3] - (5.0*np.log10(gaiacoord.distance[zz3].value)-5.0)) , 15.0 )) - 0.3   ])
    ax1.tick_params(axis='both',which='major',labelsize=16)

    ax1.plot( [0.0,0.0] , [-20.0,25.0] , 'k--' , linewidth=1 )

    ax1.errorbar( (RV[yy2]-Gvrpmllpmbb[yy2,0]) , \
           (r['phot_g_mean_mag'][yy2] - (5.0*np.log10(gaiacoord.distance[yy2].value)-5.0)) , \
            yerr=None,xerr=(RVerr[yy2]) , fmt='none' , ecolor='k' )

    for x in range(0 , np.array(yy2).size):
        msize  = (17-12.0*(sep3d[yy2[x]].value/searchradpc.value))**2
        mcolor = Gchi2[yy2[x]]
        medge  = 'black'
        mzorder= 2
        if (r['ruwe'][yy2[x]] < 1.2):
            mshape='o'
        if (r['ruwe'][yy2[x]] >= 1.2):
            mshape='s'
        ccc = ax1.scatter( (RV[yy2[x]]-Gvrpmllpmbb[yy2[x],0]) , \
                (r['phot_g_mean_mag'][yy2[x]] - (5.0*np.log10(gaiacoord.distance[yy2[x]].value)-5.0)) , \
                s=msize , c=mcolor , marker=mshape , edgecolors=medge , zorder=mzorder , \
                vmin=0.0 , vmax=vlim.value , cmap='cubehelix' , label='_nolabel' )

    temp1 = ax1.scatter([] , [] , c='white' , edgecolors='black', marker='o' , s=12**2 , label = 'RUWE < 1.2')
    temp2 = ax1.scatter([] , [] , c='white' , edgecolors='black', marker='s' , s=12**2 , label = 'RUWE >= 1.2')
    temp3 = ax1.scatter([] , [] , c='white' , edgecolors='blue' , marker='o' , s=12**2 , label = 'RV Comoving')

    if ( (Pgaia['phot_g_mean_mag'][minpos] - (5.0*np.log10(Pcoord.distance.value)-5.0)) < \
                                     (max( np.append( np.array(r['phot_g_mean_mag'][zz3] - (5.0*np.log10(gaiacoord.distance[zz3].value)-5.0)) , 0.0 )) + 0.3) ):
        ax1.plot( [0.0] , (Pgaia['phot_g_mean_mag'][minpos] - (5.0*np.log10(Pcoord.distance.value)-5.0)) , \
                  'rx' , markersize=18 , mew=3 , markeredgecolor='red' , zorder=3 , label=targname)


    ax1.set_ylabel(r'$M_G$ (mag)' , fontsize=22 , labelpad=10)
    ax1.set_xlabel(r'$v_{r,obs}-v_{r,pred}$ (km/s)' , fontsize=22 , labelpad=10)
    ax1.legend(fontsize=12)

    cb = plt.colorbar(ccc , ax=ax1)
    cb.set_label(label='Tangential Velocity Difference (km/s)',fontsize=18 , labelpad=10)

    figname=outdir + targname.replace(" ", "") + "drv.png"
    plt.savefig(figname , bbox_inches='tight', pad_inches=0.2 , dpi=200)
    if showplots == True: plt.show()
    plt.close('all')



    
    # Create XYZ plot

    Pxyz = bc.lbd_to_XYZ( Pllbb[0] , Pllbb[1] , Pcoord.distance.value/1000.0 , degree=True)

    fig,axs = plt.subplots(2,2)
    fig.set_figheight(16)
    fig.set_figwidth(16)
    fig.subplots_adjust(hspace=0.03,wspace=0.03)

    zz2= np.where( (sep3d.value < searchradpc.value) & (Gchi2 < vlim.value) & (sep.degree > 0.00001) )
    yy2= zz2[0][np.argsort((-Gchi2)[zz2])]

    for x in range(0 , np.array(yy2).size):
        msize  = (17-12.0*(sep3d[yy2[x]].value/searchradpc.value))**2
        mcolor = Gchi2[yy2[x]]
        medge  = 'black'
        mzorder= 3
        if (r['ruwe'][yy2[x]] < 1.2):
            mshape='o'
        if (r['ruwe'][yy2[x]] >= 1.2):
            mshape='s'
        if (np.isnan(rvcut) == False): 
            if (np.isnan(RV[yy2[x]])==False) & (np.abs(RV[yy2[x]]-Gvrpmllpmbb[yy2[x],0]) > rvcut):
                mshape='+'
                mcolor='black'
                mzorder=2
            if (np.isnan(RV[yy2[x]])==False) & (np.abs(RV[yy2[x]]-Gvrpmllpmbb[yy2[x],0]) <= rvcut):
                medge='blue'
        ccc = axs[0,0].scatter( 1000.0*Gxyz[yy2[x],0] , 1000.0*Gxyz[yy2[x],1] , \
                s=msize , c=mcolor , marker=mshape , edgecolors=medge , zorder=mzorder , \
                vmin=0.0 , vmax=vlim.value , cmap='cubehelix' , label='_nolabel' )
        ccc = axs[0,1].scatter( 1000.0*Gxyz[yy2[x],2] , 1000.0*Gxyz[yy2[x],1] , \
                s=msize , c=mcolor , marker=mshape , edgecolors=medge , zorder=mzorder , \
                vmin=0.0 , vmax=vlim.value , cmap='cubehelix' , label='_nolabel' )
        ccc = axs[1,0].scatter( 1000.0*Gxyz[yy2[x],0] , 1000.0*Gxyz[yy2[x],2] , \
                s=msize , c=mcolor , marker=mshape , edgecolors=medge , zorder=mzorder , \
                vmin=0.0 , vmax=vlim.value , cmap='cubehelix' , label='_nolabel' )

    temp1 = axs[0,0].scatter([] , [] , c='white' , edgecolors='black', marker='o' , s=12**2 , label = 'RUWE < 1.2')
    temp2 = axs[0,0].scatter([] , [] , c='white' , edgecolors='black', marker='s' , s=12**2 , label = 'RUWE >= 1.2')
    temp3 = axs[0,0].scatter([] , [] , c='white' , edgecolors='blue' , marker='o' , s=12**2 , label = 'RV Comoving')
    temp4 = axs[0,0].scatter([] , [] , c='black' , marker='+' , s=12**2 , label = 'RV Outlier')

    axs[0,0].plot( 1000.0*Pxyz[0] , 1000.0*Pxyz[1] , 'rx' , markersize=18 , mew=3 , markeredgecolor='red')
    axs[0,1].plot( 1000.0*Pxyz[2] , 1000.0*Pxyz[1] , 'rx' , markersize=18 , mew=3 , markeredgecolor='red')
    axs[1,0].plot( 1000.0*Pxyz[0] , 1000.0*Pxyz[2] , 'rx' , markersize=18 , mew=3 , markeredgecolor='red' , zorder=1 , label = targname)

    axs[0,0].set_xlim( [1000.0*Pxyz[0]-(search_radius+1.0) , 1000.0*Pxyz[0]+(search_radius+1.0)] )
    axs[0,0].set_ylim( [1000.0*Pxyz[1]-(search_radius+1.0) , 1000.0*Pxyz[1]+(search_radius+1.0)] )
    axs[0,1].set_xlim( [1000.0*Pxyz[2]-(search_radius+1.0) , 1000.0*Pxyz[2]+(search_radius+1.0)] )
    axs[0,1].set_ylim( [1000.0*Pxyz[1]-(search_radius+1.0) , 1000.0*Pxyz[1]+(search_radius+1.0)] )
    axs[1,0].set_xlim( [1000.0*Pxyz[0]-(search_radius+1.0) , 1000.0*Pxyz[0]+(search_radius+1.0)] )
    axs[1,0].set_ylim( [1000.0*Pxyz[2]-(search_radius+1.0) , 1000.0*Pxyz[2]+(search_radius+1.0)] )
    
    axs[0,0].set_xlabel(r'$X$ (pc)',fontsize=20,labelpad=10)
    axs[0,0].set_ylabel(r'$Y$ (pc)',fontsize=20,labelpad=10)

    axs[1,0].set_xlabel(r'$X$ (pc)',fontsize=20,labelpad=10)
    axs[1,0].set_ylabel(r'$Z$ (pc)',fontsize=20,labelpad=10)

    axs[0,1].set_xlabel(r'$Z$ (pc)',fontsize=20,labelpad=10)
    axs[0,1].set_ylabel(r'$Y$ (pc)',fontsize=20,labelpad=10)

    axs[0,0].xaxis.set_ticks_position('top')
    axs[0,1].xaxis.set_ticks_position('top')
    axs[0,1].yaxis.set_ticks_position('right')

    axs[0,0].xaxis.set_label_position('top')
    axs[0,1].xaxis.set_label_position('top')
    axs[0,1].yaxis.set_label_position('right')

    for aa in [0,1]:
        for bb in [0,1]:
            axs[aa,bb].tick_params(top=True,bottom=True,left=True,right=True,direction='in',labelsize=18)

    fig.delaxes(axs[1][1])
    strsize = 26
    if (len(targname) > 12.0): strsize = np.floor(24 / (len(targname)/14.5))
    fig.legend( bbox_to_anchor=(0.92,0.37) , prop={'size':strsize})

    cbaxes = fig.add_axes([0.55,0.14,0.02,0.34])
    cb = plt.colorbar( ccc , cax=cbaxes )
    cb.set_label( label='Velocity Difference (km/s)' , fontsize=24 , labelpad=20 )
    cb.ax.tick_params(labelsize=18)

    figname=outdir + targname.replace(" ", "") + "xyz.png"
    plt.savefig(figname , bbox_inches='tight', pad_inches=0.2 , dpi=200)

    if showplots == True: plt.show()
    plt.close('all')



    # Create sky map
    # Hacked from cartopy.mpl.gridliner
    _DEGREE_SYMBOL = u'\u00B0'
    def _east_west_formatted(longitude, num_format='g'):
        fmt_string = u'{longitude:{num_format}}{degree}'
        return fmt_string.format(longitude=(longitude if (longitude >= 0) else (longitude + 360)) , \
                                            num_format=num_format,degree=_DEGREE_SYMBOL)
    def _north_south_formatted(latitude, num_format='g'):
        fmt_string = u'{latitude:{num_format}}{degree}'
        return fmt_string.format(latitude=latitude, num_format=num_format,degree=_DEGREE_SYMBOL)
    LONGITUDE_FORMATTER = mticker.FuncFormatter(lambda v, pos:
                                                _east_west_formatted(v))
    LATITUDE_FORMATTER = mticker.FuncFormatter(lambda v, pos:
                                               _north_south_formatted(v))

    zz = np.where( (sep3d.value < searchradpc.value) & (Gchi2 < vlim.value) & (sep.degree > 0.00001) )
    yy = zz[0][np.argsort((-Gchi2)[zz])]

    searchcircle = Pcoord.directional_offset_by( (np.arange(0,360)*u.degree) , searchraddeg*np.ones(360))
    circleRA = searchcircle.ra.value
    circleDE = searchcircle.dec.value
    ww = np.where(circleRA > 180.0)
    circleRA[ww] = circleRA[ww] - 360.0

    RAlist = gaiacoord.ra[yy].value
    DElist = gaiacoord.dec[yy].value
    ww = np.where( RAlist > 180.0 )
    RAlist[ww] = RAlist[ww] - 360.0

    polelat = ((Pcoord.dec.value+90) if (Pcoord.dec.value<0) else (90-Pcoord.dec.value))
    polelong= (Pcoord.ra.value if (Pcoord.dec.value<0.0) else (Pcoord.ra.value+180.0))
    polelong= (polelong if polelong < 180 else polelong - 360.0)

    if verbose == True:
        print('Alignment variables: ',polelat,polelong,Pcoord.ra.value)
        print(Pcoord.dec.value+searchraddeg.value)
    rotated_pole = ccrs.RotatedPole( \
        pole_latitude=polelat , \
        pole_longitude=polelong , \
        central_rotated_longitude=90.0 )#\
    #    (Pcoord.ra.value if (Pcoord.dec.value > 0.0) else (Pcoord.ra.value+180.0)) )

    fig = plt.figure(figsize=(8,8))
    ax = fig.add_subplot(1, 1, 1, projection=rotated_pole)

    ax.gridlines(draw_labels=True,x_inline=True,y_inline=True, \
                 xformatter=LONGITUDE_FORMATTER,yformatter=LATITUDE_FORMATTER)
    ax.plot( circleRA , circleDE , c="gray" , ls="--" , transform=ccrs.Geodetic())
    
    figname=outdir + targname.replace(" ", "") + "sky.png"

    base=plt.cm.get_cmap('cubehelix')

    for x in range(0 , np.array(yy).size):
        msize  = (17-12.0*(sep3d[yy[x]].value/searchradpc.value))
        mcolor = base(Gchi2[yy[x]]/vlim.value)
        medge  = 'black'
        mzorder= 3
        if (r['ruwe'][yy[x]] < 1.2):
            mshape='o'
        if (r['ruwe'][yy[x]] >= 1.2):
            mshape='s'
        if (np.isnan(rvcut) == False): 
            if (np.isnan(RV[yy[x]])==False) & (np.abs(RV[yy[x]]-Gvrpmllpmbb[yy[x],0]) > rvcut):
                mshape='+'
                mcolor='black'
                mzorder=2
            if (np.isnan(RV[yy[x]])==False) & (np.abs(RV[yy[x]]-Gvrpmllpmbb[yy[x],0]) <= rvcut):
                medge='blue'
        ccc = ax.plot( RAlist[x] , DElist[x] , marker=mshape ,  \
                markeredgecolor=medge , ms = msize , mfc = mcolor , transform=ccrs.Geodetic() )
        
    ax.plot( (Pcoord.ra.value-360.0) , Pcoord.dec.value , \
            'rx' , markersize=18 , mew=3 , transform=ccrs.Geodetic())

    plt.savefig(figname , bbox_inches='tight', pad_inches=0.2 , dpi=200)
    
    if showplots == True: plt.show()
    plt.close('all')

    ## Query GALEX and 2MASS data

    zz = np.where( (sep3d.value < searchradpc.value) & (Gchi2 < vlim.value) )
    yy = zz[0][np.argsort((-Gchi2)[zz])]
    
    NUVmag = np.empty(np.array(r['ra']).size)
    NUVerr = np.empty(np.array(r['ra']).size)
    NUVmag[:] = np.nan
    NUVerr[:] = np.nan

    print('Searching on neighbors in GALEX')
    ##suppress the stupid noresultswarning from the catalogs package
    warnings.filterwarnings("ignore",category=NoResultsWarning)

    for x in range(0 , np.array(yy).size):
        querystring=((str(gaiacoord.ra[yy[x]].value) if (gaiacoord.ra[yy[x]].value > 0) \
                      else str(gaiacoord.ra[yy[x]].value+360.0)) + " " + str(gaiacoord.dec[yy[x]].value))
        print('GALEX query ',x,' of ',np.array(yy).size, end='\r')
        if verbose == True: print('GALEX query ',x,' of ',np.array(yy).size)
        if verbose == True: print(querystring)
        if (DoGALEX == True): 
            galex = Catalogs.query_object(querystring , catalog="Galex" , radius=0.0028 , TIMEOUT=600)
            if ((np.where(galex['nuv_magerr'] > 0.0)[0]).size > 0):
                ww = np.where( (galex['nuv_magerr'] == min(galex['nuv_magerr'][np.where(galex['nuv_magerr'] > 0.0)])))
                NUVmag[yy[x]] = galex['nuv_mag'][ww][0]
                NUVerr[yy[x]] = galex['nuv_magerr'][ww][0]
                if verbose == True: print(galex['distance_arcmin','ra','nuv_mag','nuv_magerr'][ww])

        
    Jmag = np.empty(np.array(r['ra']).size)
    Jerr = np.empty(np.array(r['ra']).size)
    Jmag[:] = np.nan
    Jerr[:] = np.nan

    print('Searching on neighbors in 2MASS')

    for x in range(0 , np.array(yy).size):
        if ( np.isnan(NUVmag[yy[x]]) == False ):
            querycoord = SkyCoord((str(gaiacoord.ra[yy[x]].value) if (gaiacoord.ra[yy[x]].value > 0) else \
                     str(gaiacoord.ra[yy[x]].value+360.0)) , str(gaiacoord.dec[yy[x]].value) , \
                     unit=(u.deg,u.deg) , frame='icrs')
            print('2MASS query ',x,' of ',np.array(yy).size, end='\r')
            if verbose == True: print('2MASS query ',x,' of ',np.array(yy).size)
            if verbose == True: print(querycoord)
            tmass = []
            if (DoGALEX == True): 
                tmass = Irsa.query_region(querycoord , catalog='fp_psc' , radius='0d0m10s' )
                if ((np.where(tmass['j_m'] > -10.0)[0]).size > 0):
                    ww = np.where( (tmass['j_m'] == min(tmass['j_m'][np.where(tmass['j_m'] > 0.0)])))
                    Jmag[yy[x]] = tmass['j_m'][ww][0]
                    Jerr[yy[x]] = tmass['j_cmsig'][ww][0]
                    if verbose == True: print(tmass['j_m','j_cmsig'][ww])
        


    # Create GALEX plots
    mamajek = np.loadtxt(datapath+'/sptGBpRp.txt')
    f = interp1d( mamajek[:,2] , mamajek[:,0] , kind='cubic')

    zz2 = np.where( (sep3d.value < searchradpc.value) & (Gchi2 < vlim.value) )
    yy2 = zz[0][np.argsort(sep3d[zz])]
    zz = np.where( (sep3d.value < searchradpc.value) & (Gchi2 < vlim.value) & (sep.degree > 0.00001) )
    yy = zz[0][np.argsort((-Gchi2)[zz])]

    fnuvj = (3631.0 * 10**6 * 10**(-0.4 * NUVmag)) / (1594.0 * 10**6 * 10**(-0.4 * Jmag))
    spt = f(r['bp_rp'].filled(np.nan))
    sptstring = ["nan" for x in range(np.array(r['bp_rp']).size)]
    for x in range(0 , np.array(zz2).size):
        if (round(spt[yy2[x]],1) >= 17.0) and (round(spt[yy2[x]],1) < 27.0):
            sptstring[yy2[x]] = 'M' + ('% 3.1f' % (round(spt[yy2[x]],1)-17.0)).strip()
        if (round(spt[yy2[x]],1) >= 16.0) and (round(spt[yy2[x]],1) < 17.0):
            sptstring[yy2[x]] = 'K' + ('% 3.1f' % (round(spt[yy2[x]],1)-9.0)).strip()
        if (round(spt[yy2[x]],1) >= 10.0) and (round(spt[yy2[x]],1) < 16.0):
            sptstring[yy2[x]] = 'K' + ('% 3.1f' % (round(spt[yy2[x]],1)-10.0)).strip()
        if (round(spt[yy2[x]],1) >= 0.0) and (round(spt[yy2[x]],1) < 10.0):
            sptstring[yy2[x]] = 'G' + ('% 3.1f' % (round(spt[yy2[x]],1)-0.0)).strip()
        if (round(spt[yy2[x]],1) >= -10.0) and (round(spt[yy2[x]],1) < 0.0):
            sptstring[yy2[x]] = 'F' + ('% 3.1f' % (round(spt[yy2[x]],1)+10.0)).strip()
        if (round(spt[yy2[x]],1) >= -20.0) and (round(spt[yy2[x]],1) < -10.0):
            sptstring[yy2[x]] = 'A' + ('% 3.1f' % (round(spt[yy2[x]],1)+20.0)).strip()       
        if (round(spt[yy2[x]],1) >= -30.0) and (round(spt[yy2[x]],1) < -20.0):
            sptstring[yy2[x]] = 'B' + ('% 3.1f' % (round(spt[yy2[x]],1)+30.0)).strip()  
    


    figname=outdir + targname.replace(" ", "") + "galex.png"
    if verbose == True: print(figname)
    ##Muck with the axis to get two x axes

    fig,ax1 = plt.subplots(figsize=(12,8))
    ax1.set_yscale('log')
    ax1.axis([5.0 , 24.0 , 0.000004 , 0.02])
    ax2 = ax1.twiny()
    ax2.set_xlim(ax1.get_xlim())
    ax1.set_xticks(np.array([5.0 , 10.0 , 15.0 , 17.0 , 22.0 , 24.0]))
    ax1.set_xticklabels(['G5','K0','K5','M0','M5','M7'])
    ax1.set_xlabel('SpT' , fontsize=20, labelpad=15)
    ax1.tick_params(axis='both',which='major',labelsize=16)
    ax2.set_xticks(np.array([5.0 , 10.0 , 15.0 , 17.0 , 22.0 , 24.0]))
    ax2.set_xticklabels(['0.85','0.98','1.45','1.84','3.36','4.75'])
    ax2.set_xlabel(r'$B_p-R_p$ (mag)' , fontsize=20, labelpad=15)
    ax2.tick_params(axis='both',which='major',labelsize=16)
    ax1.set_ylabel(r'$F_{NUV}/F_{J}$' , fontsize=22, labelpad=0)

    ##Hyades
    hyades = readsav(datapath +'/HYsaved.sav')
    hyadesfnuvj = (3631.0 * 10**6 * 10**(-0.4 * hyades['clnuv'])) / (1594.0 * 10**6 * 10**(-0.4 * hyades['clJ']))
    ax1.plot(hyades['clspt'] , hyadesfnuvj , 'x' , markersize=4 , mew=1 , markeredgecolor='black' , zorder=1 , label='Hyades' )

    for x in range(0 , np.array(yy).size):
        msize  = (17-12.0*(sep3d[yy[x]].value/searchradpc.value))**2
        mcolor = Gchi2[yy[x]]
        medge  = 'black'
        mzorder= 3
        if (r['ruwe'][yy[x]] < 1.2):
            mshape='o'
        if (r['ruwe'][yy[x]] >= 1.2):
            mshape='s'
        if (np.isnan(rvcut) == False): 
            if (np.isnan(RV[yy[x]])==False) & (np.abs(RV[yy[x]]-Gvrpmllpmbb[yy[x],0]) > rvcut):
                mshape='+'
                mcolor='black'
                mzorder=2
            if (np.isnan(RV[yy[x]])==False) & (np.abs(RV[yy[x]]-Gvrpmllpmbb[yy[x],0]) <= rvcut):
                medge='blue'
        ccc = ax1.scatter( spt[yy[x]] , fnuvj[yy[x]] , \
                s=msize , c=mcolor , marker=mshape , edgecolors=medge , zorder=mzorder , \
                vmin=0.0 , vmax=vlim.value , cmap='cubehelix' , label='_nolabel' )

    temp1 = ax1.scatter([] , [] , c='white' , edgecolors='black', marker='o' , s=12**2 , label = 'RUWE < 1.2')
    temp2 = ax1.scatter([] , [] , c='white' , edgecolors='black', marker='s' , s=12**2 , label = 'RUWE >= 1.2')
    temp3 = ax1.scatter([] , [] , c='white' , edgecolors='blue' , marker='o' , s=12**2 , label = 'RV Comoving')
    temp4 = ax1.scatter([] , [] , c='black' , marker='+' , s=12**2 , label = 'RV Outlier')



    # Plot science target
    if (spt[yy[0]] > 5): ax1.plot(spt[yy[0]] , fnuvj[yy[0]] , 'rx' , markersize=18 , mew=3 , markeredgecolor='red' , zorder=3 , label=targname )

    ax1.legend(fontsize=16 , loc='lower left')
    cb = fig.colorbar(ccc , ax=ax1)
    cb.set_label(label='Velocity Offset (km/s)',fontsize=13)
    if (DoGALEX == True): plt.savefig(figname , bbox_inches='tight', pad_inches=0.2 , dpi=200)
    if showplots == True: plt.show()
    plt.close('all')
    
    
    # Query CatWISE for W1+W2 and AllWISE for W3+W4

    zz = np.where( (sep3d.value < searchradpc.value) & (Gchi2 < vlim.value) )
    yy = zz[0][np.argsort((-Gchi2)[zz])]

    WISEmag = np.empty([np.array(r['ra']).size,4])
    WISEerr = np.empty([np.array(r['ra']).size,4])
    WISEmag[:] = np.nan
    WISEerr[:] = np.nan

    print('Searching on neighbors in WISE')
    ##there's an annoying nan warning here, hide it for now as it's not a problem
    warnings.filterwarnings("ignore",category=UserWarning)

    for x in range(0 , np.array(yy).size):
        querycoord = SkyCoord((str(gaiacoord.ra[yy[x]].value) if (gaiacoord.ra[yy[x]].value > 0) else \
                     str(gaiacoord.ra[yy[x]].value+360.0)) , str(gaiacoord.dec[yy[x]].value) , \
                     unit=(u.deg,u.deg) , frame='icrs')
        print('WISE query ',x,' of ',np.array(yy).size, end='\r')
        if verbose == True: print('WISE query ',x,' of ',np.array(yy).size)
        if verbose == True: print(querycoord)
    
        wisecat = []
        if (DoWISE == True): 
            wisecat = Irsa.query_region(querycoord,catalog='catwise_2020' , radius='0d0m10s')
            if ((np.where(wisecat['w1mpro'] > -10.0)[0]).size > 0):
                ww = np.where( (wisecat['w1mpro'] == min( wisecat['w1mpro'][np.where(wisecat['w1mpro'] > -10.0)]) ))
                WISEmag[yy[x],0] = wisecat['w1mpro'][ww][0]
                WISEerr[yy[x],0] = wisecat['w1sigmpro'][ww][0]
            if ((np.where(wisecat['w2mpro'] > -10.0)[0]).size > 0):
                ww = np.where( (wisecat['w2mpro'] == min( wisecat['w2mpro'][np.where(wisecat['w2mpro'] > -10.0)]) ))
                WISEmag[yy[x],1] = wisecat['w2mpro'][ww][0]
                WISEerr[yy[x],1] = wisecat['w2sigmpro'][ww][0]
 
        if (DoWISE == True): 
            wisecat = Irsa.query_region(querycoord,catalog='allwise_p3as_psd' , radius='0d0m10s')
            if ((np.where(wisecat['w1mpro'] > -10.0)[0]).size > 0):
                ww = np.where( (wisecat['w1mpro'] == min( wisecat['w1mpro'][np.where(wisecat['w1mpro'] > -10.0)]) ))
                if (np.isnan(WISEmag[yy[x],0]) == True) | (wisecat['w1mpro'][ww][0] < 11.0):				# Note, only if CatWISE absent/saturated
                    WISEmag[yy[x],0] = wisecat['w1mpro'][ww][0]
                    WISEerr[yy[x],0] = wisecat['w1sigmpro'][ww][0]
            if ((np.where(wisecat['w2mpro'] > -10.0)[0]).size > 0):
                ww = np.where( (wisecat['w2mpro'] == min( wisecat['w2mpro'][np.where(wisecat['w2mpro'] > -10.0)]) ))
                if (np.isnan(WISEmag[yy[x],1]) == True) | (wisecat['w2mpro'][ww][0] < 11.0):				# Note, only if CatWISE absent/saturated
                    WISEmag[yy[x],1] = wisecat['w2mpro'][ww][0]
                    WISEerr[yy[x],1] = wisecat['w2sigmpro'][ww][0]
            if ((np.where(wisecat['w3mpro'] > -10.0)[0]).size > 0):
                ww = np.where( (wisecat['w3mpro'] == min( wisecat['w3mpro'][np.where(wisecat['w3mpro'] > -10.0)]) ))
                WISEmag[yy[x],2] = wisecat['w3mpro'][ww][0]
                WISEerr[yy[x],2] = wisecat['w3sigmpro'][ww][0]
            if ((np.where(wisecat['w4mpro'] > -10.0)[0]).size > 0):
                ww = np.where( (wisecat['w4mpro'] == min( wisecat['w4mpro'][np.where(wisecat['w4mpro'] > -10.0)]) ))
                WISEmag[yy[x],3] = wisecat['w4mpro'][ww][0]
                WISEerr[yy[x],3] = wisecat['w4sigmpro'][ww][0]
        
        if verbose == True: print(yy[x],WISEmag[yy[x],:],WISEerr[yy[x],:])

    # Create WISE plots

    W13 = WISEmag[:,0]-WISEmag[:,2]
    W13err = ( WISEerr[:,0]**2 + WISEerr[:,2]**2 )**0.5

    zz = np.argwhere( np.isnan(W13err) )
    W13[zz] = np.nan
    W13err[zz] = np.nan

    zz = np.where( (W13err > 0.15) )
    W13[zz] = np.nan
    W13err[zz] = np.nan
    warnings.filterwarnings("default",category=UserWarning)




    zz2 = np.where( (sep3d.value < searchradpc.value) & (Gchi2 < vlim.value))
    yy2 = zz[0][np.argsort(sep3d[zz])]
    zz = np.where( (sep3d.value < searchradpc.value) & (Gchi2 < vlim.value) & (sep.degree > 0.00001) )
    yy = zz[0][np.argsort((-Gchi2)[zz])]

    figname=outdir + targname.replace(" ", "") + "wise.png"
    if verbose == True: print(figname)
    plt.figure(figsize=(12,8))

    if (verbose == True) & ((np.where(np.isfinite(W13+W13err))[0]).size > 0): print('Max y value: ' , (max((W13+W13err)[np.isfinite(W13+W13err)])+0.1) )
    plt.axis([ 5.0 , 24.0 , \
              max( [(min(np.append((W13-W13err)[ np.isfinite(W13-W13err) ],-0.1))-0.1) , -0.3]) , \
              max( [(max(np.append((W13+W13err)[ np.isfinite(W13+W13err) ],+0.0))+0.2) , +0.6]) ])

    ax1 = plt.gca()
    ax2 = ax1.twiny()
    ax2.set_xlim(5.0,24.0)

    ax1.set_xticks(np.array([5.0 , 10.0 , 15.0 , 17.0 , 22.0 , 24.0]))
    ax1.set_xticklabels(['G5','K0','K5','M0','M5','M7'])
    ax1.set_xlabel('SpT' , fontsize=20, labelpad=15)
    ax1.tick_params(axis='both',which='major',labelsize=16)

    ax2.set_xticks(np.array([5.0 , 10.0 , 15.0 , 17.0 , 22.0 , 24.0]))
    ax2.set_xticklabels(['0.85','0.98','1.45','1.84','3.36','4.75'])
    ax2.set_xlabel(r'$B_p-R_p$ (mag)' , fontsize=20, labelpad=15)
    ax2.tick_params(axis='both',which='major',labelsize=16)

    ax1.set_ylabel(r'$W1-W3$ (mag)' , fontsize=22, labelpad=0)

    # Plot field sequence from Tuc-Hor (Kraus et al. 2014)
    fldspt = [ 5 , 7 , 10 , 12 , 15 , 17 , 20 , 22 , 24 ]
    fldW13 = [ 0 , 0 ,  0 , .02, .06, .12, .27, .40, .60]
    plt.plot(fldspt , fldW13  , zorder=0 , label='Photosphere')

    # Plot neighbors
    ax1.errorbar( spt[yy] , W13[yy] , yerr=W13err[yy] , fmt='none' , ecolor='k')


    for x in range(0 , np.array(yy).size):
        msize  = (17-12.0*(sep3d[yy[x]].value/searchradpc.value))**2
        mcolor = Gchi2[yy[x]]
        medge  = 'black'
        mzorder= 3
        if (r['ruwe'][yy[x]] < 1.2):
            mshape='o'
        if (r['ruwe'][yy[x]] >= 1.2):
            mshape='s'
        if (np.isnan(rvcut) == False): 
            if (np.isnan(RV[yy[x]])==False) & (np.abs(RV[yy[x]]-Gvrpmllpmbb[yy[x],0]) > rvcut):
                mshape='+'
                mcolor='black'
                mzorder=2
            if (np.isnan(RV[yy[x]])==False) & (np.abs(RV[yy[x]]-Gvrpmllpmbb[yy[x],0]) <= rvcut):
                medge='blue'
        ccc = ax1.scatter( spt[yy[x]] , W13[yy[x]] , \
                s=msize , c=mcolor , marker=mshape , edgecolors=medge , zorder=mzorder , \
                vmin=0.0 , vmax=vlim.value , cmap='cubehelix' , label='_nolabel' )

    temp1 = ax1.scatter([] , [] , c='white' , edgecolors='black', marker='o' , s=12**2 , label = 'RUWE < 1.2')
    temp2 = ax1.scatter([] , [] , c='white' , edgecolors='black', marker='s' , s=12**2 , label = 'RUWE >= 1.2')
    temp3 = ax1.scatter([] , [] , c='white' , edgecolors='blue' , marker='o' , s=12**2 , label = 'RV Comoving')
    temp4 = ax1.scatter([] , [] , c='black' , marker='+' , s=12**2 , label = 'RV Outlier')


    # Plot science target
    if (spt[yy2[0]] > 5):
        plt.plot(spt[yy2[0]] , W13[yy2[0]] , 'rx' , markersize=18 , mew=3 , markeredgecolor='red' , zorder=3 , label=targname )

    plt.legend(fontsize=16 , loc='upper left')
    cb = plt.colorbar(ccc , ax=ax1)
    cb.set_label(label='Velocity Offset (km/s)',fontsize=14)
    if (DoWISE == True): plt.savefig(figname , bbox_inches='tight', pad_inches=0.2 , dpi=200)
    if showplots == True: plt.show()
    plt.close('all')

    # Cross-reference with ROSAT

    v = Vizier(columns=["**", "+_R"] , catalog='J/A+A/588/A103/cat2rxs' )

    zz = np.where( (sep3d.value < searchradpc.value) & (Gchi2 < vlim.value) )
    yy = zz[0][np.argsort(sep3d[zz])]

    ROSATflux = np.empty([np.array(r['ra']).size])
    ROSATflux[:] = np.nan

    print('Searching on neighbors in ROSAT')
    for x in range(0 , np.array(yy).size):
        querycoord = SkyCoord((str(gaiacoord.ra[yy[x]].value) if (gaiacoord.ra[yy[x]].value > 0) else \
                     str(gaiacoord.ra[yy[x]].value+360.0)) , str(gaiacoord.dec[yy[x]].value) , \
                     unit=(u.deg,u.deg) , frame='icrs')
        print('ROSAT query ',x,' of ',np.array(yy).size, end='\r')
        if verbose == True: print('ROSAT query ',x,' of ',np.array(yy).size)
        if verbose == True: print(querycoord)
        if (DoROSAT == True): 
            rosatcat = v.query_region(querycoord , radius='0d1m0s' )
            if (len(rosatcat) > 0):
                rosatcat = rosatcat['J/A+A/588/A103/cat2rxs']
                if verbose == True: print(rosatcat)
                if ((np.where(rosatcat['CRate'] > -999)[0]).size > 0):
                    ww = np.where( (rosatcat['CRate'] == max(rosatcat['CRate'][np.where(rosatcat['CRate'] > -999)])))
                    ROSATflux[yy[x]] = rosatcat['CRate'][ww][0]
                if verbose == True: print(x,yy[x],ROSATflux[yy[x]])


    # Create output table with results
    print('Creating Output Tables with Results')
    if verbose == True: 
        print('Reminder, there were this many input entries: ',len(Gxyz[:,0]))
        print('The search radius in velocity space is: ',vlim)
        print()

    zz = np.where( (sep3d.value < searchradpc.value) & (Gchi2 < vlim.value) )
    sortlist = np.argsort(sep3d[zz])
    yy = zz[0][sortlist]

    fmt1 = "%11.7f %11.7f %6.3f %6.3f %11.3f %8.4f %8.4f %8.2f %8.2f %8.2f %8.3f %4s %8.6f %6.2f %7.3f %7.3f %35s"
    fmt2 = "%11.7f %11.7f %6.3f %6.3f %11.3f %8.4f %8.4f %8.2f %8.2f %8.2f %8.3f %4s %8.6f %6.2f %7.3f %7.3f %35s"
    filename=outdir + targname.replace(" ", "") + ".txt"
    
    warnings.filterwarnings("ignore",category=UserWarning)
    if verbose == True: 
        print('Also creating SIMBAD query table')
        print(filename)
        print('RA            DEC        Gmag   Bp-Rp  Voff(km/s) Sep(deg)   3D(pc) Vr(pred)  Vr(obs)    Vrerr Plx(mas)  SpT    FnuvJ  W1-W3    RUWE  XCrate RVsrc')
    with open(filename,'w') as file1:
        file1.write('RA            DEC        Gmag   Bp-Rp  Voff(km/s) Sep(deg)   3D(pc) Vr(pred)  Vr(obs)    Vrerr Plx(mas)  SpT    FnuvJ  W1-W3    RUWE  XCrate RVsrc \n')
    for x in range(0 , np.array(zz).size):
            if verbose == True:
                print(fmt1 % (gaiacoord.ra[yy[x]].value,gaiacoord.dec[yy[x]].value, \
                  r['phot_g_mean_mag'][yy[x]], r['bp_rp'][yy[x]] , \
                  Gchi2[yy[x]] , sep[yy[x]].value , sep3d[yy[x]].value , \
                  Gvrpmllpmbb[yy[x],0] , RV[yy[x]] , RVerr[yy[x]] , \
                  r['parallax'][yy[x]], \
                  sptstring[yy[x]] , fnuvj[yy[x]] , W13[yy[x]] , r['ruwe'][yy[x]] , ROSATflux[yy[x]] , RVsrc[yy[x]]) )
            with open(filename,'a') as file1:
                  file1.write(fmt2 % (gaiacoord.ra[yy[x]].value,gaiacoord.dec[yy[x]].value, \
                      r['phot_g_mean_mag'][yy[x]], r['bp_rp'][yy[x]] , \
                      Gchi2[yy[x]],sep[yy[x]].value,sep3d[yy[x]].value , \
                      Gvrpmllpmbb[yy[x],0] , RV[yy[x]] , RVerr[yy[x]] , \
                      r['parallax'][yy[x]], \
                      sptstring[yy[x]] , fnuvj[yy[x]] , W13[yy[x]] , r['ruwe'][yy[x]] , ROSATflux[yy[x]] , RVsrc[yy[x]]) )
                  file1.write("\n")

    filename=outdir + targname.replace(" ", "") + ".csv"
    with open(filename,mode='w') as result_file:
        wr = csv.writer(result_file)
        wr.writerow(['RA','DEC','Gmag','Bp-Rp','Voff(km/s)','Sep(deg)','3D(pc)','Vr(pred)','Vr(obs)','Vrerr','Plx(mas)','SpT','FnuvJ','W1-W3','RUWE','XCrate','RVsrc'])
        for x in range(0 , np.array(zz).size):
            wr.writerow(( "{0:.7f}".format(gaiacoord.ra[yy[x]].value) , "{0:.7f}".format(gaiacoord.dec[yy[x]].value) , \
                      "{0:.3f}".format(r['phot_g_mean_mag'][yy[x]]), "{0:.3f}".format(r['bp_rp'][yy[x]]) , \
                      "{0:.3f}".format(Gchi2[yy[x]]) , "{0:.4f}".format(sep[yy[x]].value) , "{0:.4f}".format(sep3d[yy[x]].value) , \
                      "{0:.2f}".format(Gvrpmllpmbb[yy[x],0]) , "{0:.2f}".format(RV[yy[x]]) , "{0:.2f}".format(RVerr[yy[x]]) , \
                      "{0:.3f}".format(r['parallax'][yy[x]]), \
                      sptstring[yy[x]] , "{0:.6f}".format(fnuvj[yy[x]]) , "{0:.2f}".format(W13[yy[x]]) , \
                      "{0:.3f}".format(r['ruwe'][yy[x]]) , "{0:.3f}".format(ROSATflux[yy[x]]) , RVsrc[yy[x]].strip()) )

    if verbose == True: print('All output can be found in ' + outdir)



    return outdir
Exemplo n.º 10
0
def to_radec(cluster, do_order=False, do_key_params=False, ro=8.0, vo=220.0):
    """Convert to on-sky position, proper motion, and radial velocity of cluster
    
    Parameters
    ----------
    cluster : class
        StarCluster
    do_order : bool
        sort star by radius after coordinate change (default: False)
    do_key_params : bool
        call key_params to calculate key parameters after unit change (default: False)
    ro : float
        galpy radius scaling parameter
    vo : float
        galpy velocity scaling parameter

    Returns
    -------
    None

    History:
    -------
   2018 - Written - Webb (UofT)
    """
    if len(cluster.ra) == len(cluster.x):
        cluster.x = copy(cluster.ra)
        cluster.y = copy(cluster.dec)
        cluster.z = copy(cluster.dist)
        cluster.vx = copy(cluster.pmra)
        cluster.vy = copy(cluster.pmdec)
        cluster.vz = copy(cluster.vlos)

        cluster.units = "radec"
        cluster.origin = "sky"

    else:

        units0, origin0 = cluster.units, cluster.origin

        cluster.to_galaxy()
        cluster.to_kpckms()

        x0, y0, z0 = bovy_coords.galcenrect_to_XYZ(cluster.x,
                                                   cluster.y,
                                                   cluster.z,
                                                   Xsun=8.0,
                                                   Zsun=0.025).T

        cluster.dist = np.sqrt(x0**2.0 + y0**2.0 + z0**2.0)

        vx0, vy0, vz0 = bovy_coords.galcenrect_to_vxvyvz(
            cluster.vx,
            cluster.vy,
            cluster.vz,
            Xsun=8.0,
            Zsun=0.025,
            vsun=[-11.1, 244.0, 7.25],
        ).T

        cluster.vlos = (vx0 * x0 + vy0 * y0 +
                        vz0 * z0) / np.sqrt(x0**2.0 + y0**2.0 + z0**2.0)

        l0, b0, cluster.dist = bovy_coords.XYZ_to_lbd(x0, y0, z0,
                                                      degree=True).T
        cluster.ra, cluster.dec = bovy_coords.lb_to_radec(l0, b0,
                                                          degree=True).T

        vr0, pmll0, pmbb0 = bovy_coords.vxvyvz_to_vrpmllpmbb(vx0,
                                                             vy0,
                                                             vz0,
                                                             l0,
                                                             b0,
                                                             cluster.dist,
                                                             degree=True).T
        cluster.pmra, cluster.pmdec = bovy_coords.pmllpmbb_to_pmrapmdec(
            pmll0, pmbb0, l0, b0, degree=True).T

        x0, y0, z0 = bovy_coords.galcenrect_to_XYZ(cluster.xgc,
                                                   cluster.ygc,
                                                   cluster.zgc,
                                                   Xsun=8.0,
                                                   Zsun=0.025)
        vx0, vy0, vz0 = bovy_coords.galcenrect_to_vxvyvz(
            cluster.vxgc,
            cluster.vygc,
            cluster.vzgc,
            Xsun=8.0,
            Zsun=0.025,
            vsun=[-11.1, 244.0, 7.25],
        )

        cluster.vlos_gc = (vx0 * x0 + vy0 * y0 +
                           vz0 * z0) / np.sqrt(x0**2.0 + y0**2.0 + z0**2.0)

        l0, b0, cluster.dist_gc = bovy_coords.XYZ_to_lbd(x0,
                                                         y0,
                                                         z0,
                                                         degree=True)
        cluster.ra_gc, cluster.dec_gc = bovy_coords.lb_to_radec(l0,
                                                                b0,
                                                                degree=True)

        vr0, pmll0, pmbb0 = bovy_coords.vxvyvz_to_vrpmllpmbb(vx0,
                                                             vy0,
                                                             vz0,
                                                             l0,
                                                             b0,
                                                             cluster.dist_gc,
                                                             degree=True)
        cluster.pmra_gc, cluster.pmdec_gc = bovy_coords.pmllpmbb_to_pmrapmdec(
            pmll0, pmbb0, l0, b0, degree=True)

        cluster.x = copy(cluster.ra)
        cluster.y = copy(cluster.dec)
        cluster.z = copy(cluster.dist)
        cluster.vx = copy(cluster.pmra)
        cluster.vy = copy(cluster.pmdec)
        cluster.vz = copy(cluster.vlos)

        cluster.xgc = copy(cluster.ra_gc)
        cluster.ygc = copy(cluster.dec_gc)
        cluster.zgc = copy(cluster.dist_gc)
        cluster.vxgc = copy(cluster.pmra_gc)
        cluster.vygc = copy(cluster.pmdec_gc)
        cluster.vzgc = copy(cluster.vlos_gc)

        cluster.units = "radec"
        cluster.origin = "sky"

    cluster.rv3d()

    if do_key_params:
        cluster.key_params(do_order=do_order)
Exemplo n.º 11
0
def plot_stream_lb(plotfilename):
    #Read stream
    data= numpy.loadtxt(os.path.join(_STREAMSNAPDIR,'gd1_evol_hitres_01312.dat'),
                        delimiter=',')
    aadata= numpy.loadtxt(os.path.join(_STREAMSNAPAADIR,
                                       'gd1_evol_hitres_aa_01312.dat'),
                          delimiter=',')
    thetar= aadata[:,6]
    thetar= (numpy.pi+(thetar-numpy.median(thetar))) % (2.*numpy.pi)
    sindx= numpy.fabs(thetar-numpy.pi) > (1.5*numpy.median(numpy.fabs(thetar-numpy.median(thetar)))) #stars in the stream
    #Transform to (l,b)
    XYZ= bovy_coords.galcenrect_to_XYZ(data[:,1],data[:,3],data[:,2],Xsun=8.)
    lbd= bovy_coords.XYZ_to_lbd(XYZ[0],XYZ[1],XYZ[2],degree=True)
    vXYZ= bovy_coords.galcenrect_to_vxvyvz(data[:,4],data[:,6],data[:,5],
                                           vsun=[0.,30.24*8.,0.])
    vlbd= bovy_coords.vxvyvz_to_vrpmllpmbb(vXYZ[0],vXYZ[1],vXYZ[2],
                                           lbd[:,0],lbd[:,1],lbd[:,2],
                                           degree=True)
    includeorbit= True
    if includeorbit:
        npts= 201
        pot= potential.LogarithmicHaloPotential(normalize=1.,q=0.9)
        pts= numpy.linspace(0.,4.,npts)
        #Calculate progenitor orbit around this point
        pox= numpy.median(data[:,1])
        poy= numpy.median(data[:,3])
        poz= numpy.median(data[:,2])
        povx= numpy.median(data[:,4])
        povy= numpy.median(data[:,6])
        povz= numpy.median(data[:,5])
        pR,pphi,pZ= bovy_coords.rect_to_cyl(pox,poy,poz)
        pvR,pvT,pvZ= bovy_coords.rect_to_cyl_vec(povx,povy,povz,pR,
                                                 pphi,pZ,cyl=True)
        ppo= Orbit([pR/8.,pvR/220.,pvT/220.,pZ/8.,pvZ/220.,pphi])
        pno= Orbit([pR/8.,-pvR/220.,-pvT/220.,pZ/8.,-pvZ/220.,pphi])
        ppo.integrate(pts,pot)
        pno.integrate(pts,pot)
        pvec= numpy.zeros((6,npts*2-1))
        pvec[0,:npts-1]= pno.x(pts)[::-1][:-1]
        pvec[1,:npts-1]= pno.z(pts)[::-1][:-1]
        pvec[2,:npts-1]= pno.y(pts)[::-1][:-1]
        pvec[0,npts-1:]= ppo.x(pts)
        pvec[1,npts-1:]= ppo.z(pts)
        pvec[2,npts-1:]= ppo.y(pts)
        pvec[3,:npts-1]= -pno.vx(pts)[::-1][:-1]
        pvec[4,:npts-1]= -pno.vz(pts)[::-1][:-1]
        pvec[5,:npts-1]= -pno.vy(pts)[::-1][:-1]
        pvec[3,npts-1:]= ppo.vx(pts)
        pvec[4,npts-1:]= ppo.vz(pts)
        pvec[5,npts-1:]= ppo.vy(pts)
        pvec[:3,:]*= 8.
        pvec[3:,:]*= 220.
        pXYZ= bovy_coords.galcenrect_to_XYZ(pvec[0,:],pvec[2,:],pvec[1,:],
                                            Xsun=8.)
        plbd= bovy_coords.XYZ_to_lbd(pXYZ[0],pXYZ[1],pXYZ[2],degree=True)
        pvXYZ= bovy_coords.galcenrect_to_vxvyvz(pvec[3,:],pvec[5,:],pvec[4,:],
                                                vsun=[0.,30.24*8.,0.])
        pvlbd= bovy_coords.vxvyvz_to_vrpmllpmbb(pvXYZ[0],pvXYZ[1],pvXYZ[2],
                                                plbd[:,0],plbd[:,1],plbd[:,2],
                                                degree=True)
    includetrack= True
    if includetrack:
        #Setup stream model
        lp= potential.LogarithmicHaloPotential(q=0.9,normalize=1.)
        aAI= actionAngleIsochroneApprox(b=0.8,pot=lp)
        obs= numpy.array([1.56148083,0.35081535,-1.15481504,
                          0.88719443,-0.47713334,0.12019596])
        sdf= streamdf(_SIGV/220.,progenitor=Orbit(obs),pot=lp,aA=aAI,
                      leading=True,nTrackChunks=_NTRACKCHUNKS,
                      vsun=[0.,30.24*8.,0.],
                      tdisrupt=4.5/bovy_conversion.time_in_Gyr(220.,8.),
                      multi=_NTRACKCHUNKS)
        sdft= streamdf(_SIGV/220.,progenitor=Orbit(obs),pot=lp,aA=aAI,
                       leading=False,nTrackChunks=_NTRACKCHUNKS,
                       vsun=[0.,30.24*8.,0.],
                       tdisrupt=4.5/bovy_conversion.time_in_Gyr(220.,8.),
                       multi=_NTRACKCHUNKS)
    #Plot
    bovy_plot.bovy_print(fig_width=8.25,fig_height=3.5)
    if 'ld' in plotfilename:
        lbindx= 2
        ylabel=r'$\mathrm{Distance}\,(\mathrm{kpc})$'
        yrange=[0.,30.]
    elif 'lvlos' in plotfilename:
        lbindx= 0
        ylabel=r'$V_\mathrm{los}\,(\mathrm{km\,s}^{-1})$'
        yrange=[-500.,500.]
    elif 'lpmll' in plotfilename:
        lbindx= 1
        ylabel=r'$\mu_{l}\cos b\,(\mathrm{mas\,yr}^{-1})$'
        yrange=[-2.,13.5]
    elif 'lpmbb' in plotfilename:
        lbindx= 2
        ylabel=r'$\mu_{b}\,(\mathrm{mas\,yr}^{-1})$'
        yrange=[-8.,7.]
    else:
        lbindx= 1 
        yrange=[-10.,60.]
        ylabel=r'$\mathrm{Galactic\ latitude}\,(\mathrm{deg})$'
    if 'vlos' in plotfilename or 'pm' in plotfilename:
        #Stream
        bovy_plot.bovy_plot(lbd[sindx,0],vlbd[sindx,lbindx],'k,',
                            xlabel=r'$\mathrm{Galactic\ longitude}\,(\mathrm{deg})$',
                            ylabel=ylabel,
                            xrange=[0.,290.],
                            yrange=yrange)
        #Progenitor
        pindx= copy.copy(True-sindx)
        pindx[0:9900]= False
        bovy_plot.bovy_plot(lbd[pindx,0],vlbd[pindx,lbindx],'k,',overplot=True)
    else:
        bovy_plot.bovy_plot(lbd[sindx,0],lbd[sindx,lbindx],'k,',
                            xlabel=r'$\mathrm{Galactic\ longitude}\,(\mathrm{deg})$',
                            ylabel=ylabel,
                            xrange=[0.,290.],
                            yrange=yrange)
        #Progenitor
        pindx= copy.copy(True-sindx)
        pindx[0:9900]= False
        bovy_plot.bovy_plot(lbd[pindx,0],lbd[pindx,lbindx],'k,',overplot=True)
    if includeorbit:
        if 'vlos' in plotfilename or 'pm' in plotfilename:
            bovy_plot.bovy_plot(plbd[npts,0],pvlbd[npts,lbindx],
                                'o',color='0.5',mec='none',overplot=True,ms=8)
            bovy_plot.bovy_plot(plbd[:,0],pvlbd[:,lbindx],'k--',overplot=True)
        else:
            bovy_plot.bovy_plot(plbd[npts,0],plbd[npts,lbindx],
                                'o',color='0.5',mec='none',overplot=True,ms=8)
            bovy_plot.bovy_plot(plbd[:,0],plbd[:,lbindx],'k--',overplot=True)
    if includetrack:
        d1= 'll'
        if 'vlos' in plotfilename:
            d2= 'vlos'
        elif 'pmll' in plotfilename:
            d2= 'pmll'
        elif 'pmbb' in plotfilename:
            d2= 'pmbb'
        elif 'ld'  in plotfilename:
            d2= 'dist'
        else:
            d2= 'bb'
        sdf.plotTrack(d1=d1,d2=d2,interp=True,color='k',spread=0,
                      overplot=True,lw=1.)
        sdft.plotTrack(d1=d1,d2=d2,interp=True,color='k',spread=0,
                       overplot=True,lw=1.)
        #Insets
        if 'vlos' in plotfilename:
            xmin, xmax= 220., 250.
            ymin, ymax= 230., 390.
            pyplot.plot([xmin,xmin],[ymin,ymax],'k-')
            pyplot.plot([xmax,xmax],[ymin,ymax],'k-')
            pyplot.plot([xmin,xmax],[ymin,ymin],'k-')
            pyplot.plot([xmin,xmax],[ymax,ymax],'k-')
            pyplot.plot([xmin,152.],[ymin,-100.],'k:')
            pyplot.plot([xmin,152.],[ymax,460.],'k:')
            insetAxes= pyplot.axes([0.15,0.42,0.38,0.45])
            pyplot.sca(insetAxes)
            bovy_plot.bovy_plot(lbd[:,0],vlbd[:,lbindx],'k,',
                                overplot=True)
            sdf.plotProgenitor(d1=d1,d2=d2,color='k',ls='--',
                                overplot=True)
            sdf.plotTrack(d1=d1,d2=d2,interp=True,color='k',spread=0,
                           overplot=True,lw=1.)
            #Plot approximate scale
            bovy_plot.bovy_plot([240.,240.],[250.,275.],'k-',lw=2.,
                                overplot=True)
            bovy_plot.bovy_text(241.,255.,r'$25\,\mathrm{km\,s}^{-1}$',
                                size=16.)
            nullfmt   = NullFormatter()         # no labels
            insetAxes.xaxis.set_major_formatter(nullfmt)
            insetAxes.yaxis.set_major_formatter(nullfmt)
            insetAxes.set_xlim(xmin,xmax)
            insetAxes.set_ylim(ymin,ymax)
        elif 'pmll' in plotfilename:
            xmin, xmax= 158.,205.
            ymin, ymax= 10.5, 13.
            pyplot.plot([xmin,xmin],[ymin,ymax],'k-')
            pyplot.plot([xmax,xmax],[ymin,ymax],'k-')
            pyplot.plot([xmin,xmax],[ymin,ymin],'k-')
            pyplot.plot([xmin,xmax],[ymax,ymax],'k-')
            pyplot.plot([xmin,113.],[ymin,6.1],'k:')
            pyplot.plot([xmax,227.],[ymin,6.1],'k:')
            insetAxes= pyplot.axes([0.43,0.12,0.3,0.4])
            pyplot.sca(insetAxes)
            bovy_plot.bovy_plot(lbd[sindx,0],vlbd[sindx,lbindx],'k,',
                                overplot=True)
            bovy_plot.bovy_plot(lbd[pindx,0],vlbd[pindx,lbindx],'k,',
                                overplot=True)
            sdf.plotProgenitor(d1=d1,d2=d2,color='k',ls='--',
                                overplot=True)
            sdf.plotTrack(d1=d1,d2=d2,interp=True,color='k',spread=0,
                           overplot=True,lw=1.)
            #Plot approximate scale
            bovy_plot.bovy_plot([168.5,168.5],[10.75,11.25],'k-',lw=2.,
                                overplot=True)
            bovy_plot.bovy_text(169.8,10.875,r'$0.5\,\mathrm{mas\,yr}^{-1}$',
                                size=16.)
            nullfmt   = NullFormatter()         # no labels
            insetAxes.xaxis.set_major_formatter(nullfmt)
            insetAxes.yaxis.set_major_formatter(nullfmt)
            insetAxes.set_xlim(xmin,xmax)
            insetAxes.set_ylim(ymin,ymax)
        elif 'pmbb' in plotfilename:
            xmin, xmax= 185., 230.
            ymin, ymax= -7.4, -4.7
            pyplot.plot([xmin,xmin],[ymin,ymax],'k-')
            pyplot.plot([xmax,xmax],[ymin,ymax],'k-')
            pyplot.plot([xmin,xmax],[ymin,ymin],'k-')
            pyplot.plot([xmin,xmax],[ymax,ymax],'k-')
            pyplot.plot([xmin,159.],[ymax,1.],'k:')
            pyplot.plot([xmax,287.],[ymax,1.],'k:')
            #2nd inset
            xmin2, xmax2= 80., 125.
            ymin2, ymax2= 4.2, 5.8
            pyplot.plot([xmin2,xmin2],[ymin2,ymax2],'k-')
            pyplot.plot([xmax2,xmax2],[ymin2,ymax2],'k-')
            pyplot.plot([xmin2,xmax2],[ymin2,ymin2],'k-')
            pyplot.plot([xmin2,xmax2],[ymax2,ymax2],'k-')
            pyplot.plot([xmin2,8.],[ymin2,-1.],'k:')
            pyplot.plot([xmax2,155.],[ymin2,-1.],'k:')
            insetAxes= pyplot.axes([0.55,0.57,0.34,0.3])
            pyplot.sca(insetAxes)
            bovy_plot.bovy_plot(lbd[:,0],vlbd[:,lbindx],'k,',
                                overplot=True)
            sdf.plotProgenitor(d1=d1,d2=d2,color='k',ls='--',
                                overplot=True)
            sdf.plotTrack(d1=d1,d2=d2,interp=True,color='k',spread=0,
                           overplot=True,lw=1.)
            #Plot approximate scale
            bovy_plot.bovy_plot([200.,200.],[-5.75,-5.25],'k-',lw=2.,
                                overplot=True)
            bovy_plot.bovy_text(201.25,-5.675,r'$0.5\,\mathrm{mas\,yr}^{-1}$',
                                size=16.)
            nullfmt   = NullFormatter()         # no labels
            insetAxes.xaxis.set_major_formatter(nullfmt)
            insetAxes.yaxis.set_major_formatter(nullfmt)
            insetAxes.set_xlim(xmin,xmax)
            insetAxes.set_ylim(ymin,ymax)
            pyplot.tick_params(\
                axis='both',          # changes apply to the x-axis
                which='both',      # both major and minor ticks are affected
                bottom='off',      # ticks along the bottom edge are off
                top='off',         # ticks along the top edge are off
                left='off',      # ticks along the bottom edge are off
                right='off')         # ticks along the top edge are off
            #Also make second inset
            insetAxes= pyplot.axes([0.14,0.12,0.4,0.35])
            pyplot.sca(insetAxes)
            bovy_plot.bovy_plot(lbd[:,0],vlbd[:,lbindx],'k,',
                                overplot=True)
            sdft.plotProgenitor(d1=d1,d2=d2,color='k',ls='--',
                                overplot=True)
            sdft.plotTrack(d1=d1,d2=d2,interp=True,color='k',spread=0,
                           overplot=True,lw=1.)
            #Plot approximate scale
            bovy_plot.bovy_plot([103.,103.],[4.35,4.85],'k-',lw=2.,
                                overplot=True)
            bovy_plot.bovy_text(104.,4.5,r'$0.5\,\mathrm{mas\,yr}^{-1}$',
                                size=16.)
            nullfmt   = NullFormatter()         # no labels
            insetAxes.xaxis.set_major_formatter(nullfmt)
            insetAxes.yaxis.set_major_formatter(nullfmt)
            insetAxes.set_xlim(xmin2,xmax2)
            insetAxes.set_ylim(ymin2,ymax2)
        elif 'ld' in plotfilename:
            xmin, xmax= 158., 227.
            ymin, ymax= 7.7,9.5
            pyplot.plot([xmin,xmin],[ymin,ymax],'k-')
            pyplot.plot([xmax,xmax],[ymin,ymax],'k-')
            pyplot.plot([xmin,xmax],[ymin,ymin],'k-')
            pyplot.plot([xmin,xmax],[ymax,ymax],'k-')
            pyplot.plot([xmin,70.],[ymax,18.5],'k:')
            pyplot.plot([xmax,248.],[ymax,18.5],'k:')
            #2nd inset
            xmin2, xmax2= 72.,100.
            ymin2, ymax2= 11.5, 16.1
            pyplot.plot([xmin2,xmin2],[ymin2,ymax2],'k-')
            pyplot.plot([xmax2,xmax2],[ymin2,ymax2],'k-')
            pyplot.plot([xmin2,xmax2],[ymin2,ymin2],'k-')
            pyplot.plot([xmin2,xmax2],[ymax2,ymax2],'k-')
            pyplot.plot([xmin2,66.5],[ymax2,15.85],'k:')
            pyplot.plot([xmin2,66.5],[ymin2,0.5],'k:')
            insetAxes= pyplot.axes([0.31,0.6,0.48,0.27])
            pyplot.sca(insetAxes)
            bovy_plot.bovy_plot(lbd[sindx,0],lbd[sindx,lbindx],'k,',
                                overplot=True)
            bovy_plot.bovy_plot(lbd[pindx,0],lbd[pindx,lbindx],'k,',
                                overplot=True)
            sdf.plotProgenitor(d1=d1,d2=d2,color='k',ls='--',
                                overplot=True)
            sdf.plotTrack(d1=d1,d2=d2,interp=True,color='k',spread=0,
                           overplot=True,lw=1.)
            #Plot approximate scale
            bovy_plot.bovy_plot([168.,168.],[8.7,9.2],'k-',lw=2.,
                                overplot=True)
            bovy_plot.bovy_text(169.7,8.8,r'$0.5\,\mathrm{kpc}$',
                                size=16.)
            nullfmt   = NullFormatter()         # no labels
            insetAxes.xaxis.set_major_formatter(nullfmt)
            insetAxes.yaxis.set_major_formatter(nullfmt)
            insetAxes.set_xlim(xmin,xmax)
            insetAxes.set_ylim(ymin,ymax)
            pyplot.tick_params(\
                axis='both',          # changes apply to the x-axis
                which='both',      # both major and minor ticks are affected
                bottom='off',      # ticks along the bottom edge are off
                top='off',         # ticks along the top edge are off
                left='off',      # ticks along the bottom edge are off
                right='off')         # ticks along the top edge are off
            #Also make second inset
            insetAxes= pyplot.axes([0.13,0.12,0.17,0.4])
            pyplot.sca(insetAxes)
            bovy_plot.bovy_plot(lbd[:,0],lbd[:,lbindx],'k,',
                                overplot=True)
            sdft.plotProgenitor(d1=d1,d2=d2,color='k',ls='--',
                                overplot=True)
            sdft.plotTrack(d1=d1,d2=d2,interp=True,color='k',spread=0,
                           overplot=True,lw=1.)
            #Plot approximate scale
            bovy_plot.bovy_plot([74.,74.],[11.95,12.45],'k-',lw=2.,
                                overplot=True)
            bovy_plot.bovy_text(76.,12.01,r'$0.5\,\mathrm{kpc}$',
                                size=16.)
            nullfmt   = NullFormatter()         # no labels
            insetAxes.xaxis.set_major_formatter(nullfmt)
            insetAxes.yaxis.set_major_formatter(nullfmt)
            insetAxes.set_xlim(xmin2,xmax2)
            insetAxes.set_ylim(ymin2,ymax2)
        else:
            xmin, xmax= 90., 165.
            ymin, ymax= 47., 59.
            pyplot.plot([xmin,xmin],[ymin,ymax],'k-')
            pyplot.plot([xmax,xmax],[ymin,ymax],'k-')
            pyplot.plot([xmin,xmax],[ymin,ymin],'k-')
            pyplot.plot([xmin,xmax],[ymax,ymax],'k-')
            pyplot.plot([xmin,70.],[ymin,31.],'k:')
            pyplot.plot([xmax,213.],[ymin,31.],'k:')
            insetAxes= pyplot.axes([0.31,0.12,0.38,0.45])
            pyplot.sca(insetAxes)
            bovy_plot.bovy_plot(lbd[sindx,0],lbd[sindx,lbindx],'k,',
                                overplot=True)
            bovy_plot.bovy_plot(lbd[pindx,0],lbd[pindx,lbindx],'k,',
                                overplot=True)
            sdft.plotProgenitor(d1=d1,d2=d2,color='k',ls='--',
                                overplot=True)
            sdft.plotTrack(d1=d1,d2=d2,interp=True,color='k',spread=0,
                           overplot=True,lw=1.)
            #Plot approximate scale
            bovy_plot.bovy_plot([115.,115.],[48.5,49.5],'k-',lw=2.,
                                overplot=True)
            bovy_plot.bovy_text(117.2,48.5,r'$1^\circ$',
                                size=16.)
            nullfmt   = NullFormatter()         # no labels
            insetAxes.xaxis.set_major_formatter(nullfmt)
            insetAxes.yaxis.set_major_formatter(nullfmt)
            insetAxes.set_xlim(xmin,xmax)
            insetAxes.set_ylim(ymin,ymax)
        pyplot.tick_params(\
            axis='both',          # changes apply to the x-axis
            which='both',      # both major and minor ticks are affected
            bottom='off',      # ticks along the bottom edge are off
            top='off',         # ticks along the top edge are off
            left='off',      # ticks along the bottom edge are off
            right='off')         # ticks along the top edge are off
    bovy_plot.bovy_end_print(plotfilename)