예제 #1
0
def test_mass_in_msol():
    #Test the scaling, should be velocity^2 x position
    vofid, rofid = 200., 8.
    assert numpy.fabs(4. * bovy_conversion.mass_in_msol(vofid, rofid) /
                      bovy_conversion.mass_in_msol(2. * vofid, rofid) -
                      1.) < 10.**-10., 'mass_in_msol did not work as expected'
    assert numpy.fabs(2. * bovy_conversion.mass_in_msol(vofid, rofid) /
                      bovy_conversion.mass_in_msol(vofid, 2 * rofid) -
                      1.) < 10.**-10., 'mass_in_msol did not work as expected'
    return None
예제 #2
0
def MWBHRfo(ldeg, bdeg, dkpc):

    b = bdeg * par.degtorad
    l = ldeg * par.degtorad
    Rskpc = par.Rskpc
    Vs = par.Vs
    conversion = par.conversion
    Rpkpc = par.Rpkpc(ldeg, bdeg, dkpc)
    zkpc = dkpc * math.sin(b)
    be = (dkpc / Rskpc) * math.cos(b) - math.cos(l)
    coslam = be * (Rskpc / Rpkpc)

    MWPotential2014BH = [
        MWPotential2014,
        KeplerPotential(amp=4 * 10**6. /
                        bovy_conversion.mass_in_msol(par.Vs, par.Rskpc))
    ]

    rforce1 = evaluateRforces(
        MWPotential2014BH, Rpkpc / Rskpc, zkpc / Rskpc) * (
            (Vs * 1000.)**2.) / (Rskpc * par.kpctom)  #m/ss

    rfsun = evaluateRforces(MWPotential2014BH, Rskpc / Rskpc, 0.0 / Rskpc) * (
        (Vs * 1000.)**2.) / (Rskpc * par.kpctom)  #m/ss

    rf0 = rforce1 * coslam + rfsun * math.cos(l)  #m/ss
    rf = rf0 * math.cos(b) / par.c  # s-1
    return rf
예제 #3
0
def test_ChandrasekharDynamicalFrictionForce_varLambda():
    # Test that dynamical friction with variable Lambda for small r ranges
    # gives ~ the same result as using a constant Lambda that is the mean of
    # the variable lambda
    # Also tests that giving an axisymmetric list of potentials for the
    # density works
    from galpy.util import bovy_conversion
    from galpy.orbit import Orbit
    ro, vo = 8., 220.
    # Parameters
    GMs = 10.**9. / bovy_conversion.mass_in_msol(vo, ro)
    r_init = 3.
    dt = 2. / bovy_conversion.time_in_Gyr(vo, ro)
    # Compute evolution with variable ln Lambda
    cdf= potential.ChandrasekharDynamicalFrictionForce(\
        GMs=GMs,rhm=0.125,
        dens=potential.MWPotential2014,sigmar=lambda r: 1./numpy.sqrt(2.))
    o = Orbit([r_init, 0., 1., 0., 0., 0.])
    ts = numpy.linspace(0., dt, 1001)
    o.integrate(ts, [potential.MWPotential2014, cdf], method='odeint')
    lnLs = numpy.array([
        cdf.lnLambda(r, v) for (r, v) in zip(
            o.r(ts), numpy.sqrt(o.vx(ts)**2. + o.vy(ts)**2. + o.vz(ts)**2.))
    ])
    cdfc= potential.ChandrasekharDynamicalFrictionForce(\
        GMs=GMs,rhm=0.125,const_lnLambda=numpy.mean(lnLs),
        dens=potential.MWPotential2014,sigmar=lambda r: 1./numpy.sqrt(2.))
    oc = o()
    oc.integrate(ts, [potential.MWPotential2014, cdfc], method='odeint')
    assert numpy.fabs(
        oc.r(ts[-1]) - o.r(ts[-1])
    ) < 0.05, 'ChandrasekharDynamicalFrictionForce with variable lnLambda for a short radial range is not close to the calculation using a constant lnLambda'
    return None
def MWBHRfo(bdeg, ldeg, dkpc):

    b = bdeg * par.degtorad
    l = ldeg * par.degtorad
    Rskpc = par.Rskpc
    Vs = par.Vs
    conversion = par.conversion
    Rpkpc = Rpkpcfunc(dkpc, b, l, Rskpc)
    zkpc = dkpc * math.sin(b)
    be = (dkpc / Rskpc) * math.cos(b) - math.cos(l)
    coslam = be * (Rskpc / Rpkpc)

    MWPotential2014.append(
        KeplerPotential(amp=4 * 10**6. /
                        bovy_conversion.mass_in_msol(Vs, Rskpc)))

    rforce1 = evaluateRforces(MWPotential2014, Rpkpc / Rskpc,
                              zkpc / Rskpc) * bovy_conversion.force_in_kmsMyr(
                                  Vs, Rskpc)

    rfsun = evaluateRforces(MWPotential2014, Rskpc / Rskpc,
                            0.0 / Rskpc) * bovy_conversion.force_in_kmsMyr(
                                Vs, Rskpc)

    #rf = (rforce1-rfsun)*conversion*math.cos(b) # s-1
    rf0 = rforce1 * coslam + rfsun * math.cos(l)
    rf = rf0 * conversion * math.cos(b)  # s-1

    return rf
예제 #5
0
def test_ChandrasekharDynamicalFrictionForce_constLambda():
    # Test that the ChandrasekharDynamicalFrictionForce with constant Lambda
    # agrees with analytical solutions for circular orbits:
    # assuming that a mass remains on a circular orbit in an isothermal halo
    # with velocity dispersion sigma and for constant Lambda:
    # r_final^2 - r_initial^2 = -0.604 ln(Lambda) GM/sigma t
    # (e.g., B&T08, p. 648)
    from galpy.util import bovy_conversion
    from galpy.orbit import Orbit
    ro, vo = 8., 220.
    # Parameters
    GMs = 10.**9. / bovy_conversion.mass_in_msol(vo, ro)
    const_lnLambda = 7.
    r_init = 2.
    dt = 2. / bovy_conversion.time_in_Gyr(vo, ro)
    # Compute
    lp = potential.LogarithmicHaloPotential(normalize=1., q=1.)
    cdfc= potential.ChandrasekharDynamicalFrictionForce(\
        GMs=GMs,const_lnLambda=const_lnLambda,
        dens=lp) # don't provide sigmar, so it gets computed using galpy.df.jeans
    o = Orbit([r_init, 0., 1., 0., 0., 0.])
    ts = numpy.linspace(0., dt, 1001)
    o.integrate(ts, [lp, cdfc], method='odeint')
    r_pred = numpy.sqrt(o.r()**2. -
                        0.604 * const_lnLambda * GMs * numpy.sqrt(2.) * dt)
    assert numpy.fabs(
        r_pred - o.r(ts[-1])
    ) < 0.01, 'ChandrasekharDynamicalFrictionForce with constant lnLambda for circular orbits does not agree with analytical prediction'
    return None
예제 #6
0
def MWBHZfo(bdeg, ldeg, dkpc):

    b = bdeg * par.degtorad
    l = ldeg * par.degtorad
    Rskpc = par.Rskpc
    Vs = par.Vs
    conversion = par.conversion
    Rpkpc = Rpkpcfunc(dkpc, b, l, Rskpc)
    zkpc = dkpc * math.sin(b)
    '''
    bp= PowerSphericalPotentialwCutoff(alpha=1.8,rc=1.9/8.,normalize=0.05)
    mp= MiyamotoNagaiPotential(a=3./8.,b=0.28/8.,normalize=.6)
    np= NFWPotential(a=16./8.,normalize=.35)
    kp = KeplerPotential(amp=4*10**6./bovy_conversion.mass_in_msol(par.Vs,par.Rskpc))
    MWBH = [bp,mp,np,kp]
    zf1 = evaluatezforces(MWBH, Rpkpc/Rskpc,zkpc/Rskpc)*bovy_conversion.force_in_kmsMyr(Vs,Rskpc)
    '''
    MWPotential2014wBH = [
        MWPotential2014,
        KeplerPotential(amp=4 * 10**6. /
                        bovy_conversion.mass_in_msol(par.Vs, par.Rskpc))
    ]
    zf1 = evaluatezforces(MWPotential2014wBH, Rpkpc / Rskpc, zkpc /
                          Rskpc) * bovy_conversion.force_in_kmsMyr(Vs, Rskpc)

    Excz = zf1 * conversion * math.sin(b)  #s-1

    return Excz
