예제 #1
0
 def Jz(self,*args,**kwargs):
     """
     NAME:
        Jz
     PURPOSE:
        evaluate the action jz
     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
        scipy.integrate.quadrature keywords
     OUTPUT:
        jz
     HISTORY:
        2012-07-30 - Written - Bovy (IAS@MPIA)
     """
     meta= actionAngle(*args)
     Phi= galpy.potential.evaluatePotentials(meta._R,meta._z,self._pot)
     Phio= galpy.potential.evaluatePotentials(meta._R,0.,self._pot)
     Ez= Phi-Phio+meta._vz**2./2.
     #Bigger than Ezzmax?
     thisEzZmax= numpy.exp(self._EzZmaxsInterp(meta._R))
     if meta._R > self._Rmax or meta._R < self._Rmin or (Ez != 0. and numpy.log(Ez) > thisEzZmax): #Outside of the grid
         if _PRINTOUTSIDEGRID: #pragma: no cover
             print "Outside of grid in Ez"
         jz= self._aA(meta._R,0.,1.,#these two r dummies
                      0.,math.sqrt(2.*Ez),
                      _justjz=True,
                      **kwargs)[2]
     else:
         jz= (self._jzInterp(meta._R,Ez/thisEzZmax)\
             *(numpy.exp(self._jzEzmaxInterp(meta._R))-10.**-5.))[0][0]
     return jz
예제 #2
0
 def calczmax(self,*args,**kwargs):
     """
     NAME:
        calczmax
     PURPOSE:
        calculate the maximum height
     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
     OUTPUT:
        zmax
     HISTORY:
        2012-06-01 - Written - Bovy (IAS)
     """
     #Set up the actionAngleAxi object
     meta= actionAngle(*args)
     if isinstance(self._pot,list):
         thispot= [p.toPlanar() for p in self._pot]
     else:
         thispot= self._pot.toPlanar()
     if isinstance(self._pot,list):
         thisverticalpot= [p.toVertical(meta._R) for p in self._pot]
     else:
         thisverticalpot= self._pot.toVertical(meta._R)
     aAAxi= actionAngleAxi(*args,pot=thispot,
                            verticalPot=thisverticalpot,
                            gamma=self._gamma)
     return aAAxi.calczmax(**kwargs)
예제 #3
0
 def actionsFreqs(self,*args,**kwargs):
     """
     NAME:
        actionsFreqs
     PURPOSE:
        evaluate the actions and frequencies (jr,lz,jz,Omegar,Omegaphi,Omegaz)
     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
        scipy.integrate.quadrature keywords
     OUTPUT:
         (jr,lz,jz,Omegar,Omegaphi,Omegaz)
     HISTORY:
        2013-09-08 - Written - Bovy (IAS)
     """
     if len(args) == 5: #R,vR.vT, z, vz
         R,vR,vT, z, vz= args
     elif len(args) == 6: #R,vR.vT, z, vz, phi
         R,vR,vT, z, vz, phi= args
     else:
         meta= actionAngle(*args)
         R= meta._R
         vR= meta._vR
         vT= meta._vT
         z= meta._z
         vz= meta._vz
     if isinstance(R,float):
         R= nu.array([R])
         vR= nu.array([vR])
         vT= nu.array([vT])
         z= nu.array([z])
         vz= nu.array([vz])
     if self._c: #pragma: no cover
         pass
     else:
         Lz= R*vT
         Lx= -z*vT
         Ly= z*vR-R*vz
         L2= Lx*Lx+Ly*Ly+Lz*Lz
         E= self._ip(R,z)+vR**2./2.+vT**2./2.+vz**2./2.
         L= nu.sqrt(L2)
         #Actions
         Jphi= Lz
         Jz= L-nu.fabs(Lz)
         Jr= self.amp/nu.sqrt(-2.*E)\
             -0.5*(L+nu.sqrt((L2+4.*self.amp*self.b)))
         #Frequencies
         Omegar= (-2.*E)**1.5/self.amp
         Omegaz= 0.5*(1.+L/nu.sqrt(L2+4.*self.amp*self.b))*Omegar
         Omegaphi= copy.copy(Omegaz)
         indx= Lz < 0.
         Omegaphi[indx]*= -1.
         return (Jr,Jphi,Jz,Omegar,Omegaphi,Omegaz)
 def Jz(self, *args, **kwargs):
     """
     NAME:
        Jz
     PURPOSE:
        evaluate the action jz
     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
        scipy.integrate.quadrature keywords
     OUTPUT:
        jz
     HISTORY:
        2012-07-30 - Written - Bovy (IAS@MPIA)
     """
     meta = actionAngle(*args)
     Phi = galpy.potential.evaluatePotentials(meta._R, meta._z, self._pot)
     Phio = galpy.potential.evaluatePotentials(meta._R, 0., self._pot)
     Ez = Phi - Phio + meta._vz**2. / 2.
     #Bigger than Ezzmax?
     thisEzZmax = numpy.exp(self._EzZmaxsInterp(meta._R))
     if meta._R > self._Rmax or meta._R < self._Rmin or (
             Ez != 0. and numpy.log(Ez) > thisEzZmax):  #Outside of the grid
         if _PRINTOUTSIDEGRID:  #pragma: no cover
             print("Outside of grid in Ez")
         jz = self._aA(
             meta._R,
             0.,
             1.,  #these two r dummies
             0.,
             math.sqrt(2. * Ez),
             _justjz=True,
             **kwargs)[2]
     else:
         jz= (self._jzInterp(meta._R,Ez/thisEzZmax)\
             *(numpy.exp(self._jzEzmaxInterp(meta._R))-10.**-5.))[0][0]
     return jz
