예제 #1
0
def minimize_function(x, rho_nfw_target, rho_midplane_target,
                      density_conversion):
    """
    Computes the chi^2 penalty for a galactic potential for the purpose of finding an NFWPotential and MiyamotoNagaiPotential
    circular velocity normalization that yeild the desired midplane and nfw physical densities
    :param x: numpy array of proposed disk and nfw circular velocity normalizations (in that order)
    :param rho_nfw_target: desired nfw_normalization in physical M_sun / pc^2
    :param rho_midplane_target: desired midplane density in physical M_sun / pc^2
    :param density_conversion: a conversion factor between galpy internal density units and physical M_sun / pc^2
    :return: chi^2 penalty
    """

    galactic_potential = [
        PowerSphericalPotentialwCutoff(normalize=0.05, alpha=1.8, rc=1.9 / 8.),
        MiyamotoNagaiPotential(a=3. / 8., b=0.28 / 8., normalize=x[0]),
        NFWPotential(a=2., normalize=x[1])
    ]
    nfw_potential = NFWPotential(a=2., normalize=x[1])

    rho = evaluateDensities(galactic_potential, R=1.,
                            z=0.) * density_conversion
    rho_nfw = evaluateDensities(nfw_potential, R=1, z=0.) * density_conversion
    dx = (rho - rho_midplane_target)**2 / 0.000001**2 + (
        rho_nfw - rho_nfw_target)**2 / 0.000001**2

    return dx**0.5
예제 #2
0
 def _dens(self,R,z,phi=0.,t=0.):
     """
     NAME:
        _dens
     PURPOSE:
        evaluate the density for this potential
     INPUT:
        R - Galactocentric cylindrical radius
        z - vertical height
        phi - azimuth
        t - time
     OUTPUT:
        the density
     HISTORY:
        2013-01-29 - Written - Bovy (IAS)
     """
     if self._interpDens and False:#self._enable_c:
         if isinstance(R,float):
             R= numpy.array([R])
         if isinstance(z,float):
             z= numpy.array([z])
         if self._zsym:
             return eval_dens_c(self,R,numpy.fabs(z))[0]
         else:
             return eval_dens_c(self,R,z)[0]
     from galpy.potential import evaluateDensities
     if self._interpDens:
         if isinstance(R,float):
             return self._dens(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]= numpy.exp(self._densInterp.ev(numpy.log(R[indx]),numpy.fabs(z[indx])))-10.**-10.
                 else:
                     out[indx]= numpy.exp(self._densInterp.ev(R[indx],numpy.fabs(z[indx])))-10.**-10.
             else:
                 if self._logR:
                     out[indx]= numpy.exp(self._densInterp.ev(numpy.log(R[indx]),z[indx]))-10.**-10.
                 else:
                     out[indx]= numpy.exp(self._densInterp.ev(R[indx],z[indx]))-10.**-10.
         if numpy.sum(True-indx) > 0:
             out[True-indx]= evaluateDensities(R[True-indx],
                                               z[True-indx],
                                               self._origPot)
         return out
     else:
         return evaluateDensities(R,z,self._origPot)
예제 #3
0
    def _dens(self, R, z, phi=0.0, t=0.0):
        from galpy.potential import evaluateDensities

        if self._interpDens:
            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._logR:
                    out[indx] = numpy.exp(self._densInterp.ev(numpy.log(R[indx]), z[indx])) - 10.0 ** -10.0
                else:
                    out[indx] = numpy.exp(self._densInterp.ev(R[indx], z[indx])) - 10.0 ** -10.0
            if numpy.sum(True - indx) > 0:
                out[True - indx] = evaluateDensities(R[True - indx], z[True - indx], self._origPot)
            return out
        else:
            return evaluateDensities(R, z, self._origPot)
예제 #4
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)))
예제 #5
0
    def mass_density(self,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))

        dens=potential.evaluateDensities(self.pot,R/self.ro,zed/self.ro,phi=phi,t=self.tgalpy,ro=self.ro,vo=self.vo) | units.MSun/(units.parsec**3.)
                        
        return dens
예제 #6
0
 def _dens(self,R,z,phi=0.,t=0.):
     from galpy.potential import evaluateDensities
     if self._interpDens:
         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._logR:
                 out[indx]= numpy.exp(self._densInterp.ev(numpy.log(R[indx]),z[indx]))-10.**-10.
             else:
                 out[indx]= numpy.exp(self._densInterp.ev(R[indx],z[indx]))-10.**-10.
         if numpy.sum(True^indx) > 0:
             out[True^indx]= evaluateDensities(self._origPot,
                                               R[True^indx],
                                               z[True^indx])
         return out
     else:
         return evaluateDensities(self._origPot,R,z)
예제 #7
0
def test_estimate_hz():
    qdf= quasiisothermaldf(1./4.,0.2,0.1,1.,1.,
                           pot=MWPotential,aA=aAS,cutcounter=True)
    from scipy import integrate
    from galpy.potential import evaluateDensities
    expec_hz= 0.1**2./2.\
        /integrate.quad(lambda x: evaluateDensities(0.9,x,MWPotential),
                        0.,0.125)[0]/2./numpy.pi
    assert numpy.fabs((qdf.estimate_hz(0.9,z=0.125)-expec_hz)/expec_hz) < 0.1, 'estimated scale height not as expected'
    assert qdf.estimate_hz(0.9,z=0.) > 1., 'estimated scale height at z=0 not very large'
    #Another one
    qdf= quasiisothermaldf(1./4.,0.3,0.2,1.,1.,
                           pot=MWPotential,aA=aAS,cutcounter=True)
    expec_hz= 0.2**2./2.\
        /integrate.quad(lambda x: evaluateDensities(0.9,x,MWPotential),
                        0.,0.125)[0]/2./numpy.pi
    assert numpy.fabs((qdf.estimate_hz(0.9,z=0.125)-expec_hz)/expec_hz) < 0.15, 'estimated scale height not as expected'
    return None
예제 #8
0
def plotPriorSurf(plotfilename):
    #Calculate the surface density profile for each trial potential, then plot the range
    if '.png' in plotfilename:
        savefilename= plotfilename.replace('.png','.sav')
    elif '.ps' in plotfilename:
        savefilename= plotfilename.replace('.ps','.sav')
    if not os.path.exists(savefilename):
        options= setup_options(None)
        options.potential= 'dpdiskplhalofixbulgeflatwgasalt'
        options.fitdvt= False
        rs= numpy.linspace(4.2,9.8,101)
        rds= numpy.linspace(2.,3.4,8)
        fhs= numpy.linspace(0.,1.,16)
        surfz= numpy.zeros((len(rs),len(rds)*len(fhs)))+numpy.nan
        ro= 1.
        vo= 230./220.
        dlnvcdlnr= 0.
        zh= 400.
        for jj in range(len(rds)):
            for kk in range(len(fhs)):
                #Setup potential to calculate stuff
                potparams= numpy.array([numpy.log(rds[jj]/8.),vo,numpy.log(zh/8000.),fhs[kk],dlnvcdlnr])
                try:
                    pot= setup_potential(potparams,options,0,returnrawpot=True)
                except RuntimeError:
                    continue
                for ii in range(len(rs)):
                    surfz[ii,jj*len(fhs)+kk]= 2.*integrate.quad((lambda zz: potential.evaluateDensities(rs[ii]/8.,zz,pot)),0.,options.height/_REFR0/ro)[0]*_REFV0**2.*vo**2./_REFR0**2./ro**2./4.302*_REFR0*ro
        #Find minimum and maximum curves
        minsurfz= numpy.nanmin(surfz,axis=1)
        maxsurfz= numpy.nanmax(surfz,axis=1)
        #Save
        save_pickles(savefilename,rs,minsurfz,maxsurfz)
    else:
        savefile= open(savefilename,'rb')
        rs= pickle.load(savefile)
        minsurfz= pickle.load(savefile)
        maxsurfz= pickle.load(savefile)
        savefile.close()
    #Plot
    bovy_plot.bovy_print()
    bovy_plot.bovy_plot([numpy.nan],[numpy.nan],'ko',
                        xlabel=r'$R\ (\mathrm{kpc})$',
                        ylabel=r'$\Sigma(R,|Z| \leq 1.1\,\mathrm{kpc})\ (M_\odot\,\mathrm{pc}^{-2})$',
                        xrange=[4.,10.],
                        yrange=[10,1050.],
                        semilogy=True)
    pyplot.fill_between(rs,minsurfz,maxsurfz,
                        color='0.50')
    bovy_plot.bovy_text(8.,68.,r'$\odot$',size=16.,verticalalignment='center',
                        horizontalalignment='center')
    bovy_plot.bovy_end_print(plotfilename)
    return None
예제 #9
0
def visible_dens(
    pot: Sequence[Potential],
    ro: float = REFR0,
    vo: float = REFV0,
    r: float = 1.0,
) -> float:
    """The visible surface density at 8 kpc from the center.

    Parameters
    ----------
    pot: Potential
    ro : float
        default REFR0
    vo : float
        default REFV0
    r: float
        default 1.0

    Returns
    -------
    float

    """
    if len(pot) == 4:
        return (2.0 * (integrate.quad(
            (lambda zz: potential.evaluateDensities(pot[1], r, zz, phi=0.0)),
            0.0,
            2.0,
        )[0] + integrate.quad(
            (lambda zz: potential.evaluateDensities(pot[3], r, zz, phi=0.0)),
            0.0,
            2.0,
        )[0]) * bovy_conversion.surfdens_in_msolpc2(vo, ro))
    else:
        return (2.0 * integrate.quad(
            (lambda zz: potential.evaluateDensities(pot[1], r, zz, phi=0.0)),
            0.0,
            2.0,
        )[0] * bovy_conversion.surfdens_in_msolpc2(vo, ro))
예제 #10
0
    def test_minimize_func(self):

        disk_norm, nfw_norm = solve_normalizations(self.rho_nfw_target,
                                                   self.rho_midplane_target,
                                                   self.density_conversion)

        pot = [
            PowerSphericalPotentialwCutoff(normalize=0.05,
                                           alpha=1.8,
                                           rc=1.9 / 8.),
            MiyamotoNagaiPotential(a=3. / 8., b=0.28 / 8.,
                                   normalize=disk_norm),
            NFWPotential(a=2., normalize=nfw_norm)
        ]
        rho = evaluateDensities(pot, R=1., z=0) * self.density_conversion
        npt.assert_almost_equal(rho, self.rho_midplane_target, 3)

        disk_norm, nfw_norm = solve_normalizations(self.rho_nfw_target,
                                                   self.rho_nfw_target * 0.5,
                                                   self.density_conversion)
        npt.assert_equal(True, disk_norm < 0)
예제 #11
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
예제 #12
0
def calcOrbits(parser):
    options,args= parser.parse_args()
    #Read data
    XYZ,vxvyvz,cov_vxvyvz,rawdata= readData(metal='allall',
                                            sample=options.sample,
                                            loggmin=4.2,
                                            snmin=15.,
                                            select=options.select)
    #Define potential
    if options.logp:
        pot= LogarithmicHaloPotential(normalize=1.)
    else:
        pot= MWPotential
    ts= numpy.linspace(0.,_MAXT,10000) #times to integrate
    if os.path.exists(args[0]):#Load savefile
        savefile= open(args[0],'rb')
        orbits= pickle.load(savefile)
        _ORBITSLOADED= True
        try:
            samples= pickle.load(savefile)
        except EORError:
            _SAMPLESLOADED= False
        else:
            _SAMPLESLOADED= True
        finally:
            savefile.close()
    else:
        _ORBITSLOADED= False
    if not _ORBITSLOADED:
        #First calculate orbits
        es, rmeans, rperis, raps, zmaxs = [], [], [], [], []
        densrmeans, vzrmeans= [], []
        for ii in range(len(rawdata)):
            sys.stdout.write('\r'+"Working on object %i/%i" % (ii,len(rawdata)))
            sys.stdout.flush()
            #Integrate the orbit
            data= rawdata[ii]
            o= Orbit([data.ra,data.dec,data.dist,data.pmra,data.pmdec,data.vr],
                     radec=True,vo=220.,ro=8.,zo=_ZSUN)
            o.integrate(ts,pot)
            es.append(o.e())
            rperis.append(o.rperi())
            raps.append(o.rap())
            zmaxs.append(o.zmax())
            rmeans.append(0.5*(o.rperi()+o.rap()))
            Rs= o.R(ts)
            vz2= o.vz(ts)**2.
            dens= evaluateDensities(Rs,0.*Rs,pot)
            densrmeans.append(numpy.sum(dens*Rs)/numpy.sum(dens))
            vzrmeans.append(numpy.sum(vz2*Rs)/numpy.sum(vz2))
#            print " ", rmeans[-1], densrmeans[-1], vzrmeans[-1]
        sys.stdout.write('\r'+_ERASESTR+'\r')
        sys.stdout.flush()
        es= numpy.array(es)
        rmeans= numpy.array(rmeans)
        rperis= numpy.array(rperis)
        raps= numpy.array(raps)
        zmaxs= numpy.array(zmaxs)
        orbits= _append_field_recarray(rawdata,'e',es)
        orbits= _append_field_recarray(orbits,'rmean',rmeans)
        orbits= _append_field_recarray(orbits,'rperi',rperis)
        orbits= _append_field_recarray(orbits,'rap',raps)
        orbits= _append_field_recarray(orbits,'zmax',zmaxs)
        orbits= _append_field_recarray(orbits,'densrmean',densrmeans)
        orbits= _append_field_recarray(orbits,'vzrmean',vzrmeans)
        #Pickle
        savefile= open(args[0],'wb')
        pickle.dump(orbits,savefile)
        savefile.close()
    return None
