Ejemplo n.º 1
0
def _get_gravity_accel(x, y, z, galpy_pot=False):
    """

    :param x:
    :param y:
    :param z:
    :param galpy_pot:
    :return:
    """
    r_gal = np.sqrt(x**2 + y**2) / 1e3  # in pc -> kpc
    z_gal = z / 1e3  # in pc -> kpc as required by the function
    dr_gal = 2.5e-4  # in kpc
    if galpy_pot:
        dpot = (evaluatePotentials(MWPotential2014, (r_gal + dr_gal) * un.kpc,
                                   z_gal * un.kpc,
                                   phi=0,
                                   t=0,
                                   dR=0) -
                evaluatePotentials(MWPotential2014, (r_gal - dr_gal) * un.kpc,
                                   z_gal * un.kpc,
                                   phi=0,
                                   t=0,
                                   dR=0))
        kms_to_pcyr = (un.km**2 / un.s**2).to(un.pc**2 / un.yr**2)
        dpot *= kms_to_pcyr
    else:
        dpot = (_galactic_potential(r_gal + dr_gal, z_gal) -
                _galactic_potential(r_gal - dr_gal, z_gal))
    dpot_dr = dpot / (
        2. * dr_gal * 1e3
    )  # dr_gal converted to pc as dpot is returned in pc2/yr2
    return -1. * dpot_dr  # pc/yr2
Ejemplo n.º 2
0
    def escape_velocity(self, gal, interpolants):
        """
        Calculates the escape velocity for each particle at their respective radius.
        """

        print('Calculating particle escape velocities...\n')

        # Read in Rvals, assuming particles start in the plane
        R_vals = self.R
        z_vals = np.zeros_like(R_vals)

        # specify radius and height at "infinity" in kpc
        R_inf = 1000 * u.kpc
        z_inf = 1000 * u.kpc

        Vescs = []
        for idx, (t0, R, z) in enumerate(zip(self.t0, R_vals, z_vals)):
            if interpolants:
                potential = interpolants[t0]
            else:
                potential = gal.full_potentials[t0]

            pot_at_inf = evaluatePotentials(potential, R_inf, z_inf).value
            Vescs.append(
                np.sqrt(
                    2 *
                    (pot_at_inf - evaluatePotentials(potential, R, z).value)))

        self.Vesc = np.asarray(Vescs) * u.km / u.s
        return
Ejemplo n.º 3
0
def v_esc(pot, r):
    """Calculate the escape velocity at r

    Parameters
    ----------
    pot : galpy.potential.Potential or list of Potentials
        The potential used to calculate the escape velocity.
    r : array_like
        Initial position vector of the desired orbit in Galactocentric
        cylindrical coordinates, of the form [R, z, phi] in [pc, pc, rad].

    Returns
    -------
    ve : float
        The escape velocity at r.
    """
    R, z, phi = r
    E_min = evaluatePotentials(pot,
                               R / _pc,
                               z / _pc,
                               phi=phi,
                               use_physical=False)
    E_max = evaluatePotentials(pot, 1e+12, 0, phi=phi, use_physical=False)
    ve = (2 * (E_max - E_min))**0.5
    return ve * _kms
Ejemplo n.º 4
0
 def _evaluate(self,R,z,phi=0.,t=0.,dR=0,dphi=0):
     if self._interpPot and self._enable_c:
         if isinstance(R,float):
             R= numpy.array([R])
         if isinstance(z,float):
             z= numpy.array([z])
         if self._zsym:
             return eval_potential_c(self,R,numpy.fabs(z))[0]
         else:
             return eval_potential_c(self,R,z)[0]
     from galpy.potential import evaluatePotentials
     if self._interpPot:
         if isinstance(R,float):
             return self._evaluate(numpy.array([R]),numpy.array([z]))
         out= numpy.empty_like(R)
         indx= (R >= self._rgrid[0])*(R <= self._rgrid[-1])
         if numpy.sum(indx) > 0:
             if self._zsym:
                 if self._logR:
                     out[indx]= self._potInterp.ev(numpy.log(R[indx]),numpy.fabs(z[indx]))
                 else:
                     out[indx]= self._potInterp.ev(R[indx],numpy.fabs(z[indx]))
             else:
                 if self._logR:
                     out[indx]= self._potInterp.ev(numpy.log(R[indx]),z[indx])
                 else:
                     out[indx]= self._potInterp.ev(R[indx],z[indx])
         if numpy.sum(True-indx) > 0:
             out[True-indx]= evaluatePotentials(R[True-indx],
                                                z[True-indx],
                                                self._origPot)
         return out
     else:
         return evaluatePotentials(R,z,self._origPot)
Ejemplo n.º 5
0
def Energy(coord, custom_potential=None):
    """
    NAME:
        Energy
    PURPOSE:
        Given an array of 6 coordinates for the position and velocity of stars 
        in Cartesian coordinate, return a list of energy per mass.
        Assumes input and out put are in natrual unit.
        
    INPUT:
        coord= a numpy array of coordinate
    OUTPUT:
        energy = a list of total energy per mass
    HISTORY:
        2018-05-25 - Written - Samuel Wong
        2018-07-24 - Changed to an array of points - Samuel Wong
    """
    if custom_potential == None:
        potential_obj = MWPotential2014
    else:
        potential_obj = custom_potential

    x, y, z, vx, vy, vz = coord.T
    R = np.sqrt(x**2 + y**2)
    potential = evaluatePotentials(potential_obj, R, z)
    kinetic = (vx**2 + vy**2 + vz**2) / 2.
    energy = kinetic + potential
    return energy
Ejemplo n.º 6
0
def test_mwpotential2014():
    from galpy.potential import (MWPotential2014,
                                 evaluateDensities,
                                 evaluatezforces,
                                 evaluatePotentials)

    # Here these have to be default:
    ro = 8 * u.kpc
    vo = 220 * u.km/u.s

    gala_pot = BovyMWPotential2014()
    bovy_pot = MWPotential2014
    for x in bovy_pot:
        x.turn_physical_on()

    Rs = np.random.uniform(1, 15, size=ntest) * u.kpc
    zs = np.random.uniform(1, 15, size=ntest) * u.kpc

    xyz = np.zeros((3, Rs.size)) * u.kpc
    xyz[0] = Rs
    xyz[2] = zs
    assert np.allclose(gala_pot.density(xyz).to_value(u.Msun/u.pc**3),
                       evaluateDensities(bovy_pot, R=Rs.to_value(ro), z=zs.to_value(ro)))

    assert np.allclose(gala_pot.energy(xyz).to_value((u.km / u.s)**2),
                       evaluatePotentials(bovy_pot, R=Rs.to_value(ro), z=zs.to_value(ro)))

    assert np.allclose(gala_pot.gradient(xyz).to_value((u.km/u.s) * u.pc/u.Myr / u.pc)[2],
                       -evaluatezforces(bovy_pot, R=Rs.to_value(ro), z=zs.to_value(ro)))