예제 #5
0
 def __call__(self,*args,**kwargs):
     """
     NAME:
        __call__
     PURPOSE:
        evaluate the actions (jr,lz,jz)
     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
        scipy.integrate.quadrature keywords
     OUTPUT:
        (jr,lz,jz)
     HISTORY:
        2012-07-27 - Written - Bovy (IAS@MPIA)
     NOTE:
        For a Miyamoto-Nagai potential, this seems accurate to 0.1% and takes ~0.13 ms
        For a MWPotential, this takes ~ 0.17 ms
     """
     if len(args) == 5: #R,vR.vT, z, vz
         R,vR,vT, z, vz= args
     elif len(args) == 6: #R,vR.vT, z, vz, phi
         R,vR,vT, z, vz, phi= args
     else:
         meta= actionAngle(*args)
         R= meta._R
         vR= meta._vR
         vT= meta._vT
         z= meta._z
         vz= meta._vz
     #First work on the vertical action
     Phi= galpy.potential.evaluatePotentials(R,z,self._pot)
     try:
         Phio= galpy.potential.evaluatePotentials(R,numpy.zeros(len(R)),self._pot)
     except TypeError:
         Phio= galpy.potential.evaluatePotentials(R,0.,self._pot)
     Ez= Phi-Phio+vz**2./2.
     #Bigger than Ezzmax?
     thisEzZmax= numpy.exp(self._EzZmaxsInterp(R))
     if isinstance(R,numpy.ndarray):
         indx= (R > self._Rmax)
         indx+= (R < self._Rmin)
         indx+= (Ez != 0.)*(numpy.log(Ez) > thisEzZmax)
         indxc= True-indx
         jz= numpy.empty(R.shape)
         if numpy.sum(indxc) > 0:
             jz[indxc]= (self._jzInterp.ev(R[indxc],Ez[indxc]/thisEzZmax[indxc])\
                             *(numpy.exp(self._jzEzmaxInterp(R[indxc]))-10.**-5.))
         if numpy.sum(indx) > 0:
             jz[indx]= self._aA(R[indx],
                                numpy.zeros(numpy.sum(indx)),
                                numpy.ones(numpy.sum(indx)),#these two r dummies
                                numpy.zeros(numpy.sum(indx)),
                                numpy.sqrt(2.*Ez[indx]),
                                _justjz=True,
                                **kwargs)[2]
     else:
         if R > self._Rmax or R < self._Rmin or (Ez != 0 and numpy.log(Ez) > thisEzZmax): #Outside of the grid
             if _PRINTOUTSIDEGRID: #pragma: no cover
                 print "Outside of grid in Ez", R > self._Rmax , R < self._Rmin , (Ez != 0 and numpy.log(Ez) > thisEzZmax)
             jz= self._aA(R,0.,1.,#these two r dummies
                          0.,math.sqrt(2.*Ez),
                          _justjz=True,
                          **kwargs)[2]
         else:
             jz= (self._jzInterp(R,Ez/thisEzZmax)\
                      *(numpy.exp(self._jzEzmaxInterp(R))-10.**-5.))[0][0]
     #Radial action
     ERLz= numpy.fabs(R*vT)+self._gamma*jz
     ER= Phio+vR**2./2.+ERLz**2./2./R**2.
     thisRL= self._RLInterp(ERLz)
     thisERRL= -numpy.exp(self._ERRLInterp(ERLz))+self._ERRLmax
     thisERRa= -numpy.exp(self._ERRaInterp(ERLz))+self._ERRamax
     if isinstance(R,numpy.ndarray):
         indx= ((ER-thisERRa)/(thisERRL-thisERRa) > 1.)\
             *(((ER-thisERRa)/(thisERRL-thisERRa)-1.) < 10.**-2.)
         ER[indx]= thisERRL[indx]
         indx= ((ER-thisERRa)/(thisERRL-thisERRa) < 0.)\
             *((ER-thisERRa)/(thisERRL-thisERRa) > -10.**-2.)
         ER[indx]= thisERRa[indx]
         indx= (ERLz < self._Lzmin)
         indx+= (ERLz > self._Lzmax)
         indx+= ((ER-thisERRa)/(thisERRL-thisERRa) > 1.)
         indx+= ((ER-thisERRa)/(thisERRL-thisERRa) < 0.)
         indxc= True-indx
         jr= numpy.empty(R.shape)
         if numpy.sum(indxc) > 0:
             jr[indxc]= (self._jrInterp.ev(ERLz[indxc],
                                           (ER[indxc]-thisERRa[indxc])/(thisERRL[indxc]-thisERRa[indxc]))\
                             *(numpy.exp(self._jrERRaInterp(ERLz[indxc]))-10.**-5.))
         if numpy.sum(indx) > 0:
             jr[indx]= self._aA(thisRL[indx],
                                numpy.sqrt(2.*(ER[indx]-galpy.potential.evaluatePotentials(thisRL[indx],0.,self._pot))-ERLz[indx]**2./thisRL[indx]**2.),
                                ERLz[indx]/thisRL[indx],
                                numpy.zeros(len(thisRL)),
                                numpy.zeros(len(thisRL)),
                                _justjr=True,
                                **kwargs)[0]                
     else:
         if (ER-thisERRa)/(thisERRL-thisERRa) > 1. \
                 and ((ER-thisERRa)/(thisERRL-thisERRa)-1.) < 10.**-2.:
             ER= thisERRL
         elif (ER-thisERRa)/(thisERRL-thisERRa) < 0. \
                 and (ER-thisERRa)/(thisERRL-thisERRa) > -10.**-2.:
             ER= thisERRa
         #Outside of grid?
         if ERLz < self._Lzmin or ERLz > self._Lzmax \
                 or (ER-thisERRa)/(thisERRL-thisERRa) > 1. \
                 or (ER-thisERRa)/(thisERRL-thisERRa) < 0.:
             if _PRINTOUTSIDEGRID: #pragma: no cover
                 print "Outside of grid in ER/Lz", ERLz < self._Lzmin , ERLz > self._Lzmax \
                     , (ER-thisERRa)/(thisERRL-thisERRa) > 1. \
                     , (ER-thisERRa)/(thisERRL-thisERRa) < 0., ER, thisERRL, thisERRa, (ER-thisERRa)/(thisERRL-thisERRa)
             jr= self._aA(thisRL[0],
                          numpy.sqrt(2.*(ER-galpy.potential.evaluatePotentials(thisRL,0.,self._pot))-ERLz**2./thisRL**2.)[0],
                          (ERLz/thisRL)[0],
                          0.,0.,
                          _justjr=True,
                          **kwargs)[0]
         else:
             jr= (self._jrInterp(ERLz,
                                 (ER-thisERRa)/(thisERRL-thisERRa))\
                      *(numpy.exp(self._jrERRaInterp(ERLz))-10.**-5.))[0][0]
     return (jr,R*vT,jz)
 def __call__(self, *args, **kwargs):
     """
     NAME:
        __call__
     PURPOSE:
        evaluate the actions (jr,lz,jz)
     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
        scipy.integrate.quadrature keywords
     OUTPUT:
        (jr,lz,jz)
     HISTORY:
        2012-07-27 - Written - Bovy (IAS@MPIA)
     NOTE:
        For a Miyamoto-Nagai potential, this seems accurate to 0.1% and takes ~0.13 ms
        For a MWPotential, this takes ~ 0.17 ms
     """
     if len(args) == 5:  #R,vR.vT, z, vz
         R, vR, vT, z, vz = args
     elif len(args) == 6:  #R,vR.vT, z, vz, phi
         R, vR, vT, z, vz, phi = args
     else:
         meta = actionAngle(*args)
         R = meta._R
         vR = meta._vR
         vT = meta._vT
         z = meta._z
         vz = meta._vz
     #First work on the vertical action
     Phi = galpy.potential.evaluatePotentials(R, z, self._pot)
     try:
         Phio = galpy.potential.evaluatePotentials(R, numpy.zeros(len(R)),
                                                   self._pot)
     except TypeError:
         Phio = galpy.potential.evaluatePotentials(R, 0., self._pot)
     Ez = Phi - Phio + vz**2. / 2.
     #Bigger than Ezzmax?
     thisEzZmax = numpy.exp(self._EzZmaxsInterp(R))
     if isinstance(R, numpy.ndarray):
         indx = (R > self._Rmax)
         indx += (R < self._Rmin)
         indx += (Ez != 0.) * (numpy.log(Ez) > thisEzZmax)
         indxc = True - indx
         jz = numpy.empty(R.shape)
         if numpy.sum(indxc) > 0:
             jz[indxc]= (self._jzInterp.ev(R[indxc],Ez[indxc]/thisEzZmax[indxc])\
                             *(numpy.exp(self._jzEzmaxInterp(R[indxc]))-10.**-5.))
         if numpy.sum(indx) > 0:
             jz[indx] = self._aA(
                 R[indx],
                 numpy.zeros(numpy.sum(indx)),
                 numpy.ones(numpy.sum(indx)),  #these two r dummies
                 numpy.zeros(numpy.sum(indx)),
                 numpy.sqrt(2. * Ez[indx]),
                 _justjz=True,
                 **kwargs)[2]
     else:
         if R > self._Rmax or R < self._Rmin or (
                 Ez != 0
                 and numpy.log(Ez) > thisEzZmax):  #Outside of the grid
             if _PRINTOUTSIDEGRID:  #pragma: no cover
                 print("Outside of grid in Ez", R > self._Rmax,
                       R < self._Rmin,
                       (Ez != 0 and numpy.log(Ez) > thisEzZmax))
             jz = self._aA(
                 R,
                 0.,
                 1.,  #these two r dummies
                 0.,
                 math.sqrt(2. * Ez),
                 _justjz=True,
                 **kwargs)[2]
         else:
             jz= (self._jzInterp(R,Ez/thisEzZmax)\
                      *(numpy.exp(self._jzEzmaxInterp(R))-10.**-5.))[0][0]
     #Radial action
     ERLz = numpy.fabs(R * vT) + self._gamma * jz
     ER = Phio + vR**2. / 2. + ERLz**2. / 2. / R**2.
     thisRL = self._RLInterp(ERLz)
     thisERRL = -numpy.exp(self._ERRLInterp(ERLz)) + self._ERRLmax
     thisERRa = -numpy.exp(self._ERRaInterp(ERLz)) + self._ERRamax
     if isinstance(R, numpy.ndarray):
         indx= ((ER-thisERRa)/(thisERRL-thisERRa) > 1.)\
             *(((ER-thisERRa)/(thisERRL-thisERRa)-1.) < 10.**-2.)
         ER[indx] = thisERRL[indx]
         indx= ((ER-thisERRa)/(thisERRL-thisERRa) < 0.)\
             *((ER-thisERRa)/(thisERRL-thisERRa) > -10.**-2.)
         ER[indx] = thisERRa[indx]
         indx = (ERLz < self._Lzmin)
         indx += (ERLz > self._Lzmax)
         indx += ((ER - thisERRa) / (thisERRL - thisERRa) > 1.)
         indx += ((ER - thisERRa) / (thisERRL - thisERRa) < 0.)
         indxc = True - indx
         jr = numpy.empty(R.shape)
         if numpy.sum(indxc) > 0:
             jr[indxc]= (self._jrInterp.ev(ERLz[indxc],
                                           (ER[indxc]-thisERRa[indxc])/(thisERRL[indxc]-thisERRa[indxc]))\
                             *(numpy.exp(self._jrERRaInterp(ERLz[indxc]))-10.**-5.))
         if numpy.sum(indx) > 0:
             jr[indx] = self._aA(
                 thisRL[indx],
                 numpy.sqrt(2. *
                            (ER[indx] - galpy.potential.evaluatePotentials(
                                thisRL[indx], 0., self._pot)) -
                            ERLz[indx]**2. / thisRL[indx]**2.),
                 ERLz[indx] / thisRL[indx],
                 numpy.zeros(len(thisRL)),
                 numpy.zeros(len(thisRL)),
                 _justjr=True,
                 **kwargs)[0]
     else:
         if (ER-thisERRa)/(thisERRL-thisERRa) > 1. \
                 and ((ER-thisERRa)/(thisERRL-thisERRa)-1.) < 10.**-2.:
             ER = thisERRL
         elif (ER-thisERRa)/(thisERRL-thisERRa) < 0. \
                 and (ER-thisERRa)/(thisERRL-thisERRa) > -10.**-2.:
             ER = thisERRa
         #Outside of grid?
         if ERLz < self._Lzmin or ERLz > self._Lzmax \
                 or (ER-thisERRa)/(thisERRL-thisERRa) > 1. \
                 or (ER-thisERRa)/(thisERRL-thisERRa) < 0.:
             if _PRINTOUTSIDEGRID:  #pragma: no cover
                 print("Outside of grid in ER/Lz", ERLz < self._Lzmin , ERLz > self._Lzmax \
                     , (ER-thisERRa)/(thisERRL-thisERRa) > 1. \
                     , (ER-thisERRa)/(thisERRL-thisERRa) < 0., ER, thisERRL, thisERRa, (ER-thisERRa)/(thisERRL-thisERRa))
             jr = self._aA(
                 thisRL[0],
                 numpy.sqrt(2. * (ER - galpy.potential.evaluatePotentials(
                     thisRL, 0., self._pot)) - ERLz**2. / thisRL**2.)[0],
                 (ERLz / thisRL)[0],
                 0.,
                 0.,
                 _justjr=True,
                 **kwargs)[0]
         else:
             jr= (self._jrInterp(ERLz,
                                 (ER-thisERRa)/(thisERRL-thisERRa))\
                      *(numpy.exp(self._jrERRaInterp(ERLz))-10.**-5.))[0][0]
     return (jr, R * vT, jz)