예제 #7
0
    def __init__(self,progenitor_mass,progenitor=None,pot=None,
                 tdisrupt=None,leading=True,
                 meankvec=[2.,0.,0.3,0.,0.,0.],
                 sigkvec=[0.4,0.,0.4,0.5,0.5,0.],
                 ro=None,vo=None):
        """
        NAME:
        
           __init__
        PURPOSE:

           Initialize a stream spray DF model of a tidal stream

        INPUT:

           progenitor_mass - mass of the progenitor (can be Quantity)

           tdisrupt= (5 Gyr) time since start of disruption (can be Quantity)

           leading= (True) if True, model the leading part of the stream
                           if False, model the trailing part

           progenitor= progenitor orbit as Orbit instance (will be re-integrated, so don't bother integrating the orbit before)
           
           meankvec= (Fardal+2015-ish defaults) 
           
           sigkvec= (Fardal+2015-ish defaults) 
           
        OUTPUT:
        
            Instance
            
        HISTORY:
        
           2018-07-31 - Written - Bovy (UofT)

        """
        df.__init__(self,ro=ro,vo=vo)
        if _APY_LOADED and isinstance(progenitor_mass,units.Quantity):
            progenitor_mass= progenitor_mass.to(units.Msun).value\
                            /bovy_conversion.mass_in_msol(self._vo,self._ro)
        self._progenitor_mass= progenitor_mass
        if tdisrupt is None:
            self._tdisrupt= 5./bovy_conversion.time_in_Gyr(self._vo,self._ro)
        else:
            if _APY_LOADED and isinstance(tdisrupt,units.Quantity):
                tdisrupt= tdisrupt.to(units.Gyr).value\
                    /bovy_conversion.time_in_Gyr(self._vo,self._ro)
            self._tdisrupt= tdisrupt
        if pot is None: #pragma: no cover
            raise IOError("pot= must be set")
        self._pot= flatten_potential(pot)
        self._progenitor= progenitor()
        self._progenitor_times= numpy.linspace(0.,-self._tdisrupt,10001)
        self._progenitor.integrate(self._progenitor_times,self._pot)
        self._meankvec= numpy.array(meankvec)
        self._sigkvec= numpy.array(sigkvec)
        if leading: self._meankvec*= -1.
        return None
def powerlaw_wcutoff(massrange,cutoff):
    accept= False
    while not accept:
        prop= (10.**-(massrange[0]/2.)+(10.**-(massrange[1]/2.)\
                         -10.**(-massrange[0]/2.))\
                   *numpy.random.uniform())**-2.
        if numpy.random.uniform() < numpy.exp(-10.**cutoff/prop):
            accept= True
    return prop/bovy_conversion.mass_in_msol(V0,R0)
def powerlaw_wcutoff(massrange, cutoff):
    accept = False
    while not accept:
        prop= (10.**-(massrange[0]/2.)+(10.**-(massrange[1]/2.)\
                         -10.**(-massrange[0]/2.))\
                   *numpy.random.uniform())**-2.
        if numpy.random.uniform() < numpy.exp(-10.**cutoff / prop):
            accept = True
    return prop / bovy_conversion.mass_in_msol(V0, R0)
 def GMs(self,gms):
     if _APY_LOADED and isinstance(gms,units.Quantity):
         try:
             gms= gms.to(units.Msun).value\
                 /bovy_conversion.mass_in_msol(self._vo,self._ro)
         except units.UnitConversionError:
             # Try G x mass
             try:
                 gms= gms.to(units.pc*units.km**2/units.s**2)\
                     .value\
                     /bovy_conversion.mass_in_msol(self._vo,self._ro)\
                     /bovy_conversion._G
             except units.UnitConversionError:
                 raise units.UnitConversionError('GMs for %s should have units of mass or G x mass' % (type(self).__name__))
     self._amp*= gms/self._ms
     self._ms= gms
     # Reset the hash
     self._force_hash= None
     return None
예제 #11
0
def jacobiRadius(m, r, z):
    
    galMass = 0.

    for massElement in MWPotential2014:
        galMass += massElement.mass(r, z=z) * bovy_conversion.mass_in_msol(220., 8.) #MSun
        
    galactocentricDistance = np.sqrt(r**2. + z**2.)

    return galactocentricDistance * (m / galMass)**(1/3.)
 def GMs(self,gms):
     if _APY_LOADED and isinstance(gms,units.Quantity):
         try:
             gms= gms.to(units.Msun).value\
                 /bovy_conversion.mass_in_msol(self._vo,self._ro)
         except units.UnitConversionError:
             # Try G x mass
             try:
                 gms= gms.to(units.pc*units.km**2/units.s**2)\
                     .value\
                     /bovy_conversion.mass_in_msol(self._vo,self._ro)\
                     /bovy_conversion._G
             except units.UnitConversionError:
                 raise units.UnitConversionError('GMs for %s should have units of mass or G x mass' % (type(self).__name__))
     self._amp*= gms/self._ms
     self._ms= gms
     # Reset the hash
     self._force_hash= None
     return None
예제 #13
0
def to_galpy(cluster, do_key_params=False, ro=8.0, vo=220.0):
    """ Convert stellar positions/velocities, centre of mass, and orbital position and velocity to galpy units
    
    Parameters
    ----------
    cluster : class
        StarCluster
    do_key_params : bool
        call key_params to calculate key parameters after unit change (default: False)
    ro : float
        galpy radius scaling parameter
    vo : float
        galpy velocity scaling parameter

    Returns
    -------
    None

    History:
    -------
    2018 - Written - Webb (UofT)

    """
    if cluster.units != "kpckms" and cluster.units != "galpy":
        cluster.to_kpckms(do_key_params=False)

    if cluster.units == "kpckms":
        cluster.m = cluster.m / bovy_conversion.mass_in_msol(ro=ro, vo=vo)
        cluster.x /= ro
        cluster.y /= ro
        cluster.z /= ro
        cluster.vx /= vo
        cluster.vy /= vo
        cluster.vz /= vo

        cluster.xc /= ro
        cluster.yc /= ro
        cluster.zc /= ro
        cluster.vxc /= vo
        cluster.vyc /= vo
        cluster.vzc /= vo

        cluster.xgc /= ro
        cluster.ygc /= ro
        cluster.zgc /= ro
        cluster.vxgc /= vo
        cluster.vygc /= vo
        cluster.vzgc /= vo

        cluster.units = "galpy"

    cluster.rv3d()

    if do_key_params:
        cluster.key_params()
예제 #14
0
def MWBHZfo(ldeg, bdeg, dkpc):

    b = bdeg*par.degtorad
    l = ldeg*par.degtorad
    Rskpc = par.Rskpc
    Vs = par.Vs
    conversion = par.conversion
    Rpkpc = par.Rpkpc(ldeg, bdeg, dkpc)
    zkpc = dkpc*math.sin(b)
  
    MWPotential2014BH= [MWPotential2014,KeplerPotential(amp=4*10**6./bovy_conversion.mass_in_msol(par.Vs,par.Rskpc))]
    zf1 = evaluatezforces(MWPotential2014BH, Rpkpc/Rskpc,zkpc/Rskpc)*((Vs*1000.)**2.)/(Rskpc*par.kpctom) #m/ss
    Excz = zf1*math.sin(b)/par.c #s-1
    return Excz;
