예제 #1
0
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))
예제 #2
0
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.
예제 #4
0
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)
예제 #5
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
예제 #6
0
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
예제 #7
0
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.
예제 #9
0
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
예제 #10
0
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.
예제 #11
0
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
예제 #12
0
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
예제 #13
0
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)
예제 #14
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
예제 #15
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 = 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
예제 #16
0
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)
예제 #18
0
    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
예제 #20
0
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)
예제 #21
0
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
예제 #23
0
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
예제 #24
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 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
예제 #26
0
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
예제 #27
0
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)
예제 #29
0
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
예제 #30
0
    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")
예제 #32
0
    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