def jaccmvir(p,logc,logm): dx= 0.001 vo= numpy.exp(p[0]+dx) a= numpy.exp(p[1]) if a > 100. or a < 0.01: return 10000000000000. nfw= potential.NFWPotential(normalize=1.,a=a) try: rvir= nfw._rvir(220.*vo,8.,wrtcrit=True,overdens=96.7) except ValueError: return numpy.nan mvir= nfw.mass(rvir)*bovy_conversion.mass_in_1010msol(220.*vo,8.)/100. c= rvir/a dlogcdp0= (numpy.log10(c)-logc)/dx dlogmdp0= (numpy.log10(mvir)-logm)/dx #Change p1 vo= numpy.exp(p[0]) a= numpy.exp(p[1]+dx) if a > 100. or a < 0.01: return 10000000000000. nfw= potential.NFWPotential(normalize=1.,a=a) try: rvir= nfw._rvir(220.*vo,8.,wrtcrit=True,overdens=96.7) except ValueError: return numpy.nan mvir= nfw.mass(rvir)*bovy_conversion.mass_in_1010msol(220.*vo,8.)/100. c= rvir/a dlogcdp1= (numpy.log10(c)-logc)/dx dlogmdp1= (numpy.log10(mvir)-logm)/dx return numpy.fabs((dlogcdp0*dlogmdp1-dlogcdp1*dlogmdp0))
def chi2(p,wcprior,wmassprior): """chi2 for the Bovy & Rix and Xue et al. measurements""" vo= numpy.exp(p[0]) a= numpy.exp(p[1]) if a > 100. or a < 0.01: return 10000000000000. nfw= potential.NFWPotential(normalize=1.,a=a) try: rvir= nfw._rvir(220.*vo,8.,wrtcrit=True,overdens=96.7) except ValueError: return numpy.nan mvir= nfw.mass(rvir)*bovy_conversion.mass_in_1010msol(220.*vo,8.)/100. c= rvir/a out= 0. if wcprior: out-= -0.5*(numpy.log10(c)-1.051+0.099*numpy.log10(mvir))**2./0.111**2. elif numpy.fabs(numpy.log10(c)-1.051+0.099*numpy.log10(mvir)) > 0.1111*3.: return 10000000000000000. if wmassprior: out-= -0.9*numpy.log10(mvir) mass1= nfw.mass(10./8.)*bovy_conversion.mass_in_1010msol(220.*vo,8.) if _USE_ALL_XUE: out-= -0.5*((mass1-4.5)**2./1.5**2.) for ii in range(len(_XUER)): tmass= nfw.mass(_XUER[ii]/8.)\ *bovy_conversion.mass_in_1010msol(220.*vo,8.) out-= -0.5*((tmass-_XUEMASS[ii])**2./_XUEMASS_ERR[ii]**2.) else: mass2= nfw.mass(60./8.)*bovy_conversion.mass_in_1010msol(220.*vo,8.) out-= -0.5*((mass1-4.5)**2./1.5**2.+(mass2-35)**2./7.**2.) #Jacobian out-= numpy.log(jaccmvir(p,numpy.log10(c),numpy.log10(mvir))) return out
def mass60(pot,options): """The mass at 60 kpc in 10^11 msolar""" tR= 60./_REFR0 #For the MN potential, we just assume that all of its mass is enclosed within 60 kpc, even though this isn't technically correct (but it's WRONG) if options.twodisks: return (pot[0].mass(tR)+pot[3].mass(tR)+pot[1]._amp+pot[2]._amp)\ *bovy_conversion.mass_in_1010msol(_REFV0,_REFR0)/10. else: return (pot[0].mass(tR)+pot[2].mass(tR)+pot[1]._amp)\ *bovy_conversion.mass_in_1010msol(_REFV0,_REFR0)/10.
def _conc_opt(p, m10, mvir): vo = numpy.exp(p[0]) a = numpy.exp(p[1]) nfw = potential.NFWPotential(normalize=1.0, a=a) try: rvir = nfw._rvir(220.0 * vo, 8.0, wrtcrit=True, overdens=96.7) except ValueError: return numpy.nan mass1 = nfw.mass(10.0 / 8.0) * bovy_conversion.mass_in_1010msol(220.0 * vo, 8.0) mass2 = nfw.mass(rvir) * bovy_conversion.mass_in_1010msol(220.0 * vo, 8.0) / 100.0 return 0.5 * ((mass1 - m10) ** 2.0 + (mass2 - mvir) ** 2.0)
def test_mass_in_1010msol(): #Test the scaling, should be velocity^2 x position vofid, rofid = 200., 8. assert numpy.fabs( 4. * bovy_conversion.mass_in_1010msol(vofid, rofid) / bovy_conversion.mass_in_1010msol(2. * vofid, rofid) - 1.) < 10.**-10., 'mass_in_1010msol did not work as expected' assert numpy.fabs( 2. * bovy_conversion.mass_in_1010msol(vofid, rofid) / bovy_conversion.mass_in_1010msol(vofid, 2 * rofid) - 1.) < 10.**-10., 'mass_in_1010msol 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 mass60(pot,_REFR0,_REFV0): """The mass at 60 kpc in 10^11 msolar""" tR= 60./_REFR0 # Average r^2 FR/G return -integrate.quad(lambda x: tR**2.*potential.evaluaterforces(pot,tR*x,tR*numpy.sqrt(1.-x**2.),phi=0.), 0.,1.)[0]\ *bovy_conversion.mass_in_1010msol(_REFV0,_REFR0)/10.
def test_trailingwleadingimpact_error(): #Imports from galpy.df import streamgapdf from galpy.orbit import Orbit from galpy.potential import LogarithmicHaloPotential from galpy.actionAngle import actionAngleIsochroneApprox from galpy.util import bovy_conversion #for unit conversions lp= LogarithmicHaloPotential(normalize=1.,q=0.9) aAI= actionAngleIsochroneApprox(pot=lp,b=0.8) prog_unp_peri= Orbit([2.6556151742081835, 0.2183747276300308, 0.67876510797240575, -2.0143395648974671, -0.3273737682604374, 0.24218273922966019]) V0, R0= 220., 8. sigv= 0.365*(10./2.)**(1./3.) # km/s dum= streamgapdf(sigv/V0,progenitor=prog_unp_peri,pot=lp,aA=aAI, leading=False,nTrackChunks=26, nTrackIterations=1, sigMeanOffset=4.5, tdisrupt=10.88\ /bovy_conversion.time_in_Gyr(V0,R0), Vnorm=V0,Rnorm=R0, impactb=0., subhalovel=numpy.array([6.82200571,132.7700529, 149.4174464])/V0, timpact=0.88/bovy_conversion.time_in_Gyr(V0,R0), impact_angle=2.34, GM=10.**-2.\ /bovy_conversion.mass_in_1010msol(V0,R0), rs=0.625/R0) return None
def mvir(p): vo= numpy.exp(p[0]) a= numpy.exp(p[1]) nfw= potential.NFWPotential(normalize=1.,a=a) try: rvir= nfw._rvir(220.*vo,8.,wrtcrit=True,overdens=96.7) except ValueError: return numpy.nan return nfw.mass(rvir)*bovy_conversion.mass_in_1010msol(220.*vo,8.)/100.
def setup_phxmodel(leading=False, timpact=None, hernquist=True, age=1.5, singleImpact=False, length_factor=1., obs = obs, sigvmod = .23, progIsTrack=False, **kwargs): #obs= Orbit([229.018,-0.124,23.2,-2.296,-2.257,-58.7], # radec=True,ro=R0,vo=V0, # solarmotion=[-11.1,24.,7.25]) aAI= actionAngleIsochroneApprox(pot=MWPotential2014,b=0.8458) sigv= sigvmod*(5./age) #km/s, adjust for diff. age if timpact is None: sdf= streamdf(sigv/V0,progenitor=obs, pot=MWPotential2014,aA=aAI, leading=leading,nTrackChunks=11, progIsTrack=progIsTrack, tdisrupt=age/bovy_conversion.time_in_Gyr(V0,R0), ro=R0,vo=V0,R0=R0, vsun=[-11.1,V0+24.,7.25],**kwargs) elif singleImpact: sdf= streamgapdf(sigv/V0,progenitor=obs, pot=MWPotential2014,aA=aAI, leading=leading,nTrackChunks=11, tdisrupt=age/bovy_conversion.time_in_Gyr(V0,R0), ro=R0,vo=V0,R0=R0, vsun=[-11.1,V0+24.,7.25], timpact= 0.3/bovy_conversion.time_in_Gyr(V0,R0), spline_order=3, hernquist=hernquist, impact_angle=0.7, impactb=0., GM= 10.**-2./bovy_conversion.mass_in_1010msol(V0,R0), rs= 0.625/R0, subhalovel=np.array([6.82200571,132.7700529,14.4174464])/V0, **kwargs) else: sdf= streampepperdf(sigv/V0,progenitor=obs, pot=MWPotential2014,aA=aAI, leading=leading,nTrackChunks=101, tdisrupt=age/bovy_conversion.time_in_Gyr(V0,R0), ro=R0,vo=V0,R0=R0, vsun=[-11.1,V0+24.,7.25], timpact=timpact, spline_order=1, hernquist=hernquist, length_factor=length_factor) sdf.turn_physical_off() return sdf
def sample(stream_config, tail='leading', n=1000, Xrs = 3., plummer=False, rsfac=1., massexp=-2, massrange = [5,9], cutoff = 5., rate=None, ratemod = 1.): sample_GM = lambda: powerlaw_wcutoff(massrange, cutoff) if rate is None: rate_range= np.arange(massrange[0]+0.5, massrange[1]+0.5,1) rate = ratemod*np.sum([dNencdm(stream_config.sdf[tail],10.**r, Xrs=Xrs,plummer=plummer,rsfac=rsfac,sigma=120.) for r in rate_range]) sample_rs= lambda x: rs(x*bovy_conversion.mass_in_1010msol(V0,R0)*10.**10.,plummer=plummer,rsfac=rsfac) stream_config.sdf[tail].simulate(rate=rate,sample_GM=sample_GM,sample_rs=sample_rs, Xrs=Xrs,sigma=120./220.) samples = stream_config.sdf[tail].sample(n=n,lb=True) sc = SkyCoord(samples[0]*u.deg,samples[1]*u.deg,distance=samples[2]*u.kpc,frame='galactic') if hasattr(stream_config,'stream_coord'): sc = sc.transform_to(stream_config.stream_coord) return sc
def mass60(pot: PotentialType, ro: float = REFR0, vo: float = REFV0) -> float: """The mass at 60 kpc in 10^11 msolar. Other Parameters ---------------- ro: float vo: float """ tR = 60.0 / ro # Average r^2 FR/G return (-integrate.quad( lambda x: tR**2.0 * potential.evaluaterforces( pot, tR * x, tR * np.sqrt(1.0 - x**2.0), phi=0.0), 0.0, 1.0, )[0] * bovy_conversion.mass_in_1010msol(vo, ro) / 10.0)
def sp_stream_samples(sp, nsample=10000, lb=True, massexp=-2, GMmod=1., massrange=[6, 9], cutoff=5., ratemod=1., do_sample=False): massexp = massexp sample_GM = lambda: GMmod * powerlaw_wcutoff(massrange, cutoff) rate_range = np.arange(massrange[0] + 0.5, massrange[1] + 0.5, 1) rate = ratemod * np.sum([ dNencdm(sp, 10.**r, Xrs=5., plummer=False, rsfac=1., sigma=120.) for r in rate_range ]) sample_rs = lambda x: rs(x * bovy_conversion.mass_in_1010msol(V0, R0) * 10. **10., plummer=False, rsfac=1.) ns = 0 #print(rate) sp.simulate(rate=rate, sample_GM=sample_GM, sample_rs=sample_rs, Xrs=3., sigma=120. / 220.) if do_sample == True: sp_sample = sp.sample(n=nsample, lb=lb) spc = SkyCoord( \ sp_sample[0]*u.deg, \ sp_sample[1]*u.deg, \ distance=sp_sample[2]*u.kpc, \ radial_velocity=sp_sample[3]*u.km/u.s, \ pm_l_cosb=sp_sample[4]*u.mas/u.yr, \ pm_b=sp_sample[5]*u.mas/u.yr, \ frame='galactic') spphx = spc.transform_to(Phoenix) return sp_sample, spphx, spc
def sp_stream_samples(sp, nsample=10000, lb=True, massexp=-2, GMmod=1., massrange=[6, 9], cutoff=5., ratemod=1., do_sample=False): massexp = massexp sample_GM = lambda: GMmod * powerlaw_wcutoff(massrange, cutoff) rate_range = numpy.arange(massrange[0] + 0.5, massrange[1] + 0.5, 1) rate = ratemod * numpy.sum([ dNencdm(sp, 10.**r, Xrs=5., plummer=False, rsfac=1., sigma=120.) for r in rate_range ]) sample_rs = lambda x: rs(x * bovy_conversion.mass_in_1010msol(V0, R0) * 10. **10., plummer=False, rsfac=1.) ns = 0 print rate sp.simulate(rate=rate, sample_GM=sample_GM, sample_rs=sample_rs, Xrs=3., sigma=120. / 220.) if do_sample == True: sp_sample = sp.sample(n=nsample, lb=lb) spc = SkyCoord(sp_sample[0] * u.deg, sp_sample[1] * u.deg, distance=sp_sample[2] * u.kpc, frame='galactic') spxi = radec_to_pal5xieta(spc.icrs.ra.value, spc.icrs.dec.value, degree=True) return sp_sample, spxi, spc
def create_frames(options,args): # First reload the model with open('gd1pepper%isampling.pkl' % options.nsnap,'rb') as savefile: sdf_pepper_leading= pickle.load(savefile) with open('gd1pepper%isampling_trailing.pkl' % options.nsnap,'rb') as savefile: sdf_pepper_trailing= pickle.load(savefile) # Output times timpacts= sdf_pepper_leading._uniq_timpact # Sample unperturbed aAt numpy.random.seed(1) Oml,anglel,dtl= super(streampepperdf,sdf_pepper_leading)._sample_aAt(\ options.nparticles) Omt,anglet,dtt= super(streampepperdf,sdf_pepper_trailing)._sample_aAt(\ options.nparticles) # Setup progenitor prog= sdf_pepper_leading._progenitor().flip() prog.integrate(numpy.linspace(0.,9./bovy_conversion.time_in_Gyr(V0,R0), 10001),sdf_pepper_leading._pot) prog.flip() # Setup impacts if options.single: # Hit the leading arm and the trailing arm 1 Gyr later m= options.singlemimpact/bovy_conversion.mass_in_1010msol(V0,R0)/1000. t= timpacts[\ numpy.argmin(\ numpy.fabs(\ numpy.array(timpacts)\ -options.singletimpact\ /bovy_conversion.time_in_Gyr(V0,R0)))] sdf_pepper_leading.set_impacts(\ impactb=[0.5*simulate_streampepper.rs(options.singlemimpact*10.**7.)], subhalovel=numpy.array([[-25.,155.,30.]])/V0, impact_angle=[0.2], timpact=[t], GM=[m],rs=[simulate_streampepper.rs(options.singlemimpact*10.**7.)]) # Trailing m= options.singlemimpact/bovy_conversion.mass_in_1010msol(V0,R0)/1000. t= timpacts[\ numpy.argmin(\ numpy.fabs(\ numpy.array(timpacts)\ -(options.singletimpact+1.)\ /bovy_conversion.time_in_Gyr(V0,R0)))] sdf_pepper_trailing.set_impacts(\ impactb=[1.*simulate_streampepper.rs(options.singlemimpact*10.**7.)], subhalovel=numpy.array([[-25.,155.,30.]])/V0, impact_angle=[-0.3], timpact=[t], GM=[m],rs=[simulate_streampepper.rs(options.singlemimpact*10.**7.)]) elif options.pepper: # Sampling functions massrange=[options.Mmin,options.Mmax] plummer= False Xrs= 5. nsubhalo= simulate_streampepper.nsubhalo rs= simulate_streampepper.rs dNencdm= simulate_streampepper.dNencdm sample_GM= lambda: (10.**((-0.5)*massrange[0])\ +(10.**((-0.5)*massrange[1])\ -10.**((-0.5)*massrange[0]))\ *numpy.random.uniform())**(1./(-0.5))\ /bovy_conversion.mass_in_msol(V0,R0) rate_range= numpy.arange(massrange[0]+0.5,massrange[1]+0.5,1) rate= numpy.sum([dNencdm(sdf_pepper_leading,10.**r,Xrs=Xrs, plummer=plummer) for r in rate_range]) rate= options.timescdm*rate sample_rs= lambda x: rs(x*bovy_conversion.mass_in_1010msol(V0,R0)*10.**10., plummer=plummer) # Pepper both sdf_pepper_leading.simulate(rate=rate,sample_GM=sample_GM, sample_rs=sample_rs,Xrs=Xrs) print numpy.amax(sdf_pepper_leading._GM)*bovy_conversion.mass_in_1010msol(V0,R0) sdf_pepper_trailing.simulate(rate=rate,sample_GM=sample_GM, sample_rs=sample_rs,Xrs=Xrs) print numpy.amax(sdf_pepper_trailing._GM)*bovy_conversion.mass_in_1010msol(V0,R0) else: # Hit both with zero sdf_pepper_leading.set_impacts(\ impactb=[0.], subhalovel=numpy.array([[-25.,155.,30.]])/V0, impact_angle=[0.2], timpact=[timpacts[0]], GM=[0.],rs=[1.]) sdf_pepper_trailing.set_impacts(\ impactb=[0.], subhalovel=numpy.array([[-25.,155.,30.]])/V0, impact_angle=[-0.2], timpact=[timpacts[0]], GM=[0.],rs=[1.]) # Now make all frames dum= multi.parallel_map( (lambda x: _plot_one_frame(x,options,prog,timpacts, sdf_pepper_leading,sdf_pepper_trailing, Oml,Omt,anglel,anglet,dtl,dtt)), range(len(timpacts)), numcores=numpy.amin([len(timpacts),30])) return None
def pal5_abc(sdf_pepper, options): """ """ # Setup apar grid bins = np.linspace(options.ximin, options.ximax, options.nxi) if options.recompute: # Load density and omega from file outsamp = options.outsamp if not options.batch is None: outsamp = outsamp.replace('.dat', '.%i.dat' % options.batch) sampdata = np.genfromtxt(outsamp, delimiter=',', skip_header=1) nd = 0 else: # Setup saving if os.path.exists(options.outsamp): # First read the file to check apar print('does ' + options.outsamp + ' exist?', os.path.exists(options.outsamp)) bins_file = np.genfromtxt(options.outsamp, delimiter=',', max_rows=1) print(np.amax(np.fabs(bins_file - bins))) assert np.amax( np.fabs(bins_file - bins) ) < 10.**-5., 'bins according to options does not correspond to bins already in outsamp' csvsamp = open(options.outsamp, 'a') sampwriter = csv.writer(csvsamp, delimiter=',') else: csvsamp = open(options.outsamp, 'w') sampwriter = csv.writer(csvsamp, delimiter=',') # First write bins sampwriter.writerow([b for b in bins]) csvsamp.flush() # Setup sampling massrange = simulate_streampepper.parse_mass(options.mass) rs = simulate_streampepper.rs sample_GM= lambda: (10.**((-0.5)*massrange[0])\ +(10.**((-0.5)*massrange[1])\ -10.**((-0.5)*massrange[0]))\ *np.random.uniform())**(1./(-0.5))\ /bovy_conversion.mass_in_msol(V0,R0) sample_rs = lambda x: rs(x * bovy_conversion.mass_in_1010msol(V0, R0) * 10.**10., plummer=options.plummer) rate_range = np.arange(massrange[0] + 0.5, massrange[1] + 0.5, 1) cdmrate= np.sum([simulate_streampepper.\ dNencdm(sdf_pepper,10.**r,Xrs=options.Xrs, plummer=options.plummer, rsfac=options.rsfac) for r in rate_range]) print("Using an overall CDM rate of %f" % cdmrate) # Load Pal 5 data to compare to if options.mockfilename is None: power_data, data_err, data_ppyr, data_ppyi=\ process_pal5_densdata(options) else: power_data, data_err, data_ppyr, data_ppyi, data_py_err=\ process_mock_densdata(options) # Run ABC while True: if not options.recompute: # Simulate a rate l10rate = (np.random.uniform() * (options.ratemax - options.ratemin) + options.ratemin) #### fix to CDM for testing if options.fixcdmrate: print('warning: using only CDM rate') l10rate = 0. rate = 10.**l10rate * cdmrate print(l10rate, rate) # Simulate sdf_pepper.simulate(rate=rate, sample_GM=sample_GM, sample_rs=sample_rs, Xrs=options.Xrs) # Compute density along stream try: samp, binn = np.histogram(get_star_dx(sdf_pepper, n=options.nsamples, returnxi=True), bins=bins) except: continue write_samp = [l10rate] write_samp.extend(list(samp)) sampwriter.writerow(write_samp) csvsamp.flush() else: if nd >= len(densdata): break l10rate = densdata[nd, 0] dens = densdata[nd, 1:] omega = omegadata[nd, 1:] nd += 1 # Convert density to observed density xixi = (bins[1:] + bins[:-1]) / 2. dens = samp # Add errors (Rao-Blackwellize...) for ee in range(options.nerrsim): tdens = dens + np.random.poisson(options.nbg, size=len(dens)) tdens = np.maximum(tdens - options.nbg, np.zeros_like(tdens)) pp = Polynomial.fit(xixi, tdens, deg=options.polydeg, w=1. / np.sqrt(tdens + 1.)) tdens = tdens / pp(xixi) # Compute power spectrum tcsd = signal.csd(tdens, tdens, fs=1. / (xixi[1] - xixi[0]), scaling='spectrum', nperseg=len(xixi))[1].real power = np.sqrt(tcsd * (xixi[-1] - xixi[0])) # Compute bispectrum Bspec, Bpx = bispectrum.bispectrum(np.vstack((tdens, tdens)).T, nfft=len(tdens), wind=7, nsamp=1, overlap=0) ppyr = np.fabs(Bspec[len(Bspec) // 2 + _BISPECIND, len(Bspec) // 2:].real) ppyi = np.fabs(Bspec[len(Bspec) // 2 + _BISPECIND, len(Bspec) // 2:].imag) yield ( l10rate, power, ppyr, ppyi, #np.fabs(power[1]-power_data[1]), #np.fabs(power[2]-power_data[2]), #np.fabs(power[3]-power_data[3]), #np.fabs(np.log(np.mean(tdens[7:17])\ # /np.mean(tdens[107:117]))), #np.fabs(ppyr-data_ppyr)[_BISPECIND], #np.fabs(ppyi-data_ppyi)[_BISPECIND], ee)
def __init__(self, amp=1., a=1., normalize=False, conc=None, mvir=None, vo=None, ro=None, H=70., Om=0.3, overdens=200., wrtcrit=False): """ NAME: __init__ PURPOSE: Initialize a NFW potential INPUT: amp - amplitude to be applied to the potential (default: 1); can be a Quantity with units of mass or Gxmass a - scale radius (can be Quantity) normalize - if True, normalize such that vc(1.,0.)=1., or, if given as a number, such that the force is this fraction of the force necessary to make vc(1.,0.)=1. Alternatively, NFW potentials can be initialized using conc= concentration mvir= virial mass in 10^12 Msolar in which case you also need to supply the following keywords H= (default: 70) Hubble constant in km/s/Mpc Om= (default: 0.3) Omega matter overdens= (200) overdensity which defines the virial radius wrtcrit= (False) if True, the overdensity is wrt the critical density rather than the mean matter density ro=, vo= distance and velocity scales for translation into internal units (default from configuration file) OUTPUT: (none) HISTORY: 2010-07-09 - Written - Bovy (NYU) 2014-04-03 - Initialization w/ concentration and mass - Bovy (IAS) """ Potential.__init__(self, amp=amp, ro=ro, vo=vo, amp_units='mass') if _APY_LOADED and isinstance(a, units.Quantity): a = a.to(units.kpc).value / self._ro if conc is None: self.a = a self.alpha = 1 self.beta = 3 if normalize or \ (isinstance(normalize,(int,float)) \ and not isinstance(normalize,bool)): self.normalize(normalize) else: if wrtcrit: od = overdens / bovy_conversion.dens_in_criticaldens( self._vo, self._ro, H=H) else: od = overdens / bovy_conversion.dens_in_meanmatterdens( self._vo, self._ro, H=H, Om=Om) mvirNatural = mvir * 100. / bovy_conversion.mass_in_1010msol( self._vo, self._ro) rvir = (3. * mvirNatural / od / 4. / numpy.pi)**(1. / 3.) self.a = rvir / conc self._amp = mvirNatural / (numpy.log(1. + conc) - conc / (1. + conc)) self._scale = self.a self.hasC = True self.hasC_dxdv = True self._nemo_accname = 'NFW' return None
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
def pal5_abc(sdf_pepper, sdf_smooth, options): """ """ # Setup apar grid apar = numpy.arange(options.amin, options.amax, options.dapar) dens_unp = numpy.array([sdf_smooth._density_par(a) for a in apar]) if options.recompute: # Load density and omega from file outdens = options.outdens outomega = options.outomega if not options.batch is None: outdens = outdens.replace('.dat', '.%i.dat' % options.batch) if not options.batch is None: outomega = outomega.replace('.dat', '.%i.dat' % options.batch) densdata = numpy.genfromtxt(outdens, delimiter=',', skip_header=1) omegadata = numpy.genfromtxt(outomega, delimiter=',', skip_header=1) nd = 0 else: # Setup saving of the densities and mean Omegas denswriter, omegawriter, csvdens, csvomega=\ setup_densOmegaWriter(apar,options) # Setup sampling massrange = simulate_streampepper.parse_mass(options.mass) rs = simulate_streampepper.rs sample_GM= lambda: (10.**((-0.5)*massrange[0])\ +(10.**((-0.5)*massrange[1])\ -10.**((-0.5)*massrange[0]))\ *numpy.random.uniform())**(1./(-0.5))\ /bovy_conversion.mass_in_msol(V0,R0) sample_rs = lambda x: rs(x * bovy_conversion.mass_in_1010msol(V0, R0) * 10.**10., plummer=options.plummer) rate_range = numpy.arange(massrange[0] + 0.5, massrange[1] + 0.5, 1) cdmrate= numpy.sum([simulate_streampepper.\ dNencdm(sdf_pepper,10.**r,Xrs=options.Xrs, plummer=options.plummer, rsfac=options.rsfac) for r in rate_range]) print "Using an overall CDM rate of %f" % cdmrate # Load Pal 5 data to compare to if options.mockfilename is None: power_data, data_err, data_ppyr, data_ppyi=\ process_pal5_densdata(options) else: power_data, data_err, data_ppyr, data_ppyi=\ process_mock_densdata(options) # Run ABC while True: if not options.recompute: # Simulate a rate l10rate = (numpy.random.uniform() * (options.ratemax - options.ratemin) + options.ratemin) rate = 10.**l10rate * cdmrate print l10rate, rate # Simulate sdf_pepper.simulate(rate=rate, sample_GM=sample_GM, sample_rs=sample_rs, Xrs=options.Xrs) # Compute density and meanOmega and save try: densOmega= numpy.array([\ sdf_pepper._densityAndOmega_par_approx(a) for a in apar]).T except IndexError: # no hit dens = numpy.array([sdf_smooth._density_par(a) for a in apar]) omega = numpy.array( [sdf_smooth.meanOmega(a, oned=True) for a in apar]) else: dens = densOmega[0] omega = densOmega[1] write_dens = [l10rate] write_omega = [l10rate] write_dens.extend(list(dens)) write_omega.extend(list(omega)) denswriter.writerow(write_dens) omegawriter.writerow(write_omega) csvdens.flush() csvomega.flush() else: if nd >= len(densdata): break l10rate = densdata[nd, 0] dens = densdata[nd, 1:] omega = omegadata[nd, 1:] nd += 1 # Convert density to observed density xixi, dens = convert_dens_to_obs(sdf_pepper, apar, dens, omega, dens_unp, minxi=options.minxi, maxxi=options.maxxi) # Add errors (Rao-Blackwellize...) for ee in range(options.nerrsim): tdens = dens + numpy.random.normal(size=len(xixi)) * data_err # Compute power spectrum tcsd = signal.csd(tdens, tdens, fs=1. / (xixi[1] - xixi[0]), scaling='spectrum', nperseg=len(xixi))[1].real power = numpy.sqrt(tcsd * (xixi[-1] - xixi[0])) # Compute bispectrum Bspec, Bpx = bispectrum.bispectrum(numpy.vstack((tdens, tdens)).T, nfft=len(tdens), wind=7, nsamp=1, overlap=0) ppyr = numpy.fabs(Bspec[len(Bspec) // 2 + _BISPECIND, len(Bspec) // 2:].real) ppyi = numpy.fabs(Bspec[len(Bspec) // 2 + _BISPECIND, len(Bspec) // 2:].imag) yield (l10rate, numpy.fabs(power[1]-power_data[1]), numpy.fabs(power[2]-power_data[2]), numpy.fabs(power[3]-power_data[3]), numpy.fabs(numpy.log(numpy.mean(tdens[7:17])\ /numpy.mean(tdens[107:117]))), numpy.fabs(ppyr-data_ppyr)[_BISPECIND], numpy.fabs(ppyi-data_ppyi)[_BISPECIND], ee)
def pal5_abc(sdf_pepper, sdf_smooth, options): """ """ # Setup apar grid apar = numpy.arange(options.amin, options.amax, options.dapar) dens_unp = numpy.array([sdf_smooth._density_par(a) for a in apar]) if options.recompute: # Load density and omega from file outdens = options.outdens outomega = options.outomega if not options.batch is None: outdens = outdens.replace(".dat", ".%i.dat" % options.batch) if not options.batch is None: outomega = outomega.replace(".dat", ".%i.dat" % options.batch) densdata = numpy.genfromtxt(outdens, delimiter=",", skip_header=1) omegadata = numpy.genfromtxt(outomega, delimiter=",", skip_header=1) nd = 0 else: # Setup saving of the densities and mean Omegas denswriter, omegawriter, csvdens, csvomega = setup_densOmegaWriter(apar, options) # Setup sampling massrange = simulate_streampepper.parse_mass(options.mass) rs = simulate_streampepper.rs sample_GM = lambda: ( 10.0 ** ((-0.5) * massrange[0]) + (10.0 ** ((-0.5) * massrange[1]) - 10.0 ** ((-0.5) * massrange[0])) * numpy.random.uniform() ) ** (1.0 / (-0.5)) / bovy_conversion.mass_in_msol(V0, R0) sample_rs = lambda x: rs(x * bovy_conversion.mass_in_1010msol(V0, R0) * 10.0 ** 10.0, plummer=options.plummer) rate_range = numpy.arange(massrange[0] + 0.5, massrange[1] + 0.5, 1) cdmrate = numpy.sum( [ simulate_streampepper.dNencdm( sdf_pepper, 10.0 ** r, Xrs=options.Xrs, plummer=options.plummer, rsfac=options.rsfac ) for r in rate_range ] ) print "Using an overall CDM rate of %f" % cdmrate # Load Pal 5 data to compare to if options.mockfilename is None: power_data, data_err, data_ppyr, data_ppyi = process_pal5_densdata(options) else: power_data, data_err, data_ppyr, data_ppyi = process_mock_densdata(options) # Run ABC while True: if not options.recompute: # Simulate a rate l10rate = numpy.random.uniform() * (options.ratemax - options.ratemin) + options.ratemin rate = 10.0 ** l10rate * cdmrate print l10rate, rate # Simulate sdf_pepper.simulate(rate=rate, sample_GM=sample_GM, sample_rs=sample_rs, Xrs=options.Xrs) # Compute density and meanOmega and save try: densOmega = numpy.array([sdf_pepper._densityAndOmega_par_approx(a) for a in apar]).T except IndexError: # no hit dens = numpy.array([sdf_smooth._density_par(a) for a in apar]) omega = numpy.array([sdf_smooth.meanOmega(a, oned=True) for a in apar]) else: dens = densOmega[0] omega = densOmega[1] write_dens = [l10rate] write_omega = [l10rate] write_dens.extend(list(dens)) write_omega.extend(list(omega)) denswriter.writerow(write_dens) omegawriter.writerow(write_omega) csvdens.flush() csvomega.flush() else: if nd >= len(densdata): break l10rate = densdata[nd, 0] dens = densdata[nd, 1:] omega = omegadata[nd, 1:] nd += 1 # Convert density to observed density xixi, dens = convert_dens_to_obs( sdf_pepper, apar, dens, omega, dens_unp, minxi=options.minxi, maxxi=options.maxxi ) # Add errors (Rao-Blackwellize...) for ee in range(options.nerrsim): tdens = dens + numpy.random.normal(size=len(xixi)) * data_err # Compute power spectrum tcsd = signal.csd(tdens, tdens, fs=1.0 / (xixi[1] - xixi[0]), scaling="spectrum", nperseg=len(xixi))[1].real power = numpy.sqrt(tcsd * (xixi[-1] - xixi[0])) # Compute bispectrum Bspec, Bpx = bispectrum.bispectrum( numpy.vstack((tdens, tdens)).T, nfft=len(tdens), wind=7, nsamp=1, overlap=0 ) ppyr = numpy.fabs(Bspec[len(Bspec) // 2 + _BISPECIND, len(Bspec) // 2 :].real) ppyi = numpy.fabs(Bspec[len(Bspec) // 2 + _BISPECIND, len(Bspec) // 2 :].imag) yield ( l10rate, numpy.fabs(power[1] - power_data[1]), numpy.fabs(power[2] - power_data[2]), numpy.fabs(power[3] - power_data[3]), numpy.fabs(numpy.log(numpy.mean(tdens[7:17]) / numpy.mean(tdens[107:117]))), numpy.fabs(ppyr - data_ppyr)[_BISPECIND], numpy.fabs(ppyi - data_ppyi)[_BISPECIND], ee, )
def __init__(self, amp=1., a=1., normalize=False, conc=None, mvir=None, vo=220., ro=8., H=70., Om=0.3, overdens=200., wrtcrit=False): """ NAME: __init__ PURPOSE: Initialize a NFW potential INPUT: amp - amplitude to be applied to the potential a - "scale" (in terms of Ro) normalize - if True, normalize such that vc(1.,0.)=1., or, if given as a number, such that the force is this fraction of the force necessary to make vc(1.,0.)=1. Alternatively, NFW potentials can be initialized using conc= concentration mvir= virial mass in 10^12 Msolar in which case you also need to supply the following keywords vo= (220.) velocity unit in km/s ro= (8.) length unit in kpc H= (default: 70) Hubble constant in km/s/Mpc Om= (default: 0.3) Omega matter overdens= (200) overdensity which defines the virial radius wrtcrit= (False) if True, the overdensity is wrt the critical density rather than the mean matter density OUTPUT: (none) HISTORY: 2010-07-09 - Written - Bovy (NYU) 2014-04-03 - Initialization w/ concentration and mass - Bovy (IAS) """ Potential.__init__(self, amp=amp) if conc is None: self.a = a self.alpha = 1 self.beta = 3 if normalize or \ (isinstance(normalize,(int,float)) \ and not isinstance(normalize,bool)): self.normalize(normalize) else: if wrtcrit: od = overdens / bovy_conversion.dens_in_criticaldens( vo, ro, H=H) else: od = overdens / bovy_conversion.dens_in_meanmatterdens( vo, ro, H=H, Om=Om) mvirNatural = mvir * 100. / bovy_conversion.mass_in_1010msol( vo, ro) rvir = (3. * mvirNatural / od / 4. / numpy.pi)**(1. / 3.) self.a = rvir / conc self._amp = mvirNatural / (numpy.log(1. + conc) - conc / (1. + conc)) self._scale = self.a self.hasC = True self.hasC_dxdv = True self._nemo_accname = 'NFW' return None
def setup_streammodel( obs=None, pot = MWPotential2014, leading=False, timpact=None, hernquist=True, age=5., sigv=.5, singleImpact=False, length_factor=1., vsun=[-11.1,V0+24.,7.25], b=None, **kwargs): ''' NAME: setup_streammodel PURPOSE: Initialize a streamdf or streampepperdf instance of stellar stream, depending on its impact history INPUT: obs: Orbit instance for progenitor position pot: host potential age: stream age in Gyr sigv: ~ internal velocity dispersion in km/s, controls the stream length in proportion to the age b: fit parameter for the isochrone approximation, if None it is set automatically R, R_coord: R_name: a rotation matrix for transformation to stream coordinates,the frame they are transforming from, and a name for the new coordinate system custom_transform: depreciated, superseded by the Astropy implementation below leading: if True, use leading tail, use trailing tail otherwise hernquist: if True, use Hernquist spheres for subhalos; Plummer otherwise singleImpact: force use of the streamgapdf instead of streampepperdf length_factor: consider impacts up to length_factor x length of the stream streamdf kwargs OUTPUT: object HISTORY: 2016 - Started - Bovy (UofT) 2020-05-08 - Generalized - Hendel (UofT) ''' #automatically set up potential model if b==None: obs.turn_physical_off() b = estimateBIsochrone(pot, obs.R(), obs.z()) obs.turn_physical_on() print('Using isochrone approxmation parameter of %1.3f, should typically be between 0.5 and 1'%b) aAI= actionAngleIsochroneApprox(pot=pot,b=b) if timpact is None: sdf= streamdf(sigv/V0,progenitor=obs, pot=pot,aA=aAI, leading=leading,nTrackChunks=11, tdisrupt=age/bovy_conversion.time_in_Gyr(V0,R0), ro=R0,vo=V0,R0=R0, vsun=vsun, custom_transform=None) elif singleImpact: sdf= streamgapdf(sigv/V0,progenitor=obs, pot=pot,aA=aAI, leading=leading,nTrackChunks=11, tdisrupt=age/bovy_conversion.time_in_Gyr(V0,R0), ro=R0,vo=V0,R0=R0, vsun=vsun, custom_transform=None, timpact= 0.3/bovy_conversion.time_in_Gyr(V0,R0), spline_order=3, hernquist=hernquist, impact_angle=0.7, impactb=0., GM= 10.**-2./bovy_conversion.mass_in_1010msol(V0,R0), rs= 0.625/R0, subhalovel=np.array([6.82200571,132.7700529,14.4174464])/V0, **kwargs) else: sdf= streampepperdf(sigv/V0,progenitor=obs, pot=pot,aA=aAI, leading=leading,nTrackChunks=101, tdisrupt=age/bovy_conversion.time_in_Gyr(V0,R0), ro=R0,vo=V0,R0=R0, vsun=vsun, custom_transform=None, timpact=timpact, spline_order=3, hernquist=hernquist, length_factor=length_factor) sdf.turn_physical_off() return sdf
def test_mass_in_1010msol(): #Test the scaling, should be velocity^2 x position vofid, rofid= 200., 8. assert numpy.fabs(4.*bovy_conversion.mass_in_1010msol(vofid,rofid)/bovy_conversion.mass_in_1010msol(2.*vofid,rofid)-1.) < 10.**-10., 'mass_in_1010msol did not work as expected' assert numpy.fabs(2.*bovy_conversion.mass_in_1010msol(vofid,rofid)/bovy_conversion.mass_in_1010msol(vofid,2*rofid)-1.) < 10.**-10., 'mass_in_1010msol did not work as expected' return None
def create_frames(options, args): # First reload the model with open('gd1pepper%isampling.pkl' % options.nsnap, 'rb') as savefile: sdf_pepper_leading = pickle.load(savefile) with open('gd1pepper%isampling_trailing.pkl' % options.nsnap, 'rb') as savefile: sdf_pepper_trailing = pickle.load(savefile) # Output times timpacts = sdf_pepper_leading._uniq_timpact # Sample unperturbed aAt numpy.random.seed(1) Oml,anglel,dtl= super(streampepperdf,sdf_pepper_leading)._sample_aAt(\ options.nparticles) Omt,anglet,dtt= super(streampepperdf,sdf_pepper_trailing)._sample_aAt(\ options.nparticles) # Setup progenitor prog = sdf_pepper_leading._progenitor().flip() prog.integrate( numpy.linspace(0., 9. / bovy_conversion.time_in_Gyr(V0, R0), 10001), sdf_pepper_leading._pot) prog.flip() # Setup impacts if options.single: # Hit the leading arm and the trailing arm 1 Gyr later m = options.singlemimpact / bovy_conversion.mass_in_1010msol( V0, R0) / 1000. t= timpacts[\ numpy.argmin(\ numpy.fabs(\ numpy.array(timpacts)\ -options.singletimpact\ /bovy_conversion.time_in_Gyr(V0,R0)))] sdf_pepper_leading.set_impacts(\ impactb=[0.5*simulate_streampepper.rs(options.singlemimpact*10.**7.)], subhalovel=numpy.array([[-25.,155.,30.]])/V0, impact_angle=[0.2], timpact=[t], GM=[m],rs=[simulate_streampepper.rs(options.singlemimpact*10.**7.)]) # Trailing m = options.singlemimpact / bovy_conversion.mass_in_1010msol( V0, R0) / 1000. t= timpacts[\ numpy.argmin(\ numpy.fabs(\ numpy.array(timpacts)\ -(options.singletimpact+1.)\ /bovy_conversion.time_in_Gyr(V0,R0)))] sdf_pepper_trailing.set_impacts(\ impactb=[1.*simulate_streampepper.rs(options.singlemimpact*10.**7.)], subhalovel=numpy.array([[-25.,155.,30.]])/V0, impact_angle=[-0.3], timpact=[t], GM=[m],rs=[simulate_streampepper.rs(options.singlemimpact*10.**7.)]) elif options.pepper: # Sampling functions massrange = [options.Mmin, options.Mmax] plummer = False Xrs = 5. nsubhalo = simulate_streampepper.nsubhalo rs = simulate_streampepper.rs dNencdm = simulate_streampepper.dNencdm sample_GM= lambda: (10.**((-0.5)*massrange[0])\ +(10.**((-0.5)*massrange[1])\ -10.**((-0.5)*massrange[0]))\ *numpy.random.uniform())**(1./(-0.5))\ /bovy_conversion.mass_in_msol(V0,R0) rate_range = numpy.arange(massrange[0] + 0.5, massrange[1] + 0.5, 1) rate = numpy.sum([ dNencdm(sdf_pepper_leading, 10.**r, Xrs=Xrs, plummer=plummer) for r in rate_range ]) rate = options.timescdm * rate sample_rs = lambda x: rs(x * bovy_conversion.mass_in_1010msol(V0, R0) * 10.**10., plummer=plummer) # Pepper both sdf_pepper_leading.simulate(rate=rate, sample_GM=sample_GM, sample_rs=sample_rs, Xrs=Xrs) print numpy.amax( sdf_pepper_leading._GM) * bovy_conversion.mass_in_1010msol(V0, R0) sdf_pepper_trailing.simulate(rate=rate, sample_GM=sample_GM, sample_rs=sample_rs, Xrs=Xrs) print numpy.amax( sdf_pepper_trailing._GM) * bovy_conversion.mass_in_1010msol( V0, R0) else: # Hit both with zero sdf_pepper_leading.set_impacts(\ impactb=[0.], subhalovel=numpy.array([[-25.,155.,30.]])/V0, impact_angle=[0.2], timpact=[timpacts[0]], GM=[0.],rs=[1.]) sdf_pepper_trailing.set_impacts(\ impactb=[0.], subhalovel=numpy.array([[-25.,155.,30.]])/V0, impact_angle=[-0.2], timpact=[timpacts[0]], GM=[0.],rs=[1.]) # Now make all frames dum = multi.parallel_map((lambda x: _plot_one_frame( x, options, prog, timpacts, sdf_pepper_leading, sdf_pepper_trailing, Oml, Omt, anglel, anglet, dtl, dtt)), range(len(timpacts)), numcores=numpy.amin([len(timpacts), 30])) return None
def test_sanders15_leading_setup(): #Imports from galpy.df import streamdf, streamgapdf from galpy.orbit import Orbit from galpy.potential import LogarithmicHaloPotential, PlummerPotential from galpy.actionAngle import actionAngleIsochroneApprox from galpy.util import bovy_conversion #for unit conversions lp= LogarithmicHaloPotential(normalize=1.,q=0.9) aAI= actionAngleIsochroneApprox(pot=lp,b=0.8) prog_unp_peri= Orbit([2.6556151742081835, 0.2183747276300308, 0.67876510797240575, -2.0143395648974671, -0.3273737682604374, 0.24218273922966019]) global sdfl_sanders15 V0, R0= 220., 8. sigv= 0.365*(10./2.)**(1./3.) # km/s # Use a Potential object for the impact pp= PlummerPotential(amp=10.**-2.\ /bovy_conversion.mass_in_1010msol(V0,R0), b=0.625/R0) import warnings from galpy.util import galpyWarning with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always",galpyWarning) sdfl_sanders15= streamgapdf(sigv/V0,progenitor=prog_unp_peri, pot=lp,aA=aAI, leading=True,nTrackChunks=26, nTrackChunksImpact=29, nTrackIterations=1, sigMeanOffset=4.5, tdisrupt=10.88\ /bovy_conversion.time_in_Gyr(V0,R0), Vnorm=V0,Rnorm=R0, impactb=0., subhalovel=numpy.array([49.447319, 116.179436, 155.104156])/V0, timpact=0.88/bovy_conversion.time_in_Gyr(V0,R0), impact_angle=2.09, subhalopot=pp, nKickPoints=290, deltaAngleTrackImpact=4.5, multi=True) # test multi # Should raise warning bc of deltaAngleTrackImpact, might raise others raisedWarning= False for wa in w: raisedWarning= (str(wa.message) == "WARNING: deltaAngleTrackImpact angle range large compared to plausible value") if raisedWarning: break assert raisedWarning, 'deltaAngleTrackImpact warning not raised when it should have been' assert not sdfl_sanders15 is None, 'sanders15 trailing streamdf setup did not work' # Also setup the unperturbed model global sdfl_sanders15_unp sdfl_sanders15_unp= streamdf(sigv/V0,progenitor=prog_unp_peri, pot=lp,aA=aAI, leading=True,nTrackChunks=26, nTrackIterations=1, sigMeanOffset=4.5, tdisrupt=10.88\ /bovy_conversion.time_in_Gyr(V0,R0), Vnorm=V0,Rnorm=R0) assert not sdfl_sanders15_unp is None, \ 'sanders15 unperturbed streamdf setup did not work' return None
def verysimplenfwfit(plotfilename,wcprior=False,wmassprior=False): #Fit p= optimize.fmin_powell(chi2,[-0.5,0.7],args=(wcprior,wmassprior)) print mvir(p), conc(p)*numpy.exp(p[1])*8. vo= numpy.exp(p[0]) a= numpy.exp(p[1]) nfw= potential.NFWPotential(normalize=1.,a=a) rs= numpy.linspace(0.01,350.,1001) masses= numpy.array([nfw.mass(r/8.) for r in rs]) bovy_plot.bovy_print(fig_width=6.) bovy_plot.bovy_plot(rs, masses*bovy_conversion.mass_in_1010msol(220.*vo,8.)/100., 'k-',loglog=True, xlabel=r'$R\,(\mathrm{kpc})$', ylabel=r'$M(<R)\,(10^{12}\,M_\odot)$', yrange=[0.01,1.2], xrange=[3.,400.]) if _USE_ALL_XUE: plotx= [10.] plotx.extend(list(_XUER)) ploty= [4.5/100.] ploty.extend(list(_XUEMASS/100.)) plotyerr= [1.5/100] plotyerr.extend(list(_XUEMASS_ERR/100.)) pyplot.errorbar(plotx,ploty,yerr=plotyerr,marker='o',ls='none', color='k') else: pyplot.errorbar([10.,60.],[4.5/100.,3.5/10.],yerr=[1.5/100.,0.7/10.], marker='o',ls='none',color='k') pyplot.errorbar([150.],[7.5/10.],[2.5/10.],marker='None',color='k') dx= .5 arr= FancyArrowPatch(posA=(7.,4./100.),posB=(numpy.exp(numpy.log(7.)+dx),numpy.exp(numpy.log(4./100.)+1.5*dx)),arrowstyle='->',connectionstyle='arc3,rad=%4.2f' % (0.),shrinkA=2.0, shrinkB=2.0,mutation_scale=20.0, mutation_aspect=None,fc='k') ax = pyplot.gca() ax.add_patch(arr) #Sample MCMC to get virial mass uncertainty samples= bovy_mcmc.markovpy(p, 0.05, lnlike, (wcprior,wmassprior), isDomainFinite=[[False,False],[False,False]], domain=[[0.,0.],[0.,0.]], nsamples=10000, nwalkers=6) mvirs= numpy.array([mvir(x) for x in samples]) concs= numpy.array([conc(x) for x in samples]) indx= True-numpy.isnan(mvirs) mvirs= mvirs[indx] indx= True-numpy.isnan(concs) concs= concs[indx] rvirs= concs[indx]*numpy.array([numpy.exp(x[1]) for x in samples])*8. bovy_plot.bovy_text(r'$M_{\mathrm{vir}} = %.2f\pm%.2f\times10^{12}\,M_\odot$' % (numpy.median(mvirs),1.4826*numpy.median(numpy.fabs(mvirs-numpy.median(mvirs)))) +'\n'+ r'$r_{\mathrm{vir}} = %i\pm%i\,\mathrm{kpc}$' % (numpy.median(rvirs),1.4826*numpy.median(numpy.fabs(rvirs-numpy.median(rvirs))))+'\n'+ r'$c = %.1f\pm%.1f$' % (numpy.median(concs),1.4826*numpy.median(numpy.fabs(concs-numpy.median(concs)))), top_left=True,size=18.) #Create inset with PDF insetAxes= pyplot.axes([0.55,0.22,0.3,0.3]) pyplot.sca(insetAxes) bovy_plot.bovy_hist(mvirs,range=[0.,3.],bins=51,histtype='step', color='k', normed=True, overplot=True) insetAxes.set_xlim(0.,3.) insetAxes.set_ylim(0.,1.49) insetAxes.set_xlabel(r'$M_{\mathrm{vir}}\,(10^{12}\,M_\odot)$') bovy_plot._add_ticks() bovy_plot.bovy_end_print(plotfilename)
*numpy.random.uniform())**(1./(massexp+1.5))\ /bovy_conversion.mass_in_msol(V0,R0) rate_range = numpy.arange(massrange[0] + 0.5, massrange[1] + 0.5, 1) rate = numpy.sum([ dNencdm(sp, 10.**r, Xrs=3., plummer=False, rsfac=1., sigma=120.) for r in rate_range ]) for i in np.arange(10): sample_GM = lambda: powerlaw_wcutoff(massrange, 7.) rate_range = numpy.arange(massrange[0] + 0.5, massrange[1] + 0.5, 1) rate = 3 * numpy.sum([ dNencdm(sp, 10.**r, Xrs=3., plummer=False, rsfac=1., sigma=120.) for r in rate_range ]) sample_rs = lambda x: rs(x * bovy_conversion.mass_in_1010msol(V0, R0) * 10. **10., plummer=False, rsfac=1.) ns = 0 sp.simulate(rate=rate, sample_GM=sample_GM, sample_rs=sample_rs, Xrs=3., sigma=120. / 220.) sp._useInterp = True sp_sample = sp.sample(n=10000, lb=True) spc = SkyCoord(sp_sample[0] * u.deg, sp_sample[1] * u.deg, frame='galactic') spxi = radec_to_pal5xieta(spc.icrs.ra, spc.icrs.dec)
def run_simulations(sdf_pepper, sdf_smooth, options): # Setup apar grid apar = numpy.arange(options.amin, options.amax, options.dapar) # Check whether the output files already exist and if so, get the amin, amax, da from them if os.path.exists(options.outdens): # First read the file to check apar apar_file = numpy.genfromtxt(options.outdens, delimiter=',', max_rows=1) print(numpy.amax(numpy.fabs(apar_file - apar))) assert numpy.amax( numpy.fabs(apar_file - apar) ) < 10.**-5., 'apar according to options does not correspond to apar already in outdens' apar_file = numpy.genfromtxt(options.outomega, delimiter=',', max_rows=1) print(numpy.amax(numpy.fabs(apar_file - apar))) assert numpy.amax( numpy.fabs(apar_file - apar) ) < 10.**-5., 'apar according to options does not correspond to apar already in outomega' csvdens = open(options.outdens, 'a') csvomega = open(options.outomega, 'a') denswriter = csv.writer(csvdens, delimiter=',') omegawriter = csv.writer(csvomega, delimiter=',') else: csvdens = open(options.outdens, 'w') csvomega = open(options.outomega, 'w') denswriter = csv.writer(csvdens, delimiter=',') omegawriter = csv.writer(csvomega, delimiter=',') # First write apar and the smooth calculations denswriter.writerow([a for a in apar]) omegawriter.writerow([a for a in apar]) if sdf_smooth is None and options.stream.lower() == 'gd1like': sdf_smooth = gd1_util.setup_gd1model(age=options.age) elif sdf_smooth is None and options.stream.lower() == 'pal5like': sdf_smooth = pal5_util.setup_pal5model(age=options.age) dens_unp = [sdf_smooth._density_par(a) for a in apar] denswriter.writerow(dens_unp) omega_unp = [sdf_smooth.meanOmega(a, oned=True) for a in apar] omegawriter.writerow(omega_unp) csvdens.flush() csvomega.flush() # Parse mass massrange = parse_mass(options.mass) if len(massrange) == 1: sample_GM= lambda: 10.**(massrange[0]-10.)\ /bovy_conversion.mass_in_1010msol(V0,R0) rate = options.timescdm * dNencdm(sdf_pepper, 10.**massrange[0], Xrs=options.Xrs, plummer=options.plummer, rsfac=options.rsfac, sigma=options.sigma) elif len(massrange) == 2: # Sample from power-law if not options.cutoff is None: sample_GM = lambda: powerlaw_wcutoff(massrange, options.cutoff) elif numpy.fabs(options.massexp + 1.5) < 10.**-6.: sample_GM= lambda: 10.**(massrange[0]\ +(massrange[1]-massrange[0])\ *numpy.random.uniform())\ /bovy_conversion.mass_in_msol(V0,R0) else: sample_GM= lambda: (10.**((options.massexp+1.5)*massrange[0])\ +(10.**((options.massexp+1.5)*massrange[1])\ -10.**((options.massexp+1.5)*massrange[0]))\ *numpy.random.uniform())**(1./(options.massexp+1.5))\ /bovy_conversion.mass_in_msol(V0,R0) rate_range = numpy.arange(massrange[0] + 0.5, massrange[1] + 0.5, 1) rate= options.timescdm\ *numpy.sum([dNencdm(sdf_pepper,10.**r,Xrs=options.Xrs, plummer=options.plummer,rsfac=options.rsfac, sigma=options.sigma) for r in rate_range]) if not options.cutoff is None: rate*= integrate.quad(lambda x: x**-1.5\ *numpy.exp(-10.**options.cutoff/x), 10.**massrange[0],10.**massrange[1])[0]\ /integrate.quad(lambda x: x**-1.5, 10.**massrange[0], 10.**massrange[1])[0] print("Using an overall rate of %f" % rate) sample_rs = lambda x: rs(x * bovy_conversion.mass_in_1010msol(V0, R0) * 10. **10., plummer=options.plummer, rsfac=options.rsfac) # Simulate start = time.time() ns = 0 while True: if options.nsamples is None and time.time() >= (start + options.dt * 60.): break elif not options.nsamples is None and ns > options.nsamples: break ns += 1 sdf_pepper.simulate(rate=rate, sample_GM=sample_GM, sample_rs=sample_rs, Xrs=options.Xrs, sigma=options.sigma / V0) # Compute density and meanOmega and save try: densOmega = numpy.array( [sdf_pepper._densityAndOmega_par_approx(a) for a in apar]).T except IndexError: # no hit dens_unp = [sdf_smooth._density_par(a) for a in apar] omega_unp = [sdf_smooth.meanOmega(a, oned=True) for a in apar] denswriter.writerow(dens_unp) omegawriter.writerow(omega_unp) else: denswriter.writerow(list(densOmega[0])) omegawriter.writerow(list(densOmega[1])) csvdens.flush() csvomega.flush() csvdens.close() csvomega.close() return None
def __init__(self,amp=1.,a=1.,normalize=False, conc=None,mvir=None, vo=220.,ro=8., H=70.,Om=0.3,overdens=200.,wrtcrit=False): """ NAME: __init__ PURPOSE: Initialize a NFW potential INPUT: amp - amplitude to be applied to the potential a - "scale" (in terms of Ro) normalize - if True, normalize such that vc(1.,0.)=1., or, if given as a number, such that the force is this fraction of the force necessary to make vc(1.,0.)=1. Alternatively, NFW potentials can be initialized using conc= concentration mvir= virial mass in 10^12 Msolar in which case you also need to supply the following keywords vo= (220.) velocity unit in km/s ro= (8.) length unit in kpc H= (default: 70) Hubble constant in km/s/Mpc Om= (default: 0.3) Omega matter overdens= (200) overdensity which defines the virial radius wrtcrit= (False) if True, the overdensity is wrt the critical density rather than the mean matter density OUTPUT: (none) HISTORY: 2010-07-09 - Written - Bovy (NYU) 2014-04-03 - Initialization w/ concentration and mass - Bovy (IAS) """ Potential.__init__(self,amp=amp) if conc is None: self.a= a self.alpha= 1 self.beta= 3 if normalize or \ (isinstance(normalize,(int,float)) \ and not isinstance(normalize,bool)): self.normalize(normalize) else: if wrtcrit: od= overdens/bovy_conversion.dens_in_criticaldens(vo,ro,H=H) else: od= overdens/bovy_conversion.dens_in_meanmatterdens(vo,ro,H=H,Om=Om) mvirNatural= mvir*100./bovy_conversion.mass_in_1010msol(vo,ro) rvir= (3.*mvirNatural/od/4./numpy.pi)**(1./3.) self.a= rvir/conc self._amp= mvirNatural/(numpy.log(1.+conc)-conc/(1.+conc)) self._scale= self.a self.hasC= True return None
def main(args: Optional[list] = None, opts: Optional[argparse.Namespace] = None): """Fit Combination Pal5 and GD1 to MW Potential Script Function. Parameters ---------- args : list, optional an optional single argument that holds the sys.argv list, except for the script name (e.g., argv[1:]) """ if opts is not None and args is None: pass else: parser = make_parser() opts = parser.parse_args(args) fpath = opts.fpath + "/" if not opts.fpath.endswith("/") else opts.fpath opath = opts.opath + "/" if not opts.opath.endswith("/") else opts.opath # ----------------------- # Adding in the force measurements from Pal 5 *and* GD-1; also fitting # $R_0$ and $V_c(R_0)$ plt.figure(figsize=(16, 5)) p_b15_pal5gd1_voro = mw_pot.fit( fitc=True, c=None, addpal5=True, addgd1=True, fitvoro=True, mc16=True, plots=fpath + "fit.pdf", ) # ----------------------- samples_savefilename = opath + "mwpot14varyc-fitvoro-pal5gd1-samples.pkl" if os.path.exists(samples_savefilename): with open(samples_savefilename, "rb") as savefile: s = pickle.load(savefile) else: s = mw_pot.sample( nsamples=100000, params=p_b15_pal5gd1_voro[0], fitc=True, c=None, plots=fpath + "mwpot14varyc-fitvoro-pal5gd1-samples.pdf", mc16=True, addpal5=True, addgd1=True, fitvoro=True, ) save_pickles(samples_savefilename, s) # ----------------------- plt.figure() mw_pot.plot_samples( s, True, True, addpal5=True, addgd1=True, savefig=fpath + "mwpot14varyc-fitvoro-pal5gd1-samples-corner.pdf", ) # ----------------------- bf_savefilename = opath + "mwpot14varyc-bf.pkl" # should already exist if os.path.exists(bf_savefilename): with open(bf_savefilename, "rb") as savefile: cs = pickle.load(savefile) bf_params = pickle.load(savefile) else: cs = np.arange(0.5, 4.1, 0.1) bf_params = [] for c in tqdm(cs): dum = mw_pot.fit( fitc=False, c=c, plots=fpath + "mwpot14varyc-bf-fit.pdf", ) bf_params.append(dum[0]) save_pickles(bf_savefilename, cs, bf_params) # ----------------------- plt.figure() bovy_plot.bovy_print( axes_labelsize=17.0, text_fontsize=12.0, xtick_labelsize=15.0, ytick_labelsize=15.0, ) su.plot_mcmc_c( s, True, cs, bf_params, savefig=fpath + "mwpot14varyc-bf-combo_pal5_gd1-dependence.pdf", ) if save_figures: plt.savefig( os.path.join( os.getenv("PAPERSDIR"), "2016-mwhalo-shape", "mwpot14-varyc-wp5g1.pdf", ), bbox_inches="tight", ) # ----------------------- plt.figure(figsize=(4, 4)) cindx = 9 dum = bovy_plot.bovy_hist( s[cindx], bins=36, histtype="step", lw=2.0, xlabel=r"$c/a$", xrange=[0.5, 1.5], normed=True, ) plt.savefig(fpath + "mwpot14varyc-bf-combo_pal5_gd1-shape_hist.pdf") with open(opath + "fit_potential_combo-pal5-gd1.txt", "w") as file: sortedc = np.array(sorted(s[cindx][-50000:])) file.write("2.5%% and 0.5%% lower limits: %.3f, %.3f" % ( sortedc[int(np.floor(0.025 * len(sortedc)))], sortedc[int(np.floor(0.005 * len(sortedc)))], )) file.write("2.5%% and 0.5%% upper limits: %.3f, %.3f" % ( sortedc[int(np.floor(0.975 * len(sortedc)))], sortedc[int(np.floor(0.995 * len(sortedc)))], )) file.write("Median, 68%% confidence: %.3f, %.3f, %.3f" % ( np.median(sortedc), sortedc[int(np.floor(0.16 * len(sortedc)))], sortedc[int(np.floor(0.84 * len(sortedc)))], )) file.write("Mean, std. dev.: %.2f,%.2f" % ( np.mean(sortedc), np.std(sortedc), )) # ----------------------- # What is the constraint on the mass of the halo? tR = 20.0 / REFR0 skip = 1 hmass = [] for sa in tqdm(s.T[::skip]): pot = mw_pot.setup_potential( sa, sa[-1], True, False, REFR0 * sa[8], REFV0 * sa[7], fitvoro=True, ) hmass.append(-integrate.quad( lambda x: tR**2.0 * potential.evaluaterforces( pot[2], tR * x, tR * np.sqrt(1.0 - x**2.0), phi=0.0), 0.0, 1.0, )[0] * bovy_conversion.mass_in_1010msol(REFV0, REFR0) / 10.0) hmass = np.array(hmass) with open(opath + "fit_potential_combo-pal5-gd1.txt", "a") as file: # append file.write("\nMass Constraints:") sortedhm = np.array(sorted(hmass)) file.write("2.5%% and 0.5%% lower limits: %.2f, %.2f" % ( sortedhm[int(np.floor(0.025 * len(sortedhm)))], sortedhm[int(np.floor(0.005 * len(sortedhm)))], )) file.write("2.5%% and 0.5%% upper limits: %.2f, %.2f" % ( sortedhm[int(np.floor(0.975 * len(sortedhm)))], sortedhm[int(np.floor(0.995 * len(sortedhm)))], )) file.write("Median, 68%% confidence: %.2f, %.2f, %.2f" % ( np.median(sortedhm), sortedhm[int(np.floor(0.16 * len(sortedhm)))], sortedhm[int(np.floor(0.84 * len(sortedhm)))], )) # ----------------------- bovy_plot.scatterplot( hmass, s[-1, ::skip], "k,", onedhists=True, bins=31, xrange=[0.5, 1.5], yrange=[0.5, 1.5], xlabel=r"$M_{\mathrm{halo}} (r<20\,\mathrm{kpc})\,(M_\odot)$", ylabel=r"$c/a$", ) plt.savefig(fpath + "scatterplot.pdf")
def __init__(self,amp=1.,a=1.,normalize=False, conc=None,mvir=None, vo=None,ro=None, H=70.,Om=0.3,overdens=200.,wrtcrit=False): """ NAME: __init__ PURPOSE: Initialize a NFW potential INPUT: amp - amplitude to be applied to the potential (default: 1); can be a Quantity with units of mass or Gxmass a - scale radius (can be Quantity) normalize - if True, normalize such that vc(1.,0.)=1., or, if given as a number, such that the force is this fraction of the force necessary to make vc(1.,0.)=1. Alternatively, NFW potentials can be initialized using conc= concentration mvir= virial mass in 10^12 Msolar in which case you also need to supply the following keywords H= (default: 70) Hubble constant in km/s/Mpc Om= (default: 0.3) Omega matter overdens= (200) overdensity which defines the virial radius wrtcrit= (False) if True, the overdensity is wrt the critical density rather than the mean matter density ro=, vo= distance and velocity scales for translation into internal units (default from configuration file) OUTPUT: (none) HISTORY: 2010-07-09 - Written - Bovy (NYU) 2014-04-03 - Initialization w/ concentration and mass - Bovy (IAS) """ Potential.__init__(self,amp=amp,ro=ro,vo=vo,amp_units='mass') if _APY_LOADED and isinstance(a,units.Quantity): a= a.to(units.kpc).value/self._ro if conc is None: self.a= a self.alpha= 1 self.beta= 3 if normalize or \ (isinstance(normalize,(int,float)) \ and not isinstance(normalize,bool)): self.normalize(normalize) else: if wrtcrit: od= overdens/bovy_conversion.dens_in_criticaldens(self._vo, self._ro,H=H) else: od= overdens/bovy_conversion.dens_in_meanmatterdens(self._vo, self._ro, H=H,Om=Om) mvirNatural= mvir*100./bovy_conversion.mass_in_1010msol(self._vo, self._ro) rvir= (3.*mvirNatural/od/4./numpy.pi)**(1./3.) self.a= rvir/conc self._amp= mvirNatural/(numpy.log(1.+conc)-conc/(1.+conc)) self._scale= self.a self.hasC= True self.hasC_dxdv= True self._nemo_accname= 'NFW' return None
def run_simulations(sdf_pepper,sdf_smooth,options): # Setup apar grid apar= numpy.arange(options.amin,options.amax,options.dapar) # Check whether the output files already exist and if so, get the amin, amax, da from them if os.path.exists(options.outdens): # First read the file to check apar apar_file= numpy.genfromtxt(options.outdens,delimiter=',',max_rows=1) print numpy.amax(numpy.fabs(apar_file-apar)) assert numpy.amax(numpy.fabs(apar_file-apar)) < 10.**-5., 'apar according to options does not correspond to apar already in outdens' apar_file= numpy.genfromtxt(options.outomega,delimiter=',',max_rows=1) print numpy.amax(numpy.fabs(apar_file-apar)) assert numpy.amax(numpy.fabs(apar_file-apar)) < 10.**-5., 'apar according to options does not correspond to apar already in outomega' csvdens= open(options.outdens,'a') csvomega= open(options.outomega,'a') denswriter= csv.writer(csvdens,delimiter=',') omegawriter= csv.writer(csvomega,delimiter=',') else: csvdens= open(options.outdens,'w') csvomega= open(options.outomega,'w') denswriter= csv.writer(csvdens,delimiter=',') omegawriter= csv.writer(csvomega,delimiter=',') # First write apar and the smooth calculations denswriter.writerow([a for a in apar]) omegawriter.writerow([a for a in apar]) if sdf_smooth is None and options.stream.lower() == 'gd1like': sdf_smooth= gd1_util.setup_gd1model(age=options.age) elif sdf_smooth is None and options.stream.lower() == 'pal5like': sdf_smooth= pal5_util.setup_pal5model(age=options.age) dens_unp= [sdf_smooth._density_par(a) for a in apar] denswriter.writerow(dens_unp) omega_unp= [sdf_smooth.meanOmega(a,oned=True) for a in apar] omegawriter.writerow(omega_unp) csvdens.flush() csvomega.flush() # Parse mass massrange= parse_mass(options.mass) if len(massrange) == 1: sample_GM= lambda: 10.**(massrange[0]-10.)\ /bovy_conversion.mass_in_1010msol(V0,R0) rate= options.timescdm*dNencdm(sdf_pepper, 10.**massrange[0],Xrs=options.Xrs, plummer=options.plummer, rsfac=options.rsfac, sigma=options.sigma) elif len(massrange) == 2: # Sample from power-law if not options.cutoff is None: sample_GM= lambda: powerlaw_wcutoff(massrange,options.cutoff) elif numpy.fabs(options.massexp+1.5) < 10.**-6.: sample_GM= lambda: 10.**(massrange[0]\ +(massrange[1]-massrange[0])\ *numpy.random.uniform())\ /bovy_conversion.mass_in_msol(V0,R0) else: sample_GM= lambda: (10.**((options.massexp+1.5)*massrange[0])\ +(10.**((options.massexp+1.5)*massrange[1])\ -10.**((options.massexp+1.5)*massrange[0]))\ *numpy.random.uniform())**(1./(options.massexp+1.5))\ /bovy_conversion.mass_in_msol(V0,R0) rate_range= numpy.arange(massrange[0]+0.5,massrange[1]+0.5,1) rate= options.timescdm\ *numpy.sum([dNencdm(sdf_pepper,10.**r,Xrs=options.Xrs, plummer=options.plummer,rsfac=options.rsfac, sigma=options.sigma) for r in rate_range]) if not options.cutoff is None: rate*= integrate.quad(lambda x: x**-1.5\ *numpy.exp(-10.**options.cutoff/x), 10.**massrange[0],10.**massrange[1])[0]\ /integrate.quad(lambda x: x**-1.5, 10.**massrange[0], 10.**massrange[1])[0] print "Using an overall rate of %f" % rate sample_rs= lambda x: rs(x*bovy_conversion.mass_in_1010msol(V0,R0)*10.**10., plummer=options.plummer,rsfac=options.rsfac) # Simulate start= time.time() ns= 0 while True: if options.nsamples is None and time.time() >= (start+options.dt*60.): break elif not options.nsamples is None and ns > options.nsamples: break ns+= 1 sdf_pepper.simulate(rate=rate,sample_GM=sample_GM,sample_rs=sample_rs, Xrs=options.Xrs,sigma=options.sigma/V0) # Compute density and meanOmega and save try: densOmega= numpy.array([sdf_pepper._densityAndOmega_par_approx(a) for a in apar]).T except IndexError: # no hit dens_unp= [sdf_smooth._density_par(a) for a in apar] omega_unp= [sdf_smooth.meanOmega(a,oned=True) for a in apar] denswriter.writerow(dens_unp) omegawriter.writerow(omega_unp) else: denswriter.writerow(list(densOmega[0])) omegawriter.writerow(list(densOmega[1])) csvdens.flush() csvomega.flush() csvdens.close() csvomega.close() return None