예제 #15
0
def MWBHRfo(ldeg, sigl, bdeg, sigb, dkpc, sigd):

    b = bdeg * par.degtorad
    l = ldeg * par.degtorad
    Rskpc = par.Rskpc
    Vs = par.Vs
    conversion = par.conversion
    Rpkpc = par.Rpkpc(ldeg, sigl, bdeg, sigb, dkpc, sigd)
    zkpc = dkpc * math.sin(b)
    be = (dkpc / Rskpc) * math.cos(b) - math.cos(l)
    coslam = be * (Rskpc / Rpkpc)
    '''
    bp= PowerSphericalPotentialwCutoff(alpha=1.8,rc=1.9/8.,normalize=0.05)
    mp= MiyamotoNagaiPotential(a=3./8.,b=0.28/8.,normalize=.6)
    np= NFWPotential(a=16./8.,normalize=.35)
    kp = KeplerPotential(amp=4*10**6./bovy_conversion.mass_in_msol(par.Vs,par.Rskpc))
    MWBH = [bp,mp,np,kp]

    rforce1 = evaluateRforces(MWBH, Rpkpc/Rskpc,zkpc/Rskpc)*bovy_conversion.force_in_kmsMyr(Vs,Rskpc)

    rfsun = evaluateRforces(MWBH, Rskpc/Rskpc,0.0/Rskpc)*bovy_conversion.force_in_kmsMyr(Vs,Rskpc)
    '''

    #MWPotential2014.append(KeplerPotential(amp=4*10**6./bovy_conversion.mass_in_msol(Vs,Rskpc)))

    #rforce1 = evaluateRforces(MWPotential2014, Rpkpc/Rskpc,zkpc/Rskpc)*bovy_conversion.force_in_kmsMyr(Vs,Rskpc)

    #rfsun = evaluateRforces(MWPotential2014, Rskpc/Rskpc,0.0/Rskpc)*bovy_conversion.force_in_kmsMyr(Vs,Rskpc)

    MWPotential2014wBH = [
        MWPotential2014,
        KeplerPotential(amp=4 * 10**6. /
                        bovy_conversion.mass_in_msol(par.Vs, par.Rskpc))
    ]
    rforce1 = evaluateRforces(MWPotential2014wBH, Rpkpc / Rskpc,
                              zkpc / Rskpc) * bovy_conversion.force_in_kmsMyr(
                                  Vs, Rskpc)

    rfsun = evaluateRforces(MWPotential2014wBH, Rskpc / Rskpc,
                            0.0 / Rskpc) * bovy_conversion.force_in_kmsMyr(
                                Vs, Rskpc)

    #rf = (rforce1-rfsun)*conversion*math.cos(b) # s-1
    rf0 = rforce1 * coslam + rfsun * math.cos(l)
    rf = rf0 * conversion * math.cos(b)  # s-1
    return rf
예제 #16
0
def test_ChandrasekharDynamicalFrictionForce_pickling():
    # Test that ChandrasekharDynamicalFrictionForce objects can/cannot be
    # pickled as expected
    import pickle
    from galpy.util import bovy_conversion
    ro, vo = 8., 220.
    # Parameters
    GMs = 10.**9. / bovy_conversion.mass_in_msol(vo, ro)
    # sigmar internally computed, should be able to be pickled
    # Compute evolution with variable ln Lambda
    cdf= potential.ChandrasekharDynamicalFrictionForce(\
        GMs=GMs,rhm=0.125,
        dens=potential.MWPotential2014,
        minr=0.5,maxr=2.)
    pickled = pickle.dumps(cdf)
    cdfu = pickle.loads(pickled)
    # Test a few values
    assert numpy.fabs(cdf.Rforce(1.,0.2,v=[1.,1.,0.])\
                          -cdfu.Rforce(1.,0.2,v=[1.,1.,0.])) < 1e-10, 'Pickling of ChandrasekharDynamicalFrictionForce object does not work as expected'
    assert numpy.fabs(cdf.zforce(2.,-0.2,v=[1.,1.,0.])\
                          -cdfu.zforce(2.,-0.2,v=[1.,1.,0.])) < 1e-10, 'Pickling of ChandrasekharDynamicalFrictionForce object does not work as expected'
    # Not providing dens = Logarithmic should also work
    cdf= potential.ChandrasekharDynamicalFrictionForce(\
        GMs=GMs,rhm=0.125,
        minr=0.5,maxr=2.)
    pickled = pickle.dumps(cdf)
    cdfu = pickle.loads(pickled)
    # Test a few values
    assert numpy.fabs(cdf.Rforce(1.,0.2,v=[1.,1.,0.])\
                          -cdfu.Rforce(1.,0.2,v=[1.,1.,0.])) < 1e-10, 'Pickling of ChandrasekharDynamicalFrictionForce object does not work as expected'
    assert numpy.fabs(cdf.zforce(2.,-0.2,v=[1.,1.,0.])\
                          -cdfu.zforce(2.,-0.2,v=[1.,1.,0.])) < 1e-10, 'Pickling of ChandrasekharDynamicalFrictionForce object does not work as expected'

    # Providing sigmar as a lambda function gives AttributeError
    sigmar = lambda r: 1. / r
    cdf= potential.ChandrasekharDynamicalFrictionForce(\
        GMs=GMs,rhm=0.125,
        dens=potential.MWPotential2014,sigmar=sigmar,
        minr=0.5,maxr=2.)
    if PY3:
        with pytest.raises(AttributeError) as excinfo:
            pickled = pickle.dumps(cdf)
    else:
        with pytest.raises(pickle.PicklingError) as excinfo:
            pickled = pickle.dumps(cdf)
    return None
예제 #17
0
def sample_galpy_potential(pot,n,rmin,rmax,ro=8.,vo=220.,coordinates='cartesian'):
    ran=np.random.rand(n)
    rad=np.linspace(rmin,rmax,n)
    
    try:
        menc=pot.mass(rad/ro,z=0,t=0,forceint=False)
    except:
        vc= potential.vcirc(pot,rad/ro,phi=0,t=0.,ro=ro,vo=vo,use_physical=False)
        menc=vc**2.*(rad/ro)

    menc*=bovy_conversion.mass_in_msol(ro=ro,vo=vo)       
    
    r=np.interp(ran, menc/menc[-1], rad)
    phi=2.0*np.pi*np.random.rand(n)
    theta=np.arccos(1.0-2.0*np.random.rand(n))
    
    x=r*np.sin(theta)*np.cos(phi)
    y=r*np.sin(theta)*np.sin(phi)
    z=r*np.cos(theta)
    
    sigma_v_1d=vo*potential.vcirc(pot,rad/ro,phi=0,t=0.,ro=ro,vo=vo,use_physical=False)/np.sqrt(3.)

    vx=np.random.normal(0.,sigma_v_1d,n)        
    vy=np.random.normal(0.,sigma_v_1d,n)        
    vz=np.random.normal(0.,sigma_v_1d,n) 
    
    if coordinates=='spherical':
        vr = (vx * np.sin(theta) * np.cos(phi)
            + vy * np.sin(theta) * np.sin(phi)
            + vz * np.cos(theta)
        )
        vtheta = (
            vx * np.cos(theta) * np.cos(phi)
            + vy * np.cos(theta) * np.sin(phi)
            - vz * np.sin(theta)
        )
        vphi = vx * -np.sin(phi) + vy * np.cos(phi)
        
        x,y,z=r,phi,theta
        vx,vy,vz=vr,vphi,vtheta
        
    elif coordinates=='cylindrical':
        x,y,z=bovy_coords.rect_to_cyl(x,y,z)
        vx,vy,vz=bovy_coords.rect_to_cyl_vec(vx,vy,vz,x,y,z,True)
    
    return x,y,z,vx,vy,vz