예제 #7
0
 def __call__(self,*args,**kwargs):
     """
     NAME:
        __call__
     PURPOSE:
        evaluate the actions (jr,lz,jz)
     INPUT:
        Either:
           R,vR,vT,z,vz
        scipy.integrate.quadrature keywords (for off-the-grid calcs)
     OUTPUT:
        (jr,lz,jz)
     HISTORY:
        2012-11-29 - Written - Bovy (IAS)
     """
     if len(args) == 5: #R,vR.vT, z, vz
         R,vR,vT, z, vz= args
     elif len(args) == 6: #R,vR.vT, z, vz, phi
         R,vR,vT, z, vz, phi= args
     else:
         meta= actionAngle(*args)
         R= meta._R
         vR= meta._vR
         vT= meta._vT
         z= meta._z
         vz= meta._vz
     Lz= R*vT
     Phi= galpy.potential.evaluatePotentials(R,z,self._pot)
     E= Phi+vR**2./2.+vT**2./2.+vz**2./2.
     thisRL= self._RLInterp(Lz)
     thisERL= -numpy.exp(self._ERLInterp(Lz))+self._ERLmax
     thisERa= -numpy.exp(self._ERaInterp(Lz))+self._ERamax
     if isinstance(R,numpy.ndarray):
         if len(R) == 1 and not isinstance(thisERL,numpy.ndarray):
             thisERL= numpy.array([thisERL])
             thisERa= numpy.array([thisERa])
         indx= ((E-thisERa)/(thisERL-thisERa) > 1.)\
             *(((E-thisERa)/(thisERL-thisERa)-1.) < 10.**-2.)
         E[indx]= thisERL[indx]
         indx= ((E-thisERa)/(thisERL-thisERa) < 0.)\
             *((E-thisERa)/(thisERL-thisERa) > -10.**-2.)
         E[indx]= thisERa[indx]
         indx= (Lz < self._Lzmin)
         indx+= (Lz > self._Lzmax)
         indx+= ((E-thisERa)/(thisERL-thisERa) > 1.)
         indx+= ((E-thisERa)/(thisERL-thisERa) < 0.)
         indxc= True-indx
         jr= numpy.empty(R.shape)
         jz= numpy.empty(R.shape)
         if numpy.sum(indxc) > 0:
             u0= numpy.exp(self._logu0Interp.ev(Lz[indxc],
                                                (_Efunc(E[indxc],thisERL[indxc])-_Efunc(thisERa[indxc],thisERL[indxc]))/(_Efunc(thisERL[indxc],thisERL[indxc])-_Efunc(thisERa[indxc],thisERL[indxc]))))
             #                                                   (E[indxc]-thisERa[indxc])/(thisERL[indxc]-thisERa[indxc])))
             sinh2u0= numpy.sinh(u0)**2.
             thisEr= self.Er(R[indxc],z[indxc],vR[indxc],vz[indxc],
                             E[indxc],Lz[indxc],sinh2u0,u0)
             thisEz= self.Ez(R[indxc],z[indxc],vR[indxc],vz[indxc],
                             E[indxc],Lz[indxc],sinh2u0,u0)
             thisv2= self.vatu0(E[indxc],Lz[indxc],u0,self._delta*numpy.sinh(u0),retv2=True)
             cos2psi= 2.*thisEr/thisv2/(1.+sinh2u0) #latter is cosh2u0
             cos2psi[(cos2psi > 1.)*(cos2psi < 1.+10.**-5.)]= 1.
             indxCos2psi= (cos2psi > 1.)
             indxCos2psi+= (cos2psi < 0.)
             indxc[indxc]= True-indxCos2psi#Handle these two cases as off-grid
             indx= True-indxc
             psi= numpy.arccos(numpy.sqrt(cos2psi[True-indxCos2psi]))
             coords= numpy.empty((3,numpy.sum(indxc)))
             coords[0,:]= (Lz[indxc]-self._Lzmin)/(self._Lzmax-self._Lzmin)*(self._nLz-1.)
             #coords[1,:]= (E[indxc]-thisERa[indxc])/(thisERL[indxc]-thisERa[indxc])*(self._nE-1.)
             y= (_Efunc(E[indxc],thisERL[indxc])-_Efunc(thisERa[indxc],thisERL[indxc]))/(_Efunc(thisERL[indxc],thisERL[indxc])-_Efunc(thisERa[indxc],thisERL[indxc]))
             coords[1,:]= y*(self._nE-1.)
             coords[2,:]= psi/numpy.pi*2.*(self._npsi-1.)
             jr[indxc]= (numpy.exp(ndimage.interpolation.map_coordinates(self._jrFiltered,
                                                                         coords,
                                                                         order=3,
                                                                         prefilter=False))-10.**-10.)*(numpy.exp(self._jrLzInterp(Lz[indxc]))-10.**-5.)
             #Switch to Ez-calculated psi
             sin2psi= 2.*thisEz[True-indxCos2psi]/thisv2[True-indxCos2psi]/(1.+sinh2u0[True-indxCos2psi]) #latter is cosh2u0
             sin2psi[(sin2psi > 1.)*(sin2psi < 1.+10.**-5.)]= 1.
             indxSin2psi= (sin2psi > 1.)
             indxSin2psi+= (sin2psi < 0.)
             indxc[indxc]= True-indxSin2psi#Handle these two cases as off-grid
             indx= True-indxc
             psiz= numpy.arcsin(numpy.sqrt(sin2psi[True-indxSin2psi]))
             newcoords= numpy.empty((3,numpy.sum(indxc)))
             newcoords[0:2,:]= coords[0:2,True-indxSin2psi]
             newcoords[2,:]= psiz/numpy.pi*2.*(self._npsi-1.)
             jz[indxc]= (numpy.exp(ndimage.interpolation.map_coordinates(self._jzFiltered,
                                                                        newcoords,
                                                                        order=3,
                                                                        prefilter=False))-10.**-10.)*(numpy.exp(self._jzLzInterp(Lz[indxc]))-10.**-5.)
         if numpy.sum(indx) > 0:
             jrindiv, lzindiv, jzindiv= self._aA(R[indx],
                                                 vR[indx],
                                                 vT[indx],
                                                 z[indx],
                                                 vz[indx],
                                                 **kwargs)
             jr[indx]= jrindiv
             jz[indx]= jzindiv
             """
             jrindiv= numpy.empty(numpy.sum(indx))
             jzindiv= numpy.empty(numpy.sum(indx))
             for ii in range(numpy.sum(indx)):
                 try:
                     thisaA= actionAngleStaeckel.actionAngleStaeckelSingle(\
                         R[indx][ii], #R
                         vR[indx][ii], #vR
                         vT[indx][ii], #vT
                         z[indx][ii], #z
                         vz[indx][ii], #vz
                         pot=self._pot,delta=self._delta)
                     jrindiv[ii]= thisaA.JR(fixed_quad=True)[0]
                     jzindiv[ii]= thisaA.Jz(fixed_quad=True)[0]
                 except (UnboundError,OverflowError):
                     jrindiv[ii]= numpy.nan
                     jzindiv[ii]= numpy.nan
             jr[indx]= jrindiv
             jz[indx]= jzindiv
             """
     else:
         jr,Lz, jz= self(numpy.array([R]),
                         numpy.array([vR]),
                         numpy.array([vT]),
                         numpy.array([z]),
                         numpy.array([vz]),
                         **kwargs)
         return (jr[0],Lz[0],jz[0])
     return (jr,R*vT,jz)
 def __call__(self, *args, **kwargs):
     """
     NAME:
        __call__
     PURPOSE:
        evaluate the actions (jr,lz,jz)
     INPUT:
        Either:
           R,vR,vT,z,vz
        scipy.integrate.quadrature keywords (for off-the-grid calcs)
     OUTPUT:
        (jr,lz,jz)
     HISTORY:
        2012-11-29 - Written - Bovy (IAS)
     """
     if len(args) == 5:  #R,vR.vT, z, vz
         R, vR, vT, z, vz = args
     elif len(args) == 6:  #R,vR.vT, z, vz, phi
         R, vR, vT, z, vz, phi = args
     else:
         meta = actionAngle(*args)
         R = meta._R
         vR = meta._vR
         vT = meta._vT
         z = meta._z
         vz = meta._vz
     Lz = R * vT
     Phi = galpy.potential.evaluatePotentials(R, z, self._pot)
     E = Phi + vR**2. / 2. + vT**2. / 2. + vz**2. / 2.
     thisERL = -numpy.exp(self._ERLInterp(Lz)) + self._ERLmax
     thisERa = -numpy.exp(self._ERaInterp(Lz)) + self._ERamax
     if isinstance(R, numpy.ndarray):
         indx= ((E-thisERa)/(thisERL-thisERa) > 1.)\
             *(((E-thisERa)/(thisERL-thisERa)-1.) < 10.**-2.)
         E[indx] = thisERL[indx]
         indx= ((E-thisERa)/(thisERL-thisERa) < 0.)\
             *((E-thisERa)/(thisERL-thisERa) > -10.**-2.)
         E[indx] = thisERa[indx]
         indx = (Lz < self._Lzmin)
         indx += (Lz > self._Lzmax)
         indx += ((E - thisERa) / (thisERL - thisERa) > 1.)
         indx += ((E - thisERa) / (thisERL - thisERa) < 0.)
         indxc = True - indx
         jr = numpy.empty(R.shape)
         jz = numpy.empty(R.shape)
         if numpy.sum(indxc) > 0:
             u0 = numpy.exp(
                 self._logu0Interp.ev(
                     Lz[indxc], (_Efunc(E[indxc], thisERL[indxc]) -
                                 _Efunc(thisERa[indxc], thisERL[indxc])) /
                     (_Efunc(thisERL[indxc], thisERL[indxc]) -
                      _Efunc(thisERa[indxc], thisERL[indxc]))))
             sinh2u0 = numpy.sinh(u0)**2.
             thisEr = self.Er(R[indxc], z[indxc], vR[indxc], vz[indxc],
                              E[indxc], Lz[indxc], sinh2u0, u0)
             thisEz = self.Ez(R[indxc], z[indxc], vR[indxc], vz[indxc],
                              E[indxc], Lz[indxc], sinh2u0, u0)
             thisv2 = self.vatu0(E[indxc],
                                 Lz[indxc],
                                 u0,
                                 self._delta * numpy.sinh(u0),
                                 retv2=True)
             cos2psi = 2. * thisEr / thisv2 / (1. + sinh2u0
                                               )  #latter is cosh2u0
             cos2psi[(cos2psi > 1.) * (cos2psi < 1. + 10.**-5.)] = 1.
             indxCos2psi = (cos2psi > 1.)
             indxCos2psi += (cos2psi < 0.)
             indxc[
                 indxc] = True - indxCos2psi  #Handle these two cases as off-grid
             indx = True - indxc
             psi = numpy.arccos(numpy.sqrt(cos2psi[True - indxCos2psi]))
             coords = numpy.empty((3, numpy.sum(indxc)))
             coords[0, :] = (Lz[indxc] - self._Lzmin) / (
                 self._Lzmax - self._Lzmin) * (self._nLz - 1.)
             y = (_Efunc(E[indxc], thisERL[indxc]) -
                  _Efunc(thisERa[indxc], thisERL[indxc])) / (
                      _Efunc(thisERL[indxc], thisERL[indxc]) -
                      _Efunc(thisERa[indxc], thisERL[indxc]))
             coords[1, :] = y * (self._nE - 1.)
             coords[2, :] = psi / numpy.pi * 2. * (self._npsi - 1.)
             jr[indxc] = (numpy.exp(
                 ndimage.interpolation.map_coordinates(
                     self._jrFiltered, coords, order=3, prefilter=False)) -
                          10.**-10.) * (numpy.exp(
                              self._jrLzInterp(Lz[indxc])) - 10.**-5.)
             #Switch to Ez-calculated psi
             sin2psi = 2. * thisEz[True - indxCos2psi] / thisv2[
                 True - indxCos2psi] / (1. + sinh2u0[True - indxCos2psi]
                                        )  #latter is cosh2u0
             sin2psi[(sin2psi > 1.) * (sin2psi < 1. + 10.**-5.)] = 1.
             indxSin2psi = (sin2psi > 1.)
             indxSin2psi += (sin2psi < 0.)
             indxc[
                 indxc] = True - indxSin2psi  #Handle these two cases as off-grid
             indx = True - indxc
             psiz = numpy.arcsin(numpy.sqrt(sin2psi[True - indxSin2psi]))
             newcoords = numpy.empty((3, numpy.sum(indxc)))
             newcoords[0:2, :] = coords[0:2, True - indxSin2psi]
             newcoords[2, :] = psiz / numpy.pi * 2. * (self._npsi - 1.)
             jz[indxc] = (numpy.exp(
                 ndimage.interpolation.map_coordinates(
                     self._jzFiltered, newcoords, order=3,
                     prefilter=False)) - 10.**-10.) * (
                         numpy.exp(self._jzLzInterp(Lz[indxc])) - 10.**-5.)
         if numpy.sum(indx) > 0:
             jrindiv, lzindiv, jzindiv = self._aA(R[indx], vR[indx],
                                                  vT[indx], z[indx],
                                                  vz[indx], **kwargs)
             jr[indx] = jrindiv
             jz[indx] = jzindiv
             """
             jrindiv= numpy.empty(numpy.sum(indx))
             jzindiv= numpy.empty(numpy.sum(indx))
             for ii in range(numpy.sum(indx)):
                 try:
                     thisaA= actionAngleStaeckel.actionAngleStaeckelSingle(\
                         R[indx][ii], #R
                         vR[indx][ii], #vR
                         vT[indx][ii], #vT
                         z[indx][ii], #z
                         vz[indx][ii], #vz
                         pot=self._pot,delta=self._delta)
                     jrindiv[ii]= thisaA.JR(fixed_quad=True)[0]
                     jzindiv[ii]= thisaA.Jz(fixed_quad=True)[0]
                 except (UnboundError,OverflowError):
                     jrindiv[ii]= numpy.nan
                     jzindiv[ii]= numpy.nan
             jr[indx]= jrindiv
             jz[indx]= jzindiv
             """
     else:
         jr, Lz, jz = self(numpy.array([R]), numpy.array([vR]),
                           numpy.array([vT]), numpy.array([z]),
                           numpy.array([vz]), **kwargs)
         return (jr[0], Lz[0], jz[0])
     jr[jr < 0.] = 0.
     jz[jz < 0.] = 0.
     return (jr, R * vT, jz)