def like_func(
    params: Sequence,
    c: float,
    surfrs: list,
    kzs,
    kzerrs,
    termdata,
    termsigma,
    fitc,
    fitvoro,
    dblexp,
    addpal5,
    addgd1,
    ro: float,
    vo: float,
    addgas: bool,
):
    """Likelihood Function.

    Parameters
    ----------
    params: list
    c: float
    surfrs: list
    kzs
    kzerrs
    termdata
    termsigma
    fitc
    fitvoro
    dblexp
    addpal5
    addgd1
    ro: float
    vo: float
    addgas: bool

    Returns
    -------
    float

    """
    # --------------------------------------------------------------------

    from .potential import setup_potential  # TODO how do not internally?

    # TODO use a more generic switcher so can use any stream
    from ..streams.pal5.pal5_util import force_pal5
    from ..streams.gd1.gd1_util import force_gd1

    # --------------------------------------------------------------------
    # Check ranges

    if params[0] < 0.0 or params[0] > 1.0:
        return np.finfo(np.dtype(np.float64)).max
    elif params[1] < 0.0 or params[1] > 1.0:
        return np.finfo(np.dtype(np.float64)).max
    elif (1.0 - params[0] - params[1]) < 0.0 or (1.0 - params[0] - params[1]) > 1.0:
        return np.finfo(np.dtype(np.float64)).max
    elif params[2] < np.log(1.0 / REFR0) or params[2] > np.log(8.0 / REFR0):
        return np.finfo(np.dtype(np.float64)).max
    elif params[3] < np.log(0.05 / REFR0) or params[3] > np.log(1.0 / REFR0):
        return np.finfo(np.dtype(np.float64)).max
    elif fitvoro and (params[7] <= 150.0 / REFV0 or params[7] > 290.0 / REFV0):
        return np.finfo(np.dtype(np.float64)).max
    elif fitvoro and (params[8] <= 7.0 / REFR0 or params[8] > 9.4 / REFR0):
        return np.finfo(np.dtype(np.float64)).max
    elif fitc and (params[7 + 2 * fitvoro] <= 0.0 or params[7 + 2 * fitvoro] > 4.0):
        return np.finfo(np.dtype(np.float64)).max

    # --------------------------------------------------------------------

    if fitvoro:
        ro, vo = REFR0 * params[8], REFV0 * params[7]

    # Setup potential
    pot = setup_potential(
        params, c, fitc, dblexp, ro, vo, fitvoro=fitvoro, addgas=addgas
    )

    # Calculate model surface density at surfrs
    modelkzs = np.empty_like(surfrs)
    for ii in range(len(surfrs)):
        modelkzs[ii] = -potential.evaluatezforces(
            pot, (ro - 8.0 + surfrs[ii]) / ro, 1.1 / ro, phi=0.0
        ) * bovy_conversion.force_in_2piGmsolpc2(vo, ro)
    out = 0.5 * np.sum((kzs - modelkzs) ** 2.0 / kzerrs ** 2.0)

    # Add terminal velocities
    vrsun = params[5]
    vtsun = params[6]
    cl_glon, cl_vterm, cl_corr, mc_glon, mc_vterm, mc_corr = termdata

    # Calculate terminal velocities at data glon
    cl_vterm_model = np.zeros_like(cl_vterm)
    for ii in range(len(cl_glon)):
        cl_vterm_model[ii] = potential.vterm(pot, cl_glon[ii])
    cl_vterm_model += vrsun * np.cos(cl_glon / 180.0 * np.pi) - vtsun * np.sin(
        cl_glon / 180.0 * np.pi
    )
    mc_vterm_model = np.zeros_like(mc_vterm)
    for ii in range(len(mc_glon)):
        mc_vterm_model[ii] = potential.vterm(pot, mc_glon[ii])
    mc_vterm_model += vrsun * np.cos(mc_glon / 180.0 * np.pi) - vtsun * np.sin(
        mc_glon / 180.0 * np.pi
    )
    cl_dvterm = (cl_vterm - cl_vterm_model * vo) / termsigma
    mc_dvterm = (mc_vterm - mc_vterm_model * vo) / termsigma
    out += 0.5 * np.sum(cl_dvterm * np.dot(cl_corr, cl_dvterm))
    out += 0.5 * np.sum(mc_dvterm * np.dot(mc_corr, mc_dvterm))

    # Rotation curve constraint
    out -= logprior_dlnvcdlnr(potential.dvcircdR(pot, 1.0, phi=0.0))

    # K dwarfs, Kz
    out += (
        0.5
        * (
            -potential.evaluatezforces(pot, 1.0, 1.1 / ro, phi=0.0)
            * bovy_conversion.force_in_2piGmsolpc2(vo, ro)
            - 67.0
        )
        ** 2.0
        / 36.0
    )
    # K dwarfs, visible
    out += 0.5 * (visible_dens(pot, ro, vo) - 55.0) ** 2.0 / 25.0
    # Local density prior
    localdens = potential.evaluateDensities(
        pot, 1.0, 0.0, phi=0.0
    ) * bovy_conversion.dens_in_msolpc3(vo, ro)
    out += 0.5 * (localdens - 0.102) ** 2.0 / 0.01 ** 2.0
    # Bulge velocity dispersion
    out += 0.5 * (bulge_dispersion(pot, ro, vo) - 117.0) ** 2.0 / 225.0
    # Mass at 60 kpc
    out += 0.5 * (mass60(pot, ro, vo) - 4.0) ** 2.0 / 0.7 ** 2.0

    # Pal5
    if addpal5:
        # q = 0.94 +/- 0.05 + add'l
        fp5 = force_pal5(pot, 23.46, ro, vo)
        out += 0.5 * (np.sqrt(2.0 * fp5[0] / fp5[1]) - 0.94) ** 2.0 / 0.05 ** 2.0
        out += (
            0.5
            * (0.94 ** 2.0 * (fp5[0] + 0.8) + 2.0 * (fp5[1] + 1.82) + 0.2) ** 2.0
            / 0.6 ** 2.0
        )

    # GD-1
    if addgd1:
        # q = 0.95 +/- 0.04 + add'l
        fg1 = force_gd1(pot, ro, vo)
        out += (
            0.5 * (np.sqrt(6.675 / 12.5 * fg1[0] / fg1[1]) - 0.95) ** 2.0 / 0.04 ** 2.0
        )
        out += (
            0.5
            * (0.95 ** 2.0 * (fg1[0] + 2.51) + 6.675 / 12.5 * (fg1[1] + 1.47) + 0.05)
            ** 2.0
            / 0.3 ** 2.0
        )

    # vc and ro measurements: vc=218 +/- 10 km/s, ro= 8.1 +/- 0.1 kpc
    out += (vo - 218.0) ** 2.0 / 200.0 + (ro - 8.1) ** 2.0 / 0.02

    if np.isnan(out):
        return np.finfo(np.dtype(np.float64)).max
    else:
        return out