예제 #18
0
def VpratioMWBH(Rpkpc):
    #MWPotential2014.append(KeplerPotential(amp=4*10**6./bovy_conversion.mass_in_msol(par.Vs,par.Rskpc)))
    #a = vcirc(MWPotential2014,Rpkpc/par.Rskpc)
    '''
    bp= PowerSphericalPotentialwCutoff(alpha=1.8,rc=1.9/8.,normalize=0.05)
    mp= MiyamotoNagaiPotential(a=3./8.,b=0.28/8.,normalize=.6)
    np= NFWPotential(a=16./8.,normalize=.35)
    kp = KeplerPotential(amp=4*10**6./bovy_conversion.mass_in_msol(par.Vs,par.Rskpc))
    MWBH = [bp,mp,np,kp]
    a = vcirc(MWBH,Rpkpc/par.Rskpc)
    '''
    MWPotential2014wBH = [
        MWPotential2014,
        KeplerPotential(amp=4 * 10**6. /
                        bovy_conversion.mass_in_msol(par.Vs, par.Rskpc))
    ]
    a = vcirc(MWPotential2014wBH, Rpkpc / par.Rskpc)
    return a
def MWBHZfo(bdeg, ldeg, dkpc):

    b = bdeg * par.degtorad
    l = ldeg * par.degtorad
    Rskpc = par.Rskpc
    Vs = par.Vs
    conversion = par.conversion
    Rpkpc = Rpkpcfunc(dkpc, b, l, Rskpc)
    zkpc = dkpc * math.sin(b)

    MWPotential2014.append(
        KeplerPotential(amp=4 * 10**6. /
                        bovy_conversion.mass_in_msol(Vs, Rskpc)))
    zf1 = evaluatezforces(MWPotential2014, Rpkpc / Rskpc, zkpc /
                          Rskpc) * bovy_conversion.force_in_kmsMyr(Vs, Rskpc)
    Excz = zf1 * conversion * math.sin(b)  #s-1

    return Excz
예제 #20
0
def test_ChandrasekharDynamicalFrictionForce_evaloutsideminrmaxr():
    # Test that dynamical friction returns the expected force when evaluating
    # outside of the [minr,maxr] range over which sigmar is interpolated:
    # 0 at r < minr
    # using sigmar(r) for r > maxr
    from galpy.util import bovy_conversion
    ro, vo = 8., 220.
    # Parameters
    GMs = 10.**9. / bovy_conversion.mass_in_msol(vo, ro)
    # Compute evolution with variable ln Lambda
    sigmar = lambda r: 1. / r
    cdf= potential.ChandrasekharDynamicalFrictionForce(\
        GMs=GMs,rhm=0.125,
        dens=potential.MWPotential2014,sigmar=sigmar,
        minr=0.5,maxr=2.)
    # cdf 2 for checking r > maxr of cdf
    cdf2= potential.ChandrasekharDynamicalFrictionForce(\
        GMs=GMs,rhm=0.125,
        dens=potential.MWPotential2014,sigmar=sigmar,
        minr=0.5,maxr=4.)
    v = [0.1, 0., 0.]
    # r < minr
    assert numpy.fabs(
        cdf.Rforce(0.1, 0., v=v)
    ) < 1e-16, 'potential.ChandrasekharDynamicalFrictionForce at r < minr not equal to zero'
    assert numpy.fabs(
        cdf.zforce(0.1, 0., v=v)
    ) < 1e-16, 'potential.ChandrasekharDynamicalFrictionForce at r < minr not equal to zero'
    # r > maxr
    assert numpy.fabs(
        cdf.Rforce(3., 0., v=v) - cdf2.Rforce(3., 0., v=v)
    ) < 1e-10, 'potential.ChandrasekharDynamicalFrictionForce at r > maxr not as expected'
    assert numpy.fabs(
        cdf.zforce(3., 0., v=v) - cdf2.zforce(3., 0., v=v)
    ) < 1e-10, 'potential.ChandrasekharDynamicalFrictionForce at r > maxr not as expected'
    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 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
예제 #23
0
def _sample_galpy_potential(pot,
                            n,
                            rmin,
                            rmax,
                            ro=8.,
                            vo=220.,
                            coordinates='cartesian'):
    """Generate positions and velocities from galpy potentail

    Parameters
    ----------
    pot : class
        galpy potential
    N : int
        number of stars in the cluster (default: 1000)
    rmin : float
        minimum stellar radius (default: 0.01)
    rmax : float
        maximnum stellar radius (default: 100.)
    ro : float
        galpy distance scaling parameter
    vo : float
        galpy velocity scaling parameter
    coordinates : str
        coordinate system to return (default: cartesian)

    Returns
    -------
    x,y,z,vx,vy,vz : float
        positions and velocities of generated points

    History
    -------
    2020 - Written - Webb (UofT)
    """
    ran = np.random.rand(n)
    rad = np.linspace(rmin, rmax, n)

    try:
        menc = pot.mass(rad / ro, z=0, t=0, forceint=False)
    except:
        vc = potential.vcirc(pot,
                             rad / ro,
                             phi=0,
                             t=0.,
                             ro=ro,
                             vo=vo,
                             use_physical=False)
        menc = vc**2. * (rad / ro)

    menc *= bovy_conversion.mass_in_msol(ro=ro, vo=vo)

    r = np.interp(ran, menc / menc[-1], rad)
    phi = 2.0 * np.pi * np.random.rand(n)
    theta = np.arccos(1.0 - 2.0 * np.random.rand(n))

    x = r * np.sin(theta) * np.cos(phi)
    y = r * np.sin(theta) * np.sin(phi)
    z = r * np.cos(theta)

    sigma_v_1d = vo * potential.vcirc(
        pot, rad / ro, phi=0, t=0., ro=ro, vo=vo,
        use_physical=False) / np.sqrt(3.)

    vx = np.random.normal(0., sigma_v_1d, n)
    vy = np.random.normal(0., sigma_v_1d, n)
    vz = np.random.normal(0., sigma_v_1d, n)

    if coordinates == 'spherical':
        vr = (vx * np.sin(theta) * np.cos(phi) +
              vy * np.sin(theta) * np.sin(phi) + vz * np.cos(theta))
        vtheta = (vx * np.cos(theta) * np.cos(phi) +
                  vy * np.cos(theta) * np.sin(phi) - vz * np.sin(theta))
        vphi = vx * -np.sin(phi) + vy * np.cos(phi)

        x, y, z = r, phi, theta
        vx, vy, vz = vr, vphi, vtheta

    elif coordinates == 'cylindrical':
        x, y, z = bovy_coords.rect_to_cyl(x, y, z)
        vx, vy, vz = bovy_coords.rect_to_cyl_vec(vx, vy, vz, x, y, z, True)

    return x, y, z, vx, vy, vz
