def test_impulse_deltav_general_curved_hernquist(): from galpy.df import impulse_deltav_hernquist_curvedstream, \ impulse_deltav_general_curvedstream from galpy.potential import HernquistPotential GM = 1.5 tol= -10. kick= impulse_deltav_hernquist_curvedstream(\ numpy.array([[3.4,0.,0.]]), numpy.array([[4.,0.,0.]]), 3., numpy.array([0.,numpy.pi/2.,0.]), numpy.array([0.,0.,0.]), numpy.array([3.4,0.,0.]), GM,4.) # Note factor of 2 in definition of GM and amp pp= HernquistPotential(amp=2.*GM,a=4.) general_kick= impulse_deltav_general_curvedstream(\ numpy.array([[3.4,0.,0.]]), numpy.array([[4.,0.,0.]]), 3., numpy.array([0.,numpy.pi/2.,0.]), numpy.array([0.,0.,0.]), numpy.array([3.4,0.,0.]), pp) assert numpy.all(numpy.fabs(kick-general_kick) < 10.**tol), 'general kick calculation does not agree with Hernquist calculation for a Hernquist potential, for curved stream' # Same for a bunch of positions GM = numpy.pi v= numpy.zeros((100,3)) v[:,0]= 3.4 xpos= numpy.random.normal(size=100) xpos= numpy.array([xpos,numpy.zeros(100),numpy.zeros(100)]).T kick= impulse_deltav_hernquist_curvedstream(\ v, xpos, 3., numpy.array([0.,numpy.pi/2.,0.]), numpy.array([0.,0.,0.]), numpy.array([3.4,0.,0.]), GM,numpy.exp(1.)) pp= HernquistPotential(amp=2.*GM,a=numpy.exp(1.)) general_kick=\ impulse_deltav_general_curvedstream(\ v, xpos, 3., numpy.array([0.,numpy.pi/2.,0.]), numpy.array([0.,0.,0.]), numpy.array([3.4,0.,0.]), pp) assert numpy.all(numpy.fabs(kick-general_kick) < 10.**tol), 'general kick calculation does not agree with Hernquist calculation for a Hernquist potential, for curved stream' return None
def setup_class(cls): """Setup fixtures for testing.""" super().setup_class() # make potential cls.mass = 1e12 * u.solMass hernquist_pot = HernquistPotential(amp=2 * cls.mass) hernquist_pot.turn_physical_on() # force units cls.potential = hernquist_pot cls.df = isotropicHernquistdf(hernquist_pot) cls.df.turn_physical_on() cls.inst = cls.obj(GalpyPotentialWrapper(cls.potential))
def get_halo_potentials(masses, mass_definition, concentration_at_8=18.0, physical_off=False): halo_potentials = [] for m in masses: if mass_definition == 'HERNQUIST': c = sample_concentration_herquist(m, concentration_at_8) pot = HernquistPotential(amp=0.5 * m * apu.solMass, a=c * apu.kpc) elif mass_definition == 'NFW': c = sample_concentration_nfw(m, concentration_at_8) pot = NFWPotential(mvir=m / 10**12, conc=c) else: raise Exception('mass definition must be HERNQUIST or NFW') if physical_off: galpy.potential.turn_physical_off(pot) halo_potentials.append(pot) return halo_potentials
def render_subhalos(mlow, mhigh, f_sub, log_slope, m_host, via_lactea_kde, c8, galactic_potential, global_potential_extension, time_Gyr, mdef='HERNQUIST', dr_max=8, pass_through_disk_limit=3): N_halos = normalization(f_sub, log_slope, m_host, mlow, mhigh) sample_orbits_0 = generate_sample_orbits_kde(N_halos, via_lactea_kde, galactic_potential, time_Gyr) # print('generated ' + str(N_halos) + ' halos... ') rs_host, r_core = 25, 25. args, func = (rs_host, r_core), core_nfw_pdf inds_keep = filter_orbits_NFW(sample_orbits_0, time_Gyr, func, args) sample_orbits_1 = [sample_orbits_0[idx] for idx in inds_keep] nearby_orbits_1_inds, _ = passed_near_solar_neighorhood( sample_orbits_1, time_Gyr, global_potential_extension, R_solar=8, dr_max=dr_max, pass_through_disk_limit=pass_through_disk_limit, tdep=True) nearby_orbits_1 = [sample_orbits_0[idx] for idx in nearby_orbits_1_inds] n_nearby_1 = len(nearby_orbits_1) halo_masses_1 = sample_mass_function(n_nearby_1, log_slope, mlow, mhigh) halo_potentials = [] if mdef == 'HERNQUIST': concentrations = sample_concentration_herquist(halo_masses_1, c8) for m, c in zip(halo_masses_1, concentrations): pot = HernquistPotential(amp=0.5 * m * apu.solMass, a=c * apu.kpc) halo_potentials.append(pot) elif mdef == 'NFW': concentrations = sample_concentration_nfw(halo_masses_1, c8) for m, c in zip(halo_masses_1, concentrations): pot = NFWPotential(mvir=m / 10**12, conc=c) halo_potentials.append(pot) subhalo_orbit_list = [] for orb in nearby_orbits_1: orb.turn_physical_off() subhalo_orbit_list.append(orb) return subhalo_orbit_list, halo_potentials
def dwarf_galaxies(names, include_no_data=True, log_mass_mean=8., log_mass_sigma=0.5): # these from Errani et al. 2018 dwarfs = { 'Fornax': 8.9, 'LeoI': 9.3, 'Sculptor': 9.3, 'LeoII': 8.5, 'Sextans': 8.5, 'Carina': 8.6, 'UrsaMinor': 8.9, 'Draco': 9.5, 'CanesVenaticiI': 8.5, 'CraterII': 7., 'LeoT': 9.8, 'Hercules': 7.1, 'BootesI': 6.4, 'LeoIV': 7.2, 'UrsaMajorI': 8.5, 'UrsaMajorII': 9.1, 'CanesVenaticiII': 8.7, 'ComaBerenices': 8.6, 'BootesII': 10.4, 'Willman1': 10.4, 'Segue2': 9., 'Segue1': 9.8, 'LeoV': 7.5, 'LMC': np.log10(2 * 10**11) } dwarf_masses = [] dwarf_names = [] for name in names: if name in dwarfs.keys(): dwarf_masses.append(dwarfs[name]) dwarf_names.append(name) else: if include_no_data: logm = np.random.normal(log_mass_mean, log_mass_sigma) dwarf_masses.append(logm) dwarf_names.append(name) else: print('excluing dwarf ' + name) dwarf_potentials = [] for logm in dwarf_masses: m = 10**logm c = sample_concentration_herquist(m, 17.5) pot = HernquistPotential(amp=0.5 * m * apu.solMass, a=c * apu.kpc) dwarf_potentials.append(pot) return dwarf_potentials, dwarf_names
def obj(x,data,bp,dp,hp): #x=[fd,fh,vc,rs,hdisk] if x[0] > 1. or x[0] < 0.: return numpy.finfo(numpy.dtype(numpy.float64)).max if x[1] > 1. or x[1] < 0.: return numpy.finfo(numpy.dtype(numpy.float64)).max if (1.-x[0]-x[1]) > 1. or (1.-x[0]-x[1]) < 0.: return numpy.finfo(numpy.dtype(numpy.float64)).max if x[2] < 0. or x[3] < 0. or x[4] < 0.: return numpy.finfo(numpy.dtype(numpy.float64)).max if x[2] > 2. or x[3] > 10. or x[4] > 2.: return numpy.finfo(numpy.dtype(numpy.float64)).max if False: #Renormalize potentials, intially normalized to 1./3. each bp= copy.deepcopy(bp) dp= copy.deepcopy(dp) hp= copy.deepcopy(hp) bp._amp*= (1.-x[0]-x[1])**2.*9. dp._amp*= x[0]**2.*9. hp._amp*= x[1]**2.*9. #Re-define disk scale length and halo scale length if _dexp: dp._hr= x[4] else: dp._a= x[4] hp._a= x[3] else: #Set-up bp= HernquistPotential(a=0.6/_REFR0,normalize=1.-x[0]-x[1]) if _dexp: dp= DoubleExponentialDiskPotential(normalize=x[0], hr=x[4], hz=0.3/_REFR0) else: dp= MiyamotoNagaiPotential(normalize=x[0], a=x[4], b=0.3/_REFR0) hp= NFWPotential(normalize=x[1], a=x[3]) #Re-normalize data vcircdata= copy.copy(data) vcircdata[:,1]/= x[2] vcircdata[:,2]/= x[2] #Vcirc chi2 vcmodel= numpy.zeros(vcircdata.shape[0]) for ii in range(vcircdata.shape[0]): vcmodel[ii]= numpy.sqrt(vcircdata[ii,0]\ *numpy.fabs(evaluateRforces(vcircdata[ii,0], 0.,[bp,dp,hp]))) #print vcircdata[:,0], vcmodel chi2= numpy.sum((vcircdata[:,1]-vcmodel)**2./vcircdata[:,2]**2.) #Add scale length measurement chi2+= (x[4]-_diskscale)**2./_diskscaleerr**2. #Add dark matter density at the Solar radius #print hp.dens(1.,0.),_rhodm*x[2]**2. #chi2+= (hp.dens(1.,0.)-_rhodm*x[2]**2.)**2./_rhodmerr**2./x[2]**4. return chi2
def accHernquistfix(x,y,z): x = x/kpctocm y = y/kpctocm z = z/kpctocm r = np.sqrt( x**2 + y**2) pot = HernquistPotential(2.e12*u.M_sun , 30e3*u.pc) az = evaluatezforces(pot,r*u.kpc , z*u.kpc) ar = evaluateRforces(pot,r*u.kpc , z*u.kpc) az = -az*1.e5/(1.e6*3.15e7) ar = ar*1.e5/(1.e6*3.15e7) ax = -ar*x/r ay = -ar*y/r return ax,ay,az
def setup_class(cls): """Setup fixtures for testing.""" # make potential cls.mass = 1e12 * u.solMass hernquist_pot = HernquistPotential(amp=2 * cls.mass) hernquist_pot.turn_physical_on() # force units cls.potential = hernquist_pot nx = ny = nz = 76 # must be int and even nxr0 = nyr0 = nzr0 = 2.3 * 2 X, Y, Z = np.array( np.meshgrid( np.linspace(-nxr0 / 2, nxr0 / 2, nx), np.linspace(-nyr0 / 2, nyr0 / 2, ny), np.linspace(-nzr0 / 2, nzr0 / 2, nz), indexing="ij", ), ) XYZ = coord.CartesianRepresentation(X, Y, Z, unit=u.kpc) cls.meshgrid = XYZ cls.inst = cls.obj(cls.potential, meshgrid=cls.meshgrid)
def MWPotential(Ms=0.76, rs=24.8, c=1., T=True): ''' Milky Way potential from Marchetti 2017b -- see galpy for the definitions of the potential components Parameters ---------- Ms : float NFW profile scale mass in units of e12 Msun rs : float Radial profile in units of kpc c : float Axis ratio T : bool If True, use triaxialNFWPotential ''' # NFW profile Ms = Ms * 1e12 * u.Msun rs = rs * u.kpc #Disk Md = 1e11 * u.Msun ad = 6.5 * u.kpc bd = 260. * u.pc #Bulge Mb = 3.4 * 1e10 * u.Msun Rb = 0.7 * u.kpc #BH mass in 1e6 Msun Mbh = 4e6 * u.Msun if (T): halop = TriaxialNFWPotential(amp=Ms, a=rs, c=c, normalize=False) else: halop = NFWPotential(amp=Ms, a=rs, normalize=False) diskp = MiyamotoNagaiPotential(amp=Md, a=ad, b=bd, normalize=False) bulgep = HernquistPotential( amp=2 * Mb, a=Rb, normalize=False) #Factor 2 because of the galpy definition bh = KeplerPotential(amp=Mbh, normalize=False) return [halop, diskp, bulgep, bh]
def test_actionAngleTorus_basic_freqs(): from galpy.actionAngle import actionAngleTorus from galpy.potential import epifreq, omegac, verticalfreq, rl, \ JaffePotential, PowerSphericalPotential, HernquistPotential tol= -3. jr= 10.**-6. jz= 10.**-6. jp= JaffePotential(normalize=1.) aAT= actionAngleTorus(pot=jp) # at Lz=1 jphi= 1. om= aAT.Freqs(jr,jphi,jz) assert numpy.fabs((om[0]-epifreq(jp,rl(jp,jphi)))/om[0]) < 10.**tol, \ 'Close-to-circular orbit does not have Or=kappa for actionAngleTorus' assert numpy.fabs((om[1]-omegac(jp,rl(jp,jphi)))/om[1]) < 10.**tol, \ 'Close-to-circular orbit does not have Ophi=omega for actionAngleTorus' assert numpy.fabs((om[2]-verticalfreq(jp,rl(jp,jphi)))/om[2]) < 10.**tol, \ 'Close-to-circular orbit does not have Oz=nu for actionAngleTorus' # at Lz=1.5, w/ different potential pp= PowerSphericalPotential(normalize=1.) aAT= actionAngleTorus(pot=pp) jphi= 1.5 om= aAT.Freqs(jr,jphi,jz) assert numpy.fabs((om[0]-epifreq(pp,rl(pp,jphi)))/om[0]) < 10.**tol, \ 'Close-to-circular orbit does not have Or=kappa for actionAngleTorus' assert numpy.fabs((om[1]-omegac(pp,rl(pp,jphi)))/om[1]) < 10.**tol, \ 'Close-to-circular orbit does not have Ophi=omega for actionAngleTorus' assert numpy.fabs((om[2]-verticalfreq(pp,rl(pp,jphi)))/om[2]) < 10.**tol, \ 'Close-to-circular orbit does not have Oz=nu for actionAngleTorus' # at Lz=0.5, w/ different potential tol= -2.5 # appears more difficult hp= HernquistPotential(normalize=1.) aAT= actionAngleTorus(pot=hp) jphi= 0.5 om= aAT.Freqs(jr,jphi,jz) assert numpy.fabs((om[0]-epifreq(hp,rl(hp,jphi)))/om[0]) < 10.**tol, \ 'Close-to-circular orbit does not have Or=kappa for actionAngleTorus' assert numpy.fabs((om[1]-omegac(hp,rl(hp,jphi)))/om[1]) < 10.**tol, \ 'Close-to-circular orbit does not have Ophi=omega for actionAngleTorus' assert numpy.fabs((om[2]-verticalfreq(hp,rl(hp,jphi)))/om[2]) < 10.**tol, \ 'Close-to-circular orbit does not have Oz=nu for actionAngleTorus' return None
def calcj(rotcurve): if rotcurve == 'flat': savefilename = 'myjs.sav' elif rotcurve == 'power': savefilename = 'myjs_power.sav' if os.path.exists(savefilename): savefile = open(savefilename, 'rb') myjr = pickle.load(savefile) myjp = pickle.load(savefile) mywr = pickle.load(savefile) mywp = pickle.load(savefile) mye = pickle.load(savefile) myzmax = pickle.load(savefile) e = pickle.load(savefile) zmax = pickle.load(savefile) savefile.close() else: dialect = csv.excel dialect.skipinitialspace = True reader = csv.reader(open('../data/gcs.tsv', 'r'), delimiter='|', dialect=dialect) vxvs = [] es = [] zmaxs = [] for row in reader: if row[0][0] == '#': continue thisra = row[0] thisdec = row[1] thisd = read_float(row[2]) / 1000. if thisd > 0.2: continue thisu = read_float(row[3]) thisv = read_float(row[4]) thisw = read_float(row[5]) thise = read_float(row[6]) thiszmax = read_float(row[7]) if thisd == -9999 or thisu == -9999 or thisv == -9999 or thisw == -9999: continue vxvs.append([ hms_to_rad(thisra), dms_to_rad(thisdec), thisd, thisu, thisv, thisw ]) es.append(thise) zmaxs.append(thiszmax) vxvv = nu.array(vxvs) e = nu.array(es) zmax = nu.array(zmaxs) #Define potential lp = LogarithmicHaloPotential(normalize=1.) pp = PowerSphericalPotential(normalize=1., alpha=-2.) mp = MiyamotoNagaiPotential(a=0.5, b=0.0375, amp=1., normalize=.6) np = NFWPotential(a=4.5, normalize=.35) hp = HernquistPotential(a=0.6 / 8, normalize=0.05) ts = nu.linspace(0., 20., 10000) myjr = nu.zeros(len(e)) myjp = nu.zeros(len(e)) mywr = nu.zeros(len(e)) mywp = nu.zeros(len(e)) mye = nu.zeros(len(e)) myzmax = nu.zeros(len(e)) for ii in range(len(e)): #Integrate the orbit o = Orbit(vxvv[ii, :], radec=True, uvw=True, vo=220., ro=8.) #o.integrate(ts,[mp,np,hp]) if rotcurve == 'flat': o.integrate(ts, lp) mye[ii] = o.e() myzmax[ii] = o.zmax() * 8. print e[ii], mye[ii], zmax[ii], myzmax[ii] o = o.toPlanar() myjr[ii] = o.jr(lp)[0] else: o = o.toPlanar() myjr[ii] = o.jr(pp)[0] myjp[ii] = o.jp()[0] mywr[ii] = o.wr()[0] mywp[ii] = o.wp() #Save savefile = open(savefilename, 'wb') pickle.dump(myjr, savefile) pickle.dump(myjp, savefile) pickle.dump(mywr, savefile) pickle.dump(mywp, savefile) pickle.dump(mye, savefile) pickle.dump(myzmax, savefile) pickle.dump(e, savefile) pickle.dump(zmax, savefile) savefile.close() #plot if rotcurve == 'flat': plot.bovy_print() plot.bovy_plot(nu.array([0., 1.]), nu.array([0., 1.]), 'k-', xlabel=r'$\mathrm{Holmberg\ et\ al.}\ e$', ylabel=r'$\mathrm{galpy}\ e$') plot.bovy_plot(e, mye, 'k,', overplot=True) plot.bovy_end_print('myee.png') plot.bovy_print() plot.bovy_plot( nu.array([0., 2.5]), nu.array([0., 2.5]), 'k-', xlabel=r'$\mathrm{Holmberg\ et\ al.}\ z_{\mathrm{max}}$', ylabel=r'$\mathrm{galpy}\ z_{\mathrm{max}}$') plot.bovy_plot(zmax, myzmax, 'k,', overplot=True) plot.bovy_end_print('myzmaxzmax.png') plot.bovy_print() plot.bovy_plot(myjp, myjr / 2. / nu.pi, 'k,', xlabel=r'$J_{\phi}$', ylabel=r'$J_R/2\pi$', xrange=[0.7, 1.3], yrange=[0., 0.05]) if rotcurve == 'flat': plot.bovy_end_print('jrjp.png') else: plot.bovy_end_print('jrjp_power.png')
def calc_es(): savefilename= 'myes.sav' if os.path.exists(savefilename): savefile= open(savefilename,'rb') mye= pickle.load(savefile) e= pickle.load(savefile) savefile.close() else: #Read data dialect= csv.excel dialect.skipinitialspace=True reader= csv.reader(open('../data/Dierickx-etal-tab2.txt','r'),delimiter=' ',dialect=dialect) vxvs= [] es= [] vphis= [] vxs= [] vys= [] vzs= [] ls= [] for row in reader: thisra= float(row[3]) thisdec= float(row[4]) thisd= float(row[17])/1000. thispmra= float(row[13]) thispmdec= float(row[15]) thisvlos= float(row[11]) thise= float(row[26]) vxvs.append([thisra,thisdec,thisd,thispmra,thispmdec,thisvlos]) es.append(thise) vphis.append(float(row[25])) vxs.append(float(row[19])) vys.append(float(row[21])) vzs.append(float(row[23])) ls.append(float(row[5])) vxvv= nu.array(vxvs) e= nu.array(es) vphi= nu.array(vphis) vx= nu.array(vxs) vy= nu.array(vys) vz= nu.array(vzs) l= nu.array(ls) #Define potential lp= LogarithmicHaloPotential(normalize=1.) mp= MiyamotoNagaiPotential(a=0.5,b=0.0375,amp=1.,normalize=.6) np= NFWPotential(a=4.5,normalize=.35) hp= HernquistPotential(a=0.6/8,normalize=0.05) ts= nu.linspace(0.,20.,10000) mye= nu.zeros(len(e)) for ii in range(len(e)): #Integrate the orbit o= Orbit(vxvv[ii,:],radec=True,vo=220.,ro=8.) o.integrate(ts,lp) mye[ii]= o.e() #Save savefile= open(savefilename,'wb') pickle.dump(mye,savefile) pickle.dump(e,savefile) savefile.close() #plot plot.print() plot.plot(nu.array([0.,1.]),nu.array([0.,1.]),'k-', xlabel=r'$\mathrm{Dierickx\ et\ al.}\ e$', ylabel=r'$\mathrm{galpy}\ e$') plot.plot(e,mye,'k,',overplot=True) plot.end_print('myee.png') plot.print() plot.hist(e,bins=30,xlabel=r'$\mathrm{Dierickx\ et\ al.}\ e$') plot.end_print('ehist.png') plot.print() plot.hist(mye,bins=30,xlabel=r'$\mathrm{galpy}\ e$') plot.end_print('myehist.png')
def bulgemass(out): bp= HernquistPotential(a=0.6/_REFR0,normalize=1.-out[0]-out[1]) return integrate.quad((lambda x: bp.dens(x,0.)*x**2.),0.,250./_REFR0)[0]*4.*numpy.pi*_convertmass/out[2]**2.
def test_physical_compatible_combos(): # Test that physical_compatible acts as expected for combinations of # different types of objects from galpy.util.bovy_conversion import physical_compatible from galpy.potential import HernquistPotential from galpy.orbit import Orbit from galpy.actionAngle import actionAngleSpherical from galpy.df import quasiisothermaldf # Set up different objects for possible cases # Potentials pot_default_phys = HernquistPotential(amp=0.55, a=2., ro=8., vo=220.) pot_nonstandardro = HernquistPotential(amp=0.55, a=2., ro=9., vo=220.) pot_nonstandardvo = HernquistPotential(amp=0.55, a=2., ro=8., vo=230.) pot_nonstandardrovo = HernquistPotential(amp=0.55, a=2., ro=9., vo=230.) pot_nophys = HernquistPotential(amp=0.55) pot_default_noro = HernquistPotential(amp=0.55, vo=220.) pot_default_novo = HernquistPotential(amp=0.55, ro=8.) pot_nonstandardro_novo = HernquistPotential(amp=0.55, ro=9.) pot_nonstandardvo_noro = HernquistPotential(amp=0.55, vo=230.) pot_nonstandardvo_noro = HernquistPotential(amp=0.55, vo=230.) # Orbits orb_default_phys = Orbit([1., 0.1, 1.1, 0.1, 0.3, -0.9], ro=8., vo=220.) orb_nonstandardro = Orbit([1., 0.1, 1.1, 0.1, 0.3, -0.9], ro=9., vo=220.) orb_nonstandardvo = Orbit([1., 0.1, 1.1, 0.1, 0.3, -0.9], ro=8., vo=230.) orb_nonstandardrovo = Orbit([1., 0.1, 1.1, 0.1, 0.3, -0.9], ro=9., vo=230.) orb_nophys = Orbit([1., 0.1, 1.1, 0.1, 0.3, -0.9]) orb_default_noro = Orbit([1., 0.1, 1.1, 0.1, 0.3, -0.9], vo=220.) orb_nonstandardvo_noro = Orbit([1., 0.1, 1.1, 0.1, 0.3, -0.9], vo=230.) # aAs aA_default_phys = actionAngleSpherical(pot=pot_default_phys, ro=8., vo=220.) aA_nonstandardro = actionAngleSpherical(pot=pot_nonstandardro, ro=9., vo=220.) aA_nonstandardvo = actionAngleSpherical(pot=pot_nonstandardvo, ro=8., vo=230.) aA_nonstandardrovo = actionAngleSpherical(pot=pot_nonstandardrovo, ro=9., vo=230.) aA_nophys = actionAngleSpherical(pot=pot_nophys) aA_default_novo = actionAngleSpherical(pot=pot_default_novo, ro=8.) aA_nonstandardvo_noro = actionAngleSpherical(pot=pot_nonstandardvo_noro, vo=230.) # DFs qdf_default_phys = quasiisothermaldf(1. / 3., 0.2, 0.1, 1., 1., pot=pot_default_phys, aA=aA_default_phys, ro=8., vo=220.) qdf_nonstandardro = quasiisothermaldf(1. / 3., 0.2, 0.1, 1., 1., pot=pot_nonstandardro, aA=aA_nonstandardro, ro=9., vo=220.) qdf_nonstandardvo = quasiisothermaldf(1. / 3., 0.2, 0.1, 1., 1., pot=pot_nonstandardvo, aA=aA_nonstandardvo, ro=8., vo=230.) qdf_nonstandardrovo = quasiisothermaldf(1. / 3., 0.2, 0.1, 1., 1., pot=pot_nonstandardrovo, aA=aA_nonstandardrovo, ro=9., vo=230.) qdf_nophys = quasiisothermaldf(1. / 3., 0.2, 0.1, 1., 1., pot=pot_nophys, aA=aA_nophys) # Now do some tests! assert physical_compatible(pot_default_phys,orb_default_phys), \ "pot_default_phys does not behave as expected for combinations of different objects" assert physical_compatible(pot_default_phys,aA_default_phys), \ "pot_default_phys does not behave as expected for combinations of different objects" assert physical_compatible(pot_default_phys,qdf_default_phys), \ "pot_default_phys does not behave as expected for combinations of different objects" assert physical_compatible(pot_nonstandardro,orb_nonstandardro), \ "pot_default_phys does not behave as expected for combinations of different objects" assert physical_compatible(pot_nonstandardro,aA_nonstandardro), \ "pot_default_phys does not behave as expected for combinations of different objects" assert physical_compatible(pot_nonstandardro,qdf_nonstandardro), \ "pot_default_phys does not behave as expected for combinations of different objects" assert not physical_compatible(pot_default_phys,orb_nonstandardro), \ "pot_default_phys does not behave as expected for combinations of different objects" assert not physical_compatible(pot_default_phys,aA_nonstandardro), \ "pot_default_phys does not behave as expected for combinations of different objects" assert not physical_compatible(pot_default_phys,qdf_nonstandardro), \ "pot_default_phys does not behave as expected for combinations of different objects" assert not physical_compatible(pot_default_phys,orb_nonstandardvo), \ "pot_default_phys does not behave as expected for combinations of different objects" assert not physical_compatible(pot_default_phys,aA_nonstandardvo), \ "pot_default_phys does not behave as expected for combinations of different objects" assert not physical_compatible(pot_default_phys,qdf_nonstandardvo), \ "pot_default_phys does not behave as expected for combinations of different objects" assert not physical_compatible(pot_default_phys,orb_nonstandardrovo), \ "pot_default_phys does not behave as expected for combinations of different objects" assert not physical_compatible(pot_default_phys,aA_nonstandardrovo), \ "pot_default_phys does not behave as expected for combinations of different objects" assert not physical_compatible(pot_default_phys,qdf_nonstandardrovo), \ "pot_default_phys does not behave as expected for combinations of different objects" assert physical_compatible([pot_nophys,pot_nophys],orb_nonstandardrovo), \ "pot_default_phys does not behave as expected for combinations of different objects" assert physical_compatible(pot_nophys,aA_nonstandardrovo), \ "pot_default_phys does not behave as expected for combinations of different objects" assert physical_compatible(pot_nophys,qdf_nonstandardrovo), \ "pot_default_phys does not behave as expected for combinations of different objects" assert physical_compatible(pot_nophys,orb_default_phys), \ "pot_default_phys does not behave as expected for combinations of different objects" assert physical_compatible(pot_nophys,aA_default_phys), \ "pot_default_phys does not behave as expected for combinations of different objects" assert physical_compatible(pot_nophys,qdf_default_phys), \ "pot_default_phys does not behave as expected for combinations of different objects" assert physical_compatible(pot_nophys,orb_nophys), \ "pot_default_phys does not behave as expected for combinations of different objects" assert physical_compatible(pot_nophys,orb_nophys), \ "pot_default_phys does not behave as expected for combinations of different objects" assert physical_compatible(pot_nophys,qdf_nophys), \ "pot_default_phys does not behave as expected for combinations of different objects" assert physical_compatible(pot_default_noro,qdf_nonstandardro), \ "pot_default_phys does not behave as expected for combinations of different objects" assert physical_compatible(pot_nonstandardro_novo,orb_default_noro), \ "pot_default_phys does not behave as expected for combinations of different objects" assert physical_compatible(aA_nonstandardvo_noro,orb_nonstandardvo_noro), \ "pot_default_phys does not behave as expected for combinations of different objects" assert not physical_compatible(aA_default_novo,qdf_nonstandardrovo), \ "pot_default_phys does not behave as expected for combinations of different objects" # Also test agained None! assert physical_compatible(None,pot_default_phys), \ "pot_default_phys does not behave as expected for combinations of different objects" assert physical_compatible(None,orb_default_phys), \ "pot_default_phys does not behave as expected for combinations of different objects" assert physical_compatible(None,aA_default_phys), \ "pot_default_phys does not behave as expected for combinations of different objects" assert physical_compatible(None,qdf_default_phys), \ "pot_default_phys does not behave as expected for combinations of different objects" assert physical_compatible(pot_default_phys,None), \ "pot_default_phys does not behave as expected for combinations of different objects" assert physical_compatible(orb_default_phys,None), \ "pot_default_phys does not behave as expected for combinations of different objects" assert physical_compatible(aA_default_phys,None), \ "pot_default_phys does not behave as expected for combinations of different objects" assert physical_compatible(qdf_default_phys,None), \ "pot_default_phys does not behave as expected for combinations of different objects" return None
def test_physical_compatible_potential(): # Test that physical_compatible acts as expected from galpy.util.bovy_conversion import physical_compatible from galpy.potential import HernquistPotential # Set up potentials for all possible cases pot_default_phys = HernquistPotential(amp=0.55, a=2., ro=8., vo=220.) pot_nonstandardro = HernquistPotential(amp=0.55, a=2., ro=9., vo=220.) pot_nonstandardvo = HernquistPotential(amp=0.55, a=2., ro=8., vo=230.) pot_nonstandardrovo = HernquistPotential(amp=0.55, a=2., ro=9., vo=230.) pot_nophys = HernquistPotential(amp=0.55) pot_default_noro = HernquistPotential(amp=0.55, vo=220.) pot_default_novo = HernquistPotential(amp=0.55, ro=8.) pot_nonstandardro_novo = HernquistPotential(amp=0.55, ro=9.) pot_nonstandardvo_noro = HernquistPotential(amp=0.55, vo=230.) # Test expected behavior for single potentials assert physical_compatible(pot_default_phys,pot_default_phys), \ "pot_default_phys does not behave as expected" assert not physical_compatible(pot_default_phys,pot_nonstandardro), \ "pot_default_phys does not behave as expected" assert not physical_compatible(pot_nonstandardro,pot_default_phys), \ "pot_default_phys does not behave as expected" assert not physical_compatible(pot_default_phys,pot_nonstandardvo), \ "pot_default_phys does not behave as expected" assert not physical_compatible(pot_default_phys,pot_nonstandardrovo), \ "pot_default_phys does not behave as expected" assert physical_compatible(pot_default_phys,pot_nophys), \ "pot_default_phys does not behave as expected" assert physical_compatible(pot_default_phys,pot_default_noro), \ "pot_default_phys does not behave as expected" assert physical_compatible(pot_default_phys,pot_default_novo), \ "pot_default_phys does not behave as expected" assert not physical_compatible(pot_default_phys,pot_nonstandardro_novo), \ "pot_default_phys does not behave as expected" assert not physical_compatible(pot_default_phys,pot_nonstandardvo_noro), \ "pot_default_phys does not behave as expected" # Test expected behavior for single,list pairs assert physical_compatible(pot_default_phys, [pot_default_phys,pot_default_phys]), \ "pot_default_phys does not behave as expected" assert not physical_compatible(pot_default_phys, [pot_nonstandardro,pot_nonstandardro]), \ "pot_default_phys does not behave as expected" assert not physical_compatible(pot_default_phys, [pot_nonstandardro,pot_default_phys]), \ "pot_default_phys does not behave as expected" assert not physical_compatible(pot_nonstandardro, [pot_default_phys,pot_default_phys]), \ "pot_default_phys does not behave as expected" assert not physical_compatible(pot_default_phys, [pot_nonstandardvo,pot_default_phys]), \ "pot_default_phys does not behave as expected" assert not physical_compatible(pot_default_phys, [pot_nonstandardrovo,pot_nonstandardro]), \ "pot_default_phys does not behave as expected" assert physical_compatible(pot_default_phys, [pot_nophys,pot_nophys]), \ "pot_default_phys does not behave as expected" assert physical_compatible(pot_default_phys, [pot_default_noro,pot_default_phys]), \ "pot_default_phys does not behave as expected" assert physical_compatible(pot_default_phys, [pot_default_novo,pot_nophys]), \ "pot_default_phys does not behave as expected" assert not physical_compatible(pot_default_phys, [pot_nonstandardro_novo,pot_nophys]), \ "pot_default_phys does not behave as expected" assert not physical_compatible(pot_default_phys, [pot_nonstandardvo_noro,pot_nophys]), \ "pot_default_phys does not behave as expected" # Test expected behavior for list,list pairs assert physical_compatible([pot_default_phys,pot_default_phys], [pot_default_phys,pot_default_phys]), \ "pot_default_phys does not behave as expected" assert not physical_compatible([pot_default_phys,pot_default_phys], [pot_nonstandardro,pot_nonstandardro]), \ "pot_default_phys does not behave as expected" assert not physical_compatible([pot_default_phys,pot_default_phys], [pot_nonstandardro,pot_default_phys]), \ "pot_default_phys does not behave as expected" assert not physical_compatible([pot_nonstandardro,pot_default_phys], [pot_default_phys,pot_default_phys]), \ "pot_default_phys does not behave as expected" assert not physical_compatible([pot_default_phys,pot_default_phys], [pot_nonstandardvo,pot_default_phys]), \ "pot_default_phys does not behave as expected" assert not physical_compatible([pot_default_phys,pot_default_phys], [pot_nonstandardrovo,pot_nonstandardro]), \ "pot_default_phys does not behave as expected" assert physical_compatible([pot_default_phys,pot_default_phys], [pot_nophys,pot_nophys]), \ "pot_default_phys does not behave as expected" assert physical_compatible([pot_default_phys,pot_default_phys], [pot_default_noro,pot_default_phys]), \ "pot_default_phys does not behave as expected" assert physical_compatible([pot_default_phys,pot_default_phys], [pot_default_novo,pot_nophys]), \ "pot_default_phys does not behave as expected" assert not physical_compatible([pot_default_phys,pot_default_phys], [pot_nonstandardro_novo,pot_nophys]), \ "pot_default_phys does not behave as expected" assert not physical_compatible([pot_default_phys,pot_default_phys], [pot_nonstandardvo_noro,pot_nophys]), \ "pot_default_phys does not behave as expected" return None
def single_iteration(samples, tabulated_potential, kde_instance, phase_space_res, **kwargs): try: potential_local = tabulated_potential.evaluate(samples['rho_nfw'], samples['rho_midplane']) except: # prior sampled out of bounds # print('out of bounds: ', samples['nfw_norm'], samples['disk_norm']) return None, None, None keywords = [ 'rho_midplane', 'rho_midplane', 'log_sag_mass_DM', 'sag_mass2light', 'f_sub', 'log_slope', 'm_host', 'velocity_dispersion_1', 'velocity_dispersion_2', 'velocity_dispersion_3', 'component_amplitude_1', 'component_amplitude_2', 'component_amplitude_3', 'orbit_ra', 'orbit_dec', 'orbit_z', 'orbit_pm_ra', 'orbit_pm_dec', 'orbit_vlos', 'gal_norm', 'c8' ] for kw in keywords: assert kw in samples.keys(), 'did not find ' + str(kw) velocity_dispersion = [samples['velocity_dispersion_1']] component_amplitude = [samples['component_amplitude_1']] if samples['velocity_dispersion_2'] is not None: velocity_dispersion.append(samples['velocity_dispersion_2']) component_amplitude_2 = 1 - component_amplitude[0] component_amplitude.append(component_amplitude_2) assert len(velocity_dispersion) == len(component_amplitude) assert np.sum(component_amplitude) == 1 galactic_potential = sample_galactic_potential(samples['gal_norm']) z_min_max = 2. vmin_max = 100. potential_global = PotentialExtension(galactic_potential, z_min_max, vmin_max, phase_space_res, compute_action_angle=False) if 'include_LMC' in kwargs.keys() and kwargs['include_LMC']: assert 'log_LMC_mass' in samples.keys() LMC_mass = 10**samples['log_LMC_mass'] c = sample_concentration_herquist(LMC_mass, 17.5) LMC_potential = HernquistPotential(amp=0.5 * LMC_mass * apu.solMass, a=c * apu.kpc) lmc_orbit = Orbit.from_name('LMC') lmc_orbit.integrate(time_Gyr, galactic_potential) galactic_potential_for_integrations = galactic_potential + MovingObjectPotential( lmc_orbit, LMC_potential, ro=potential_local.units['ro'], vo=potential_local.units['vo']) else: galactic_potential_for_integrations = galactic_potential subhalo_orbit_list, halo_potentials = [], [] if samples['f_sub'] > 0: mlow, mhigh = kwargs['mlow'], kwargs['mhigh'] print('creating subhalos... ') subhalo_orbit_list, halo_potentials = render_subhalos( mlow, mhigh, samples['f_sub'], samples['log_slope'], samples['m_host'], kde_instance, samples['c8'], galactic_potential_for_integrations, potential_global, time_Gyr, mdef='HERNQUIST', dr_max=10, pass_through_disk_limit=3) dwarf_orbits, dwarf_galaxy_potentials = [], [] if 'include_dwarfs' in kwargs.keys() and kwargs['include_dwarfs']: o = Orbit.from_name('MW satellite galaxies') names = o.name kept_names = [] dwarf_orbits = [] dwarf_masses, dwarf_names = dwarf_galaxies(names) for i, name in enumerate(dwarf_names): o = Orbit.from_name(name) if o.r() < kwargs['r_min_dwarfs'] and name != 'Sgr': o.integrate(time_Gyr, galactic_potential_for_integrations) o.turn_physical_off() dwarf_orbits += [o] kept_names.append(name) dwarf_galaxy_potentials, _ = dwarf_galaxies(kept_names, include_no_data=True, log_mass_mean=8, log_mass_sigma=0.5) ####################################### Integrate orbit of Sag. ################################# orbit_init_sag = [ samples['orbit_ra'] * apu.deg, samples['orbit_dec'] * apu.deg, samples['orbit_z'] * apu.kpc, samples['orbit_pm_ra'] * apu.mas / apu.yr, samples['orbit_pm_dec'] * apu.mas / apu.yr, samples['orbit_vlos'] * apu.km / apu.s ] sag_orbit_phsical_off = integrate_orbit( orbit_init_sag, galactic_potential_for_integrations, time_Gyr) sag_orbit = [sag_orbit_phsical_off] ####################################################################################################### ####################################### Set Sag. properties ######################################## m_sag_dm = 10**samples['log_sag_mass_DM'] m_sag_stellar = m_sag_dm / samples['sag_mass2light'] a_sag = 3 * (m_sag_dm / 10**10)**1. / 3 a_stellar = 1.5 * (m_sag_stellar / 10**9)**1. / 3 sag_potential_1 = galpy.potential.HernquistPotential(amp=m_sag_dm * apu.M_sun, a=a_sag * apu.kpc) sag_potential_2 = galpy.potential.HernquistPotential(amp=m_sag_stellar * apu.M_sun, a=a_stellar * apu.kpc) sag_potential = [sag_potential_1 + sag_potential_2] galpy.potential.turn_physical_off(sag_potential) ####################################################################################################### ############################# Compute distribution function ############################################ disc = Disc(potential_local, potential_global) time_internal_units = sag_orbit_phsical_off.time() perturber_orbits = sag_orbit + subhalo_orbit_list + dwarf_orbits perturber_potentials = sag_potential + halo_potentials + dwarf_galaxy_potentials dF, delta_J, force = compute_df(disc, time_internal_units, perturber_orbits, perturber_potentials, velocity_dispersion, component_amplitude, verbose=False) asymmetry, mean_vz, density = dF.A, dF.mean_v_relative, dF.density # import matplotlib.pyplot as plt # plt.plot(asymmetry, color='k') return asymmetry, mean_vz, density
import galpy from galpy.potential import HernquistPotential from galpy.potential import LogarithmicHaloPotential from galpy.potential import MiyamotoNagaiPotential from .mwahpy_glob import G #=============================================================================== # CONSTANTS #=============================================================================== m_bulge = 3.4e10*u.solMass #solar masses m_disk = 1.0e11*u.solMass v_halo = 74.61*u.km/u.s #km/s pot_bulge = HernquistPotential(amp=2*m_bulge, a=0.7*u.kpc, ro=8., vo=220.) pot_disk = MiyamotoNagaiPotential(amp=G*m_disk, a=6.5*u.kpc, b=0.26*u.kpc, ro=8., vo=220.) pot_halo = LogarithmicHaloPotential(amp=2*v_halo**2, q=1., core=12.0*u.kpc, ro=8., vo=220.) #this potential is from Newberg et al. 2010, Orphan Stream Model 5. It's basically Law 2005 mwahpy_default_pot = [pot_bulge, pot_disk, pot_halo] energy_offset = -60000 #adjusts the energy to be consistent with Donlon et al. 2019 #=============================================================================== # FUNCTIONS #=============================================================================== #produces a rotation curve for the given potential def plot_potential(potential, Rrange=[0.01,10.]): fig = plt.figure(figsize=(12,8))
def fitMass(): #Read data vcircdata= numpy.loadtxt('vcirc.txt',comments='#',delimiter='|') vcircdata[:,0]/= _REFR0 vcircdata[:,1]/= _REFV0 vcircdata[:,2]/= _REFV0 #Set-up bp= HernquistPotential(a=0.6/_REFR0,normalize=1./3.) if _dexp: dp= DoubleExponentialDiskPotential(normalize=1./3., hr=3.25/_REFR0, hz=0.3/_REFR0) else: dp= MiyamotoNagaiPotential(normalize=1./3., a=3.25/_REFR0, b=0.3/_REFR0) hp= NFWPotential(normalize=1./3., a=5./_REFR0) init= numpy.array([0.6,0.35,218./_REFV0,15./_REFR0,3.25/_REFR0]) #print _convertrho out= optimize.fmin_powell(obj,init,args=(vcircdata,bp,dp,hp), callback=cb) print out #Calculate mass #Halo mass halo= halomass(out) bulge= halomass(out) disk= diskmass(out) print halo, disk, bulge, totalmass(out) #Sample samples= bovy_mcmc.markovpy(out,0.05, (lambda x: -obj(x,vcircdata,bp,dp,hp)), (), isDomainFinite=[[True,True], [True,True], [True,True], [True,True], [True,True]], domain=[[0.,1.], [0.,1.], [0.,2.], [0.,10.], [0.,2.]], nwalkers=8, nsamples=10000) print "Done with sampling ..." print numpy.mean(numpy.array(samples),axis=0) print numpy.std(numpy.array(samples),axis=0) samples= numpy.random.permutation(samples)[0:500] #halo totalmasssamples= [] for s in samples: totalmasssamples.append(halomass(s)) totalmasssamples= numpy.array(totalmasssamples) print "halo mass: ", numpy.mean(totalmasssamples), numpy.std(totalmasssamples) print sixtyeigthinterval(halomass(out),totalmasssamples,quantile=.68) #total totalmasssamples= [] for s in samples: totalmasssamples.append(totalmass(s)) totalmasssamples= numpy.array(totalmasssamples) print "total mass: ", numpy.mean(totalmasssamples), numpy.std(totalmasssamples) print sixtyeigthinterval(totalmass(out),totalmasssamples,quantile=.68) bovy_plot.bovy_print() bovy_plot.bovy_hist(totalmasssamples,bins=16,range=[0.,2.]) bovy_plot.bovy_end_print('totalmass.png') return None #disk totalmasssamples= [] for s in samples: totalmasssamples.append(diskmass(s)) totalmasssamples= numpy.array(totalmasssamples) print "disk mass: ", numpy.mean(totalmasssamples), numpy.std(totalmasssamples) #bulge totalmasssamples= [] for s in samples: totalmasssamples.append(bulgemass(s)) totalmasssamples= numpy.array(totalmasssamples) print "bulge mass: ", numpy.mean(totalmasssamples), numpy.std(totalmasssamples) return None