예제 #9
0
 def __call__(self,*args,**kwargs):
     """
     NAME:
        __call__
     PURPOSE:
        evaluate the actions (jr,lz,jz)
     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
        scipy.integrate.quadrature keywords
        _justjr, _justjz= if True, only calculate the radial or vertical action (internal use)
     OUTPUT:
        (jr,lz,jz), where jr=[jr,jrerr], and jz=[jz,jzerr]
     HISTORY:
        2012-07-26 - Written - Bovy (IAS@MPIA)
     """
     if ((self._c and not ('c' in kwargs and not kwargs['c']))\
             or (ext_loaded and (('c' in kwargs and kwargs['c'])))) \
             and _check_c(self._pot):
         if len(args) == 5: #R,vR.vT, z, vz
             R,vR,vT, z, vz= args
         elif len(args) == 6: #R,vR.vT, z, vz, phi
             R,vR,vT, z, vz, phi= args
         else:
             meta= actionAngle(*args)
             R= meta._R
             vR= meta._vR
             vT= meta._vT
             z= meta._z
             vz= meta._vz
         if isinstance(R,float):
             R= nu.array([R])
             vR= nu.array([vR])
             vT= nu.array([vT])
             z= nu.array([z])
             vz= nu.array([vz])
         Lz= R*vT
         jr, jz, err= actionAngleAdiabatic_c.actionAngleAdiabatic_c(\
             self._pot,self._gamma,R,vR,vT,z,vz)
         if err == 0:
             return (jr,Lz,jz)
         else: #pragma: no cover
             raise RuntimeError("C-code for calculation actions failed; try with c=False")
     else:
         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
         kwargs.pop('c',None)
         if (len(args) == 5 or len(args) == 6) \
                 and isinstance(args[0],nu.ndarray):
             ojr= nu.zeros((len(args[0])))
             olz= nu.zeros((len(args[0])))
             ojz= nu.zeros((len(args[0])))
             for ii in range(len(args[0])):
                 if len(args) == 5:
                     targs= (args[0][ii],args[1][ii],args[2][ii],
                             args[3][ii],args[4][ii])
                 elif len(args) == 6:
                     targs= (args[0][ii],args[1][ii],args[2][ii],
                             args[3][ii],args[4][ii],args[5][ii])
                 tjr,tlz,tjz= self(*targs,**copy.copy(kwargs))
                 ojr[ii]= tjr
                 ojz[ii]= tjz
                 olz[ii]= tlz
             return (ojr,olz,ojz)
         else:
             #Set up the actionAngleAxi object
             meta= actionAngle(*args)
             if isinstance(self._pot,list):
                 thispot= [p.toPlanar() for p in self._pot]
             else:
                 thispot= self._pot.toPlanar()
             if isinstance(self._pot,list):
                 thisverticalpot= [p.toVertical(meta._R) for p in self._pot]
             else:
                 thisverticalpot= self._pot.toVertical(meta._R)
             aAAxi= actionAngleAxi(*args,pot=thispot,
                                    verticalPot=thisverticalpot,
                                    gamma=self._gamma)
             if kwargs.get('_justjr',False):
                 kwargs.pop('_justjr')
                 return (aAAxi.JR(**kwargs),nu.nan,nu.nan)
             elif kwargs.get('_justjz',False):
                 kwargs.pop('_justjz')
                 return (nu.nan,nu.nan,aAAxi.Jz(**kwargs))
             else:
                 return (aAAxi.JR(**kwargs),aAAxi._R*aAAxi._vT,aAAxi.Jz(**kwargs))