예제 #24
0
def fdotdotexcwBHcal(ldeg, bdeg, dkpc, mul, mub, Rpkpc, zkpc, f, fdotobs, vrad,
                     fex_pl, fex_z, fex_shk):

    Rskpc = par.Rskpc
    Vs = par.Vs
    conversion = par.conversion
    yrts = par.yrts
    c = par.c
    kpctom = par.kpctom
    Rs = Rskpc * kpctom
    mastorad = par.mastorad

    normpottoSI = par.normpottoSI
    normForcetoSI = par.normForcetoSI
    normjerktoSI = par.normjerktoSI

    b = bdeg * par.degtorad
    l = ldeg * par.degtorad

    fex_tot = fex_pl + fex_z + fex_shk

    #mub = mu_alpha #mas/yr
    #mul = mu_delta

    muT = (mub**2. + mul**2.)**0.5
    #MWPotential2014= [MWPotential2014,KeplerPotential(amp=4*10**6./bovy_conversion.mass_in_msol(par.Vs,par.Rskpc))]
    MWPot = [
        MWPotential2014,
        KeplerPotential(amp=4 * 10**6. /
                        bovy_conversion.mass_in_msol(par.Vs, par.Rskpc))
    ]

    appl = evaluateRforces(MWPot, Rpkpc / Rskpc, zkpc / Rskpc) * normForcetoSI
    aspl = evaluateRforces(MWPot, Rskpc / Rskpc, 0.0 / Rskpc) * normForcetoSI
    apz = evaluatezforces(MWPot, Rpkpc / Rskpc, zkpc / Rskpc) * normForcetoSI

    be = (dkpc / Rskpc) * math.cos(b) - math.cos(l)
    coslam = be * (Rskpc / Rpkpc)
    coslpluslam = math.cos(l) * coslam - (Rskpc * math.sin(l) /
                                          Rpkpc) * math.sin(l)

    aTl1 = -(appl * (Rskpc * math.sin(l) / Rpkpc) - aspl * math.sin(l))
    aTb1 = appl * coslam * math.sin(b) - apz * math.cos(b) + aspl * math.cos(
        l) * math.sin(b)
    aTnet1 = (aTl1**2. + aTb1**2.)**(0.5)
    alphaV1 = math.atan2(mub, mul) / par.degtorad
    alphaA1 = math.atan2(aTb1, aTl1) / par.degtorad
    if alphaV1 < 0.:
        alphaV = 360. + alphaV1
    else:
        alphaV = alphaV1

    if alphaA1 < 0.:
        alphaA = 360. + alphaA1
    else:
        alphaA = alphaA1
    alpha = abs(alphaA - alphaV)

    aT1 = 2. * appl * aspl * coslpluslam
    aT2 = (c * (fex_pl + fex_z))**2.
    aTsq = appl**2. + aspl**2. + aT1 + apz**2. - aT2
    #if aTsq < 0.0:
    aT = (appl**2. + aspl**2. + aT1 + apz**2. - aT2)**0.5

    Combterm = fdotdotSB1cal(
        ldeg, bdeg, dkpc, mul, mub, Rpkpc, zkpc, vrad, coslam,
        alpha, appl, apz, aspl, aT, MWPot) + fdotdotSB2cal(
            ldeg, bdeg, dkpc, mul, mub, Rpkpc, zkpc, fex_pl, fex_z, fex_shk,
            appl, apz, aspl) + fdotdotSB3cal(vrad, aT, muT, alpha)

    fddotfex = -Combterm + fdotdotSB4cal(f, fdotobs, fex_pl, fex_z, fex_shk)

    #fdotint = fdotobs-fs*fex_tot
    #fddotint = fddotobs-fs*fddotfex

    return fddotfex
예제 #25
0
def compute_impact_parameters_GC(timp,a,xs,ys,zs,pot=MWPotential2014,npart=64,sampling_low_file='',bmax=0.5,td=9.):
    
    '''
    timp : timpacts
    a,xs,ys,zs : list of array, each array decribes the stream at that time, no of arrays = timpacts
    sampling_low : low timpact object on to which the impacts from high timpact case will be set
    bmax: fixed max impact parameter 
       
    
    '''
    
    if pot != MWPotential2014 :
        chain_ind=int(pot)
        prog,pot,sigv,tvo=set_prog_potential(chain_ind)
        t_age= np.linspace(0.,td,1001)/bovy_conversion.time_in_Gyr(tvo,_REFR0)
        bovy_convert_mass=bovy_conversion.mass_in_msol(tvo,_REFR0)
        
    else : 
        #integrate their orbits td Gyr back,
        t_age= np.linspace(0.,td,1001)/bovy_conversion.time_in_Gyr(_REFV0,_REFR0)
        bovy_convert_mass=bovy_conversion.mass_in_msol(_REFV0,_REFR0)
       
    #load the GMCs
    #M,rs,coord=add_MCs(pot=pot,Mmin=Mmin,rand_rotate=rand_rotate,Rmax=Rmax,Rmin=Rmin)
    M,rs,coord=add_GCs()
 
    orbits=[]

    N=len(M)

    for ii in range(N):
    
        orbits.append(Orbit(coord[ii],radec=True,ro=8.,vo=220.,solarmotion=[-11.1,24.,7.25]).flip()) # flip flips the velocities for backwards integration
        orbits[ii].integrate(t_age,pot)
        
    min_sep_matrix=np.empty([N,len(timp)])
    apar_matrix=np.empty([N,len(timp)])

    #compute min_sep of each MC
    for kk in range(len(timp)):
        for jj in range(N) :
            x_mc=orbits[jj].x(timp[kk])
            y_mc=orbits[jj].y(timp[kk])
            z_mc=orbits[jj].z(timp[kk])

            min_sep,apar_min=compute_min_separation(x_mc,y_mc,z_mc,a[kk],xs[kk],ys[kk],zs[kk])

            min_sep_matrix[jj,kk]=min_sep
            apar_matrix[jj,kk]=apar_min
            
            
    impactb=[]
    impact_angle=[]
    vx_mc=[]
    vy_mc=[]
    vz_mc=[]
    tmin=[]
    rs_mc=[]
    M_mc=[]
    impactMC_ind=[]

    #just to get timpacts
    with open(sampling_low_file,'rb') as savefile:
        sdf_pepper_low= pickle.load(savefile,encoding='latin1')
            
    timpact_low=sdf_pepper_low._timpact
    
    c=0
    for ii in range(len(orbits)):

        bmax=bmax/_REFR0

        if min(min_sep_matrix[ii]) <= bmax :
            c+=1

            min_timpact_ind=np.argmin(min_sep_matrix[ii])

            impactMC_ind.append(ii)

            t_high=timp[min_timpact_ind]

            #round t_high to the nearest timpact in the low timpact sampling
            t_low=timpact_low[np.argmin(np.abs(timpact_low-t_high))]
            tmin.append(t_low)

            impactb.append(min_sep_matrix[ii,min_timpact_ind])
            impact_angle.append(apar_matrix[ii,min_timpact_ind]) # _sigMeanSign = -/+ = trail/lead

            rs_mc.append(rs[ii]/_REFR0)
            M_mc.append(M[ii]/bovy_convert_mass)
            #flip velocities
            vx_mc.append(-orbits[ii].vx(t_high))
            vy_mc.append(-orbits[ii].vy(t_high))
            vz_mc.append(-orbits[ii].vz(t_high))

    #combine vx,vy,vz to v
    v_mc=np.c_[vx_mc,vy_mc,vz_mc]
    print ("The stream had %i impacts"%c)
    
    M_mc=np.array(M_mc)
    rs_mc=np.array(rs_mc)
    v_mc=np.array(v_mc)
    impactb=np.array(impactb)
    impact_angle=np.array(impact_angle)
    tmin=np.array(tmin)
        
    return (impactMC_ind,M_mc,rs_mc,v_mc,impactb,impact_angle,tmin)
예제 #26
0
def test_mass_in_msol():
    #Test the scaling, should be velocity^2 x position
    vofid, rofid= 200., 8.
    assert numpy.fabs(4.*bovy_conversion.mass_in_msol(vofid,rofid)/bovy_conversion.mass_in_msol(2.*vofid,rofid)-1.) < 10.**-10., 'mass_in_msol did not work as expected'
    assert numpy.fabs(2.*bovy_conversion.mass_in_msol(vofid,rofid)/bovy_conversion.mass_in_msol(vofid,2*rofid)-1.) < 10.**-10., 'mass_in_msol did not work as expected'
    return None