예제 #14
0
def plot_DFsingles(options,args):
    raw= read_rawdata(options)
    #Bin the data
    binned= pixelAfeFeh(raw,dfeh=options.dfeh,dafe=options.dafe)
    if options.tighten:
        tightbinned= pixelAfeFeh(raw,dfeh=options.dfeh,dafe=options.dafe,
                                 fehmin=-1.6,fehmax=0.5,afemin=-0.05,
                                 afemax=0.55)
    else:
        tightbinned= binned
    #Map the bins with ndata > minndata in 1D
    fehs, afes= [], []
    counter= 0
    abindx= numpy.zeros((len(binned.fehedges)-1,len(binned.afeedges)-1),
                        dtype='int')
    for ii in range(len(binned.fehedges)-1):
        for jj in range(len(binned.afeedges)-1):
            data= binned(binned.feh(ii),binned.afe(jj))
            if len(data) < options.minndata:
                continue
            #print binned.feh(ii), binned.afe(jj), len(data)
            fehs.append(binned.feh(ii))
            afes.append(binned.afe(jj))
            abindx[ii,jj]= counter
            counter+= 1
    nabundancebins= len(fehs)
    fehs= numpy.array(fehs)
    afes= numpy.array(afes)
    #Load each solutions
    sols= []
    savename= args[0]
    initname= options.init
    for ii in range(nabundancebins):
        spl= savename.split('.')
        newname= ''
        for jj in range(len(spl)-1):
            newname+= spl[jj]
            if not jj == len(spl)-2: newname+= '.'
        newname+= '_%i.' % ii
        newname+= spl[-1]
        savefilename= newname
        #Read savefile
        try:
            savefile= open(savefilename,'rb')
        except IOError:
            print "WARNING: MISSING ABUNDANCE BIN"
            sols.append(None)
        else:
            sols.append(pickle.load(savefile))
            savefile.close()
        #Load samples as well
        if options.mcsample:
            #Do the same for init
            spl= initname.split('.')
            newname= ''
            for jj in range(len(spl)-1):
                newname+= spl[jj]
                if not jj == len(spl)-2: newname+= '.'
            newname+= '_%i.' % ii
            newname+= spl[-1]
            options.init= newname
    mapfehs= monoAbundanceMW.fehs()
    mapafes= monoAbundanceMW.afes()
    #Now plot
    #Run through the pixels and gather
    if options.type.lower() == 'afe' or options.type.lower() == 'feh' \
            or options.type.lower() == 'fehafe' \
            or options.type.lower() == 'afefeh':
        plotthis= []
        errors= []
    else:
        plotthis= numpy.zeros((tightbinned.npixfeh(),tightbinned.npixafe()))
    for ii in range(tightbinned.npixfeh()):
        for jj in range(tightbinned.npixafe()):
            data= binned(tightbinned.feh(ii),tightbinned.afe(jj))
            if len(data) < options.minndata:
                if options.type.lower() == 'afe' or options.type.lower() == 'feh' or options.type.lower() == 'fehafe' \
                        or options.type.lower() == 'afefeh':
                    continue
                else:
                    plotthis[ii,jj]= numpy.nan
                    continue
            #Find abundance indx
            fehindx= binned.fehindx(tightbinned.feh(ii))#Map onto regular binning
            afeindx= binned.afeindx(tightbinned.afe(jj))
            solindx= abindx[fehindx,afeindx]
            monoabindx= numpy.argmin((tightbinned.feh(ii)-mapfehs)**2./0.01 \
                                         +(tightbinned.afe(jj)-mapafes)**2./0.0025)
            if sols[solindx] is None:
                if options.type.lower() == 'afe' or options.type.lower() == 'feh' or options.type.lower() == 'fehafe' \
                        or options.type.lower() == 'afefeh':
                    continue
                else:
                    plotthis[ii,jj]= numpy.nan
                    continue
            if options.type.lower() == 'q':
                s= get_potparams(sols[solindx],options,1)
                plotthis[ii,jj]= s[0]
                if not options.flatten is None:
                    plotthis[ii,jj]/= options.flatten
            elif options.type.lower() == 'vc':
                if options.fixvo:
                    plotthis[ii,jj]= 1.
                else:
                    s= get_potparams(sols[solindx],options,1)
                    plotthis[ii,jj]= s[1]
            elif options.type.lower() == 'rd':
                s= get_potparams(sols[solindx],options,1)
                plotthis[ii,jj]= numpy.exp(s[0])
            elif options.type.lower() == 'zh':
                s= get_potparams(sols[solindx],options,1)
                plotthis[ii,jj]= numpy.exp(s[2-(1-(options.fixvo is None))])
            elif options.type.lower() == 'ndata':
                plotthis[ii,jj]= len(data)
            elif options.type.lower() == 'hr':
                s= get_dfparams(sols[solindx],0,options)
                plotthis[ii,jj]= s[0]*_REFR0
                if options.relative:
                    thishr= monoAbundanceMW.hr(mapfehs[monoabindx],mapafes[monoabindx])
                    plotthis[ii,jj]/= thishr
            elif options.type.lower() == 'sz':
                s= get_dfparams(sols[solindx],0,options)
                plotthis[ii,jj]= s[2]*_REFV0
                if options.relative:
                    thissz= monoAbundanceMW.sigmaz(mapfehs[monoabindx],mapafes[monoabindx])
                    plotthis[ii,jj]/= thissz
            elif options.type.lower() == 'sr':
                s= get_dfparams(sols[solindx],0,options)
                plotthis[ii,jj]= s[1]*_REFV0
                if options.relative:
                    thissr= monoAbundanceMW.sigmaz(mapfehs[monoabindx],mapafes[monoabindx])*2.
                    plotthis[ii,jj]/= thissr
            elif options.type.lower() == 'srsz':
                #Setup everything
                pot= setup_potential(sols[solindx],options,1)
                vo= get_vo(sols[solindx],options,1)
                ro= get_ro(sols[solindx],options)
                aA= setup_aA(pot,options)               
                dfparams= get_dfparams(sols[solindx],0,options,log=False)
                if options.dfmodel.lower() == 'qdf':
                    #Normalize
                    hr= dfparams[0]/ro
                    sr= dfparams[1]/vo
                    sz= dfparams[2]/vo
                    hsr= dfparams[3]/ro
                    hsz= dfparams[4]/ro
                    #Setup
                    qdf= quasiisothermaldf(hr,sr,sz,hsr,hsz,pot=pot,
                                           aA=aA,cutcounter=True)              
                plotthis[ii,jj]= numpy.sqrt(qdf.sigmaR2(1.,1./_REFR0/ro,
                                                        ngl=options.ngl,gl=True)\
                                                /qdf.sigmaz2(1.,1./_REFR0/ro,
                                                            ngl=options.ngl,gl=True))
            elif options.type.lower() == 'outfrac':
                s= get_dfparams(sols[solindx],0,options)
                plotthis[ii,jj]= s[5]
            elif options.type.lower() == 'rhodm':
                #Setup potential
                pot= setup_potential(sols[solindx],options,1)
                vo= get_vo(sols[solindx],options,1)
                ro= get_ro(sols[solindx],options)
                if 'mwpotential' in options.potential.lower():
                    plotthis[ii,jj]= pot[1].dens(1.,0.)*_REFV0**2.*vo**2./_REFR0**2./ro**2./4.302*10.**-3.
                elif options.potential.lower() == 'mpdiskplhalofixbulgeflat':
                    plotthis[ii,jj]= pot[1].dens(1.,0.)*_REFV0**2.*vo**2./_REFR0**2./ro**2./4.302*10.**-3.
                elif options.potential.lower() == 'mpdiskflplhalofixplfixbulgeflat':
                    plotthis[ii,jj]= pot[1].dens(1.,0.)*_REFV0**2.*vo**2./_REFR0**2./ro**2./4.302*10.**-3.
            elif options.type.lower() == 'rhoo':
                #Setup potential
                pot= setup_potential(sols[solindx],options,1)
                vo= get_vo(sols[solindx],options,1)
                ro= get_ro(sols[solindx],options)
                plotthis[ii,jj]= potential.evaluateDensities(1.,0.,pot)*_REFV0**2.*vo**2./_REFR0**2./ro**2./4.302*10.**-3.
            elif options.type.lower() == 'surfz':
                #Setup potential
                pot= setup_potential(sols[solindx],options,1)
                vo= get_vo(sols[solindx],options,1)
                ro= get_ro(sols[solindx],options)
                plotthis[ii,jj]= 2.*integrate.quad((lambda zz: potential.evaluateDensities(1.,zz,pot)),0.,options.height/_REFR0/ro)[0]*_REFV0**2.*vo**2./_REFR0**2./ro**2./4.302*_REFR0*ro
            elif options.type.lower() == 'surfzdisk':
                #Setup potential
                pot= setup_potential(sols[solindx],options,1)
                vo= get_vo(sols[solindx],options,1)
                ro= get_ro(sols[solindx],options)
                if 'mpdisk' in options.potential.lower() or 'mwpotential' in options.potential.lower():
                    plotthis[ii,jj]= 2.*integrate.quad((lambda zz: potential.evaluateDensities(1.,zz,pot[0])),0.,options.height/_REFR0/ro)[0]*_REFV0**2.*vo**2./_REFR0**2./ro**2./4.302*_REFR0*ro
            elif options.type.lower() == 'kz':
                #Setup potential
                pot= setup_potential(sols[solindx],options,1)
                vo= get_vo(sols[solindx],options,1)
                ro= get_ro(sols[solindx],options)
                plotthis[ii,jj]= numpy.fabs(potential.evaluatezforces(1.,options.height/ro/_REFR0,pot)/2./numpy.pi/4.302*_REFV0**2.*vo**2./_REFR0/ro)
            elif options.type.lower() == 'plhalo':
                #Setup potential
                pot= setup_potential(sols[solindx],options,1)
                vo= get_vo(sols[solindx],options,1)
                ro= get_ro(sols[solindx],options)
                if options.potential.lower() == 'mpdiskplhalofixbulgeflat':
                    plotthis[ii,jj]= pot[1].alpha
            elif options.type.lower() == 'qhalo':
                #Setup potential
                s= get_potparams(sols[solindx],options,1)
                if options.potential.lower() == 'mpdiskflplhalofixplfixbulgeflat':
                    plotthis[ii,jj]= s[4]
            elif options.type.lower() == 'dlnvcdlnr':
                #Setup potential
                pot= setup_potential(sols[solindx],options,1)
                vo= get_vo(sols[solindx],options,1)
                ro= get_ro(sols[solindx],options)
                plotthis[ii,jj]= potential.dvcircdR(pot,1.)
            elif options.type.lower() == 'fd':
                #Setup potential
                pot= setup_potential(sols[solindx],options,1)
                vo= get_vo(sols[solindx],options,1)
                ro= get_ro(sols[solindx],options)
                if 'mwpotential' in options.potential.lower():
                    plotthis[ii,jj]= (pot[0].vcirc(1.))**2.
            elif options.type.lower() == 'fh':
                #Setup potential
                pot= setup_potential(sols[solindx],options,1)
                vo= get_vo(sols[solindx],options,1)
                ro= get_ro(sols[solindx],options)
                if 'mwpotential' in options.potential.lower():
                    plotthis[ii,jj]= (pot[1].vcirc(1.))**2.
            elif options.type.lower() == 'fb':
                #Setup potential
                pot= setup_potential(sols[solindx],options,1)
                vo= get_vo(sols[solindx],options,1)
                ro= get_ro(sols[solindx],options)
                if 'mwpotential' in options.potential.lower():
                    plotthis[ii,jj]= (pot[2].vcirc(1.))**2.
            elif options.type.lower() == 'afe' or options.type.lower() == 'feh' or options.type.lower() == 'fehafe' \
                    or options.type.lower() == 'afefeh':
                thisplot=[tightbinned.feh(ii),
                          tightbinned.afe(jj),
                          len(data)]
                if options.subtype.lower() == 'qvc':
                    s= get_potparams(sols[solindx],options,1)
                    thisq= s[0]
                    if not options.flatten is None:
                        thisq/= options.flatten
                    thisvc= s[1]
                    thisplot.extend([thisq,thisvc])
                elif options.subtype.lower() == 'rdzh':
                    s= get_potparams(sols[solindx],options,1)
                    thisrd= numpy.exp(s[0])
                    thiszh= numpy.exp(s[2-(1-(options.fixvo is None))])
                    thisplot.extend([thisrd,thiszh])
                elif options.subtype.lower() == 'zhvc':
                    s= get_potparams(sols[solindx],options,1)
                    thiszh= numpy.exp(s[2-(1-(options.fixvo is None))])
                    thisvc= s[1]*_REFV0
                    thisplot.extend([thiszh,thisvc])
                elif options.subtype.lower() == 'dlnvcdlnrvc':
                    s= get_potparams(sols[solindx],options,1)
                    thisslope= s[3-(1-(options.fixvo is None))]/30.
                    thisvc= s[1]*_REFV0
                    thisplot.extend([thisslope,thisvc])
                elif options.subtype.lower() == 'rdvc':
                    s= get_potparams(sols[solindx],options,1)
                    thisrd= numpy.exp(s[0])
                    thisvc= s[1]*_REFV0
                    thisplot.extend([thisrd,thisvc])
                elif options.subtype.lower() == 'rdplhalo':
                    s= get_potparams(sols[solindx],options,1)
                    thisrd= numpy.exp(s[0])
                    #Setup potential
                    pot= setup_potential(sols[solindx],options,1)
                    vo= get_vo(sols[solindx],options,1)
                    ro= get_ro(sols[solindx],options)
                    if options.potential.lower() == 'mpdiskplhalofixbulgeflat':
                        thisplhalo= pot[1].alpha
                    thisplot.extend([thisrd,thisplhalo])
                elif options.subtype.lower() == 'dlnvcdlnrplhalo':
                    s= get_potparams(sols[solindx],options,1)
                    thisslope= s[3-(1-(options.fixvo is None))]/30.
                    #Setup potential
                    pot= setup_potential(sols[solindx],options,1)
                    vo= get_vo(sols[solindx],options,1)
                    ro= get_ro(sols[solindx],options)
                    if options.potential.lower() == 'mpdiskplhalofixbulgeflat':
                        thisplhalo= pot[1].alpha
                    thisplot.extend([thisslope,thisplhalo])
                elif options.subtype.lower() == 'dlnvcdlnrzh':
                    s= get_potparams(sols[solindx],options,1)
                    thisslope= s[3-(1-(options.fixvo is None))]/30.
                    thiszh= numpy.exp(s[2-(1-(options.fixvo is None))])
                    thisplot.extend([thisslope,thiszh])
                elif options.subtype.lower() == 'vc14plhalo':
                    s= get_potparams(sols[solindx],options,1)
                    #Setup potential
                    pot= setup_potential(sols[solindx],options,1)
                    vo= get_vo(sols[solindx],options,1)
                    ro= get_ro(sols[solindx],options)
                    if options.potential.lower() == 'mpdiskplhalofixbulgeflat':
                        thisplhalo= pot[1].alpha
                    thisvc14= potential.vcirc(pot,14./_REFR0/ro)*_REFV0*vo
                    thisplot.extend([thisplhalo,thisvc14])
                elif options.subtype.lower() == 'plhalovc':
                    s= get_potparams(sols[solindx],options,1)
                    thisvc= s[1]*_REFV0
                    #Setup potential
                    pot= setup_potential(sols[solindx],options,1)
                    vo= get_vo(sols[solindx],options,1)
                    ro= get_ro(sols[solindx],options)
                    if options.potential.lower() == 'mpdiskplhalofixbulgeflat':
                        thisplhalo= pot[1].alpha
                    thisplot.extend([thisplhalo,thisvc])
                elif options.subtype.lower() == 'zhplhalo':
                    s= get_potparams(sols[solindx],options,1)
                    thiszh= numpy.exp(s[2-(1-(options.fixvo is None))])
                    #Setup potential
                    pot= setup_potential(sols[solindx],options,1)
                    vo= get_vo(sols[solindx],options,1)
                    ro= get_ro(sols[solindx],options)
                    if options.potential.lower() == 'mpdiskplhalofixbulgeflat':
                        thisplhalo= pot[1].alpha
                    thisplot.extend([thiszh,thisplhalo])
                elif options.subtype.lower() == 'rhodmzh':
                    s= get_potparams(sols[solindx],options,1)
                    thisrd= numpy.exp(s[0])
                    #Setup potential
                    pot= setup_potential(sols[solindx],options,1)
                    vo= get_vo(sols[solindx],options,1)
                    ro= get_ro(sols[solindx],options)
                    thiszh= numpy.exp(s[2-(1-(options.fixvo is None))])
                    if 'mwpotential' in options.potential.lower():
                        thisrhodm= pot[1].dens(1.,0.)*_REFV0**2.*vo**2./_REFR0**2./ro**2./4.302*10.**-3.
                    elif options.potential.lower() == 'mpdiskplhalofixbulgeflat':
                        thisrhodm= pot[1].dens(1.,0.)*_REFV0**2.*vo**2./_REFR0**2./ro**2./4.302*10.**-3.
                    thisplot.extend([thisrhodm,thiszh])
                elif options.subtype.lower() == 'rhodmsurfz':
                    s= get_potparams(sols[solindx],options,1)
                    thisrd= numpy.exp(s[0])
                    #Setup potential
                    pot= setup_potential(sols[solindx],options,1)
                    vo= get_vo(sols[solindx],options,1)
                    ro= get_ro(sols[solindx],options)
                    thissurfz= 2.*integrate.quad((lambda zz: potential.evaluateDensities(1.,zz,pot)),0.,options.height/_REFR0/ro)[0]*_REFV0**2.*vo**2./_REFR0**2./ro**2./4.302*_REFR0*ro
                    if 'mwpotential' in options.potential.lower():
                        thisrhodm= pot[1].dens(1.,0.)*_REFV0**2.*vo**2./_REFR0**2./ro**2./4.302*10.**-3.
                    elif options.potential.lower() == 'mpdiskplhalofixbulgeflat':
                        thisrhodm= pot[1].dens(1.,0.)*_REFV0**2.*vo**2./_REFR0**2./ro**2./4.302*10.**-3.
                    thisplot.extend([thisrhodm,thissurfz])
                elif options.subtype.lower() == 'surfzzh':
                    s= get_potparams(sols[solindx],options,1)
                    thisrd= numpy.exp(s[0])
                    #Setup potential
                    pot= setup_potential(sols[solindx],options,1)
                    vo= get_vo(sols[solindx],options,1)
                    ro= get_ro(sols[solindx],options)
                    thiszh= numpy.exp(s[2-(1-(options.fixvo is None))])
                    thissurfz= 2.*integrate.quad((lambda zz: potential.evaluateDensities(1.,zz,pot)),0.,options.height/_REFR0/ro)[0]*_REFV0**2.*vo**2./_REFR0**2./ro**2./4.302*_REFR0*ro
                    thisplot.extend([thissurfz,thiszh])
                elif options.subtype.lower() == 'rhoozh':
                    s= get_potparams(sols[solindx],options,1)
                    thisrd= numpy.exp(s[0])
                    #Setup potential
                    pot= setup_potential(sols[solindx],options,1)
                    vo= get_vo(sols[solindx],options,1)
                    ro= get_ro(sols[solindx],options)
                    thiszh= numpy.exp(s[2-(1-(options.fixvo is None))])
                    thisrhoo= potential.evaluateDensities(1.,0.,pot)*_REFV0**2.*vo**2./_REFR0**2./ro**2./4.302*10.**-3.
                    thisplot.extend([thisrhoo,thiszh])
                elif options.subtype.lower() == 'rhodmvc':
                    s= get_potparams(sols[solindx],options,1)
                    thisvc= s[1]*_REFV0
                    #Setup potential
                    pot= setup_potential(sols[solindx],options,1)
                    vo= get_vo(sols[solindx],options,1)
                    ro= get_ro(sols[solindx],options)
                    if 'mwpotential' in options.potential.lower():
                        thisrhodm= pot[1].dens(1.,0.)*_REFV0**2.*vo**2./_REFR0**2./ro**2./4.302*10.**-3.
                    elif options.potential.lower() == 'mpdiskplhalofixbulgeflat':
                        thisrhodm= pot[1].dens(1.,0.)*_REFV0**2.*vo**2./_REFR0**2./ro**2./4.302*10.**-3.
                    thisplot.extend([thisrhodm,thisvc])
                elif options.subtype.lower() == 'rhodmrd':
                    s= get_potparams(sols[solindx],options,1)
                    thisrd= numpy.exp(s[0])
                    #Setup potential
                    pot= setup_potential(sols[solindx],options,1)
                    vo= get_vo(sols[solindx],options,1)
                    ro= get_ro(sols[solindx],options)
                    thisrdh= numpy.exp(s[0])
                    if 'mwpotential' in options.potential.lower():
                        thisrhodm= pot[1].dens(1.,0.)*_REFV0**2.*vo**2./_REFR0**2./ro**2./4.302*10.**-3.
                    elif options.potential.lower() == 'mpdiskplhalofixbulgeflat':
                        thisrhodm= pot[1].dens(1.,0.)*_REFV0**2.*vo**2./_REFR0**2./ro**2./4.302*10.**-3.
                    thisplot.extend([thisrhodm,thisrd])
                elif options.subtype.lower() == 'rhodmplhalo':
                    s= get_potparams(sols[solindx],options,1)
                    thisrd= numpy.exp(s[0])
                    #Setup potential
                    pot= setup_potential(sols[solindx],options,1)
                    vo= get_vo(sols[solindx],options,1)
                    ro= get_ro(sols[solindx],options)
                    if options.potential.lower() == 'mpdiskplhalofixbulgeflat':
                        thisplhalo= pot[1].alpha
                    if 'mwpotential' in options.potential.lower():
                        thisrhodm= pot[1].dens(1.,0.)*_REFV0**2.*vo**2./_REFR0**2./ro**2./4.302*10.**-3.
                    elif options.potential.lower() == 'mpdiskplhalofixbulgeflat':
                        thisrhodm= pot[1].dens(1.,0.)*_REFV0**2.*vo**2./_REFR0**2./ro**2./4.302*10.**-3.
                    thisplot.extend([thisrhodm,thisplhalo])
                plotthis.append(thisplot)
    #Set up plot
    if options.type.lower() == 'q':
        if not options.flatten is None:
            vmin, vmax= 0.9, 1.1
            zlabel=r'$\mathrm{flattening}\ q / %.1f$' % options.flatten
        elif 'real' in options.outfilename.lower():
            vmin, vmax= 0.9, 1.1
            medianq= numpy.median(plotthis[numpy.isfinite(plotthis)])
            plotthis/= medianq
            zlabel=r'$\mathrm{flattening}\ q / %.2f$' % medianq
        else:
            vmin, vmax= 0.5, 1.2
            zlabel=r'$\mathrm{flattening}\ q$'
    elif options.type.lower() == 'vc':
        vmin, vmax= 0.95, 1.05
        zlabel=r'$V_c / %i\ \mathrm{km\,s}^{-1}$' % int(_REFV0)
        if 'real' in options.outfilename.lower():
           medianvc= numpy.median(plotthis[numpy.isfinite(plotthis)])
           plotthis/= medianvc
           zlabel=r'$V_c / %i\ \mathrm{km\,s}^{-1}$' % int(_REFV0*medianvc)
    elif options.type.lower() == 'rhodm':
        vmin, vmax= 0.00, 0.02
        zlabel=r'$\rho_{\mathrm{DM}}(R_0,0)\ [M_\odot\,\mathrm{pc}^{-3}]$'
    elif options.type.lower() == 'rhoo':
        vmin, vmax= 0.00, 0.2
        zlabel=r'$\rho(R_0,0)\ [M_\odot\,\mathrm{pc}^{-3}]$'
    elif options.type.lower() == 'surfz':
        vmin, vmax= 50.,120.
        zlabel=r'$\Sigma(%.1f\,\mathrm{kpc};R_0)\ [M_\odot\,\mathrm{pc}^{-2}]$' % options.height
    elif options.type.lower() == 'surfzdisk':
        vmin, vmax= 20.,90.
        zlabel=r'$\Sigma_{\mathrm{disk}}(%.1f\,\mathrm{kpc};R_0)\ [M_\odot\,\mathrm{pc}^{-2}]$' % options.height
    elif options.type.lower() == 'kz':
        vmin, vmax= 50.,120.
        zlabel=r'$K_Z(%.1f\,\mathrm{kpc};R_0)\ [M_\odot\,\mathrm{pc}^{-2}]$' % options.height
    elif options.type.lower() == 'dlnvcdlnr':
        vmin, vmax= -0.3,0.2
        zlabel=r'$\frac{\mathrm{d} \ln V_c}{\mathrm{d} \ln R}$'
    elif options.type.lower() == 'fd':
        vmin, vmax= 0.00, 1.
        zlabel=r'$V_{c,\mathrm{disk}} / V_c\,(R_0)$'
    elif options.type.lower() == 'fh':
        vmin, vmax= 0.00, 1.
        zlabel=r'$V_{c,\mathrm{halo}} / V_c\,(R_0)$'
    elif options.type.lower() == 'fb':
        vmin, vmax= 0.00, .1
        zlabel=r'$V_{c,\mathrm{halo}} / V_c\,(R_0)$'
    elif options.type.lower() == 'rd':
        vmin, vmax= 0.2, 0.6
        zlabel=r'$R_d / R_0$'
    elif options.type.lower() == 'zh':
        vmin, vmax= 0.0125, 0.075
        zlabel=r'$z_h / R_0$'
    elif options.type.lower() == 'plhalo':
        vmin, vmax= 0.0, 2.
        zlabel=r'$\alpha\ \mathrm{in}\ \rho_{\mathrm{halo}} \propto 1/r^\alpha$'
    elif options.type.lower() == 'qhalo':
        vmin, vmax= 0.4, 1.15
        zlabel=r'$q_\Phi^{\mathrm{halo}}$'
    elif options.type.lower() == 'ndata':
        vmin, vmax= numpy.nanmin(plotthis), numpy.nanmax(plotthis)
        zlabel=r'$N_\mathrm{data}$'
    elif options.type == 'hr':
        if options.relative:
            vmin, vmax= 0.8, 1.2
            zlabel=r'$\mathrm{input / output\ radial\ scale\ length}$'
        else:
            vmin, vmax= 1.35,4.5
            zlabel=r'$\mathrm{model\ radial\ scale\ length\ [kpc]}$'
    elif options.type == 'sz':
        if options.relative:
            vmin, vmax= 0.8, 1.2
            zlabel= r'$\mathrm{input / output\ model}\ \sigma_z$'
        else:
            vmin, vmax= 10.,60.
            zlabel= r'$\mathrm{model}\ \sigma_z\ [\mathrm{km\ s}^{-1}]$'
    elif options.type == 'sr':
        if options.relative:
            vmin, vmax= 0.8, 1.2
            zlabel= r'$\mathrm{input/output\ model}\ \sigma_R$'
        else:
            vmin, vmax= 10.,60.
            zlabel= r'$\mathrm{model}\ \sigma_R\ [\mathrm{km\ s}^{-1}]$'
    elif options.type == 'srsz':
        vmin, vmax= 0.5,2.
        zlabel= r'$\sigma_R/\sigma_z\ (R_0,1\,\mathrm{kpc})$'
    elif options.type == 'outfrac':
        vmin, vmax= 0., 1.
        zlabel= r'$\mathrm{relative\ number\ of\ outliers}$'
    elif options.type == 'afe':
        vmin, vmax= 0.0,.5
        zlabel=r'$[\alpha/\mathrm{Fe}]$'
    elif options.type == 'feh':
        vmin, vmax= -1.6,0.4
        zlabel=r'$[\mathrm{Fe/H}]$'
    elif options.type == 'fehafe':
        vmin, vmax= -.7,.7
        zlabel=r'$[\mathrm{Fe/H}]-[\mathrm{Fe/H}]_{1/2}([\alpha/\mathrm{Fe}])$'
    elif options.type == 'afefeh':
        vmin, vmax= -.15,.15
        zlabel=r'$[\alpha/\mathrm{Fe}]-[\alpha/\mathrm{Fe}]_{1/2}([\mathrm{Fe/H}])$'
    if options.tighten:
        xrange=[-1.6,0.5]
        yrange=[-0.05,0.55]
    else:
        xrange=[-2.,0.5]
        yrange=[-0.2,0.6]
    #Now plot
    if options.type.lower() == 'afe' or options.type.lower() == 'feh' \
            or options.type.lower() == 'fehafe':
        #Gather everything
        afe, feh, ndata, x, y= [], [], [], [], []
        for ii in range(len(plotthis)):
            afe.append(plotthis[ii][1])
            feh.append(plotthis[ii][0])
            ndata.append(plotthis[ii][2])
            x.append(plotthis[ii][3])
            y.append(plotthis[ii][4])
        afe= numpy.array(afe)
        feh= numpy.array(feh)
        ndata= numpy.array(ndata)
        x= numpy.array(x)
        y= numpy.array(y)
        #Process ndata
        ndata= ndata**.5
        ndata= ndata/numpy.median(ndata)*35.
        if options.type.lower() == 'afe':
            plotc= afe
        elif options.type.lower() == 'feh':
            plotc= feh
        elif options.type.lower() == 'afefeh':
            #Go through the bins to determine whether feh is high or low for this alpha
            plotc= numpy.zeros(len(afe))
            for ii in range(tightbinned.npixfeh()):
                fehbin= ii
                data= tightbinned.data[(tightbinned.data.feh > tightbinned.fehedges[fehbin])\
                                           *(tightbinned.data.feh <= tightbinned.fehedges[fehbin+1])]
                medianafe= numpy.median(data.afe)
                for jj in range(len(afe)):
                    if feh[jj] == tightbinned.feh(ii):
                        plotc[jj]= afe[jj]-medianafe
        else:
            #Go through the bins to determine whether feh is high or low for this alpha
            plotc= numpy.zeros(len(feh))
            for ii in range(tightbinned.npixafe()):
                afebin= ii
                data= tightbinned.data[(tightbinned.data.afe > tightbinned.afeedges[afebin])\
                                           *(tightbinned.data.afe <= tightbinned.afeedges[afebin+1])]
                medianfeh= numpy.median(data.feh)
                for jj in range(len(feh)):
                    if afe[jj] == tightbinned.afe(ii):
                        plotc[jj]= feh[jj]-medianfeh
        onedhists=False
        if options.subtype.lower() == 'qvc':
            if not options.flatten is None:
                xrange= [0.9,1.1]
                xlabel=r'$\mathrm{flattening}\ q / %.1f$' % options.flatten
            elif 'real' in options.outfilename.lower():
                xrange= [0.9,1.1]
                medianq= numpy.median(x[numpy.isfinite(x)])
                x/= medianq
                xlabel=r'$\mathrm{flattening}\ q / %.2f$' % medianq
            else:
                xrange= [0.5, 1.2]
                xlabel=r'$\mathrm{flattening}\ q$'
            yrange= [0.95, 1.05]
            ylabel=r'$V_c / %i\ \mathrm{km\,s}^{-1}$' % int(_REFV0)
            if 'real' in options.outfilename.lower():
                medianvc= numpy.median(y[numpy.isfinite(y)])
                y/= medianvc
                ylabel=r'$V_c / %i\ \mathrm{km\,s}^{-1}$' % int(_REFV0*medianvc)
        elif options.subtype.lower() == 'rdzh':
            yrange= [0.0125,0.1]
            xrange= [0.2,0.8]
            xlabel=r'$R_d / R_0$'
            ylabel=r'$z_h / R_0$'
        elif options.subtype.lower() == 'rdplhalo':
            yrange= [0.,2.]
            xrange= [0.2,0.8]
            xlabel=r'$R_d / R_0$'
            ylabel=r'$\alpha\ \mathrm{in}\ \rho_{\mathrm{halo}} \propto 1/r^\alpha$'
        elif options.subtype.lower() == 'vc14plhalo':
            yrange= [210.,280.]
            xrange= [0.,2.]
            xlabel=r'$\alpha\ \mathrm{in}\ \rho_{\mathrm{halo}} \propto 1/r^\alpha$'
            ylabel=r'$V_c (R=14\,\mathrm{kpc})\ [\mathrm{km\,s}^{-1}$]'
        elif options.subtype.lower() == 'zhplhalo':
            yrange= [0.,2.]
            xrange= [0.0125,0.1]

            ylabel=r'$\alpha\ \mathrm{in}\ \rho_{\mathrm{halo}} \propto 1/r^\alpha$'
            xlabel=r'$z_h / R_0$'
        elif options.subtype.lower() == 'rhodmplhalo':
            xrange= [0.,0.02]
            yrange= [0.,2.]
            ylabel=r'$\alpha\ \mathrm{in}\ \rho_{\mathrm{halo}} \propto 1/r^\alpha$'
            xlabel=r'$\rho_{\mathrm{DM}}(R_0,0)\ [M_\odot\,\mathrm{pc}^{-3}]$'
        elif options.subtype.lower() == 'rhodmzh':
            yrange= [0.0125,0.1]
            xrange= [0.,0.02]
            ylabel=r'$z_h / R_0$'
            xlabel=r'$\rho_{\mathrm{DM}}(R_0,0)\ [M_\odot\,\mathrm{pc}^{-3}]$'
        elif options.subtype.lower() == 'rhoozh':
            yrange= [0.0125,0.1]
            xrange= [0.,0.2]
            ylabel=r'$z_h / R_0$'
            xlabel=r'$\rho(R_0,0)\ [M_\odot\,\mathrm{pc}^{-3}]$'
        elif options.subtype.lower() == 'surfzzh':
            yrange= [0.0125,0.1]
            xrange= [50.+20.*(options.height-1.1),120.+20.*(options.height-1.1)]
            ylabel=r'$z_h / R_0$'
            xlabel=r'$\Sigma(%.1f\,\mathrm{kpc};R_0)\ [M_\odot\,\mathrm{pc}^{-2}]$' % options.height
        elif options.subtype.lower() == 'rhodmsurfz':
            yrange= [50.+20.*(options.height-1.1),120.+20.*(options.height-1.1)]
            xrange= [0.,0.02]
            ylabel=r'$\Sigma(%.1f\,\mathrm{kpc};R_0)\ [M_\odot\,\mathrm{pc}^{-2}]$' % options.height
            xlabel=r'$\rho_{\mathrm{DM}}(R_0,0)\ [M_\odot\,\mathrm{pc}^{-3}]$'
        elif options.subtype.lower() == 'rhodmrd':
            yrange= [0.2,0.8]
            xrange= [0.,0.02]
            ylabel=r'$R_d / R_0$'
            xlabel=r'$\rho_{\mathrm{DM}}(R_0,0)\ [M_\odot\,\mathrm{pc}^{-3}]$'
        elif options.subtype.lower() == 'rdvc':
            yrange= [210.,250.]
            xrange= [0.2,0.8]
            xlabel=r'$R_d / R_0$'
            ylabel=r'$V_c\ [\mathrm{km\,s}^{-1}]$'
        elif options.subtype.lower() == 'zhvc':
            yrange= [210.,250.]
            xrange= [0.0125,0.1]
            xlabel=r'$z_h / R_0$'
            ylabel=r'$V_c\ [\mathrm{km\,s}^{-1}]$'
        elif options.subtype.lower() == 'dlnvcdlnrvc':
            yrange= [210.,250.]
            xrange= [-0.2,0.07]
            xlabel=r'$\mathrm{d}\ln V_c / \mathrm{d}\ln R\, (R_0)$'
            ylabel=r'$V_c\ [\mathrm{km\,s}^{-1}]$'
            onedhists=True
        elif options.subtype.lower() == 'dlnvcdlnrplhalo':
            yrange= [0.,2.]
            ylabel=r'$\alpha\ \mathrm{in}\ \rho_{\mathrm{halo}} \propto 1/r^\alpha$'
            xrange= [-0.2,0.07]
            xlabel=r'$\mathrm{d}\ln V_c / \mathrm{d}\ln R\, (R_0)$'
        elif options.subtype.lower() == 'dlnvcdlnrzh':
            yrange= [0.0125,0.1]
            ylabel=r'$z_h / R_0$'
            xrange= [-0.2,0.07]
            xlabel=r'$\mathrm{d}\ln V_c / \mathrm{d}\ln R\, (R_0)$'
        elif options.subtype.lower() == 'rhodmvc':
            yrange= [210.,250.]
            xrange= [0.,0.02]
            ylabel=r'$V_c\ [\mathrm{km\,s}^{-1}]$'
            xlabel=r'$\rho_{\mathrm{DM}}(R_0,0)\ [M_\odot\,\mathrm{pc}^{-3}]$'
        elif options.subtype.lower() == 'plhalovc':
            yrange= [210.,250.]
            xrange= [0.,2.]
            xlabel=r'$\alpha\ \mathrm{in}\ \rho_{\mathrm{halo}} \propto 1/r^\alpha$'
            ylabel=r'$V_c\ [\mathrm{km\,s}^{-1}$]'
        bovy_plot.bovy_print(fig_height=3.87,fig_width=5.)
        ax= bovy_plot.bovy_plot(x,y,
                            s=ndata,c=plotc,
                            cmap='jet',
                            xlabel=xlabel,ylabel=ylabel,
                            clabel=zlabel,
                            xrange=xrange,yrange=yrange,
                            vmin=vmin,vmax=vmax,
                            scatter=True,edgecolors='none',
                            colorbar=True-onedhists,
                            onedhists=onedhists,
                            onedhistxnormed=onedhists,
                            onedhistynormed=onedhists,
                            bins=15)
        if onedhists:
            axS, axx, axy= ax
        if options.subtype.lower() == 'dlnvcdlnrvc':
            #Plot prior on one-d axes
            sb= numpy.linspace(-0.2,0.0399,1001)
            fsb= numpy.exp(numpy.log((0.04-sb)/0.04)-(0.04-sb)/0.04)
            fsb/= numpy.sum(fsb)*(sb[1]-sb[0])
            axx.plot(sb,fsb,'-',color='0.65')
            tvc= numpy.linspace(150.,350.,1001)
            fvc= numpy.exp(-(tvc-225.)**2./2./15.**2.)
            fvc/= numpy.sum(fvc)*(tvc[1]-tvc[0])
            axy.plot(fvc,tvc,'-',color='0.65')
    else:
        bovy_plot.bovy_print()
        bovy_plot.bovy_dens2d(plotthis.T,origin='lower',cmap='jet',
                              interpolation='nearest',
                              xlabel=r'$[\mathrm{Fe/H}]$',
                              ylabel=r'$[\alpha/\mathrm{Fe}]$',
                              zlabel=zlabel,
                              xrange=xrange,yrange=yrange,
                              vmin=vmin,vmax=vmax,
                              contours=False,
                              colorbar=True,shrink=0.78)
        if options.type.lower() == 'q' or options.type.lower() == 'vc' \
                or options.relative or options.type.lower() == 'rd' \
                or options.type.lower() == 'fd' \
                or options.type.lower() == 'fh' \
                or options.type.lower() == 'fb' \
                or options.type.lower() == 'plhalo' \
                or options.type.lower() == 'surfz' \
                or options.type.lower() == 'surfzdisk' \
                or options.type.lower() == 'rhoo' \
                or options.type.lower() == 'qhalo' \
                or options.type.lower() == 'kz':
            bovy_plot.bovy_text(r'$\mathrm{median} = %.2f \pm %.2f$' % (numpy.median(plotthis[numpy.isfinite(plotthis)]),
                                                                        1.4826*numpy.median(numpy.fabs(plotthis[numpy.isfinite(plotthis)]-numpy.median(plotthis[numpy.isfinite(plotthis)])))),
                                bottom_left=True,size=14.)
        if options.type.lower() == 'zh' or options.type.lower() == 'rhodm':
            bovy_plot.bovy_text(r'$\mathrm{median} = %.4f \pm %.4f$' % (numpy.median(plotthis[numpy.isfinite(plotthis)]),
                                                                        1.4826*numpy.median(numpy.fabs(plotthis[numpy.isfinite(plotthis)]-numpy.median(plotthis[numpy.isfinite(plotthis)])))),
                                bottom_left=True,size=14.)
    bovy_plot.bovy_end_print(options.outfilename)
    return None
