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_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 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 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 get_gc_for_pole(_lon, _lat, degree=True, step=0.01, dlat=0., center=None, dlon=None): if degree: f = np.pi / 180. else: f = 1. lon, lat = f * _lon, f * _lat #Generate great circle with pole = u_z azs, thetas = np.array([]), np.array([]) if dlat > 0: for lato in np.radians(np.arange(-dlat / 2., dlat / 2., step)): aux = np.radians(np.arange(0., 360., step)) azs = np.append(azs, aux) thetas = np.append(thetas, lato * np.ones_like(aux)) else: azs = np.radians(np.arange(0., 360., step)) thetas = np.zeros_like(azs) _x = np.cos(azs) * np.cos(thetas) _y = np.sin(azs) * np.cos(thetas) _z = np.sin(thetas) #Rotate so that pole has now the given lon,lat coslon, sinlon, coscolat, sincolat = np.cos(lon), np.sin(lon), np.cos( np.pi / 2. - lat), np.sin(np.pi / 2. - lat) _x1 = coscolat * _x + sincolat * _z _y1 = _y _z1 = -sincolat * _x + coscolat * _z _x2 = coslon * _x1 - sinlon * _y1 _y2 = sinlon * _x1 + coslon * _y1 _z2 = _z1 m = bovyc.XYZ_to_lbd(_x2, _y2, _z2, degree=degree) phi2, theta2, Rgal2 = m.T if center and dlon: cphi, ctheta = center dist = (1. / f) * np.arccos( np.sin(theta2 * f) * np.sin(ctheta * f) + np.cos(theta2 * f) * np.cos(ctheta * f) * np.cos(f * (phi2 - cphi))) mask = dist <= dlon / 2. phi2, theta2 = phi2[mask], theta2[mask] return (phi2, theta2)
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)