예제 #27
0
    def __init__(self, amp=1., ro=None, vo=None, amp_units=None):
        """
        NAME:

           __init__

        PURPOSE:

           Initialize Force

        INPUT:

           amp - amplitude to be applied when evaluating the potential and its forces
           
           ro - physical distance scale (in kpc or as Quantity)

           vo - physical velocity scale (in km/s or as Quantity)

           amp_units - ('mass', 'velocity2', 'density') type of units that amp should have if it has units
           
        OUTPUT:

        HISTORY:
           2018-03-18 - Written to generalize Potential to force that may or may not be conservative - Bovy (UofT)
        """
        self._amp = amp
        # Parse ro and vo
        if ro is None:
            self._ro = config.__config__.getfloat('normalization', 'ro')
            self._roSet = False
        else:
            if _APY_LOADED and isinstance(ro, units.Quantity):
                ro = ro.to(units.kpc).value
            self._ro = ro
            self._roSet = True
        if vo is None:
            self._vo = config.__config__.getfloat('normalization', 'vo')
            self._voSet = False
        else:
            if _APY_LOADED and isinstance(vo, units.Quantity):
                vo = vo.to(units.km / units.s).value
            self._vo = vo
            self._voSet = True
        # Parse amp if it has units
        if _APY_LOADED and isinstance(self._amp, units.Quantity):
            # Try a bunch of possible units
            unitFound = False
            # velocity^2
            try:
                self._amp= self._amp.to(units.km**2/units.s**2).value\
                    /self._vo**2.
            except units.UnitConversionError:
                pass
            else:
                unitFound = True
                if not amp_units == 'velocity2':
                    raise units.UnitConversionError(
                        'amp= parameter of %s should have units of %s, but has units of velocity2 instead'
                        % (type(self).__name__, amp_units))
            if not unitFound:
                # mass
                try:
                    self._amp= self._amp.to(units.Msun).value\
                        /bovy_conversion.mass_in_msol(self._vo,self._ro)
                except units.UnitConversionError:
                    pass
                else:
                    unitFound = True
                    if not amp_units == 'mass':
                        raise units.UnitConversionError(
                            'amp= parameter of %s should have units of %s, but has units of mass instead'
                            % (type(self).__name__, amp_units))
            if not unitFound:
                # G x mass
                try:
                    self._amp= self._amp.to(units.pc*units.km**2/units.s**2)\
                        .value\
                        /bovy_conversion.mass_in_msol(self._vo,self._ro)\
                        /bovy_conversion._G
                except units.UnitConversionError:
                    pass
                else:
                    unitFound = True
                    if not amp_units == 'mass':
                        raise units.UnitConversionError(
                            'amp= parameter of %s should have units of %s, but has units of G x mass instead'
                            % (type(self).__name__, amp_units))
            if not unitFound:
                # density
                try:
                    self._amp= self._amp.to(units.Msun/units.pc**3).value\
                        /bovy_conversion.dens_in_msolpc3(self._vo,self._ro)
                except units.UnitConversionError:
                    pass
                else:
                    unitFound = True
                    if not amp_units == 'density':
                        raise units.UnitConversionError(
                            'amp= parameter of %s should have units of %s, but has units of density instead'
                            % (type(self).__name__, amp_units))
            if not unitFound:
                # G x density
                try:
                    self._amp= self._amp.to(units.km**2/units.s**2\
                                                /units.pc**2).value\
                        /bovy_conversion.dens_in_msolpc3(self._vo,self._ro)\
                        /bovy_conversion._G
                except units.UnitConversionError:
                    pass
                else:
                    unitFound = True
                    if not amp_units == 'density':
                        raise units.UnitConversionError(
                            'amp= parameter of %s should have units of %s, but has units of G x density instead'
                            % (type(self).__name__, amp_units))
            if not unitFound:
                # surface density
                try:
                    self._amp= self._amp.to(units.Msun/units.pc**2).value\
                        /bovy_conversion.surfdens_in_msolpc2(self._vo,self._ro)
                except units.UnitConversionError:
                    pass
                else:
                    unitFound = True
                    if not amp_units == 'surfacedensity':
                        raise units.UnitConversionError(
                            'amp= parameter of %s should have units of %s, but has units of surface density instead'
                            % (type(self).__name__, amp_units))
            if not unitFound:
                # G x surface density
                try:
                    self._amp= self._amp.to(units.km**2/units.s**2\
                                                /units.pc).value\
                        /bovy_conversion.surfdens_in_msolpc2(self._vo,self._ro)\
                        /bovy_conversion._G
                except units.UnitConversionError:
                    pass
                else:
                    unitFound = True
                    if not amp_units == 'surfacedensity':
                        raise units.UnitConversionError(
                            'amp= parameter of %s should have units of %s, but has units of G x surface density instead'
                            % (type(self).__name__, amp_units))
            if not unitFound:
                raise units.UnitConversionError(
                    'amp= parameter of %s should have units of %s; given units are not understood'
                    % (type(self).__name__, amp_units))
            else:
                # When amplitude is given with units, turn on physical output
                self._roSet = True
                self._voSet = True
        return None
예제 #28
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,
            )
예제 #29
0
파일: Force.py 프로젝트: jobovy/galpy
    def __init__(self,amp=1.,ro=None,vo=None,amp_units=None):
        """
        NAME:

           __init__

        PURPOSE:

           Initialize Force

        INPUT:

           amp - amplitude to be applied when evaluating the potential and its forces
           
           ro - physical distance scale (in kpc or as Quantity)

           vo - physical velocity scale (in km/s or as Quantity)

           amp_units - ('mass', 'velocity2', 'density') type of units that amp should have if it has units
           
        OUTPUT:

        HISTORY:
           2018-03-18 - Written to generalize Potential to force that may or may not be conservative - Bovy (UofT)
        """
        self._amp= amp
        # Parse ro and vo
        if ro is None:
            self._ro= config.__config__.getfloat('normalization','ro')
            self._roSet= False
        else:
            if _APY_LOADED and isinstance(ro,units.Quantity):
                ro= ro.to(units.kpc).value
            self._ro= ro
            self._roSet= True
        if vo is None:
            self._vo= config.__config__.getfloat('normalization','vo')
            self._voSet= False
        else:
            if _APY_LOADED and isinstance(vo,units.Quantity):
                vo= vo.to(units.km/units.s).value
            self._vo= vo
            self._voSet= True
        # Parse amp if it has units
        if _APY_LOADED and isinstance(self._amp,units.Quantity):
            # Try a bunch of possible units
            unitFound= False
            # velocity^2
            try:
                self._amp= self._amp.to(units.km**2/units.s**2).value\
                    /self._vo**2.
            except units.UnitConversionError: pass
            else:
                unitFound= True
                if not amp_units == 'velocity2':
                    raise units.UnitConversionError('amp= parameter of %s should have units of %s, but has units of velocity2 instead' % (type(self).__name__,amp_units))
            if not unitFound:
                # mass
                try:
                    self._amp= self._amp.to(units.Msun).value\
                        /bovy_conversion.mass_in_msol(self._vo,self._ro)
                except units.UnitConversionError: pass
                else:
                    unitFound= True
                    if not amp_units == 'mass':
                        raise units.UnitConversionError('amp= parameter of %s should have units of %s, but has units of mass instead' % (type(self).__name__,amp_units))
            if not unitFound:
                # G x mass
                try:
                    self._amp= self._amp.to(units.pc*units.km**2/units.s**2)\
                        .value\
                        /bovy_conversion.mass_in_msol(self._vo,self._ro)\
                        /bovy_conversion._G
                except units.UnitConversionError: pass
                else:
                    unitFound= True
                    if not amp_units == 'mass':
                        raise units.UnitConversionError('amp= parameter of %s should have units of %s, but has units of G x mass instead' % (type(self).__name__,amp_units))
            if not unitFound:
                # density
                try:
                    self._amp= self._amp.to(units.Msun/units.pc**3).value\
                        /bovy_conversion.dens_in_msolpc3(self._vo,self._ro)
                except units.UnitConversionError: pass
                else:
                    unitFound= True
                    if not amp_units == 'density':
                        raise units.UnitConversionError('amp= parameter of %s should have units of %s, but has units of density instead' % (type(self).__name__,amp_units))
            if not unitFound:
                # G x density
                try:
                    self._amp= self._amp.to(units.km**2/units.s**2\
                                                /units.pc**2).value\
                        /bovy_conversion.dens_in_msolpc3(self._vo,self._ro)\
                        /bovy_conversion._G
                except units.UnitConversionError: pass
                else:
                    unitFound= True
                    if not amp_units == 'density':
                        raise units.UnitConversionError('amp= parameter of %s should have units of %s, but has units of G x density instead' % (type(self).__name__,amp_units))
            if not unitFound:
                # surface density
                try:
                    self._amp= self._amp.to(units.Msun/units.pc**2).value\
                        /bovy_conversion.surfdens_in_msolpc2(self._vo,self._ro)
                except units.UnitConversionError: pass
                else:
                    unitFound= True
                    if not amp_units == 'surfacedensity':
                        raise units.UnitConversionError('amp= parameter of %s should have units of %s, but has units of surface density instead' % (type(self).__name__,amp_units))
            if not unitFound:
                # G x surface density
                try:
                    self._amp= self._amp.to(units.km**2/units.s**2\
                                                /units.pc).value\
                        /bovy_conversion.surfdens_in_msolpc2(self._vo,self._ro)\
                        /bovy_conversion._G
                except units.UnitConversionError: pass
                else:
                    unitFound= True
                    if not amp_units == 'surfacedensity':
                        raise units.UnitConversionError('amp= parameter of %s should have units of %s, but has units of G x surface density instead' % (type(self).__name__,amp_units))
            if not unitFound:
                raise units.UnitConversionError('amp= parameter of %s should have units of %s; given units are not understood' % (type(self).__name__,amp_units))    
            else:
                # When amplitude is given with units, turn on physical output
                self._roSet= True
                self._voSet= True
        return None