예제 #15
0
def rlimiting(
    cluster,
    pot=MWPotential2014,
    rgc=None,
    r0=8.0,
    v0=220.0,
    nrad=20,
    projected=False,
    plot=False,
    verbose=False,
    **kwargs
):
    """
    NAME:

       rlimiting

    PURPOSE:

       Calculate limiting radius of the cluster
       --> The limiting radius is defined to be where the cluster's density reaches the local background density of the host galaxy

    INPUT:

       cluster - StarCluster instance

       pot - GALPY potential used to calculate actions

       rgc - Set galactocentric distance at which the tidal radius is to be evaluated

       r0,v0 - GALPY scaling parameters

       nrad - number of radial bins used to calculate density profile (Default: 20)

       projected - use projected values (Default: False)

       plot - plot the density profile and mark the limiting radius of the cluster (Default: False)

    KWARGS:

       Same as ..util.plots.nplot

    OUTPUT:

        rl

    HISTORY:

       2019 - Written - Webb (UofT)

    """
    units0, origin0 = save_cluster(cluster)

    cluster.to_centre()
    cluster.to_galpy()


    if rgc != None:
        R = rgc / r0
        z = 0.0
    else:
        R = np.sqrt(cluster.xgc ** 2.0 + cluster.ygc ** 2.0)
        z = cluster.zgc

    # Calculate local density:
    rho_local = potential.evaluateDensities(
        pot, R, z, ro=r0, vo=v0, use_physical=False
    ) / bovy_conversion.dens_in_msolpc3(ro=r0, vo=v0)

    rprof, pprof, nprof = rho_prof(cluster, nrad=nrad, projected=projected)

    if pprof[-1] > rho_local:
        rl = rprof[-1]
    elif pprof[0] < rho_local:
        rl = 0.0
    else:
        indx = np.argwhere(pprof < rho_local)[0][0]
        r1 = (rprof[indx - 1], pprof[indx - 1])
        r2 = (rprof[indx], pprof[indx])

        rl = interpolate(r1, r2, y=rho_local)

    if verbose:
        print("FINAL RL: ", rl * r0 * 1000.0, "pc")

    if units0 == "realpc":
        rl *= 1000.0 * r0
    elif units0 == "realkpc":
        rl *= r0
    elif units0 == "nbody":
        rl *= 1000.0 * r0 / cluster.rbar

    cluster.rl = rl

    return_cluster(cluster, units0, origin0, do_order=True, do_key_params=True)

    if plot:
        if verbose:
            print("LOCAL DENSITY = ", rho_local)

        filename = kwargs.pop("filename", None)
        overplot = kwargs.pop("overplot", False)

        if cluster.units == "nbody":
            rprof *= r0 * 1000.0 / cluster.rbar
            pprof *= (
                bovy_conversion.dens_in_msolpc3(ro=r0, vo=v0)
                * (cluster.rbar ** 3.0)
                / cluster.zmbar
            )
            rho_local *= (
                bovy_conversion.dens_in_msolpc3(ro=r0, vo=v0)
                * (cluster.rbar ** 3.0)
                / cluster.zmbar
            )
            xunits = " (NBODY)"
            yunits = " (NBODY)"
        elif cluster.units == "realpc":
            rprof *= r0 * 1000.0
            pprof *= bovy_conversion.dens_in_msolpc3(ro=r0, vo=v0)
            rho_local *= bovy_conversion.dens_in_msolpc3(ro=r0, vo=v0)
            xunits = " (pc)"
            if projected:
                yunits = " Msun/pc^2"
            else:
                yunits = " Msun/pc^3"
        elif cluster.units == "realkpc":
            rprof *= r0
            pprof *= bovy_conversion.dens_in_msolpc3(ro=r0, vo=v0) * (1000.0 ** 3.0)
            rho_local *= bovy_conversion.dens_in_msolpc3(ro=r0, vo=v0) * (1000.0 ** 3.0)

            xunits = " (kpc)"
            if projected:
                yunits = " Msun/kpc^2"
            else:
                yunits = " Msun/kpc^3"
        elif cluster.units == "galpy":
            xunits = " (GALPY)"
            yunits = " (GALPY)"

        else:
            xunits = ""
            yunits = ""

        x, y, n = rprof, pprof, nprof
        nlplot(
            x,
            y,
            xlabel=r"$R %s$" % (xunits),
            ylabel=r"$\rho %s$" % (yunits),
            title="Time = %f" % cluster.tphys,
            log=True,
            overplot=overplot,
            filename=filename,
        )
        nlplot(x, np.ones(len(x)) * rho_local, "--", overplot=True)
        nlplot(np.ones(len(y)) * rl, y, "--", overplot=True)

        if filename != None:
            plt.savefig(filename)

    return rl
