def __init__(self, *args, **kwargs): """ NAME: __init__ PURPOSE: initialize an actionAngleIsochrone object INPUT: Either: b= scale parameter of the isochrone parameter (can be Quantity) ip= instance of a IsochronePotential ro= distance from vantage point to GC (kpc; can be Quantity) vo= circular velocity at ro (km/s; can be Quantity) OUTPUT: instance HISTORY: 2013-09-08 - Written - Bovy (IAS) """ actionAngle.__init__(self, ro=kwargs.get('ro', None), vo=kwargs.get('vo', None)) if not 'b' in kwargs and not 'ip' in kwargs: #pragma: no cover raise IOError("Must specify b= for actionAngleIsochrone") if 'ip' in kwargs: ip = kwargs['ip'] if not isinstance(ip, IsochronePotential): #pragma: no cover raise IOError( "'Provided ip= does not appear to be an instance of an IsochronePotential" ) # Check the units self._pot = ip self._check_consistent_units() self.b = ip.b self.amp = ip._amp else: self.b = kwargs['b'] if _APY_LOADED and isinstance(self.b, units.Quantity): self.b = self.b.to(units.kpc).value / self._ro rb = nu.sqrt(self.b**2. + 1.) self.amp = (self.b + rb)**2. * rb self._c = False ext_loaded = False if ext_loaded and (('c' in kwargs and kwargs['c']) or not 'c' in kwargs): #pragma: no cover self._c = True else: self._c = False if not self._c: self._ip = IsochronePotential(amp=self.amp, b=self.b) #Define _pot, because some functions that use actionAngle instances need this self._pot = IsochronePotential(amp=self.amp, b=self.b) # Check the units self._check_consistent_units() return None
def __init__(self, *args, **kwargs): """ NAME: __init__ PURPOSE: initialize an actionAngleStaeckel object INPUT: pot= potential or list of potentials (3D) delta= focus (can be Quantity) useu0 - use u0 to calculate dV (NOT recommended) c= if True, always use C for calculations order= (10) number of points to use in the Gauss-Legendre numerical integration of the relevant action, frequency, and angle integrals ro= distance from vantage point to GC (kpc; can be Quantity) vo= circular velocity at ro (km/s; can be Quantity) OUTPUT: instance HISTORY: 2012-11-27 - Written - Bovy (IAS) """ actionAngle.__init__(self, ro=kwargs.get('ro', None), vo=kwargs.get('vo', None)) if not 'pot' in kwargs: #pragma: no cover raise IOError("Must specify pot= for actionAngleStaeckel") self._pot = kwargs['pot'] if self._pot == MWPotential: warnings.warn( "Use of MWPotential as a Milky-Way-like potential is deprecated; galpy.potential.MWPotential2014, a potential fit to a large variety of dynamical constraints (see Bovy 2015), is the preferred Milky-Way-like potential in galpy", galpyWarning) if not 'delta' in kwargs: #pragma: no cover raise IOError("Must specify delta= for actionAngleStaeckel") if ext_loaded and (('c' in kwargs and kwargs['c']) or not 'c' in kwargs): self._c = _check_c(self._pot) if 'c' in kwargs and kwargs['c'] and not self._c: warnings.warn( "C module not used because potential does not have a C implementation", galpyWarning) #pragma: no cover else: self._c = False self._useu0 = kwargs.get('useu0', False) self._delta = kwargs['delta'] self._order = kwargs.get('order', 10) if _APY_LOADED and isinstance(self._delta, units.Quantity): self._delta = self._delta.to(units.kpc).value / self._ro # Check the units self._check_consistent_units() return None
def __init__(self, *args, **kwargs): """ NAME: __init__ PURPOSE: initialize an actionAngleStaeckelSingle object INPUT: Either: a) R,vR,vT,z,vz b) Orbit instance: initial condition used if that's it, orbit(t) if there is a time given as well pot= potential or list of potentials OUTPUT: HISTORY: 2012-11-27 - Written - Bovy (IAS) """ actionAngle.__init__(self, *args, **kwargs) if not 'pot' in kwargs: #pragma: no cover raise IOError("Must specify pot= for actionAngleStaeckelSingle") self._pot = kwargs['pot'] if not 'delta' in kwargs: #pragma: no cover raise IOError("Must specify delta= for actionAngleStaeckel") self._delta = kwargs['delta'] #Pre-calculate everything self._ux, self._vx = bovy_coords.Rz_to_uv(self._R, self._z, delta=self._delta) self._sinvx = nu.sin(self._vx) self._cosvx = nu.cos(self._vx) self._coshux = nu.cosh(self._ux) self._sinhux = nu.sinh(self._ux) self._pux = self._delta * (self._vR * self._coshux * self._sinvx + self._vz * self._sinhux * self._cosvx) self._pvx = self._delta * (self._vR * self._sinhux * self._cosvx - self._vz * self._coshux * self._sinvx) EL = self.calcEL() self._E = EL[0] self._Lz = EL[1] #Determine umin and umax self._u0 = kwargs.pop( 'u0', self._ux) #u0 as defined by Binney does not matter for a #single action evaluation, so we don't determine it here self._sinhu0 = nu.sinh(self._u0) self._potu0v0 = potentialStaeckel(self._u0, self._vx, self._pot, self._delta) self._I3U= self._E*self._sinhux**2.-self._pux**2./2./self._delta**2.\ -self._Lz**2./2./self._delta**2./self._sinhux**2. self._potupi2 = potentialStaeckel(self._ux, nu.pi / 2., self._pot, self._delta) dV = (self._coshux**2. * self._potupi2 - (self._sinhux**2. + self._sinvx**2.) * potentialStaeckel(self._ux, self._vx, self._pot, self._delta)) self._I3V= -self._E*self._sinvx**2.+self._pvx**2./2./self._delta**2.\ +self._Lz**2./2./self._delta**2./self._sinvx**2.\ -dV self.calcUminUmax() self.calcVmin() return None
def __init__(self,*args,**kwargs): """ NAME: __init__ PURPOSE: initialize an actionAngleIsochrone object INPUT: Either: b= scale parameter of the isochrone parameter (can be Quantity) ip= instance of a IsochronePotential ro= distance from vantage point to GC (kpc; can be Quantity) vo= circular velocity at ro (km/s; can be Quantity) OUTPUT: instance HISTORY: 2013-09-08 - Written - Bovy (IAS) """ actionAngle.__init__(self, ro=kwargs.get('ro',None),vo=kwargs.get('vo',None)) if not 'b' in kwargs and not 'ip' in kwargs: #pragma: no cover raise IOError("Must specify b= for actionAngleIsochrone") if 'ip' in kwargs: ip= kwargs['ip'] if not isinstance(ip,IsochronePotential): #pragma: no cover raise IOError("'Provided ip= does not appear to be an instance of an IsochronePotential") # Check the units self._pot= ip self._check_consistent_units() self.b= ip.b self.amp= ip._amp else: self.b= kwargs['b'] if _APY_LOADED and isinstance(self.b,units.Quantity): self.b= self.b.to(units.kpc).value/self._ro rb= nu.sqrt(self.b**2.+1.) self.amp= (self.b+rb)**2.*rb self._c= False ext_loaded= False if ext_loaded and (('c' in kwargs and kwargs['c']) or not 'c' in kwargs): #pragma: no cover self._c= True else: self._c= False if not self._c: self._ip= IsochronePotential(amp=self.amp,b=self.b) #Define _pot, because some functions that use actionAngle instances need this self._pot= IsochronePotential(amp=self.amp,b=self.b) # Check the units self._check_consistent_units() return None
def __init__(self,*args,**kwargs): """ NAME: __init__ PURPOSE: initialize an actionAngleStaeckelSingle object INPUT: Either: a) R,vR,vT,z,vz b) Orbit instance: initial condition used if that's it, orbit(t) if there is a time given as well pot= potential or list of potentials OUTPUT: HISTORY: 2012-11-27 - Written - Bovy (IAS) """ actionAngle.__init__(self,*args,**kwargs) if not 'pot' in kwargs: #pragma: no cover raise IOError("Must specify pot= for actionAngleStaeckelSingle") self._pot= kwargs['pot'] if not 'delta' in kwargs: #pragma: no cover raise IOError("Must specify delta= for actionAngleStaeckel") self._delta= kwargs['delta'] #Pre-calculate everything self._ux, self._vx= bovy_coords.Rz_to_uv(self._R,self._z, delta=self._delta) self._sinvx= nu.sin(self._vx) self._cosvx= nu.cos(self._vx) self._coshux= nu.cosh(self._ux) self._sinhux= nu.sinh(self._ux) self._pux= self._delta*(self._vR*self._coshux*self._sinvx +self._vz*self._sinhux*self._cosvx) self._pvx= self._delta*(self._vR*self._sinhux*self._cosvx -self._vz*self._coshux*self._sinvx) EL= self.calcEL() self._E= EL[0] self._Lz= EL[1] #Determine umin and umax self._u0= kwargs.pop('u0',self._ux) #u0 as defined by Binney does not matter for a #single action evaluation, so we don't determine it here self._sinhu0= nu.sinh(self._u0) self._potu0v0= potentialStaeckel(self._u0,self._vx, self._pot,self._delta) self._I3U= self._E*self._sinhux**2.-self._pux**2./2./self._delta**2.\ -self._Lz**2./2./self._delta**2./self._sinhux**2. self._potupi2= potentialStaeckel(self._ux,nu.pi/2., self._pot,self._delta) dV= (self._coshux**2.*self._potupi2 -(self._sinhux**2.+self._sinvx**2.) *potentialStaeckel(self._ux,self._vx, self._pot,self._delta)) self._I3V= -self._E*self._sinvx**2.+self._pvx**2./2./self._delta**2.\ +self._Lz**2./2./self._delta**2./self._sinvx**2.\ -dV self.calcUminUmax() self.calcVmin() return None
def __init__(self,*args,**kwargs): """ NAME: __init__ PURPOSE: initialize an actionAngleStaeckel object INPUT: pot= potential or list of potentials (3D) delta= focus (can be Quantity) useu0 - use u0 to calculate dV (NOT recommended) c= if True, always use C for calculations ro= distance from vantage point to GC (kpc; can be Quantity) vo= circular velocity at ro (km/s; can be Quantity) OUTPUT: instance HISTORY: 2012-11-27 - Written - Bovy (IAS) """ actionAngle.__init__(self, ro=kwargs.get('ro',None),vo=kwargs.get('vo',None)) if not 'pot' in kwargs: #pragma: no cover raise IOError("Must specify pot= for actionAngleStaeckel") self._pot= kwargs['pot'] if self._pot == MWPotential: warnings.warn("Use of MWPotential as a Milky-Way-like potential is deprecated; galpy.potential.MWPotential2014, a potential fit to a large variety of dynamical constraints (see Bovy 2015), is the preferred Milky-Way-like potential in galpy", galpyWarning) if not 'delta' in kwargs: #pragma: no cover raise IOError("Must specify delta= for actionAngleStaeckel") if ext_loaded and (('c' in kwargs and kwargs['c']) or not 'c' in kwargs): self._c= _check_c(self._pot) if 'c' in kwargs and kwargs['c'] and not self._c: warnings.warn("C module not used because potential does not have a C implementation",galpyWarning) #pragma: no cover else: self._c= False self._useu0= kwargs.get('useu0',False) self._delta= kwargs['delta'] if _APY_LOADED and isinstance(self._delta,units.Quantity): self._delta= self._delta.to(units.kpc).value/self._ro # Check the units self._check_consistent_units() return None
def __init__(self, *args, **kwargs): """ NAME: __init__ PURPOSE: initialize an actionAngleAdiabatic object INPUT: pot= potential or list of potentials (planarPotentials) gamma= (default=1.) replace Lz by Lz+gamma Jz in effective potential ro= distance from vantage point to GC (kpc; can be Quantity) vo= circular velocity at ro (km/s; can be Quantity) OUTPUT: instance HISTORY: 2012-07-26 - Written - Bovy (IAS@MPIA) """ actionAngle.__init__(self, ro=kwargs.get('ro', None), vo=kwargs.get('vo', None)) if not 'pot' in kwargs: #pragma: no cover raise IOError("Must specify pot= for actionAngleAxi") self._pot = kwargs['pot'] if self._pot == MWPotential: warnings.warn( "Use of MWPotential as a Milky-Way-like potential is deprecated; galpy.potential.MWPotential2014, a potential fit to a large variety of dynamical constraints (see Bovy 2015), is the preferred Milky-Way-like potential in galpy", galpyWarning) if ext_loaded and 'c' in kwargs and kwargs['c']: self._c = _check_c(self._pot) if 'c' in kwargs and kwargs['c'] and not self._c: warnings.warn( "C module not used because potential does not have a C implementation", galpyWarning) #pragma: no cover else: self._c = False self._gamma = kwargs.get('gamma', 1.) # Check the units self._check_consistent_units() return None
def __init__(self,*args,**kwargs): """ NAME: __init__ PURPOSE: initialize an actionAngleAdiabatic object INPUT: pot= potential or list of potentials (planarPotentials) gamma= (default=1.) replace Lz by Lz+gamma Jz in effective potential ro= distance from vantage point to GC (kpc; can be Quantity) vo= circular velocity at ro (km/s; can be Quantity) OUTPUT: instance HISTORY: 2012-07-26 - Written - Bovy (IAS@MPIA) """ actionAngle.__init__(self, ro=kwargs.get('ro',None),vo=kwargs.get('vo',None)) if not 'pot' in kwargs: #pragma: no cover raise IOError("Must specify pot= for actionAngleAxi") self._pot= kwargs['pot'] if self._pot == MWPotential: warnings.warn("Use of MWPotential as a Milky-Way-like potential is deprecated; galpy.potential.MWPotential2014, a potential fit to a large variety of dynamical constraints (see Bovy 2015), is the preferred Milky-Way-like potential in galpy", galpyWarning) if ext_loaded and 'c' in kwargs and kwargs['c']: self._c= _check_c(self._pot) if 'c' in kwargs and kwargs['c'] and not self._c: warnings.warn("C module not used because potential does not have a C implementation",galpyWarning) #pragma: no cover else: self._c= False self._gamma= kwargs.get('gamma',1.) # Check the units self._check_consistent_units() return None
def __init__(self, pot=None, zmax=1., gamma=1., Rmax=5., nR=16, nEz=16, nEr=31, nLz=31, numcores=1, **kwargs): """ NAME: __init__ PURPOSE: initialize an actionAngleAdiabaticGrid object INPUT: pot= potential or list of potentials zmax= zmax for building Ez grid Rmax = Rmax for building grids gamma= (default=1.) replace Lz by Lz+gamma Jz in effective potential nEz=, nEr=, nLz, nR= grid size numcores= number of cpus to use to parallellize c= if True, use C to calculate actions ro= distance from vantage point to GC (kpc; can be Quantity) vo= circular velocity at ro (km/s; can be Quantity) +scipy.integrate.quad keywords OUTPUT: instance HISTORY: 2012-07-27 - Written - Bovy (IAS@MPIA) """ actionAngle.__init__(self, ro=kwargs.get('ro', None), vo=kwargs.get('vo', None)) if pot is None: #pragma: no cover raise IOError("Must specify pot= for actionAngleAxi") self._c = kwargs.pop('c', False) self._gamma = gamma self._pot = pot self._zmax = zmax self._Rmax = Rmax self._Rmin = 0.01 #Set up the actionAngleAdiabatic object that we will use to interpolate self._aA = actionAngleAdiabatic(pot=self._pot, gamma=self._gamma, c=self._c) #Build grid for Ez, first calculate Ez(zmax;R) function self._Rs = numpy.linspace(self._Rmin, self._Rmax, nR) self._EzZmaxs= _evaluatePotentials(self._pot,self._Rs, self._zmax*numpy.ones(nR))\ -_evaluatePotentials(self._pot,self._Rs,numpy.zeros(nR)) self._EzZmaxsInterp = interpolate.InterpolatedUnivariateSpline( self._Rs, numpy.log(self._EzZmaxs), k=3) y = numpy.linspace(0., 1., nEz) jz = numpy.zeros((nR, nEz)) jzEzzmax = numpy.zeros(nR) thisRs = (numpy.tile(self._Rs, (nEz, 1)).T).flatten() thisEzZmaxs = (numpy.tile(self._EzZmaxs, (nEz, 1)).T).flatten() thisy = (numpy.tile(y, (nR, 1))).flatten() if self._c: jz = self._aA( thisRs, numpy.zeros(len(thisRs)), numpy.ones(len(thisRs)), #these two r dummies numpy.zeros(len(thisRs)), numpy.sqrt(2. * thisy * thisEzZmaxs), **kwargs)[2] jz = numpy.reshape(jz, (nR, nEz)) jzEzzmax[0:nR] = jz[:, nEz - 1] else: if numcores > 1: jz = multi.parallel_map( ( lambda x: self._aA( thisRs[x], 0., 1., #these two r dummies 0., math.sqrt(2. * thisy[x] * thisEzZmaxs[x]), _justjz=True, **kwargs)[2]), range(nR * nEz), numcores=numcores) jz = numpy.reshape(jz, (nR, nEz)) jzEzzmax[0:nR] = jz[:, nEz - 1] else: for ii in range(nR): for jj in range(nEz): #Calculate Jz jz[ii, jj] = self._aA( self._Rs[ii], 0., 1., #these two r dummies 0., numpy.sqrt(2. * y[jj] * self._EzZmaxs[ii]), _justjz=True, **kwargs)[2] if jj == nEz - 1: jzEzzmax[ii] = jz[ii, jj] for ii in range(nR): jz[ii, :] /= jzEzzmax[ii] #First interpolate Ez=Ezmax self._jzEzmaxInterp = interpolate.InterpolatedUnivariateSpline( self._Rs, numpy.log(jzEzzmax + 10.**-5.), k=3) self._jz = jz self._jzInterp = interpolate.RectBivariateSpline(self._Rs, y, jz, kx=3, ky=3, s=0.) #JR grid self._Lzmin = 0.01 self._Lzs= numpy.linspace(self._Lzmin, self._Rmax\ *galpy.potential.vcirc(self._pot, self._Rmax), nLz) self._Lzmax = self._Lzs[-1] #Calculate ER(vr=0,R=RL) self._RL = numpy.array( [galpy.potential.rl(self._pot, l) for l in self._Lzs]) self._RLInterp = interpolate.InterpolatedUnivariateSpline(self._Lzs, self._RL, k=3) self._ERRL = _evaluatePotentials( self._pot, self._RL, numpy.zeros(nLz)) + self._Lzs**2. / 2. / self._RL**2. self._ERRLmax = numpy.amax(self._ERRL) + 1. self._ERRLInterp = interpolate.InterpolatedUnivariateSpline( self._Lzs, numpy.log(-(self._ERRL - self._ERRLmax)), k=3) self._Ramax = 99. self._ERRa = _evaluatePotentials( self._pot, self._Ramax, 0.) + self._Lzs**2. / 2. / self._Ramax**2. self._ERRamax = numpy.amax(self._ERRa) + 1. self._ERRaInterp = interpolate.InterpolatedUnivariateSpline( self._Lzs, numpy.log(-(self._ERRa - self._ERRamax)), k=3) y = numpy.linspace(0., 1., nEr) jr = numpy.zeros((nLz, nEr)) jrERRa = numpy.zeros(nLz) thisRL = (numpy.tile(self._RL, (nEr - 1, 1)).T).flatten() thisLzs = (numpy.tile(self._Lzs, (nEr - 1, 1)).T).flatten() thisERRL = (numpy.tile(self._ERRL, (nEr - 1, 1)).T).flatten() thisERRa = (numpy.tile(self._ERRa, (nEr - 1, 1)).T).flatten() thisy = (numpy.tile(y[0:-1], (nLz, 1))).flatten() if self._c: mjr = self._aA( thisRL, numpy.sqrt(2. * (thisERRa + thisy * (thisERRL - thisERRa) - _evaluatePotentials( self._pot, thisRL, numpy.zeros( (nEr - 1) * nLz))) - thisLzs**2. / thisRL**2.), thisLzs / thisRL, numpy.zeros(len(thisRL)), numpy.zeros(len(thisRL)), **kwargs)[0] jr[:, 0:-1] = numpy.reshape(mjr, (nLz, nEr - 1)) jrERRa[0:nLz] = jr[:, 0] else: if numcores > 1: mjr = multi.parallel_map((lambda x: self._aA( thisRL[x], numpy.sqrt(2. * (thisERRa[x] + thisy[x] * (thisERRL[x] - thisERRa[x]) - _evaluatePotentials(self._pot, thisRL[ x], 0.)) - thisLzs[x]**2. / thisRL[x]**2.), thisLzs[x] / thisRL[x], 0., 0., _justjr=True, **kwargs)[0]), range((nEr - 1) * nLz), numcores=numcores) jr[:, 0:-1] = numpy.reshape(mjr, (nLz, nEr - 1)) jrERRa[0:nLz] = jr[:, 0] else: for ii in range(nLz): for jj in range(nEr - 1): #Last one is zero by construction try: jr[ii, jj] = self._aA( self._RL[ii], numpy.sqrt(2. * (self._ERRa[ii] + y[jj] * (self._ERRL[ii] - self._ERRa[ii]) - _evaluatePotentials( self._pot, self._RL[ii], 0.)) - self._Lzs[ii]**2. / self._RL[ii]**2.), self._Lzs[ii] / self._RL[ii], 0., 0., _justjr=True, **kwargs)[0] except UnboundError: #pragma: no cover raise if jj == 0: jrERRa[ii] = jr[ii, jj] for ii in range(nLz): jr[ii, :] /= jrERRa[ii] #First interpolate Ez=Ezmax self._jr = jr self._jrERRaInterp = interpolate.InterpolatedUnivariateSpline( self._Lzs, numpy.log(jrERRa + 10.**-5.), k=3) self._jrInterp = interpolate.RectBivariateSpline(self._Lzs, y, jr, kx=3, ky=3, s=0.) # Check the units self._check_consistent_units() return None
def __init__(self,pot=None,zmax=1.,gamma=1.,Rmax=5., nR=16,nEz=16,nEr=31,nLz=31,numcores=1, **kwargs): """ NAME: __init__ PURPOSE: initialize an actionAngleAdiabaticGrid object INPUT: pot= potential or list of potentials zmax= zmax for building Ez grid Rmax = Rmax for building grids gamma= (default=1.) replace Lz by Lz+gamma Jz in effective potential nEz=, nEr=, nLz, nR= grid size numcores= number of cpus to use to parallellize c= if True, use C to calculate actions ro= distance from vantage point to GC (kpc; can be Quantity) vo= circular velocity at ro (km/s; can be Quantity) +scipy.integrate.quad keywords OUTPUT: instance HISTORY: 2012-07-27 - Written - Bovy (IAS@MPIA) """ actionAngle.__init__(self, ro=kwargs.get('ro',None),vo=kwargs.get('vo',None)) if pot is None: #pragma: no cover raise IOError("Must specify pot= for actionAngleAxi") self._c= kwargs.pop('c',False) self._gamma= gamma self._pot= pot self._zmax= zmax self._Rmax= Rmax self._Rmin= 0.01 #Set up the actionAngleAdiabatic object that we will use to interpolate self._aA= actionAngleAdiabatic(pot=self._pot,gamma=self._gamma, c=self._c) #Build grid for Ez, first calculate Ez(zmax;R) function self._Rs= numpy.linspace(self._Rmin,self._Rmax,nR) self._EzZmaxs= _evaluatePotentials(self._pot,self._Rs, self._zmax*numpy.ones(nR))\ -_evaluatePotentials(self._pot,self._Rs,numpy.zeros(nR)) self._EzZmaxsInterp= interpolate.InterpolatedUnivariateSpline(self._Rs,numpy.log(self._EzZmaxs),k=3) y= numpy.linspace(0.,1.,nEz) jz= numpy.zeros((nR,nEz)) jzEzzmax= numpy.zeros(nR) thisRs= (numpy.tile(self._Rs,(nEz,1)).T).flatten() thisEzZmaxs= (numpy.tile(self._EzZmaxs,(nEz,1)).T).flatten() thisy= (numpy.tile(y,(nR,1))).flatten() if self._c: jz= self._aA(thisRs, numpy.zeros(len(thisRs)), numpy.ones(len(thisRs)),#these two r dummies numpy.zeros(len(thisRs)), numpy.sqrt(2.*thisy*thisEzZmaxs), **kwargs)[2] jz= numpy.reshape(jz,(nR,nEz)) jzEzzmax[0:nR]= jz[:,nEz-1] else: if numcores > 1: jz= multi.parallel_map((lambda x: self._aA(thisRs[x],0.,1.,#these two r dummies 0.,math.sqrt(2.*thisy[x]*thisEzZmaxs[x]), _justjz=True, **kwargs)[2]), range(nR*nEz),numcores=numcores) jz= numpy.reshape(jz,(nR,nEz)) jzEzzmax[0:nR]= jz[:,nEz-1] else: for ii in range(nR): for jj in range(nEz): #Calculate Jz jz[ii,jj]= self._aA(self._Rs[ii],0.,1.,#these two r dummies 0.,numpy.sqrt(2.*y[jj]*self._EzZmaxs[ii]), _justjz=True,**kwargs)[2] if jj == nEz-1: jzEzzmax[ii]= jz[ii,jj] for ii in range(nR): jz[ii,:]/= jzEzzmax[ii] #First interpolate Ez=Ezmax self._jzEzmaxInterp= interpolate.InterpolatedUnivariateSpline(self._Rs,numpy.log(jzEzzmax+10.**-5.),k=3) self._jz= jz self._jzInterp= interpolate.RectBivariateSpline(self._Rs, y, jz, kx=3,ky=3,s=0.) #JR grid self._Lzmin= 0.01 self._Lzs= numpy.linspace(self._Lzmin, self._Rmax\ *galpy.potential.vcirc(self._pot, self._Rmax), nLz) self._Lzmax= self._Lzs[-1] #Calculate ER(vr=0,R=RL) self._RL= numpy.array([galpy.potential.rl(self._pot,l) for l in self._Lzs]) self._RLInterp= interpolate.InterpolatedUnivariateSpline(self._Lzs, self._RL,k=3) self._ERRL= _evaluatePotentials(self._pot,self._RL,numpy.zeros(nLz)) +self._Lzs**2./2./self._RL**2. self._ERRLmax= numpy.amax(self._ERRL)+1. self._ERRLInterp= interpolate.InterpolatedUnivariateSpline(self._Lzs, numpy.log(-(self._ERRL-self._ERRLmax)),k=3) self._Ramax= 99. self._ERRa= _evaluatePotentials(self._pot,self._Ramax,0.) +self._Lzs**2./2./self._Ramax**2. self._ERRamax= numpy.amax(self._ERRa)+1. self._ERRaInterp= interpolate.InterpolatedUnivariateSpline(self._Lzs, numpy.log(-(self._ERRa-self._ERRamax)),k=3) y= numpy.linspace(0.,1.,nEr) jr= numpy.zeros((nLz,nEr)) jrERRa= numpy.zeros(nLz) thisRL= (numpy.tile(self._RL,(nEr-1,1)).T).flatten() thisLzs= (numpy.tile(self._Lzs,(nEr-1,1)).T).flatten() thisERRL= (numpy.tile(self._ERRL,(nEr-1,1)).T).flatten() thisERRa= (numpy.tile(self._ERRa,(nEr-1,1)).T).flatten() thisy= (numpy.tile(y[0:-1],(nLz,1))).flatten() if self._c: mjr= self._aA(thisRL, numpy.sqrt(2.*(thisERRa+thisy*(thisERRL-thisERRa)-_evaluatePotentials(self._pot,thisRL,numpy.zeros((nEr-1)*nLz)))-thisLzs**2./thisRL**2.), thisLzs/thisRL, numpy.zeros(len(thisRL)), numpy.zeros(len(thisRL)), **kwargs)[0] jr[:,0:-1]= numpy.reshape(mjr,(nLz,nEr-1)) jrERRa[0:nLz]= jr[:,0] else: if numcores > 1: mjr= multi.parallel_map((lambda x: self._aA(thisRL[x], numpy.sqrt(2.*(thisERRa[x]+thisy[x]*(thisERRL[x]-thisERRa[x])-_evaluatePotentials(self._pot,thisRL[x],0.))-thisLzs[x]**2./thisRL[x]**2.), thisLzs[x]/thisRL[x], 0.,0., _justjr=True, **kwargs)[0]), range((nEr-1)*nLz), numcores=numcores) jr[:,0:-1]= numpy.reshape(mjr,(nLz,nEr-1)) jrERRa[0:nLz]= jr[:,0] else: for ii in range(nLz): for jj in range(nEr-1): #Last one is zero by construction try: jr[ii,jj]= self._aA(self._RL[ii], numpy.sqrt(2.*(self._ERRa[ii]+y[jj]*(self._ERRL[ii]-self._ERRa[ii])-_evaluatePotentials(self._pot,self._RL[ii],0.))-self._Lzs[ii]**2./self._RL[ii]**2.), self._Lzs[ii]/self._RL[ii], 0.,0., _justjr=True, **kwargs)[0] except UnboundError: #pragma: no cover raise if jj == 0: jrERRa[ii]= jr[ii,jj] for ii in range(nLz): jr[ii,:]/= jrERRa[ii] #First interpolate Ez=Ezmax self._jr= jr self._jrERRaInterp= interpolate.InterpolatedUnivariateSpline(self._Lzs, numpy.log(jrERRa+10.**-5.),k=3) self._jrInterp= interpolate.RectBivariateSpline(self._Lzs, y, jr, kx=3,ky=3,s=0.) # Check the units self._check_consistent_units() return None
def __init__(self,pot=None,delta=None,Rmax=5., nE=25,npsi=25,nLz=30,numcores=1, **kwargs): """ NAME: __init__ PURPOSE: initialize an actionAngleStaeckelGrid object INPUT: pot= potential or list of potentials delta= focus of prolate confocal coordinate system (can be Quantity) Rmax = Rmax for building grids (natural units) nE=, npsi=, nLz= grid size numcores= number of cpus to use to parallellize ro= distance from vantage point to GC (kpc; can be Quantity) vo= circular velocity at ro (km/s; can be Quantity) OUTPUT: instance HISTORY: 2012-11-29 - Written - Bovy (IAS) """ actionAngle.__init__(self, ro=kwargs.get('ro',None),vo=kwargs.get('vo',None)) if pot is None: raise IOError("Must specify pot= for actionAngleStaeckelGrid") self._pot= pot if delta is None: raise IOError("Must specify delta= for actionAngleStaeckelGrid") if ext_loaded and 'c' in kwargs and kwargs['c']: self._c= True else: self._c= False self._delta= delta if _APY_LOADED and isinstance(self._delta,units.Quantity): self._delta= self._delta.to(units.kpc).value/self._ro self._Rmax= Rmax self._Rmin= 0.01 #Set up the actionAngleStaeckel object that we will use to interpolate self._aA= actionAngleStaeckel.actionAngleStaeckel(pot=self._pot,delta=self._delta,c=self._c) #Build grid self._Lzmin= 0.01 self._Lzs= numpy.linspace(self._Lzmin, self._Rmax\ *galpy.potential.vcirc(self._pot, self._Rmax), nLz) self._Lzmax= self._Lzs[-1] self._nLz= nLz #Calculate E_c(R=RL), energy of circular orbit self._RL= numpy.array([galpy.potential.rl(self._pot,l) for l in self._Lzs]) self._RLInterp= interpolate.InterpolatedUnivariateSpline(self._Lzs, self._RL,k=3) self._ERL= _evaluatePotentials(self._pot,self._RL, numpy.zeros(self._nLz))\ +self._Lzs**2./2./self._RL**2. self._ERLmax= numpy.amax(self._ERL)+1. self._ERLInterp= interpolate.InterpolatedUnivariateSpline(self._Lzs, numpy.log(-(self._ERL-self._ERLmax)),k=3) self._Ramax= 200./8. self._ERa= _evaluatePotentials(self._pot,self._Ramax,0.) +self._Lzs**2./2./self._Ramax**2. #self._EEsc= numpy.array([self._ERL[ii]+galpy.potential.vesc(self._pot,self._RL[ii])**2./4. for ii in range(nLz)]) self._ERamax= numpy.amax(self._ERa)+1. self._ERaInterp= interpolate.InterpolatedUnivariateSpline(self._Lzs, numpy.log(-(self._ERa-self._ERamax)),k=3) y= numpy.linspace(0.,1.,nE) self._nE= nE psis= numpy.linspace(0.,1.,npsi)*numpy.pi/2. self._npsi= npsi jr= numpy.zeros((nLz,nE,npsi)) jz= numpy.zeros((nLz,nE,npsi)) u0= numpy.zeros((nLz,nE)) jrLzE= numpy.zeros((nLz)) jzLzE= numpy.zeros((nLz)) #First calculate u0 thisLzs= (numpy.tile(self._Lzs,(nE,1)).T).flatten() thisERL= (numpy.tile(self._ERL,(nE,1)).T).flatten() thisERa= (numpy.tile(self._ERa,(nE,1)).T).flatten() thisy= (numpy.tile(y,(nLz,1))).flatten() thisE= _invEfunc(_Efunc(thisERa,thisERL)+thisy*(_Efunc(thisERL,thisERL)-_Efunc(thisERa,thisERL)),thisERL) if isinstance(self._pot,galpy.potential.interpRZPotential) and hasattr(self._pot,'_origPot'): u0pot= self._pot._origPot else: u0pot= self._pot if self._c: mu0= actionAngleStaeckel_c.actionAngleStaeckel_calcu0(thisE,thisLzs, u0pot, self._delta)[0] else: if numcores > 1: mu0= multi.parallel_map((lambda x: self.calcu0(thisE[x], thisLzs[x])), range(nE*nLz), numcores=numcores) else: mu0= list(map((lambda x: self.calcu0(thisE[x], thisLzs[x])), range(nE*nLz))) u0= numpy.reshape(mu0,(nLz,nE)) thisR= self._delta*numpy.sinh(u0) thisv= numpy.reshape(self.vatu0(thisE.flatten(),thisLzs.flatten(), u0.flatten(), thisR.flatten()),(nLz,nE)) self.thisv= thisv #reshape thisLzs= numpy.reshape(thisLzs,(nLz,nE)) thispsi= numpy.tile(psis,(nLz,nE,1)).flatten() thisLzs= numpy.tile(thisLzs.T,(npsi,1,1)).T.flatten() thisR= numpy.tile(thisR.T,(npsi,1,1)).T.flatten() thisv= numpy.tile(thisv.T,(npsi,1,1)).T.flatten() mjr, mlz, mjz= self._aA(thisR, #R thisv*numpy.cos(thispsi), #vR thisLzs/thisR, #vT numpy.zeros(len(thisR)), #z thisv*numpy.sin(thispsi), #vz fixed_quad=True) if isinstance(self._pot,galpy.potential.interpRZPotential) and hasattr(self._pot,'_origPot'): #Interpolated potentials have problems with extreme orbits indx= (mjr == 9999.99) indx+= (mjz == 9999.99) #Re-calculate these using the original potential, hopefully not too slow tmpaA= actionAngleStaeckel.actionAngleStaeckel(pot=self._pot._origPot,delta=self._delta,c=self._c) mjr[indx], dum, mjz[indx]= tmpaA(thisR[indx], #R thisv[indx]*numpy.cos(thispsi[indx]), #vR thisLzs[indx]/thisR[indx], #vT numpy.zeros(numpy.sum(indx)), #z thisv[indx]*numpy.sin(thispsi[indx]), #vz fixed_quad=True) jr= numpy.reshape(mjr,(nLz,nE,npsi)) jz= numpy.reshape(mjz,(nLz,nE,npsi)) for ii in range(nLz): jrLzE[ii]= numpy.nanmax(jr[ii,(jr[ii,:,:] != 9999.99)])#:,:]) jzLzE[ii]= numpy.nanmax(jz[ii,(jz[ii,:,:] != 9999.99)])#:,:]) jrLzE[(jrLzE == 0.)]= numpy.nanmin(jrLzE[(jrLzE > 0.)]) jzLzE[(jzLzE == 0.)]= numpy.nanmin(jzLzE[(jzLzE > 0.)]) for ii in range(nLz): jr[ii,:,:]/= jrLzE[ii] jz[ii,:,:]/= jzLzE[ii] #Deal w/ 9999.99 jr[(jr > 1.)]= 1. jz[(jz > 1.)]= 1. #Deal w/ NaN jr[numpy.isnan(jr)]= 0. jz[numpy.isnan(jz)]= 0. #First interpolate the maxima self._jr= jr self._jz= jz self._u0= u0 self._jrLzE= jrLzE self._jzLzE= jzLzE self._jrLzInterp= interpolate.InterpolatedUnivariateSpline(self._Lzs, numpy.log(jrLzE+10.**-5.),k=3) self._jzLzInterp= interpolate.InterpolatedUnivariateSpline(self._Lzs, numpy.log(jzLzE+10.**-5.),k=3) #Interpolate u0 self._logu0Interp= interpolate.RectBivariateSpline(self._Lzs, y, numpy.log(u0), kx=3,ky=3,s=0.) #spline filter jr and jz, such that they can be used with ndimage.map_coordinates self._jrFiltered= ndimage.spline_filter(numpy.log(self._jr+10.**-10.),order=3) self._jzFiltered= ndimage.spline_filter(numpy.log(self._jz+10.**-10.),order=3) # Check the units self._check_consistent_units() return None
def __init__(self,*args,**kwargs): """ NAME: __init__ PURPOSE: initialize an actionAngleIsochroneApprox object INPUT: Either: b= scale parameter of the isochrone parameter (can be Quantity) ip= instance of a IsochronePotential aAI= instance of an actionAngleIsochrone pot= potential to calculate action-angle variables for tintJ= (default: 100) time to integrate orbits for to estimate actions (can be Quantity) ntintJ= (default: 10000) number of time-integration points integrate_method= (default: 'dopr54_c') integration method to use dt= (None) orbit.integrate dt keyword (for fixed stepsize integration) maxn= (default: 3) Default value for all methods when using a grid in vec(n) up to this n (zero-based) ro= distance from vantage point to GC (kpc; can be Quantity) vo= circular velocity at ro (km/s; can be Quantity) OUTPUT: instance HISTORY: 2013-09-10 - Written - Bovy (IAS) """ actionAngle.__init__(self, ro=kwargs.get('ro',None),vo=kwargs.get('vo',None)) if not 'pot' in kwargs: #pragma: no cover raise IOError("Must specify pot= for actionAngleIsochroneApprox") self._pot= kwargs['pot'] if self._pot == MWPotential: warnings.warn("Use of MWPotential as a Milky-Way-like potential is deprecated; galpy.potential.MWPotential2014, a potential fit to a large variety of dynamical constraints (see Bovy 2015), is the preferred Milky-Way-like potential in galpy", galpyWarning) if not 'b' in kwargs and not 'ip' in kwargs \ and not 'aAI' in kwargs: #pragma: no cover raise IOError("Must specify b=, ip=, or aAI= for actionAngleIsochroneApprox") if 'aAI' in kwargs: if not isinstance(kwargs['aAI'],actionAngleIsochrone): #pragma: no cover raise IOError("'Provided aAI= does not appear to be an instance of an actionAngleIsochrone") self._aAI= kwargs['aAI'] elif 'ip' in kwargs: ip= kwargs['ip'] if not isinstance(ip,IsochronePotential): #pragma: no cover raise IOError("'Provided ip= does not appear to be an instance of an IsochronePotential") self._aAI= actionAngleIsochrone(ip=ip) else: if _APY_LOADED and isinstance(kwargs['b'],units.Quantity): b= kwargs['b'].to(units.kpc).value/self._ro else: b= kwargs['b'] self._aAI= actionAngleIsochrone(ip=IsochronePotential(b=b, normalize=1.)) self._tintJ= kwargs.get('tintJ',100.) if _APY_LOADED and isinstance(self._tintJ,units.Quantity): self._tintJ= self._tintJ.to(units.Gyr).value\ /time_in_Gyr(self._vo,self._ro) self._ntintJ= kwargs.get('ntintJ',10000) self._integrate_dt= kwargs.get('dt',None) self._tsJ= nu.linspace(0.,self._tintJ,self._ntintJ) self._integrate_method= kwargs.get('integrate_method','dopr54_c') self._maxn= kwargs.get('maxn',3) self._c= False ext_loaded= False if ext_loaded and (('c' in kwargs and kwargs['c']) or not 'c' in kwargs): #pragma: no cover self._c= True else: self._c= False # Check the units self._check_consistent_units() return None
def __init__(self, *args, **kwargs): """ NAME: __init__ PURPOSE: initialize an actionAngleIsochroneApprox object INPUT: Either: b= scale parameter of the isochrone parameter (can be Quantity) ip= instance of a IsochronePotential aAI= instance of an actionAngleIsochrone pot= potential to calculate action-angle variables for tintJ= (default: 100) time to integrate orbits for to estimate actions (can be Quantity) ntintJ= (default: 10000) number of time-integration points integrate_method= (default: 'dopr54_c') integration method to use dt= (None) orbit.integrate dt keyword (for fixed stepsize integration) maxn= (default: 3) Default value for all methods when using a grid in vec(n) up to this n (zero-based) ro= distance from vantage point to GC (kpc; can be Quantity) vo= circular velocity at ro (km/s; can be Quantity) OUTPUT: instance HISTORY: 2013-09-10 - Written - Bovy (IAS) """ actionAngle.__init__(self, ro=kwargs.get('ro', None), vo=kwargs.get('vo', None)) if not 'pot' in kwargs: #pragma: no cover raise IOError("Must specify pot= for actionAngleIsochroneApprox") self._pot = flatten_potential(kwargs['pot']) if self._pot == MWPotential: warnings.warn( "Use of MWPotential as a Milky-Way-like potential is deprecated; galpy.potential.MWPotential2014, a potential fit to a large variety of dynamical constraints (see Bovy 2015), is the preferred Milky-Way-like potential in galpy", galpyWarning) if not 'b' in kwargs and not 'ip' in kwargs \ and not 'aAI' in kwargs: #pragma: no cover raise IOError( "Must specify b=, ip=, or aAI= for actionAngleIsochroneApprox") if 'aAI' in kwargs: if not isinstance(kwargs['aAI'], actionAngleIsochrone): #pragma: no cover raise IOError( "'Provided aAI= does not appear to be an instance of an actionAngleIsochrone" ) self._aAI = kwargs['aAI'] elif 'ip' in kwargs: ip = kwargs['ip'] if not isinstance(ip, IsochronePotential): #pragma: no cover raise IOError( "'Provided ip= does not appear to be an instance of an IsochronePotential" ) self._aAI = actionAngleIsochrone(ip=ip) else: if _APY_LOADED and isinstance(kwargs['b'], units.Quantity): b = kwargs['b'].to(units.kpc).value / self._ro else: b = kwargs['b'] self._aAI = actionAngleIsochrone( ip=IsochronePotential(b=b, normalize=1.)) self._tintJ = kwargs.get('tintJ', 100.) if _APY_LOADED and isinstance(self._tintJ, units.Quantity): self._tintJ= self._tintJ.to(units.Gyr).value\ /time_in_Gyr(self._vo,self._ro) self._ntintJ = kwargs.get('ntintJ', 10000) self._integrate_dt = kwargs.get('dt', None) self._tsJ = nu.linspace(0., self._tintJ, self._ntintJ) self._integrate_method = kwargs.get('integrate_method', 'dopr54_c') self._maxn = kwargs.get('maxn', 3) self._c = False ext_loaded = False if ext_loaded and (('c' in kwargs and kwargs['c']) or not 'c' in kwargs): #pragma: no cover self._c = True else: self._c = False # Check the units self._check_consistent_units() return None