def setphi(self, phi): """ NAME: setphi PURPOSE: set initial azimuth INPUT: phi - desired azimuth OUTPUT: (none) HISTORY: 2010-08-01 - Written - Bovy (NYU) BUGS: Should perform check that this orbit has phi """ if len(self.vxvv) == 2: raise AttributeError("One-dimensional orbit has no azimuth") elif len(self.vxvv) == 3: #Upgrade vxvv = [self.vxvv[0], self.vxvv[1], self.vxvv[2], phi] self.vxvv = vxvv self._orb = planarROrbit(vxvv=vxvv) elif len(self.vxvv) == 4: self.vxvv[-1] = phi self._orb.vxvv[-1] = phi elif len(self.vxvv) == 5: #Upgrade vxvv = [ self.vxvv[0], self.vxvv[1], self.vxvv[2], self.vxvv[3], self.vxvv[4], phi ] self.vxvv = vxvv self._orb = FullOrbit(vxvv=vxvv) elif len(self.vxvv) == 6: self.vxvv[-1] = phi self._orb.vxvv[-1] = phi
def setphi(self,phi): """ NAME: setphi PURPOSE: set initial azimuth INPUT: phi - desired azimuth OUTPUT: (none) HISTORY: 2010-08-01 - Written - Bovy (NYU) BUGS: Should perform check that this orbit has phi """ if len(self.vxvv) == 2: raise AttributeError("One-dimensional orbit has no azimuth") elif len(self.vxvv) == 3: #Upgrade vxvv= [self.vxvv[0],self.vxvv[1],self.vxvv[2],phi] self.vxvv= vxvv self._orb= planarROrbit(vxvv=vxvv) elif len(self.vxvv) == 4: self.vxvv[-1]= phi self._orb.vxvv[-1]= phi elif len(self.vxvv) == 5: #Upgrade vxvv= [self.vxvv[0],self.vxvv[1],self.vxvv[2],self.vxvv[3], self.vxvv[4],phi] self.vxvv= vxvv self._orb= FullOrbit(vxvv=vxvv) elif len(self.vxvv) == 6: self.vxvv[-1]= phi self._orb.vxvv[-1]= phi
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)
class Orbit: """General orbit class representing an orbit""" 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 setphi(self,phi): """ NAME: setphi PURPOSE: set initial azimuth INPUT: phi - desired azimuth OUTPUT: (none) HISTORY: 2010-08-01 - Written - Bovy (NYU) BUGS: Should perform check that this orbit has phi """ if len(self.vxvv) == 2: raise AttributeError("One-dimensional orbit has no azimuth") elif len(self.vxvv) == 3: #Upgrade vxvv= [self.vxvv[0],self.vxvv[1],self.vxvv[2],phi] self.vxvv= vxvv self._orb= planarROrbit(vxvv=vxvv) elif len(self.vxvv) == 4: self.vxvv[-1]= phi self._orb.vxvv[-1]= phi elif len(self.vxvv) == 5: #Upgrade vxvv= [self.vxvv[0],self.vxvv[1],self.vxvv[2],self.vxvv[3], self.vxvv[4],phi] self.vxvv= vxvv self._orb= FullOrbit(vxvv=vxvv) elif len(self.vxvv) == 6: self.vxvv[-1]= phi self._orb.vxvv[-1]= phi def dim(self): """ NAME: dim PURPOSE: return the dimension of the problem INPUT: (none) OUTPUT: dimension HISTORY: 2011-02-03 - Written - Bovy (NYU) """ if len(self.vxvv) == 2: return 1 elif len(self.vxvv) == 3 or len(self.vxvv) == 4: return 2 elif len(self.vxvv) == 5 or len(self.vxvv) == 6: return 3 def integrate(self,t,pot,method='leapfrog_c'): """ NAME: integrate PURPOSE: integrate the orbit INPUT: t - list of times at which to output (0 has to be in this!) pot - potential instance or list of instances method= 'odeint' for scipy's odeint or 'leapfrog' for a simple leapfrog implementation OUTPUT: (none) (get the actual orbit using getOrbit() HISTORY: 2010-07-10 - Written - Bovy (NYU) """ self._orb.integrate(t,pot,method=method) def integrateBC(self,pot,bc=_zEqZeroBC,method='odeint'): """ NAME: integrateBC PURPOSE: integrate the orbit subject to a final boundary condition INPUT: pot - potential instance or list of instances bc= boundary condition, takes array of phase-space position (in the manner that is relevant to the type of Orbit) and outputs the condition that should be zero; default: z=0 method= 'odeint' for scipy's odeint integrator, 'leapfrog' for a simple symplectic integrator OUTPUT: (Another Orbit instance,time at which BC is reached) HISTORY: 2011-09-30 """ o,tout= self._orb.integrateBC(pot,bc=bc,method=method) return (Orbit(vxvv=o[1,:]),tout) def reverse(self): """ NAME: reverse PURPOSE: reverse an already integrated orbit (that is, make it go from end to beginning in t=0 to tend) INPUT: (none) OUTPUT: (none) HISTORY: 2011-04-13 - Written - Bovy (NYU) """ if hasattr(self,'_orbInterp'): delattr(self,'_orbInterp') if hasattr(self,'rs'): delattr(self,'rs') sortindx = range(len(self._orb.t)) sortindx.sort(lambda x,y: cmp(self._orb.t[x],self._orb.t[y]), reverse=True) for ii in range(self._orb.orbit.shape[1]): self._orb.orbit[:,ii]= self._orb.orbit[sortindx,ii] return None def getOrbit(self): """ NAME: getOrbit PURPOSE: return a previously calculated orbit INPUT: (none) OUTPUT: array orbit[nt,nd] HISTORY: 2010-07-10 - Written - Bovy (NYU) """ return self._orb.getOrbit() def E(self,*args,**kwargs): """ NAME: E PURPOSE: calculate the energy INPUT: t - (optional) time at which to get the radius pot= Potential instance or list of such instances OUTPUT: energy HISTORY: 2010-09-15 - Written - Bovy (NYU) """ return self._orb.E(*args,**kwargs) def L(self,*args,**kwargs): """ NAME: L PURPOSE: calculate the angular momentum at time t INPUT: t - (optional) time at which to get the radius OUTPUT: angular momentum HISTORY: 2010-09-15 - Written - Bovy (NYU) """ return self._orb.L(*args,**kwargs) def Jacobi(self,*args,**kwargs): """ NAME: Jacobi PURPOSE: calculate the Jacobi integral E - Omega L INPUT: t - (optional) time at which to get the radius OmegaP= pattern speed pot= potential instance or list of such instances OUTPUT: Jacobi integral HISTORY: 2011-04-18 - Written - Bovy (NYU) """ return self._orb.Jacobi(*args,**kwargs) def e(self,analytic=False,pot=None): """ NAME: e PURPOSE: calculate the eccentricity INPUT: analytic - compute this analytically pot - potential to use for analytical calculation OUTPUT: eccentricity HISTORY: 2010-09-15 - Written - Bovy (NYU) """ return self._orb.e(analytic=analytic,pot=pot) def rap(self,analytic=False,pot=None): """ NAME: rap PURPOSE: calculate the apocenter radius INPUT: analytic - compute this analytically pot - potential to use for analytical calculation OUTPUT: R_ap HISTORY: 2010-09-20 - Written - Bovy (NYU) """ return self._orb.rap(analytic=analytic,pot=pot) def rperi(self,analytic=False,pot=None): """ NAME: rperi PURPOSE: calculate the pericenter radius INPUT: analytic - compute this analytically pot - potential to use for analytical calculation OUTPUT: R_peri HISTORY: 2010-09-20 - Written - Bovy (NYU) """ return self._orb.rperi(analytic=analytic,pot=pot) def zmax(self,analytic=False,pot=None): """ NAME: zmax PURPOSE: calculate the maximum vertical height INPUT: analytic - compute this analytically pot - potential to use for analytical calculation OUTPUT: Z_max HISTORY: 2010-09-20 - Written - Bovy (NYU) """ return self._orb.zmax(analytic=analytic,pot=pot) def wp(self,pot=None): """ NAME: wp PURPOSE: calculate the azimuthal angle INPUT: pot - potential OUTPUT: wp HISTORY: 2010-11-30 - Written - Bovy (NYU) """ return self._orb.wp(pot=pot) def jr(self,pot=None,**kwargs): """ NAME: jr PURPOSE: calculate the radial action INPUT: pot - potential +scipy.integrate.quadrature keywords OUTPUT: jr HISTORY: 2010-11-30 - Written - Bovy (NYU) """ self._orb._setupaA(pot=pot) return self._orb._aA.JR(**kwargs) def jp(self,pot=None,**kwargs): """ NAME: jp PURPOSE: calculate the azimuthal action INPUT: pot - potential +scipy.integrate.quadrature keywords OUTPUT: jp HISTORY: 2010-11-30 - Written - Bovy (NYU) """ self._orb._setupaA(pot=pot) return self._orb._aA.Jphi(**kwargs) def jz(self,pot=None,**kwargs): """ NAME: jz PURPOSE: calculate the vertical action INPUT: pot - potential +scipy.integrate.quadrature keywords OUTPUT: jz HISTORY: 2012-06-01 - Written - Bovy (IAS) """ self._orb._setupaA(pot=pot) return self._orb._aA.Jz(**kwargs) def wr(self,pot=None,**kwargs): """ NAME: wr PURPOSE: calculate the radial angle INPUT: pot - potential +scipy.integrate.quadrature keywords OUTPUT: wr HISTORY: 2010-11-30 - Written - Bovy (NYU) """ self._orb._setupaA(pot=pot) return self._orb._aA.angleR(**kwargs) def wz(self,pot=None,**kwargs): """ NAME: wz PURPOSE: calculate the vertical angle INPUT: pot - potential +scipy.integrate.quadrature keywords OUTPUT: wz HISTORY: 2012-06-01 - Written - Bovy (IAS) """ self._orb._setupaA(pot=pot) return self._orb._aA.anglez(**kwargs) def Tr(self,pot=None,**kwargs): """ NAME: Tr PURPOSE: calculate the radial period INPUT: pot - potential +scipy.integrate.quadrature keywords OUTPUT: Tr HISTORY: 2010-11-30 - Written - Bovy (NYU) """ self._orb._setupaA(pot=pot) return self._orb._aA.TR(**kwargs) def Tp(self,pot=None,**kwargs): """ NAME: Tp PURPOSE: calculate the radial period INPUT: pot - potential +scipy.integrate.quadrature keywords OUTPUT: Tp HISTORY: 2010-11-30 - Written - Bovy (NYU) """ self._orb._setupaA(pot=pot) return self._orb._aA.Tphi(**kwargs) def TrTp(self,pot=None,**kwargs): """ NAME: TrTp PURPOSE: the 'ratio' between the radial and azimuthal period Tr/Tphi*pi INPUT: pot - potential +scipy.integrate.quadrature keywords OUTPUT: Tr/Tp*pi HISTORY: 2010-11-30 - Written - Bovy (NYU) """ self._orb._setupaA(pot=pot) return self._orb._aA.I(**kwargs) def Tz(self,pot=None,**kwargs): """ NAME: Tz PURPOSE: calculate the vertical period INPUT: pot - potential +scipy.integrate.quadrature keywords OUTPUT: Tz HISTORY: 2012-06-01 - Written - Bovy (IAS) """ self._orb._setupaA(pot=pot) return self._orb._aA.Tz(**kwargs) def R(self,*args,**kwargs): """ NAME: R PURPOSE: return cylindrical radius at time t INPUT: t - (optional) time at which to get the radius OUTPUT: R(t) HISTORY: 2010-09-21 - Written - Bovy (NYU) """ return self._orb.R(*args,**kwargs) def vR(self,*args,**kwargs): """ NAME: vR PURPOSE: return radial velocity at time t INPUT: t - (optional) time at which to get the radial velocity OUTPUT: vR(t) HISTORY: 2010-09-21 - Written - Bovy (NYU) """ return self._orb.vR(*args,**kwargs) def vT(self,*args,**kwargs): """ NAME: vT PURPOSE: return tangential velocity at time t INPUT: t - (optional) time at which to get the tangential velocity OUTPUT: vT(t) HISTORY: 2010-09-21 - Written - Bovy (NYU) """ return self._orb.vT(*args,**kwargs) def z(self,*args,**kwargs): """ NAME: z PURPOSE: return vertical height INPUT: t - (optional) time at which to get the vertical height OUTPUT: z(t) HISTORY: 2010-09-21 - Written - Bovy (NYU) """ return self._orb.z(*args,**kwargs) def vz(self,*args,**kwargs): """ NAME: vz PURPOSE: return vertical velocity INPUT: t - (optional) time at which to get the vertical velocity OUTPUT: vz(t) HISTORY: 2010-09-21 - Written - Bovy (NYU) """ return self._orb.vz(*args,**kwargs) def phi(self,*args,**kwargs): """ NAME: phi PURPOSE: return azimuth INPUT: t - (optional) time at which to get the azimuth OUTPUT: phi(t) HISTORY: 2010-09-21 - Written - Bovy (NYU) """ return self._orb.phi(*args,**kwargs) def vphi(self,*args,**kwargs): """ NAME: vphi PURPOSE: return angular velocity INPUT: t - (optional) time at which to get the angular velocity OUTPUT: vphi(t) HISTORY: 2010-09-21 - Written - Bovy (NYU) """ return self._orb.vphi(*args,**kwargs) def x(self,*args,**kwargs): """ NAME: x PURPOSE: return x INPUT: t - (optional) time at which to get x OUTPUT: x(t) HISTORY: 2010-09-21 - Written - Bovy (NYU) """ return self._orb.x(*args,**kwargs) def y(self,*args,**kwargs): """ NAME: y PURPOSE: return y INPUT: t - (optional) time at which to get y OUTPUT: y(t) HISTORY: 2010-09-21 - Written - Bovy (NYU) """ return self._orb.y(*args,**kwargs) def vx(self,*args,**kwargs): """ NAME: vx PURPOSE: return x velocity at time t INPUT: t - (optional) time at which to get the velocity OUTPUT: vx(t) HISTORY: 2010-11-30 - Written - Bovy (NYU) """ return self._orb.vx(*args,**kwargs) def vy(self,*args,**kwargs): """ NAME: vy PURPOSE: return y velocity at time t INPUT: t - (optional) time at which to get the velocity OUTPUT: vy(t) HISTORY: 2010-11-30 - Written - Bovy (NYU) """ return self._orb.vy(*args,**kwargs) def ra(self,*args,**kwargs): """ NAME: ra PURPOSE: return the right ascension INPUT: t - (optional) time at which to get ra obs=[X,Y,Z] - (optional) position of observer (in kpc) (default=[8.5,0.,0.]) OR Orbit object that corresponds to the orbit of the observer ro= distance in kpc corresponding to R=1. (default: 8.5) OUTPUT: ra(t) HISTORY: 2011-02-23 - Written - Bovy (NYU) """ return self._orb.ra(*args,**kwargs) def dec(self,*args,**kwargs): """ NAME: dec PURPOSE: return the declination INPUT: t - (optional) time at which to get dec obs=[X,Y,Z] - (optional) position of observer (in kpc) (default=[8.5,0.,0.]) OR Orbit object that corresponds to the orbit of the observer ro= distance in kpc corresponding to R=1. (default: 8.5) OUTPUT: dec(t) HISTORY: 2011-02-23 - Written - Bovy (NYU) """ return self._orb.dec(*args,**kwargs) def ll(self,*args,**kwargs): """ NAME: ll PURPOSE: return Galactic longitude INPUT: t - (optional) time at which to get ll obs=[X,Y,Z] - (optional) position of observer (in kpc) (default=[8.5,0.,0.]) OR Orbit object that corresponds to the orbit of the observer ro= distance in kpc corresponding to R=1. (default: 8.5) OUTPUT: l(t) HISTORY: 2011-02-23 - Written - Bovy (NYU) """ return self._orb.ll(*args,**kwargs) def bb(self,*args,**kwargs): """ NAME: bb PURPOSE: return Galactic latitude INPUT: t - (optional) time at which to get bb obs=[X,Y,Z] - (optional) position of observer (in kpc) (default=[8.5,0.,0.]) OR Orbit object that corresponds to the orbit of the observer ro= distance in kpc corresponding to R=1. (default: 8.5) OUTPUT: b(t) HISTORY: 2011-02-23 - Written - Bovy (NYU) """ return self._orb.bb(*args,**kwargs) def dist(self,*args,**kwargs): """ NAME: dist PURPOSE: return distance from the observer INPUT: t - (optional) time at which to get dist obs=[X,Y,Z] - (optional) position of observer (in kpc) (default=[8.5,0.,0.]) OR Orbit object that corresponds to the orbit of the observer ro= distance in kpc corresponding to R=1. (default: 8.5) OUTPUT: dist(t) in kpc HISTORY: 2011-02-23 - Written - Bovy (NYU) """ return self._orb.dist(*args,**kwargs) def pmra(self,*args,**kwargs): """ NAME: pmra PURPOSE: return proper motion in right ascension (in mas/yr) INPUT: t - (optional) time at which to get pmra obs=[X,Y,Z,vx,vy,vz] - (optional) position and velocity of observer (in kpc and km/s) (default=[8.5,0.,0.,0.,235.,0.]) OR Orbit object that corresponds to the orbit of the observer ro= distance in kpc corresponding to R=1. (default: 8.5) vo= velocity in km/s corresponding to v=1. (default: 235.) OUTPUT: pm_ra(t) HISTORY: 2011-02-24 - Written - Bovy (NYU) """ return self._orb.pmra(*args,**kwargs) def pmdec(self,*args,**kwargs): """ NAME: pmdec PURPOSE: return proper motion in declination (in mas/yr) INPUT: t - (optional) time at which to get pmdec obs=[X,Y,Z,vx,vy,vz] - (optional) position and velocity of observer (in kpc and km/s) (default=[8.5,0.,0.,0.,235.,0.]) OR Orbit object that corresponds to the orbit of the observer ro= distance in kpc corresponding to R=1. (default: 8.5) vo= velocity in km/s corresponding to v=1. (default: 235.) OUTPUT: pm_dec(t) HISTORY: 2011-02-24 - Written - Bovy (NYU) """ return self._orb.pmdec(*args,**kwargs) def pmll(self,*args,**kwargs): """ NAME: pmll PURPOSE: return proper motion in Galactic longitude (in mas/yr) INPUT: t - (optional) time at which to get pmll obs=[X,Y,Z,vx,vy,vz] - (optional) position and velocity of observer (in kpc and km/s) (default=[8.5,0.,0.,0.,235.,0.]) OR Orbit object that corresponds to the orbit of the observer ro= distance in kpc corresponding to R=1. (default: 8.5) vo= velocity in km/s corresponding to v=1. (default: 235.) OUTPUT: pm_l(t) HISTORY: 2011-02-24 - Written - Bovy (NYU) """ return self._orb.pmll(*args,**kwargs) def pmbb(self,*args,**kwargs): """ NAME: pmbb PURPOSE: return proper motion in Galactic latitude (in mas/yr) INPUT: t - (optional) time at which to get pmbb obs=[X,Y,Z,vx,vy,vz] - (optional) position and velocity of observer (in kpc and km/s) (default=[8.5,0.,0.,0.,235.,0.]) OR Orbit object that corresponds to the orbit of the observer ro= distance in kpc corresponding to R=1. (default: 8.5) vo= velocity in km/s corresponding to v=1. (default: 235.) OUTPUT: pm_b(t) HISTORY: 2011-02-24 - Written - Bovy (NYU) """ return self._orb.pmbb(*args,**kwargs) def vlos(self,*args,**kwargs): """ NAME: vlos PURPOSE: return the line-of-sight velocity (in km/s) INPUT: t - (optional) time at which to get vlos obs=[X,Y,Z,vx,vy,vz] - (optional) position and velocity of observer (in kpc and km/s) (default=[8.5,0.,0.,0.,235.,0.]) OR Orbit object that corresponds to the orbit of the observer ro= distance in kpc corresponding to R=1. (default: 8.5) vo= velocity in km/s corresponding to v=1. (default: 235.) OUTPUT: vlos(t) HISTORY: 2011-02-24 - Written - Bovy (NYU) """ return self._orb.vlos(*args,**kwargs) def vra(self,*args,**kwargs): """ NAME: vra PURPOSE: return velocity in right ascension (km/s) INPUT: t - (optional) time at which to get pmra obs=[X,Y,Z,vx,vy,vz] - (optional) position and velocity of observer (in kpc and km/s) (default=[8.5,0.,0.,0.,235.,0.]) OR Orbit object that corresponds to the orbit of the observer ro= distance in kpc corresponding to R=1. (default: 8.5) vo= velocity in km/s corresponding to v=1. (default: 235.) OUTPUT: v_ra(t) in km/s HISTORY: 2011-03-27 - Written - Bovy (NYU) """ return self._orb.dist(*args,**kwargs)*_K*\ self._orb.pmra(*args,**kwargs) def vdec(self,*args,**kwargs): """ NAME: vdec PURPOSE: return velocity in declination (km/s) INPUT: t - (optional) time at which to get pmdec obs=[X,Y,Z,vx,vy,vz] - (optional) position and velocity of observer (in kpc and km/s) (default=[8.5,0.,0.,0.,235.,0.]) OR Orbit object that corresponds to the orbit of the observer ro= distance in kpc corresponding to R=1. (default: 8.5) vo= velocity in km/s corresponding to v=1. (default: 235.) OUTPUT: v_dec(t) in km/s HISTORY: 2011-03-27 - Written - Bovy (NYU) """ return self._orb.dist(*args,**kwargs)*_K*\ self._orb.pmdec(*args,**kwargs) def vll(self,*args,**kwargs): """ NAME: vll PURPOSE: return the velocity in Galactic longitude (km/s) INPUT: t - (optional) time at which to get pmll obs=[X,Y,Z,vx,vy,vz] - (optional) position and velocity of observer (in kpc and km/s) (default=[8.5,0.,0.,0.,235.,0.]) OR Orbit object that corresponds to the orbit of the observer ro= distance in kpc corresponding to R=1. (default: 8.5) vo= velocity in km/s corresponding to v=1. (default: 235.) OUTPUT: v_l(t) in km/s HISTORY: 2011-03-27 - Written - Bovy (NYU) """ return self._orb.dist(*args,**kwargs)*_K*\ self._orb.pmll(*args,**kwargs) def vbb(self,*args,**kwargs): """ NAME: vbb PURPOSE: return velocity in Galactic latitude (km/s) INPUT: t - (optional) time at which to get pmbb obs=[X,Y,Z,vx,vy,vz] - (optional) position and velocity of observer (in kpc and km/s) (default=[8.5,0.,0.,0.,235.,0.]) OR Orbit object that corresponds to the orbit of the observer ro= distance in kpc corresponding to R=1. (default: 8.5) vo= velocity in km/s corresponding to v=1. (default: 235.) OUTPUT: v_b(t) in km/s HISTORY: 2011-02-24 - Written - Bovy (NYU) """ return self._orb.dist(*args,**kwargs)*_K*\ self._orb.pmbb(*args,**kwargs) def helioX(self,*args,**kwargs): """ NAME: helioX PURPOSE: return Heliocentric Galactic rectangular x-coordinate (aka "X") INPUT: t - (optional) time at which to get X obs=[X,Y,Z] - (optional) position and velocity of observer (in kpc and km/s) (default=[8.5,0.,0.,0.,235.,0.]) OR Orbit object that corresponds to the orbit of the observer ro= distance in kpc corresponding to R=1. (default: 8.5) OUTPUT: helioX(t) HISTORY: 2011-02-24 - Written - Bovy (NYU) """ return self._orb.helioX(*args,**kwargs) def helioY(self,*args,**kwargs): """ NAME: helioY PURPOSE: return Heliocentric Galactic rectangular y-coordinate (aka "Y") INPUT: t - (optional) time at which to get Y obs=[X,Y,Z] - (optional) position and velocity of observer (in kpc and km/s) (default=[8.5,0.,0.,0.,235.,0.]) OR Orbit object that corresponds to the orbit of the observer ro= distance in kpc corresponding to R=1. (default: 8.5) OUTPUT: helioY(t) HISTORY: 2011-02-24 - Written - Bovy (NYU) """ return self._orb.helioY(*args,**kwargs) def helioZ(self,*args,**kwargs): """ NAME: helioZ PURPOSE: return Heliocentric Galactic rectangular z-coordinate (aka "Z") INPUT: t - (optional) time at which to get Z obs=[X,Y,Z] - (optional) position and velocity of observer (in kpc and km/s) (default=[8.5,0.,0.,0.,235.,0.]) OR Orbit object that corresponds to the orbit of the observer ro= distance in kpc corresponding to R=1. (default: 8.5) OUTPUT: helioZ(t) HISTORY: 2011-02-24 - Written - Bovy (NYU) """ return self._orb.helioZ(*args,**kwargs) def U(self,*args,**kwargs): """ NAME: U PURPOSE: return Heliocentric Galactic rectangular x-velocity (aka "U") INPUT: t - (optional) time at which to get U obs=[X,Y,Z,vx,vy,vz] - (optional) position and velocity of observer (in kpc and km/s) (default=[8.5,0.,0.,0.,235.,0.]) OR Orbit object that corresponds to the orbit of the observer ro= distance in kpc corresponding to R=1. (default: 8.5) vo= velocity in km/s corresponding to v=1. (default: 235.) OUTPUT: U(t) HISTORY: 2011-02-24 - Written - Bovy (NYU) """ return self._orb.U(*args,**kwargs) def V(self,*args,**kwargs): """ NAME: V PURPOSE: return Heliocentric Galactic rectangular y-velocity (aka "V") INPUT: t - (optional) time at which to get U obs=[X,Y,Z,vx,vy,vz] - (optional) position and velocity of observer (in kpc and km/s) (default=[8.5,0.,0.,0.,235.,0.]) OR Orbit object that corresponds to the orbit of the observer ro= distance in kpc corresponding to R=1. (default: 8.5) vo= velocity in km/s corresponding to v=1. (default: 235.) OUTPUT: V(t) HISTORY: 2011-02-24 - Written - Bovy (NYU) """ return self._orb.V(*args,**kwargs) def W(self,*args,**kwargs): """ NAME: W PURPOSE: return Heliocentric Galactic rectangular z-velocity (aka "W") INPUT: t - (optional) time at which to get W obs=[X,Y,Z,vx,vy,vz] - (optional) position and velocity of observer (in kpc and km/s) (default=[8.5,0.,0.,0.,235.,0.]) OR Orbit object that corresponds to the orbit of the observer ro= distance in kpc corresponding to R=1. (default: 8.5) vo= velocity in km/s corresponding to v=1. (default: 235.) OUTPUT: W(t) HISTORY: 2011-02-24 - Written - Bovy (NYU) """ return self._orb.W(*args,**kwargs) def __call__(self,*args,**kwargs): """ NAME: __call__ PURPOSE: return the orbit at time t INPUT: t - desired time rect - if true, return rectangular coordinates OUTPUT: an Orbit instance with initial condition set to the phase-space at time t or list of Orbit instances if multiple times are given HISTORY: 2010-07-10 - Written - Bovy (NYU) """ thiso= self._orb(*args,**kwargs) if len(thiso.shape) == 1: return Orbit(vxvv=thiso) else: return [Orbit(vxvv=thiso[:,ii]) for ii in range(thiso.shape[1])] def plot(self,*args,**kwargs): """ NAME: plot PURPOSE: plot a previously calculated orbit (with reasonable defaults) INPUT: d1= first dimension to plot ('x', 'y', 'R', 'vR', 'vT', 'z', 'vz', ...) d2= second dimension to plot matplotlib.plot inputs+bovy_plot.plot inputs OUTPUT: sends plot to output device HISTORY: 2010-07-10 - Written - Bovy (NYU) """ self._orb.plot(*args,**kwargs) def plot3d(self,*args,**kwargs): """ NAME: plot3d PURPOSE: plot 3D aspects of an Orbit INPUT: bovy_plot3d args and kwargs OUTPUT: plot HISTORY: 2010-07-26 - Written - Bovy (NYU) 2010-09-22 - Adapted to more general framework - Bovy (NYU) 2010-01-08 - Adapted to 3D - Bovy (NYU) """ self._orb.plot3d(*args,**kwargs) def plotE(self,*args,**kwargs): """ NAME: plotE PURPOSE: plot E(.) along the orbit INPUT: pot= - Potential instance or list of instances in which the orbit was integrated d1= - plot Ez vs d1: e.g., 't', 'z', 'R', 'vR', 'vT', 'vz' +bovy_plot.bovy_plot inputs OUTPUT: figure to output device HISTORY: 2010-07-10 - Written - Bovy (NYU) """ self._orb.plotE(*args,**kwargs) def plotEz(self,*args,**kwargs): """ NAME: plotEz PURPOSE: plot E_z(.) along the orbit INPUT: po= - Potential instance or list of instances in which the orbit was integrated d1= - plot Ez vs d1: e.g., 't', 'z', 'R' +bovy_plot.bovy_plot inputs OUTPUT: figure to output device HISTORY: 2010-07-10 - Written - Bovy (NYU) """ self._orb.plotEz(*args,**kwargs) def plotEzJz(self,*args,**kwargs): """ NAME: plotEzJzt PURPOSE: plot E_z(t)/sqrt(dens(R)) along the orbit INPUT: pot - Potential instance or list of instances in which the orbit was integrated d1= - plot Ez vs d1: e.g., 't', 'z', 'R' +bovy_plot.bovy_plot inputs OUTPUT: figure to output device HISTORY: 2010-08-08 - Written - Bovy (NYU) """ self._orb.plotEzJz(*args,**kwargs) def plotJacobi(self,*args,**kwargs): """ NAME: plotJacobi PURPOSE: plot the Jacobi integral along the orbit INPUT: OmegaP= pattern speed pot= - Potential instance or list of instances in which the orbit was integrated d1= - plot Ez vs d1: e.g., 't', 'z', 'R', 'vR', 'vT', 'vz' +bovy_plot.bovy_plot inputs OUTPUT: figure to output device HISTORY: 2011-10-10 - Written - Bovy (IAS) """ self._orb.plotJacobi(*args,**kwargs) def plotR(self,*args,**kwargs): """ NAME: plotR PURPOSE: plot R(.) along the orbit INPUT: d1= plot vs d1: e.g., 't', 'z', 'R' bovy_plot.bovy_plot inputs OUTPUT: figure to output device HISTORY: 2010-07-10 - Written - Bovy (NYU) """ self._orb.plotR(*args,**kwargs) def plotz(self,*args,**kwargs): """ NAME: plotz PURPOSE: plot z(.) along the orbit INPUT: d1= plot vs d1: e.g., 't', 'z', 'R' bovy_plot.bovy_plot inputs OUTPUT: figure to output device HISTORY: 2010-07-10 - Written - Bovy (NYU) """ self._orb.plotz(*args,**kwargs) def plotvR(self,*args,**kwargs): """ NAME: plotvR PURPOSE: plot vR(.) along the orbit INPUT: d1= plot vs d1: e.g., 't', 'z', 'R' bovy_plot.bovy_plot inputs OUTPUT: figure to output device HISTORY: 2010-07-10 - Written - Bovy (NYU) """ self._orb.plotvR(*args,**kwargs) def plotvT(self,*args,**kwargs): """ NAME: plotvT PURPOSE: plot vT(.) along the orbit INPUT: d1= plot vs d1: e.g., 't', 'z', 'R' bovy_plot.bovy_plot inputs OUTPUT: figure to output device HISTORY: 2010-07-10 - Written - Bovy (NYU) """ self._orb.plotvT(*args,**kwargs) def plotphi(self,*args,**kwargs): """ NAME: plotphi PURPOSE: plot \phi(.) along the orbit INPUT: d1= plot vs d1: e.g., 't', 'z', 'R' bovy_plot.bovy_plot inputs OUTPUT: figure to output device HISTORY: 2010-07-10 - Written - Bovy (NYU) """ self._orb.plotphi(*args,**kwargs) def plotvz(self,*args,**kwargs): """ NAME: plotvz PURPOSE: plot vz(.) along the orbit INPUT: d1= plot vs d1: e.g., 't', 'z', 'R' bovy_plot.bovy_plot inputs OUTPUT: figure to output device HISTORY: 2010-07-10 - Written - Bovy (NYU) """ self._orb.plotvz(*args,**kwargs) def plotx(self,*args,**kwargs): """ NAME: plotx PURPOSE: plot a one-dimensional orbit position INPUT: d1= plot vs d1: e.g., 't', 'z', 'R' bovy_plot.bovy_plot inputs OUTPUT: figure to output device HISTORY: 2010-07-21 - Written - Bovy (NYU) """ self._orb.plotx(*args,**kwargs) def plotvx(self,*args,**kwargs): """ NAME: plotvx PURPOSE: plot a one-dimensional orbit velocity INPUT: d1= plot vs d1: e.g., 't', 'z', 'R' bovy_plot.bovy_plot inputs OUTPUT: figure to output device HISTORY: 2010-07-21 - Written - Bovy (NYU) """ self._orb.plotvx(*args,**kwargs) def ploty(self,*args,**kwargs): """ NAME: ploty PURPOSE: plot a one-dimensional orbit position INPUT: d1= plot vs d1: e.g., 't', 'z', 'R' bovy_plot.bovy_plot inputs OUTPUT: figure to output device HISTORY: 2010-07-21 - Written - Bovy (NYU) """ self._orb.ploty(*args,**kwargs) def plotvy(self,*args,**kwargs): """ NAME: plotvy PURPOSE: plot a one-dimensional orbit velocity INPUT: d1= plot vs d1: e.g., 't', 'z', 'R' bovy_plot.bovy_plot inputs OUTPUT: figure to output device HISTORY: 2010-07-21 - Written - Bovy (NYU) """ self._orb.plotvy(*args,**kwargs) def toPlanar(self): """ NAME: toPlanar PURPOSE: convert a 3D orbit into a 2D orbit INPUT: (none) OUTPUT: planar Orbit HISTORY: 2010-11-30 - Written - Bovy (NYU) """ if len(self.vxvv) == 6: vxvv= [self.vxvv[0],self.vxvv[1],self.vxvv[2],self.vxvv[5]] elif len(self.vxvv) == 5: vxvv= [self.vxvv[0],self.vxvv[1],self.vxvv[2]] else: raise AttributeError("planar or linear Orbits do not have the toPlanar attribute") return Orbit(vxvv=vxvv) def toLinear(self): """ NAME: toLinear PURPOSE: convert a 3D orbit into a 1D orbit (z) INPUT: (none) OUTPUT: linear Orbit HISTORY: 2010-11-30 - Written - Bovy (NYU) """ if len(self.vxvv) == 6 or len(self.vxvv) == 5: vxvv= [self.vxvv[3],self.vxvv[4]] else: raise AttributeError("planar or linear Orbits do not have the toPlanar attribute") return Orbit(vxvv=vxvv) def __add__(self,linOrb): """ NAME: __add__ PURPOSE: add a linear orbit and a planar orbit to make a 3D orbit INPUT: linear or plane orbit instance OUTPUT: 3D orbit HISTORY: 2010-07-21 - Written - Bovy (NYU) """ if (not (isinstance(self._orb,planarROrbit) and isinstance(linOrb._orb,linearOrbit)) and not (isinstance(self._orb,linearOrbit) and isinstance(linOrb._orb,planarROrbit))): raise AttributeError("Only planarROrbit+linearOrbit is supported") if isinstance(self._orb,planarROrbit): return Orbit(vxvv=[self._orb.vxvv[0],self._orb.vxvv[1], self._orb.vxvv[2], linOrb._orb.vxvv[0],linOrb._orb.vxvv[1]]) else: return Orbit(vxvv=[linOrb._orb.vxvv[0],linOrb._orb.vxvv[1], linOrb._orb.vxvv[2], self._orb.vxvv[0],self._orb.vxvv[1]]) #4 pickling def __getinitargs__(self): return (self.vxvv,) def __getstate__(self): return self.vxvv def __setstate__(self,state): self.vxvv= state
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)
class Orbit: """General orbit class representing an orbit""" 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 setphi(self, phi): """ NAME: setphi PURPOSE: set initial azimuth INPUT: phi - desired azimuth OUTPUT: (none) HISTORY: 2010-08-01 - Written - Bovy (NYU) BUGS: Should perform check that this orbit has phi """ if len(self.vxvv) == 2: raise AttributeError("One-dimensional orbit has no azimuth") elif len(self.vxvv) == 3: #Upgrade vxvv = [self.vxvv[0], self.vxvv[1], self.vxvv[2], phi] self.vxvv = vxvv self._orb = planarROrbit(vxvv=vxvv) elif len(self.vxvv) == 4: self.vxvv[-1] = phi self._orb.vxvv[-1] = phi elif len(self.vxvv) == 5: #Upgrade vxvv = [ self.vxvv[0], self.vxvv[1], self.vxvv[2], self.vxvv[3], self.vxvv[4], phi ] self.vxvv = vxvv self._orb = FullOrbit(vxvv=vxvv) elif len(self.vxvv) == 6: self.vxvv[-1] = phi self._orb.vxvv[-1] = phi def dim(self): """ NAME: dim PURPOSE: return the dimension of the problem INPUT: (none) OUTPUT: dimension HISTORY: 2011-02-03 - Written - Bovy (NYU) """ if len(self.vxvv) == 2: return 1 elif len(self.vxvv) == 3 or len(self.vxvv) == 4: return 2 elif len(self.vxvv) == 5 or len(self.vxvv) == 6: return 3 def integrate(self, t, pot, method='leapfrog_c'): """ NAME: integrate PURPOSE: integrate the orbit INPUT: t - list of times at which to output (0 has to be in this!) pot - potential instance or list of instances method= 'odeint' for scipy's odeint or 'leapfrog' for a simple leapfrog implementation OUTPUT: (none) (get the actual orbit using getOrbit() HISTORY: 2010-07-10 - Written - Bovy (NYU) """ self._orb.integrate(t, pot, method=method) def integrateBC(self, pot, bc=_zEqZeroBC, method='odeint'): """ NAME: integrateBC PURPOSE: integrate the orbit subject to a final boundary condition INPUT: pot - potential instance or list of instances bc= boundary condition, takes array of phase-space position (in the manner that is relevant to the type of Orbit) and outputs the condition that should be zero; default: z=0 method= 'odeint' for scipy's odeint integrator, 'leapfrog' for a simple symplectic integrator OUTPUT: (Another Orbit instance,time at which BC is reached) HISTORY: 2011-09-30 """ o, tout = self._orb.integrateBC(pot, bc=bc, method=method) return (Orbit(vxvv=o[1, :]), tout) def reverse(self): """ NAME: reverse PURPOSE: reverse an already integrated orbit (that is, make it go from end to beginning in t=0 to tend) INPUT: (none) OUTPUT: (none) HISTORY: 2011-04-13 - Written - Bovy (NYU) """ if hasattr(self, '_orbInterp'): delattr(self, '_orbInterp') if hasattr(self, 'rs'): delattr(self, 'rs') sortindx = range(len(self._orb.t)) sortindx.sort(lambda x, y: cmp(self._orb.t[x], self._orb.t[y]), reverse=True) for ii in range(self._orb.orbit.shape[1]): self._orb.orbit[:, ii] = self._orb.orbit[sortindx, ii] return None def getOrbit(self): """ NAME: getOrbit PURPOSE: return a previously calculated orbit INPUT: (none) OUTPUT: array orbit[nt,nd] HISTORY: 2010-07-10 - Written - Bovy (NYU) """ return self._orb.getOrbit() def E(self, *args, **kwargs): """ NAME: E PURPOSE: calculate the energy INPUT: t - (optional) time at which to get the radius pot= Potential instance or list of such instances OUTPUT: energy HISTORY: 2010-09-15 - Written - Bovy (NYU) """ return self._orb.E(*args, **kwargs) def L(self, *args, **kwargs): """ NAME: L PURPOSE: calculate the angular momentum at time t INPUT: t - (optional) time at which to get the radius OUTPUT: angular momentum HISTORY: 2010-09-15 - Written - Bovy (NYU) """ return self._orb.L(*args, **kwargs) def Jacobi(self, *args, **kwargs): """ NAME: Jacobi PURPOSE: calculate the Jacobi integral E - Omega L INPUT: t - (optional) time at which to get the radius OmegaP= pattern speed pot= potential instance or list of such instances OUTPUT: Jacobi integral HISTORY: 2011-04-18 - Written - Bovy (NYU) """ return self._orb.Jacobi(*args, **kwargs) def e(self, analytic=False, pot=None): """ NAME: e PURPOSE: calculate the eccentricity INPUT: analytic - compute this analytically pot - potential to use for analytical calculation OUTPUT: eccentricity HISTORY: 2010-09-15 - Written - Bovy (NYU) """ return self._orb.e(analytic=analytic, pot=pot) def rap(self, analytic=False, pot=None): """ NAME: rap PURPOSE: calculate the apocenter radius INPUT: analytic - compute this analytically pot - potential to use for analytical calculation OUTPUT: R_ap HISTORY: 2010-09-20 - Written - Bovy (NYU) """ return self._orb.rap(analytic=analytic, pot=pot) def rperi(self, analytic=False, pot=None): """ NAME: rperi PURPOSE: calculate the pericenter radius INPUT: analytic - compute this analytically pot - potential to use for analytical calculation OUTPUT: R_peri HISTORY: 2010-09-20 - Written - Bovy (NYU) """ return self._orb.rperi(analytic=analytic, pot=pot) def zmax(self, analytic=False, pot=None): """ NAME: zmax PURPOSE: calculate the maximum vertical height INPUT: analytic - compute this analytically pot - potential to use for analytical calculation OUTPUT: Z_max HISTORY: 2010-09-20 - Written - Bovy (NYU) """ return self._orb.zmax(analytic=analytic, pot=pot) def wp(self, pot=None): """ NAME: wp PURPOSE: calculate the azimuthal angle INPUT: pot - potential OUTPUT: wp HISTORY: 2010-11-30 - Written - Bovy (NYU) """ return self._orb.wp(pot=pot) def jr(self, pot=None, **kwargs): """ NAME: jr PURPOSE: calculate the radial action INPUT: pot - potential +scipy.integrate.quadrature keywords OUTPUT: jr HISTORY: 2010-11-30 - Written - Bovy (NYU) """ self._orb._setupaA(pot=pot) return self._orb._aA.JR(**kwargs) def jp(self, pot=None, **kwargs): """ NAME: jp PURPOSE: calculate the azimuthal action INPUT: pot - potential +scipy.integrate.quadrature keywords OUTPUT: jp HISTORY: 2010-11-30 - Written - Bovy (NYU) """ self._orb._setupaA(pot=pot) return self._orb._aA.Jphi(**kwargs) def jz(self, pot=None, **kwargs): """ NAME: jz PURPOSE: calculate the vertical action INPUT: pot - potential +scipy.integrate.quadrature keywords OUTPUT: jz HISTORY: 2012-06-01 - Written - Bovy (IAS) """ self._orb._setupaA(pot=pot) return self._orb._aA.Jz(**kwargs) def wr(self, pot=None, **kwargs): """ NAME: wr PURPOSE: calculate the radial angle INPUT: pot - potential +scipy.integrate.quadrature keywords OUTPUT: wr HISTORY: 2010-11-30 - Written - Bovy (NYU) """ self._orb._setupaA(pot=pot) return self._orb._aA.angleR(**kwargs) def wz(self, pot=None, **kwargs): """ NAME: wz PURPOSE: calculate the vertical angle INPUT: pot - potential +scipy.integrate.quadrature keywords OUTPUT: wz HISTORY: 2012-06-01 - Written - Bovy (IAS) """ self._orb._setupaA(pot=pot) return self._orb._aA.anglez(**kwargs) def Tr(self, pot=None, **kwargs): """ NAME: Tr PURPOSE: calculate the radial period INPUT: pot - potential +scipy.integrate.quadrature keywords OUTPUT: Tr HISTORY: 2010-11-30 - Written - Bovy (NYU) """ self._orb._setupaA(pot=pot) return self._orb._aA.TR(**kwargs) def Tp(self, pot=None, **kwargs): """ NAME: Tp PURPOSE: calculate the radial period INPUT: pot - potential +scipy.integrate.quadrature keywords OUTPUT: Tp HISTORY: 2010-11-30 - Written - Bovy (NYU) """ self._orb._setupaA(pot=pot) return self._orb._aA.Tphi(**kwargs) def TrTp(self, pot=None, **kwargs): """ NAME: TrTp PURPOSE: the 'ratio' between the radial and azimuthal period Tr/Tphi*pi INPUT: pot - potential +scipy.integrate.quadrature keywords OUTPUT: Tr/Tp*pi HISTORY: 2010-11-30 - Written - Bovy (NYU) """ self._orb._setupaA(pot=pot) return self._orb._aA.I(**kwargs) def Tz(self, pot=None, **kwargs): """ NAME: Tz PURPOSE: calculate the vertical period INPUT: pot - potential +scipy.integrate.quadrature keywords OUTPUT: Tz HISTORY: 2012-06-01 - Written - Bovy (IAS) """ self._orb._setupaA(pot=pot) return self._orb._aA.Tz(**kwargs) def R(self, *args, **kwargs): """ NAME: R PURPOSE: return cylindrical radius at time t INPUT: t - (optional) time at which to get the radius OUTPUT: R(t) HISTORY: 2010-09-21 - Written - Bovy (NYU) """ return self._orb.R(*args, **kwargs) def vR(self, *args, **kwargs): """ NAME: vR PURPOSE: return radial velocity at time t INPUT: t - (optional) time at which to get the radial velocity OUTPUT: vR(t) HISTORY: 2010-09-21 - Written - Bovy (NYU) """ return self._orb.vR(*args, **kwargs) def vT(self, *args, **kwargs): """ NAME: vT PURPOSE: return tangential velocity at time t INPUT: t - (optional) time at which to get the tangential velocity OUTPUT: vT(t) HISTORY: 2010-09-21 - Written - Bovy (NYU) """ return self._orb.vT(*args, **kwargs) def z(self, *args, **kwargs): """ NAME: z PURPOSE: return vertical height INPUT: t - (optional) time at which to get the vertical height OUTPUT: z(t) HISTORY: 2010-09-21 - Written - Bovy (NYU) """ return self._orb.z(*args, **kwargs) def vz(self, *args, **kwargs): """ NAME: vz PURPOSE: return vertical velocity INPUT: t - (optional) time at which to get the vertical velocity OUTPUT: vz(t) HISTORY: 2010-09-21 - Written - Bovy (NYU) """ return self._orb.vz(*args, **kwargs) def phi(self, *args, **kwargs): """ NAME: phi PURPOSE: return azimuth INPUT: t - (optional) time at which to get the azimuth OUTPUT: phi(t) HISTORY: 2010-09-21 - Written - Bovy (NYU) """ return self._orb.phi(*args, **kwargs) def vphi(self, *args, **kwargs): """ NAME: vphi PURPOSE: return angular velocity INPUT: t - (optional) time at which to get the angular velocity OUTPUT: vphi(t) HISTORY: 2010-09-21 - Written - Bovy (NYU) """ return self._orb.vphi(*args, **kwargs) def x(self, *args, **kwargs): """ NAME: x PURPOSE: return x INPUT: t - (optional) time at which to get x OUTPUT: x(t) HISTORY: 2010-09-21 - Written - Bovy (NYU) """ return self._orb.x(*args, **kwargs) def y(self, *args, **kwargs): """ NAME: y PURPOSE: return y INPUT: t - (optional) time at which to get y OUTPUT: y(t) HISTORY: 2010-09-21 - Written - Bovy (NYU) """ return self._orb.y(*args, **kwargs) def vx(self, *args, **kwargs): """ NAME: vx PURPOSE: return x velocity at time t INPUT: t - (optional) time at which to get the velocity OUTPUT: vx(t) HISTORY: 2010-11-30 - Written - Bovy (NYU) """ return self._orb.vx(*args, **kwargs) def vy(self, *args, **kwargs): """ NAME: vy PURPOSE: return y velocity at time t INPUT: t - (optional) time at which to get the velocity OUTPUT: vy(t) HISTORY: 2010-11-30 - Written - Bovy (NYU) """ return self._orb.vy(*args, **kwargs) def ra(self, *args, **kwargs): """ NAME: ra PURPOSE: return the right ascension INPUT: t - (optional) time at which to get ra obs=[X,Y,Z] - (optional) position of observer (in kpc) (default=[8.5,0.,0.]) OR Orbit object that corresponds to the orbit of the observer ro= distance in kpc corresponding to R=1. (default: 8.5) OUTPUT: ra(t) HISTORY: 2011-02-23 - Written - Bovy (NYU) """ return self._orb.ra(*args, **kwargs) def dec(self, *args, **kwargs): """ NAME: dec PURPOSE: return the declination INPUT: t - (optional) time at which to get dec obs=[X,Y,Z] - (optional) position of observer (in kpc) (default=[8.5,0.,0.]) OR Orbit object that corresponds to the orbit of the observer ro= distance in kpc corresponding to R=1. (default: 8.5) OUTPUT: dec(t) HISTORY: 2011-02-23 - Written - Bovy (NYU) """ return self._orb.dec(*args, **kwargs) def ll(self, *args, **kwargs): """ NAME: ll PURPOSE: return Galactic longitude INPUT: t - (optional) time at which to get ll obs=[X,Y,Z] - (optional) position of observer (in kpc) (default=[8.5,0.,0.]) OR Orbit object that corresponds to the orbit of the observer ro= distance in kpc corresponding to R=1. (default: 8.5) OUTPUT: l(t) HISTORY: 2011-02-23 - Written - Bovy (NYU) """ return self._orb.ll(*args, **kwargs) def bb(self, *args, **kwargs): """ NAME: bb PURPOSE: return Galactic latitude INPUT: t - (optional) time at which to get bb obs=[X,Y,Z] - (optional) position of observer (in kpc) (default=[8.5,0.,0.]) OR Orbit object that corresponds to the orbit of the observer ro= distance in kpc corresponding to R=1. (default: 8.5) OUTPUT: b(t) HISTORY: 2011-02-23 - Written - Bovy (NYU) """ return self._orb.bb(*args, **kwargs) def dist(self, *args, **kwargs): """ NAME: dist PURPOSE: return distance from the observer INPUT: t - (optional) time at which to get dist obs=[X,Y,Z] - (optional) position of observer (in kpc) (default=[8.5,0.,0.]) OR Orbit object that corresponds to the orbit of the observer ro= distance in kpc corresponding to R=1. (default: 8.5) OUTPUT: dist(t) in kpc HISTORY: 2011-02-23 - Written - Bovy (NYU) """ return self._orb.dist(*args, **kwargs) def pmra(self, *args, **kwargs): """ NAME: pmra PURPOSE: return proper motion in right ascension (in mas/yr) INPUT: t - (optional) time at which to get pmra obs=[X,Y,Z,vx,vy,vz] - (optional) position and velocity of observer (in kpc and km/s) (default=[8.5,0.,0.,0.,235.,0.]) OR Orbit object that corresponds to the orbit of the observer ro= distance in kpc corresponding to R=1. (default: 8.5) vo= velocity in km/s corresponding to v=1. (default: 235.) OUTPUT: pm_ra(t) HISTORY: 2011-02-24 - Written - Bovy (NYU) """ return self._orb.pmra(*args, **kwargs) def pmdec(self, *args, **kwargs): """ NAME: pmdec PURPOSE: return proper motion in declination (in mas/yr) INPUT: t - (optional) time at which to get pmdec obs=[X,Y,Z,vx,vy,vz] - (optional) position and velocity of observer (in kpc and km/s) (default=[8.5,0.,0.,0.,235.,0.]) OR Orbit object that corresponds to the orbit of the observer ro= distance in kpc corresponding to R=1. (default: 8.5) vo= velocity in km/s corresponding to v=1. (default: 235.) OUTPUT: pm_dec(t) HISTORY: 2011-02-24 - Written - Bovy (NYU) """ return self._orb.pmdec(*args, **kwargs) def pmll(self, *args, **kwargs): """ NAME: pmll PURPOSE: return proper motion in Galactic longitude (in mas/yr) INPUT: t - (optional) time at which to get pmll obs=[X,Y,Z,vx,vy,vz] - (optional) position and velocity of observer (in kpc and km/s) (default=[8.5,0.,0.,0.,235.,0.]) OR Orbit object that corresponds to the orbit of the observer ro= distance in kpc corresponding to R=1. (default: 8.5) vo= velocity in km/s corresponding to v=1. (default: 235.) OUTPUT: pm_l(t) HISTORY: 2011-02-24 - Written - Bovy (NYU) """ return self._orb.pmll(*args, **kwargs) def pmbb(self, *args, **kwargs): """ NAME: pmbb PURPOSE: return proper motion in Galactic latitude (in mas/yr) INPUT: t - (optional) time at which to get pmbb obs=[X,Y,Z,vx,vy,vz] - (optional) position and velocity of observer (in kpc and km/s) (default=[8.5,0.,0.,0.,235.,0.]) OR Orbit object that corresponds to the orbit of the observer ro= distance in kpc corresponding to R=1. (default: 8.5) vo= velocity in km/s corresponding to v=1. (default: 235.) OUTPUT: pm_b(t) HISTORY: 2011-02-24 - Written - Bovy (NYU) """ return self._orb.pmbb(*args, **kwargs) def vlos(self, *args, **kwargs): """ NAME: vlos PURPOSE: return the line-of-sight velocity (in km/s) INPUT: t - (optional) time at which to get vlos obs=[X,Y,Z,vx,vy,vz] - (optional) position and velocity of observer (in kpc and km/s) (default=[8.5,0.,0.,0.,235.,0.]) OR Orbit object that corresponds to the orbit of the observer ro= distance in kpc corresponding to R=1. (default: 8.5) vo= velocity in km/s corresponding to v=1. (default: 235.) OUTPUT: vlos(t) HISTORY: 2011-02-24 - Written - Bovy (NYU) """ return self._orb.vlos(*args, **kwargs) def vra(self, *args, **kwargs): """ NAME: vra PURPOSE: return velocity in right ascension (km/s) INPUT: t - (optional) time at which to get pmra obs=[X,Y,Z,vx,vy,vz] - (optional) position and velocity of observer (in kpc and km/s) (default=[8.5,0.,0.,0.,235.,0.]) OR Orbit object that corresponds to the orbit of the observer ro= distance in kpc corresponding to R=1. (default: 8.5) vo= velocity in km/s corresponding to v=1. (default: 235.) OUTPUT: v_ra(t) in km/s HISTORY: 2011-03-27 - Written - Bovy (NYU) """ return self._orb.dist(*args,**kwargs)*_K*\ self._orb.pmra(*args,**kwargs) def vdec(self, *args, **kwargs): """ NAME: vdec PURPOSE: return velocity in declination (km/s) INPUT: t - (optional) time at which to get pmdec obs=[X,Y,Z,vx,vy,vz] - (optional) position and velocity of observer (in kpc and km/s) (default=[8.5,0.,0.,0.,235.,0.]) OR Orbit object that corresponds to the orbit of the observer ro= distance in kpc corresponding to R=1. (default: 8.5) vo= velocity in km/s corresponding to v=1. (default: 235.) OUTPUT: v_dec(t) in km/s HISTORY: 2011-03-27 - Written - Bovy (NYU) """ return self._orb.dist(*args,**kwargs)*_K*\ self._orb.pmdec(*args,**kwargs) def vll(self, *args, **kwargs): """ NAME: vll PURPOSE: return the velocity in Galactic longitude (km/s) INPUT: t - (optional) time at which to get pmll obs=[X,Y,Z,vx,vy,vz] - (optional) position and velocity of observer (in kpc and km/s) (default=[8.5,0.,0.,0.,235.,0.]) OR Orbit object that corresponds to the orbit of the observer ro= distance in kpc corresponding to R=1. (default: 8.5) vo= velocity in km/s corresponding to v=1. (default: 235.) OUTPUT: v_l(t) in km/s HISTORY: 2011-03-27 - Written - Bovy (NYU) """ return self._orb.dist(*args,**kwargs)*_K*\ self._orb.pmll(*args,**kwargs) def vbb(self, *args, **kwargs): """ NAME: vbb PURPOSE: return velocity in Galactic latitude (km/s) INPUT: t - (optional) time at which to get pmbb obs=[X,Y,Z,vx,vy,vz] - (optional) position and velocity of observer (in kpc and km/s) (default=[8.5,0.,0.,0.,235.,0.]) OR Orbit object that corresponds to the orbit of the observer ro= distance in kpc corresponding to R=1. (default: 8.5) vo= velocity in km/s corresponding to v=1. (default: 235.) OUTPUT: v_b(t) in km/s HISTORY: 2011-02-24 - Written - Bovy (NYU) """ return self._orb.dist(*args,**kwargs)*_K*\ self._orb.pmbb(*args,**kwargs) def helioX(self, *args, **kwargs): """ NAME: helioX PURPOSE: return Heliocentric Galactic rectangular x-coordinate (aka "X") INPUT: t - (optional) time at which to get X obs=[X,Y,Z] - (optional) position and velocity of observer (in kpc and km/s) (default=[8.5,0.,0.,0.,235.,0.]) OR Orbit object that corresponds to the orbit of the observer ro= distance in kpc corresponding to R=1. (default: 8.5) OUTPUT: helioX(t) HISTORY: 2011-02-24 - Written - Bovy (NYU) """ return self._orb.helioX(*args, **kwargs) def helioY(self, *args, **kwargs): """ NAME: helioY PURPOSE: return Heliocentric Galactic rectangular y-coordinate (aka "Y") INPUT: t - (optional) time at which to get Y obs=[X,Y,Z] - (optional) position and velocity of observer (in kpc and km/s) (default=[8.5,0.,0.,0.,235.,0.]) OR Orbit object that corresponds to the orbit of the observer ro= distance in kpc corresponding to R=1. (default: 8.5) OUTPUT: helioY(t) HISTORY: 2011-02-24 - Written - Bovy (NYU) """ return self._orb.helioY(*args, **kwargs) def helioZ(self, *args, **kwargs): """ NAME: helioZ PURPOSE: return Heliocentric Galactic rectangular z-coordinate (aka "Z") INPUT: t - (optional) time at which to get Z obs=[X,Y,Z] - (optional) position and velocity of observer (in kpc and km/s) (default=[8.5,0.,0.,0.,235.,0.]) OR Orbit object that corresponds to the orbit of the observer ro= distance in kpc corresponding to R=1. (default: 8.5) OUTPUT: helioZ(t) HISTORY: 2011-02-24 - Written - Bovy (NYU) """ return self._orb.helioZ(*args, **kwargs) def U(self, *args, **kwargs): """ NAME: U PURPOSE: return Heliocentric Galactic rectangular x-velocity (aka "U") INPUT: t - (optional) time at which to get U obs=[X,Y,Z,vx,vy,vz] - (optional) position and velocity of observer (in kpc and km/s) (default=[8.5,0.,0.,0.,235.,0.]) OR Orbit object that corresponds to the orbit of the observer ro= distance in kpc corresponding to R=1. (default: 8.5) vo= velocity in km/s corresponding to v=1. (default: 235.) OUTPUT: U(t) HISTORY: 2011-02-24 - Written - Bovy (NYU) """ return self._orb.U(*args, **kwargs) def V(self, *args, **kwargs): """ NAME: V PURPOSE: return Heliocentric Galactic rectangular y-velocity (aka "V") INPUT: t - (optional) time at which to get U obs=[X,Y,Z,vx,vy,vz] - (optional) position and velocity of observer (in kpc and km/s) (default=[8.5,0.,0.,0.,235.,0.]) OR Orbit object that corresponds to the orbit of the observer ro= distance in kpc corresponding to R=1. (default: 8.5) vo= velocity in km/s corresponding to v=1. (default: 235.) OUTPUT: V(t) HISTORY: 2011-02-24 - Written - Bovy (NYU) """ return self._orb.V(*args, **kwargs) def W(self, *args, **kwargs): """ NAME: W PURPOSE: return Heliocentric Galactic rectangular z-velocity (aka "W") INPUT: t - (optional) time at which to get W obs=[X,Y,Z,vx,vy,vz] - (optional) position and velocity of observer (in kpc and km/s) (default=[8.5,0.,0.,0.,235.,0.]) OR Orbit object that corresponds to the orbit of the observer ro= distance in kpc corresponding to R=1. (default: 8.5) vo= velocity in km/s corresponding to v=1. (default: 235.) OUTPUT: W(t) HISTORY: 2011-02-24 - Written - Bovy (NYU) """ return self._orb.W(*args, **kwargs) def __call__(self, *args, **kwargs): """ NAME: __call__ PURPOSE: return the orbit at time t INPUT: t - desired time rect - if true, return rectangular coordinates OUTPUT: an Orbit instance with initial condition set to the phase-space at time t or list of Orbit instances if multiple times are given HISTORY: 2010-07-10 - Written - Bovy (NYU) """ thiso = self._orb(*args, **kwargs) if len(thiso.shape) == 1: return Orbit(vxvv=thiso) else: return [Orbit(vxvv=thiso[:, ii]) for ii in range(thiso.shape[1])] def plot(self, *args, **kwargs): """ NAME: plot PURPOSE: plot a previously calculated orbit (with reasonable defaults) INPUT: d1= first dimension to plot ('x', 'y', 'R', 'vR', 'vT', 'z', 'vz', ...) d2= second dimension to plot matplotlib.plot inputs+bovy_plot.plot inputs OUTPUT: sends plot to output device HISTORY: 2010-07-10 - Written - Bovy (NYU) """ self._orb.plot(*args, **kwargs) def plot3d(self, *args, **kwargs): """ NAME: plot3d PURPOSE: plot 3D aspects of an Orbit INPUT: bovy_plot3d args and kwargs OUTPUT: plot HISTORY: 2010-07-26 - Written - Bovy (NYU) 2010-09-22 - Adapted to more general framework - Bovy (NYU) 2010-01-08 - Adapted to 3D - Bovy (NYU) """ self._orb.plot3d(*args, **kwargs) def plotE(self, *args, **kwargs): """ NAME: plotE PURPOSE: plot E(.) along the orbit INPUT: pot= - Potential instance or list of instances in which the orbit was integrated d1= - plot Ez vs d1: e.g., 't', 'z', 'R', 'vR', 'vT', 'vz' +bovy_plot.bovy_plot inputs OUTPUT: figure to output device HISTORY: 2010-07-10 - Written - Bovy (NYU) """ self._orb.plotE(*args, **kwargs) def plotEz(self, *args, **kwargs): """ NAME: plotEz PURPOSE: plot E_z(.) along the orbit INPUT: po= - Potential instance or list of instances in which the orbit was integrated d1= - plot Ez vs d1: e.g., 't', 'z', 'R' +bovy_plot.bovy_plot inputs OUTPUT: figure to output device HISTORY: 2010-07-10 - Written - Bovy (NYU) """ self._orb.plotEz(*args, **kwargs) def plotEzJz(self, *args, **kwargs): """ NAME: plotEzJzt PURPOSE: plot E_z(t)/sqrt(dens(R)) along the orbit INPUT: pot - Potential instance or list of instances in which the orbit was integrated d1= - plot Ez vs d1: e.g., 't', 'z', 'R' +bovy_plot.bovy_plot inputs OUTPUT: figure to output device HISTORY: 2010-08-08 - Written - Bovy (NYU) """ self._orb.plotEzJz(*args, **kwargs) def plotJacobi(self, *args, **kwargs): """ NAME: plotJacobi PURPOSE: plot the Jacobi integral along the orbit INPUT: OmegaP= pattern speed pot= - Potential instance or list of instances in which the orbit was integrated d1= - plot Ez vs d1: e.g., 't', 'z', 'R', 'vR', 'vT', 'vz' +bovy_plot.bovy_plot inputs OUTPUT: figure to output device HISTORY: 2011-10-10 - Written - Bovy (IAS) """ self._orb.plotJacobi(*args, **kwargs) def plotR(self, *args, **kwargs): """ NAME: plotR PURPOSE: plot R(.) along the orbit INPUT: d1= plot vs d1: e.g., 't', 'z', 'R' bovy_plot.bovy_plot inputs OUTPUT: figure to output device HISTORY: 2010-07-10 - Written - Bovy (NYU) """ self._orb.plotR(*args, **kwargs) def plotz(self, *args, **kwargs): """ NAME: plotz PURPOSE: plot z(.) along the orbit INPUT: d1= plot vs d1: e.g., 't', 'z', 'R' bovy_plot.bovy_plot inputs OUTPUT: figure to output device HISTORY: 2010-07-10 - Written - Bovy (NYU) """ self._orb.plotz(*args, **kwargs) def plotvR(self, *args, **kwargs): """ NAME: plotvR PURPOSE: plot vR(.) along the orbit INPUT: d1= plot vs d1: e.g., 't', 'z', 'R' bovy_plot.bovy_plot inputs OUTPUT: figure to output device HISTORY: 2010-07-10 - Written - Bovy (NYU) """ self._orb.plotvR(*args, **kwargs) def plotvT(self, *args, **kwargs): """ NAME: plotvT PURPOSE: plot vT(.) along the orbit INPUT: d1= plot vs d1: e.g., 't', 'z', 'R' bovy_plot.bovy_plot inputs OUTPUT: figure to output device HISTORY: 2010-07-10 - Written - Bovy (NYU) """ self._orb.plotvT(*args, **kwargs) def plotphi(self, *args, **kwargs): """ NAME: plotphi PURPOSE: plot \phi(.) along the orbit INPUT: d1= plot vs d1: e.g., 't', 'z', 'R' bovy_plot.bovy_plot inputs OUTPUT: figure to output device HISTORY: 2010-07-10 - Written - Bovy (NYU) """ self._orb.plotphi(*args, **kwargs) def plotvz(self, *args, **kwargs): """ NAME: plotvz PURPOSE: plot vz(.) along the orbit INPUT: d1= plot vs d1: e.g., 't', 'z', 'R' bovy_plot.bovy_plot inputs OUTPUT: figure to output device HISTORY: 2010-07-10 - Written - Bovy (NYU) """ self._orb.plotvz(*args, **kwargs) def plotx(self, *args, **kwargs): """ NAME: plotx PURPOSE: plot a one-dimensional orbit position INPUT: d1= plot vs d1: e.g., 't', 'z', 'R' bovy_plot.bovy_plot inputs OUTPUT: figure to output device HISTORY: 2010-07-21 - Written - Bovy (NYU) """ self._orb.plotx(*args, **kwargs) def plotvx(self, *args, **kwargs): """ NAME: plotvx PURPOSE: plot a one-dimensional orbit velocity INPUT: d1= plot vs d1: e.g., 't', 'z', 'R' bovy_plot.bovy_plot inputs OUTPUT: figure to output device HISTORY: 2010-07-21 - Written - Bovy (NYU) """ self._orb.plotvx(*args, **kwargs) def ploty(self, *args, **kwargs): """ NAME: ploty PURPOSE: plot a one-dimensional orbit position INPUT: d1= plot vs d1: e.g., 't', 'z', 'R' bovy_plot.bovy_plot inputs OUTPUT: figure to output device HISTORY: 2010-07-21 - Written - Bovy (NYU) """ self._orb.ploty(*args, **kwargs) def plotvy(self, *args, **kwargs): """ NAME: plotvy PURPOSE: plot a one-dimensional orbit velocity INPUT: d1= plot vs d1: e.g., 't', 'z', 'R' bovy_plot.bovy_plot inputs OUTPUT: figure to output device HISTORY: 2010-07-21 - Written - Bovy (NYU) """ self._orb.plotvy(*args, **kwargs) def toPlanar(self): """ NAME: toPlanar PURPOSE: convert a 3D orbit into a 2D orbit INPUT: (none) OUTPUT: planar Orbit HISTORY: 2010-11-30 - Written - Bovy (NYU) """ if len(self.vxvv) == 6: vxvv = [self.vxvv[0], self.vxvv[1], self.vxvv[2], self.vxvv[5]] elif len(self.vxvv) == 5: vxvv = [self.vxvv[0], self.vxvv[1], self.vxvv[2]] else: raise AttributeError( "planar or linear Orbits do not have the toPlanar attribute") return Orbit(vxvv=vxvv) def toLinear(self): """ NAME: toLinear PURPOSE: convert a 3D orbit into a 1D orbit (z) INPUT: (none) OUTPUT: linear Orbit HISTORY: 2010-11-30 - Written - Bovy (NYU) """ if len(self.vxvv) == 6 or len(self.vxvv) == 5: vxvv = [self.vxvv[3], self.vxvv[4]] else: raise AttributeError( "planar or linear Orbits do not have the toPlanar attribute") return Orbit(vxvv=vxvv) def __add__(self, linOrb): """ NAME: __add__ PURPOSE: add a linear orbit and a planar orbit to make a 3D orbit INPUT: linear or plane orbit instance OUTPUT: 3D orbit HISTORY: 2010-07-21 - Written - Bovy (NYU) """ if (not (isinstance(self._orb, planarROrbit) and isinstance(linOrb._orb, linearOrbit)) and not (isinstance(self._orb, linearOrbit) and isinstance(linOrb._orb, planarROrbit))): raise AttributeError("Only planarROrbit+linearOrbit is supported") if isinstance(self._orb, planarROrbit): return Orbit(vxvv=[ self._orb.vxvv[0], self._orb.vxvv[1], self._orb.vxvv[2], linOrb._orb.vxvv[0], linOrb._orb.vxvv[1] ]) else: return Orbit(vxvv=[ linOrb._orb.vxvv[0], linOrb._orb.vxvv[1], linOrb._orb.vxvv[2], self._orb.vxvv[0], self._orb.vxvv[1] ]) #4 pickling def __getinitargs__(self): return (self.vxvv, ) def __getstate__(self): return self.vxvv def __setstate__(self, state): self.vxvv = state