예제 #16
0
def plotSurfRdfh(plotfilename):
    #Calculate the surface density profile for each trial potential, then plot in 2D
    if '.png' in plotfilename:
        savefilename= plotfilename.replace('.png','.sav')
    elif '.ps' in plotfilename:
        savefilename= plotfilename.replace('.ps','.sav')
    if not os.path.exists(savefilename):
        options= setup_options(None)
        options.potential= 'dpdiskplhalofixbulgeflatwgasalt'
        options.fitdvt= False
        rs= numpy.array([5.,8.,11.])
        rds= numpy.linspace(2.,3.4,_NRDS)
        fhs= numpy.linspace(0.,1.,_NFHS)
        surfz= numpy.zeros((len(rs),len(rds),len(fhs)))+numpy.nan
        ro= 1.
        vo= _VC/ _REFV0
        dlnvcdlnr= _DLNVCDLNR
        zh= _ZH
        for jj in range(len(rds)):
            for kk in range(len(fhs)):
                #Setup potential to calculate stuff
                potparams= numpy.array([numpy.log(rds[jj]/8.),vo,numpy.log(zh/8000.),fhs[kk],dlnvcdlnr])
                try:
                    pot= setup_potential(potparams,options,0,returnrawpot=True)
                except RuntimeError:
                    continue
                for ii in range(len(rs)):
                    if False:
                        surfz[ii,jj,kk]= -potential.evaluatezforces(rs[ii]/_REFR0,options.height/_REFR0/ro,pot)*_REFV0**2.*vo**2./_REFR0**2./ro**2./4.302*_REFR0*ro/2./numpy.pi
                    else:
                        surfz[ii,jj,kk]= 2.*integrate.quad((lambda zz: potential.evaluateDensities(rs[ii]/8.,zz,pot)),0.,options.height/_REFR0/ro)[0]*_REFV0**2.*vo**2./_REFR0**2./ro**2./4.302*_REFR0*ro
        #Save
        save_pickles(savefilename,rs,rds,fhs,surfz)
    else:
        savefile= open(savefilename,'rb')
        rs= pickle.load(savefile)
        rds= pickle.load(savefile)
        fhs= pickle.load(savefile)
        surfz= pickle.load(savefile)
        savefile.close()
    #Now plot
    bovy_plot.bovy_print()
    data = numpy.ma.masked_invalid(surfz[1,:,:])
    bovy_plot.bovy_dens2d(data.filled(data.mean()).T,
                          origin='lower',
                          cmap='jet',
                          colorbar=True,
                          shrink=0.775,
                          xlabel=r'$\mathrm{disk\ scale\ length}\,(\mathrm{kpc})$',
                          ylabel=r'$\mathrm{relative\ halo\ contribution\ to}\ V^2_c(R_0)$',
                          zlabel=r'$\Sigma(R_0,|Z| \leq 1.1\,\mathrm{kpc})\, (M_\odot\,\mathrm{pc}^{-2})$',
                          xrange=[rds[0]-(rds[1]-rds[0])/2.,
                                  rds[-1]+(rds[1]-rds[0])/2.],
                          yrange=[fhs[0]-(fhs[1]-fhs[0])/2.,
                                  fhs[-1]+(fhs[1]-fhs[0])/2.])
    #Fix bad data
    bad_data = numpy.ma.masked_where(~data.mask, data.mask)
    bovy_plot.bovy_dens2d(bad_data.T,
                          origin='lower',
                          interpolation='nearest',
                          cmap=cm.gray_r,
                          overplot=True,
                          
                          xrange=[rds[0]-(rds[1]-rds[0])/2.,
                                  rds[-1]+(rds[1]-rds[0])/2.],
                          yrange=[fhs[0]-(fhs[1]-fhs[0])/2.,
                                  fhs[-1]+(fhs[1]-fhs[0])/2.])
    #Overlay contours of sigma at other R
    bovy_plot.bovy_dens2d(surfz[0,:,:].T,origin='lower',
                          xrange=[rds[0]-(rds[1]-rds[0])/2.,
                                  rds[-1]+(rds[1]-rds[0])/2.],
                          yrange=[fhs[0]-(fhs[1]-fhs[0])/2.,
                                  fhs[-1]+(fhs[1]-fhs[0])/2.],
                          overplot=True,
                          justcontours=True,
                          contours=True,
                          cntrcolors='k',
                          cntrls='-')
    bovy_plot.bovy_dens2d(surfz[2,:,:].T,origin='lower',
                          xrange=[rds[0]-(rds[1]-rds[0])/2.,
                                  rds[-1]+(rds[1]-rds[0])/2.],
                          yrange=[fhs[0]-(fhs[1]-fhs[0])/2.,
                                  fhs[-1]+(fhs[1]-fhs[0])/2.],
                          overplot=True,
                          justcontours=True,
                          contours=True,
                          cntrcolors='w',
#                          cntrlabel=True,
                          cntrls='--')
    #Add labels
    bovy_plot.bovy_text(r'$\Sigma(R=5\,\mathrm{kpc})$'
                        +'\n'
                        +r'$\Sigma(R=11\,\mathrm{kpc})$',
                        bottom_left=True,size=14.)
    bovy_plot.bovy_plot([2.575,2.8],[0.15,0.31],'-',color='0.5',overplot=True)
    bovy_plot.bovy_plot([2.625,2.95],[0.06,0.1525],'-',color='0.5',overplot=True)
    #overplot actual gridpoints
    gridrds= numpy.linspace(2.,3.4,8)
    gridfhs= numpy.linspace(0.,1.,16)
    for ii in range(len(gridrds)):
        bovy_plot.bovy_plot(gridrds[ii]+numpy.zeros(len(gridfhs)),
                            gridfhs,
                            's',
                            color='w',ms=3.,overplot=True,
                            markeredgecolor='none')
    bovy_plot.bovy_end_print(plotfilename)
    return None
def like_func(params,c,surfrs,kzs,kzerrs,termdata,termsigma,fitc,fitvoro,
              dblexp,addpal5,addgd1,ro,vo,addgas):
    #Check ranges
    if params[0] < 0. or params[0] > 1.: return numpy.finfo(numpy.dtype(numpy.float64)).max
    if params[1] < 0. or params[1] > 1.: return numpy.finfo(numpy.dtype(numpy.float64)).max
    if (1.-params[0]-params[1]) < 0. or (1.-params[0]-params[1]) > 1.: return numpy.finfo(numpy.dtype(numpy.float64)).max
    if params[2] < numpy.log(1./_REFR0) or params[2] > numpy.log(8./_REFR0):
        return numpy.finfo(numpy.dtype(numpy.float64)).max
    if params[3] < numpy.log(0.05/_REFR0) or params[3] > numpy.log(1./_REFR0):
        return numpy.finfo(numpy.dtype(numpy.float64)).max
    if fitvoro and (params[7] <= 150./_REFV0 or params[7] > 290./_REFV0):
        return numpy.finfo(numpy.dtype(numpy.float64)).max
    if fitvoro and (params[8] <= 7./_REFR0 or params[8] > 9.4/_REFR0):
        return numpy.finfo(numpy.dtype(numpy.float64)).max
    if fitc and (params[7+2*fitvoro] <= 0. or params[7+2*fitvoro] > 4.):
        return numpy.finfo(numpy.dtype(numpy.float64)).max
    if fitvoro:
        ro, vo= _REFR0*params[8], _REFV0*params[7]
    #Setup potential
    pot= setup_potential(params,c,fitc,dblexp,ro,vo,fitvoro=fitvoro,
                         addgas=addgas)
    #Calculate model surface density at surfrs
    modelkzs= numpy.empty_like(surfrs)
    for ii in range(len(surfrs)):
        modelkzs[ii]= -potential.evaluatezforces(pot,
                                                 (ro-8.+surfrs[ii])/ro,
                                                 1.1/ro,
                                                 phi=0.)*bovy_conversion.force_in_2piGmsolpc2(vo,ro)
    out= 0.5*numpy.sum((kzs-modelkzs)**2./kzerrs**2.)
    #Add terminal velocities
    vrsun= params[5]
    vtsun= params[6]
    cl_glon, cl_vterm, cl_corr, mc_glon, mc_vterm, mc_corr= termdata
    #Calculate terminal velocities at data glon
    cl_vterm_model= numpy.zeros_like(cl_vterm)
    for ii in range(len(cl_glon)):
        cl_vterm_model[ii]= potential.vterm(pot,cl_glon[ii])
    cl_vterm_model+= vrsun*numpy.cos(cl_glon/180.*numpy.pi)\
        -vtsun*numpy.sin(cl_glon/180.*numpy.pi)
    mc_vterm_model= numpy.zeros_like(mc_vterm)
    for ii in range(len(mc_glon)):
        mc_vterm_model[ii]= potential.vterm(pot,mc_glon[ii])
    mc_vterm_model+= vrsun*numpy.cos(mc_glon/180.*numpy.pi)\
        -vtsun*numpy.sin(mc_glon/180.*numpy.pi)
    cl_dvterm= (cl_vterm-cl_vterm_model*vo)/termsigma
    mc_dvterm= (mc_vterm-mc_vterm_model*vo)/termsigma
    out+= 0.5*numpy.sum(cl_dvterm*numpy.dot(cl_corr,cl_dvterm))
    out+= 0.5*numpy.sum(mc_dvterm*numpy.dot(mc_corr,mc_dvterm))
    #Rotation curve constraint
    out-= logprior_dlnvcdlnr(potential.dvcircdR(pot,1.,phi=0.))
    #K dwarfs, Kz
    out+= 0.5*(-potential.evaluatezforces(pot,1.,1.1/ro,phi=0.)*bovy_conversion.force_in_2piGmsolpc2(vo,ro)-67.)**2./36.
    #K dwarfs, visible
    out+= 0.5*(visible_dens(pot,ro,vo)-55.)**2./25.
    #Local density prior
    localdens= potential.evaluateDensities(pot,1.,0.,phi=0.)*bovy_conversion.dens_in_msolpc3(vo,ro)
    out+= 0.5*(localdens-0.102)**2./0.01**2.
    #Bulge velocity dispersion
    out+= 0.5*(bulge_dispersion(pot,ro,vo)-117.)**2./225.
    #Mass at 60 kpc
    out+= 0.5*(mass60(pot,ro,vo)-4.)**2./0.7**2.
    #Pal5
    if addpal5:
        # q = 0.94 +/- 0.05 + add'l
        fp5= force_pal5(pot,23.46,ro,vo)
        out+= 0.5*(numpy.sqrt(2.*fp5[0]/fp5[1])-0.94)**2./0.05**2.
        out+= 0.5*(0.94**2.*(fp5[0]+0.8)+2.*(fp5[1]+1.82)+0.2)**2./0.6**2.
    #GD-1
    if addgd1:
        # q = 0.95 +/- 0.04 + add'l
        fg1= force_gd1(pot,ro,vo)
        out+= 0.5*(numpy.sqrt(6.675/12.5*fg1[0]/fg1[1])-0.95)**2./0.04**2.
        out+= 0.5*(0.95**2.*(fg1[0]+2.51)+6.675/12.5*(fg1[1]+1.47)+0.05)**2./0.3**2.
    # vc and ro measurements: vc=218 +/- 10 km/s, ro= 8.1 +/- 0.1 kpc
    out+= (vo-218.)**2./200.+(ro-8.1)**2./0.02
    if numpy.isnan(out): 
        return numpy.finfo(numpy.dtype(numpy.float64)).max
    else:
        return out
def visible_dens(pot,_REFR0,_REFV0,r=1.):
    """The visible surface density at 8 kpc from the center"""
    if len(pot) == 4:
        return 2.*(integrate.quad((lambda zz: potential.evaluateDensities(pot[1],r,zz,phi=0.)),0.,2.)[0]+integrate.quad((lambda zz: potential.evaluateDensities(pot[3],r,zz,phi=0.)),0.,2.)[0])*bovy_conversion.surfdens_in_msolpc2(_REFV0,_REFR0)
    else:
        return 2.*integrate.quad((lambda zz: potential.evaluateDensities(pot[1],r,zz,phi=0.)),0.,2.)[0]*bovy_conversion.surfdens_in_msolpc2(_REFV0,_REFR0)
def writeTable(pot,params,tablename,options,fzrd):
    outfile= open(tablename,'w')
    delimiter= ' & '
    #First list the explicit parameters
    printline= '$R_0\,(\kpc)$%s$8$%sfixed\\\\\n' % (delimiter,delimiter)
    outfile.write(printline)
    printline= '$v_c(R_0)\,(\kms)$%s$220$%sfixed\\\\\n' % (delimiter,delimiter)
    outfile.write(printline)
    if options.twodisks:
        printline= '$f_{b}$%s$%.2f$%s\ldots\\\\\n' % (delimiter,1.-params[0]-params[1]-params[2],delimiter)        
        outfile.write(printline)
        printline= '$f_{d,1}$%s$%.2f$%s\ldots\\\\\n' % (delimiter,params[0],delimiter)
        outfile.write(printline)
        printline= '$f_{d,2}$%s$%.2f$%s\ldots\\\\\n' % (delimiter,params[1],delimiter)        
        outfile.write(printline)
        printline= '$f_{h}$%s$%.2f$%s\ldots\\\\\n' % (delimiter,params[2],delimiter)        
        outfile.write(printline)
    else:
        printline= '$f_{b}$%s$%.2f$%s\ldots\\\\\n' % (delimiter,1.-params[0]-params[1],delimiter)        
        outfile.write(printline)
        printline= '$f_{d}$%s%.2f%s\ldots\\\\\n' % (delimiter,params[0],delimiter)
        outfile.write(printline)
        printline= '$f_{h}$%s$%.2f$%s\ldots\\\\\n' % (delimiter,params[1],delimiter)        
        outfile.write(printline)
    #Bulge power-law and rc
    printline= '$\mathrm{Bulge\ power}$%s$-1.8$%sfixed\\\\\n' % (delimiter,delimiter)        
    outfile.write(printline)
    printline= '$\mathrm{Bulge\ cut}\,(\kpc)$%s$1.9$%sfixed\\\\\n' % (delimiter,delimiter)        
    outfile.write(printline)
    #Disk scale length and height
    printline= '$a\,(\kpc)$%s$%.1f$%s\ldots\\\\\n' % (delimiter,numpy.exp(params[2+options.twodisks])*_REFR0,delimiter)        
    outfile.write(printline)
    printline= '$b\,(\pc)$%s$%.0f$%s\ldots\\\\\n' % (delimiter,1000.*numpy.exp(params[3+options.twodisks])*_REFR0,delimiter)        
    outfile.write(printline)
    printline= '$\mathrm{Halo}\ r_s\,(\kpc)$%s$%.0f$%s\ldots\\\\\n' % (delimiter,numpy.exp(params[4+options.twodisks])*_REFR0,delimiter)        
    outfile.write(printline)
    outfile.write('%s%s\\\\\n' % (delimiter,delimiter))
    #Now the constraints
    printline= '$\sigma_b\,(\kms)$%s$%.0f$%s$117\pm15$\\\\\n' % (delimiter,bulge_dispersion(pot),delimiter)
    outfile.write(printline)
    printline= '$F_Z(R_0,1.1\kpc)\,(2\pi G\,M_\odot\pc^{-2})$%s$%.0f$%s$67\pm6$\\\\\n' % (delimiter,-potential.evaluatezforces(1.,1.1/_REFR0,pot)*bovy_conversion.force_in_2piGmsolpc2(_REFV0,_REFR0),delimiter)
    outfile.write(printline)
    printline= '$\Sigma_{\mathrm{vis}}(R_0)\,(M_\odot\pc^{-2})$%s$%.0f$%s$55\pm5$\\\\\n' % (delimiter,visible_dens(pot,options),delimiter)
    outfile.write(printline)
    printline= '$F_Z\ \mathrm{scale\ length}\,(\kpc)$%s%.1f%s$2.7\pm0.1$\\\\\n' % (delimiter,fzrd*_REFR0,delimiter)
    outfile.write(printline)
    printline= '$\\rho(R_0,z=0)\,(M_\odot\pc^{-3})$%s$%.2f$%s$0.10\pm0.01$\\\\\n' % (delimiter,potential.evaluateDensities(1.,0.,pot)*bovy_conversion.dens_in_msolpc3(_REFV0,_REFR0),delimiter)
    outfile.write(printline)
    printline= '$(\dd \ln v_c/\dd \ln R)|_{R_0}$%s$%.2f$%s$-0.2\ \mathrm{to}\ 0$\\\\\n' % (delimiter,potential.dvcircdR(pot,1.),delimiter)
    outfile.write(printline)
    printline= '$M(r<60\kpc)\,(10^{11}\,M_\odot)$%s$%.1f$%s$4.0\pm0.7$\\\\\n' % (delimiter,mass60(pot,options),delimiter)
    outfile.write(printline)
    outfile.write('%s%s\\\\\n' % (delimiter,delimiter))
    #Now some derived properties
    printline= '$M_b\,(10^{10}\,M_\odot)$%s$%.1f$%s\ldots\\\\\n' % (delimiter,pot[0].mass(10.)*bovy_conversion.mass_in_1010msol(_REFV0,_REFR0),delimiter)
    outfile.write(printline)
    if options.twodisks:
        printline= '$M_d\,(10^{10}\,M_\odot)$%s$%.1f$%s\ldots\\\\\n' % (delimiter,(pot[1]._amp+pot[2]._amp)*bovy_conversion.mass_in_1010msol(_REFV0,_REFR0),delimiter)
    else:
        printline= '$M_d\,(10^{10}\,M_\odot)$%s$%.1f$%s\ldots\\\\\n' % (delimiter,pot[1]._amp*bovy_conversion.mass_in_1010msol(_REFV0,_REFR0),delimiter)
    outfile.write(printline)
    krs= numpy.linspace(4./_REFR0,9./_REFR0,101)
    disksurf= numpy.array([visible_dens(pot,options,r=kr) for kr in krs])
    p= numpy.polyfit(krs,numpy.log(disksurf),1)
    rd= -1./p[0]*_REFR0
    printline= '$R_{d}\,(\kpc)$%s$%.1f$%s\ldots\\\\\n' % (delimiter,rd,delimiter)
    outfile.write(printline)
    rvir= pot[2+options.twodisks].rvir(_REFV0,_REFR0,wrtcrit=True,overdens=96.7)
    printline= '$\\rho_{\mathrm{DM}}(R_0)\,(M_\odot\pc^{-3})$%s$%.3f$%s\\\\\n' % (delimiter,potential.evaluateDensities(1.,0.,pot[2+options.twodisks])*bovy_conversion.dens_in_msolpc3(_REFV0,_REFR0),delimiter)
    outfile.write(printline)
    printline= '$M_{\mathrm{vir}}\,(10^{12}\,M_\odot)$%s$%.1f$%s\ldots\\\\\n' % (delimiter,pot[2+options.twodisks].mass(rvir)*bovy_conversion.mass_in_1010msol(_REFV0,_REFR0)/100.,delimiter)
    outfile.write(printline)
    printline= '$r_{\mathrm{vir}}\,(\kpc)$%s$%.0f$%s\ldots\\\\\n' % (delimiter,rvir*_REFR0,delimiter)
    outfile.write(printline)
    printline= '$\mathrm{Concentration}$%s$%.1f$%s\ldots\\\\\n' % (delimiter,rvir/pot[2+options.twodisks].a,delimiter)
    outfile.write(printline)
    printline= '$v_{\mathrm{esc}}(R_0)\,(\kms)$%s$%.0f$%s\ldots\n' % (delimiter,potential.vesc(pot,1.)*_REFV0,delimiter)
    outfile.write(printline)
    #printline= '$r_{\mathrm{vir}}\,(\kpc)$%s$%.0f$%s\ldots\\\\\n' % (delimiter,delimiter)
    #outfile.write(printline)
    
    outfile.write('\\enddata\n')
    pass