Ejemplo n.º 7
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-08-28 - Written - Bovy (IAS)
     """
     if ((self._c and not (kwargs.has_key('c') and not kwargs['c']))\
             or (ext_loaded and ((kwargs.has_key('c') 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 kwargs.has_key('u0'):
                 u0= 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]
             if kwargs.has_key('u0'): kwargs.pop('u0')
         else:
             u0= None
         jr, jz, Omegar, Omegaphi, Omegaz, err= actionAngleStaeckel_c.actionAngleFreqStaeckel_c(\
             self._pot,self._delta,R,vR,vT,z,vz,u0=u0)
         if err == 0:
             return (jr,Lz,jz,Omegar,Omegaphi,Omegaz)
         else:
             raise RuntimeError("C-code for calculation actions failed; try with c=False")
     else:
         if kwargs.has_key('c') and kwargs['c'] and not self._c:
             warnings.warn("C module not used because potential does not have a C implementation",galpyWarning)
         raise NotImplementedError("actionsFreqs with c=False not implemented")
Ejemplo n.º 8
0
    def test_v_esc(self):
        R = z = phi = 1
        ve = v_esc(MWPotential2014, [R, z, phi])
        orb = Orbit(vxvv=[R/_pc, 0, ve/_kms, z/_pc, 0, phi])
        E = orb.E(pot=MWPotential2014)
        E_inf = evaluatePotentials(MWPotential2014, 1e+12, 0)

        self.assertAlmostEqual(E, E_inf, 10, msg="v_esc returns incorrect "
                                                 "escape velocity")
Ejemplo n.º 9
0
    def get_potential_at_point(self,eps,x,y,z):

        R=np.sqrt(x.value_in(units.kpc)**2.+y.value_in(units.kpc)**2.)
        zed=z.value_in(units.kpc)
        phi=np.arctan2(y.value_in(units.kpc),x.value_in(units.kpc))

        pot=potential.evaluatePotentials(self.pot,R/self.ro,zed/self.ro,phi=phi,t=self.tgalpy,ro=self.ro,vo=self.vo) | units.km**2*units.s**-2
                    
        return pot
Ejemplo n.º 10
0
    def _evaluate(self, R, z, phi=0.0, t=0.0):
        from galpy.potential import evaluatePotentials

        if self._interpPot:
            out = numpy.empty_like(R)
            indx = (R >= self._rgrid[0]) * (R <= self._rgrid[-1]) * (z <= self._zgrid[-1]) * (z >= self._zgrid[0])
            if numpy.sum(indx) > 0:
                if self._enable_c:
                    out[indx] = eval_potential_c(self, R[indx], z[indx])[0] / self._amp
                else:
                    if self._logR:
                        out[indx] = self._potInterp.ev(numpy.log(R[indx]), z[indx])
                    else:
                        out[indx] = self._potInterp.ev(R[indx], z[indx])
            if numpy.sum(True - indx) > 0:
                out[True - indx] = evaluatePotentials(R[True - indx], z[True - indx], self._origPot)
            return out
        else:
            return evaluatePotentials(R, z, self._origPot)
Ejemplo n.º 11
0
def test_vcirc():
    #test the circular velocity of the KuzminKutuzovStaeckelPotential
    #using parameters from Batsleer & Dejonghe 1994, fig. 1-3
    #and their formula eq. (10)

    #_____model parameters______
    #surface ratios of disk and halo:
    ac_Ds = [50.  ,50.  ,50.  ,50. ,50. ,50.  ,40. ,40. ,40. ]
    ac_Hs = [1.005,1.005,1.005,1.01,1.01,1.01 ,1.02,1.02,1.02 ]
    #disk contribution to total mass:
    ks    = [0.05 ,0.06 ,0.07 ,0.07,0.1 ,0.125,0.1 ,0.12,0.125]
    #focal distance:
    Delta = 1.

    for ii in range(9):
        ac_D = ac_Ds[ii]
        ac_H = ac_Hs[ii]
        k    = ks[ii]
        
        #_____setup potential_____
        #first try, not normalized:
        V_D = KuzminKutuzovStaeckelPotential(amp=    k ,ac=ac_D,Delta=Delta,normalize=False)
        V_H = KuzminKutuzovStaeckelPotential(amp=(1.-k),ac=ac_H,Delta=Delta,normalize=False)
        pot = [V_D,V_H]
        #normalization according to Batsleer & Dejonghe 1994:
        V00 = evaluatePotentials(pot,0.,0.)
        #second try, normalized:
        V_D = KuzminKutuzovStaeckelPotential(amp=    k  / (-V00),ac=ac_D,Delta=Delta,normalize=False)
        V_H = KuzminKutuzovStaeckelPotential(amp=(1.-k) / (-V00),ac=ac_H,Delta=Delta,normalize=False)
        pot = [V_D,V_H]
        
        #_____calculate rotation curve_____
        Rs = numpy.linspace(0.,20.,100)
        z = 0.
        vcirc_calc = numpy.sqrt(-Rs * evaluateRforces(pot,Rs,z))
            
        #_____vcirc by Batsleer & Dejonghe eq. (10) (with proper Jacobian)_____
        def vc2w(R):
            g_D = Delta**2 / (1.-ac_D**2)
            a_D = g_D - Delta**2
            g_H = Delta**2 / (1.-ac_H**2)
            a_H = g_H - Delta**2
            l = R**2 - a_D
            q = a_H - a_D
            termD = numpy.sqrt(l  )*(numpy.sqrt(l  ) + numpy.sqrt(-g_D  ))**2
            termH = numpy.sqrt(l-q)*(numpy.sqrt(l-q) + numpy.sqrt(-g_D-q))**2
            return R**2 * (k / termD + (1.-k) / termH)
        vcirc_formula = numpy.sqrt(vc2w(Rs)/(-V00))

        assert numpy.all(numpy.fabs(vcirc_calc - vcirc_formula) < 10**-8.), \
                'Calculated circular velocity for KuzminKutuzovStaeckelPotential '+ \
                'does not agree with eq. (10) (corrected by proper Jacobian) '+ \
                'by Batsleer & Dejonghe (1994)'

    return None
Ejemplo n.º 12
0
 def _evaluate(self,R,z,phi=0.,t=0.):
     from galpy.potential import evaluatePotentials
     if self._interpPot:
         out= numpy.empty_like(R)
         indx= (R >= self._rgrid[0])*(R <= self._rgrid[-1])\
             *(z <= self._zgrid[-1])*(z >= self._zgrid[0])
         if numpy.sum(indx) > 0:
             if self._enable_c:
                 out[indx]= eval_potential_c(self,R[indx],z[indx])[0]/self._amp
             else:
                 if self._logR:
                     out[indx]= self._potInterp.ev(numpy.log(R[indx]),z[indx])
                 else:
                     out[indx]= self._potInterp.ev(R[indx],z[indx])
         if numpy.sum(True^indx) > 0:
             out[True^indx]= evaluatePotentials(self._origPot,
                                                R[True^indx],
                                                z[True^indx])
         return out
     else:
         return evaluatePotentials(self._origPot,R,z)
Ejemplo n.º 13
0
def jz(z,vz,R,pot=MWPotential):
    """
    NAME:
       jz
    PURPOSE:
       calculate the vertical action
    INPUT:
       z - height (/R0)
       vz - velocity (/V0)
       R - Galactocentric radius (/Ro)
       pot= potential to use
    OUTPUT:
    HISTORY:
       2012-03-07 - Written - Bovy (IAS)
    """
    #Calculate Ez, /vz for stability
    potzero= evaluatePotentials(R,0.,pot)/vz**2.
    Ez= 0.5+evaluatePotentials(R,z,pot)/vz**2.-potzero
    #Integrate to get Jz
    out= 2.*numpy.fabs(vz)/math.pi*integrate.quad(_jzIntegrand,0.,numpy.inf,
                                                  args=(R,pot,
                                                        Ez,potzero,vz))[0]
    #if out == 0.: print Ez, z, vz
    return out
Ejemplo n.º 14
0
def potentialStaeckel(u, v, pot, delta):
    """
    NAME:
       potentialStaeckel
    PURPOSE:
       return the potential
    INPUT:
       u - confocal u
       v - confocal v
       pot - potential
       delta - focus
    OUTPUT:
       Phi(u,v)
    HISTORY:
       2012-11-29 - Written - Bovy (IAS)
    """
    R, z = bovy_coords.uv_to_Rz(u, v, delta=delta)
    return evaluatePotentials(R, z, pot)
Ejemplo n.º 15
0
def calcELStaeckel(R,vR,vT,z,vz,pot,vc=1.,ro=1.):
    """
    NAME:
       calcELStaeckel
    PURPOSE:
       calculate the energy and angular momentum
    INPUT:
       R - Galactocentric radius (/ro)
       vR - radial part of the velocity (/vc)
       vT - azimuthal part of the velocity (/vc)
       vc - circular velocity
       ro - reference radius
    OUTPUT:
       (E,L)
    HISTORY:
       2012-11-30 - Written - Bovy (IAS)
    """                           
    return (evaluatePotentials(R,z,pot)+vR**2./2.+vT**2./2.+vz**2./2.,R*vT)
Ejemplo n.º 16
0
def potentialStaeckel(u,v,pot,delta):
    """
    NAME:
       potentialStaeckel
    PURPOSE:
       return the potential
    INPUT:
       u - confocal u
       v - confocal v
       pot - potential
       delta - focus
    OUTPUT:
       Phi(u,v)
    HISTORY:
       2012-11-29 - Written - Bovy (IAS)
    """
    R,z= bovy_coords.uv_to_Rz(u,v,delta=delta)
    return evaluatePotentials(R,z,pot)
Ejemplo n.º 17
0
def calcELStaeckel(R, vR, vT, z, vz, pot, vc=1., ro=1.):
    """
    NAME:
       calcELStaeckel
    PURPOSE:
       calculate the energy and angular momentum
    INPUT:
       R - Galactocentric radius (/ro)
       vR - radial part of the velocity (/vc)
       vT - azimuthal part of the velocity (/vc)
       vc - circular velocity
       ro - reference radius
    OUTPUT:
       (E,L)
    HISTORY:
       2012-11-30 - Written - Bovy (IAS)
    """
    return (evaluatePotentials(R, z, pot) + vR**2. / 2. + vT**2. / 2. +
            vz**2. / 2., R * vT)
Ejemplo n.º 18
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 (kwargs.has_key('c') and not kwargs['c']))\
             or (ext_loaded and ((kwargs.has_key('c') 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 kwargs.has_key('u0'):
                 u0= 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]
             if kwargs.has_key('u0'): kwargs.pop('u0')
         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:
             raise RuntimeError("C-code for calculation actions failed; try with c=False")
     else:
         if kwargs.has_key('c') and kwargs['c'] and not self._c:
             warnings.warn("C module not used because potential does not have a C implementation",galpyWarning)
         if kwargs.has_key('c'): kwargs.pop('c')
         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)))
Ejemplo n.º 19
0
    def __init__(self,
                 RZPot=None,rgrid=(numpy.log(0.01),numpy.log(20.),101),
                 zgrid=(0.,1.,101),logR=True,
                 interpPot=False,interpRforce=False,interpzforce=False,
                 interpDens=False,
                 interpvcirc=False,
                 interpdvcircdr=False,
                 interpepifreq=False,interpverticalfreq=False,
                 ro=None,vo=None,
                 use_c=False,enable_c=False,zsym=True,
                 numcores=None):
        """
        NAME:

           __init__

        PURPOSE:

           Initialize an interpRZPotential instance

        INPUT:

           RZPot - RZPotential to be interpolated

           rgrid - R grid to be given to linspace as in rs= linspace(*rgrid)

           zgrid - z grid to be given to linspace as in zs= linspace(*zgrid)

           logR - if True, rgrid is in the log of R so logrs= linspace(*rgrid)

           interpPot, interpRforce, interpzforce, interpDens,interpvcirc, interpepifreq, interpverticalfreq, interpdvcircdr= if True, interpolate these functions

           use_c= use C to speed up the calculation of the grid

           enable_c= enable use of C for interpolations

           zsym= if True (default), the potential is assumed to be symmetric around z=0 (so you can use, e.g.,  zgrid=(0.,1.,101)).

           numcores= if set to an integer, use this many cores (only used for vcirc, dvcircdR, epifreq, and verticalfreq; NOT NECESSARILY FASTER, TIME TO MAKE SURE)

           ro=, vo= distance and velocity scales for translation into internal units (default from configuration file)

        OUTPUT:

           instance

        HISTORY:

           2010-07-21 - Written - Bovy (NYU)

           2013-01-24 - Started with new implementation - Bovy (IAS)

        """
        if isinstance(RZPot,interpRZPotential):
            from galpy.potential import PotentialError
            raise PotentialError('Cannot setup interpRZPotential with another interpRZPotential')
        # Propagate ro and vo
        roSet= True
        voSet= True
        if ro is None:
            if isinstance(RZPot,list):
                ro= RZPot[0]._ro
                roSet= RZPot[0]._roSet
            else:
                ro= RZPot._ro
                roSet= RZPot._roSet
        if vo is None:
            if isinstance(RZPot,list):
                vo= RZPot[0]._vo
                voSet= RZPot[0]._voSet
            else:
                vo= RZPot._vo
                voSet= RZPot._voSet
        Potential.__init__(self,amp=1.,ro=ro,vo=vo)
        # Turn off physical if it hadn't been on
        if not roSet: self._roSet= False
        if not voSet: self._voSet= False
        self._origPot= RZPot
        self._rgrid= numpy.linspace(*rgrid)
        self._logR= logR
        if self._logR:
            self._rgrid= numpy.exp(self._rgrid)
            self._logrgrid= numpy.log(self._rgrid)
        self._zgrid= numpy.linspace(*zgrid)
        self._interpPot= interpPot
        self._interpRforce= interpRforce
        self._interpzforce= interpzforce
        self._interpDens= interpDens
        self._interpvcirc= interpvcirc
        self._interpdvcircdr= interpdvcircdr
        self._interpepifreq= interpepifreq
        self._interpverticalfreq= interpverticalfreq
        self._enable_c= enable_c*ext_loaded
        self.hasC= self._enable_c
        self._zsym= zsym
        if interpPot:
            if use_c*ext_loaded:
                self._potGrid, err= calc_potential_c(self._origPot,self._rgrid,self._zgrid)
            else:
                from galpy.potential import evaluatePotentials
                potGrid= numpy.zeros((len(self._rgrid),len(self._zgrid)))
                for ii in range(len(self._rgrid)):
                    for jj in range(len(self._zgrid)):
                        potGrid[ii,jj]= evaluatePotentials(self._origPot,self._rgrid[ii],self._zgrid[jj])
                self._potGrid= potGrid
            if self._logR:
                self._potInterp= interpolate.RectBivariateSpline(self._logrgrid,
                                                                 self._zgrid,
                                                                 self._potGrid,
                                                                 kx=3,ky=3,s=0.)
            else:
                self._potInterp= interpolate.RectBivariateSpline(self._rgrid,
                                                                 self._zgrid,
                                                                 self._potGrid,
                                                                 kx=3,ky=3,s=0.)
            if enable_c*ext_loaded:
                self._potGrid_splinecoeffs= calc_2dsplinecoeffs_c(self._potGrid)
        if interpRforce:
            if use_c*ext_loaded:
                self._rforceGrid, err= calc_potential_c(self._origPot,self._rgrid,self._zgrid,rforce=True)
            else:
                from galpy.potential import evaluateRforces
                rforceGrid= numpy.zeros((len(self._rgrid),len(self._zgrid)))
                for ii in range(len(self._rgrid)):
                    for jj in range(len(self._zgrid)):
                        rforceGrid[ii,jj]= evaluateRforces(self._origPot,self._rgrid[ii],self._zgrid[jj])
                self._rforceGrid= rforceGrid
            if self._logR:
                self._rforceInterp= interpolate.RectBivariateSpline(self._logrgrid,
                                                                    self._zgrid,
                                                                    self._rforceGrid,
                                                                    kx=3,ky=3,s=0.)
            else:
                self._rforceInterp= interpolate.RectBivariateSpline(self._rgrid,
                                                                    self._zgrid,
                                                                    self._rforceGrid,
                                                                    kx=3,ky=3,s=0.)
            if enable_c*ext_loaded:
                self._rforceGrid_splinecoeffs= calc_2dsplinecoeffs_c(self._rforceGrid)
        if interpzforce:
            if use_c*ext_loaded:
                self._zforceGrid, err= calc_potential_c(self._origPot,self._rgrid,self._zgrid,zforce=True)
            else:
                from galpy.potential import evaluatezforces
                zforceGrid= numpy.zeros((len(self._rgrid),len(self._zgrid)))
                for ii in range(len(self._rgrid)):
                    for jj in range(len(self._zgrid)):
                        zforceGrid[ii,jj]= evaluatezforces(self._origPot,self._rgrid[ii],self._zgrid[jj])
                self._zforceGrid= zforceGrid
            if self._logR:
                self._zforceInterp= interpolate.RectBivariateSpline(self._logrgrid,
                                                                    self._zgrid,
                                                                    self._zforceGrid,
                                                                    kx=3,ky=3,s=0.)
            else:
                self._zforceInterp= interpolate.RectBivariateSpline(self._rgrid,
                                                                    self._zgrid,
                                                                    self._zforceGrid,
                                                                    kx=3,ky=3,s=0.)
            if enable_c*ext_loaded:
                self._zforceGrid_splinecoeffs= calc_2dsplinecoeffs_c(self._zforceGrid)
        if interpDens:
            from galpy.potential import evaluateDensities
            densGrid= numpy.zeros((len(self._rgrid),len(self._zgrid)))
            for ii in range(len(self._rgrid)):
                for jj in range(len(self._zgrid)):
                    densGrid[ii,jj]= evaluateDensities(self._origPot,self._rgrid[ii],self._zgrid[jj])
            self._densGrid= densGrid
            if self._logR:
                self._densInterp= interpolate.RectBivariateSpline(self._logrgrid,
                                                                  self._zgrid,
                                                                  numpy.log(self._densGrid+10.**-10.),
                                                                  kx=3,ky=3,s=0.)
            else:
                self._densInterp= interpolate.RectBivariateSpline(self._rgrid,
                                                                  self._zgrid,
                                                                  numpy.log(self._densGrid+10.**-10.),
                                                                  kx=3,ky=3,s=0.)
        if interpvcirc:
            from galpy.potential import vcirc
            if not numcores is None:
                self._vcircGrid= multi.parallel_map((lambda x: vcirc(self._origPot,self._rgrid[x])),
                                                    list(range(len(self._rgrid))),numcores=numcores)
            else:
                self._vcircGrid= numpy.array([vcirc(self._origPot,r) for r in self._rgrid])
            if self._logR:
                self._vcircInterp= interpolate.InterpolatedUnivariateSpline(self._logrgrid,self._vcircGrid,k=3)
            else:
                self._vcircInterp= interpolate.InterpolatedUnivariateSpline(self._rgrid,self._vcircGrid,k=3)
        if interpdvcircdr:
            from galpy.potential import dvcircdR
            if not numcores is None:
                self._dvcircdrGrid= multi.parallel_map((lambda x: dvcircdR(self._origPot,self._rgrid[x])),
                                                       list(range(len(self._rgrid))),numcores=numcores)
            else:
                self._dvcircdrGrid= numpy.array([dvcircdR(self._origPot,r) for r in self._rgrid])
            if self._logR:
                self._dvcircdrInterp= interpolate.InterpolatedUnivariateSpline(self._logrgrid,self._dvcircdrGrid,k=3)
            else:
                self._dvcircdrInterp= interpolate.InterpolatedUnivariateSpline(self._rgrid,self._dvcircdrGrid,k=3)
        if interpepifreq:
            from galpy.potential import epifreq
            if not numcores is None:
                self._epifreqGrid= numpy.array(multi.parallel_map((lambda x: epifreq(self._origPot,self._rgrid[x])),
                                                      list(range(len(self._rgrid))),numcores=numcores))
            else:
                self._epifreqGrid= numpy.array([epifreq(self._origPot,r) for r in self._rgrid])
            indx= True^numpy.isnan(self._epifreqGrid)
            if numpy.sum(indx) < 4:
                if self._logR:
                    self._epifreqInterp= interpolate.InterpolatedUnivariateSpline(self._logrgrid[indx],self._epifreqGrid[indx],k=1)
                else:
                    self._epifreqInterp= interpolate.InterpolatedUnivariateSpline(self._rgrid[indx],self._epifreqGrid[indx],k=1)
            else:
                if self._logR:
                    self._epifreqInterp= interpolate.InterpolatedUnivariateSpline(self._logrgrid[indx],self._epifreqGrid[indx],k=3)
                else:
                    self._epifreqInterp= interpolate.InterpolatedUnivariateSpline(self._rgrid[indx],self._epifreqGrid[indx],k=3)
        if interpverticalfreq:
            from galpy.potential import verticalfreq
            if not numcores is None:
                self._verticalfreqGrid= multi.parallel_map((lambda x: verticalfreq(self._origPot,self._rgrid[x])),
                                                       list(range(len(self._rgrid))),numcores=numcores)
            else:
                self._verticalfreqGrid= numpy.array([verticalfreq(self._origPot,r) for r in self._rgrid])
            if self._logR:
                self._verticalfreqInterp= interpolate.InterpolatedUnivariateSpline(self._logrgrid,self._verticalfreqGrid,k=3)
            else:
                self._verticalfreqInterp= interpolate.InterpolatedUnivariateSpline(self._rgrid,self._verticalfreqGrid,k=3)
        return None
def process_single(i):
    vxvv = [ra[i], dec[i], distance[i], pmra[i], pmdec[i], rv[i]]
    if not np.all(np.isfinite(vxvv)) or not np.all(np.isfinite(covariance[i])):
        return np.ones(56) * np.nan
    samp = np.random.multivariate_normal(vxvv, covariance[i], size=1000)
    if not (np.all(samp[:, 1] < 90.) & np.all(samp[:, 1] > -90.)):
        return np.ones(56) * np.nan
    sXYZ, svxyz, sRpz, svRvTvz = obs_to_galcen(samp[:, 0],
                                               samp[:, 1],
                                               samp[:, 2],
                                               samp[:, 3],
                                               samp[:, 4],
                                               samp[:, 5],
                                               ro=_R0,
                                               vo=_v0,
                                               zo=_z0)
    deltas = estimateDeltaStaeckel(MWPotential2014, np.median(sRpz[:, 0]), np.median(sRpz[:, 2]), no_median=True)
    aAS = actionAngleStaeckel(pot=MWPotential2014, delta=np.mean(deltas))
    e, zmax, rperi, rap = aAS.EccZmaxRperiRap(sRpz[:, 0],
                                              svRvTvz[:, 0],
                                              svRvTvz[:, 1],
                                              sRpz[:, 2],
                                              svRvTvz[:, 2],
                                              sRpz[:, 1], delta=deltas)
    tcov = np.cov(np.dstack([e, zmax, rperi, rap])[0].T)
    errs = np.sqrt(np.diag(tcov))
    e_zmax_corr = tcov[0, 1] / (errs[0] * errs[1])
    e_rperi_corr = tcov[0, 2] / (errs[0] * errs[2])
    e_rap_corr = tcov[0, 3] / (errs[0] * errs[3])
    zmax_rperi_corr = tcov[1, 2] / (errs[1] * errs[2])
    zmax_rap_corr = tcov[1, 3] / (errs[1] * errs[3])
    rperi_rap_corr = tcov[2, 3] / (errs[2] * errs[3])
    e_err, zmax_err, rperi_err, rap_err = errs
    action = np.array(
        aAS.actionsFreqsAngles(sRpz[:, 0], svRvTvz[:, 0], svRvTvz[:, 1], sRpz[:, 2], svRvTvz[:, 2], sRpz[:, 1]))
    tcov_after_action = np.cov(action)
    errs = np.sqrt(np.diag(tcov_after_action))
    jr_lz_corr = tcov_after_action[0, 1] / (errs[0] * errs[1])
    jr_jz_corr = tcov_after_action[0, 2] / (errs[0] * errs[2])
    lz_jz_corr = tcov_after_action[1, 2] / (errs[1] * errs[2])
    jr_err, lz_err, jz_err, or_err, op_err, oz_err, tr_err, tphi_err, tz_err = errs

    Rc = np.array([rl(MWPotential2014, lz) for lz in action[1]]) * _R0
    Ec = (evaluatePotentials(MWPotential2014, Rc, 0.) + 0.5 * (action[1]) ** 2. / Rc ** 2.) * _v0 ** 2
    E = (evaluatePotentials(MWPotential2014, sRpz[:, 0], sRpz[:, 2], phi=sRpz[:, 1]) + np.sum(svRvTvz ** 2 / 2.,
                                                                                              axis=1)) * _v0 ** 2

    # galactocentric coord and vel uncertainty
    galcen_tcov = np.cov(np.dstack([sRpz[:, 0], sRpz[:, 1], sRpz[:, 2]])[0].T)
    galcen_errs = np.sqrt(np.diag(galcen_tcov))
    galr_err, galphi_err, galz_err = galcen_errs

    galcenv_tcov = np.cov(np.dstack([svRvTvz[:, 0], svRvTvz[:, 1], svRvTvz[:, 2]])[0].T)
    galcenv_errs = np.sqrt(np.diag(galcenv_tcov))
    galvr_err, galvt_err, galvz_err = galcenv_errs

    galvr_galvt_corr = galcenv_tcov[0, 1] / (galcenv_errs[0] * galcenv_errs[1])
    galvr_galvz_corr = galcenv_tcov[0, 2] / (galcenv_errs[0] * galcenv_errs[2])
    galvt_galvz_corr = galcenv_tcov[1, 2] / (galcenv_errs[1] * galcenv_errs[2])

    return np.nanmean(e), e_err, np.nanmean(zmax) * _R0, zmax_err * _R0, np.nanmean(
        rperi) * _R0, rperi_err * _R0, np.nanmean(rap) * _R0, rap_err * _R0, \
           e_zmax_corr, e_rperi_corr, e_rap_corr, zmax_rperi_corr, zmax_rap_corr, rperi_rap_corr, \
           np.nanmean(action[0]) * _R0 * _v0, jr_err * _R0 * _v0, np.nanmean(
        action[1]) * _R0 * _v0, lz_err * _R0 * _v0, np.nanmean(action[2]) * _R0 * _v0, jz_err * _R0 * _v0, \
           jr_lz_corr, jr_jz_corr, lz_jz_corr, \
           np.nanmean(action[3]) * _freq, or_err * _freq, np.nanmean(action[4]) * _freq, op_err * _freq, np.nanmean(
        action[5]) * _freq, oz_err * _freq, \
           np.nanmean(action[6]), tr_err, np.nanmean(action[7]), tphi_err, np.nanmean(action[8]), tz_err, \
           np.nanmean(Rc), np.nanstd(Rc), np.nanmean(E), np.nanstd(E), np.nanmean(E - Ec), np.nanstd(
        E - Ec), \
           np.nanmean(sRpz[:, 0]) * _R0, \
           np.nanmean(sRpz[:, 1]), \
           np.nanmean(sRpz[:, 2]) * _R0, \
           np.nanmean(svRvTvz[:, 0]) * _v0, \
           np.nanmean(svRvTvz[0, 1]) * _v0, \
           np.nanmean(svRvTvz[:, 2]) * _v0, \
           galr_err * _R0, \
           galphi_err, \
           galz_err * _R0, \
           galvr_err * _v0, \
           galvt_err * _v0, \
           galvz_err * _v0, \
           galvr_galvt_corr, \
           galvr_galvz_corr, \
           galvt_galvz_corr
Ejemplo n.º 21
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
        fixed_quad= (False) if True, use n=10 fixed_quad integration
        scipy.integrate.quadrature keywords
     OUTPUT:
        (jr,lz,jz)
     HISTORY:
        2013-12-28 - Written - Bovy (IAS)
     """
     fixed_quad = kwargs.pop('fixed_quad', False)
     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 = evaluatePotentials(
             R, z, self._pot) + vR**2. / 2. + vT**2. / 2. + vz**2. / 2.
         L = nu.sqrt(L2)
         #Actions
         Jphi = Lz
         Jz = L - nu.fabs(Lz)
         #Jr requires some more work
         #Set up an actionAngleAxi object for EL and rap/rperi calculations
         axiR = nu.sqrt(R**2. + z**2.)
         axivT = L / axiR
         axivR = (R * vR + z * vz) / axiR
         Jr = []
         for ii in range(len(axiR)):
             axiaA = actionAngleAxi(axiR[ii],
                                    axivR[ii],
                                    axivT[ii],
                                    pot=self._2dpot)
             (rperi, rap) = axiaA.calcRapRperi()
             EL = axiaA.calcEL()
             E, L = EL
             Jr.append(self._calc_jr(rperi, rap, E, L, fixed_quad,
                                     **kwargs))
         return (nu.array(Jr), Jphi, Jz)