예제 #10
0
 def __call__(self, *args, **kwargs):
     """
     NAME:
        __call__
     PURPOSE:
        evaluate the actions (jr,lz,jz)
     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
         c= True/False; overrides the object's c= keyword to use C or not
        scipy.integrate.quadrature keywords
     OUTPUT:
        (jr,lz,jz)
     HISTORY:
        2012-11-27 - Written - Bovy (IAS)
     """
     if ((self._c and not ('c' in kwargs and not kwargs['c']))\
             or (ext_loaded and (('c' in kwargs and kwargs['c'])))) \
             and _check_c(self._pot):
         if len(args) == 5:  #R,vR.vT, z, vz
             R, vR, vT, z, vz = args
         elif len(args) == 6:  #R,vR.vT, z, vz, phi
             R, vR, vT, z, vz, phi = args
         else:
             meta = actionAngle(*args)
             R = meta._R
             vR = meta._vR
             vT = meta._vT
             z = meta._z
             vz = meta._vz
         if isinstance(R, float):
             R = nu.array([R])
             vR = nu.array([vR])
             vT = nu.array([vT])
             z = nu.array([z])
             vz = nu.array([vz])
         Lz = R * vT
         if self._useu0:
             #First calculate u0
             if 'u0' in kwargs:
                 u0 = nu.asarray(kwargs['u0'])
             else:
                 E = nu.array([
                     evaluatePotentials(R[ii], z[ii], self._pot) +
                     vR[ii]**2. / 2. + vz[ii]**2. / 2. + vT[ii]**2. / 2.
                     for ii in range(len(R))
                 ])
                 u0 = actionAngleStaeckel_c.actionAngleStaeckel_calcu0(
                     E, Lz, self._pot, self._delta)[0]
             kwargs.pop('u0', None)
         else:
             u0 = None
         jr, jz, err= actionAngleStaeckel_c.actionAngleStaeckel_c(\
             self._pot,self._delta,R,vR,vT,z,vz,u0=u0)
         if err == 0:
             return (jr, Lz, jz)
         else:  #pragma: no cover
             raise RuntimeError(
                 "C-code for calculation actions failed; try with c=False")
     else:
         if 'c' in kwargs and kwargs['c'] and not self._c:  #pragma: no cover
             warnings.warn(
                 "C module not used because potential does not have a C implementation",
                 galpyWarning)
         kwargs.pop('c', None)
         if (len(args) == 5 or len(args) == 6) \
                 and isinstance(args[0],nu.ndarray):
             ojr = nu.zeros((len(args[0])))
             olz = nu.zeros((len(args[0])))
             ojz = nu.zeros((len(args[0])))
             for ii in range(len(args[0])):
                 if len(args) == 5:
                     targs = (args[0][ii], args[1][ii], args[2][ii],
                              args[3][ii], args[4][ii])
                 elif len(args) == 6:
                     targs = (args[0][ii], args[1][ii], args[2][ii],
                              args[3][ii], args[4][ii], args[5][ii])
                 tjr, tlz, tjz = self(*targs, **copy.copy(kwargs))
                 ojr[ii] = tjr
                 ojz[ii] = tjz
                 olz[ii] = tlz
             return (ojr, olz, ojz)
         else:
             #Set up the actionAngleStaeckelSingle object
             aASingle = actionAngleStaeckelSingle(*args,
                                                  pot=self._pot,
                                                  delta=self._delta)
             return (aASingle.JR(**copy.copy(kwargs)),
                     aASingle._R * aASingle._vT,
                     aASingle.Jz(**copy.copy(kwargs)))
