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= 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 '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 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 = 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 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 actionAngleTorus object INPUT: pot= potential or list of potentials (3D) tol= default tolerance to use when fitting tori (|dJ|/J) dJ= default action difference when computing derivatives (Hessian or Jacobian) OUTPUT: instance HISTORY: 2015-08-07 - Written - Bovy (UofT) """ if not 'pot' in kwargs: #pragma: no cover raise IOError("Must specify pot= for actionAngleTorus") self._pot = flatten_potential(kwargs['pot']) if _isNonAxi(self._pot): raise RuntimeError( "actionAngleTorus for non-axisymmetric potentials is not supported" ) 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: self._c = _check_c(self._pot) if not self._c: raise RuntimeError( 'The given potential is not fully implemented in C; using the actionAngleTorus code is not supported in pure Python' ) else: # pragma: no cover raise RuntimeError( 'actionAngleTorus instances cannot be used, because the actionAngleTorus_c extension failed to load' ) self._tol = kwargs.get('tol', 0.001) self._dJ = kwargs.get('dJ', 0.001) return None
def __init__(self,*args,**kwargs): """ NAME: __init__ PURPOSE: initialize an actionAngleSpherical object INPUT: pot= a Spherical 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: 2013-12-28 - 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 actionAngleSpherical") self._pot= flatten_potential(kwargs['pot']) #Also store a 'planar' (2D) version of the potential if isinstance(self._pot,list): self._2dpot= [p.toPlanar() for p in self._pot] else: self._2dpot= self._pot.toPlanar() #The following for if we ever implement this code in C self._c= False ext_loaded= False if ext_loaded and (('c' in kwargs and kwargs['c']) or not 'c' in kwargs): self._c= True #pragma: no cover else: self._c= False # 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= 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 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 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
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= flatten_potential(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, interpecc=False, **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 interpecc= (False) if True, also interpolate the approximate eccentricity, zmax, rperi, and rapo 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) 2017-12-15 - Written - Bovy (UofT) """ 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= flatten_potential(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 interpecc: mecc, mzmax, mrperi, mrap=\ self._aA.EccZmaxRperiRap(thisR, #R thisv*numpy.cos(thispsi), #vR thisLzs/thisR, #vT numpy.zeros(len(thisR)), #z thisv*numpy.sin(thispsi)) #vz 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) if interpecc: mecc[indx], mzmax[indx], mrperi[indx], mrap[indx]=\ self._aA.EccZmaxRperiRap(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 jr= numpy.reshape(mjr,(nLz,nE,npsi)) jz= numpy.reshape(mjz,(nLz,nE,npsi)) if interpecc: ecc= numpy.reshape(mecc,(nLz,nE,npsi)) zmax= numpy.reshape(mzmax,(nLz,nE,npsi)) rperi= numpy.reshape(mrperi,(nLz,nE,npsi)) rap= numpy.reshape(mrap,(nLz,nE,npsi)) zmaxLzE= numpy.zeros((nLz)) rperiLzE= numpy.zeros((nLz)) rapLzE= numpy.zeros((nLz)) 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)])#:,:]) if interpecc: zmaxLzE[ii]= numpy.amax(zmax[ii,numpy.isfinite(zmax[ii])]) rperiLzE[ii]= numpy.amax(rperi[ii,numpy.isfinite(rperi[ii])]) rapLzE[ii]= numpy.amax(rap[ii,numpy.isfinite(rap[ii])]) jrLzE[(jrLzE == 0.)]= numpy.nanmin(jrLzE[(jrLzE > 0.)]) jzLzE[(jzLzE == 0.)]= numpy.nanmin(jzLzE[(jzLzE > 0.)]) if interpecc: zmaxLzE[(zmaxLzE == 0.)]= numpy.nanmin(zmaxLzE[(zmaxLzE > 0.)]) rperiLzE[(rperiLzE == 0.)]= numpy.nanmin(rperiLzE[(rperiLzE > 0.)]) rapLzE[(rapLzE == 0.)]= numpy.nanmin(rapLzE[(rapLzE > 0.)]) for ii in range(nLz): jr[ii,:,:]/= jrLzE[ii] jz[ii,:,:]/= jzLzE[ii] if interpecc: zmax[ii,:,:]/= zmaxLzE[ii] rperi[ii,:,:]/= rperiLzE[ii] rap[ii,:,:]/= rapLzE[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. if interpecc: ecc[(ecc < 0.)]= 0. ecc[(ecc > 1.)]= 1. ecc[numpy.isnan(ecc)]= 0. ecc[numpy.isinf(ecc)]= 1. zmax[(zmax > 1.)]= 1. zmax[numpy.isnan(zmax)]= 0. zmax[numpy.isinf(zmax)]= 1. rperi[(rperi > 1.)]= 1. rperi[numpy.isnan(rperi)]= 0. rperi[numpy.isinf(rperi)]= 0. # typically orbits that can reach 0 rap[(rap > 1.)]= 1. rap[numpy.isnan(rap)]= 0. rap[numpy.isinf(rap)]= 1. #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) if interpecc: self._ecc= ecc self._zmax= zmax self._rperi= rperi self._rap= rap self._zmaxLzE= zmaxLzE self._rperiLzE= rperiLzE self._rapLzE= rapLzE self._zmaxLzInterp=\ interpolate.InterpolatedUnivariateSpline(self._Lzs, numpy.log(zmaxLzE+10.**-5.),k=3) self._rperiLzInterp=\ interpolate.InterpolatedUnivariateSpline(self._Lzs, numpy.log(rperiLzE+10.**-5.),k=3) self._rapLzInterp=\ interpolate.InterpolatedUnivariateSpline(self._Lzs, numpy.log(rapLzE+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) if interpecc: self._eccFiltered= ndimage.spline_filter(numpy.log(self._ecc+10.**-10.),order=3) self._zmaxFiltered= ndimage.spline_filter(numpy.log(self._zmax+10.**-10.),order=3) self._rperiFiltered= ndimage.spline_filter(numpy.log(self._rperi+10.**-10.),order=3) self._rapFiltered= ndimage.spline_filter(numpy.log(self._rap+10.**-10.),order=3) # Check the units self._check_consistent_units() return None
def __init__(self, progenitor_mass, progenitor=None, pot=None, tdisrupt=None, leading=True, meankvec=[2., 0., 0.3, 0., 0., 0.], sigkvec=[0.4, 0., 0.4, 0.5, 0.5, 0.], ro=None, vo=None): """ NAME: __init__ PURPOSE: Initialize a stream spray DF model of a tidal stream INPUT: progenitor_mass - mass of the progenitor (can be Quantity) tdisrupt= (5 Gyr) time since start of disruption (can be Quantity) leading= (True) if True, model the leading part of the stream if False, model the trailing part progenitor= progenitor orbit as Orbit instance (will be re-integrated, so don't bother integrating the orbit before) meankvec= (Fardal+2015-ish defaults) sigkvec= (Fardal+2015-ish defaults) OUTPUT: Instance HISTORY: 2018-07-31 - Written - Bovy (UofT) """ if _APY_LOADED and isinstance(progenitor_mass, units.Quantity): progenitor_mass= progenitor_mass.to(units.Msun).value\ /bovy_conversion.mass_in_msol(self._vo,self._ro) self._progenitor_mass = progenitor_mass if tdisrupt is None: self._tdisrupt = 5. / bovy_conversion.time_in_Gyr( self._vo, self._ro) else: if _APY_LOADED and isinstance(tdisrupt, units.Quantity): tdisrupt= tdisrupt.to(units.Gyr).value\ /bovy_conversion.time_in_Gyr(self._vo,self._ro) self._tdisrupt = tdisrupt if pot is None: #pragma: no cover raise IOError("pot= must be set") self._pot = flatten_potential(pot) self._progenitor = progenitor() self._progenitor_times = numpy.linspace(0., -self._tdisrupt, 10001) self._progenitor.integrate(self._progenitor_times, self._pot) self._meankvec = numpy.array(meankvec) self._sigkvec = numpy.array(sigkvec) if leading: self._meankvec *= -1. 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
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 = flatten_potential(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