Ejemplo n.º 22
0
 def actionsFreqsAngles(self, *args, **kwargs):
     """
     NAME:
        actionsFreqsAngles
     PURPOSE:
        evaluate the actions, frequencies, and angles
        (jr,lz,jz,Omegar,Omegaphi,Omegaz,ar,ap,az)
     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
        fixed_quad= (False) if True, use n=10 fixed_quad integration
        scipy.integrate.quadrature keywords
     OUTPUT:
         (jr,lz,jz,Omegar,Omegaphi,Omegaz,ar,aphi,az)
     HISTORY:
        2013-12-29 - Written - Bovy (IAS)
     """
     fixed_quad = kwargs.pop('fixed_quad', False)
     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 = evaluatePotentials(
             R, z, self._pot) + vR**2. / 2. + vT**2. / 2. + vz**2. / 2.
         L = nu.sqrt(L2)
         #Actions
         Jphi = Lz
         Jz = L - nu.fabs(Lz)
         #Jr requires some more work
         #Set up an actionAngleAxi object for EL and rap/rperi calculations
         axiR = nu.sqrt(R**2. + z**2.)
         axivT = L / axiR  #these are really spherical coords, called axi bc they go in actionAngleAxi
         axivR = (R * vR + z * vz) / axiR
         axivz = (z * vR - R * vz) / axiR
         Jr = []
         Or = []
         Op = []
         ar = []
         az = []
         #Calculate the longitude of the ascending node
         asc = self._calc_long_asc(z, R, axivz, phi, Lz, L)
         for ii in range(len(axiR)):
             axiaA = actionAngleAxi(axiR[ii],
                                    axivR[ii],
                                    axivT[ii],
                                    pot=self._2dpot)
             (rperi, rap) = axiaA.calcRapRperi()
             EL = axiaA.calcEL()
             E, L = EL
             Jr.append(self._calc_jr(rperi, rap, E, L, fixed_quad,
                                     **kwargs))
             #Radial period
             Rmean = m.exp((m.log(rperi) + m.log(rap)) / 2.)
             if Jr[-1] < 10.**-9.:  #Circular orbit
                 Or.append(epifreq(self._pot, axiR[ii]))
                 Op.append(omegac(self._pot, axiR[ii]))
             else:
                 Or.append(
                     self._calc_or(Rmean, rperi, rap, E, L, fixed_quad,
                                   **kwargs))
                 Op.append(
                     self._calc_op(Or[-1], Rmean, rperi, rap, E, L,
                                   fixed_quad, **kwargs))
             #Angles
             ar.append(
                 self._calc_angler(Or[-1], axiR[ii], Rmean, rperi, rap, E,
                                   L, axivR[ii], fixed_quad, **kwargs))
             az.append(
                 self._calc_anglez(Or[-1], Op[-1], ar[-1], z[ii], axiR[ii],
                                   Rmean, rperi, rap, E, L, Lz[ii],
                                   axivR[ii], axivz[ii], fixed_quad,
                                   **kwargs))
         Op = nu.array(Op)
         Oz = copy.copy(Op)
         Op[vT < 0.] *= -1.
         ap = copy.copy(asc)
         ar = nu.array(ar)
         az = nu.array(az)
         ap[vT < 0.] -= az[vT < 0.]
         ap[vT >= 0.] += az[vT >= 0.]
         ar = ar % (2. * nu.pi)
         ap = ap % (2. * nu.pi)
         az = az % (2. * nu.pi)
         return (nu.array(Jr), Jphi, Jz, nu.array(Or), Op, Oz, ar, ap, az)