예제 #30
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
예제 #31
0
def fdotdotSB3calBH(ldeg, bdeg, dkpc, mul, mub, vrad):

    Rskpc = par.Rskpc
    Vs = par.Vs
    conversion = par.conversion
    yrts = par.yrts
    c = par.c
    kpctom = par.kpctom
    Rs = Rskpc * kpctom
    mastorad = par.mastorad

    normpottoSI = par.normpottoSI
    normForcetoSI = par.normForcetoSI
    normjerktoSI = par.normjerktoSI

    b = bdeg * par.degtorad
    l = ldeg * par.degtorad

    Rpkpc = par.Rpkpc(ldeg, bdeg, dkpc)

    zkpc = par.z(ldeg, bdeg, dkpc)

    fex_pl = excGalBH.Expl(ldeg, bdeg, dkpc)

    fex_z = excGalBH.Exz(ldeg, bdeg, dkpc)

    fex_shk = Shk.Exshk(dkpc, mul, mub)

    fex_tot = fex_pl + fex_z + fex_shk

    #mub = mu_alpha #mas/yr
    #mul = mu_delta

    muT = (mub**2. + mul**2.)**0.5
    #MWPotential2014= [MWPotential2014,KeplerPotential(amp=4*10**6./bovy_conversion.mass_in_msol(par.Vs,par.Rskpc))]
    MWPot = [
        MWPotential2014,
        KeplerPotential(amp=4 * 10**6. /
                        bovy_conversion.mass_in_msol(par.Vs, par.Rskpc))
    ]

    appl = evaluateRforces(MWPot, Rpkpc / Rskpc, zkpc / Rskpc) * normForcetoSI
    aspl = evaluateRforces(MWPot, Rskpc / Rskpc, 0.0 / Rskpc) * normForcetoSI
    apz = evaluatezforces(MWPot, Rpkpc / Rskpc, zkpc / Rskpc) * normForcetoSI

    be = (dkpc / Rskpc) * math.cos(b) - math.cos(l)
    coslam = be * (Rskpc / Rpkpc)
    coslpluslam = math.cos(l) * coslam - (Rskpc * math.sin(l) /
                                          Rpkpc) * math.sin(l)

    aTl1 = -(appl * (Rskpc * math.sin(l) / Rpkpc) - aspl * math.sin(l))
    aTb1 = appl * coslam * math.sin(b) - apz * math.cos(b) + aspl * math.cos(
        l) * math.sin(b)
    aTnet1 = (aTl1**2. + aTb1**2.)**(0.5)
    alphaV1 = math.atan2(mub, mul) / par.degtorad
    alphaA1 = math.atan2(aTb1, aTl1) / par.degtorad
    if alphaV1 < 0.:
        alphaV = 360. + alphaV1
    else:
        alphaV = alphaV1

    if alphaA1 < 0.:
        alphaA = 360. + alphaA1
    else:
        alphaA = alphaA1
    alpha = abs(alphaA - alphaV)

    aT1 = 2. * appl * aspl * coslpluslam
    aT2 = (c * (fex_pl + fex_z))**2.
    aTsq = appl**2. + aspl**2. + aT1 + apz**2. - aT2
    #if aTsq < 0.0:
    aT = (appl**2. + aspl**2. + aT1 + apz**2. - aT2)**0.5

    yrts = par.yrts
    c = par.c
    mastorad = par.mastorad

    #tsbvrad = (1./c)*(3.*(1000.0*vrad)*(((mastorad/yrts)*muT)**2.))
    tsbt = (1. / c) * (aT * ((mastorad / yrts) * muT) * math.cos(alpha) - 3. *
                       (1000.0 * vrad) * (((mastorad / yrts) * muT)**2.))
    return tsbt
예제 #32
0
        ax = axs[i, j]

        print('')
        print('')
        print(row['Name'])
        x, y, z = row['X'] - 8., row['Y'], row['Z']

        print(x, y, z)

        galMass = 0.

        #bulge, bar, disk
        for massElement in MWPotential2014:

            galMass += massElement.mass(np.sqrt(x**2. + y**2.),
                                        z=z) * bovy_conversion.mass_in_msol(
                                            220., 8.)

        gcDist = np.sqrt(x**2. + y**2. + z**2.)
        jacobiRadius = 3. * gcDist * (gcMasses[row['ID']] / galMass)**(1 / 3.)

        print('enclosed mass: %.02e' % (galMass))
        print('gcDist: %.03f kpc' % (gcDist))
        print('jacobiRadius: %.03f pc' % (jacobiRadius * 1000.))

        if row['Name'] == 'omega Cen':
            ax.annotate(r'$\omega$ Cen',
                        xy=(0.6, 0.8),
                        xycoords='axes fraction',
                        fontsize=16)
        else:
            ax.annotate(row['Name'],
예제 #33
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)
#sdf_smooth= pal5_util.setup_pal5model(age=9.)
#sdf_pepper= pal5_util.setup_pal5model(singleImpact=True)
#
#