예제 #11
0
 def actionsFreqsAngles(self, *args, **kwargs):
     """
     NAME:
        actionsFreqsAngles
     PURPOSE:
        evaluate the actions, frequencies, and angles 
        (jr,lz,jz,Omegar,Omegaphi,Omegaz,angler,anglephi,anglez)
     INPUT:
        Either:
           a) R,vR,vT,z,vz,phi (MUST HAVE PHI)
           b) Orbit instance: initial condition used if that's it, orbit(t)
              if there is a time given as well
        scipy.integrate.quadrature keywords
     OUTPUT:
         (jr,lz,jz,Omegar,Omegaphi,Omegaz,angler,anglephi,anglez)
     HISTORY:
        2013-08-28 - Written - Bovy (IAS)
     """
     if ((self._c and not ('c' in kwargs and not kwargs['c']))\
             or (ext_loaded and (('c' in kwargs and kwargs['c'])))) \
             and _check_c(self._pot):
         if len(args) == 5:  #R,vR.vT, z, vz pragma: no cover
             raise IOError("Must specify phi")
         elif len(args) == 6:  #R,vR.vT, z, vz, phi
             R, vR, vT, z, vz, phi = args
         else:
             meta = actionAngle(*args)
             R = meta._R
             vR = meta._vR
             vT = meta._vT
             z = meta._z
             vz = meta._vz
             phi = meta._phi
         if isinstance(R, float):
             R = nu.array([R])
             vR = nu.array([vR])
             vT = nu.array([vT])
             z = nu.array([z])
             vz = nu.array([vz])
             phi = nu.array([phi])
         Lz = R * vT
         if self._useu0:
             #First calculate u0
             if 'u0' in kwargs:
                 u0 = nu.asarray(kwargs['u0'])
             else:
                 E = nu.array([
                     evaluatePotentials(R[ii], z[ii], self._pot) +
                     vR[ii]**2. / 2. + vz[ii]**2. / 2. + vT[ii]**2. / 2.
                     for ii in range(len(R))
                 ])
                 u0 = actionAngleStaeckel_c.actionAngleStaeckel_calcu0(
                     E, Lz, self._pot, self._delta)[0]
             kwargs.pop('u0', None)
         else:
             u0 = None
         jr, jz, Omegar, Omegaphi, Omegaz, angler, anglephi,anglez, err= actionAngleStaeckel_c.actionAngleFreqAngleStaeckel_c(\
             self._pot,self._delta,R,vR,vT,z,vz,phi,u0=u0)
         # Adjustements for close-to-circular orbits
         indx = nu.isnan(Omegar) * (jr < 10.**-3.) + nu.isnan(Omegaz) * (
             jz < 10.**-3.
         )  #Close-to-circular and close-to-the-plane orbits
         if nu.sum(indx) > 0:
             Omegar[indx] = [epifreq(self._pot, r) for r in R[indx]]
             Omegaphi[indx] = [omegac(self._pot, r) for r in R[indx]]
             Omegaz[indx] = [verticalfreq(self._pot, r) for r in R[indx]]
         if err == 0:
             return (jr, Lz, jz, Omegar, Omegaphi, Omegaz, angler, anglephi,
                     anglez)
         else:
             raise RuntimeError(
                 "C-code for calculation actions failed; try with c=False"
             )  #pragma: no cover
     else:  #pragma: no cover
         if 'c' in kwargs and kwargs['c'] and not self._c:  #pragma: no cover
             warnings.warn(
                 "C module not used because potential does not have a C implementation",
                 galpyWarning)
         raise NotImplementedError(
             "actionsFreqs with c=False not implemented")