예제 #20
0
def test_density():
    #test the density calculation of the KuzminKutuzovStaeckelPotential
    #using parameters from Batsleer & Dejonghe 1994, tab. 2

    #_____parameters_____
    #table 2 in Batsleer & Dejonghe
    ac_D = [
        25., 25., 25., 25., 25., 25., 40., 40., 40., 40., 40., 50., 50., 50.,
        50., 50., 50., 75., 75., 75., 75., 75., 75., 100., 100., 100., 100.,
        100., 100., 150., 150., 150., 150., 150., 150.
    ]
    ac_H = [
        1.005, 1.005, 1.01, 1.01, 1.02, 1.02, 1.005, 1.005, 1.01, 1.01, 1.02,
        1.005, 1.005, 1.01, 1.01, 1.02, 1.02, 1.005, 1.005, 1.01, 1.01, 1.02,
        1.02, 1.005, 1.005, 1.01, 1.01, 1.02, 1.02, 1.005, 1.005, 1.01, 1.01,
        1.02, 1.02
    ]
    k = [
        0.05, 0.08, 0.075, 0.11, 0.105, 0.11, 0.05, 0.08, 0.075, 0.11, 0.11,
        0.05, 0.07, 0.07, 0.125, 0.1, 0.125, 0.05, 0.065, 0.07, 0.125, 0.10,
        0.125, 0.05, 0.065, 0.07, 0.125, 0.10, 0.125, 0.05, 0.065, 0.075,
        0.125, 0.11, 0.125
    ]
    Delta = [
        0.99, 1.01, 0.96, 0.99, 0.86, 0.88, 1.00, 1.01, 0.96, 0.99, 0.89, 1.05,
        1.06, 1.00, 1.05, 0.91, 0.97, 0.98, 0.99, 0.94, 0.98, 0.85, 0.91, 1.06,
        1.07, 1.01, 1.06, 0.94, 0.97, 1.06, 1.07, 0.98, 1.06, 0.94, 0.97
    ]
    Mmin = [
        7.49, 6.17, 4.08, 3.70, 2.34, 2.36, 7.57, 6.16, 4.08, 2.64, 2.38, 8.05,
        6.94, 4.37, 3.70, 2.48, 2.50, 7.37, 6.66, 4.05, 3.46, 2.33, 2.36, 8.14,
        7.27, 4.42, 3.72, 2.56, 2.50, 8.14, 7.26, 4.17, 3.72, 2.51, 2.50
    ]
    Mmax = [
        7.18, 6.12, 3.99, 3.69, 2.37, 2.40, 7.27, 6.11, 3.99, 2.66, 2.42, 7.76,
        6.85, 4.26, 3.72, 2.51, 2.54, 7.07, 6.51, 3.95, 3.48, 2.36, 2.40, 7.85,
        7.15, 4.30, 3.75, 2.58, 2.54, 7.85, 7.07, 4.08, 3.75, 2.53, 2.53
    ]
    rhomin = [
        0.04, 0.05, 0.04, 0.04, 0.03, 0.03, 0.06, 0.06, 0.05, 0.04, 0.04, 0.07,
        0.08, 0.06, 0.07, 0.04, 0.05, 0.08, 0.09, 0.07, 0.09, 0.05, 0.06, 0.12,
        0.13, 0.09, 0.13, 0.07, 0.09, 0.16, 0.19, 0.12, 0.18, 0.10, 0.12
    ]
    rhomax = [
        0.03, 0.03, 0.02, 0.03, 0.02, 0.02, 0.04, 0.04, 0.03, 0.03, 0.02, 0.05,
        0.05, 0.04, 0.05, 0.03, 0.03, 0.05, 0.06, 0.04, 0.06, 0.03, 0.04, 0.07,
        0.08, 0.06, 0.08, 0.04, 0.05, 0.09, 0.10, 0.07, 0.10, 0.06, 0.07
    ]
    Sigmin = [
        58, 52, 52, 49, 39, 40, 58, 55, 51, 44, 40, 59, 54, 53, 49, 41, 42, 58,
        55, 51, 48, 39, 40, 59, 55, 53, 49, 42, 42, 59, 55, 52, 49, 42, 42
    ]
    Sigmax = [
        45, 41, 38, 37, 28, 28, 45, 32, 37, 32, 30, 46, 43, 40, 37, 30, 31, 45,
        43, 38, 36, 28, 29, 46, 43, 40, 38, 31, 31, 46, 44, 39, 38, 30, 31
    ]

    for ii in range(len(ac_D)):

        if ac_D[ii] == 40.:
            continue
            #because I believe that there are typos in tab. 2 by Batsleer & Dejonghe...

        for jj in range(2):

            #_____parameters depending on solar position____
            if jj == 0:
                Rsun = 7.5
                zsun = 0.004
                GM = Mmin[ii]  #units: G = 1, M in 10^11 solar masses
                rho = rhomin[ii]
                Sig = Sigmin[ii]
            elif jj == 1:
                Rsun = 8.5
                zsun = 0.02
                GM = Mmax[ii]  #units: G = 1, M in 10^11 solar masses
                rho = rhomax[ii]
                Sig = Sigmax[ii]
            outstr = 'ac_D='+str(ac_D[ii])+', ac_H='+str(ac_H[ii])+', k='+str(k[ii])+', Delta='+str(Delta[ii])+\
                     ', Mtot='+str(GM)+'*10^11Msun, Rsun='+str(Rsun)+'kpc, rho(Rsun,zsun)='+str(rho)+'Msun/pc^3, Sig(Rsun,z<1.1kpc)='+str(Sig)+'Msun/pc^2'

            #_____setup potential_____
            amp_D = GM * k[ii]
            V_D = KuzminKutuzovStaeckelPotential(amp=amp_D,
                                                 ac=ac_D[ii],
                                                 Delta=Delta[ii],
                                                 normalize=False)
            amp_H = GM * (1. - k[ii])
            V_H = KuzminKutuzovStaeckelPotential(amp=amp_H,
                                                 ac=ac_H[ii],
                                                 Delta=Delta[ii],
                                                 normalize=False)
            pot = [V_D, V_H]

            #_____local density_____
            rho_calc = evaluateDensities(
                pot, Rsun, zsun) * 100.  #units: [solar mass / pc^3]
            rho_calc = round(rho_calc, 2)

            #an error of 0.01 corresponds to the significant digit
            #given in the table, to which the density was rounded,
            #to be wrong by one.
            assert numpy.fabs(rho_calc - rho) <= 0.01+10.**-8, \
                'Calculated density %f for KuzminKutuzovStaeckelPotential ' % rho_calc + \
                'with model parameters:\n'+outstr+'\n'+ \
                'does not agree with value from tab. 2 '+ \
                'by Batsleer & Dejonghe (1994)'

            #_____surface density_____
            Sig_calc, err = scipy.integrate.quad(
                lambda z: (evaluateDensities(pot, Rsun, z / 1000.) * 100.
                           ),  #units: [solar mass / pc^3]
                0.,
                1100.)  #units: pc
            Sig_calc = round(2. * Sig_calc)

            #an error of 1 corresponds to the significant digit
            #given in the table, to which the surface density was rounded,
            #to be wrong by one.
            assert numpy.fabs(Sig_calc - Sig) <= 1., \
                'Calculated surface density %f for KuzminKutuzovStaeckelPotential ' % Sig_calc + \
                'with model parameters:\n'+outstr+'\n'+ \
                'does not agree with value from tab. 2 '+ \
                'by Batsleer & Dejonghe (1994)'

    return None
def visible_dens(pot,options,r=1.):
    """The visible surface density at 8 kpc from the center"""
    if options.twodisks:
        return 2.*integrate.quad((lambda zz: potential.evaluateDensities(r,zz,pot[1:3])),0.,2.)[0]*bovy_conversion.surfdens_in_msolpc2(_REFV0,_REFR0)
    else:
        return 2.*integrate.quad((lambda zz: potential.evaluateDensities(r,zz,pot[1])),0.,2.)[0]*bovy_conversion.surfdens_in_msolpc2(_REFV0,_REFR0)
예제 #22
0
def rlimiting(cluster,
              pot=MWPotential2014,
              rgc=None,
              ro=8.0,
              vo=220.0,
              nrad=20,
              projected=False,
              plot=False,
              **kwargs):
    """Calculate limiting radius of the cluster
       
    - The limiting radius is defined to be where the cluster's density reaches the local background density of the host galaxy
    - for cases where the cluster's orbital parameters are not set, it is possible to manually set rgc which is assumed to be in kpc.

    Parameters
    ----------

    cluster : class
        StarCluster
    pot : class 
        GALPY potential used to calculate actions
    rgc : 
        Manually set galactocentric distance in kpc at which the tidal radius is to be evaluated (default: None)
    ro : float
        GALPY radius scaling parameter
    vo : float
        GALPY velocity scaling parameter
    nrad : int
        number of radial bins used to calculate density profile (Default: 20)
    projected : bool
        use projected values (default: False)
    plot : bool
        plot the density profile and mark the limiting radius of the cluster (default: False)

    Returns
    -------
        rl : float
            limiting radius

    Other Parameters
    ----------------
    kwargs : str
        key words for plotting

    History
    -------
    2019 - Written - Webb (UofT)
    """
    units0, origin0 = save_cluster(cluster)

    cluster.to_centre()
    cluster.to_galpy()

    if rgc != None:
        R = rgc / ro
        z = 0.0
    else:
        R = np.sqrt(cluster.xgc**2.0 + cluster.ygc**2.0)
        z = cluster.zgc

    # Calculate local density:
    rho_local = potential.evaluateDensities(
        pot, R, z, ro=ro, vo=vo,
        use_physical=False) / bovy_conversion.dens_in_msolpc3(ro=ro, vo=vo)

    rprof, pprof, nprof = _rho_prof(cluster, nrad=nrad, projected=projected)

    if pprof[-1] > rho_local:
        rl = rprof[-1]
    elif pprof[0] < rho_local:
        rl = 0.0
    else:
        indx = np.argwhere(pprof < rho_local)[0][0]
        r1 = (rprof[indx - 1], pprof[indx - 1])
        r2 = (rprof[indx], pprof[indx])

        rl = interpolate(r1, r2, y=rho_local)

    if units0 == "pckms":
        rl *= 1000.0 * ro
    elif units0 == "kpckms":
        rl *= ro
    elif units0 == "nbody":
        rl *= 1000.0 * ro / cluster.rbar

    return_cluster(cluster, units0, origin0, do_order=True, do_key_params=True)

    if plot:

        filename = kwargs.pop("filename", None)
        overplot = kwargs.pop("overplot", False)

        if cluster.units == "nbody":
            rprof *= ro * 1000.0 / cluster.rbar
            pprof *= (bovy_conversion.dens_in_msolpc3(ro=ro, vo=vo) *
                      (cluster.rbar**3.0) / cluster.zmbar)
            rho_local *= (bovy_conversion.dens_in_msolpc3(ro=ro, vo=vo) *
                          (cluster.rbar**3.0) / cluster.zmbar)
            xunits = " (NBODY)"
            yunits = " (NBODY)"
        elif cluster.units == "pckms":
            rprof *= ro * 1000.0
            pprof *= bovy_conversion.dens_in_msolpc3(ro=ro, vo=vo)
            rho_local *= bovy_conversion.dens_in_msolpc3(ro=ro, vo=vo)
            xunits = " (pc)"
            if projected:
                yunits = " Msun/pc^2"
            else:
                yunits = " Msun/pc^3"
        elif cluster.units == "kpckms":
            rprof *= ro
            pprof *= bovy_conversion.dens_in_msolpc3(ro=ro, vo=vo) * (1000.0**
                                                                      3.0)
            rho_local *= bovy_conversion.dens_in_msolpc3(ro=ro,
                                                         vo=vo) * (1000.0**3.0)

            xunits = " (kpc)"
            if projected:
                yunits = " Msun/kpc^2"
            else:
                yunits = " Msun/kpc^3"
        elif cluster.units == "galpy":
            xunits = " (GALPY)"
            yunits = " (GALPY)"

        else:
            xunits = ""
            yunits = ""

        x, y, n = rprof, pprof, nprof
        _lplot(
            x,
            y,
            xlabel=r"$R %s$" % (xunits),
            ylabel=r"$\rho %s$" % (yunits),
            title="Time = %f" % cluster.tphys,
            log=True,
            overplot=overplot,
            filename=filename,
        )
        _lplot(x, np.ones(len(x)) * rho_local, "--", overplot=True)
        _lplot(np.ones(len(y)) * rl, y, "--", overplot=True)

        if filename != None:
            plt.savefig(filename)

    return rl