if 0:
    sdf_pepper_t = pal5_util.setup_pal5model(timpact=[1.])
    sdf_pepper_l = pal5_util.setup_pal5model(timpact=[1.], leading=True)
    massrange = [7., 9.]
    massexp = -2.
    sp = sdf_pepper_l
    sample_GM= lambda: (10.**((massexp+1.5)*massrange[0])\
                            +(10.**((massexp+1.5)*massrange[1])\
                                  -10.**((massexp+1.5)*massrange[0]))\
                            *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.,
def simulate_subhalos_vary_amp_slope_mwdm(sdf_pepper,
                                          m_wdm,
                                          mf_slope=-1.9,
                                          c0kpc=2.02 * 10**(-13),
                                          r=20.,
                                          Xrs=5.,
                                          sigma=120. / 220.):
    '''
    Sample amp and slope such that dN/dM = amp*M^slope and simulate subhalo impacts
    '''

    Mbin_edge = [5., 6., 7., 8., 9.]
    Nbins = len(Mbin_edge) - 1
    #compute number of subhalos in each mass bin
    nden_bin = np.empty(Nbins)
    rate_bin = np.empty(Nbins)
    for ll in range(Nbins):
        nden_bin[ll] = nsub_wdm(Mbin_edge[ll],
                                Mbin_edge[ll + 1],
                                m_wdm=m_wdm,
                                r=r,
                                c0kpc=c0kpc,
                                mf_slope=mf_slope)
        Mmid = 10**(0.5 * (Mbin_edge[ll] + Mbin_edge[ll + 1]))
        rate_bin[ll] = sdf_pepper.subhalo_encounters(sigma=sigma,
                                                     nsubhalo=nden_bin[ll],
                                                     bmax=Xrs *
                                                     rs(Mmid, plummer=True))

    rate = np.sum(rate_bin)

    Nimpact = numpy.random.poisson(rate)

    norm = 1. / quad(lambda M: fac(M, m_wdm) * (
        (M)**(mf_slope + 0.5)), 10**(Mbin_edge[0]), 10**(Mbin_edge[Nbins]))[0]

    def cdf(M):
        return quad(lambda M: norm * fac(M, m_wdm) * (M)**(mf_slope + 0.5),
                    10**Mbin_edge[0], M)[0]

    MM = numpy.linspace(Mbin_edge[0], Mbin_edge[Nbins], 10000)

    cdfl = [cdf(i) for i in 10**MM]
    icdf = interpolate.InterpolatedUnivariateSpline(cdfl, 10**MM, k=1)
    timpact_sub = numpy.array(sdf_pepper._uniq_timpact)[numpy.random.choice(
        len(sdf_pepper._uniq_timpact), size=Nimpact, p=sdf_pepper._ptimpact)]
    # Sample angles from the part of the stream that existed then
    impact_angle_sub = numpy.array([
        sdf_pepper._icdf_stream_len[ti](numpy.random.uniform())
        for ti in timpact_sub
    ])

    sample_GM = lambda: icdf(numpy.random.uniform()
                             ) / bovy_conversion.mass_in_msol(vo, ro)
    GM_sub = numpy.array([sample_GM() for a in impact_angle_sub])
    rs_sub = numpy.array(
        [rs(gm * bovy_conversion.mass_in_msol(vo, ro)) for gm in GM_sub])
    # impact b
    impactb_sub = (2. * numpy.random.uniform(size=len(impact_angle_sub)) -
                   1.) * Xrs * rs_sub
    # velocity

    subhalovel_sub = numpy.empty((len(impact_angle_sub), 3))
    for ii in range(len(timpact_sub)):
        subhalovel_sub[ii] = sdf_pepper._draw_impact_velocities(
            timpact_sub[ii], sigma, impact_angle_sub[ii], n=1)[0]
    # Flip angle sign if necessary
    #if not sdf_pepper._gap_leading: impact_angles*= -1.
    #angles not flipped, flip them after including angles from GMC and GC impacts
    return impact_angle_sub, impactb_sub, subhalovel_sub, timpact_sub, GM_sub, rs_sub
def compute_impact_parameters_GMC(timp,
                                  a,
                                  xs,
                                  ys,
                                  zs,
                                  pot=MWPotential2014,
                                  npart=64,
                                  sampling_low_file='',
                                  imp_fac=5.,
                                  Mmin=10**6.,
                                  rand_rotate=False):
    '''
    timp : timpacts
    a,xs,ys,zs : list of array, each array decribes the stream at that time, no of arrays = timpacts
    sampling_low : low timpact object on to which the impacts from high timpact case will be set
    imp_fac: X where bmax= X.r_s
    Mmin min mass above which all GMCs will be considered for impact
    rand_rotate : give the GMCs an ol' shaka shaka along phi
    
    '''

    if pot != MWPotential2014:
        chain_ind = int(pot)
        prog, pot, sigv, tvo = set_prog_potential(chain_ind)
        t_age = np.linspace(0., 5., 1001) / bovy_conversion.time_in_Gyr(
            tvo, _REFR0)
        bovy_convert_mass = bovy_conversion.mass_in_msol(tvo, _REFR0)

    else:
        #integrate their orbits 5 Gyr back,
        t_age = np.linspace(0., 5., 1001) / bovy_conversion.time_in_Gyr(
            _REFV0, _REFR0)
        bovy_convert_mass = bovy_conversion.mass_in_msol(_REFV0, _REFR0)

    #load the GMCs
    M, rs, coord = add_MCs(pot=pot, Mmin=Mmin, rand_rotate=rand_rotate)

    orbits = []

    N = len(M)

    for ii in range(N):

        orbits.append(Orbit(coord[ii]).flip()
                      )  # flip flips the velocities for backwards integration
        orbits[ii].integrate(t_age, pot)

    min_sep_matrix = np.empty([N, len(timp)])
    apar_matrix = np.empty([N, len(timp)])

    #compute min_sep of each MC
    for kk in range(len(timp)):
        for jj in range(N):
            x_mc = orbits[jj].x(timp[kk])
            y_mc = orbits[jj].y(timp[kk])
            z_mc = orbits[jj].z(timp[kk])

            min_sep, apar_min = compute_min_separation(x_mc, y_mc, z_mc, a[kk],
                                                       xs[kk], ys[kk], zs[kk])

            min_sep_matrix[jj, kk] = min_sep
            apar_matrix[jj, kk] = apar_min

    impactb = []
    impact_angle = []
    vx_mc = []
    vy_mc = []
    vz_mc = []
    tmin = []
    rs_mc = []
    M_mc = []
    impactMC_ind = []

    if npart > 1:
        #just to get timpacts
        with open(sampling_low_file, 'rb') as savefile:
            sdf_pepper_low = pickle.load(savefile, encoding='latin1')

        timpact_low = sdf_pepper_low._timpact

        c = 0
        for ii in range(len(orbits)):

            bmax = imp_fac * rs[ii] / _REFR0

            if min(min_sep_matrix[ii]) <= bmax:
                c += 1

                min_timpact_ind = np.argmin(min_sep_matrix[ii])

                impactMC_ind.append(ii)

                t_high = timp[min_timpact_ind]

                #round t_high to the nearest timpact in the low timpact sampling
                t_low = timpact_low[np.argmin(np.abs(timpact_low - t_high))]
                tmin.append(t_low)

                impactb.append(min_sep_matrix[ii, min_timpact_ind])
                impact_angle.append(apar_matrix[
                    ii, min_timpact_ind])  # _sigMeanSign = -/+ = trail/lead

                rs_mc.append(rs[ii] / _REFR0)
                M_mc.append(M[ii] / bovy_convert_mass)
                #flip velocities
                vx_mc.append(-orbits[ii].vx(t_high))
                vy_mc.append(-orbits[ii].vy(t_high))
                vz_mc.append(-orbits[ii].vz(t_high))

        #combine vx,vy,vz to v
        v_mc = np.c_[vx_mc, vy_mc, vz_mc]
        print("The stream had %i impacts" % c)

    else:

        c = 0
        for ii in range(len(orbits)):

            bmax = imp_fac * rs[ii] / _REFR0

            if min(min_sep_matrix[ii]) <= bmax:
                c += 1

                min_timpact_ind = np.argmin(min_sep_matrix[ii])
                impactMC_ind.append(ii)
                t_imp_min = timp[min_timpact_ind]
                tmin.append(t_imp_min)

                impactb.append(min_sep_matrix[ii, min_timpact_ind])
                impact_angle.append(apar_matrix[
                    ii, min_timpact_ind])  # _sigMeanSign = -/+ = trail/lead

                rs_mc.append(rs[ii] / _REFR0)
                M_mc.append(M[ii] /
                            bovy_conversion.mass_in_msol(_REFV0, _REFR0))
                #flip velocities
                vx_mc.append(-orbits[ii].vx(t_imp_min))
                vy_mc.append(-orbits[ii].vy(t_imp_min))
                vz_mc.append(-orbits[ii].vz(t_imp_min))

        #combine vx,vy,vz to v
        v_mc = np.c_[vx_mc, vy_mc, vz_mc]
        print("The stream had %i impacts" % c)

    return (impactMC_ind, M_mc, rs_mc, v_mc, impactb, impact_angle, tmin)
예제 #37
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