예제 #12
0
 def __call__(self,*args,**kwargs):
     """
     NAME:
        __call__
     PURPOSE:
        evaluate the actions (jr,lz,jz)
     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
         c= True/False; overrides the object's c= keyword to use C or not
        scipy.integrate.quadrature keywords
     OUTPUT:
        (jr,lz,jz)
     HISTORY:
        2012-11-27 - Written - Bovy (IAS)
     """
     if ((self._c and not ('c' in kwargs and not kwargs['c']))\
             or (ext_loaded and (('c' in kwargs and kwargs['c'])))) \
             and _check_c(self._pot):
         if len(args) == 5: #R,vR.vT, z, vz
             R,vR,vT, z, vz= args
         elif len(args) == 6: #R,vR.vT, z, vz, phi
             R,vR,vT, z, vz, phi= args
         else:
             meta= actionAngle(*args)
             R= meta._R
             vR= meta._vR
             vT= meta._vT
             z= meta._z
             vz= meta._vz
         if isinstance(R,float):
             R= nu.array([R])
             vR= nu.array([vR])
             vT= nu.array([vT])
             z= nu.array([z])
             vz= nu.array([vz])
         Lz= R*vT
         if self._useu0:
             #First calculate u0
             if 'u0' in kwargs:
                 u0= nu.asarray(kwargs['u0'])
             else:
                 E= nu.array([evaluatePotentials(R[ii],z[ii],self._pot) +vR[ii]**2./2.+vz[ii]**2./2.+vT[ii]**2./2. for ii in range(len(R))])
                 u0= actionAngleStaeckel_c.actionAngleStaeckel_calcu0(E,Lz,
                                                                      self._pot,
                                                                      self._delta)[0]
             kwargs.pop('u0',None)
         else:
             u0= None
         jr, jz, err= actionAngleStaeckel_c.actionAngleStaeckel_c(\
             self._pot,self._delta,R,vR,vT,z,vz,u0=u0)
         if err == 0:
             return (jr,Lz,jz)
         else: #pragma: no cover
             raise RuntimeError("C-code for calculation actions failed; try with c=False")
     else:
         if 'c' in kwargs and kwargs['c'] and not self._c: #pragma: no cover
             warnings.warn("C module not used because potential does not have a C implementation",galpyWarning)
         kwargs.pop('c',None)
         if (len(args) == 5 or len(args) == 6) \
                 and isinstance(args[0],nu.ndarray):
             ojr= nu.zeros((len(args[0])))
             olz= nu.zeros((len(args[0])))
             ojz= nu.zeros((len(args[0])))
             for ii in range(len(args[0])):
                 if len(args) == 5:
                     targs= (args[0][ii],args[1][ii],args[2][ii],
                             args[3][ii],args[4][ii])
                 elif len(args) == 6:
                     targs= (args[0][ii],args[1][ii],args[2][ii],
                             args[3][ii],args[4][ii],args[5][ii])
                 tjr,tlz,tjz= self(*targs,**copy.copy(kwargs))
                 ojr[ii]= tjr
                 ojz[ii]= tjz
                 olz[ii]= tlz
             return (ojr,olz,ojz)
         else:
             #Set up the actionAngleStaeckelSingle object
             aASingle= actionAngleStaeckelSingle(*args,pot=self._pot,
                                                  delta=self._delta)
             return (aASingle.JR(**copy.copy(kwargs)),
                     aASingle._R*aASingle._vT,
                     aASingle.Jz(**copy.copy(kwargs)))
예제 #13
0
 def actionsFreqsAngles(self,*args,**kwargs):
     """
     NAME:
        actionsFreqsAngles
     PURPOSE:
        evaluate the actions, frequencies, and angles 
        (jr,lz,jz,Omegar,Omegaphi,Omegaz,angler,anglephi,anglez)
     INPUT:
        Either:
           a) R,vR,vT,z,vz,phi (MUST HAVE PHI)
           b) Orbit instance: initial condition used if that's it, orbit(t)
              if there is a time given as well
        scipy.integrate.quadrature keywords
     OUTPUT:
         (jr,lz,jz,Omegar,Omegaphi,Omegaz,angler,anglephi,anglez)
     HISTORY:
        2013-08-28 - Written - Bovy (IAS)
     """
     if ((self._c and not ('c' in kwargs and not kwargs['c']))\
             or (ext_loaded and (('c' in kwargs and kwargs['c'])))) \
             and _check_c(self._pot):
         if len(args) == 5: #R,vR.vT, z, vz pragma: no cover
             raise IOError("Must specify phi")
         elif len(args) == 6: #R,vR.vT, z, vz, phi
             R,vR,vT, z, vz, phi= args
         else:
             meta= actionAngle(*args)
             R= meta._R
             vR= meta._vR
             vT= meta._vT
             z= meta._z
             vz= meta._vz
             phi= meta._phi
         if isinstance(R,float):
             R= nu.array([R])
             vR= nu.array([vR])
             vT= nu.array([vT])
             z= nu.array([z])
             vz= nu.array([vz])
             phi= nu.array([phi])
         Lz= R*vT
         if self._useu0:
             #First calculate u0
             if 'u0' in kwargs:
                 u0= nu.asarray(kwargs['u0'])
             else:
                 E= nu.array([evaluatePotentials(R[ii],z[ii],self._pot) +vR[ii]**2./2.+vz[ii]**2./2.+vT[ii]**2./2. for ii in range(len(R))])
                 u0= actionAngleStaeckel_c.actionAngleStaeckel_calcu0(E,Lz,
                                                                      self._pot,
                                                                      self._delta)[0]
             kwargs.pop('u0',None)
         else:
             u0= None
         jr, jz, Omegar, Omegaphi, Omegaz, angler, anglephi,anglez, err= actionAngleStaeckel_c.actionAngleFreqAngleStaeckel_c(\
             self._pot,self._delta,R,vR,vT,z,vz,phi,u0=u0)
         # Adjustements for close-to-circular orbits
         indx= nu.isnan(Omegar)*(jr < 10.**-3.)+nu.isnan(Omegaz)*(jz < 10.**-3.) #Close-to-circular and close-to-the-plane orbits
         if nu.sum(indx) > 0:
             Omegar[indx]= [epifreq(self._pot,r) for r in R[indx]]
             Omegaphi[indx]= [omegac(self._pot,r) for r in R[indx]]
             Omegaz[indx]= [verticalfreq(self._pot,r) for r in R[indx]]
         if err == 0:
             return (jr,Lz,jz,Omegar,Omegaphi,Omegaz,angler,anglephi,anglez)
         else:
             raise RuntimeError("C-code for calculation actions failed; try with c=False") #pragma: no cover
     else: #pragma: no cover
         if 'c' in kwargs and kwargs['c'] and not self._c: #pragma: no cover
             warnings.warn("C module not used because potential does not have a C implementation",galpyWarning)
         raise NotImplementedError("actionsFreqs with c=False not implemented")
