Example #1
0
    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
Example #2
0
    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
Example #3
0
 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
Example #7
0
    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
Example #10
0
    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
Example #11
0
    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
Example #13
0
    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