def like_func(params,surfrs,kzs,kzerrs,
              termdata,options):
    #Check ranges
    if params[0] < 0. or params[0] > 1.: return numpy.finfo(numpy.dtype(numpy.float64)).max
    if params[1] < 0. or params[1] > 1.: return numpy.finfo(numpy.dtype(numpy.float64)).max
    if options.twodisks and (params[2] < 0. or params[2] > 1.): return numpy.finfo(numpy.dtype(numpy.float64)).max
    if (1.-params[0]-params[1]-options.twodisks*params[2]) < 0. or (1.-params[0]-params[1]-options.twodisks*params[2]) > 1.: return numpy.finfo(numpy.dtype(numpy.float64)).max
    if params[2+options.twodisks] < numpy.log(1./_REFR0) or params[2+options.twodisks] > numpy.log(8./_REFR0):
        return numpy.finfo(numpy.dtype(numpy.float64)).max
    if params[3+options.twodisks] < numpy.log(0.05/_REFR0) or params[3+options.twodisks] > numpy.log(1./_REFR0):
        return numpy.finfo(numpy.dtype(numpy.float64)).max
    if options.twodisks:
        if params[5] < numpy.log(1./_REFR0) or params[5] > numpy.log(8./_REFR0):
            return numpy.finfo(numpy.dtype(numpy.float64)).max
        if params[6] < numpy.log(0.05/_REFR0) or params[6] > numpy.log(1./_REFR0):
            return numpy.finfo(numpy.dtype(numpy.float64)).max
    #Setup potential
    if options.twodisks:
        pot= [potential.PowerSphericalPotentialwCutoff(normalize=1.-params[0]-params[1]-params[2],
                                                       alpha=1.8,rc=1.9/_REFR0),
              potential.MiyamotoNagaiPotential(normalize=params[0],
                                               a=numpy.exp(params[3]),
                                               b=numpy.exp(params[4])),
              potential.MiyamotoNagaiPotential(normalize=params[1],
                                               a=numpy.exp(params[5]),
                                               b=numpy.exp(params[6])),
              potential.NFWPotential(normalize=params[2],
                                     a=numpy.exp(params[7]))]
    else:
        pot= [potential.PowerSphericalPotentialwCutoff(normalize=1.-params[0]-params[1],
                                                       alpha=1.8,rc=1.9/_REFR0),
              potential.MiyamotoNagaiPotential(normalize=params[0],
                                               a=numpy.exp(params[2]),
                                               b=numpy.exp(params[3])),
              potential.NFWPotential(normalize=params[1],a=numpy.exp(params[4]))]
    #Calculate model surface density at surfrs
    modelkzs= numpy.empty_like(surfrs)
    for ii in range(len(surfrs)):
        modelkzs[ii]= -potential.evaluatezforces(surfrs[ii]/_REFR0,1.1/_REFR0,
                                                 pot)*bovy_conversion.force_in_2piGmsolpc2(_REFV0,_REFR0)
    out= 0.5*numpy.sum((kzs-modelkzs)**2./kzerrs**2.)
    #Add terminal velocities
    vrsun= params[5+3*options.twodisks]
    vtsun= params[6+3*options.twodisks]
    cl_glon, cl_vterm, cl_corr, mc_glon, mc_vterm, mc_corr= termdata
    #Calculate terminal velocities at data glon
    cl_vterm_model= numpy.zeros_like(cl_vterm)
    for ii in range(len(cl_glon)):
        cl_vterm_model[ii]= potential.vterm(pot,cl_glon[ii])
    cl_vterm_model+= vrsun*numpy.cos(cl_glon/180.*numpy.pi)\
        -vtsun*numpy.sin(cl_glon/180.*numpy.pi)
    mc_vterm_model= numpy.zeros_like(mc_vterm)
    for ii in range(len(mc_glon)):
        mc_vterm_model[ii]= potential.vterm(pot,mc_glon[ii])
    mc_vterm_model+= vrsun*numpy.cos(mc_glon/180.*numpy.pi)\
        -vtsun*numpy.sin(mc_glon/180.*numpy.pi)
    cl_dvterm= (cl_vterm-cl_vterm_model)/options.termsigma*_REFV0
    mc_dvterm= (mc_vterm-mc_vterm_model)/options.termsigma*_REFV0
    out+= 0.5*numpy.sum(cl_dvterm*numpy.dot(cl_corr,cl_dvterm))
    out+= 0.5*numpy.sum(mc_dvterm*numpy.dot(mc_corr,mc_dvterm))
    #Rotation curve constraint
    out-= logprior_dlnvcdlnr(potential.dvcircdR(pot,1.))
    #K dwarfs, Kz
    out+= 0.5*(-potential.evaluatezforces(1.,1.1/_REFR0,pot)*bovy_conversion.force_in_2piGmsolpc2(_REFV0,_REFR0)-67.)**2./36.
    #K dwarfs, visible
    out+= 0.5*(visible_dens(pot,options)-55.)**2./25.
    #Local density prior
    localdens= potential.evaluateDensities(1.,0.,pot)*bovy_conversion.dens_in_msolpc3(_REFV0,_REFR0)
    out+= 0.5*(localdens-0.102)**2./0.01**2.
    #Bulge velocity dispersion
    out+= 0.5*(bulge_dispersion(pot)-117.)**2./225.
    #Mass at 60 kpc
    out+= 0.5*(mass60(pot,options)-4.)**2./0.7**2.
    #Concentration prior?
    return out
예제 #24
0
def illustrateBestR(options,args):
    if options.sample.lower() == 'g':
        npops= 62
    elif options.sample.lower() == 'k':
        npops= 54
    if options.sample.lower() == 'g':
        savefile= open('binmapping_g.sav','rb')
    elif options.sample.lower() == 'k':
        savefile= open('binmapping_k.sav','rb')
    fehs= pickle.load(savefile)
    afes= pickle.load(savefile)
    savefile.close()
    #For bin 10, calculate the correlation between sigma and Rd
    bin= options.index
    derivProps= calcAllSurfErr(bin,options,args)
    #rs= numpy.linspace(4.5,9.,101)
    #derivProps= numpy.zeros((101,6))
    rs= derivProps[:,0]
    #also calculate the full surface density profile for each Rd's best fh
    if _NOTDONEYET:
        spl= options.restart.split('.')
    else:
        spl= args[0].split('.')
    newname= ''
    for jj in range(len(spl)-1):
        newname+= spl[jj]
        if not jj == len(spl)-2: newname+= '.'
    newname+= '_%i.' % bin
    newname+= spl[-1]
    options.potential= 'dpdiskplhalofixbulgeflatwgasalt'
    options.fitdvt= False
    savefile= open(newname,'rb')
    try:
        if not _NOTDONEYET:
            params= pickle.load(savefile)
            mlogl= pickle.load(savefile)
        logl= pickle.load(savefile)
    except:
        raise
    finally:
        savefile.close()
    if _NOTDONEYET:
        logl[(logl == 0.)]= -numpy.finfo(numpy.dtype(numpy.float64)).max
    logl[numpy.isnan(logl)]= -numpy.finfo(numpy.dtype(numpy.float64)).max
    marglogl= numpy.zeros((logl.shape[0],logl.shape[3]))
    sigs= numpy.zeros((logl.shape[0],len(rs)))
    rds= numpy.linspace(2.,3.4,8)
    fhs= numpy.linspace(0.,1.,16)
    hiresfhs= numpy.linspace(0.,1.,101)
    ro= 1.
    vo= options.fixvc/_REFV0
    for jj in range(logl.shape[0]):
        for kk in range(logl.shape[3]):
            marglogl[jj,kk]= misc.logsumexp(logl[jj,0,0,kk,:,:,:,0].flatten())
        #interpolate
        tindx= marglogl[jj,:] > -1000000000.
        intp= interpolate.InterpolatedUnivariateSpline(fhs[tindx],marglogl[jj,tindx],
                                                       k=3)
        ml= intp(hiresfhs)
        indx= numpy.argmax(ml)
        indx2= numpy.argmax(marglogl[jj,:])
        #Setup potential to calculate stuff
        potparams= numpy.array([numpy.log(rds[jj]/8.),vo,numpy.log(options.fixzh/8000.),hiresfhs[indx],options.dlnvcdlnr])
        try:
            pot= setup_potential(potparams,options,0,returnrawpot=True)
        except RuntimeError:
            continue
        #Total surface density
        for ll in range(len(rs)):
            surfz= 2.*integrate.quad((lambda zz: potential.evaluateDensities(rs[ll]/_REFR0,zz,pot)),0.,options.height/_REFR0/ro)[0]*_REFV0**2.*vo**2./_REFR0**2./ro**2./4.302*_REFR0*ro
            sigs[jj,ll]= surfz
    #Now plot sigs
    bovy_plot.bovy_print(fig_height=7.,fig_width=5.)
    left, bottom, width, height= 0.1, 0.35, 0.8, 0.4
    axTop= pyplot.axes([left,bottom,width,height])
    fig= pyplot.gcf()
    fig.sca(axTop)
    ii= 0
    bovy_plot.bovy_plot(rs,sigs[ii,:],'k-',
                        xlabel=r'$R\ (\mathrm{kpc})$',
                        ylabel=r'$\Sigma(R,|Z| \leq 1.1\,\mathrm{kpc})\ (M_\odot\,\mathrm{pc}^{-2})$',
                        xrange=[4.,10.],
                        yrange=[10,1050.],
                        semilogy=True,overplot=True)
    for ii in range(1,logl.shape[0]):
        bovy_plot.bovy_plot(rs,sigs[ii,:],'k-',overplot=True)
    thisax= pyplot.gca()
    thisax.set_yscale('log')
    nullfmt   = NullFormatter()         # no labels
    thisax.xaxis.set_major_formatter(nullfmt)
    thisax.set_ylim(10.,1050.)
    thisax.set_xlim(4.,10.)
    pyplot.ylabel(r'$\Sigma_{1.1}(R)\ (M_\odot\,\mathrm{pc}^{-2})$')
    bovy_plot._add_ticks(yticks=False)
    bovy_plot.bovy_text(r'$[\mathrm{Fe/H}] = %.2f$' % (fehs[bin])
                        +'\n'
                        r'$[\alpha/\mathrm{Fe}] = %.3f$' % (afes[bin]),
                        size=16.,top_right=True)

    left, bottom, width, height= 0.1, 0.1, 0.8, 0.25
    ax2= pyplot.axes([left,bottom,width,height])
    fig= pyplot.gcf()
    fig.sca(ax2)
    bovy_plot.bovy_plot(rs,derivProps[:,2],'k-',lw=2.,
                        xrange=[4.,10.],
                        overplot=True)
    indx= numpy.argmin(numpy.fabs(derivProps[:,2]))
    bovy_plot.bovy_plot([4.,10.],[0.,0.],'-',color='0.5',overplot=True)
    bovy_plot.bovy_plot([rs[indx],rs[indx]],[derivProps[indx,2],1000.],
                        'k--',overplot=True)
    thisax= pyplot.gca()
    pyplot.ylabel(r'$\mathrm{Correlation\ between}$'+'\n'+r'$\!\!\!\!\!\!\!\!R_d\ \&\ \Sigma_{1.1}(R)$')
    pyplot.xlabel(r'$R\ (\mathrm{kpc})$')   
    pyplot.xlim(4.,10.)
    pyplot.ylim(-.5,.5)
    bovy_plot._add_ticks()
    pyplot.sca(axTop)
    bovy_plot.bovy_plot([rs[indx],rs[indx]],[0.01,sigs[3,indx]],
                        'k--',overplot=True)   
    bovy_plot.bovy_end_print(options.outfilename)
예제 #25
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
예제 #26
0
def test_density():
    #test the density calculation of the KuzminKutuzovStaeckelPotential
    #using parameters from Batsleer & Dejonghe 1994, tab. 2

    #_____parameters_____
    #table 2 in Batsleer & Dejonghe
    ac_D   = [25.  ,25.  ,25.  ,25. ,25.  ,25. ,40.  ,40.  ,40.  ,40. ,40. ,50.  ,50.  ,50. ,50.  ,50. ,50.  ,75.  ,75.  ,75. ,75.  ,75. ,75.  ,100. ,100. ,100.,100. ,100.,100. ,150. ,150. ,150. ,150. ,150.,150.]
    ac_H   = [1.005,1.005,1.01 ,1.01,1.02 ,1.02,1.005,1.005,1.01 ,1.01,1.02,1.005,1.005,1.01,1.01 ,1.02,1.02 ,1.005,1.005,1.01,1.01 ,1.02,1.02 ,1.005,1.005,1.01,1.01 ,1.02,1.02 ,1.005,1.005,1.01 ,1.01 ,1.02,1.02]
    k      = [0.05 ,0.08 ,0.075,0.11,0.105,0.11,0.05 ,0.08 ,0.075,0.11,0.11,0.05 ,0.07 ,0.07,0.125,0.1 ,0.125,0.05 ,0.065 ,0.07,0.125,0.10,0.125,0.05,0.065,0.07,0.125,0.10,0.125,0.05 ,0.065,0.075,0.125,0.11,0.125]
    Delta  = [0.99 ,1.01 ,0.96 ,0.99,0.86 ,0.88,1.00 ,1.01 ,0.96 ,0.99,0.89,1.05 ,1.06 ,1.00,1.05 ,0.91,0.97 ,0.98 ,0.99 ,0.94,0.98 ,0.85,0.91 ,1.06 ,1.07 ,1.01,1.06 ,0.94,0.97 ,1.06 ,1.07 ,0.98 ,1.06 ,0.94,0.97]
    Mmin   = [7.49 ,6.17 ,4.08 ,3.70,2.34 ,2.36,7.57 ,6.16 ,4.08 ,2.64,2.38,8.05 ,6.94 ,4.37,3.70 ,2.48,2.50 ,7.37 ,6.66 ,4.05,3.46 ,2.33,2.36 ,8.14 ,7.27 ,4.42,3.72 ,2.56,2.50 ,8.14 ,7.26 ,4.17 ,3.72 ,2.51,2.50]
    Mmax   = [7.18 ,6.12 ,3.99 ,3.69,2.37 ,2.40,7.27 ,6.11 ,3.99 ,2.66,2.42,7.76 ,6.85 ,4.26,3.72 ,2.51,2.54 ,7.07 ,6.51 ,3.95,3.48 ,2.36,2.40 ,7.85 ,7.15 ,4.30,3.75 ,2.58,2.54 ,7.85 ,7.07 ,4.08 ,3.75 ,2.53,2.53]
    rhomin = [0.04 ,0.05 ,0.04 ,0.04,0.03 ,0.03,0.06 ,0.06 ,0.05 ,0.04,0.04,0.07 ,0.08 ,0.06,0.07 ,0.04,0.05 ,0.08 ,0.09 ,0.07,0.09 ,0.05,0.06 ,0.12 ,0.13 ,0.09,0.13 ,0.07,0.09 ,0.16 ,0.19 ,0.12 ,0.18 ,0.10,0.12]
    rhomax = [0.03 ,0.03 ,0.02 ,0.03,0.02 ,0.02,0.04 ,0.04 ,0.03 ,0.03,0.02,0.05 ,0.05 ,0.04,0.05 ,0.03,0.03 ,0.05 ,0.06 ,0.04,0.06 ,0.03,0.04 ,0.07 ,0.08 ,0.06,0.08 ,0.04,0.05 ,0.09 ,0.10 ,0.07 ,0.10 ,0.06,0.07]
    Sigmin = [58   ,52   ,52   ,49  ,39   ,40  ,58   ,55   ,51   ,44  ,40  ,59   ,54   ,53  ,49   ,41  ,42   ,58   ,55   ,51  ,48   ,39  ,40   ,59   ,55   ,53  ,49   ,42  ,42   ,59   ,55   ,52   ,49   ,42  ,42]
    Sigmax = [45   ,41   ,38   ,37  ,28   ,28  ,45   ,32   ,37   ,32  ,30  ,46   ,43   ,40  ,37   ,30  ,31   ,45   ,43   ,38  ,36   ,28  ,29   ,46   ,43   ,40  ,38   ,31  ,31   ,46   ,44   ,39   ,38   ,30  ,31]

    for ii in range(len(ac_D)):

        if ac_D[ii] == 40.: 
            continue    
            #because I believe that there are typos in tab. 2 by Batsleer & Dejonghe...
    
        for jj in range(2):

            #_____parameters depending on solar position____
            if jj == 0:
                Rsun = 7.5
                zsun = 0.004
                GM   = Mmin[ii]  #units: G = 1, M in 10^11 solar masses
                rho  = rhomin[ii]
                Sig  = Sigmin[ii]
            elif jj == 1:
                Rsun = 8.5
                zsun = 0.02
                GM   = Mmax[ii]  #units: G = 1, M in 10^11 solar masses
                rho  = rhomax[ii]
                Sig  = Sigmax[ii]
            outstr = 'ac_D='+str(ac_D[ii])+', ac_H='+str(ac_H[ii])+', k='+str(k[ii])+', Delta='+str(Delta[ii])+\
                     ', Mtot='+str(GM)+'*10^11Msun, Rsun='+str(Rsun)+'kpc, rho(Rsun,zsun)='+str(rho)+'Msun/pc^3, Sig(Rsun,z<1.1kpc)='+str(Sig)+'Msun/pc^2'
            

            #_____setup potential_____
            amp_D = GM * k[ii]
            V_D = KuzminKutuzovStaeckelPotential(amp=amp_D,ac=ac_D[ii],Delta=Delta[ii],normalize=False)
            amp_H = GM * (1.-k[ii])
            V_H = KuzminKutuzovStaeckelPotential(amp=amp_H,ac=ac_H[ii],Delta=Delta[ii],normalize=False)
            pot = [V_D,V_H]

            #_____local density_____
            rho_calc = evaluateDensities(pot,Rsun,zsun) * 100. #units: [solar mass / pc^3]
            rho_calc = round(rho_calc,2)

            #an error of 0.01 corresponds to the significant digit 
            #given in the table, to which the density was rounded, 
            #to be wrong by one.
            assert numpy.fabs(rho_calc - rho) <= 0.01+10.**-8, \
                'Calculated density %f for KuzminKutuzovStaeckelPotential ' % rho_calc + \
                'with model parameters:\n'+outstr+'\n'+ \
                'does not agree with value from tab. 2 '+ \
                'by Batsleer & Dejonghe (1994)' 

            #_____surface density_____
            Sig_calc, err = scipy.integrate.quad(lambda z: (evaluateDensities(pot,Rsun,z/1000.) * 100.), #units: [solar mass / pc^3]
                                            0., 1100.) #units: pc
            Sig_calc = round(2. * Sig_calc)

            #an error of 1 corresponds to the significant digit 
            #given in the table, to which the surface density was rounded, 
            #to be wrong by one.
            assert numpy.fabs(Sig_calc - Sig) <= 1., \
                'Calculated surface density %f for KuzminKutuzovStaeckelPotential ' % Sig_calc + \
                'with model parameters:\n'+outstr+'\n'+ \
                'does not agree with value from tab. 2 '+ \
                'by Batsleer & Dejonghe (1994)' 

    return None
