def test_surfdens_in_msolpc2(): #Test the scaling, as a 1st derivative of the potential, should scale as velocity^2/position vofid, rofid = 200., 8. assert numpy.fabs( 4. * bovy_conversion.surfdens_in_msolpc2(vofid, rofid) / bovy_conversion.surfdens_in_msolpc2(2. * vofid, rofid) - 1.) < 10.**-10., 'surfdens_in_msolpc2 did not work as expected' assert numpy.fabs( .5 * bovy_conversion.surfdens_in_msolpc2(vofid, rofid) / bovy_conversion.surfdens_in_msolpc2(vofid, 2 * rofid) - 1.) < 10.**-10., 'surfdens_in_msolpc2 did not work as expected' return None
def test_units(): import galpy.util.bovy_conversion as conversion print(conversion.force_in_pcMyr2(220.,8.))#pc/Myr^2 assert numpy.fabs(conversion.force_in_pcMyr2(220.,8.)-6.32793804994) < 10.**-4., 'unit conversion has changed' print(conversion.dens_in_msolpc3(220.,8.))#Msolar/pc^3 assert numpy.fabs((conversion.dens_in_msolpc3(220.,8.)-0.175790330079)/0.175790330079) < 5.*10.**-5., 'unit conversion has changed' print(conversion.surfdens_in_msolpc2(220.,8.))#Msolar/pc^2 assert numpy.fabs((conversion.surfdens_in_msolpc2(220.,8.)-1406.32264063)/1406.32264063) < 5.*10.**-5., 'unit conversion has changed' print(conversion.mass_in_1010msol(220.,8.))#10^10 Msolar assert numpy.fabs((conversion.mass_in_1010msol(220.,8.)-9.00046490005)/9.00046490005) < 5.*10.**-5., 'unit conversion has changed' print(conversion.freq_in_Gyr(220.,8.))#1/Gyr assert numpy.fabs(conversion.freq_in_Gyr(220.,8.)-28.1245845523) < 10.**-4., 'unit conversion has changed' print(conversion.time_in_Gyr(220.,8.))#Gyr assert numpy.fabs(conversion.time_in_Gyr(220.,8.)-0.0355560807712) < 10.**-4., 'unit conversion has changed' return None
def test_units(): import galpy.util.bovy_conversion as conversion print(conversion.force_in_pcMyr2(220.,8.))#pc/Myr^2 assert numpy.fabs(conversion.force_in_pcMyr2(220.,8.)-6.32793804994) < 10.**-4., 'unit conversion has changed' print(conversion.dens_in_msolpc3(220.,8.))#Msolar/pc^3 assert numpy.fabs(conversion.dens_in_msolpc3(220.,8.)-0.175790330079) < 10.**-4., 'unit conversion has changed' print(conversion.surfdens_in_msolpc2(220.,8.))#Msolar/pc^2 assert numpy.fabs(conversion.surfdens_in_msolpc2(220.,8.)-1406.32264063) < 10.**-4., 'unit conversion has changed' print(conversion.mass_in_1010msol(220.,8.))#10^10 Msolar assert numpy.fabs(conversion.mass_in_1010msol(220.,8.)-9.00046490005) < 10.**-4., 'unit conversion has changed' print(conversion.freq_in_Gyr(220.,8.))#1/Gyr assert numpy.fabs(conversion.freq_in_Gyr(220.,8.)-28.1245845523) < 10.**-4., 'unit conversion has changed' print(conversion.time_in_Gyr(220.,8.))#Gyr assert numpy.fabs(conversion.time_in_Gyr(220.,8.)-0.0355560807712) < 10.**-4., 'unit conversion has changed' return None
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))
def test_surfdens_in_msolpc2(): #Test the scaling, as a 1st derivative of the potential, should scale as velocity^2/position vofid, rofid= 200., 8. assert numpy.fabs(4.*bovy_conversion.surfdens_in_msolpc2(vofid,rofid)/bovy_conversion.surfdens_in_msolpc2(2.*vofid,rofid)-1.) < 10.**-10., 'surfdens_in_msolpc2 did not work as expected' assert numpy.fabs(.5*bovy_conversion.surfdens_in_msolpc2(vofid,rofid)/bovy_conversion.surfdens_in_msolpc2(vofid,2*rofid)-1.) < 10.**-10., 'surfdens_in_msolpc2 did not work as expected' return None
def __init__(self, amp=1., ro=None, vo=None, amp_units=None): """ NAME: __init__ PURPOSE: Initialize Force INPUT: amp - amplitude to be applied when evaluating the potential and its forces ro - physical distance scale (in kpc or as Quantity) vo - physical velocity scale (in km/s or as Quantity) amp_units - ('mass', 'velocity2', 'density') type of units that amp should have if it has units OUTPUT: HISTORY: 2018-03-18 - Written to generalize Potential to force that may or may not be conservative - Bovy (UofT) """ self._amp = amp # Parse ro and vo if ro is None: self._ro = config.__config__.getfloat('normalization', 'ro') self._roSet = False else: if _APY_LOADED and isinstance(ro, units.Quantity): ro = ro.to(units.kpc).value self._ro = ro self._roSet = True if vo is None: self._vo = config.__config__.getfloat('normalization', 'vo') self._voSet = False else: if _APY_LOADED and isinstance(vo, units.Quantity): vo = vo.to(units.km / units.s).value self._vo = vo self._voSet = True # Parse amp if it has units if _APY_LOADED and isinstance(self._amp, units.Quantity): # Try a bunch of possible units unitFound = False # velocity^2 try: self._amp= self._amp.to(units.km**2/units.s**2).value\ /self._vo**2. except units.UnitConversionError: pass else: unitFound = True if not amp_units == 'velocity2': raise units.UnitConversionError( 'amp= parameter of %s should have units of %s, but has units of velocity2 instead' % (type(self).__name__, amp_units)) if not unitFound: # mass try: self._amp= self._amp.to(units.Msun).value\ /bovy_conversion.mass_in_msol(self._vo,self._ro) except units.UnitConversionError: pass else: unitFound = True if not amp_units == 'mass': raise units.UnitConversionError( 'amp= parameter of %s should have units of %s, but has units of mass instead' % (type(self).__name__, amp_units)) if not unitFound: # G x mass try: self._amp= self._amp.to(units.pc*units.km**2/units.s**2)\ .value\ /bovy_conversion.mass_in_msol(self._vo,self._ro)\ /bovy_conversion._G except units.UnitConversionError: pass else: unitFound = True if not amp_units == 'mass': raise units.UnitConversionError( 'amp= parameter of %s should have units of %s, but has units of G x mass instead' % (type(self).__name__, amp_units)) if not unitFound: # density try: self._amp= self._amp.to(units.Msun/units.pc**3).value\ /bovy_conversion.dens_in_msolpc3(self._vo,self._ro) except units.UnitConversionError: pass else: unitFound = True if not amp_units == 'density': raise units.UnitConversionError( 'amp= parameter of %s should have units of %s, but has units of density instead' % (type(self).__name__, amp_units)) if not unitFound: # G x density try: self._amp= self._amp.to(units.km**2/units.s**2\ /units.pc**2).value\ /bovy_conversion.dens_in_msolpc3(self._vo,self._ro)\ /bovy_conversion._G except units.UnitConversionError: pass else: unitFound = True if not amp_units == 'density': raise units.UnitConversionError( 'amp= parameter of %s should have units of %s, but has units of G x density instead' % (type(self).__name__, amp_units)) if not unitFound: # surface density try: self._amp= self._amp.to(units.Msun/units.pc**2).value\ /bovy_conversion.surfdens_in_msolpc2(self._vo,self._ro) except units.UnitConversionError: pass else: unitFound = True if not amp_units == 'surfacedensity': raise units.UnitConversionError( 'amp= parameter of %s should have units of %s, but has units of surface density instead' % (type(self).__name__, amp_units)) if not unitFound: # G x surface density try: self._amp= self._amp.to(units.km**2/units.s**2\ /units.pc).value\ /bovy_conversion.surfdens_in_msolpc2(self._vo,self._ro)\ /bovy_conversion._G except units.UnitConversionError: pass else: unitFound = True if not amp_units == 'surfacedensity': raise units.UnitConversionError( 'amp= parameter of %s should have units of %s, but has units of G x surface density instead' % (type(self).__name__, amp_units)) if not unitFound: raise units.UnitConversionError( 'amp= parameter of %s should have units of %s; given units are not understood' % (type(self).__name__, amp_units)) else: # When amplitude is given with units, turn on physical output self._roSet = True self._voSet = True return None
def __init__(self,amp=1.,ro=None,vo=None,amp_units=None): """ NAME: __init__ PURPOSE: Initialize Force INPUT: amp - amplitude to be applied when evaluating the potential and its forces ro - physical distance scale (in kpc or as Quantity) vo - physical velocity scale (in km/s or as Quantity) amp_units - ('mass', 'velocity2', 'density') type of units that amp should have if it has units OUTPUT: HISTORY: 2018-03-18 - Written to generalize Potential to force that may or may not be conservative - Bovy (UofT) """ self._amp= amp # Parse ro and vo if ro is None: self._ro= config.__config__.getfloat('normalization','ro') self._roSet= False else: if _APY_LOADED and isinstance(ro,units.Quantity): ro= ro.to(units.kpc).value self._ro= ro self._roSet= True if vo is None: self._vo= config.__config__.getfloat('normalization','vo') self._voSet= False else: if _APY_LOADED and isinstance(vo,units.Quantity): vo= vo.to(units.km/units.s).value self._vo= vo self._voSet= True # Parse amp if it has units if _APY_LOADED and isinstance(self._amp,units.Quantity): # Try a bunch of possible units unitFound= False # velocity^2 try: self._amp= self._amp.to(units.km**2/units.s**2).value\ /self._vo**2. except units.UnitConversionError: pass else: unitFound= True if not amp_units == 'velocity2': raise units.UnitConversionError('amp= parameter of %s should have units of %s, but has units of velocity2 instead' % (type(self).__name__,amp_units)) if not unitFound: # mass try: self._amp= self._amp.to(units.Msun).value\ /bovy_conversion.mass_in_msol(self._vo,self._ro) except units.UnitConversionError: pass else: unitFound= True if not amp_units == 'mass': raise units.UnitConversionError('amp= parameter of %s should have units of %s, but has units of mass instead' % (type(self).__name__,amp_units)) if not unitFound: # G x mass try: self._amp= self._amp.to(units.pc*units.km**2/units.s**2)\ .value\ /bovy_conversion.mass_in_msol(self._vo,self._ro)\ /bovy_conversion._G except units.UnitConversionError: pass else: unitFound= True if not amp_units == 'mass': raise units.UnitConversionError('amp= parameter of %s should have units of %s, but has units of G x mass instead' % (type(self).__name__,amp_units)) if not unitFound: # density try: self._amp= self._amp.to(units.Msun/units.pc**3).value\ /bovy_conversion.dens_in_msolpc3(self._vo,self._ro) except units.UnitConversionError: pass else: unitFound= True if not amp_units == 'density': raise units.UnitConversionError('amp= parameter of %s should have units of %s, but has units of density instead' % (type(self).__name__,amp_units)) if not unitFound: # G x density try: self._amp= self._amp.to(units.km**2/units.s**2\ /units.pc**2).value\ /bovy_conversion.dens_in_msolpc3(self._vo,self._ro)\ /bovy_conversion._G except units.UnitConversionError: pass else: unitFound= True if not amp_units == 'density': raise units.UnitConversionError('amp= parameter of %s should have units of %s, but has units of G x density instead' % (type(self).__name__,amp_units)) if not unitFound: # surface density try: self._amp= self._amp.to(units.Msun/units.pc**2).value\ /bovy_conversion.surfdens_in_msolpc2(self._vo,self._ro) except units.UnitConversionError: pass else: unitFound= True if not amp_units == 'surfacedensity': raise units.UnitConversionError('amp= parameter of %s should have units of %s, but has units of surface density instead' % (type(self).__name__,amp_units)) if not unitFound: # G x surface density try: self._amp= self._amp.to(units.km**2/units.s**2\ /units.pc).value\ /bovy_conversion.surfdens_in_msolpc2(self._vo,self._ro)\ /bovy_conversion._G except units.UnitConversionError: pass else: unitFound= True if not amp_units == 'surfacedensity': raise units.UnitConversionError('amp= parameter of %s should have units of %s, but has units of G x surface density instead' % (type(self).__name__,amp_units)) if not unitFound: raise units.UnitConversionError('amp= parameter of %s should have units of %s; given units are not understood' % (type(self).__name__,amp_units)) else: # When amplitude is given with units, turn on physical output self._roSet= True self._voSet= True return None
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)
import numpy as np from galpy.potential import DiskSCFPotential, NFWPotential, \ SCFPotential, scf_compute_coeffs_axi from galpy.util import bovy_conversion from SCF_derivs import mySCFPotential, myDiskSCFPotential ro = 8.21 vo = 233.1 sigo = bovy_conversion.surfdens_in_msolpc2(vo=vo, ro=ro) rhoo = bovy_conversion.dens_in_msolpc3(vo=vo, ro=ro) #gas disk parameters (fixed in McMillan (2017)...) Rd_HI = 7/ro Rm_HI = 4/ro zd_HI = 0.085/ro Sigma0_HI = 53.1/sigo Rd_H2 = 1.5/ro Rm_H2 = 12/ro zd_H2 = 0.045/ro Sigma0_H2 = 2180/sigo #parameters of best-fitting model in McMillan (2017) #stellar disks Sigma0_thin = 896/sigo Rd_thin = 2.5/ro zd_thin = 0.3/ro Sigma0_thick = 183/sigo Rd_thick = 3.02/ro zd_thick = 0.9/ro #bulge rho0_bulge = 98.4/rhoo
### Imports ## Basic import numpy as np import sys, os, pdb ## galpy from galpy import potential from galpy.util import bovy_conversion as gpconv # ---------------------------------------------------------------------------- # Module globals ro=8.21 vo=233.1 sigo = gpconv.surfdens_in_msolpc2(vo=vo, ro=ro) rhoo = gpconv.dens_in_msolpc3(vo=vo, ro=ro) #gas disk parameters (fixed in McMillan (2017)...) Rd_HI = 7/ro Rm_HI = 4/ro zd_HI = 0.085/ro Sigma0_HI = 53.1/sigo Rd_H2 = 1.5/ro Rm_H2 = 12/ro zd_H2 = 0.045/ro Sigma0_H2 = 2180/sigo #parameters of best-fitting model in McMillan (2017) #stellar disks Sigma0_thin = 896/sigo
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)