Ejemplo n.º 23
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
        fixed_quad= (False) if True, use n=10 fixed_quad integration
        scipy.integrate.quadrature keywords
     OUTPUT:
         (jr,lz,jz,Omegar,Omegaphi,Omegaz)
     HISTORY:
        2013-12-28 - Written - Bovy (IAS)
     """
     fixed_quad = kwargs.pop('fixed_quad', False)
     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 = evaluatePotentials(
             R, z, self._pot) + vR**2. / 2. + vT**2. / 2. + vz**2. / 2.
         L = nu.sqrt(L2)
         #Actions
         Jphi = Lz
         Jz = L - nu.fabs(Lz)
         #Jr requires some more work
         #Set up an actionAngleAxi object for EL and rap/rperi calculations
         axiR = nu.sqrt(R**2. + z**2.)
         axivT = L / axiR
         axivR = (R * vR + z * vz) / axiR
         Jr = []
         Or = []
         Op = []
         for ii in range(len(axiR)):
             axiaA = actionAngleAxi(axiR[ii],
                                    axivR[ii],
                                    axivT[ii],
                                    pot=self._2dpot)
             (rperi, rap) = axiaA.calcRapRperi()
             EL = axiaA.calcEL()
             E, L = EL
             Jr.append(self._calc_jr(rperi, rap, E, L, fixed_quad,
                                     **kwargs))
             #Radial period
             if Jr[-1] < 10.**-9.:  #Circular orbit
                 Or.append(epifreq(self._pot, axiR[ii]))
                 Op.append(omegac(self._pot, axiR[ii]))
                 continue
             Rmean = m.exp((m.log(rperi) + m.log(rap)) / 2.)
             Or.append(
                 self._calc_or(Rmean, rperi, rap, E, L, fixed_quad,
                               **kwargs))
             Op.append(
                 self._calc_op(Or[-1], Rmean, rperi, rap, E, L, fixed_quad,
                               **kwargs))
         Op = nu.array(Op)
         Oz = copy.copy(Op)
         Op[vT < 0.] *= -1.
         return (nu.array(Jr), Jphi, Jz, nu.array(Or), Op, Oz)
Ejemplo n.º 24
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)))
def process_single(i):
    vxvv = [ra[i], dec[i], distance[i], pmra[i], pmdec[i], rv[i]]
    if not np.all(np.isfinite(vxvv)) or not np.all(np.isfinite(covariance[i])):
        return np.ones(56) * np.nan
    samp = np.random.multivariate_normal(vxvv, covariance[i], size=1000)
    if not (np.all(samp[:, 1] < 90.) & np.all(samp[:, 1] > -90.)):
        return np.ones(56) * np.nan

    os = Orbit(np.array([
        samp[:, 0], samp[:, 1], samp[:, 2], samp[:, 3], samp[:, 4], samp[:, 5]
    ]).T,
               radec=True,
               ro=_R0,
               vo=_v0,
               zo=_z0,
               solarmotion=[-11.1, 25.7, 7.25])

    sXYZ = np.dstack([os.x(), os.y(), os.z()])[0] / _R0
    sRpz = np.dstack([os.R() / _R0, os.phi(), os.z() / _R0])[0]
    svRvTvz = np.dstack([os.vR(), os.vT(), os.vz()])[0] / _v0

    deltas = estimateDeltaStaeckel(MWPotential2014,
                                   np.median(sRpz[:, 0]),
                                   np.median(sRpz[:, 2]),
                                   no_median=True)
    aAS = actionAngleStaeckel(pot=MWPotential2014, delta=np.mean(deltas))
    e, zmax, rperi, rap = aAS.EccZmaxRperiRap(sRpz[:, 0],
                                              svRvTvz[:, 0],
                                              svRvTvz[:, 1],
                                              sRpz[:, 2],
                                              svRvTvz[:, 2],
                                              sRpz[:, 1],
                                              delta=deltas)
    tcov = np.cov(np.dstack([e, zmax, rperi, rap])[0].T)
    errs = np.sqrt(np.diag(tcov))
    e_zmax_corr = tcov[0, 1] / (errs[0] * errs[1])
    e_rperi_corr = tcov[0, 2] / (errs[0] * errs[2])
    e_rap_corr = tcov[0, 3] / (errs[0] * errs[3])
    zmax_rperi_corr = tcov[1, 2] / (errs[1] * errs[2])
    zmax_rap_corr = tcov[1, 3] / (errs[1] * errs[3])
    rperi_rap_corr = tcov[2, 3] / (errs[2] * errs[3])
    e_err, zmax_err, rperi_err, rap_err = errs
    action = np.array(
        aAS.actionsFreqsAngles(sRpz[:, 0], svRvTvz[:, 0], svRvTvz[:, 1],
                               sRpz[:, 2], svRvTvz[:, 2], sRpz[:, 1]))
    tcov_after_action = np.cov(action)
    errs = np.sqrt(np.diag(tcov_after_action))
    jr_lz_corr = tcov_after_action[0, 1] / (errs[0] * errs[1])
    jr_jz_corr = tcov_after_action[0, 2] / (errs[0] * errs[2])
    lz_jz_corr = tcov_after_action[1, 2] / (errs[1] * errs[2])
    jr_err, lz_err, jz_err, or_err, op_err, oz_err, tr_err, tphi_err, tz_err = errs

    Rc = np.array([rl(MWPotential2014, lz) for lz in action[1]]) * _R0
    Ec = (evaluatePotentials(MWPotential2014, Rc, 0.) + 0.5 *
          (action[1])**2. / Rc**2.) * _v0**2
    E = os.E(pot=MWPotential2014)

    # galactocentric coord and vel uncertainty
    galcen_tcov = np.cov(np.dstack([sRpz[:, 0], sRpz[:, 1], sRpz[:, 2]])[0].T)
    galcen_errs = np.sqrt(np.diag(galcen_tcov))
    galr_err, galphi_err, galz_err = galcen_errs

    galcenv_tcov = np.cov(
        np.dstack([svRvTvz[:, 0], svRvTvz[:, 1], svRvTvz[:, 2]])[0].T)
    galcenv_errs = np.sqrt(np.diag(galcenv_tcov))
    galvr_err, galvt_err, galvz_err = galcenv_errs

    galvr_galvt_corr = galcenv_tcov[0, 1] / (galcenv_errs[0] * galcenv_errs[1])
    galvr_galvz_corr = galcenv_tcov[0, 2] / (galcenv_errs[0] * galcenv_errs[2])
    galvt_galvz_corr = galcenv_tcov[1, 2] / (galcenv_errs[1] * galcenv_errs[2])

    # galr mean to avoid issue near GC, error propagation
    x_mean = np.nanmean(sXYZ[:, 0])
    y_mean = np.nanmean(sXYZ[:, 1])
    x_err = np.nanstd(sXYZ[:, 0])
    y_err = np.nanstd(sXYZ[:, 1])
    x_err_percentage = x_err / np.nanmean(sXYZ[:, 0])
    y_err_percentage = y_err / np.nanmean(sXYZ[:, 1])
    x2_err = (x_mean**2) * (2 * x_err_percentage)
    y2_err = (y_mean**2) * (2 * y_err_percentage)
    galr = np.sqrt(x_mean**2 + y_mean**2)
    galr2_err = np.sqrt(x2_err**2 + y2_err**2)
    galr2_err_percentage = galr2_err / (galr**2)
    galr_err = galr * (0.5 * galr2_err_percentage)

    # galphi mean to avoid issue near GC, error propagation
    galphi = np.arctan2(y_mean, x_mean)
    galphi_err_x = (
        y_mean /
        (x_mean**2 + y_mean**2)) * x_err  # error propagation from x_mean
    galphi_err_y = (
        -x_mean /
        (x_mean**2 + y_mean**2)) * y_err  # error propagation from y_mean
    galphi_err = np.sqrt(galphi_err_x**2 + galphi_err_y**2)  # add them up

    return np.nanmean(e), \
           e_err, \
           np.nanmean(zmax) * _R0, \
           zmax_err * _R0, \
           np.nanmean(rperi) * _R0, \
           rperi_err * _R0, \
           np.nanmean(rap) * _R0, \
           rap_err * _R0, \
           e_zmax_corr, \
           e_rperi_corr, \
           e_rap_corr, \
           zmax_rperi_corr, \
           zmax_rap_corr, \
           rperi_rap_corr, \
           np.nanmean(action[0]) * _R0 * _v0, \
           jr_err * _R0 * _v0, \
           np.nanmean(action[1]) * _R0 * _v0, \
           lz_err * _R0 * _v0, \
           np.nanmean(action[2]) * _R0 * _v0, \
           jz_err * _R0 * _v0, \
           jr_lz_corr, \
           jr_jz_corr, \
           lz_jz_corr, \
           np.nanmean(action[3]) * _freq, or_err * _freq, \
           np.nanmean(action[4]) * _freq, op_err * _freq, \
           np.nanmean(action[5]) * _freq, oz_err * _freq, \
           np.nanmean(action[6]), \
           tr_err, \
           np.nanmean(action[7]), \
           tphi_err, \
           np.nanmean(action[8]), \
           tz_err, \
           np.nanmean(Rc), \
           np.nanstd(Rc), \
           np.nanmean(E), \
           np.nanstd(E), \
           np.nanmean(E - Ec), \
           np.nanstd(E - Ec), \
           galr * _R0, \
           galphi, \
           np.nanmean(sRpz[:, 2]) * _R0, \
           np.nanmean(svRvTvz[:, 0]) * _v0, \
           np.nanmean(svRvTvz[0, 1]) * _v0, \
           np.nanmean(svRvTvz[:, 2]) * _v0, \
           galr_err * _R0, \
           galphi_err, \
           galz_err * _R0, \
           galvr_err * _v0, \
           galvt_err * _v0, \
           galvz_err * _v0, \
           galvr_galvt_corr, \
           galvr_galvz_corr, \
           galvt_galvz_corr
Ejemplo n.º 26
0
def _jzIntegrand(z,R,pot,Ez,potzero,vz):
    vz2= 2.*Ez-evaluatePotentials(R,z,pot)/vz**2.+potzero
    if vz2 < 0.: return 0. #Such that we don't have to specify the upper limit
    else: return numpy.sqrt(vz2)
Ejemplo n.º 27
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")
def plotForceField(savefig: Optional[str] = None):
    """Plot MW Force Field.

    Parameters
    ----------
    savefic: str, optional

    """
    p_b15_pal5gd1_voro = fit(fitc=True,
                             c=None,
                             addpal5=True,
                             addgd1=True,
                             fitvoro=True,
                             mc16=True)

    # Set up potential
    p_b15 = p_b15_pal5gd1_voro[0]
    ro, vo = REFR0, REFV0
    pot = setup_potential(p_b15, p_b15_pal5gd1_voro[0][-1], False, False, ro,
                          vo)
    # Compute force field
    Rs = np.linspace(0.01, 20.0, 51)
    zs = np.linspace(-20.0, 20.0, 151)
    mRs, mzs = np.meshgrid(Rs, zs, indexing="ij")
    forces = np.zeros((len(Rs), len(zs), 2))
    potvals = np.zeros((len(Rs), len(zs)))
    for ii in tqdm(range(len(Rs))):
        for jj in tqdm(range(len(zs))):
            forces[ii, jj, 0] = potential.evaluateRforces(
                pot,
                mRs[ii, jj] / ro,
                mzs[ii, jj] / ro,
                use_physical=True,
                ro=ro,
                vo=vo,
            )
            forces[ii, jj, 1] = potential.evaluatezforces(
                pot,
                mRs[ii, jj] / ro,
                mzs[ii, jj] / ro,
                use_physical=True,
                ro=ro,
                vo=vo,
            )
            potvals[ii, jj] = potential.evaluatePotentials(
                pot,
                mRs[ii, jj] / ro,
                mzs[ii, jj] / ro,
                use_physical=True,
                ro=ro,
                vo=vo,
            )

    fig = plt.figure(figsize=(8, 16))
    skip = 10  # Make sure to keep zs symmetric!!
    scale = 35.0
    # Don't plot these
    # forces[(mRs < 5.)*(np.fabs(mzs) < 4.)]= np.nan
    forces[(mRs < 2.0) * (np.fabs(mzs) < 5.0)] = np.nan
    bovy_plot.bovy_dens2d(
        potvals.T,
        origin="lower",
        cmap="viridis",
        xrange=[Rs[0], Rs[-1]],
        yrange=[zs[0], zs[-1]],
        xlabel=r"$R\,(\mathrm{kpc})$",
        ylabel=r"$Z\,(\mathrm{kpc})$",
        contours=True,
        aspect=1.0,
    )
    plt.quiver(
        mRs[1::skip, 5:-1:skip],
        mzs[1::skip, 5:-1:skip],
        forces[1::skip, 5:-1:skip, 0],
        forces[1::skip, 5:-1:skip, 1],
        scale=scale,
    )
    # Add a few lines pointing to the GC
    for angle in tqdm(np.linspace(0.0, np.pi / 2.0, 8)):
        plt.plot((0.0, 100.0 * np.cos(angle)), (0.0, 100.0 * np.sin(angle)),
                 "k:")
        plt.plot((0.0, 100.0 * np.cos(angle)), (0.0, -100.0 * np.sin(angle)),
                 "k:")
    # Add measurements
    # Pal 5
    plt.quiver((8.0, ), (16.0, ), (-0.8, ), (-1.82, ),
               color="w",
               zorder=10,
               scale=scale)
    # GD-1
    plt.quiver(
        (12.5, ),
        (6.675, ),
        (-2.51, ),
        (-1.47, ),
        color="w",
        zorder=10,
        scale=scale,
    )
    # Disk + flat APOGEE rotation curve:
    # Use Bovy & Tremaine (2012) method for translating F_R in the plane to F_R
    # at 1.1 kpc: dFr/dz = dFz / dR
    diskrs = np.linspace(5.5, 8.5, 3)
    diskfzs = (-67.0 * np.exp(-(diskrs - 8.0) / 2.7) /
               bovy_conversion.force_in_2piGmsolpc2(220.0, 8.0) *
               bovy_conversion.force_in_kmsMyr(220.0, 8.0))
    diskfrs = (-(218.0**2.0 / diskrs) * bovy_conversion._kmsInPcMyr / 1000.0 -
               1.1 * diskfzs / 2.7)
    plt.quiver(
        diskrs,
        1.1 * np.ones_like(diskrs),
        diskfrs,
        diskfzs,
        color="w",
        zorder=10,
        scale=scale,
    )
    # Labels
    bovy_plot.bovy_text(5.8, 16.0, r"$\mathbf{Pal\ 5}$", color="w", size=17.0)
    bovy_plot.bovy_text(12.5, 7.0, r"$\mathbf{GD-1}$", color="w", size=17.0)
    bovy_plot.bovy_text(8.65,
                        0.5,
                        r"$\mathbf{disk\ stars}$",
                        color="w",
                        size=17.0)

    if savefig is not None:
        fig.savefig(savefig)

    return fig
Ejemplo n.º 29
0
def test_vcirc():
    #test the circular velocity of the KuzminKutuzovStaeckelPotential
    #using parameters from Batsleer & Dejonghe 1994, fig. 1-3
    #and their formula eq. (10)

    #_____model parameters______
    #surface ratios of disk and halo:
    ac_Ds = [50., 50., 50., 50., 50., 50., 40., 40., 40.]
    ac_Hs = [1.005, 1.005, 1.005, 1.01, 1.01, 1.01, 1.02, 1.02, 1.02]
    #disk contribution to total mass:
    ks = [0.05, 0.06, 0.07, 0.07, 0.1, 0.125, 0.1, 0.12, 0.125]
    #focal distance:
    Delta = 1.

    for ii in range(9):
        ac_D = ac_Ds[ii]
        ac_H = ac_Hs[ii]
        k = ks[ii]

        #_____setup potential_____
        #first try, not normalized:
        V_D = KuzminKutuzovStaeckelPotential(amp=k,
                                             ac=ac_D,
                                             Delta=Delta,
                                             normalize=False)
        V_H = KuzminKutuzovStaeckelPotential(amp=(1. - k),
                                             ac=ac_H,
                                             Delta=Delta,
                                             normalize=False)
        pot = [V_D, V_H]
        #normalization according to Batsleer & Dejonghe 1994:
        V00 = evaluatePotentials(pot, 0., 0.)
        #second try, normalized:
        V_D = KuzminKutuzovStaeckelPotential(amp=k / (-V00),
                                             ac=ac_D,
                                             Delta=Delta,
                                             normalize=False)
        V_H = KuzminKutuzovStaeckelPotential(amp=(1. - k) / (-V00),
                                             ac=ac_H,
                                             Delta=Delta,
                                             normalize=False)
        pot = [V_D, V_H]

        #_____calculate rotation curve_____
        Rs = numpy.linspace(0., 20., 100)
        z = 0.
        vcirc_calc = numpy.sqrt(-Rs * evaluateRforces(pot, Rs, z))

        #_____vcirc by Batsleer & Dejonghe eq. (10) (with proper Jacobian)_____
        def vc2w(R):
            g_D = Delta**2 / (1. - ac_D**2)
            a_D = g_D - Delta**2
            g_H = Delta**2 / (1. - ac_H**2)
            a_H = g_H - Delta**2
            l = R**2 - a_D
            q = a_H - a_D
            termD = numpy.sqrt(l) * (numpy.sqrt(l) + numpy.sqrt(-g_D))**2
            termH = numpy.sqrt(l - q) * (numpy.sqrt(l - q) +
                                         numpy.sqrt(-g_D - q))**2
            return R**2 * (k / termD + (1. - k) / termH)

        vcirc_formula = numpy.sqrt(vc2w(Rs) / (-V00))

        assert numpy.all(numpy.fabs(vcirc_calc - vcirc_formula) < 10**-8.), \
                'Calculated circular velocity for KuzminKutuzovStaeckelPotential '+ \
                'does not agree with eq. (10) (corrected by proper Jacobian) '+ \
                'by Batsleer & Dejonghe (1994)'

    return None
Ejemplo n.º 30
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")
Ejemplo n.º 31
0
 def __init__(self,
              RZPot=None,rgrid=(0.01,2.,101),zgrid=(0.,0.2,101),logR=False,
              interpPot=False,interpRforce=False,interpzforce=False,
              interpDens=False,
              interpvcirc=False,
              interpdvcircdr=False,
              interpepifreq=False,interpverticalfreq=False,
              use_c=False,enable_c=False,zsym=True,
              numcores=None):
     """
     NAME:
        __init__
     PURPOSE:
        Initialize an interpRZPotential instance
     INPUT:
        RZPot - RZPotential to be interpolated
        rgrid - R grid to be given to linspace
        zgrid - z grid to be given to linspace
        logR - if True, rgrid is in the log of R
        interpPot, interpRfoce, interpzforce, interpDens,interpvcirc, interpeopifreq, interpverticalfreq, interpdvcircdr= if True, interpolate these functions
        use_c= use C to speed up the calculation
        enable_c= enable use of C for interpolations
        zsym= if True (default), the potential is assumed to be symmetric around z=0 (so you can use, e.g.,  zgrid=(0.,1.,101)).
        numcores= if set to an integer, use this many cores (only used for vcirc, dvcircdR, epifreq, and verticalfreq; NOT NECESSARILY FASTER, TIME TO MAKE SURE)
     OUTPUT:
        instance
     HISTORY:
        2010-07-21 - Written - Bovy (NYU)
        2013-01-24 - Started with new implementation - Bovy (IAS)
     """
     Potential.__init__(self,amp=1.)
     self.hasC= True
     self._origPot= RZPot
     self._rgrid= numpy.linspace(*rgrid)
     self._logR= logR
     if self._logR:
         self._rgrid= numpy.exp(self._rgrid)
         self._logrgrid= numpy.log(self._rgrid)
     self._zgrid= numpy.linspace(*zgrid)
     self._interpPot= interpPot
     self._interpRforce= interpRforce
     self._interpzforce= interpzforce
     self._interpDens= interpDens
     self._interpvcirc= interpvcirc
     self._interpdvcircdr= interpdvcircdr
     self._interpepifreq= interpepifreq
     self._interpverticalfreq= interpverticalfreq
     self._enable_c= enable_c*ext_loaded
     self._zsym= zsym
     if interpPot:
         if use_c*ext_loaded:
             self._potGrid, err= calc_potential_c(self._origPot,self._rgrid,self._zgrid)
         else:
             from galpy.potential import evaluatePotentials
             potGrid= numpy.zeros((len(self._rgrid),len(self._zgrid)))
             for ii in range(len(self._rgrid)):
                 for jj in range(len(self._zgrid)):
                     potGrid[ii,jj]= evaluatePotentials(self._rgrid[ii],self._zgrid[jj],self._origPot)
             self._potGrid= potGrid
         if self._logR:
             self._potInterp= interpolate.RectBivariateSpline(self._logrgrid,
                                                              self._zgrid,
                                                              self._potGrid,
                                                              kx=3,ky=3,s=0.)
         else:
             self._potInterp= interpolate.RectBivariateSpline(self._rgrid,
                                                              self._zgrid,
                                                              self._potGrid,
                                                              kx=3,ky=3,s=0.)
         if enable_c*ext_loaded:
             self._potGrid_splinecoeffs= calc_2dsplinecoeffs_c(self._potGrid)
     if interpRforce:
         if use_c*ext_loaded:
             self._rforceGrid, err= calc_potential_c(self._origPot,self._rgrid,self._zgrid,rforce=True)
         else:
             from galpy.potential import evaluateRforces
             rforceGrid= numpy.zeros((len(self._rgrid),len(self._zgrid)))
             for ii in range(len(self._rgrid)):
                 for jj in range(len(self._zgrid)):
                     rforceGrid[ii,jj]= evaluateRforces(self._rgrid[ii],self._zgrid[jj],self._origPot)
             self._rforceGrid= rforceGrid
         if self._logR:
             self._rforceInterp= interpolate.RectBivariateSpline(self._logrgrid,
                                                                 self._zgrid,
                                                                 self._rforceGrid,
                                                                 kx=3,ky=3,s=0.)
         else:
             self._rforceInterp= interpolate.RectBivariateSpline(self._rgrid,
                                                                 self._zgrid,
                                                                 self._rforceGrid,
                                                                 kx=3,ky=3,s=0.)
         if enable_c*ext_loaded:
             self._rforceGrid_splinecoeffs= calc_2dsplinecoeffs_c(self._rforceGrid)
     if interpzforce:
         if use_c*ext_loaded:
             self._zforceGrid, err= calc_potential_c(self._origPot,self._rgrid,self._zgrid,zforce=True)
         else:
             from galpy.potential import evaluatezforces
             zforceGrid= numpy.zeros((len(self._rgrid),len(self._zgrid)))
             for ii in range(len(self._rgrid)):
                 for jj in range(len(self._zgrid)):
                     zforceGrid[ii,jj]= evaluatezforces(self._rgrid[ii],self._zgrid[jj],self._origPot)
             self._zforceGrid= zforceGrid
         if self._logR:
             self._zforceInterp= interpolate.RectBivariateSpline(self._logrgrid,
                                                                 self._zgrid,
                                                                 self._zforceGrid,
                                                                 kx=3,ky=3,s=0.)
         else:
             self._zforceInterp= interpolate.RectBivariateSpline(self._rgrid,
                                                                 self._zgrid,
                                                                 self._zforceGrid,
                                                                 kx=3,ky=3,s=0.)
         if enable_c*ext_loaded:
             self._zforceGrid_splinecoeffs= calc_2dsplinecoeffs_c(self._zforceGrid)
     if interpDens:
         if False:
             raise NotImplementedError("Using C to calculate an interpolation grid for the density is not supported currently")
             self._densGrid, err= calc_dens_c(self._origPot,self._rgrid,self._zgrid)
         else:
             from galpy.potential import evaluateDensities
             densGrid= numpy.zeros((len(self._rgrid),len(self._zgrid)))
             for ii in range(len(self._rgrid)):
                 for jj in range(len(self._zgrid)):
                     densGrid[ii,jj]= evaluateDensities(self._rgrid[ii],self._zgrid[jj],self._origPot)
             self._densGrid= densGrid
         if self._logR:
             self._densInterp= interpolate.RectBivariateSpline(self._logrgrid,
                                                               self._zgrid,
                                                               numpy.log(self._densGrid+10.**-10.),
                                                               kx=3,ky=3,s=0.)
         else:
             self._densInterp= interpolate.RectBivariateSpline(self._rgrid,
                                                               self._zgrid,
                                                               numpy.log(self._densGrid+10.**-10.),
                                                               kx=3,ky=3,s=0.)
         if False:
             self._densGrid_splinecoeffs= calc_2dsplinecoeffs_c(self._densGrid)
     if interpvcirc:
         from galpy.potential import vcirc
         if not numcores is None:
             self._vcircGrid= multi.parallel_map((lambda x: vcirc(self._origPot,self._rgrid[x])),
                                                 range(len(self._rgrid)),numcores=numcores)
         else:
             self._vcircGrid= numpy.array([vcirc(self._origPot,r) for r in self._rgrid])
         if self._logR:
             self._vcircInterp= interpolate.InterpolatedUnivariateSpline(self._logrgrid,self._vcircGrid,k=3)
         else:
             self._vcircInterp= interpolate.InterpolatedUnivariateSpline(self._rgrid,self._vcircGrid,k=3)
     if interpdvcircdr:
         from galpy.potential import dvcircdR
         if not numcores is None:
             self._dvcircdrGrid= multi.parallel_map((lambda x: dvcircdR(self._origPot,self._rgrid[x])),
                                                    range(len(self._rgrid)),numcores=numcores)
         else:
             self._dvcircdrGrid= numpy.array([dvcircdR(self._origPot,r) for r in self._rgrid])
         if self._logR:
             self._dvcircdrInterp= interpolate.InterpolatedUnivariateSpline(self._logrgrid,self._dvcircdrGrid,k=3)
         else:
             self._dvcircdrInterp= interpolate.InterpolatedUnivariateSpline(self._rgrid,self._dvcircdrGrid,k=3)
     if interpepifreq:
         from galpy.potential import epifreq
         if not numcores is None:
             self._epifreqGrid= multi.parallel_map((lambda x: epifreq(self._origPot,self._rgrid[x])),
                                                   range(len(self._rgrid)),numcores=numcores)
         else:
             self._epifreqGrid= numpy.array([epifreq(self._origPot,r) for r in self._rgrid])
         indx= True-numpy.isnan(self._epifreqGrid)
         if numpy.sum(indx) < 4:
             if self._logR:
                 self._epifreqInterp= interpolate.InterpolatedUnivariateSpline(self._logrgrid[indx],self._epifreqGrid[indx],k=1)
             else:
                 self._epifreqInterp= interpolate.InterpolatedUnivariateSpline(self._rgrid[indx],self._epifreqGrid[indx],k=1)
         else:
             if self._logR:
                 self._epifreqInterp= interpolate.InterpolatedUnivariateSpline(self._logrgrid[indx],self._epifreqGrid[indx],k=3)
             else:
                 self._epifreqInterp= interpolate.InterpolatedUnivariateSpline(self._rgrid[indx],self._epifreqGrid[indx],k=3)
     if interpverticalfreq:
         from galpy.potential import verticalfreq
         if not numcores is None:
             self._verticalfreqGrid= multi.parallel_map((lambda x: verticalfreq(self._origPot,self._rgrid[x])),
                                                    range(len(self._rgrid)),numcores=numcores)
         else:
             self._verticalfreqGrid= numpy.array([verticalfreq(self._origPot,r) for r in self._rgrid])
         if self._logR:
             self._verticalfreqInterp= interpolate.InterpolatedUnivariateSpline(self._logrgrid,self._verticalfreqGrid,k=3)
         else:
             self._verticalfreqInterp= interpolate.InterpolatedUnivariateSpline(self._rgrid,self._verticalfreqGrid,k=3)
     return None
Ejemplo n.º 32
0
def RK():
    r=8e3*pc_in_km        #位置の初期値 km
    phi=0.0
    z = 0.0*pc_in_km  #km
    vr=vr0                #km/s    #速度の初期値
    vphi=vphi0 
    vz=vz0 
    tmax=46e+8*year_in_sec  #繰り返し最大回数
    dt=1e+3*year_in_sec                #刻み幅

    t_list,r_list,phi_list,z_list,vr_list,vphi_list,vz_list,E_list,Lz_list =\
    [],[],[],[],[],[],[],[],[]

    for i in range(0,int(tmax/dt)):
        t = dt*i

        k10=dt*fr(r,phi,z,vr,vphi,vz)
        k11=dt*fphi(r,phi,z,vr,vphi,vz)
        k12=dt*fz(r,phi,z,vr,vphi,vz)
        k13=dt*fvr(r,phi,z,vr,vphi,vz)
        k14=dt*fvphi(r,phi,z,vr,vphi,vz)
        k15=dt*fvz(r,phi,z,vr,vphi,vz)

        k20=dt/2.*fr(r+k10/2.,phi+k11/2.,
                       z+k12/2.,vr+k13/2.,
                       vphi+k14/2.,vz+k15/2.)
        k21=dt/2.*fphi(r+k10/2.,phi+k11/2.,
                         z+k12/2.,vr+k13/2.,
                         vphi+k14/2.,vz+k15/2.)
        k22=dt/2.*fz(r+k10/2.,phi+k11/2.,
                         z+k12/2.,vr+k13/2.,
                         vphi+k14/2.,vz+k15/2.)
        k23=dt/2.*fvr(r+k10/2.,phi+k11/2.,
                        z+k12/2.,vr+k13/2.,
                        vphi+k14/2.,vz+k15/2.)
        k24=dt/2.*fvphi(r+k10/2.,phi+k11/2.,
                          z+k12/2.,vr+k13/2.,
                           vphi+k14/2.,vz+k15/2.)
        k25=dt/2.*fvz(r+k10/2.,phi+k11/2.,
                        z+k12/2.,vr+k13/2.,
                        vphi+k14/2.,vz+k15/2.)

        k30=dt/2.*fr(r+k20/2.,phi+k21/2.,
                       z+k22/2.,vr+k23/2.,
                       vphi+k24/2.,vz+k25/2.)
        k31=dt/2.*fphi(r+k20/2.,phi+k21/2.,
                         z+k22/2.,vr+k23/2.,
                         vphi+k24/2.,vz+k25/2.)
        k32=dt/2.*fz(r+k20/2.,phi+k21/2.,
                       z+k22/2.,vr+k23/2.,
                       vphi+k24/2.,vz+k25/2.)
        k33=dt/2.*fvr(r+k20/2.,phi+k21/2.,
                        z+k22/2.,vr+k23/2.,
                        vphi+k24/2.,vz+k25/2.)
        k34=dt/2.*fvphi(r+k20/2.,phi+k21/2.,
                          z+k22/2.,vr+k23/2.,
                          vphi+k24/2.,vz+k25/2.)
        k35=dt/2.*fvz(r+k20/2.,phi+k21/2.,
                        z+k22/2.,vr+k23/2.,
                        vphi+k24/2.,vz+k25/2.)

        k40=dt*fr(r+k30,phi+k31,
                  z+k32,vr+k33,
                  vphi+k34,vz+k35)
        k41=dt*fphi(r+k30,phi+k31,
                    z+k32,vr+k33,
                    vphi+k34,vz+k35)
        k42=dt*fz(r+k30,phi+k31,
                  z+k32,vr+k33,
                  vphi+k34,vz+k35)
        k43=dt*fvr(r+k30,phi+k31,
                   z+k32,vr+k33,
                   vphi+k34,vz+k35)
        k44=dt*fvphi(r+k30,phi+k31,
                     z+k32,vr+k33,
                     vphi+k34,vz+k35)
        k45=dt*fvz(r+k30,phi+k31,
                   z+k32,vr+k33,
                   vphi+k34,vz+k35)

        r+=(k10+2.*k20+2.*k30+k40)/6.0
        phi+=(k11+2.*k21+2.*k31+k41)/6.0
        z+=(k12+2.*k22+2.*k32+k42)/6.0
        vr+=(k13+2.*k23+2.*k33+k43)/6.0
        vphi+=(k14+2.*k24+2.*k34+k44)/6.0
        vz+=(k15+2.*k25+2.*k35+k45)/6.0

        E = 0.5*(vr**2. + vphi**2. + vz**2.) + evaluatePotentials(MWPotential2014,R=r,z=z)

        Lz = r*vphi

        t_list.append(t)
        r_list.append(r)
        phi_list.append(phi)
        z_list.append(z)
        vr_list.append(vr)
        vphi_list.append(vphi)
        vz_list.append(vz)
        E_list.append(E)
        Lz_list.append(Lz)

    t_array = np.array([t_list])[0,:]
    r_array = np.array([r_list])[0,:]
    phi_array = np.array([phi_list])[0,:]
    z_array = np.array([z_list])[0,:]
    vr_array = np.array([vr_list])[0,:]
    vphi_array = np.array([vphi_list])[0,:]
    vz_array = np.array([vz_list])[0,:]
    E_array = np.array([E_list])[0,:]
    Lz_array = np.array([Lz_list])[0,:]

    data = np.array([t_array/(1e6*year_in_sec),r_array/1e3/pc_in_km,phi_array,\
                    z_array/pc_in_km,vr_array,vphi_array,vz_array,E_array,Lz_array]).T
    np.savetxt('output_MW14.dat', data)