예제 #27
0
def calcDFResults(options,args,boot=True,nomedian=False):
    if len(args) == 2 and options.sample == 'gk':
        toptions= copy.copy(options)
        toptions.sample= 'g'
        toptions.select= 'all'
        outg= calcDFResults(toptions,[args[0]],boot=boot,nomedian=True)
        toptions.sample= 'k'
        toptions.select= 'program'
        outk= calcDFResults(toptions,[args[1]],boot=boot,nomedian=True)
        #Combine
        out= {}
        for k in outg.keys():
            valg= outg[k]
            valk= outk[k]
            val= numpy.zeros(len(valg)+len(valk))
            val[0:len(valg)]= valg
            val[len(valg):len(valg)+len(valk)]= valk
            out[k]= val
        if nomedian: return out
        else: return add_median(out,boot=boot)
    raw= read_rawdata(options)
    #Bin the data
    binned= pixelAfeFeh(raw,dfeh=options.dfeh,dafe=options.dafe)
    tightbinned= binned
    #Map the bins with ndata > minndata in 1D
    fehs, afes= [], []
    counter= 0
    abindx= numpy.zeros((len(binned.fehedges)-1,len(binned.afeedges)-1),
                        dtype='int')
    for ii in range(len(binned.fehedges)-1):
        for jj in range(len(binned.afeedges)-1):
            data= binned(binned.feh(ii),binned.afe(jj))
            if len(data) < options.minndata:
                continue
            #print binned.feh(ii), binned.afe(jj), len(data)
            fehs.append(binned.feh(ii))
            afes.append(binned.afe(jj))
            abindx[ii,jj]= counter
            counter+= 1
    nabundancebins= len(fehs)
    fehs= numpy.array(fehs)
    afes= numpy.array(afes)
    #Load each of the solutions
    sols= []
    chi2s= []
    savename= args[0]
    initname= options.init
    for ii in range(nabundancebins):
        spl= savename.split('.')
        newname= ''
        for jj in range(len(spl)-1):
            newname+= spl[jj]
            if not jj == len(spl)-2: newname+= '.'
        newname+= '_%i.' % ii
        newname+= spl[-1]
        savefilename= newname
        #Read savefile
        try:
            savefile= open(savefilename,'rb')
        except IOError:
            print "WARNING: MISSING ABUNDANCE BIN"
            sols.append(None)
            chi2s.append(None)
        else:
            sols.append(pickle.load(savefile))
            chi2s.append(pickle.load(savefile))
            savefile.close()
        #Load samples as well
        if options.mcsample:
            #Do the same for init
            spl= initname.split('.')
            newname= ''
            for jj in range(len(spl)-1):
                newname+= spl[jj]
                if not jj == len(spl)-2: newname+= '.'
            newname+= '_%i.' % ii
            newname+= spl[-1]
            options.init= newname
    mapfehs= monoAbundanceMW.fehs()
    mapafes= monoAbundanceMW.afes()
    #Now plot
    #Run through the pixels and gather
    fehs= []
    afes= []
    ndatas= []
    zmedians= []
    #Basic parameters
    hrs= []
    srs= []
    szs= []
    hsrs= []
    hszs= []
    outfracs= []
    rds= []
    rdexps= []
    vcs= []
    zhs= []
    zhexps= []
    dlnvcdlnrs= []
    plhalos= []
    rorss= []
    dvts= []
    #derived parameters
    surfzs= []
    surfz800s= []
    surfzdisks= []
    massdisks= []
    rhoos= []
    rhooalts= []
    rhodms= []
    vcdvcros= []
    vcdvcs= []
    vescs= []
    mloglikemins= []
    for ii in range(tightbinned.npixfeh()):
        for jj in range(tightbinned.npixafe()):
            data= binned(tightbinned.feh(ii),tightbinned.afe(jj))
            if len(data) < options.minndata:
                continue
            #Find abundance indx
            fehindx= binned.fehindx(tightbinned.feh(ii))#Map onto regular binning
            afeindx= binned.afeindx(tightbinned.afe(jj))
            solindx= abindx[fehindx,afeindx]
            monoabindx= numpy.argmin((tightbinned.feh(ii)-mapfehs)**2./0.01 \
                                         +(tightbinned.afe(jj)-mapafes)**2./0.0025)
            if sols[solindx] is None:
                continue
            try:
                pot= setup_potential(sols[solindx],options,1,interpDens=True,
                                     interpdvcircdr=True,returnrawpot=True)
            except RuntimeError:
                print "A bin has an unphysical potential ..."
                continue
#            if 'dpdisk' in options.potential.lower():
#                try:
#                    rawpot= setup_potential(sols[solindx],options,1,
#                                            returnrawpot=True)
#                except RuntimeError:
#                    print "A bin has an unphysical potential ..."
#                    continue
            fehs.append(tightbinned.feh(ii))
            afes.append(tightbinned.afe(jj))
            zmedians.append(numpy.median(numpy.fabs(data.zc+_ZSUN)))
            #vc
            s= get_potparams(sols[solindx],options,1)
            ro= get_ro(sols[solindx],options)
            if options.fixvo:
                vcs.append(options.fixvo*_REFV0)
            else:
                vcs.append(s[1]*_REFV0)
            #rd
            rds.append(numpy.exp(s[0]))
            #zh
            zhs.append(numpy.exp(s[2-(1-(options.fixvo is None))]))
            #rdexp & zhexp
            if options.sample == 'g': tz= 1.1/_REFR0/ro
            elif options.sample == 'k': tz= 0.84/_REFR0/ro
            if 'mpdisk' in options.potential.lower() or 'mwpotential' in options.potential.lower():
                mp= potential.MiyamotoNagaiPotential(a=rds[-1],b=zhs[-1])
                #rdexp
                f= mp.dens(1.,0.125)
                dr= 10.**-3.
                df= (mp.dens(1.+dr/2.,0.125)-mp.dens(1.-dr/2.,0.125))/dr
                rdexps.append(-f/df)
                #zhexp
                f= mp.dens(1.,tz)
                dz= 10.**-3.
                df= (mp.dens(1.,tz+dz/2.)-mp.dens(1.,tz-dz/2.))/dz
                zhexps.append(-f/df)
            elif 'dpdisk' in options.potential.lower():
                rdexps.append(numpy.exp(s[0]))
                zhexps.append(numpy.exp(s[2-(1-(options.fixvo is None))]))
            #ndata
            ndatas.append(len(data))
            #hr
            dfparams= get_dfparams(sols[solindx],0,options)
            if options.relative:
                thishr= monoAbundanceMW.hr(mapfehs[monoabindx],mapafes[monoabindx])
                hrs.append(dfparams[0]*_REFR0/thishr)
            else:
                hrs.append(dfparams[0]*_REFR0)
            #sz
            if options.relative:
                thissz= monoAbundanceMW.sigmaz(mapfehs[monoabindx],mapafes[monoabindx])
                szs.append(dfparams[2]*_REFV0/thissz)
            else:
                szs.append(dfparams[2]*_REFV0)
            #sr
            if options.relative:
                thissr= monoAbundanceMW.sigmaz(mapfehs[monoabindx],mapafes[monoabindx])*2.#BOVY: UPDATE
                srs.append(dfparams[1]*_REFV0/thissr)
            else:
                srs.append(dfparams[1]*_REFV0)
            #hsr
            hsrs.append(dfparams[3]*_REFR0)
            #hsz
            hszs.append(dfparams[4]*_REFR0)
            #outfrac
            outfracs.append(dfparams[5])
            #rhodm
            #Setup potential
            vo= get_vo(sols[solindx],options,1)
            if 'mwpotential' in options.potential.lower():
                rhodms.append(pot[1].dens(1.,0.)*_REFV0**2.*vo**2./_REFR0**2./ro**2./4.302*10.**-3.)
            elif options.potential.lower() == 'mpdiskplhalofixbulgeflat':
                rhodms.append(pot[1].dens(1.,0.)*_REFV0**2.*vo**2./_REFR0**2./ro**2./4.302*10.**-3.)
            elif options.potential.lower() == 'mpdiskflplhalofixplfixbulgeflat':
                rhodms.append(pot[1].dens(1.,0.)*_REFV0**2.*vo**2./_REFR0**2./ro**2./4.302*10.**-3.)
            elif options.potential.lower() == 'dpdiskplhalofixbulgeflat' \
                    or options.potential.lower() == 'dpdiskplhalofixbulgeflatwgas' \
                    or options.potential.lower() == 'dpdiskplhalofixbulgeflatwgasalt' \
                    or options.potential.lower() == 'dpdiskflplhalofixbulgeflatwgas':
                rhodms.append(pot[1].dens(1.,0.)*_REFV0**2.*vo**2./_REFR0**2./ro**2./4.302*10.**-3.)
            #rhoo
            rhoos.append(potential.evaluateDensities(1.,0.,pot)*_REFV0**2.*vo**2./_REFR0**2./ro**2./4.302*10.**-3.)
            #surfz
            surfzs.append(2.*integrate.quad((lambda zz: potential.evaluateDensities(1.,zz,pot)),0.,options.height/_REFR0/ro)[0]*_REFV0**2.*vo**2./_REFR0**2./ro**2./4.302*_REFR0*ro)
            #surfz800
            surfz800s.append(2.*integrate.quad((lambda zz: potential.evaluateDensities(1.,zz,pot)),0.,0.8/_REFR0/ro)[0]*_REFV0**2.*vo**2./_REFR0**2./ro**2./4.302*_REFR0*ro)
            #surzdisk
            if 'mpdisk' in options.potential.lower() or 'mwpotential' in options.potential.lower():
                surfzdisks.append(2.*integrate.quad((lambda zz: potential.evaluateDensities(1.,zz,pot[0])),0.,options.height/_REFR0/ro)[0]*_REFV0**2.*vo**2./_REFR0**2./ro**2./4.302*_REFR0*ro)
                surfzdiskzm= 2.*integrate.quad((lambda zz: potential.evaluateDensities(1.,zz,pot[0])),0.,tz)[0]*_REFV0**2.*vo**2./_REFR0**2./ro**2./4.302*_REFR0*ro
            elif 'dpdisk' in options.potential.lower():
                surfzdisks.append(2.*pot[0].dens(1.,0.)*_REFV0**2.*vo**2./_REFR0**2./ro**2./4.302*10.**-3.*zhexps[-1]*ro*_REFR0*1000.)
            #rhooalt
            if options.potential.lower() == 'mpdiskplhalofixbulgeflat':
                rhooalts.append(rhoos[-1]-pot[0].dens(1.,0.)*_REFV0**2.*vo**2./_REFR0**2./ro**2./4.302*10.**-3.+surfzdiskzm/2./zhexps[-1]/ro/_REFR0/1000./(1.-numpy.exp(-tz/zhexps[-1])))
            elif options.potential.lower() == 'dpdiskplhalofixbulgeflat' \
                    or options.potential.lower() == 'dpdiskplhalofixbulgeflatwgas' \
                    or options.potential.lower() == 'dpdiskplhalofixbulgeflatwgasalt' \
                    or options.potential.lower() == 'dpdiskflplhalofixbulgeflatwgas':
                rhooalts.append(rhoos[-1])
            #massdisk
            if options.potential.lower() == 'dpdiskplhalofixbulgeflat' \
                    or options.potential.lower() == 'dpdiskplhalofixbulgeflatwgas' \
                    or options.potential.lower() == 'dpdiskplhalofixbulgeflatwgasalt' \
                    or options.potential.lower() == 'dpdiskflplhalofixbulgeflatwgas':
                rhod= pot[0].dens(1.,0.)*_REFV0**2.*vo**2./_REFR0**2./ro**2./4.302*10.**-3.
            else:
                rhod= surfzdiskzm/2./zhexps[-1]/ro/_REFR0/1000./(1.-numpy.exp(-tz/zhexps[-1]))
            massdisks.append(rhod*2.*zhexps[-1]*numpy.exp(1./rdexps[-1])*rdexps[-1]**2.*2.*numpy.pi*(ro*_REFR0)**3./10.)
            #plhalo
            if options.potential.lower() == 'mpdiskplhalofixbulgeflat':
                plhalos.append(pot[1].alpha)
                plhalos.append((1.-pot[1].alpha)/(pot[1].alpha-3.))
            elif options.potential.lower() == 'dpdiskplhalofixbulgeflat' \
                    or options.potential.lower() == 'dpdiskplhalofixbulgeflatwgas' \
                    or options.potential.lower() == 'dpdiskplhalofixbulgeflatwgasalt' \
                    or options.potential.lower() == 'dpdiskflplhalofixbulgeflatwgas':
                plhalos.append(pot[1].alpha)
                rorss.append((1.-pot[1].alpha)/(pot[1].alpha-3.))
            #dlnvcdlnr
            if options.potential.lower() == 'dpdiskplhalofixbulgeflat' \
                    or options.potential.lower() == 'dpdiskplhalofixbulgeflatwgas' \
                    or options.potential.lower() == 'dpdiskplhalofixbulgeflatwgasalt' \
                    or options.potential.lower() == 'dpdiskflplhalofixbulgeflatwgas':
                dlnvcdlnrs.append(potential.dvcircdR(pot,1.))
            else:
                dlnvcdlnrs.append(potential.dvcircdR(pot,1.))
            #vcdvc
            if options.potential.lower() == 'dpdiskplhalofixbulgeflat' \
                    or options.potential.lower() == 'dpdiskplhalofixbulgeflatwgas' \
                    or options.potential.lower() == 'dpdiskplhalofixbulgeflatwgasalt' \
                    or options.potential.lower() == 'dpdiskflplhalofixbulgeflatwgas':
                vcdvcros.append(pot[0].vcirc(1.)/potential.vcirc(pot,1.))
                vcdvcs.append(pot[0].vcirc(2.2*rdexps[-1])/potential.vcirc(pot,2.2*rdexps[-1]))
            else:
                vcdvcros.append(pot[0].vcirc(1.)/potential.vcirc(pot,1.))
                vcdvcs.append(pot[0].vcirc(2.2*rdexps[-1])/potential.vcirc(pot,2.2*rdexps[-1]))
            #mloglike
            mloglikemins.append(chi2s[solindx])
            #escape velocity
            vescs.append(potential.vesc(pot,1.)*_REFV0)
            if options.fitdvt:
                dvts.append(sols[solindx][0])
    #Gather
    fehs= numpy.array(fehs)
    afes= numpy.array(afes)
    zmedians= numpy.array(zmedians)
    ndatas= numpy.array(ndatas)
    #Basic parameters
    hrs= numpy.array(hrs)
    srs= numpy.array(srs)
    szs= numpy.array(szs)
    hsrs= numpy.array(hsrs)
    hszs= numpy.array(hszs)
    outfracs= numpy.array(outfracs)
    vcs= numpy.array(vcs)
    rds= numpy.array(rds)
    zhs= numpy.array(zhs)
    rdexps= numpy.array(rdexps)
    zhexps= numpy.array(zhexps)
    dlnvcdlnrs= numpy.array(dlnvcdlnrs)
    plhalos= numpy.array(plhalos)
    rorss= numpy.array(rorss)
    if options.fitdvt:
        dvts= numpy.array(dvts)
    #derived parameters
    surfzs= numpy.array(surfzs)
    surfz800s= numpy.array(surfz800s)
    surfzdisks= numpy.array(surfzdisks)
    massdisks= numpy.array(massdisks)
    rhoos= numpy.array(rhoos)
    rhooalts= numpy.array(rhooalts)
    rhodms= numpy.array(rhodms)
    vcdvcros= numpy.array(vcdvcros)
    vcdvcs= numpy.array(vcdvcs)
    rexps= numpy.sqrt(2.)*(rds+zhs)/2.2
    mloglikemins= numpy.array(mloglikemins)
    vescs= numpy.array(vescs)
    #Load into dictionary
    out= {}
    out['feh']= fehs
    out['afe']= afes
    out['zmedian']= zmedians
    out['ndata']= ndatas
    out['hr']= hrs
    out['sr']= srs
    out['sz']= szs
    out['hsr']= hsrs
    out['hsz']= hszs
    out['outfrac']= outfracs
    out['vc']= vcs
    out['rd']= rds
    out['zh']= zhs
    out['rdexp']= rdexps
    out['zhexp']= zhexps
    out['dlnvcdlnr']= dlnvcdlnrs
    out['plhalo']= plhalos
    out['rors']= rorss
    out['surfz']= surfzs
    out['surfz800']= surfz800s
    out['surfzdisk']= surfzdisks
    out['massdisk']= massdisks
    out['rhoo']= rhoos
    out['rhooalt']= rhooalts
    out['rhodm']= rhodms
    out['vcdvc']= vcdvcs
    out['vcdvcro']= vcdvcros
    out['rexp']= rexps
    out['mloglikemin']= mloglikemins
    out['vesc']= vescs
    if options.fitdvt:
        out['dvt']= dvts
    if nomedian: return out
    else: return add_median(out,boot=boot)