def get_gc_for_pair(lono, lato, lonf, latf, step=0.01, degree=True, dlat=0.): #Find pole cartesian coords u_ini = bovyc.lbd_to_XYZ(lono, lato, 1., degree=degree) u_end = bovyc.lbd_to_XYZ(lonf, latf, 1., degree=degree) u_ini, u_end = np.array(u_ini), np.array(u_end) #Do cross product to find great-circle pole pX, pY, pZ = np.cross(u_ini, u_end) #Convert pole coords back to spherical pole_lon, pole_lat = bovyc.XYZ_to_lbd(pX, pY, pZ, degree=degree)[:2] #Find center as average of the two vectors cX, cY, cZ = u_ini + u_end #these are cartesian, so we're good clon, clat = bovyc.XYZ_to_lbd(cX, cY, cZ, degree=degree)[:2] #Length equals great circle distance between end-points dlon = great_circle_distance(lono, lato, lonf, latf, degree=degree) #Get great circle arc connecting the given end-points gc_lons, gc_lats = get_gc_for_pole(pole_lon, pole_lat, degree=degree, step=step, dlat=dlat, dlon=dlon, center=[clon, clat]) return gc_lons, gc_lats, clon, clat
def compute_galactocentric_coords(self,verbose=False,degree=True): #Convert to heliocentric cartesian. Bovy's library assumes Sun's position is positive #tuple output, no .T needed if verbose: print 'Converting Heliocentric Galactic Spherical to Heliocentric Cartesian coords...' m=bovyc.lbd_to_XYZ(self.l,self.b,self.Rhel,degree=degree) self.xhel,self.yhel,self.zhel=m.T if hasattr(self,'vrad') and hasattr(self,'pmb') : m=bovyc.vrpmllpmbb_to_vxvyvz(self.vrad,self.pmlstar,self.pmb,self.l,self.b,self.Rhel,XYZ=False,degree=degree) self.vxhel,self.vyhel,self.vzhel=m.T #Convert Heliocentric Cartesian to Galactocentric Cartesian if verbose: print 'Converting Heliocentric Cartesian to Galactocentric Cartesian coords...' m=bovyc.XYZ_to_galcenrect(self.xhel,self.yhel,self.zhel,Xsun=self.xsun,Ysun=self.ysun,Zsun=self.zsun) self.x,self.y,self.z=m if hasattr(self,'vrad') and hasattr(self,'mub') : m=bovyc.vxvyvz_to_galcenrect(self.vxhel,self.vyhel,self.vzhel,vsun=[self.vxsun, self.vysun, self.vzsun]) self.vx,self.vy,self.vz=m #Compute Galactocentric Spherical m=bovyc.XYZ_to_lbd(self.x,self.y,self.z,degree=degree) self.phi,self.theta,self.Rgal=m.T #Bovy's ref system's x-axis points towards the Sun. Mine points away from the Sun, i.e. x-axis is the same as for lbd #Will use my ref system for consistency with pole-ref system used in PyMGC3 if degree: f=180./np.pi else: f=1. self.x=-self.x self.phi= (2*np.pi*f - self.phi) - np.pi*f self.phi[self.phi<0]=self.phi[self.phi<0]+2*np.pi*f
def get_phi_theta_for_survey(self,obs,pars=None): if pars is None: print('No params file found. Using default parameter file mgc3.par') print_sample_parfile() pars=parse_pars('mgc3.par') print('--->',pars['par_muas']) #Check coord system. If equatorial, convert coords and proper motions to galactic #Makes use of Jo Bovy's coordinate conversion library if pars['deg']: fc=d2r else: fc=1. #fc will be used to convert inputs to radians from the start (if necessary) if not pars['coo_glactc']: ra,dec=fc*obs[:,pars['lon_col']],fc*obs[:,pars['lat_col']] #Convert. Output is in the same units as input if np.ndim(ra)>0: lb_m=bc.radec_to_lb(ra,dec,degree=False,epoch=2000.0) l,b=np.array(list(lb_m[:,0])),np.array(list(lb_m[:,1])) else: l,b=bc.radec_to_lb(ra,dec,degree=False,epoch=2000.0) else: l,b=fc*obs[:,pars['lon_col']],fc*obs[:,pars['lat_col']] #Read parallax and radial velocity if pars['par_muas']: factor=1. else: factor=1000. parallax=factor*obs[:,pars['par_col']] rhel=self.Ap/parallax xyz_hel=bc.lbd_to_XYZ(l,b,rhel,degree=False) xhel,ygal,zgal=xyz_hel[:,0],xyz_hel[:,1],xyz_hel[:,2] print(np.shape(xhel)) xgal=xhel-self.rsun #convert to spherical galactocentric Rproy=np.sqrt(xgal**2+ygal**2) sinphi,cosphi=ygal/Rproy,xgal/Rproy tanphihalf=sinphi/(1.+cosphi) phi=2*np.arctan(tanphihalf) phi=phi % (2*np.pi) theta=np.arcsin(zgal/Rproy) Rgal=np.sqrt(Rproy**2+zgal**2) #If deg_flag is set, convert phi,theta to radians to be consistent if pars['deg']: phi,theta=phi/self.d2r,theta/self.d2r #Add this columns to the obsdata matrix and dictionary new_cols=np.array([phi,theta,Rgal]).T #matrix with p,t,r as columns print(np.shape(obs), np.shape(new_cols)) new_obs=np.hstack((obs,new_cols)) #append as new columns print(np.shape(new_obs)) Nobs=len(obs[0,:]) new_pars=pars.copy() new_pars['phi_col']=Nobs new_pars['theta_col']=Nobs+1 new_pars['Rgal_col']=Nobs+2 return (new_obs,new_pars)
def compute_heliocentric_coords(self, verbose=False, degree=True): #Set Galactocentric Cartesian coords xg, yg, zg = bovyc.lbd_to_XYZ(self.phi, self.theta, self.Rgal, degree=degree).T self.x, self.y, self.z = -xg, yg, zg #Convert to Heliocentric self.xhel, self.yhel, self.zhel = bovyc.galcenrect_to_XYZ( self.x, self.y, self.z, Xsun=self.xsun, Ysun=self.ysun, Zsun=self.zsun) #Save Heliocentric galactic and equatorial self.l, self.b, self.Rhel = bovyc.XYZ_to_lbd(self.xhel, self.yhel, self.zhel, degree=degree).T self.ra, self.dec = bovyc.lb_to_radec(self.l, self.b, degree=degree).T #Set kinematic attributes, if vels available if hasattr(self, 'vx') and hasattr(self, 'vy') and hasattr(self, 'vz'): #Cartesian Heliocentric m = bovyc.galcenrect_to_vxvyvz( self.vx, self.vy, self.vz, vsun=[self.vxsun, self.vysun, self.vzsun]) self.vxhel, self.vyhel, self.vzhel = m #Spherical Heliocentric Galactic m = bovyc.vxvyvz_to_vrpmllpmbb(self.vxhel, self.vyhel, self.vzhel, self.l, self.b, self.Rhel, XYZ=False, degree=degree) self.vrad, self.pmlstar, self.pmb = m.T self.pml = self.pmlstar / np.cos(self.b * self._f) #Spherical Heliocentric Equatorial self.pmrastar, self.pmdec = pmllpmbb_to_pmrapmdec(self.pml, self.pmb, self.l, self.b, degree=degree, epoch=2000.0) self.pmra = self.pmrastar / np.cos(self.dec * self._f)
def compute_sky_center(self): #Set defaults #Need to get cartesian coords to do vector-average (this works whether or not Rhel exists) mm=bovyc.lbd_to_XYZ(self.l,self.b,np.ones_like(self.l),degree=True) if self.l.size>1: _xx,_yy,_zz=mm.T else: _xx,_yy,_zz=mm _xc,_yc,_zc=_xx.sum(),_yy.sum(),_zz.sum() self.cl,self.cb=bovyc.XYZ_to_lbd(_xc,_yc,_zc,degree=True)[:2] self.cra,self.cdec=bovyc.lb_to_radec(self.cl,self.cb,degree=True) if hasattr(self,'phi') and hasattr(self,'theta'): _xgc,_ygc,_zgc=self.x.sum(),self.y.sum(),self.z.sum() self.cphi,self.ctheta=bovyc.XYZ_to_lbd(_xgc,_ygc,_zgc,degree=True)[:2]
def __init__(self,l,b,parallax,mulstar,mub,vrad,flag_mulstar=True,xyz_sun=[-8.5,0.,0.],vel_sun=[10.3,232.6,5.9],verbose=False,degree=False,Rhel=None): #Degree2Radian conversion if degree: _d2r=np.pi/180. else: _d2r=1. #Save inputs self.l,self.b,self.parallax=l,b,parallax self.mub,self.vrad,self.Rhel=mub,vrad,1000./self.parallax #if par in mas/muas, rhel in pc/kpc if Rhel is not None: #If Rhel is given, force Rhel to be passed value self.Rhel=Rhel if flag_mulstar: self.mulstar=mulstar self.mul=mulstar/np.cos(self.b*_d2r) else: self.mul=mulstar self.mulstar=self.mul*np.cos(self.b*_d2r) #Bovy's library assumes Sun's position is positive. Flip X-axis if xsun<0 if xyz_sun[0]<0.: sign=-1 else: sign=+1 #Save Sun's position self.xsun, self.ysun, self.zsun= xyz_sun self.vxsun, self.vysun, self.vzsun= vel_sun self.xsun, self.vxsun = sign*self.xsun, sign*self.vxsun #Convert to heliocentric cartesian. Bovy's library assumes Sun's position is positive #tuple output, no .T needed if verbose: print 'Converting Heliocentric Galactic Spherical to Heliocentric Cartesian coords...' m=bovyc.lbd_to_XYZ(self.l,self.b,self.Rhel,degree=degree) self.xhel,self.yhel,self.zhel=m.T m=bovyc.vrpmllpmbb_to_vxvyvz(self.vrad,self.mulstar,self.mub,self.l,self.b,self.Rhel,XYZ=False,degree=degree) self.vxhel,self.vyhel,self.vzhel=m.T #m=bovyc.galcenrect_to_XYZ(self.x,self.y,self.z,Xsun=self.xsun,Ysun=self.ysun,Zsun=self.zsun)a #Convert Heliocentric Cartesian to Galactocentric Cartesian if verbose: print 'Converting Heliocentric Cartesian to Galactocentric Cartesian coords...' m=bovyc.XYZ_to_galcenrect(self.xhel,self.yhel,self.zhel,Xsun=self.xsun,Ysun=self.ysun,Zsun=self.zsun) self.x,self.y,self.z=m m=bovyc.vxvyvz_to_galcenrect(self.vxhel,self.vyhel,self.vzhel,vsun=[self.vxsun, self.vysun, self.vzsun]) self.vx,self.vy,self.vz=m #Compute Galactocentric Spherical if verbose: print 'Converting Galactocentric Cartesian to Spherical coords...' m=bovyc.XYZ_to_lbd(self.x,self.y,self.z,degree=degree) self.phi,self.theta,self.Rgal=m.T self.phi=(self.phi+180.) % 360.
def get_avg_vec(phis, thetas, degree=True, lon0=0.): X, Y, Z = bovyc.lbd_to_XYZ(phis, thetas, np.ones_like(phis), degree=degree).T #Vector sum Xsum = X.sum() Ysum = Y.sum() Zsum = Z.sum() #Normalize (not necessary, but nicer) norm = np.sqrt(Xsum**2 + Ysum**2 + Zsum**2) Xsum, Ysum, Zsum = Xsum / norm, Ysum / norm, Zsum / norm #Back to spherical phisum, thetasum, Rgal = bovyc.XYZ_to_lbd(Xsum, Ysum, Zsum, degree=degree) return (phisum, thetasum)