def test_vxvyvz_to_galcencyl(): X,Y,Z= 3.,4.,2. vx,vy,vz= 10.,-20.,30 vgc= bovy_coords.vxvyvz_to_galcencyl(vx,vy,vz,X,Y,Z,vsun=[-5.,10.,5.]) assert numpy.fabs(vgc[0]+17.) < 10.**-10., 'vxvyvz_to_galcenrect conversion did not work as expected' assert numpy.fabs(vgc[1]-6.) < 10.**-10., 'vxvyvz_to_galcenrect conversion did not work as expected' assert numpy.fabs(vgc[2]-35.) < 10.**-10., 'vxvyvz_to_galcenrect conversion did not work as expected' #with galcen=True vgc= bovy_coords.vxvyvz_to_galcencyl(vx,vy,vz,5.,numpy.arctan(4./3.),Z, vsun=[-5.,10.,5.],galcen=True) assert numpy.fabs(vgc[0]+17.) < 10.**-10., 'vxvyvz_to_galcenrect conversion did not work as expected' assert numpy.fabs(vgc[1]-6.) < 10.**-10., 'vxvyvz_to_galcenrect conversion did not work as expected' assert numpy.fabs(vgc[2]-35.) < 10.**-10., 'vxvyvz_to_galcenrect conversion did not work as expected' return None
def UVW_to_galcen(self): """ Converts UVW space vels to galactocentric frame Assumes R0=8 kpc, z0 = 0.025 kpc, vsun=[-11.1,30.24*8.,7.2] km/s Uses R, phi, z in kpc from RC catalog This matches JoBo's RC catalog assumptions # BUGS - galpy maipulates input GLON, GLAT - HACK: puts in back in degrees - EVENTUAL FIX: PR galpy with not mutating attribute # Output vRg, vTg, vZg # km/s """ self.vRvTvZ_g = bcoords.vxvyvz_to_galcencyl(self.spacevels[:, 0], self.spacevels[:, 1], self.spacevels[:, 2], self.get_col('RC_GALR'), self.get_col('RC_GALPHI'), self.get_col('RC_GALZ'), vsun=[-11.1, 30.24*8., 7.2], galcen=True)
def obs_to_galcen(ra, dec, dist, pmra, pmdec, rv, ro=_R0, vo=_v0, zo=_z0): vxvv = np.dstack([ra, dec, dist, pmra, pmdec, rv])[0] ra, dec = vxvv[:, 0], vxvv[:, 1] lb = bovy_coords.radec_to_lb(ra, dec, degree=True) pmra, pmdec = vxvv[:, 3], vxvv[:, 4] pmllpmbb = bovy_coords.pmrapmdec_to_pmllpmbb(pmra, pmdec, ra, dec, degree=True) d, vlos = vxvv[:, 2], vxvv[:, 5] rectgal = bovy_coords.sphergal_to_rectgal(lb[:, 0], lb[:, 1], d, vlos, pmllpmbb[:, 0], pmllpmbb[:, 1], degree=True) vsolar = np.array([-11.1, 245.7, 7.25]) vsun = vsolar / vo X = rectgal[:, 0] / ro Y = rectgal[:, 1] / ro Z = rectgal[:, 2] / ro vx = rectgal[:, 3] / vo vy = rectgal[:, 4] / vo vz = rectgal[:, 5] / vo XYZ = np.dstack([X, Y, Z])[0] vxyz = np.dstack([vx, vy, vz])[0] Rpz = bovy_coords.XYZ_to_galcencyl(XYZ[:, 0], XYZ[:, 1], XYZ[:, 2], Zsun=zo / ro) vRvTvz = bovy_coords.vxvyvz_to_galcencyl(vxyz[:, 0], vxyz[:, 1], vxyz[:, 2], Rpz[:, 0], Rpz[:, 1], Rpz[:, 2], vsun=vsun, Xsun=1., Zsun=zo / ro, galcen=True) return XYZ, vxyz, Rpz, vRvTvz
def test_coords(): from galpy.util import bovy_coords ra, dec, dist = 161., 50., 8.5 pmra, pmdec, vlos = -6.8, -10., -115. # Convert to Galactic and then to rect. Galactic ll, bb = bovy_coords.radec_to_lb(ra, dec, degree=True) pmll, pmbb = bovy_coords.pmrapmdec_to_pmllpmbb(pmra, pmdec, ra, dec, degree=True) X, Y, Z = bovy_coords.lbd_to_XYZ(ll, bb, dist, degree=True) vX, vY, vZ = bovy_coords.vrpmllpmbb_to_vxvyvz(vlos, pmll, pmbb, X, Y, Z, XYZ=True) # Convert to cylindrical Galactocentric # Assuming Sun's distance to GC is (8,0.025) in (R,z) R, phi, z = bovy_coords.XYZ_to_galcencyl(X, Y, Z, Xsun=8., Zsun=0.025) vR, vT, vz = bovy_coords.vxvyvz_to_galcencyl(vX, vY, vZ, R, phi, Z, vsun=[-10.1, 244., 6.7], galcen=True) # 5/12/2016: test weakened, because improved galcen<->heliocen # transformation has changed these, but still close print(R, phi, z, vR, vT, vz) assert numpy.fabs(R - 12.51328515156942 ) < 10.**-1., 'Coordinate transformation has changed' assert numpy.fabs(phi - 0.12177409073433249 ) < 10.**-1., 'Coordinate transformation has changed' assert numpy.fabs(z - 7.1241282354856228 ) < 10.**-1., 'Coordinate transformation has changed' assert numpy.fabs(vR - 78.961682923035966 ) < 10.**-1., 'Coordinate transformation has changed' assert numpy.fabs(vT + 241.49247772351964 ) < 10.**-1., 'Coordinate transformation has changed' assert numpy.fabs(vz + 102.83965442188689 ) < 10.**-1., 'Coordinate transformation has changed' return None
def test_coords(): from galpy.util import bovy_coords ra, dec, dist= 161., 50., 8.5 pmra, pmdec, vlos= -6.8, -10., -115. # Convert to Galactic and then to rect. Galactic ll, bb= bovy_coords.radec_to_lb(ra,dec,degree=True) pmll, pmbb= bovy_coords.pmrapmdec_to_pmllpmbb(pmra,pmdec,ra,dec,degree=True) X,Y,Z= bovy_coords.lbd_to_XYZ(ll,bb,dist,degree=True) vX,vY,vZ= bovy_coords.vrpmllpmbb_to_vxvyvz(vlos,pmll,pmbb,X,Y,Z,XYZ=True) # Convert to cylindrical Galactocentric # Assuming Sun's distance to GC is (8,0.025) in (R,z) R,phi,z= bovy_coords.XYZ_to_galcencyl(X,Y,Z,Xsun=8.,Zsun=0.025) vR,vT,vz= bovy_coords.vxvyvz_to_galcencyl(vX,vY,vZ,R,phi,Z,vsun=[-10.1,244.,6.7],galcen=True) assert numpy.fabs(R-12.51328515156942) < 10.**-4., 'Coordinate transformation has changed' assert numpy.fabs(phi-0.12177409073433249) < 10.**-4., 'Coordinate transformation has changed' assert numpy.fabs(z-7.1241282354856228) < 10.**-4., 'Coordinate transformation has changed' assert numpy.fabs(vR-78.961682923035966) < 10.**-4., 'Coordinate transformation has changed' assert numpy.fabs(vT+241.49247772351964) < 10.**-4., 'Coordinate transformation has changed' assert numpy.fabs(vz+102.83965442188689) < 10.**-4., 'Coordinate transformation has changed' return None
def _add_proper_motions_gaia(data): from gaia_tools import xmatch gaia2_matches, matches_indx = xmatch.cds(data, colRA='RA', colDec='DEC', xcat='vizier:I/345/gaia2') # Add matches try: #These already exist currently, but may not always exist data = esutil.numpy_util.remove_fields(data, ['PMRA', 'PMDEC']) except ValueError: pass data = esutil.numpy_util.add_fields(data, [('PLX', numpy.float), ('PMRA', numpy.float), ('PMDEC', numpy.float), ('PLX_ERR', numpy.float), ('PMRA_ERR', numpy.float), ('PMDEC_ERR', numpy.float), ('PMMATCH', numpy.int32)]) data['PMMATCH'] = 0 data['PMMATCH'][matches_indx] = 1 data['PLX'][matches_indx] = gaia2_matches['parallax'] data['PMRA'][matches_indx] = gaia2_matches['pmra'] data['PMDEC'][matches_indx] = gaia2_matches['pmdec'] data['PLX_ERR'][matches_indx] = gaia2_matches['parallax_error'] data['PMRA_ERR'][matches_indx] = gaia2_matches['pmra_error'] data['PMDEC_ERR'][matches_indx] = gaia2_matches['pmdec_error'] # Set values for those without match to -999 pmindx = data['PMMATCH'] == 1 data['PLX'][True ^ pmindx] = -9999.99 data['PMRA'][True ^ pmindx] = -9999.99 data['PMDEC'][True ^ pmindx] = -9999.99 data['PLX_ERR'][True ^ pmindx] = -9999.99 data['PMRA_ERR'][True ^ pmindx] = -9999.99 data['PMDEC_ERR'][True ^ pmindx] = -9999.99 #Calculate Galactocentric velocities data = esutil.numpy_util.add_fields(data, [('GALVR', numpy.float), ('GALVT', numpy.float), ('GALVZ', numpy.float)]) lb = bovy_coords.radec_to_lb(data['RA'], data['DEC'], degree=True) XYZ = bovy_coords.lbd_to_XYZ(lb[:, 0], lb[:, 1], data['RC_DIST'], degree=True) pmllpmbb = bovy_coords.pmrapmdec_to_pmllpmbb(data['PMRA'], data['PMDEC'], data['RA'], data['DEC'], degree=True) vxvyvz = bovy_coords.vrpmllpmbb_to_vxvyvz(data['VHELIO_AVG'], pmllpmbb[:, 0], pmllpmbb[:, 1], lb[:, 0], lb[:, 1], data['RC_DIST'], degree=True) vRvTvZ = bovy_coords.vxvyvz_to_galcencyl( vxvyvz[:, 0], vxvyvz[:, 1], vxvyvz[:, 2], 8. - XYZ[:, 0], XYZ[:, 1], XYZ[:, 2] + 0.0208, vsun=[-11.1, 30.24 * 8.15, 7.25] ) #Assumes proper motion of Sgr A* and R0=8.15 kpc, zo= 20.8 pc (Bennett & Bovy 2019) data['GALVR'] = vRvTvZ[:, 0] data['GALVT'] = vRvTvZ[:, 1] data['GALVZ'] = vRvTvZ[:, 2] data['GALVR'][True ^ pmindx] = -9999.99 data['GALVT'][True ^ pmindx] = -9999.99 data['GALVZ'][True ^ pmindx] = -9999.99 return data
def __init__(self,vxvv=None,uvw=False,lb=False, radec=False,vo=235.,ro=8.5,zo=0.025, solarmotion='hogg'): """ NAME: __init__ PURPOSE: Initialize an Orbit instance INPUT: vxvv - initial conditions 3D can be either 1) in Galactocentric cylindrical coordinates [R,vR,vT(,z,vz,phi)] 2) [ra,dec,d,mu_ra, mu_dec,vlos] in [deg,deg,kpc,mas/yr,mas/yr,km/s] (all J2000.0; mu_ra = mu_ra * cos dec) 3) [ra,dec,d,U,V,W] in [deg,deg,kpc,km/s,km/s,kms] 4) (l,b,d,mu_l, mu_b, vlos) in [deg,deg,kpc,mas/yr,mas/yr,km/s) (all J2000.0; mu_l = mu_l * cos b) 5) [l,b,d,U,V,W] in [deg,deg,kpc,km/s,km/s,kms] 4) and 5) also work when leaving out b and mu_b/W OPTIONAL INPUTS: radec - if True, input is 2) (or 3) above uvw - if True, velocities are UVW lb - if True, input is 4) or 5) above vo - circular velocity at ro ro - distance from vantage point to GC (kpc) zo - offset toward the NGP of the Sun wrt the plane (kpc) solarmotion - 'hogg' or 'dehnen', or 'schoenrich', or value in [-U,V,W] OUTPUT: instance HISTORY: 2010-07-20 - Written - Bovy (NYU) """ if isinstance(solarmotion,str) and solarmotion.lower() == 'hogg': vsolar= nu.array([-10.1,4.0,6.7])/vo elif isinstance(solarmotion,str) and solarmotion.lower() == 'dehnen': vsolar= nu.array([-10.,5.25,7.17])/vo elif isinstance(solarmotion,str) \ and solarmotion.lower() == 'schoenrich': vsolar= nu.array([-11.1,12.24,7.25])/vo else: vsolar= nu.array(solarmotion)/vo if radec or lb: if radec: l,b= coords.radec_to_lb(vxvv[0],vxvv[1],degree=True) elif len(vxvv) == 4: l, b= vxvv[0], 0. else: l,b= vxvv[0],vxvv[1] if uvw: X,Y,Z= coords.lbd_to_XYZ(l,b,vxvv[2],degree=True) vx= vxvv[3] vy= vxvv[4] vz= vxvv[5] else: if radec: pmll, pmbb= coords.pmrapmdec_to_pmllpmbb(vxvv[3],vxvv[4], vxvv[0],vxvv[1], degree=True) d, vlos= vxvv[2], vxvv[5] elif len(vxvv) == 4: pmll, pmbb= vxvv[2], 0. d, vlos= vxvv[1], vxvv[3] else: pmll, pmbb= vxvv[3], vxvv[4] d, vlos= vxvv[2], vxvv[5] X,Y,Z,vx,vy,vz= coords.sphergal_to_rectgal(l,b,d, vlos,pmll, pmbb, degree=True) X/= ro Y/= ro Z/= ro vx/= vo vy/= vo vz/= vo vsun= nu.array([0.,1.,0.,])+vsolar R, phi, z= coords.XYZ_to_galcencyl(X,Y,Z,Zsun=zo/ro) vR, vT,vz= coords.vxvyvz_to_galcencyl(vx,vy,vz, R,phi,z, vsun=vsun,galcen=True) if lb and len(vxvv) == 4: vxvv= [R,vR,vT,phi] else: vxvv= [R,vR,vT,z,vz,phi] self.vxvv= vxvv if len(vxvv) == 2: self._orb= linearOrbit(vxvv=vxvv) elif len(vxvv) == 3: self._orb= planarROrbit(vxvv=vxvv) elif len(vxvv) == 4: self._orb= planarOrbit(vxvv=vxvv) elif len(vxvv) == 5: self._orb= RZOrbit(vxvv=vxvv) elif len(vxvv) == 6: self._orb= FullOrbit(vxvv=vxvv)
def make_rcsample(parser): options,args= parser.parse_args() savefilename= options.savefilename if savefilename is None: #Create savefilename if not given savefilename= os.path.join(appath._APOGEE_DATA, 'rcsample_'+appath._APOGEE_REDUX+'.fits') print "Saving to %s ..." % savefilename #Read the base-sample data= apread.allStar(adddist=_ADDHAYDENDIST,rmdups=options.rmdups) #Remove a bunch of fields that we do not want to keep data= esutil.numpy_util.remove_fields(data, ['TARGET_ID', 'FILE', 'AK_WISE', 'SFD_EBV', 'SYNTHVHELIO_AVG', 'SYNTHVSCATTER', 'SYNTHVERR', 'SYNTHVERR_MED', 'RV_TEFF', 'RV_LOGG', 'RV_FEH', 'RV_CCFWHM', 'RV_AUTOFWHM', 'SYNTHSCATTER', 'CHI2_THRESHOLD', 'APSTAR_VERSION', 'ASPCAP_VERSION', 'RESULTS_VERSION', 'REDUCTION_ID', 'SRC_H', 'PM_SRC']) if not appath._APOGEE_REDUX.lower() == 'current' \ and int(appath._APOGEE_REDUX[1:]) < 500: data= esutil.numpy_util.remove_fields(data, ['ELEM']) #Select red-clump stars jk= data['J0']-data['K0'] z= isodist.FEH2Z(data['METALS'],zsolar=0.017) if appath._APOGEE_REDUX.lower() == 'current' \ or int(appath._APOGEE_REDUX[1:]) > 600: from apogee.tools import paramIndx if False: #Use my custom logg calibration that's correct for the RC logg= (1.-0.042)*data['FPARAM'][:,paramIndx('logg')]-0.213 lowloggindx= data['FPARAM'][:,paramIndx('logg')] < 1. logg[lowloggindx]= data['FPARAM'][lowloggindx,paramIndx('logg')]-0.255 hiloggindx= data['FPARAM'][:,paramIndx('logg')] > 3.8 logg[hiloggindx]= data['FPARAM'][hiloggindx,paramIndx('logg')]-0.3726 else: #Use my custom logg calibration that's correct on average logg= (1.+0.03)*data['FPARAM'][:,paramIndx('logg')]-0.37 lowloggindx= data['FPARAM'][:,paramIndx('logg')] < 1. logg[lowloggindx]= data['FPARAM'][lowloggindx,paramIndx('logg')]-0.34 hiloggindx= data['FPARAM'][:,paramIndx('logg')] > 3.8 logg[hiloggindx]= data['FPARAM'][hiloggindx,paramIndx('logg')]-0.256 else: logg= data['LOGG'] indx= (jk < 0.8)*(jk >= 0.5)\ *(z <= 0.06)\ *(z <= rcmodel.jkzcut(jk,upper=True))\ *(z >= rcmodel.jkzcut(jk))\ *(logg >= rcmodel.loggteffcut(data['TEFF'],z,upper=False))\ *(logg <= rcmodel.loggteffcut(data['TEFF'],z,upper=True)) data= data[indx] #Add more aggressive flag cut data= esutil.numpy_util.add_fields(data,[('ADDL_LOGG_CUT',numpy.int32)]) data['ADDL_LOGG_CUT']= ((data['TEFF']-4800.)/1000.+2.75) > data['LOGG'] if options.loggcut: data= data[data['ADDL_LOGG_CUT'] == 1] print "Making catalog of %i objects ..." % len(data) #Add distances data= esutil.numpy_util.add_fields(data,[('RC_DIST', float), ('RC_DM', float), ('RC_GALR', float), ('RC_GALPHI', float), ('RC_GALZ', float)]) rcd= rcmodel.rcdist() jk= data['J0']-data['K0'] z= isodist.FEH2Z(data['METALS'],zsolar=0.017) data['RC_DIST']= rcd(jk,z,appmag=data['K0'])*options.distfac data['RC_DM']= 5.*numpy.log10(data['RC_DIST'])+10. XYZ= bovy_coords.lbd_to_XYZ(data['GLON'], data['GLAT'], data['RC_DIST'], degree=True) R,phi,Z= bovy_coords.XYZ_to_galcencyl(XYZ[:,0], XYZ[:,1], XYZ[:,2], Xsun=8.,Zsun=0.025) data['RC_GALR']= R data['RC_GALPHI']= phi data['RC_GALZ']= Z #Save fitsio.write(savefilename,data,clobber=True) if not options.nostat: #Determine statistical sample and add flag apo= apogee.select.apogeeSelect() statIndx= apo.determine_statistical(data) mainIndx= apread.mainIndx(data) data= esutil.numpy_util.add_fields(data,[('STAT',numpy.int32), ('INVSF',float)]) data['STAT']= 0 data['STAT'][statIndx*mainIndx]= 1 for ii in range(len(data)): if (statIndx*mainIndx)[ii]: data['INVSF'][ii]= 1./apo(data['LOCATION_ID'][ii], data['H'][ii]) else: data['INVSF'][ii]= -1. if options.nopm: fitsio.write(savefilename,data,clobber=True) return None #Get proper motions from astroquery.vizier import Vizier import astroquery from astropy import units as u import astropy.coordinates as coord pmfile= savefilename.split('.')[0]+'_pms.fits' if os.path.exists(pmfile): pmdata= fitsio.read(pmfile,1) else: pmdata= numpy.recarray(len(data), formats=['f8','f8','f8','f8','f8','f8','i4'], names=['RA','DEC','PMRA','PMDEC', 'PMRA_ERR','PMDEC_ERR','PMMATCH']) rad= u.Quantity(4./3600.,u.degree) v= Vizier(columns=['RAJ2000','DEJ2000','pmRA','pmDE','e_pmRA','e_pmDE']) for ii in range(len(data)): #if ii > 100: break sys.stdout.write('\r'+"Getting pm data for point %i / %i" % (ii+1,len(data))) sys.stdout.flush() pmdata.RA[ii]= data['RA'][ii] pmdata.DEC[ii]= data['DEC'][ii] co= coord.ICRS(ra=data['RA'][ii], dec=data['DEC'][ii], unit=(u.degree, u.degree)) trying= True while trying: try: tab= v.query_region(co,rad,catalog='I/322') #UCAC-4 catalog except astroquery.exceptions.TimeoutError: pass else: trying= False if len(tab) == 0: pmdata.PMMATCH[ii]= 0 print "Didn't find a match for %i ..." % ii continue else: pmdata.PMMATCH[ii]= len(tab) if len(tab[0]['pmRA']) > 1: print "Found more than 1 match for %i ..." % ii try: pmdata.PMRA[ii]= float(tab[0]['pmRA']) except TypeError: jj= 1 while len(tab[0]['pmRA']) > 1 and jj < 4: trad= u.Quantity((4.-jj)/3600.,u.degree) trying= True while trying: try: tab= v.query_region(co,trad,catalog='I/322') #UCAC-4 catalog except astroquery.exceptions.TimeoutError: pass else: trying= False jj+= 1 if len(tab) == 0: pmdata.PMMATCH[ii]= 0 print "Didn't find a unambiguous match for %i ..." % ii continue pmdata.PMRA[ii]= float(tab[0]['pmRA']) pmdata.PMDEC[ii]= float(tab[0]['pmDE']) pmdata.PMRA_ERR[ii]= float(tab[0]['e_pmRA']) pmdata.PMDEC_ERR[ii]= float(tab[0]['e_pmDE']) if numpy.isnan(float(tab[0]['pmRA'])): pmdata.PMMATCH[ii]= 0 sys.stdout.write('\r'+_ERASESTR+'\r') sys.stdout.flush() fitsio.write(pmfile,pmdata,clobber=True) #To make sure we're using the same format below pmdata= fitsio.read(pmfile,1) #Match proper motions try: #These already exist currently, but may not always exist data= esutil.numpy_util.remove_fields(data,['PMRA','PMDEC']) except ValueError: pass data= esutil.numpy_util.add_fields(data,[('PMRA', numpy.float), ('PMDEC', numpy.float), ('PMRA_ERR', numpy.float), ('PMDEC_ERR', numpy.float), ('PMMATCH',numpy.int32)]) data['PMMATCH']= 0 h=esutil.htm.HTM() m1,m2,d12 = h.match(pmdata['RA'],pmdata['DEC'], data['RA'],data['DEC'], 2./3600.,maxmatch=1) data['PMRA'][m2]= pmdata['PMRA'][m1] data['PMDEC'][m2]= pmdata['PMDEC'][m1] data['PMRA_ERR'][m2]= pmdata['PMRA_ERR'][m1] data['PMDEC_ERR'][m2]= pmdata['PMDEC_ERR'][m1] data['PMMATCH'][m2]= pmdata['PMMATCH'][m1].astype(numpy.int32) pmindx= data['PMMATCH'] == 1 data['PMRA'][True-pmindx]= -9999.99 data['PMDEC'][True-pmindx]= -9999.99 data['PMRA_ERR'][True-pmindx]= -9999.99 data['PMDEC_ERR'][True-pmindx]= -9999.99 #Calculate Galactocentric velocities data= esutil.numpy_util.add_fields(data,[('GALVR', numpy.float), ('GALVT', numpy.float), ('GALVZ', numpy.float)]) lb= bovy_coords.radec_to_lb(data['RA'],data['DEC'],degree=True) XYZ= bovy_coords.lbd_to_XYZ(lb[:,0],lb[:,1],data['RC_DIST'],degree=True) pmllpmbb= bovy_coords.pmrapmdec_to_pmllpmbb(data['PMRA'],data['PMDEC'], data['RA'],data['DEC'], degree=True) vxvyvz= bovy_coords.vrpmllpmbb_to_vxvyvz(data['VHELIO_AVG'], pmllpmbb[:,0], pmllpmbb[:,1], lb[:,0],lb[:,1],data['RC_DIST'], degree=True) vR, vT, vZ= bovy_coords.vxvyvz_to_galcencyl(vxvyvz[:,0], vxvyvz[:,1], vxvyvz[:,2], 8.-XYZ[:,0], XYZ[:,1], XYZ[:,2]+0.025, vsun=[-11.1,30.24*8.,7.25])#Assumes proper motion of Sgr A* and R0=8 kpc, zo= 25 pc data['GALVR']= vR data['GALVT']= vT data['GALVZ']= vZ data['GALVR'][True-pmindx]= -9999.99 data['GALVT'][True-pmindx]= -9999.99 data['GALVZ'][True-pmindx]= -9999.99 #Get proper motions pmfile= savefilename.split('.')[0]+'_pms_ppmxl.fits' if os.path.exists(pmfile): pmdata= fitsio.read(pmfile,1) else: pmdata= numpy.recarray(len(data), formats=['f8','f8','f8','f8','f8','f8','i4'], names=['RA','DEC','PMRA','PMDEC', 'PMRA_ERR','PMDEC_ERR','PMMATCH']) rad= u.Quantity(4./3600.,u.degree) v= Vizier(columns=['RAJ2000','DEJ2000','pmRA','pmDE','e_pmRA','e_pmDE']) for ii in range(len(data)): #if ii > 100: break sys.stdout.write('\r'+"Getting pm data for point %i / %i" % (ii+1,len(data))) sys.stdout.flush() pmdata.RA[ii]= data['RA'][ii] pmdata.DEC[ii]= data['DEC'][ii] co= coord.ICRS(ra=data['RA'][ii], dec=data['DEC'][ii], unit=(u.degree, u.degree)) trying= True while trying: try: tab= v.query_region(co,rad,catalog='I/317') #PPMXL catalog except astroquery.exceptions.TimeoutError: pass else: trying= False if len(tab) == 0: pmdata.PMMATCH[ii]= 0 print "Didn't find a match for %i ..." % ii continue else: pmdata.PMMATCH[ii]= len(tab) if len(tab[0]['pmRA']) > 1: pass #print "Found more than 1 match for %i ..." % ii try: pmdata.PMRA[ii]= float(tab[0]['pmRA']) except TypeError: #Find nearest cosdists= numpy.zeros(len(tab[0]['pmRA'])) for jj in range(len(tab[0]['pmRA'])): cosdists[jj]= cos_sphere_dist(tab[0]['RAJ2000'][jj], tab[0]['DEJ2000'][jj], data['RA'][ii], data['DEC'][ii]) closest= numpy.argmax(cosdists) pmdata.PMRA[ii]= float(tab[0]['pmRA'][closest]) pmdata.PMDEC[ii]= float(tab[0]['pmDE'][closest]) pmdata.PMRA_ERR[ii]= float(tab[0]['e_pmRA'][closest]) pmdata.PMDEC_ERR[ii]= float(tab[0]['e_pmDE'][closest]) if numpy.isnan(float(tab[0]['pmRA'][closest])): pmdata.PMMATCH[ii]= 0 else: pmdata.PMDEC[ii]= float(tab[0]['pmDE']) pmdata.PMRA_ERR[ii]= float(tab[0]['e_pmRA']) pmdata.PMDEC_ERR[ii]= float(tab[0]['e_pmDE']) if numpy.isnan(float(tab[0]['pmRA'])): pmdata.PMMATCH[ii]= 0 sys.stdout.write('\r'+_ERASESTR+'\r') sys.stdout.flush() fitsio.write(pmfile,pmdata,clobber=True) #To make sure we're using the same format below pmdata= fitsio.read(pmfile,1) #Match proper motions to ppmxl data= esutil.numpy_util.add_fields(data,[('PMRA_PPMXL', numpy.float), ('PMDEC_PPMXL', numpy.float), ('PMRA_ERR_PPMXL', numpy.float), ('PMDEC_ERR_PPMXL', numpy.float), ('PMMATCH_PPMXL',numpy.int32)]) data['PMMATCH_PPMXL']= 0 h=esutil.htm.HTM() m1,m2,d12 = h.match(pmdata['RA'],pmdata['DEC'], data['RA'],data['DEC'], 2./3600.,maxmatch=1) data['PMRA_PPMXL'][m2]= pmdata['PMRA'][m1] data['PMDEC_PPMXL'][m2]= pmdata['PMDEC'][m1] data['PMRA_ERR_PPMXL'][m2]= pmdata['PMRA_ERR'][m1] data['PMDEC_ERR_PPMXL'][m2]= pmdata['PMDEC_ERR'][m1] data['PMMATCH_PPMXL'][m2]= pmdata['PMMATCH'][m1].astype(numpy.int32) pmindx= data['PMMATCH_PPMXL'] == 1 data['PMRA_PPMXL'][True-pmindx]= -9999.99 data['PMDEC_PPMXL'][True-pmindx]= -9999.99 data['PMRA_ERR_PPMXL'][True-pmindx]= -9999.99 data['PMDEC_ERR_PPMXL'][True-pmindx]= -9999.99 #Calculate Galactocentric velocities data= esutil.numpy_util.add_fields(data,[('GALVR_PPMXL', numpy.float), ('GALVT_PPMXL', numpy.float), ('GALVZ_PPMXL', numpy.float)]) lb= bovy_coords.radec_to_lb(data['RA'],data['DEC'],degree=True) XYZ= bovy_coords.lbd_to_XYZ(lb[:,0],lb[:,1],data['RC_DIST'],degree=True) pmllpmbb= bovy_coords.pmrapmdec_to_pmllpmbb(data['PMRA_PPMXL'], data['PMDEC_PPMXL'], data['RA'],data['DEC'], degree=True) vxvyvz= bovy_coords.vrpmllpmbb_to_vxvyvz(data['VHELIO_AVG'], pmllpmbb[:,0], pmllpmbb[:,1], lb[:,0],lb[:,1],data['RC_DIST'], degree=True) vR, vT, vZ= bovy_coords.vxvyvz_to_galcencyl(vxvyvz[:,0], vxvyvz[:,1], vxvyvz[:,2], 8.-XYZ[:,0], XYZ[:,1], XYZ[:,2]+0.025, vsun=[-11.1,30.24*8.,7.25])#Assumes proper motion of Sgr A* and R0=8 kpc, zo= 25 pc data['GALVR_PPMXL']= vR data['GALVT_PPMXL']= vT data['GALVZ_PPMXL']= vZ data['GALVR_PPMXL'][True-pmindx]= -9999.99 data['GALVT_PPMXL'][True-pmindx]= -9999.99 data['GALVZ_PPMXL'][True-pmindx]= -9999.99 #Save fitsio.write(savefilename,data,clobber=True) return None
def __init__(self, vxvv=None, uvw=False, lb=False, radec=False, vo=235., ro=8.5, zo=0.025, solarmotion='hogg'): """ NAME: __init__ PURPOSE: Initialize an Orbit instance INPUT: vxvv - initial conditions 3D can be either 1) in Galactocentric cylindrical coordinates [R,vR,vT(,z,vz,phi)] 2) [ra,dec,d,mu_ra, mu_dec,vlos] in [deg,deg,kpc,mas/yr,mas/yr,km/s] (all J2000.0; mu_ra = mu_ra * cos dec) 3) [ra,dec,d,U,V,W] in [deg,deg,kpc,km/s,km/s,kms] 4) (l,b,d,mu_l, mu_b, vlos) in [deg,deg,kpc,mas/yr,mas/yr,km/s) (all J2000.0; mu_l = mu_l * cos b) 5) [l,b,d,U,V,W] in [deg,deg,kpc,km/s,km/s,kms] 4) and 5) also work when leaving out b and mu_b/W OPTIONAL INPUTS: radec - if True, input is 2) (or 3) above uvw - if True, velocities are UVW lb - if True, input is 4) or 5) above vo - circular velocity at ro ro - distance from vantage point to GC (kpc) zo - offset toward the NGP of the Sun wrt the plane (kpc) solarmotion - 'hogg' or 'dehnen', or 'schoenrich', or value in [-U,V,W] OUTPUT: instance HISTORY: 2010-07-20 - Written - Bovy (NYU) """ if isinstance(solarmotion, str) and solarmotion.lower() == 'hogg': vsolar = nu.array([-10.1, 4.0, 6.7]) / vo elif isinstance(solarmotion, str) and solarmotion.lower() == 'dehnen': vsolar = nu.array([-10., 5.25, 7.17]) / vo elif isinstance(solarmotion,str) \ and solarmotion.lower() == 'schoenrich': vsolar = nu.array([-11.1, 12.24, 7.25]) / vo else: vsolar = nu.array(solarmotion) / vo if radec or lb: if radec: l, b = coords.radec_to_lb(vxvv[0], vxvv[1], degree=True) elif len(vxvv) == 4: l, b = vxvv[0], 0. else: l, b = vxvv[0], vxvv[1] if uvw: X, Y, Z = coords.lbd_to_XYZ(l, b, vxvv[2], degree=True) vx = vxvv[3] vy = vxvv[4] vz = vxvv[5] else: if radec: pmll, pmbb = coords.pmrapmdec_to_pmllpmbb(vxvv[3], vxvv[4], vxvv[0], vxvv[1], degree=True) d, vlos = vxvv[2], vxvv[5] elif len(vxvv) == 4: pmll, pmbb = vxvv[2], 0. d, vlos = vxvv[1], vxvv[3] else: pmll, pmbb = vxvv[3], vxvv[4] d, vlos = vxvv[2], vxvv[5] X, Y, Z, vx, vy, vz = coords.sphergal_to_rectgal(l, b, d, vlos, pmll, pmbb, degree=True) X /= ro Y /= ro Z /= ro vx /= vo vy /= vo vz /= vo vsun = nu.array([ 0., 1., 0., ]) + vsolar R, phi, z = coords.XYZ_to_galcencyl(X, Y, Z, Zsun=zo / ro) vR, vT, vz = coords.vxvyvz_to_galcencyl(vx, vy, vz, R, phi, z, vsun=vsun, galcen=True) if lb and len(vxvv) == 4: vxvv = [R, vR, vT, phi] else: vxvv = [R, vR, vT, z, vz, phi] self.vxvv = vxvv if len(vxvv) == 2: self._orb = linearOrbit(vxvv=vxvv) elif len(vxvv) == 3: self._orb = planarROrbit(vxvv=vxvv) elif len(vxvv) == 4: self._orb = planarOrbit(vxvv=vxvv) elif len(vxvv) == 5: self._orb = RZOrbit(vxvv=vxvv) elif len(vxvv) == 6: self._orb = FullOrbit(vxvv=vxvv)
def action(ra_deg, dec_deg, d_kpc, pm_ra_masyr, pm_dec_masyr, v_los_kms, verbose=False): """ parameters: ---------- ra_deg: (float) RA in degrees. dec_deg: (float) Dec in degress. d_kpc: (float) Distance in kpc. pm_ra_masyr: (float) RA proper motion in mas/yr. pm_decmasyr: (float) Dec proper motion in mas/yr. v_los_kms: (float) RV in kms. returns: ------ R_kpc, phi_rad, z_kpc, vR_kms, vT_kms, vz_kms jR: (float) Radial action. lz: (float) Vertical ang mom. jz: (float) Vertical action. """ ra_rad = ra_deg * (np.pi / 180.) # RA [rad] dec_rad = dec_deg * (np.pi / 180.) # dec [rad] # Galactocentric position of the Sun: X_gc_sun_kpc = 8. # [kpc] Z_gc_sun_kpc = 0.025 # [kpc] # Galactocentric velocity of the Sun: vX_gc_sun_kms = -9.58 # = -U [kms] vY_gc_sun_kms = 10.52 + 220. # = V+v_circ(R_Sun) [kms] vZ_gc_sun_kms = 7.01 # = W [kms] # a. convert spatial coordinates (ra,dec,d) to (R,z,phi) # (ra,dec) --> Galactic coordinates (l,b): lb = bovy_coords.radec_to_lb(ra_rad, dec_rad, degree=False, epoch=2000.0) # l_rad = lb[:, 0] # b_rad = lb[:, 1] l_rad = lb[0] b_rad = lb[1] # (l,b,d) --> Galactocentric cartesian coordinates (x,y,z): xyz = bovy_coords.lbd_to_XYZ(l_rad, b_rad, d_kpc, degree=False) # x_kpc = xyz[:, 0] # y_kpc = xyz[:, 1] # z_kpc = xyz[:, 2] x_kpc = xyz[0] y_kpc = xyz[1] z_kpc = xyz[2] # (x,y,z) --> Galactocentric cylindrical coordinates (R,z,phi): Rzphi = bovy_coords.XYZ_to_galcencyl(x_kpc, y_kpc, z_kpc, Xsun=X_gc_sun_kpc, Zsun=Z_gc_sun_kpc) # R_kpc = Rzphi[:, 0] # phi_rad = Rzphi[:, 1] # z_kpc = Rzphi[:, 2] R_kpc = Rzphi[0] phi_rad = Rzphi[1] z_kpc = Rzphi[2] # b. convert velocities (pm_ra,pm_dec,vlos) to (vR,vz,vT) # (pm_ra,pm_dec) --> (pm_l,pm_b): pmlpmb = bovy_coords.pmrapmdec_to_pmllpmbb(pm_ra_masyr, pm_dec_masyr, ra_rad, dec_rad, degree=False, epoch=2000.0) # pml_masyr = pmlpmb[:, 0] # pmb_masyr = pmlpmb[:, 1] pml_masyr = pmlpmb[0] pmb_masyr = pmlpmb[1] # (v_los,pm_l,pm_b) & (l,b,d) --> (vx,vy,vz): vxvyvz = bovy_coords.vrpmllpmbb_to_vxvyvz(v_los_kms, pml_masyr, pmb_masyr, l_rad, b_rad, d_kpc, XYZ=False, degree=False) # vx_kms = vxvyvz[:, 0] # vy_kms = vxvyvz[:, 1] # vz_kms = vxvyvz[:, 2] vx_kms = vxvyvz[0] vy_kms = vxvyvz[1] vz_kms = vxvyvz[2] # (vx,vy,vz) & (x,y,z) --> (vR,vT,vz): vRvTvZ = bovy_coords.vxvyvz_to_galcencyl(vx_kms, vy_kms, vz_kms, R_kpc, phi_rad, z_kpc, vsun=[vX_gc_sun_kms, vY_gc_sun_kms, vZ_gc_sun_kms], galcen=True) # vR_kms = vRvTvZ[:, 0] # vT_kms = vRvTvZ[:, 1] # vz_kms = vRvTvZ[:, 2] vR_kms = vRvTvZ[0] vT_kms = vRvTvZ[1] vz_kms = vRvTvZ[2] if verbose: print("R = ", R_kpc, "\t kpc") print("phi = ", phi_rad, "\t rad") print("z = ", z_kpc, "\t kpc") print("v_R = ", vR_kms, "\t km/s") print("v_T = ", vT_kms, "\t km/s") print("v_z = ", vz_kms, "\t km/s") jR, lz, jz = calc_actions(R_kpc, phi_rad, z_kpc, vR_kms, vT_kms, vz_kms) return R_kpc, phi_rad, z_kpc, vR_kms, vT_kms, vz_kms, jR, lz, jz
def calc_eccentricity(args, options): table = os.path.join(args[0],'table2.dat') readme = os.path.join(args[0],'ReadMe') dierickx = ascii.read(table, readme=readme) vxvv = np.dstack([dierickx['RAdeg'], dierickx['DEdeg'], dierickx['Dist']/1e3, dierickx['pmRA'], dierickx['pmDE'], dierickx['HRV']])[0] ro, vo, zo = 8., 220., 0.025 ra, dec= vxvv[:,0], vxvv[:,1] lb= bovy_coords.radec_to_lb(ra,dec,degree=True) pmra, pmdec= vxvv[:,3], vxvv[:,4] pmllpmbb= bovy_coords.pmrapmdec_to_pmllpmbb(pmra,pmdec,ra,dec,degree=True) d, vlos= vxvv[:,2], vxvv[:,5] rectgal= bovy_coords.sphergal_to_rectgal(lb[:,0],lb[:,1],d,vlos,pmllpmbb[:,0], pmllpmbb[:,1],degree=True) vsolar= np.array([-10.1,4.0,6.7]) vsun= np.array([0.,1.,0.,])+vsolar/vo X = rectgal[:,0]/ro Y = rectgal[:,1]/ro Z = rectgal[:,2]/ro vx = rectgal[:,3]/vo vy = rectgal[:,4]/vo vz = rectgal[:,5]/vo vsun= np.array([0.,1.,0.,])+vsolar/vo Rphiz= bovy_coords.XYZ_to_galcencyl(X,Y,Z,Zsun=zo/ro) vRvTvz= bovy_coords.vxvyvz_to_galcencyl(vx,vy,vz,Rphiz[:,0],Rphiz[:,1],Rphiz[:,2],vsun=vsun,Xsun=1.,Zsun=zo/ro,galcen=True) #do the integration and individual analytic estimate for each object ts= np.linspace(0.,20.,10000) lp= LogarithmicHaloPotential(normalize=1.) e_ana = numpy.zeros(len(vxvv)) e_int = numpy.zeros(len(vxvv)) print('Performing orbit integration and analytic parameter estimates for Dierickx et al. sample...') for i in tqdm(range(len(vxvv))): try: orbit = Orbit(vxvv[i], radec=True, vo=220., ro=8.) e_ana[i] = orbit.e(analytic=True, pot=lp, c=True) except UnboundError: e_ana[i] = np.nan orbit.integrate(ts, lp) e_int[i] = orbit.e(analytic=False) fig = plt.figure() fig.set_size_inches(1.5*columnwidth, 1.5*columnwidth) plt.scatter(e_int, e_ana, s=1, color='Black', lw=0.) plt.xlabel(r'$\mathrm{galpy\ integrated}\ e$') plt.ylabel(r'$\mathrm{galpy\ analytic}\ e$') plt.xlim(0.,1.) plt.ylim(0.,1.) fig.tight_layout() plt.savefig(os.path.join(args[0],'dierickx-integratedeanalytice.png'), format='png', dpi=200) fig = plt.figure() fig.set_size_inches(1.5*columnwidth, 1.5*columnwidth) plt.hist(e_int, bins=30) plt.xlim(0.,1.) plt.xlabel(r'$\mathrm{galpy}\ e$') fig.tight_layout() plt.savefig(os.path.join(args[0], 'dierickx-integratedehist.png'), format='png', dpi=200) fig = plt.figure() fig.set_size_inches(1.5*columnwidth, 1.5*columnwidth) plt.scatter(dierickx['e'], e_int, s=1, color='Black', lw=0.) plt.xlabel(r'$\mathrm{Dierickx\ et\ al.}\ e$') plt.ylabel(r'$\mathrm{galpy\ integrated}\ e$') plt.xlim(0.,1.) plt.ylim(0.,1.) fig.tight_layout() plt.savefig(os.path.join(args[0],'dierickx-integratedee.png'), format='png', dpi=200) fig = plt.figure() fig.set_size_inches(1.5*columnwidth, 1.5*columnwidth) plt.scatter(dierickx['e'], e_ana, s=1, color='Black', lw=0.) plt.xlabel(r'$\mathrm{Dierickx\ et\ al.}\ e$') plt.ylabel(r'$\mathrm{galpy\ estimated}\ e$') plt.xlim(0.,1.) plt.ylim(0.,1.) fig.tight_layout() plt.savefig(os.path.join(args[0],'dierickx-analyticee.png'), format='png', dpi=200) arr = numpy.recarray(len(e_ana), dtype=[('analytic_e', float), ('integrated_e', float)]) arr['analytic_e'] = e_ana arr['integrated_e'] = e_int with open(os.path.join(args[0],'eccentricities.dat'), 'w') as file: pickle.dump(arr, file) file.close()
def make_rcsample(parser): options, args = parser.parse_args() savefilename = options.savefilename if savefilename is None: #Create savefilename if not given savefilename = os.path.join( appath._APOGEE_DATA, 'rcsample_' + appath._APOGEE_REDUX + '.fits') print("Saving to %s ..." % savefilename) #Read the base-sample data = apread.allStar(adddist=_ADDHAYDENDIST, rmdups=options.rmdups) #Remove a bunch of fields that we do not want to keep data = esutil.numpy_util.remove_fields(data, [ 'TARGET_ID', 'FILE', 'AK_WISE', 'SFD_EBV', 'SYNTHVHELIO_AVG', 'SYNTHVSCATTER', 'SYNTHVERR', 'SYNTHVERR_MED', 'RV_TEFF', 'RV_LOGG', 'RV_FEH', 'RV_ALPHA', 'RV_CARB', 'RV_CCFWHM', 'RV_AUTOFWHM', 'SYNTHSCATTER', 'STABLERV_CHI2', 'STABLERV_RCHI2', 'STABLERV_CHI2_PROB', 'CHI2_THRESHOLD', 'APSTAR_VERSION', 'ASPCAP_VERSION', 'RESULTS_VERSION', 'WASH_M', 'WASH_M_ERR', 'WASH_T2', 'WASH_T2_ERR', 'DDO51', 'DDO51_ERR', 'IRAC_3_6', 'IRAC_3_6_ERR', 'IRAC_4_5', 'IRAC_4_5_ERR', 'IRAC_5_8', 'IRAC_5_8_ERR', 'IRAC_8_0', 'IRAC_8_0_ERR', 'WISE_4_5', 'WISE_4_5_ERR', 'TARG_4_5', 'TARG_4_5_ERR', 'WASH_DDO51_GIANT_FLAG', 'WASH_DDO51_STAR_FLAG', 'REDUCTION_ID', 'SRC_H', 'PM_SRC' ]) if not appath._APOGEE_REDUX.lower() == 'current' \ and not 'l30' in appath._APOGEE_REDUX \ and int(appath._APOGEE_REDUX[1:]) < 500: data = esutil.numpy_util.remove_fields(data, ['ELEM']) #Select red-clump stars jk = data['J0'] - data['K0'] z = isodist.FEH2Z(data['METALS'], zsolar=0.017) if 'l30' in appath._APOGEE_REDUX: logg = data['LOGG'] elif appath._APOGEE_REDUX.lower() == 'current' \ or int(appath._APOGEE_REDUX[1:]) > 600: from apogee.tools import paramIndx if False: #Use my custom logg calibration that's correct for the RC logg = (1. - 0.042) * data['FPARAM'][:, paramIndx('logg')] - 0.213 lowloggindx = data['FPARAM'][:, paramIndx('logg')] < 1. logg[lowloggindx] = data['FPARAM'][lowloggindx, paramIndx('logg')] - 0.255 hiloggindx = data['FPARAM'][:, paramIndx('logg')] > 3.8 logg[hiloggindx] = data['FPARAM'][hiloggindx, paramIndx('logg')] - 0.3726 else: #Use my custom logg calibration that's correct on average logg = (1. + 0.03) * data['FPARAM'][:, paramIndx('logg')] - 0.37 lowloggindx = data['FPARAM'][:, paramIndx('logg')] < 1. logg[lowloggindx] = data['FPARAM'][lowloggindx, paramIndx('logg')] - 0.34 hiloggindx = data['FPARAM'][:, paramIndx('logg')] > 3.8 logg[hiloggindx] = data['FPARAM'][hiloggindx, paramIndx('logg')] - 0.256 else: logg = data['LOGG'] indx= (jk < 0.8)*(jk >= 0.5)\ *(z <= 0.06)\ *(z <= rcmodel.jkzcut(jk,upper=True))\ *(z >= rcmodel.jkzcut(jk))\ *(logg >= rcmodel.loggteffcut(data['TEFF'],z,upper=False))\ *(logg <= rcmodel.loggteffcut(data['TEFF'],z,upper=True)) data = data[indx] #Add more aggressive flag cut data = esutil.numpy_util.add_fields(data, [('ADDL_LOGG_CUT', numpy.int32)]) data['ADDL_LOGG_CUT'] = ( (data['TEFF'] - 4800.) / 1000. + 2.75) > data['LOGG'] if options.loggcut: data = data[data['ADDL_LOGG_CUT'] == 1] print("Making catalog of %i objects ..." % len(data)) #Add distances data = esutil.numpy_util.add_fields(data, [('RC_DIST', float), ('RC_DM', float), ('RC_GALR', float), ('RC_GALPHI', float), ('RC_GALZ', float)]) rcd = rcmodel.rcdist() jk = data['J0'] - data['K0'] z = isodist.FEH2Z(data['METALS'], zsolar=0.017) data['RC_DIST'] = rcd(jk, z, appmag=data['K0']) * options.distfac data['RC_DM'] = 5. * numpy.log10(data['RC_DIST']) + 10. XYZ = bovy_coords.lbd_to_XYZ(data['GLON'], data['GLAT'], data['RC_DIST'], degree=True) R, phi, Z = bovy_coords.XYZ_to_galcencyl(XYZ[:, 0], XYZ[:, 1], XYZ[:, 2], Xsun=8., Zsun=0.025) data['RC_GALR'] = R data['RC_GALPHI'] = phi data['RC_GALZ'] = Z #Save fitsio.write(savefilename, data, clobber=True) # Add Tycho-2 matches if options.tyc2: data = esutil.numpy_util.add_fields(data, [('TYC2MATCH', numpy.int32), ('TYC1', numpy.int32), ('TYC2', numpy.int32), ('TYC3', numpy.int32)]) data['TYC2MATCH'] = 0 data['TYC1'] = -1 data['TYC2'] = -1 data['TYC3'] = -1 # Write positions posfilename = tempfile.mktemp('.csv', dir=os.getcwd()) resultfilename = tempfile.mktemp('.csv', dir=os.getcwd()) with open(posfilename, 'w') as csvfile: wr = csv.writer(csvfile, delimiter=',', quoting=csv.QUOTE_MINIMAL) wr.writerow(['RA', 'DEC']) for ii in range(len(data)): wr.writerow([data[ii]['RA'], data[ii]['DEC']]) # Send to CDS for matching result = open(resultfilename, 'w') try: subprocess.check_call([ 'curl', '-X', 'POST', '-F', 'request=xmatch', '-F', 'distMaxArcsec=2', '-F', 'RESPONSEFORMAT=csv', '-F', 'cat1=@%s' % os.path.basename(posfilename), '-F', 'colRA1=RA', '-F', 'colDec1=DEC', '-F', 'cat2=vizier:Tycho2', 'http://cdsxmatch.u-strasbg.fr/xmatch/api/v1/sync' ], stdout=result) except subprocess.CalledProcessError: os.remove(posfilename) if os.path.exists(resultfilename): result.close() os.remove(resultfilename) result.close() # Directly match on input RA ma = numpy.loadtxt(resultfilename, delimiter=',', skiprows=1, usecols=(1, 2, 7, 8, 9)) iis = numpy.arange(len(data)) mai = [iis[data['RA'] == ma[ii, 0]][0] for ii in range(len(ma))] data['TYC2MATCH'][mai] = 1 data['TYC1'][mai] = ma[:, 2] data['TYC2'][mai] = ma[:, 3] data['TYC3'][mai] = ma[:, 4] os.remove(posfilename) os.remove(resultfilename) if not options.nostat: #Determine statistical sample and add flag apo = apogee.select.apogeeSelect() statIndx = apo.determine_statistical(data) mainIndx = apread.mainIndx(data) data = esutil.numpy_util.add_fields(data, [('STAT', numpy.int32), ('INVSF', float)]) data['STAT'] = 0 data['STAT'][statIndx * mainIndx] = 1 for ii in range(len(data)): if (statIndx * mainIndx)[ii]: data['INVSF'][ii] = 1. / apo(data['LOCATION_ID'][ii], data['H'][ii]) else: data['INVSF'][ii] = -1. if options.nopm: fitsio.write(savefilename, data, clobber=True) return None #Get proper motions, in a somewhat roundabout way pmfile = savefilename.split('.')[0] + '_pms.fits' if os.path.exists(pmfile): pmdata = fitsio.read(pmfile, 1) else: pmdata = numpy.recarray( len(data), formats=['f8', 'f8', 'f8', 'f8', 'f8', 'f8', 'i4'], names=[ 'RA', 'DEC', 'PMRA', 'PMDEC', 'PMRA_ERR', 'PMDEC_ERR', 'PMMATCH' ]) # Write positions, again ... posfilename = tempfile.mktemp('.csv', dir=os.getcwd()) resultfilename = tempfile.mktemp('.csv', dir=os.getcwd()) with open(posfilename, 'w') as csvfile: wr = csv.writer(csvfile, delimiter=',', quoting=csv.QUOTE_MINIMAL) wr.writerow(['RA', 'DEC']) for ii in range(len(data)): wr.writerow([data[ii]['RA'], data[ii]['DEC']]) # Send to CDS for matching result = open(resultfilename, 'w') try: subprocess.check_call([ 'curl', '-X', 'POST', '-F', 'request=xmatch', '-F', 'distMaxArcsec=4', '-F', 'RESPONSEFORMAT=csv', '-F', 'cat1=@%s' % os.path.basename(posfilename), '-F', 'colRA1=RA', '-F', 'colDec1=DEC', '-F', 'cat2=vizier:UCAC4', 'http://cdsxmatch.u-strasbg.fr/xmatch/api/v1/sync' ], stdout=result) except subprocess.CalledProcessError: os.remove(posfilename) if os.path.exists(resultfilename): result.close() os.remove(resultfilename) result.close() # Match back and only keep the closest one ma = numpy.loadtxt(resultfilename, delimiter=',', skiprows=1, converters={ 15: lambda s: float(s.strip() or -9999), 16: lambda s: float(s.strip() or -9999), 17: lambda s: float(s.strip() or -9999), 18: lambda s: float(s.strip() or -9999) }, usecols=(4, 5, 15, 16, 17, 18)) h = esutil.htm.HTM() m1, m2, d12 = h.match(data['RA'], data['DEC'], ma[:, 0], ma[:, 1], 4. / 3600., maxmatch=1) pmdata['PMMATCH'] = 0 pmdata['RA'] = data['RA'] pmdata['DEC'] = data['DEC'] pmdata['PMMATCH'][m1] = 1 pmdata['PMRA'][m1] = ma[m2, 2] pmdata['PMDEC'][m1] = ma[m2, 3] pmdata['PMRA_ERR'][m1] = ma[m2, 4] pmdata['PMDEC_ERR'][m1] = ma[m2, 5] pmdata['PMMATCH'][(pmdata['PMRA'] == -9999) \ +(pmdata['PMDEC'] == -9999) \ +(pmdata['PMRA_ERR'] == -9999) \ +(pmdata['PMDEC_ERR'] == -9999)]= 0 fitsio.write(pmfile, pmdata, clobber=True) #To make sure we're using the same format below pmdata = fitsio.read(pmfile, 1) os.remove(posfilename) os.remove(resultfilename) #Match proper motions try: #These already exist currently, but may not always exist data = esutil.numpy_util.remove_fields(data, ['PMRA', 'PMDEC']) except ValueError: pass data = esutil.numpy_util.add_fields(data, [('PMRA', numpy.float), ('PMDEC', numpy.float), ('PMRA_ERR', numpy.float), ('PMDEC_ERR', numpy.float), ('PMMATCH', numpy.int32)]) data['PMMATCH'] = 0 h = esutil.htm.HTM() m1, m2, d12 = h.match(pmdata['RA'], pmdata['DEC'], data['RA'], data['DEC'], 2. / 3600., maxmatch=1) data['PMRA'][m2] = pmdata['PMRA'][m1] data['PMDEC'][m2] = pmdata['PMDEC'][m1] data['PMRA_ERR'][m2] = pmdata['PMRA_ERR'][m1] data['PMDEC_ERR'][m2] = pmdata['PMDEC_ERR'][m1] data['PMMATCH'][m2] = pmdata['PMMATCH'][m1].astype(numpy.int32) pmindx = data['PMMATCH'] == 1 data['PMRA'][True - pmindx] = -9999.99 data['PMDEC'][True - pmindx] = -9999.99 data['PMRA_ERR'][True - pmindx] = -9999.99 data['PMDEC_ERR'][True - pmindx] = -9999.99 #Calculate Galactocentric velocities data = esutil.numpy_util.add_fields(data, [('GALVR', numpy.float), ('GALVT', numpy.float), ('GALVZ', numpy.float)]) lb = bovy_coords.radec_to_lb(data['RA'], data['DEC'], degree=True) XYZ = bovy_coords.lbd_to_XYZ(lb[:, 0], lb[:, 1], data['RC_DIST'], degree=True) pmllpmbb = bovy_coords.pmrapmdec_to_pmllpmbb(data['PMRA'], data['PMDEC'], data['RA'], data['DEC'], degree=True) vxvyvz = bovy_coords.vrpmllpmbb_to_vxvyvz(data['VHELIO_AVG'], pmllpmbb[:, 0], pmllpmbb[:, 1], lb[:, 0], lb[:, 1], data['RC_DIST'], degree=True) vR, vT, vZ = bovy_coords.vxvyvz_to_galcencyl( vxvyvz[:, 0], vxvyvz[:, 1], vxvyvz[:, 2], 8. - XYZ[:, 0], XYZ[:, 1], XYZ[:, 2] + 0.025, vsun=[-11.1, 30.24 * 8., 7.25]) #Assumes proper motion of Sgr A* and R0=8 kpc, zo= 25 pc data['GALVR'] = vR data['GALVT'] = vT data['GALVZ'] = vZ data['GALVR'][True - pmindx] = -9999.99 data['GALVT'][True - pmindx] = -9999.99 data['GALVZ'][True - pmindx] = -9999.99 #Get PPMXL proper motions, in a somewhat roundabout way pmfile = savefilename.split('.')[0] + '_pms_ppmxl.fits' if os.path.exists(pmfile): pmdata = fitsio.read(pmfile, 1) else: pmdata = numpy.recarray( len(data), formats=['f8', 'f8', 'f8', 'f8', 'f8', 'f8', 'i4'], names=[ 'RA', 'DEC', 'PMRA', 'PMDEC', 'PMRA_ERR', 'PMDEC_ERR', 'PMMATCH' ]) # Write positions, again ... posfilename = tempfile.mktemp('.csv', dir=os.getcwd()) resultfilename = tempfile.mktemp('.csv', dir=os.getcwd()) with open(posfilename, 'w') as csvfile: wr = csv.writer(csvfile, delimiter=',', quoting=csv.QUOTE_MINIMAL) wr.writerow(['RA', 'DEC']) for ii in range(len(data)): wr.writerow([data[ii]['RA'], data[ii]['DEC']]) # Send to CDS for matching result = open(resultfilename, 'w') try: subprocess.check_call([ 'curl', '-X', 'POST', '-F', 'request=xmatch', '-F', 'distMaxArcsec=4', '-F', 'RESPONSEFORMAT=csv', '-F', 'cat1=@%s' % os.path.basename(posfilename), '-F', 'colRA1=RA', '-F', 'colDec1=DEC', '-F', 'cat2=vizier:PPMXL', 'http://cdsxmatch.u-strasbg.fr/xmatch/api/v1/sync' ], stdout=result) except subprocess.CalledProcessError: os.remove(posfilename) if os.path.exists(resultfilename): result.close() os.remove(resultfilename) result.close() # Match back and only keep the closest one ma = numpy.loadtxt(resultfilename, delimiter=',', skiprows=1, converters={ 15: lambda s: float(s.strip() or -9999), 16: lambda s: float(s.strip() or -9999), 17: lambda s: float(s.strip() or -9999), 18: lambda s: float(s.strip() or -9999) }, usecols=(4, 5, 15, 16, 19, 20)) h = esutil.htm.HTM() m1, m2, d12 = h.match(data['RA'], data['DEC'], ma[:, 0], ma[:, 1], 4. / 3600., maxmatch=1) pmdata['PMMATCH'] = 0 pmdata['RA'] = data['RA'] pmdata['DEC'] = data['DEC'] pmdata['PMMATCH'][m1] = 1 pmdata['PMRA'][m1] = ma[m2, 2] pmdata['PMDEC'][m1] = ma[m2, 3] pmdata['PMRA_ERR'][m1] = ma[m2, 4] pmdata['PMDEC_ERR'][m1] = ma[m2, 5] pmdata['PMMATCH'][(pmdata['PMRA'] == -9999) \ +(pmdata['PMDEC'] == -9999) \ +(pmdata['PMRA_ERR'] == -9999) \ +(pmdata['PMDEC_ERR'] == -9999)]= 0 fitsio.write(pmfile, pmdata, clobber=True) #To make sure we're using the same format below pmdata = fitsio.read(pmfile, 1) os.remove(posfilename) os.remove(resultfilename) #Match proper motions to ppmxl data = esutil.numpy_util.add_fields(data, [('PMRA_PPMXL', numpy.float), ('PMDEC_PPMXL', numpy.float), ('PMRA_ERR_PPMXL', numpy.float), ('PMDEC_ERR_PPMXL', numpy.float), ('PMMATCH_PPMXL', numpy.int32)]) data['PMMATCH_PPMXL'] = 0 h = esutil.htm.HTM() m1, m2, d12 = h.match(pmdata['RA'], pmdata['DEC'], data['RA'], data['DEC'], 2. / 3600., maxmatch=1) data['PMRA_PPMXL'][m2] = pmdata['PMRA'][m1] data['PMDEC_PPMXL'][m2] = pmdata['PMDEC'][m1] data['PMRA_ERR_PPMXL'][m2] = pmdata['PMRA_ERR'][m1] data['PMDEC_ERR_PPMXL'][m2] = pmdata['PMDEC_ERR'][m1] data['PMMATCH_PPMXL'][m2] = pmdata['PMMATCH'][m1].astype(numpy.int32) pmindx = data['PMMATCH_PPMXL'] == 1 data['PMRA_PPMXL'][True - pmindx] = -9999.99 data['PMDEC_PPMXL'][True - pmindx] = -9999.99 data['PMRA_ERR_PPMXL'][True - pmindx] = -9999.99 data['PMDEC_ERR_PPMXL'][True - pmindx] = -9999.99 #Calculate Galactocentric velocities data = esutil.numpy_util.add_fields(data, [('GALVR_PPMXL', numpy.float), ('GALVT_PPMXL', numpy.float), ('GALVZ_PPMXL', numpy.float)]) lb = bovy_coords.radec_to_lb(data['RA'], data['DEC'], degree=True) XYZ = bovy_coords.lbd_to_XYZ(lb[:, 0], lb[:, 1], data['RC_DIST'], degree=True) pmllpmbb = bovy_coords.pmrapmdec_to_pmllpmbb(data['PMRA_PPMXL'], data['PMDEC_PPMXL'], data['RA'], data['DEC'], degree=True) vxvyvz = bovy_coords.vrpmllpmbb_to_vxvyvz(data['VHELIO_AVG'], pmllpmbb[:, 0], pmllpmbb[:, 1], lb[:, 0], lb[:, 1], data['RC_DIST'], degree=True) vR, vT, vZ = bovy_coords.vxvyvz_to_galcencyl( vxvyvz[:, 0], vxvyvz[:, 1], vxvyvz[:, 2], 8. - XYZ[:, 0], XYZ[:, 1], XYZ[:, 2] + 0.025, vsun=[-11.1, 30.24 * 8., 7.25]) #Assumes proper motion of Sgr A* and R0=8 kpc, zo= 25 pc data['GALVR_PPMXL'] = vR data['GALVT_PPMXL'] = vT data['GALVZ_PPMXL'] = vZ data['GALVR_PPMXL'][True - pmindx] = -9999.99 data['GALVT_PPMXL'][True - pmindx] = -9999.99 data['GALVZ_PPMXL'][True - pmindx] = -9999.99 #Save fitsio.write(savefilename, data, clobber=True) return None
def _add_proper_motions_pregaia(data, savefilename): #Get proper motions, in a somewhat roundabout way pmfile = savefilename.split('.')[0] + '_pms.fits' if os.path.exists(pmfile): pmdata = fitsread(pmfile, 1) else: pmdata = numpy.recarray( len(data), formats=['f8', 'f8', 'f8', 'f8', 'f8', 'f8', 'i4'], names=[ 'RA', 'DEC', 'PMRA', 'PMDEC', 'PMRA_ERR', 'PMDEC_ERR', 'PMMATCH' ]) # Write positions, again ... posfilename = tempfile.mktemp('.csv', dir=os.getcwd()) resultfilename = tempfile.mktemp('.csv', dir=os.getcwd()) with open(posfilename, 'w') as csvfile: wr = csv.writer(csvfile, delimiter=',', quoting=csv.QUOTE_MINIMAL) wr.writerow(['RA', 'DEC']) for ii in range(len(data)): wr.writerow([data[ii]['RA'], data[ii]['DEC']]) # Send to CDS for matching result = open(resultfilename, 'w') try: subprocess.check_call([ 'curl', '-X', 'POST', '-F', 'request=xmatch', '-F', 'distMaxArcsec=4', '-F', 'RESPONSEFORMAT=csv', '-F', 'cat1=@%s' % os.path.basename(posfilename), '-F', 'colRA1=RA', '-F', 'colDec1=DEC', '-F', 'cat2=vizier:UCAC4', 'http://cdsxmatch.u-strasbg.fr/xmatch/api/v1/sync' ], stdout=result) except subprocess.CalledProcessError: os.remove(posfilename) if os.path.exists(resultfilename): result.close() os.remove(resultfilename) result.close() # Match back and only keep the closest one ma = numpy.loadtxt(resultfilename, delimiter=',', skiprows=1, converters={ 15: lambda s: float(s.strip() or -9999), 16: lambda s: float(s.strip() or -9999), 17: lambda s: float(s.strip() or -9999), 18: lambda s: float(s.strip() or -9999) }, usecols=(4, 5, 15, 16, 17, 18)) h = esutil.htm.HTM() m1, m2, d12 = h.match(data['RA'], data['DEC'], ma[:, 0], ma[:, 1], 4. / 3600., maxmatch=1) pmdata['PMMATCH'] = 0 pmdata['RA'] = data['RA'] pmdata['DEC'] = data['DEC'] pmdata['PMMATCH'][m1] = 1 pmdata['PMRA'][m1] = ma[m2, 2] pmdata['PMDEC'][m1] = ma[m2, 3] pmdata['PMRA_ERR'][m1] = ma[m2, 4] pmdata['PMDEC_ERR'][m1] = ma[m2, 5] pmdata['PMMATCH'][(pmdata['PMRA'] == -9999) \ +(pmdata['PMDEC'] == -9999) \ +(pmdata['PMRA_ERR'] == -9999) \ +(pmdata['PMDEC_ERR'] == -9999)]= 0 fitswrite(pmfile, pmdata, clobber=True) #To make sure we're using the same format below pmdata = fitsread(pmfile, 1) os.remove(posfilename) os.remove(resultfilename) #Match proper motions try: #These already exist currently, but may not always exist data = esutil.numpy_util.remove_fields(data, ['PMRA', 'PMDEC']) except ValueError: pass data = esutil.numpy_util.add_fields(data, [('PMRA', numpy.float), ('PMDEC', numpy.float), ('PMRA_ERR', numpy.float), ('PMDEC_ERR', numpy.float), ('PMMATCH', numpy.int32)]) data['PMMATCH'] = 0 h = esutil.htm.HTM() m1, m2, d12 = h.match(pmdata['RA'], pmdata['DEC'], data['RA'], data['DEC'], 2. / 3600., maxmatch=1) data['PMRA'][m2] = pmdata['PMRA'][m1] data['PMDEC'][m2] = pmdata['PMDEC'][m1] data['PMRA_ERR'][m2] = pmdata['PMRA_ERR'][m1] data['PMDEC_ERR'][m2] = pmdata['PMDEC_ERR'][m1] data['PMMATCH'][m2] = pmdata['PMMATCH'][m1].astype(numpy.int32) pmindx = data['PMMATCH'] == 1 data['PMRA'][True ^ pmindx] = -9999.99 data['PMDEC'][True ^ pmindx] = -9999.99 data['PMRA_ERR'][True ^ pmindx] = -9999.99 data['PMDEC_ERR'][True ^ pmindx] = -9999.99 #Calculate Galactocentric velocities data = esutil.numpy_util.add_fields(data, [('GALVR', numpy.float), ('GALVT', numpy.float), ('GALVZ', numpy.float)]) lb = bovy_coords.radec_to_lb(data['RA'], data['DEC'], degree=True) XYZ = bovy_coords.lbd_to_XYZ(lb[:, 0], lb[:, 1], data['RC_DIST'], degree=True) pmllpmbb = bovy_coords.pmrapmdec_to_pmllpmbb(data['PMRA'], data['PMDEC'], data['RA'], data['DEC'], degree=True) vxvyvz = bovy_coords.vrpmllpmbb_to_vxvyvz(data['VHELIO_AVG'], pmllpmbb[:, 0], pmllpmbb[:, 1], lb[:, 0], lb[:, 1], data['RC_DIST'], degree=True) vRvTvZ = bovy_coords.vxvyvz_to_galcencyl( vxvyvz[:, 0], vxvyvz[:, 1], vxvyvz[:, 2], 8. - XYZ[:, 0], XYZ[:, 1], XYZ[:, 2] + 0.025, vsun=[-11.1, 30.24 * 8., 7.25]) #Assumes proper motion of Sgr A* and R0=8 kpc, zo= 25 pc data['GALVR'] = vRvTvZ[:, 0] data['GALVT'] = vRvTvZ[:, 1] data['GALVZ'] = vRvTvZ[:, 2] data['GALVR'][True ^ pmindx] = -9999.99 data['GALVT'][True ^ pmindx] = -9999.99 data['GALVZ'][True ^ pmindx] = -9999.99 #Get HSOY proper motions, in a somewhat roundabout way pmfile = savefilename.split('.')[0] + '_pms_ppmxl.fits' if os.path.exists(pmfile): pmdata = fitsread(pmfile, 1) else: pmdata = numpy.recarray( len(data), formats=['f8', 'f8', 'f8', 'f8', 'f8', 'f8', 'i4'], names=[ 'RA', 'DEC', 'PMRA', 'PMDEC', 'PMRA_ERR', 'PMDEC_ERR', 'PMMATCH' ]) # Write positions, again ... posfilename = tempfile.mktemp('.csv', dir=os.getcwd()) resultfilename = tempfile.mktemp('.csv', dir=os.getcwd()) with open(posfilename, 'w') as csvfile: wr = csv.writer(csvfile, delimiter=',', quoting=csv.QUOTE_MINIMAL) wr.writerow(['RA', 'DEC']) for ii in range(len(data)): wr.writerow([data[ii]['RA'], data[ii]['DEC']]) # Send to CDS for matching result = open(resultfilename, 'w') try: subprocess.check_call([ 'curl', '-X', 'POST', '-F', 'request=xmatch', '-F', 'distMaxArcsec=4', '-F', 'RESPONSEFORMAT=csv', '-F', 'cat1=@%s' % os.path.basename(posfilename), '-F', 'colRA1=RA', '-F', 'colDec1=DEC', '-F', 'cat2=vizier:I/339/hsoy', 'http://cdsxmatch.u-strasbg.fr/xmatch/api/v1/sync' ], stdout=result) except subprocess.CalledProcessError: os.remove(posfilename) if os.path.exists(resultfilename): result.close() os.remove(resultfilename) result.close() # Match back and only keep the closest one ma = numpy.loadtxt(resultfilename, delimiter=',', skiprows=1, converters={ 12: lambda s: float(s.strip() or -9999), 13: lambda s: float(s.strip() or -9999), 14: lambda s: float(s.strip() or -9999), 15: lambda s: float(s.strip() or -9999) }, usecols=(3, 4, 12, 13, 14, 15)) h = esutil.htm.HTM() m1, m2, d12 = h.match(data['RA'], data['DEC'], ma[:, 0], ma[:, 1], 4. / 3600., maxmatch=1) pmdata['PMMATCH'] = 0 pmdata['RA'] = data['RA'] pmdata['DEC'] = data['DEC'] pmdata['PMMATCH'][m1] = 1 pmdata['PMRA'][m1] = ma[m2, 2] pmdata['PMDEC'][m1] = ma[m2, 3] pmdata['PMRA_ERR'][m1] = ma[m2, 4] pmdata['PMDEC_ERR'][m1] = ma[m2, 5] pmdata['PMMATCH'][(pmdata['PMRA'] == -9999) \ +(pmdata['PMDEC'] == -9999) \ +(pmdata['PMRA_ERR'] == -9999) \ +(pmdata['PMDEC_ERR'] == -9999)]= 0 fitswrite(pmfile, pmdata, clobber=True) #To make sure we're using the same format below pmdata = fitsread(pmfile, 1) os.remove(posfilename) os.remove(resultfilename) #Match proper motions to ppmxl/HSOY data = esutil.numpy_util.add_fields(data, [('PMRA_HSOY', numpy.float), ('PMDEC_HSOY', numpy.float), ('PMRA_ERR_HSOY', numpy.float), ('PMDEC_ERR_HSOY', numpy.float), ('PMMATCH_HSOY', numpy.int32)]) data['PMMATCH_HSOY'] = 0 h = esutil.htm.HTM() m1, m2, d12 = h.match(pmdata['RA'], pmdata['DEC'], data['RA'], data['DEC'], 2. / 3600., maxmatch=1) data['PMRA_HSOY'][m2] = pmdata['PMRA'][m1] data['PMDEC_HSOY'][m2] = pmdata['PMDEC'][m1] data['PMRA_ERR_HSOY'][m2] = pmdata['PMRA_ERR'][m1] data['PMDEC_ERR_HSOY'][m2] = pmdata['PMDEC_ERR'][m1] data['PMMATCH_HSOY'][m2] = pmdata['PMMATCH'][m1].astype(numpy.int32) pmindx = data['PMMATCH_HSOY'] == 1 data['PMRA_HSOY'][True ^ pmindx] = -9999.99 data['PMDEC_HSOY'][True ^ pmindx] = -9999.99 data['PMRA_ERR_HSOY'][True ^ pmindx] = -9999.99 data['PMDEC_ERR_HSOY'][True ^ pmindx] = -9999.99 #Calculate Galactocentric velocities data = esutil.numpy_util.add_fields(data, [('GALVR_HSOY', numpy.float), ('GALVT_HSOY', numpy.float), ('GALVZ_HSOY', numpy.float)]) lb = bovy_coords.radec_to_lb(data['RA'], data['DEC'], degree=True) XYZ = bovy_coords.lbd_to_XYZ(lb[:, 0], lb[:, 1], data['RC_DIST'], degree=True) pmllpmbb = bovy_coords.pmrapmdec_to_pmllpmbb(data['PMRA_HSOY'], data['PMDEC_HSOY'], data['RA'], data['DEC'], degree=True) vxvyvz = bovy_coords.vrpmllpmbb_to_vxvyvz(data['VHELIO_AVG'], pmllpmbb[:, 0], pmllpmbb[:, 1], lb[:, 0], lb[:, 1], data['RC_DIST'], degree=True) vRvTvZ = bovy_coords.vxvyvz_to_galcencyl( vxvyvz[:, 0], vxvyvz[:, 1], vxvyvz[:, 2], 8. - XYZ[:, 0], XYZ[:, 1], XYZ[:, 2] + 0.025, vsun=[-11.1, 30.24 * 8., 7.25]) #Assumes proper motion of Sgr A* and R0=8 kpc, zo= 25 pc data['GALVR_HSOY'] = vRvTvZ[:, 0] data['GALVT_HSOY'] = vRvTvZ[:, 1] data['GALVZ_HSOY'] = vRvTvZ[:, 2] data['GALVR_HSOY'][True ^ pmindx] = -9999.99 data['GALVT_HSOY'][True ^ pmindx] = -9999.99 data['GALVZ_HSOY'][True ^ pmindx] = -9999.99 #Return return data return None
def make_rcsample(parser): options,args= parser.parse_args() savefilename= options.savefilename if savefilename is None: #Create savefilename if not given savefilename= os.path.join(appath._APOGEE_DATA, 'rcsample_'+appath._APOGEE_REDUX+'.fits') print("Saving to %s ..." % savefilename) #Read the base-sample data= apread.allStar(adddist=_ADDHAYDENDIST,rmdups=options.rmdups) #Remove a bunch of fields that we do not want to keep data= esutil.numpy_util.remove_fields(data, ['TARGET_ID', 'FILE', 'AK_WISE', 'SFD_EBV', 'SYNTHVHELIO_AVG', 'SYNTHVSCATTER', 'SYNTHVERR', 'SYNTHVERR_MED', 'RV_TEFF', 'RV_LOGG', 'RV_FEH', 'RV_ALPHA', 'RV_CARB', 'RV_CCFWHM', 'RV_AUTOFWHM', 'SYNTHSCATTER', 'STABLERV_CHI2', 'STABLERV_RCHI2', 'STABLERV_CHI2_PROB', 'CHI2_THRESHOLD', 'APSTAR_VERSION', 'ASPCAP_VERSION', 'RESULTS_VERSION', 'WASH_M', 'WASH_M_ERR', 'WASH_T2', 'WASH_T2_ERR', 'DDO51', 'DDO51_ERR', 'IRAC_3_6', 'IRAC_3_6_ERR', 'IRAC_4_5', 'IRAC_4_5_ERR', 'IRAC_5_8', 'IRAC_5_8_ERR', 'IRAC_8_0', 'IRAC_8_0_ERR', 'WISE_4_5', 'WISE_4_5_ERR', 'TARG_4_5', 'TARG_4_5_ERR', 'WASH_DDO51_GIANT_FLAG', 'WASH_DDO51_STAR_FLAG', 'REDUCTION_ID', 'SRC_H', 'PM_SRC']) if not appath._APOGEE_REDUX.lower() == 'current' \ and not 'l30' in appath._APOGEE_REDUX \ and int(appath._APOGEE_REDUX[1:]) < 500: data= esutil.numpy_util.remove_fields(data, ['ELEM']) #Select red-clump stars jk= data['J0']-data['K0'] z= isodist.FEH2Z(data['METALS'],zsolar=0.017) if 'l30' in appath._APOGEE_REDUX: logg= data['LOGG'] elif appath._APOGEE_REDUX.lower() == 'current' \ or int(appath._APOGEE_REDUX[1:]) > 600: from apogee.tools import paramIndx if False: #Use my custom logg calibration that's correct for the RC logg= (1.-0.042)*data['FPARAM'][:,paramIndx('logg')]-0.213 lowloggindx= data['FPARAM'][:,paramIndx('logg')] < 1. logg[lowloggindx]= data['FPARAM'][lowloggindx,paramIndx('logg')]-0.255 hiloggindx= data['FPARAM'][:,paramIndx('logg')] > 3.8 logg[hiloggindx]= data['FPARAM'][hiloggindx,paramIndx('logg')]-0.3726 else: #Use my custom logg calibration that's correct on average logg= (1.+0.03)*data['FPARAM'][:,paramIndx('logg')]-0.37 lowloggindx= data['FPARAM'][:,paramIndx('logg')] < 1. logg[lowloggindx]= data['FPARAM'][lowloggindx,paramIndx('logg')]-0.34 hiloggindx= data['FPARAM'][:,paramIndx('logg')] > 3.8 logg[hiloggindx]= data['FPARAM'][hiloggindx,paramIndx('logg')]-0.256 else: logg= data['LOGG'] indx= (jk < 0.8)*(jk >= 0.5)\ *(z <= 0.06)\ *(z <= rcmodel.jkzcut(jk,upper=True))\ *(z >= rcmodel.jkzcut(jk))\ *(logg >= rcmodel.loggteffcut(data['TEFF'],z,upper=False))\ *(logg <= rcmodel.loggteffcut(data['TEFF'],z,upper=True)) data= data[indx] #Add more aggressive flag cut data= esutil.numpy_util.add_fields(data,[('ADDL_LOGG_CUT',numpy.int32)]) data['ADDL_LOGG_CUT']= ((data['TEFF']-4800.)/1000.+2.75) > data['LOGG'] if options.loggcut: data= data[data['ADDL_LOGG_CUT'] == 1] print("Making catalog of %i objects ..." % len(data)) #Add distances data= esutil.numpy_util.add_fields(data,[('RC_DIST', float), ('RC_DM', float), ('RC_GALR', float), ('RC_GALPHI', float), ('RC_GALZ', float)]) rcd= rcmodel.rcdist() jk= data['J0']-data['K0'] z= isodist.FEH2Z(data['METALS'],zsolar=0.017) data['RC_DIST']= rcd(jk,z,appmag=data['K0'])*options.distfac data['RC_DM']= 5.*numpy.log10(data['RC_DIST'])+10. XYZ= bovy_coords.lbd_to_XYZ(data['GLON'], data['GLAT'], data['RC_DIST'], degree=True) R,phi,Z= bovy_coords.XYZ_to_galcencyl(XYZ[:,0], XYZ[:,1], XYZ[:,2], Xsun=8.,Zsun=0.025) data['RC_GALR']= R data['RC_GALPHI']= phi data['RC_GALZ']= Z #Save fitsio.write(savefilename,data,clobber=True) # Add Tycho-2 matches if options.tyc2: data= esutil.numpy_util.add_fields(data,[('TYC2MATCH',numpy.int32), ('TYC1',numpy.int32), ('TYC2',numpy.int32), ('TYC3',numpy.int32)]) data['TYC2MATCH']= 0 data['TYC1']= -1 data['TYC2']= -1 data['TYC3']= -1 # Write positions posfilename= tempfile.mktemp('.csv',dir=os.getcwd()) resultfilename= tempfile.mktemp('.csv',dir=os.getcwd()) with open(posfilename,'w') as csvfile: wr= csv.writer(csvfile,delimiter=',',quoting=csv.QUOTE_MINIMAL) wr.writerow(['RA','DEC']) for ii in range(len(data)): wr.writerow([data[ii]['RA'],data[ii]['DEC']]) # Send to CDS for matching result= open(resultfilename,'w') try: subprocess.check_call(['curl', '-X','POST', '-F','request=xmatch', '-F','distMaxArcsec=2', '-F','RESPONSEFORMAT=csv', '-F','cat1=@%s' % os.path.basename(posfilename), '-F','colRA1=RA', '-F','colDec1=DEC', '-F','cat2=vizier:Tycho2', 'http://cdsxmatch.u-strasbg.fr/xmatch/api/v1/sync'], stdout=result) except subprocess.CalledProcessError: os.remove(posfilename) if os.path.exists(resultfilename): result.close() os.remove(resultfilename) result.close() # Directly match on input RA ma= numpy.loadtxt(resultfilename,delimiter=',',skiprows=1, usecols=(1,2,7,8,9)) iis= numpy.arange(len(data)) mai= [iis[data['RA'] == ma[ii,0]][0] for ii in range(len(ma))] data['TYC2MATCH'][mai]= 1 data['TYC1'][mai]= ma[:,2] data['TYC2'][mai]= ma[:,3] data['TYC3'][mai]= ma[:,4] os.remove(posfilename) os.remove(resultfilename) if not options.nostat: #Determine statistical sample and add flag apo= apogee.select.apogeeSelect() statIndx= apo.determine_statistical(data) mainIndx= apread.mainIndx(data) data= esutil.numpy_util.add_fields(data,[('STAT',numpy.int32), ('INVSF',float)]) data['STAT']= 0 data['STAT'][statIndx*mainIndx]= 1 for ii in range(len(data)): if (statIndx*mainIndx)[ii]: data['INVSF'][ii]= 1./apo(data['LOCATION_ID'][ii], data['H'][ii]) else: data['INVSF'][ii]= -1. if options.nopm: fitsio.write(savefilename,data,clobber=True) return None #Get proper motions, in a somewhat roundabout way pmfile= savefilename.split('.')[0]+'_pms.fits' if os.path.exists(pmfile): pmdata= fitsio.read(pmfile,1) else: pmdata= numpy.recarray(len(data), formats=['f8','f8','f8','f8','f8','f8','i4'], names=['RA','DEC','PMRA','PMDEC', 'PMRA_ERR','PMDEC_ERR','PMMATCH']) # Write positions, again ... posfilename= tempfile.mktemp('.csv',dir=os.getcwd()) resultfilename= tempfile.mktemp('.csv',dir=os.getcwd()) with open(posfilename,'w') as csvfile: wr= csv.writer(csvfile,delimiter=',',quoting=csv.QUOTE_MINIMAL) wr.writerow(['RA','DEC']) for ii in range(len(data)): wr.writerow([data[ii]['RA'],data[ii]['DEC']]) # Send to CDS for matching result= open(resultfilename,'w') try: subprocess.check_call(['curl', '-X','POST', '-F','request=xmatch', '-F','distMaxArcsec=4', '-F','RESPONSEFORMAT=csv', '-F','cat1=@%s' % os.path.basename(posfilename), '-F','colRA1=RA', '-F','colDec1=DEC', '-F','cat2=vizier:UCAC4', 'http://cdsxmatch.u-strasbg.fr/xmatch/api/v1/sync'], stdout=result) except subprocess.CalledProcessError: os.remove(posfilename) if os.path.exists(resultfilename): result.close() os.remove(resultfilename) result.close() # Match back and only keep the closest one ma= numpy.loadtxt(resultfilename,delimiter=',',skiprows=1, converters={15: lambda s: float(s.strip() or -9999), 16: lambda s: float(s.strip() or -9999), 17: lambda s: float(s.strip() or -9999), 18: lambda s: float(s.strip() or -9999)}, usecols=(4,5,15,16,17,18)) h=esutil.htm.HTM() m1,m2,d12 = h.match(data['RA'],data['DEC'], ma[:,0],ma[:,1],4./3600.,maxmatch=1) pmdata['PMMATCH']= 0 pmdata['RA']= data['RA'] pmdata['DEC']= data['DEC'] pmdata['PMMATCH'][m1]= 1 pmdata['PMRA'][m1]= ma[m2,2] pmdata['PMDEC'][m1]= ma[m2,3] pmdata['PMRA_ERR'][m1]= ma[m2,4] pmdata['PMDEC_ERR'][m1]= ma[m2,5] pmdata['PMMATCH'][(pmdata['PMRA'] == -9999) \ +(pmdata['PMDEC'] == -9999) \ +(pmdata['PMRA_ERR'] == -9999) \ +(pmdata['PMDEC_ERR'] == -9999)]= 0 fitsio.write(pmfile,pmdata,clobber=True) #To make sure we're using the same format below pmdata= fitsio.read(pmfile,1) os.remove(posfilename) os.remove(resultfilename) #Match proper motions try: #These already exist currently, but may not always exist data= esutil.numpy_util.remove_fields(data,['PMRA','PMDEC']) except ValueError: pass data= esutil.numpy_util.add_fields(data,[('PMRA', numpy.float), ('PMDEC', numpy.float), ('PMRA_ERR', numpy.float), ('PMDEC_ERR', numpy.float), ('PMMATCH',numpy.int32)]) data['PMMATCH']= 0 h=esutil.htm.HTM() m1,m2,d12 = h.match(pmdata['RA'],pmdata['DEC'], data['RA'],data['DEC'], 2./3600.,maxmatch=1) data['PMRA'][m2]= pmdata['PMRA'][m1] data['PMDEC'][m2]= pmdata['PMDEC'][m1] data['PMRA_ERR'][m2]= pmdata['PMRA_ERR'][m1] data['PMDEC_ERR'][m2]= pmdata['PMDEC_ERR'][m1] data['PMMATCH'][m2]= pmdata['PMMATCH'][m1].astype(numpy.int32) pmindx= data['PMMATCH'] == 1 data['PMRA'][True-pmindx]= -9999.99 data['PMDEC'][True-pmindx]= -9999.99 data['PMRA_ERR'][True-pmindx]= -9999.99 data['PMDEC_ERR'][True-pmindx]= -9999.99 #Calculate Galactocentric velocities data= esutil.numpy_util.add_fields(data,[('GALVR', numpy.float), ('GALVT', numpy.float), ('GALVZ', numpy.float)]) lb= bovy_coords.radec_to_lb(data['RA'],data['DEC'],degree=True) XYZ= bovy_coords.lbd_to_XYZ(lb[:,0],lb[:,1],data['RC_DIST'],degree=True) pmllpmbb= bovy_coords.pmrapmdec_to_pmllpmbb(data['PMRA'],data['PMDEC'], data['RA'],data['DEC'], degree=True) vxvyvz= bovy_coords.vrpmllpmbb_to_vxvyvz(data['VHELIO_AVG'], pmllpmbb[:,0], pmllpmbb[:,1], lb[:,0],lb[:,1],data['RC_DIST'], degree=True) vR, vT, vZ= bovy_coords.vxvyvz_to_galcencyl(vxvyvz[:,0], vxvyvz[:,1], vxvyvz[:,2], 8.-XYZ[:,0], XYZ[:,1], XYZ[:,2]+0.025, vsun=[-11.1,30.24*8.,7.25])#Assumes proper motion of Sgr A* and R0=8 kpc, zo= 25 pc data['GALVR']= vR data['GALVT']= vT data['GALVZ']= vZ data['GALVR'][True-pmindx]= -9999.99 data['GALVT'][True-pmindx]= -9999.99 data['GALVZ'][True-pmindx]= -9999.99 #Get PPMXL proper motions, in a somewhat roundabout way pmfile= savefilename.split('.')[0]+'_pms_ppmxl.fits' if os.path.exists(pmfile): pmdata= fitsio.read(pmfile,1) else: pmdata= numpy.recarray(len(data), formats=['f8','f8','f8','f8','f8','f8','i4'], names=['RA','DEC','PMRA','PMDEC', 'PMRA_ERR','PMDEC_ERR','PMMATCH']) # Write positions, again ... posfilename= tempfile.mktemp('.csv',dir=os.getcwd()) resultfilename= tempfile.mktemp('.csv',dir=os.getcwd()) with open(posfilename,'w') as csvfile: wr= csv.writer(csvfile,delimiter=',',quoting=csv.QUOTE_MINIMAL) wr.writerow(['RA','DEC']) for ii in range(len(data)): wr.writerow([data[ii]['RA'],data[ii]['DEC']]) # Send to CDS for matching result= open(resultfilename,'w') try: subprocess.check_call(['curl', '-X','POST', '-F','request=xmatch', '-F','distMaxArcsec=4', '-F','RESPONSEFORMAT=csv', '-F','cat1=@%s' % os.path.basename(posfilename), '-F','colRA1=RA', '-F','colDec1=DEC', '-F','cat2=vizier:PPMXL', 'http://cdsxmatch.u-strasbg.fr/xmatch/api/v1/sync'], stdout=result) except subprocess.CalledProcessError: os.remove(posfilename) if os.path.exists(resultfilename): result.close() os.remove(resultfilename) result.close() # Match back and only keep the closest one ma= numpy.loadtxt(resultfilename,delimiter=',',skiprows=1, converters={15: lambda s: float(s.strip() or -9999), 16: lambda s: float(s.strip() or -9999), 17: lambda s: float(s.strip() or -9999), 18: lambda s: float(s.strip() or -9999)}, usecols=(4,5,15,16,19,20)) h=esutil.htm.HTM() m1,m2,d12 = h.match(data['RA'],data['DEC'], ma[:,0],ma[:,1],4./3600.,maxmatch=1) pmdata['PMMATCH']= 0 pmdata['RA']= data['RA'] pmdata['DEC']= data['DEC'] pmdata['PMMATCH'][m1]= 1 pmdata['PMRA'][m1]= ma[m2,2] pmdata['PMDEC'][m1]= ma[m2,3] pmdata['PMRA_ERR'][m1]= ma[m2,4] pmdata['PMDEC_ERR'][m1]= ma[m2,5] pmdata['PMMATCH'][(pmdata['PMRA'] == -9999) \ +(pmdata['PMDEC'] == -9999) \ +(pmdata['PMRA_ERR'] == -9999) \ +(pmdata['PMDEC_ERR'] == -9999)]= 0 fitsio.write(pmfile,pmdata,clobber=True) #To make sure we're using the same format below pmdata= fitsio.read(pmfile,1) os.remove(posfilename) os.remove(resultfilename) #Match proper motions to ppmxl data= esutil.numpy_util.add_fields(data,[('PMRA_PPMXL', numpy.float), ('PMDEC_PPMXL', numpy.float), ('PMRA_ERR_PPMXL', numpy.float), ('PMDEC_ERR_PPMXL', numpy.float), ('PMMATCH_PPMXL',numpy.int32)]) data['PMMATCH_PPMXL']= 0 h=esutil.htm.HTM() m1,m2,d12 = h.match(pmdata['RA'],pmdata['DEC'], data['RA'],data['DEC'], 2./3600.,maxmatch=1) data['PMRA_PPMXL'][m2]= pmdata['PMRA'][m1] data['PMDEC_PPMXL'][m2]= pmdata['PMDEC'][m1] data['PMRA_ERR_PPMXL'][m2]= pmdata['PMRA_ERR'][m1] data['PMDEC_ERR_PPMXL'][m2]= pmdata['PMDEC_ERR'][m1] data['PMMATCH_PPMXL'][m2]= pmdata['PMMATCH'][m1].astype(numpy.int32) pmindx= data['PMMATCH_PPMXL'] == 1 data['PMRA_PPMXL'][True-pmindx]= -9999.99 data['PMDEC_PPMXL'][True-pmindx]= -9999.99 data['PMRA_ERR_PPMXL'][True-pmindx]= -9999.99 data['PMDEC_ERR_PPMXL'][True-pmindx]= -9999.99 #Calculate Galactocentric velocities data= esutil.numpy_util.add_fields(data,[('GALVR_PPMXL', numpy.float), ('GALVT_PPMXL', numpy.float), ('GALVZ_PPMXL', numpy.float)]) lb= bovy_coords.radec_to_lb(data['RA'],data['DEC'],degree=True) XYZ= bovy_coords.lbd_to_XYZ(lb[:,0],lb[:,1],data['RC_DIST'],degree=True) pmllpmbb= bovy_coords.pmrapmdec_to_pmllpmbb(data['PMRA_PPMXL'], data['PMDEC_PPMXL'], data['RA'],data['DEC'], degree=True) vxvyvz= bovy_coords.vrpmllpmbb_to_vxvyvz(data['VHELIO_AVG'], pmllpmbb[:,0], pmllpmbb[:,1], lb[:,0],lb[:,1],data['RC_DIST'], degree=True) vR, vT, vZ= bovy_coords.vxvyvz_to_galcencyl(vxvyvz[:,0], vxvyvz[:,1], vxvyvz[:,2], 8.-XYZ[:,0], XYZ[:,1], XYZ[:,2]+0.025, vsun=[-11.1,30.24*8.,7.25])#Assumes proper motion of Sgr A* and R0=8 kpc, zo= 25 pc data['GALVR_PPMXL']= vR data['GALVT_PPMXL']= vT data['GALVZ_PPMXL']= vZ data['GALVR_PPMXL'][True-pmindx]= -9999.99 data['GALVT_PPMXL'][True-pmindx]= -9999.99 data['GALVZ_PPMXL'][True-pmindx]= -9999.99 #Save fitsio.write(savefilename,data,clobber=True) return None
def calc_actions(ra_deg, dec_deg, d_kpc, pm_ra_masyr, pm_dec_masyr, v_los_kms): ra_rad = ra_deg * (np.pi / 180.) # RA [rad] dec_rad = dec_deg * (np.pi / 180.) # dec [rad] # Galactocentric position of the Sun: X_gc_sun_kpc = 8. # [kpc] Z_gc_sun_kpc = 0.025 # [kpc] # Galactocentric velocity of the Sun: vX_gc_sun_kms = -9.58 # = -U [kms] vY_gc_sun_kms = 10.52 + 220. # = V+v_circ(R_Sun) [kms] vZ_gc_sun_kms = 7.01 # = W [kms] # a. convert spatial coordinates (ra,dec,d) to (R,z,phi) # (ra,dec) --> Galactic coordinates (l,b): lb = bovy_coords.radec_to_lb(ra_rad, dec_rad, degree=False, epoch=2000.0) l_rad = lb[:, 0] b_rad = lb[:, 1] # (l,b,d) --> Galactocentric cartesian coordinates (x,y,z): xyz = bovy_coords.lbd_to_XYZ(l_rad, b_rad, d_kpc, degree=False) x_kpc = xyz[:, 0] y_kpc = xyz[:, 1] z_kpc = xyz[:, 2] # (x,y,z) --> Galactocentric cylindrical coordinates (R,z,phi): Rzphi = bovy_coords.XYZ_to_galcencyl(x_kpc, y_kpc, z_kpc, Xsun=X_gc_sun_kpc, Zsun=Z_gc_sun_kpc) R_kpc = Rzphi[:, 0] phi_rad = Rzphi[:, 1] z_kpc = Rzphi[:, 2] # b. convert velocities (pm_ra,pm_dec,vlos) to (vR,vz,vT) # (pm_ra,pm_dec) --> (pm_l,pm_b): pmlpmb = bovy_coords.pmrapmdec_to_pmllpmbb(pm_ra_masyr, pm_dec_masyr, ra_rad, dec_rad, degree=False, epoch=2000.0) pml_masyr = pmlpmb[:, 0] pmb_masyr = pmlpmb[:, 1] # (v_los,pm_l,pm_b) & (l,b,d) --> (vx,vy,vz): vxvyvz = bovy_coords.vrpmllpmbb_to_vxvyvz(v_los_kms, pml_masyr, pmb_masyr, l_rad, b_rad, d_kpc, XYZ=False, degree=False) vx_kms = vxvyvz[:, 0] vy_kms = vxvyvz[:, 1] vz_kms = vxvyvz[:, 2] # (vx,vy,vz) & (x,y,z) --> (vR,vT,vz): vRvTvZ = bovy_coords.vxvyvz_to_galcencyl( vx_kms, vy_kms, vz_kms, R_kpc, phi_rad, z_kpc, vsun=[vX_gc_sun_kms, vY_gc_sun_kms, vZ_gc_sun_kms], galcen=True) vR_kms = vRvTvZ[:, 0] vT_kms = vRvTvZ[:, 1] vz_kms = vRvTvZ[:, 2] print("R = ", R_kpc, "\t kpc") print("phi = ", phi_rad, "\t rad") print("z = ", z_kpc, "\t kpc") print("v_R = ", vR_kms, "\t km/s") print("v_T = ", vT_kms, "\t km/s") print("v_z = ", vz_kms, "\t km/s") return vz_kms
def obs_to_galcen(ra, dec, dist, pmra, pmdec, rv, pmra_err, pmdec_err, pmra_pmdec_corr, dist_err, rv_err, return_cov=True, verbose=True, return_rphiz=True, ro=8., vo=220., zo=0.025, parallax=False): vxvv = np.dstack([ra, dec, dist, pmra, pmdec, rv])[0] ra, dec = vxvv[:, 0], vxvv[:, 1] lb = bovy_coords.radec_to_lb(ra, dec, degree=True) pmra, pmdec = vxvv[:, 3], vxvv[:, 4] pmllpmbb = bovy_coords.pmrapmdec_to_pmllpmbb(pmra, pmdec, ra, dec, degree=True) d, vlos = vxvv[:, 2], vxvv[:, 5] if parallax: d = 1. / d rectgal = bovy_coords.sphergal_to_rectgal(lb[:, 0], lb[:, 1], d, vlos, pmllpmbb[:, 0], pmllpmbb[:, 1], degree=True) vsolar = np.array([-10.1, 4.0, 6.7]) vsun = np.array([ 0., 1., 0., ]) + vsolar / vo X = rectgal[:, 0] / ro Y = rectgal[:, 1] / ro Z = rectgal[:, 2] / ro vx = rectgal[:, 3] / vo vy = rectgal[:, 4] / vo vz = rectgal[:, 5] / vo XYZ = np.dstack([X, Y, Z])[0] vxyz = np.dstack([vx, vy, vz])[0] if return_rphiz: Rpz = bovy_coords.XYZ_to_galcencyl(XYZ[:, 0], XYZ[:, 1], XYZ[:, 2], Zsun=zo / ro) vRvTvz = bovy_coords.vxvyvz_to_galcencyl(vxyz[:, 0], vxyz[:, 1], vxyz[:, 2], Rpz[:, 0], Rpz[:, 1], Rpz[:, 2], vsun=vsun, Xsun=1., Zsun=zo / ro, galcen=True) if return_cov == True: cov_pmradec = np.empty([len(pmra_err), 2, 2]) cov_pmradec[:, 0, 0] = pmra_err**2 cov_pmradec[:, 1, 1] = pmdec_err**2 cov_pmradec[:, 0, 1] = pmra_pmdec_corr * pmra_err * pmdec_err cov_pmradec[:, 1, 0] = pmra_pmdec_corr * pmra_err * pmdec_err if verbose: print('propagating covariance in pmra pmdec -> pmll pmbb') cov_pmllbb = bovy_coords.cov_pmrapmdec_to_pmllpmbb(cov_pmradec, vxvv[:, 0], vxvv[:, 1], degree=True, epoch='J2015') if verbose: print('propagating covariance in pmll pmbb -> vx vy vz') cov_vxyz = bovy_coords.cov_dvrpmllbb_to_vxyz(vxvv[:, 2], dist_err, rv_err, pmllpmbb[:, 0], pmllpmbb[:, 1], cov_pmllbb, lb[:, 0], lb[:, 1]) if not return_rphiz: return XYZ, vxyz, cov_vxyz if verbose: print('propagating covariance in vx vy vz -> vR vT vz') cov_galcencyl = bovy_coords.cov_vxyz_to_galcencyl(cov_vxyz, Rpz[:, 1], Xsun=1., Zsun=zo / ro) return XYZ, vxyz, cov_vxyz, Rpz, vRvTvz, cov_galcencyl if not return_rphiz: return XYZ, vxyz return XYZ, vxyz, Rpz, vRvTvz
def dat_to_galcen( dat, return_cov=True, return_rphiz=True, verbose=False, ro=8., vo=220., zo=0.025, keys=['ra', 'dec', 'BPG_meandist', 'pmra', 'pmdec', 'VHELIO_AVG'], cov_keys=[ 'pmra_error', 'pmdec_error', 'pmra_pmdec_corr', 'BPG_diststd', 'VERR' ], parallax=False): vxvv = np.dstack([dat[keys[i]] for i in range(len(keys))])[0] ra, dec = vxvv[:, 0], vxvv[:, 1] lb = bovy_coords.radec_to_lb(ra, dec, degree=True) pmra, pmdec = vxvv[:, 3], vxvv[:, 4] pmllpmbb = bovy_coords.pmrapmdec_to_pmllpmbb(pmra, pmdec, ra, dec, degree=True) d, vlos = vxvv[:, 2], vxvv[:, 5] if parallax: d = 1. / d rectgal = bovy_coords.sphergal_to_rectgal(lb[:, 0], lb[:, 1], d, vlos, pmllpmbb[:, 0], pmllpmbb[:, 1], degree=True) vsolar = np.array([-11.1, 245.6, 7.25]) #use SBD10 vR and vZ and SGR proper motion vT vsun = np.array([ 0., 0., 0., ]) + vsolar / vo X = rectgal[:, 0] / ro Y = rectgal[:, 1] / ro Z = rectgal[:, 2] / ro vx = rectgal[:, 3] / vo vy = rectgal[:, 4] / vo vz = rectgal[:, 5] / vo XYZ = np.dstack([X, Y, Z])[0] vxyz = np.dstack([vx, vy, vz])[0] if return_rphiz: Rpz = bovy_coords.XYZ_to_galcencyl(XYZ[:, 0], XYZ[:, 1], XYZ[:, 2], Zsun=zo / ro) vRvTvz = bovy_coords.vxvyvz_to_galcencyl(vxyz[:, 0], vxyz[:, 1], vxyz[:, 2], Rpz[:, 0], Rpz[:, 1], Rpz[:, 2], vsun=vsun, Xsun=1., Zsun=zo / ro, galcen=True) if return_cov == True: cov_pmradec = np.array([[[ dat[cov_keys[0]][i]**2, dat[cov_keys[2]][i] * dat[cov_keys[0]][i] * dat[cov_keys[1]][i] ], [ dat[cov_keys[2]][i] * dat[cov_keys[0]][i] * dat[cov_keys[1]][i], dat[cov_keys[1]][i]**2 ]] for i in range(len(dat))]) if verbose: print('propagating covariance in pmra pmdec -> pmll pmbb') cov_pmllbb = bovy_coords.cov_pmrapmdec_to_pmllpmbb(cov_pmradec, vxvv[:, 0], vxvv[:, 1], degree=True, epoch='J2015') if verbose: print('propagating covariance in pmll pmbb -> vx vy vz') cov_vxyz = bovy_coords.cov_dvrpmllbb_to_vxyz(vxvv[:, 2], dat[cov_keys[3]], dat[cov_keys[4]], pmllpmbb[:, 0], pmllpmbb[:, 1], cov_pmllbb, lb[:, 0], lb[:, 1]) if not return_rphiz: return XYZ, vxyz, cov_vxyz if verbose: print('propagating covariance in vx vy vz -> vR vT vz') cov_galcencyl = bovy_coords.cov_vxyz_to_galcencyl(cov_vxyz, Rpz[:, 1], Xsun=1., Zsun=zo / ro) return XYZ, vxyz, cov_vxyz, Rpz, vRvTvz, cov_galcencyl if not return_rphiz: return XYZ, vxyz return XYZ, vxyz, Rpz, vRvTvz
def calc_eccentricity(args, options): table = os.path.join(args[0], 'table2.dat') readme = os.path.join(args[0], 'ReadMe') dierickx = ascii.read(table, readme=readme) vxvv = np.dstack([ dierickx['RAdeg'], dierickx['DEdeg'], dierickx['Dist'] / 1e3, dierickx['pmRA'], dierickx['pmDE'], dierickx['HRV'] ])[0] ro, vo, zo = 8., 220., 0.025 ra, dec = vxvv[:, 0], vxvv[:, 1] lb = bovy_coords.radec_to_lb(ra, dec, degree=True) pmra, pmdec = vxvv[:, 3], vxvv[:, 4] pmllpmbb = bovy_coords.pmrapmdec_to_pmllpmbb(pmra, pmdec, ra, dec, degree=True) d, vlos = vxvv[:, 2], vxvv[:, 5] rectgal = bovy_coords.sphergal_to_rectgal(lb[:, 0], lb[:, 1], d, vlos, pmllpmbb[:, 0], pmllpmbb[:, 1], degree=True) vsolar = np.array([-10.1, 4.0, 6.7]) vsun = np.array([ 0., 1., 0., ]) + vsolar / vo X = rectgal[:, 0] / ro Y = rectgal[:, 1] / ro Z = rectgal[:, 2] / ro vx = rectgal[:, 3] / vo vy = rectgal[:, 4] / vo vz = rectgal[:, 5] / vo vsun = np.array([ 0., 1., 0., ]) + vsolar / vo Rphiz = bovy_coords.XYZ_to_galcencyl(X, Y, Z, Zsun=zo / ro) vRvTvz = bovy_coords.vxvyvz_to_galcencyl(vx, vy, vz, Rphiz[:, 0], Rphiz[:, 1], Rphiz[:, 2], vsun=vsun, Xsun=1., Zsun=zo / ro, galcen=True) #do the integration and individual analytic estimate for each object ts = np.linspace(0., 20., 10000) lp = LogarithmicHaloPotential(normalize=1.) e_ana = numpy.zeros(len(vxvv)) e_int = numpy.zeros(len(vxvv)) print( 'Performing orbit integration and analytic parameter estimates for Dierickx et al. sample...' ) for i in tqdm(range(len(vxvv))): try: orbit = Orbit(vxvv[i], radec=True, vo=220., ro=8.) e_ana[i] = orbit.e(analytic=True, pot=lp, c=True) except UnboundError: e_ana[i] = np.nan orbit.integrate(ts, lp) e_int[i] = orbit.e(analytic=False) fig = plt.figure() fig.set_size_inches(1.5 * columnwidth, 1.5 * columnwidth) plt.scatter(e_int, e_ana, s=1, color='Black', lw=0.) plt.xlabel(r'$\mathrm{galpy\ integrated}\ e$') plt.ylabel(r'$\mathrm{galpy\ analytic}\ e$') plt.xlim(0., 1.) plt.ylim(0., 1.) fig.tight_layout() plt.savefig(os.path.join(args[0], 'dierickx-integratedeanalytice.png'), format='png', dpi=200) fig = plt.figure() fig.set_size_inches(1.5 * columnwidth, 1.5 * columnwidth) plt.hist(e_int, bins=30) plt.xlim(0., 1.) plt.xlabel(r'$\mathrm{galpy}\ e$') fig.tight_layout() plt.savefig(os.path.join(args[0], 'dierickx-integratedehist.png'), format='png', dpi=200) fig = plt.figure() fig.set_size_inches(1.5 * columnwidth, 1.5 * columnwidth) plt.scatter(dierickx['e'], e_int, s=1, color='Black', lw=0.) plt.xlabel(r'$\mathrm{Dierickx\ et\ al.}\ e$') plt.ylabel(r'$\mathrm{galpy\ integrated}\ e$') plt.xlim(0., 1.) plt.ylim(0., 1.) fig.tight_layout() plt.savefig(os.path.join(args[0], 'dierickx-integratedee.png'), format='png', dpi=200) fig = plt.figure() fig.set_size_inches(1.5 * columnwidth, 1.5 * columnwidth) plt.scatter(dierickx['e'], e_ana, s=1, color='Black', lw=0.) plt.xlabel(r'$\mathrm{Dierickx\ et\ al.}\ e$') plt.ylabel(r'$\mathrm{galpy\ estimated}\ e$') plt.xlim(0., 1.) plt.ylim(0., 1.) fig.tight_layout() plt.savefig(os.path.join(args[0], 'dierickx-analyticee.png'), format='png', dpi=200) arr = numpy.recarray(len(e_ana), dtype=[('analytic_e', float), ('integrated_e', float)]) arr['analytic_e'] = e_ana arr['integrated_e'] = e_int with open(os.path.join(args[0], 'eccentricities.dat'), 'w') as file: pickle.dump(arr, file) file.close()