예제 #14
0
 def actionsFreqsAngles(self,*args,**kwargs):
     """
     NAME:
        actionsFreqsAngles
     PURPOSE:
        evaluate the actions, frequencies, and angles 
        (jr,lz,jz,Omegar,Omegaphi,Omegaz,angler,anglephi,anglez)
     INPUT:
        Either:
           a) R,vR,vT,z,vz,phi (MUST HAVE PHI)
           b) Orbit instance: initial condition used if that's it, orbit(t)
              if there is a time given as well
        scipy.integrate.quadrature keywords
     OUTPUT:
         (jr,lz,jz,Omegar,Omegaphi,Omegaz,angler,anglephi,anglez)
     HISTORY:
        2013-09-08 - Written - Bovy (IAS)
     """
     if len(args) == 5: #R,vR.vT, z, vz pragma: no cover
         raise IOError("You need to provide phi when calculating angles")
     elif len(args) == 6: #R,vR.vT, z, vz, phi
         R,vR,vT, z, vz, phi= args
     else:
         meta= actionAngle(*args)
         R= meta._R
         vR= meta._vR
         vT= meta._vT
         z= meta._z
         vz= meta._vz
         phi= meta._phi
     if isinstance(R,float):
         R= nu.array([R])
         vR= nu.array([vR])
         vT= nu.array([vT])
         z= nu.array([z])
         vz= nu.array([vz])
         phi= nu.array([phi])
     if self._c: #pragma: no cover
         pass
     else:
         Lz= R*vT
         Lx= -z*vT
         Ly= z*vR-R*vz
         L2= Lx*Lx+Ly*Ly+Lz*Lz
         E= self._ip(R,z)+vR**2./2.+vT**2./2.+vz**2./2.
         L= nu.sqrt(L2)
         #Actions
         Jphi= Lz
         Jz= L-nu.fabs(Lz)
         Jr= self.amp/nu.sqrt(-2.*E)\
             -0.5*(L+nu.sqrt((L2+4.*self.amp*self.b)))
         #Frequencies
         Omegar= (-2.*E)**1.5/self.amp
         Omegaz= 0.5*(1.+L/nu.sqrt(L2+4.*self.amp*self.b))*Omegar
         Omegaphi= copy.copy(Omegaz)
         indx= Lz < 0.
         Omegaphi[indx]*= -1.
         #Angles
         c= -self.amp/2./E-self.b
         e2= 1.-L2/self.amp/c*(1.+self.b/c)
         e= nu.sqrt(e2)
         s= 1.+nu.sqrt(1.+(R**2.+z**2.)/self.b**2.)
         coseta= 1/e*(1.-self.b/c*(s-2.))
         pindx= (coseta > 1.)*(coseta < (1.+10.**-7.))
         coseta[pindx]= 1.
         pindx= (coseta < -1.)*(coseta > (-1.-10.**-7.))
         coseta[pindx]= -1.           
         eta= nu.arccos(coseta)
         costheta= z/nu.sqrt(R**2.+z**2.)
         sintheta= R/nu.sqrt(R**2.+z**2.)
         vrindx= (vR*sintheta+vz*costheta) < 0.
         eta[vrindx]= 2.*nu.pi-eta[vrindx]
         angler= eta-e*c/(c+self.b)*nu.sin(eta)
         tan11= nu.arctan(nu.sqrt((1.+e)/(1.-e))*nu.tan(0.5*eta))
         tan12= nu.arctan(nu.sqrt((1.+e+2.*self.b/c)/(1.-e+2.*self.b/c))*nu.tan(0.5*eta))
         vzindx= (-vz*sintheta+vR*costheta) > 0.
         tan11[tan11 < 0.]+= nu.pi
         tan12[tan12 < 0.]+= nu.pi
         pindx= (Lz/L > 1.)*(Lz/L < (1.+10.**-7.))
         Lz[pindx]= L[pindx]
         pindx= (Lz/L < -1.)*(Lz/L > (-1.-10.**-7.))
         Lz[pindx]= -L[pindx]
         i= nu.arccos(Lz/L)
         sinpsi= costheta/nu.sin(i)
         pindx= (sinpsi > 1.)*(sinpsi < (1.+10.**-7.))
         sinpsi[pindx]= 1.
         pindx= (sinpsi < -1.)*(sinpsi > (-1.-10.**-7.))
         sinpsi[pindx]= -1.           
         psi= nu.arcsin(sinpsi)
         psi[vzindx]= nu.pi-psi[vzindx]
         psi= psi % (2.*nu.pi)
         anglez= psi+Omegaz/Omegar*angler\
             -tan11-1./nu.sqrt(1.+4*self.amp*self.b/L2)*tan12
         sinu= z/R/nu.tan(i)
         pindx= (sinu > 1.)*(sinu < (1.+10.**-7.))
         sinu[pindx]= 1.
         pindx= (sinu < -1.)*(sinu > (-1.-10.**-7.))
         sinu[pindx]= -1.           
         u= nu.arcsin(sinu)
         u[vzindx]= nu.pi-u[vzindx]
         Omega= phi-u
         anglephi= Omega
         anglephi[indx]-= anglez[indx]
         anglephi[True-indx]+= anglez[True-indx]
         angler= angler % (2.*nu.pi)
         anglephi= anglephi % (2.*nu.pi)
         anglez= anglez % (2.*nu.pi)
         return (Jr,Jphi,Jz,Omegar,Omegaphi,Omegaz,angler,anglephi,anglez)