def setup_sdf(pot,prog,sigv,td,ro,vo,multi=None,nTrackChunks=8,isob=None,
              trailing_only=False,verbose=True,useTM=True,logpot=False):
    """Simple function to setup the stream model"""
    if isob is None:
        if True or logpot:
            isob= 0.75
    if False:
        # Determine good one
        ts= numpy.linspace(0.,15.,1001)
        # Hack!
        epot= copy.deepcopy(pot)
        epot[2]._b= 1.
        epot[2]._b2= 1.
        epot[2]._isNonAxi= False
        epot[2]._aligned= True
        prog.integrate(ts,pot)
        estb= estimateBIsochrone(epot,
                                 prog.R(ts,use_physical=False),
                                 prog.z(ts,use_physical=False),
                                 phi=prog.phi(ts,use_physical=False))
        if estb[1] < 0.3: isob= 0.3
        elif estb[1] > 1.5: isob= 1.5
        else: isob= estb[1]
        if verbose: print(pot[2]._c, isob,estb)
    if not logpot and numpy.fabs(pot[2]._b-1.) > 0.05:
        aAI= actionAngleIsochroneApprox(pot=pot,b=isob,tintJ=1000.,
                                        ntintJ=30000)
    else:
        ts= numpy.linspace(0.,100.,10000)
        aAI= actionAngleIsochroneApprox(pot=pot,b=isob,tintJ=100.,
                                        ntintJ=10000,dt=ts[1]-ts[0])
    if useTM:
        aAT= actionAngleTorus(pot=pot,tol=0.001,dJ=0.0001)
    else:
        aAT= False
    try:
        sdf=\
            streamdf(sigv/vo,progenitor=prog,pot=pot,aA=aAI,
                     useTM=aAT,approxConstTrackFreq=True,
                     leading=True,nTrackChunks=nTrackChunks,
                     tdisrupt=td/bovy_conversion.time_in_Gyr(vo,ro),
                     ro=ro,vo=vo,R0=ro,
                     vsun=[-11.1,vo+24.,7.25],
                     custom_transform=_TKOP,
                     multi=multi,
                     nospreadsetup=True)
    except numpy.linalg.LinAlgError:
        sdf=\
            streamdf(sigv/vo,progenitor=prog,pot=pot,aA=aAI,
                     useTM=aAT,approxConstTrackFreq=True,
                     leading=True,nTrackChunks=nTrackChunks,
                     nTrackIterations=0,
                     tdisrupt=td/bovy_conversion.time_in_Gyr(vo,ro),
                     ro=ro,vo=vo,R0=ro,
                     vsun=[-11.1,vo+24.,7.25],
                     custom_transform=_TKOP,
                     multi=multi)
    return sdf
def calc_aA_sim(RvR,filename,snap_gc):
    # Calculate the action angle variables for a simulation and store
    if not os.path.exists(filename):
        aAI= actionAngleIsochroneApprox(pot=lp,b=0.8)
        nbatch= 20
        multiOut= multi.parallel_map(\
            lambda x: aAI.actionsFreqsAngles(RvR[x*nbatch:(x+1)*nbatch,0]/R0,
                                             RvR[x*nbatch:(x+1)*nbatch,1]/V0,
                                             RvR[x*nbatch:(x+1)*nbatch,2]/V0,
                                             RvR[x*nbatch:(x+1)*nbatch,3]/R0,
                                             RvR[x*nbatch:(x+1)*nbatch,4]/V0,
                                             RvR[x*nbatch:(x+1)*nbatch,5]),
            range(len(snap_gc)//nbatch),
            numcores=25)
        acfs= numpy.reshape(numpy.swapaxes(numpy.array(multiOut),0,1),
                            (9,numpy.prod(numpy.array(multiOut).shape)//9))
        # Write to file
        csvfile= open(filename,'w')
        writer= csv.writer(csvfile,delimiter=',')
        for jj in range(len(acfs[0])):
            writer.writerow([acfs[0][jj],acfs[1][jj],acfs[2][jj],
                                     acfs[3][jj],acfs[4][jj],acfs[5][jj],
                                     acfs[6][jj],acfs[7][jj],acfs[8][jj]])
            csvfile.flush()
        csvfile.close()
    else:
        acfs= numpy.loadtxt(filename,delimiter=',').T
    return acfs
Example #3
0
def nemo_prog_action_angle(x, y, z, vx, vy, vz, R0, V0, q, end_time, delta, C_use):
    """
    Parameter:
    -------------------------------------------------------
        x, y, z : initial position of the progenitor
        
        vx, vy, vz : initial velocity of the progenitor
        
        R0, V0  : radius and circular velocity
        
        q       : flattening parameter
        
        end_time : time when the simulation ended
        
        delta    : focal distance
        
        C_use    : True/False - to use C code or not
        
       
    Returns:
    -------------------------------------------------------
        action-angle coordinates and the omega (frequency) as an array
        array([jr,lz,jz,Omegar,Omegaphi,Omegaz,angler,anglephi,anglez])
        This is for the progenitor.

    """
    
    p   = LogarithmicHaloPotential(q = q, normalize = 1.)
    xyz_to_cyl_vect       = np.vectorize(xyz_to_cyl)
    vxvyvz_to_vrvtvz_vect = np.vectorize(vxvyvz_to_vrvtvz)
    
    R, zz , phi = xyz_to_cyl_vect(x, y, z)
    vR, vT, vz  = vxvyvz_to_vrvtvz_vect(x, y, z, vx, vy, vz)
    
    
    # convert to natural units for use in galpy
    R  /= R0
    zz /= R0
    vR /= V0
    vT /= V0
    vz /= V0
    
    # initializing the orbit
    o = Orbit(vxvv=[R, vR, vT, zz, vz, phi], ro=R0, vo=V0)
    
    # to convert the time units to normal
    t = end_time * (V0/R0)
    time = np.linspace(0., t, 1e4)
    o.integrate(time, p)
                    
    Rf   = o.R(time)
    zzf  = o.z(time)
    vRf  = o.vR(time)
    vTf  = o.vT(time)
    vzf  = o.vz(time)
    phif = o.phi(time)
                    
    aAS = actionAngleIsochroneApprox(pot=p, b=0.8) #actionAngleStaeckel(pot = p, delta = delta, c = C_use)
    val = aAS.actionsFreqsAngles(Rf, vRf, vTf, zzf, vzf, phif)
    return val
Example #4
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 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
    with pytest.raises(ValueError) as excinfo:
        dum= streamgapdf(sigv/V0,progenitor=prog_unp_peri,pot=lp,aA=aAI,
                         leading=False,nTrackChunks=26,
                         nTrackIterations=1,
                         sigMeanOffset=4.5,
                         tdisrupt=10.88\
                             /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/conversion.time_in_Gyr(V0,R0),
                         impact_angle=2.34,
                         GM=10.**-2.\
                             /conversion.mass_in_1010msol(V0,R0),
                         rs=0.625/R0)
    return None
Example #5
0
def test_actionAngleTorus_isochroneApprox_actions():
    from galpy.potential import MWPotential2014
    from galpy.actionAngle import actionAngleTorus, \
        actionAngleIsochroneApprox
    aAIA = actionAngleIsochroneApprox(pot=MWPotential2014, b=0.8)
    tol = -2.5
    aAT = actionAngleTorus(pot=MWPotential2014, tol=tol)
    jr, jphi, jz = 0.075, 1.1, 0.05
    angler = numpy.array([0.])
    anglephi = numpy.array([numpy.pi])
    anglez = numpy.array([numpy.pi / 2.])
    # Calculate position from aAT
    RvR = aAT(jr, jphi, jz, angler, anglephi, anglez).T
    # Calculate actions from aAIA
    ji = aAIA(*RvR)
    djr = numpy.fabs((ji[0] - jr) / jr)
    dlz = numpy.fabs((ji[1] - jphi) / jphi)
    djz = numpy.fabs((ji[2] - jz) / jz)
    assert djr < 10.**tol, 'actionAngleTorus and actionAngleIsochroneApprox applied to MWPotential2014 potential disagree for Jr at %f%%' % (
        djr * 100.)
    assert dlz < 10.**tol, 'actionAngleTorus and actionAngleIsochroneApprox applied to MWPotential2014 potential disagree for Jr at %f%%' % (
        dlz * 100.)
    assert djz < 10.**tol, 'actionAngleTorus and actionAngleMWPotential2014 applied to MWPotential2014 potential disagree for Jr at %f%%' % (
        djz * 100.)
    return None
Example #6
0
def calc_aA_sim(RvR, filename, snap_gc):
    # Calculate the action angle variables for a simulation and store
    if not os.path.exists(filename):
        aAI = actionAngleIsochroneApprox(pot=lp, b=0.8)
        nbatch = 20
        multiOut= multi.parallel_map(\
            lambda x: aAI.actionsFreqsAngles(RvR[x*nbatch:(x+1)*nbatch,0]/R0,
                                             RvR[x*nbatch:(x+1)*nbatch,1]/V0,
                                             RvR[x*nbatch:(x+1)*nbatch,2]/V0,
                                             RvR[x*nbatch:(x+1)*nbatch,3]/R0,
                                             RvR[x*nbatch:(x+1)*nbatch,4]/V0,
                                             RvR[x*nbatch:(x+1)*nbatch,5]),
            range(len(snap_gc)//nbatch),
            numcores=25)
        acfs = numpy.reshape(numpy.swapaxes(numpy.array(multiOut), 0, 1),
                             (9, numpy.prod(numpy.array(multiOut).shape) // 9))
        # Write to file
        csvfile = open(filename, 'w')
        writer = csv.writer(csvfile, delimiter=',')
        for jj in range(len(acfs[0])):
            writer.writerow([
                acfs[0][jj], acfs[1][jj], acfs[2][jj], acfs[3][jj],
                acfs[4][jj], acfs[5][jj], acfs[6][jj], acfs[7][jj], acfs[8][jj]
            ])
            csvfile.flush()
        csvfile.close()
    else:
        acfs = numpy.loadtxt(filename, delimiter=',').T
    return acfs
Example #7
0
def test_setupimpact_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)
    # Should be including these:
    #                 GM=10.**-2.\
    #                     /bovy_conversion.mass_in_1010msol(V0,R0),
    #                 rs=0.625/R0)
    return None
Example #8
0
def nemo_coord_convert(pos, vel, q, delta, C_use, ro, vo, m, n):

    """
    Parameter:
    -------------------------------------------------------
        pos   : x, y, z position as an array
        
        vel   : vx, vy, vz velocities as an array
        
        q     : flattening parameter for Logarithmic potential
        
        delta : focal distance
        
        C_use : True/False - to use C code or not
        
        ro    : radius for conversio to natural units (usually 8 kpc)
        
        vo    : velocity conversio to natural units(usually 220 km/s)
        
    Returns:
    -------------------------------------------------------
        action-angle coordinates and the omega (frequency) as an array
        array([jr,lz,jz,Omegar,Omegaphi,Omegaz,angler,anglephi,anglez])
        This is for the tail.
    
    """
    
    # Logarithmic potential and action-angle function initiated
    p   = LogarithmicHaloPotential(q = q, normalize = 1.)
    aAS = actionAngleIsochroneApprox(pot=p, b=0.8)#actionAngleStaeckel(pot = p, delta = delta, c = C_use)
    
    
    # position and velocity in cartesian coordinates
    # This flips y and z and vy and vz columns
    x, y, z    = pos[0], pos[2], pos[1]
    vx, vy, vz = vel[0], vel[2], vel[1]
    
    # make these functions vectorizable to use with arrays
    xyz_to_cyl_vect       = np.vectorize(xyz_to_cyl)
    vxvyvz_to_vrvtvz_vect = np.vectorize(vxvyvz_to_vrvtvz)
    
    # position and velocity in cylindrical coordinates
    R, zz , phi = xyz_to_cyl_vect(x, y, z)
    vR, vT, vz  = vxvyvz_to_vrvtvz_vect(x, y, z, vx, vy, vz)
    
    ro = ro
    vo = vo
    
    # convert to natural units for use in galpy
    R  /= ro
    zz /= ro
    vR /= vo
    vT /= vo
    vz /= vo
    
    # action-angle and omega values
    val = aAS.actionsFreqsAngles(R[m:n],vR[m:n],vT[m:n],zz[m:n],vz[m:n],phi[m:n])
    
    return val
def aA_prog(ptype):
    """
    Parameters
    ----------------------------------------------------------------------------------
        ptype : potential type. It can be either "Log" for logarithmic potential or
                "MW" for Milky Way 2014 potential.
        
        
    Return
    ----------------------------------------------------------------------------------
        action-angle values of the progenitor for GD-1 stream given the potentia type
    """
    
    # setting up the action-angle instance
    if ptype == "Log":
        lp         = potential.LogarithmicHaloPotential(q=0.9, normalize=1.)
        aAS        = actionAngleIsochroneApprox(pot = lp, b=0.8)

    elif ptype == "MW":
        aAS        = actionAngleIsochroneApprox(pot = MWPotential2014, b=0.6, tintJ=1000,ntintJ=2000)
    
    # current position and velocity of the GD-1 stream progenitor in cartesian coordinates
    x, y, z    = np.array([12.4, 1.5, 7.1])
    vx, vy, vz = np.array([107., -243., -105.])

    # current position and velocity in cylindrical coordinate
    R, phi, zz = bovy_coords.rect_to_cyl(x, y, z)
    vR, vT, vz = bovy_coords.rect_to_cyl_vec(vx, vy, vz, x, y, z, cyl = False)
    
    ro = 8.0
    vo = 220.0

    # converting to galpy natural units
    R  /= ro
    zz /= ro
    vR /= vo
    vT /= vo
    vz /= vo

    # computing the action-angle coordinates
    val = aAS.actionsFreqsAngles(R, vR, vT, zz, vz, phi)

    return val
Example #10
0
def test_actionAngleTorus_isochroneApprox_freqsAngles():
    from galpy.potential import MWPotential2014
    from galpy.actionAngle import actionAngleTorus, \
        actionAngleIsochroneApprox
    aAIA = actionAngleIsochroneApprox(pot=MWPotential2014, b=0.8)
    tol = -3.5
    aAT = actionAngleTorus(pot=MWPotential2014, tol=tol)
    jr, jphi, jz = 0.075, 1.1, 0.05
    angler = numpy.array([0.1]) + numpy.linspace(0., numpy.pi, 21)
    angler = angler % (2. * numpy.pi)
    anglephi = numpy.array([numpy.pi]) + numpy.linspace(0., numpy.pi, 21)
    anglephi = anglephi % (2. * numpy.pi)
    anglez = numpy.array([numpy.pi / 2.]) + numpy.linspace(0., numpy.pi, 21)
    anglez = anglez % (2. * numpy.pi)
    # Calculate position from aAT
    RvRom = aAT.xvFreqs(jr, jphi, jz, angler, anglephi, anglez)
    # Calculate actions, frequencies, and angles from aAI
    ws = aAIA.actionsFreqsAngles(*RvRom[0].T)
    dOr = numpy.fabs((ws[3] - RvRom[1]))
    dOp = numpy.fabs((ws[4] - RvRom[2]))
    dOz = numpy.fabs((ws[5] - RvRom[3]))
    dar = numpy.fabs((ws[6] - angler))
    dap = numpy.fabs((ws[7] - anglephi))
    daz = numpy.fabs((ws[8] - anglez))
    dar[dar > numpy.pi] -= 2. * numpy.pi
    dar[dar < -numpy.pi] += 2. * numpy.pi
    dap[dap > numpy.pi] -= 2. * numpy.pi
    dap[dap < -numpy.pi] += 2. * numpy.pi
    daz[daz > numpy.pi] -= 2. * numpy.pi
    daz[daz < -numpy.pi] += 2. * numpy.pi
    assert numpy.all(
        dOr < 10.**tol
    ), 'actionAngleTorus and actionAngleIsochroneApprox applied to MWPotential2014 potential disagree for Or at %f%%' % (
        numpy.nanmax(dOr) * 100.)
    assert numpy.all(
        dOp < 10.**tol
    ), 'actionAngleTorus and actionAngleIsochroneApprox applied to MWPotential2014 potential disagree for Ophi at %f%%' % (
        numpy.nanmax(dOp) * 100.)
    assert numpy.all(
        dOz < 10.**tol
    ), 'actionAngleTorus and actionAngleIsochroneApprox applied to MWPotential2014 potential disagree for Oz at %f%%' % (
        numpy.nanmax(dOz) * 100.)
    assert numpy.all(
        dar < 10.**tol
    ), 'actionAngleTorus and actionAngleIsochroneApprox applied to MWPotential2014 potential disagree for ar at %f' % (
        numpy.nanmax(dar))
    assert numpy.all(
        dap < 10.**tol
    ), 'actionAngleTorus and actionAngleIsochroneApprox applied to MWPotential2014 potential disagree for aphi at %f' % (
        numpy.nanmax(dap))
    assert numpy.all(
        daz < 10.**tol
    ), 'actionAngleTorus and actionAngleIsochroneApprox applied to MWPotential2014 potential disagree for az at %f' % (
        numpy.nanmax(daz))
    return None
Example #11
0
def setup_gd1model(leading=True,
                   timpact=None,
                   hernquist=True,
                   age=9.,
                   singleImpact=False,
                   length_factor=1.,
                   **kwargs):
    lp = LogarithmicHaloPotential(normalize=1., q=0.9)
    aAI = actionAngleIsochroneApprox(pot=lp, b=0.8)
    obs = Orbit([
        1.56148083, 0.35081535, -1.15481504, 0.88719443, -0.47713334,
        0.12019596
    ])
    sigv = 0.365 / 2. * (9. / age)  #km/s, /2 bc tdis x2, adjust for diff. age
    if timpact is None:
        sdf = streamdf(sigv / 220.,
                       progenitor=obs,
                       pot=lp,
                       aA=aAI,
                       leading=leading,
                       nTrackChunks=11,
                       tdisrupt=age / bovy_conversion.time_in_Gyr(V0, R0),
                       Vnorm=V0,
                       Rnorm=R0)
    elif singleImpact:
        sdf = streamgapdf(sigv / 220.,
                          progenitor=obs,
                          pot=lp,
                          aA=aAI,
                          leading=leading,
                          nTrackChunks=11,
                          tdisrupt=age / bovy_conversion.time_in_Gyr(V0, R0),
                          Vnorm=V0,
                          Rnorm=R0,
                          timpact=timpact,
                          spline_order=3,
                          hernquist=hernquist,
                          **kwargs)
    else:
        sdf = streampepperdf(sigv / 220.,
                             progenitor=obs,
                             pot=lp,
                             aA=aAI,
                             leading=leading,
                             nTrackChunks=101,
                             tdisrupt=age /
                             bovy_conversion.time_in_Gyr(V0, R0),
                             Vnorm=V0,
                             Rnorm=R0,
                             timpact=timpact,
                             spline_order=1,
                             hernquist=hernquist,
                             length_factor=length_factor)
    sdf.turn_physical_off()
    return sdf
Example #12
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
Example #13
0
def test_sanders15_setup():
    #Imports
    from galpy.df import streamdf, 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])
    global sdf_sanders15
    V0, R0= 220., 8.
    sigv= 0.365*(10./2.)**(1./3.) # km/s
    sdf_sanders15= 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)
    assert not sdf_sanders15 is None, 'sanders15 streamgapdf setup did not work'
    # Also setup the unperturbed model
    global sdf_sanders15_unp
    sdf_sanders15_unp= streamdf(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)
    assert not sdf_sanders15_unp is None, \
        'sanders15 unperturbed streamdf setup did not work'
    return None
Example #14
0
def test_sanders15_setup():
    #Imports
    from galpy.df import streamdf, streamgapdf
    from galpy.orbit import Orbit
    from galpy.potential import LogarithmicHaloPotential
    from galpy.actionAngle import actionAngleIsochroneApprox
    from galpy.util import 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 sdf_sanders15
    V0, R0 = 220., 8.
    sigv = 0.365 * (10. / 2.)**(1. / 3.)  # km/s
    sdf_sanders15= streamgapdf(sigv/V0,progenitor=prog_unp_peri,pot=lp,aA=aAI,
                               leading=False,nTrackChunks=26,
                               nTrackIterations=1,
                               sigMeanOffset=4.5,
                               tdisrupt=10.88\
                                   /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/conversion.time_in_Gyr(V0,R0),
                               impact_angle=-2.34,
                               GM=10.**-2.\
                                   /conversion.mass_in_1010msol(V0,R0),
                               rs=0.625/R0)
    assert not sdf_sanders15 is None, 'sanders15 streamgapdf setup did not work'
    # Also setup the unperturbed model
    global sdf_sanders15_unp
    sdf_sanders15_unp= streamdf(sigv/V0,progenitor=prog_unp_peri,pot=lp,aA=aAI,
                               leading=False,nTrackChunks=26,
                               nTrackIterations=1,
                               sigMeanOffset=4.5,
                               tdisrupt=10.88\
                                   /conversion.time_in_Gyr(V0,R0),
                               Vnorm=V0,Rnorm=R0)
    assert not sdf_sanders15_unp is None, \
        'sanders15 unperturbed streamdf setup did not work'
    return None
Example #15
0
def setup_pal5model(leading=False,
                    timpact=None,
                    hernquist=True,
                    age=5.,
                    singleImpact=False,
                    length_factor=1.,
                    **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.8)
    sigv= 0.5*(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,
                      tdisrupt=age/bovy_conversion.time_in_Gyr(V0,R0),
                      Rnorm=R0,Vnorm=V0,R0=R0,
                      vsun=[-11.1,V0+24.,7.25],
                      custom_transform=_TPAL5)
    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),
                         Rnorm=R0,Vnorm=V0,R0=R0,
                         vsun=[-11.1,V0+24.,7.25],
                         custom_transform=_TPAL5,
                         timpact=timpact,
                         spline_order=3,
                         hernquist=hernquist,**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),
                            Rnorm=R0,Vnorm=V0,R0=R0,
                            vsun=[-11.1,V0+24.,7.25],
                            custom_transform=_TPAL5,
                            timpact=timpact,
                            spline_order=1,
                            hernquist=hernquist,
                            length_factor=length_factor)
    return sdf
Example #16
0
def test_actionAngleTorus_isochroneApprox_actions():
    from galpy.potential import MWPotential2014
    from galpy.actionAngle import actionAngleTorus, \
        actionAngleIsochroneApprox
    aAIA= actionAngleIsochroneApprox(pot=MWPotential2014,b=0.8)
    tol= -2.5
    aAT= actionAngleTorus(pot=MWPotential2014,tol=tol)
    jr,jphi,jz= 0.075,1.1,0.05
    angler= numpy.array([0.])
    anglephi= numpy.array([numpy.pi])
    anglez= numpy.array([numpy.pi/2.])
    # Calculate position from aAT
    RvR= aAT(jr,jphi,jz,angler,anglephi,anglez).T
    # Calculate actions from aAIA
    ji= aAIA(*RvR)
    djr= numpy.fabs((ji[0]-jr)/jr)
    dlz= numpy.fabs((ji[1]-jphi)/jphi)
    djz= numpy.fabs((ji[2]-jz)/jz)
    assert djr < 10.**tol, 'actionAngleTorus and actionAngleIsochroneApprox applied to MWPotential2014 potential disagree for Jr at %f%%' % (djr*100.)
    assert dlz < 10.**tol, 'actionAngleTorus and actionAngleIsochroneApprox applied to MWPotential2014 potential disagree for Jr at %f%%' % (dlz*100.) 
    assert djz < 10.**tol, 'actionAngleTorus and actionAngleMWPotential2014 applied to MWPotential2014 potential disagree for Jr at %f%%' % (djz*100.)
    return None
Example #17
0
def test_actionAngleTorus_isochroneApprox_freqsAngles():
    from galpy.potential import MWPotential2014
    from galpy.actionAngle import actionAngleTorus, \
        actionAngleIsochroneApprox
    aAIA= actionAngleIsochroneApprox(pot=MWPotential2014,b=0.8)
    tol= -3.5
    aAT= actionAngleTorus(pot=MWPotential2014,tol=tol)
    jr,jphi,jz= 0.075,1.1,0.05
    angler= numpy.array([0.1])+numpy.linspace(0.,numpy.pi,21)
    angler= angler % (2.*numpy.pi)
    anglephi= numpy.array([numpy.pi])+numpy.linspace(0.,numpy.pi,21)
    anglephi= anglephi % (2.*numpy.pi)
    anglez= numpy.array([numpy.pi/2.])+numpy.linspace(0.,numpy.pi,21)
    anglez= anglez % (2.*numpy.pi)
    # Calculate position from aAT
    RvRom= aAT.xvFreqs(jr,jphi,jz,angler,anglephi,anglez)
    # Calculate actions, frequencies, and angles from aAI
    ws= aAIA.actionsFreqsAngles(*RvRom[0].T)
    dOr= numpy.fabs((ws[3]-RvRom[1]))
    dOp= numpy.fabs((ws[4]-RvRom[2]))
    dOz= numpy.fabs((ws[5]-RvRom[3]))
    dar= numpy.fabs((ws[6]-angler))
    dap= numpy.fabs((ws[7]-anglephi))
    daz= numpy.fabs((ws[8]-anglez))
    dar[dar > numpy.pi]-= 2.*numpy.pi
    dar[dar < -numpy.pi]+= 2.*numpy.pi
    dap[dap > numpy.pi]-= 2.*numpy.pi
    dap[dap < -numpy.pi]+= 2.*numpy.pi
    daz[daz > numpy.pi]-= 2.*numpy.pi
    daz[daz < -numpy.pi]+= 2.*numpy.pi
    assert numpy.all(dOr < 10.**tol), 'actionAngleTorus and actionAngleIsochroneApprox applied to MWPotential2014 potential disagree for Or at %f%%' % (numpy.nanmax(dOr)*100.)
    assert numpy.all(dOp < 10.**tol), 'actionAngleTorus and actionAngleIsochroneApprox applied to MWPotential2014 potential disagree for Ophi at %f%%' % (numpy.nanmax(dOp)*100.) 
    assert numpy.all(dOz < 10.**tol), 'actionAngleTorus and actionAngleIsochroneApprox applied to MWPotential2014 potential disagree for Oz at %f%%' % (numpy.nanmax(dOz)*100.)
    assert numpy.all(dar < 10.**tol), 'actionAngleTorus and actionAngleIsochroneApprox applied to MWPotential2014 potential disagree for ar at %f' % (numpy.nanmax(dar))
    assert numpy.all(dap < 10.**tol), 'actionAngleTorus and actionAngleIsochroneApprox applied to MWPotential2014 potential disagree for aphi at %f' % (numpy.nanmax(dap))
    assert numpy.all(daz < 10.**tol), 'actionAngleTorus and actionAngleIsochroneApprox applied to MWPotential2014 potential disagree for az at %f' % (numpy.nanmax(daz))
    return None
Example #18
0
def setup_gd1model(leading=True,
                   timpact=None,
                   hernquist=True,
                   age=9.,
                   singleImpact=False,
                   length_factor=1.,
                   **kwargs):
    lp= LogarithmicHaloPotential(normalize=1.,q=0.9)
    aAI= actionAngleIsochroneApprox(pot=lp,b=0.8)
    obs= Orbit([1.56148083,0.35081535,-1.15481504,0.88719443,
                -0.47713334,0.12019596])
    sigv= 0.365/2.*(9./age) #km/s, /2 bc tdis x2, adjust for diff. age
    if timpact is None:
        sdf= streamdf(sigv/220.,progenitor=obs,pot=lp,aA=aAI,leading=leading,
                      nTrackChunks=11,
                      tdisrupt=age/bovy_conversion.time_in_Gyr(V0,R0),
                      Vnorm=V0,Rnorm=R0)
    elif singleImpact:
        sdf= streamgapdf(sigv/220.,progenitor=obs,pot=lp,aA=aAI,
                         leading=leading,
                         nTrackChunks=11,
                         tdisrupt=age/bovy_conversion.time_in_Gyr(V0,R0),
                         Vnorm=V0,Rnorm=R0,
                         timpact=timpact,
                         spline_order=3,
                         hernquist=hernquist,**kwargs)
    else:
        sdf= streampepperdf(sigv/220.,progenitor=obs,pot=lp,aA=aAI,
                            leading=leading,
                            nTrackChunks=101,
                            tdisrupt=age/bovy_conversion.time_in_Gyr(V0,R0),
                            Vnorm=V0,Rnorm=R0,
                            timpact=timpact,
                            spline_order=1,
                            hernquist=hernquist,
                            length_factor=length_factor)
    return sdf
Example #19
0
    def compute_AA(self, potential, dt=0.01 * u.Myr, AAi=None, method='S'):
        '''
            Compute action angle coordinates for a propagated orbit.
        '''
        from galpy.orbit import Orbit

        if (AAi is None):
            AAi = range(self.size)

        AAi = np.atleast_1d(AAi)
        # Integration time step
        self.dt = dt
        nsteps = np.ceil((self.tflight / self.dt).to('1').value)
        nsteps[nsteps < 100] = 100

        # Initialize position in cylindrical coords
        rho = self.r0 * np.sin(self.theta0)
        z = self.r0 * np.cos(self.theta0)
        phi = self.phi0

        #... and velocity
        vR = self.v0 * np.sin(self.thetav0) * np.cos(self.phiv0)
        vT = self.v0 * np.sin(self.thetav0) * np.sin(self.phiv0)
        vz = self.v0 * np.cos(self.thetav0)

        # Initialize empty arrays to save orbit data and integration steps
        self.orbits = [None] * self.size
        AA = [np.zeros((3, int(nsteps[i]))) for i in AAi]
        if (method != 'S'):
            from galpy.actionAngle import actionAngleIsochroneApprox, actionAngleAdiabatic
            aAA = actionAngleIsochroneApprox(pot=potential,
                                             c=True,
                                             ro=8.,
                                             vo=220.)
        else:
            from galpy.actionAngle import estimateDeltaStaeckel, actionAngleStaeckel

        k = 0
        for i in AAi:
            ts = np.linspace(0, 1, nsteps[i]) * self.tflight[i]

            self.orbits[i] = Orbit(
                vxvv=[rho[i], vR[i], vT[i], z[i], vz[i], phi[i]],
                solarmotion=self.solarmotion)
            self.orbits[i].integrate(ts, potential, method='dopr54_c')

            if (method == 'S'):
                delta = estimateDeltaStaeckel(potential,
                                              self.orbits[i].R(ts) * u.kpc,
                                              self.orbits[i].z(ts) * u.kpc)
                aAA = actionAngleStaeckel(pot=potential,
                                          c=True,
                                          ro=8.,
                                          vo=220.,
                                          delta=delta)

            AA[k] = aAA(self.orbits[i].R(ts) * u.kpc,
                        self.orbits[i].vR(ts) * u.km / u.s,
                        self.orbits[i].vT(ts) * u.km / u.s,
                        self.orbits[i].z(ts) * u.kpc,
                        self.orbits[i].vz(ts) * u.km / u.s)
            #AA[k] = aAA(self.orbits[i].R(ts)/8, self.orbits[i].vR(ts)/220, self.orbits[i].vT(ts)/220, self.orbits[i].z(ts)/8, self.orbits[i].vz(ts)/220)
            k += 1

        return AA
import astropy.units as u
import scipy
from astropy.coordinates import SkyCoord
from matplotlib.colors import LogNorm
import photErrorModel as pem
from scipy.interpolate import interp1d
#%pylab inline
R0, V0 = 8., 220.
save_figures = True

prog = 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.8)
sigv = 0.5

######################################################################
######################################################################
######################################################################

_RAPAL5 = 229.018 / 180. * numpy.pi
_DECPAL5 = -0.124 / 180. * numpy.pi
_TPAL5 = numpy.dot(
    numpy.array([[numpy.cos(_DECPAL5), 0.,
                  numpy.sin(_DECPAL5)], [0., 1., 0.],
                 [-numpy.sin(_DECPAL5), 0.,
                  numpy.cos(_DECPAL5)]]),
    numpy.array([[numpy.cos(_RAPAL5),
                  numpy.sin(_RAPAL5), 0.],
def setup_mockgd1model(leading=True,
                       pot=MWPotential2014,
                       timpact=None,
                       Zsun=0.025,
                       hernquist=True,
                       isob=0.8,
                       age=9.,
                       sigv=0.46,
                       singleImpact=False,
                       length_factor=1.,
                       **kwargs):

    aAI = actionAngleIsochroneApprox(pot=pot, b=isob)
    obs = Orbit.from_name("GD1")

    if timpact is None:
        sdf = streamdf(sigv / 220.,
                       progenitor=obs,
                       pot=pot,
                       aA=aAI,
                       leading=leading,
                       nTrackChunks=11,
                       vsun=[-11.1, 244., 7.25],
                       Zsun=Zsun,
                       tdisrupt=age / conversion.time_in_Gyr(V0, R0),
                       vo=V0,
                       ro=R0)
    elif singleImpact:
        sdf = streamgapdf(sigv / 220.,
                          progenitor=obs,
                          pot=pot,
                          aA=aAI,
                          leading=leading,
                          nTrackChunks=11,
                          vsun=[-11.1, 244., 7.25],
                          Zsun=Zsun,
                          tdisrupt=age / conversion.time_in_Gyr(V0, R0),
                          vo=V0,
                          ro=R0,
                          timpact=timpact,
                          spline_order=3,
                          hernquist=hernquist,
                          **kwargs)
    else:
        sdf = streampepperdf(sigv / 220.,
                             progenitor=obs,
                             pot=pot,
                             aA=aAI,
                             leading=leading,
                             nTrackChunks=101,
                             vsun=[-11.1, 244., 7.25],
                             Zsun=Zsun,
                             tdisrupt=age / conversion.time_in_Gyr(V0, R0),
                             vo=V0,
                             ro=R0,
                             timpact=timpact,
                             spline_order=1,
                             hernquist=hernquist,
                             length_factor=length_factor)
    sdf.turn_physical_off()  #original
    #obs.turn_physical_off()
    return sdf
Example #22
0
        0.71877924,
        -0.01519337,
        -0.01928001,
    ]

    pot = MWPotential2014Likelihood.setup_potential(p_b15, 1.0, False, False,
                                                    REFR0, REFV0)

    prog = Orbit(
        [229.018, -0.124, 23.2, -2.296, -2.257, -58.7],
        radec=True,
        ro=REFR0,
        vo=REFV0,
        solarmotion=[-11.1, 24.0, 7.25],
    )
    aAI = actionAngleIsochroneApprox(pot=pot, b=0.8)
    sigv = 0.2

    # ----------------------------------------------------------

    try:
        with open("output/sdf_trailing.pkl", "rb") as file:
            sdf_trailing = pickle.load(file)
    except Exception:
        sdf_trailing = streamdf(
            sigv / REFV0,
            progenitor=prog,
            pot=pot,
            aA=aAI,
            leading=False,
            nTrackChunks=11,
Example #23
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 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.\
                             /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\
                                        /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/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\
                                     /conversion.time_in_Gyr(V0,R0),
                                 Vnorm=V0,Rnorm=R0)
    assert not sdfl_sanders15_unp is None, \
        'sanders15 unperturbed streamdf setup did not work'
    return None
def setup_sdf(
    pot: potential.Potential,
    prog: Orbit,
    sigv: float,
    td: float,
    ro: float = REFR0,
    vo: float = REFV0,
    multi: Optional[bool] = None,
    nTrackChunks: float = 8,
    isob=None,
    trailing_only: bool = False,
    verbose: bool = True,
    useTM: bool = True,
) -> Tuple[Optional[streamdf], Optional[streamdf]]:
    """Setup Stream Distribution Function.

    Parameters
    ----------
    pot : Potential
    prog : Orbit
        Progenitor
    sigv : float
    td : float
    ro : float
    vo : float
    multi
        default None
    nTrackChunks: float
        default 8
    isob
        default None
    trailing_only: bool
        default False
    verbose: bool
        default True
    useTM: bool
        default True

    Returns
    -------
    sdf_trailing, sdf_leading: streamdf or None

    """
    if isob is None:
        # Determine good one
        ts = np.linspace(0.0, 150.0, 1001)
        # Hack!
        epot = copy.deepcopy(pot)
        epot[2]._b = 1.0
        epot[2]._b2 = 1.0
        epot[2]._isNonAxi = False
        epot[2]._aligned = True
        prog.integrate(ts, pot)
        estb = estimateBIsochrone(
            epot,
            prog.R(ts, use_physical=False),
            prog.z(ts, use_physical=False),
            phi=prog.phi(ts, use_physical=False),
        )
        if estb[1] < 0.3:
            isob = 0.3
        elif estb[1] > 1.5:
            isob = 1.5
        else:
            isob = estb[1]
    if verbose:
        print(pot[2]._c, isob)
    if np.fabs(pot[2]._b - 1.0) > 0.05:
        aAI = actionAngleIsochroneApprox(pot=pot,
                                         b=isob,
                                         tintJ=1000.0,
                                         ntintJ=30000)
    else:
        aAI = actionAngleIsochroneApprox(pot=pot, b=isob)
    if useTM:
        aAT = actionAngleTorus(pot=pot, tol=0.001, dJ=0.0001)
    else:
        aAT = False

    trailing_kwargs = dict(
        progenitor=prog,
        pot=pot,
        aA=aAI,
        useTM=aAT,
        approxConstTrackFreq=True,
        leading=False,
        nTrackChunks=nTrackChunks,
        tdisrupt=td / bovy_conversion.time_in_Gyr(vo, ro),
        ro=ro,
        vo=vo,
        R0=ro,
        vsun=[-11.1, vo + 24.0, 7.25],
        custom_transform=_TPAL5,
        multi=multi,
    )

    try:
        sdf_trailing = streamdf(sigv / vo, **trailing_kwargs)
    except np.linalg.LinAlgError:
        sdf_trailing = streamdf(sigv / vo,
                                nTrackIterations=0,
                                **trailing_kwargs)

    if trailing_only:

        sdf_leading = None

    else:

        leading_kwargs = dict(
            progenitor=prog,
            pot=pot,
            aA=aAI,
            useTM=aAT,
            approxConstTrackFreq=True,
            leading=True,
            nTrackChunks=nTrackChunks,
            tdisrupt=td / bovy_conversion.time_in_Gyr(vo, ro),
            ro=ro,
            vo=vo,
            R0=ro,
            vsun=[-11.1, vo + 24.0, 7.25],
            custom_transform=_TPAL5,
            multi=multi,
        )

        try:
            sdf_leading = streamdf(sigv / vo, **leading_kwargs)
        except np.linalg.LinAlgError:
            sdf_leading = streamdf(sigv / vo,
                                   nTrackIterations=0,
                                   **leading_kwargs)

    return sdf_trailing, sdf_leading
Example #25
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
Example #26
0
def setup_gd1model(leading=True,
                   pot=MWPotential2014,
                   timpact=None,
                   hernquist=True,
                   age=9.,
                   singleImpact=False,
                   length_factor=1.,
                   **kwargs):
    #lp= LogarithmicHaloPotential(normalize=1.,q=0.9)
    aAI = actionAngleIsochroneApprox(pot=pot, b=0.8)
    #obs= Orbit([1.56148083,0.35081535,-1.15481504,0.88719443,
    #            -0.47713334,0.12019596])
    #progenitor pos and vel from Bovy 1609.01298 and with corrected proper motion
    obs = Orbit(phi12_to_lb_6d(0, -0.82, 10.1, -8.5, -2.15, -257.),
                lb=True,
                solarmotion=[-11.1, 24., 7.25],
                ro=8.,
                vo=220.)

    sigv = 0.365 / 2. * (9. / age)  #km/s, /2 bc tdis x2, adjust for diff. age
    if timpact is None:
        sdf = streamdf(sigv / 220.,
                       progenitor=obs,
                       pot=pot,
                       aA=aAI,
                       leading=leading,
                       nTrackChunks=11,
                       vsun=[-11.1, 244., 7.25],
                       tdisrupt=age / bovy_conversion.time_in_Gyr(V0, R0),
                       Vnorm=V0,
                       Rnorm=R0)
    elif singleImpact:
        sdf = streamgapdf(sigv / 220.,
                          progenitor=obs,
                          pot=pot,
                          aA=aAI,
                          leading=leading,
                          nTrackChunks=11,
                          vsun=[-11.1, 244., 7.25],
                          tdisrupt=age / bovy_conversion.time_in_Gyr(V0, R0),
                          Vnorm=V0,
                          Rnorm=R0,
                          timpact=timpact,
                          spline_order=3,
                          hernquist=hernquist,
                          **kwargs)
    else:
        sdf = streampepperdf(sigv / 220.,
                             progenitor=obs,
                             pot=pot,
                             aA=aAI,
                             leading=leading,
                             nTrackChunks=101,
                             vsun=[-11.1, 244., 7.25],
                             tdisrupt=age /
                             bovy_conversion.time_in_Gyr(V0, R0),
                             Vnorm=V0,
                             Rnorm=R0,
                             timpact=timpact,
                             spline_order=1,
                             hernquist=hernquist,
                             length_factor=length_factor)
    #sdf.turn_physical_off()  #original
    obs.turn_physical_off()
    return sdf
Example #27
0
def calc_actions(snapfile=None,first=0):
    #Setup potential and actionAngle object
    lp= potential.LogarithmicHaloPotential(normalize=1.,q=0.9)
    aA= actionAngleIsochroneApprox(pot=lp,b=0.8)
    # Load snapshot and convert to cylindrical coordinates
    xvid= numpy.loadtxt(snapfile)
    xv= xvid[:,:6]
    id= xvid[:,6]
    xv= xv[numpy.argsort(id)]
    id= id[numpy.argsort(id)].astype(int)
    R,phi,Z= bovy_coords.rect_to_cyl(xv[:,0],xv[:,1],xv[:,2])
    vR,vT,vZ= bovy_coords.rect_to_cyl_vec(xv[:,3],xv[:,4],xv[:,5],R,phi,Z,
                                          cyl=True)
    R/= 8.
    Z/= 8.
    vR/= 220.
    vT/= 220.
    vZ/= 220.
    if False: #Used for testing
        R= R[0:100]
        vR= vR[0:100]
        vT= vT[0:100]
        Z= Z[0:100]
        vZ= vZ[0:100]
        phi= phi[0:100]
    nx= len(R)
    if first:
        R= R[:nx//2]
        vR= vR[:nx//2]
        vT= vT[:nx//2]
        Z= Z[:nx//2]
        vZ= vZ[:nx//2]
        phi= phi[:nx//2]
        id= id[:nx//2]
    else:
        R= R[nx//2:]
        vR= vR[nx//2:]
        vT= vT[nx//2:]
        Z= Z[nx//2:]
        vZ= vZ[nx//2:]
        phi= phi[nx//2:]
        id= id[nx//2:]
    nx/= 2
    #calculation actions, frequencies, and angles
    #Processes in batches to not run out of memory
    if first:
        csvfilename= snapfile.replace('.txt','_aA1.txt')
    else:
        csvfilename= snapfile.replace('.txt','_aA2.txt')
    if os.path.exists(csvfilename):
        #Don't recalculate those that have already been calculated
        nstart= int(subprocess.check_output(['wc','-l',csvfilename]).split(' ')[0])
        csvfile= open(csvfilename,'ab')
    else:
        csvfile= open(csvfilename,'wb')
        nstart= 0
    if nstart >= nx: return 1 #Done already
    print "Starting from %i ..." % nstart
    nx-= nstart
    writer= csv.writer(csvfile,delimiter=',')
    nbatch= 20
    for ii in range(nx//nbatch):
        print "Working on batch %i out of %i ..." % (ii+1,nx//nbatch)
        tR= R[nstart+ii*nbatch:numpy.amin([nstart+(ii+1)*nbatch,nstart+nx])]
        tvR= vR[nstart+ii*nbatch:numpy.amin([nstart+(ii+1)*nbatch,nstart+nx])]
        tvT= vT[nstart+ii*nbatch:numpy.amin([nstart+(ii+1)*nbatch,nstart+nx])]
        tZ= Z[nstart+ii*nbatch:numpy.amin([nstart+(ii+1)*nbatch,nstart+nx])]
        tvZ= vZ[nstart+ii*nbatch:numpy.amin([nstart+(ii+1)*nbatch,nstart+nx])]
        tphi= phi[nstart+ii*nbatch:numpy.amin([nstart+(ii+1)*nbatch,nstart+nx])]
        try:
            tacfs= aA.actionsFreqsAngles(tR,tvR,tvT,tZ,tvZ,tphi)
        except numpy.linalg.linalg.LinAlgError:
            print tR,tvR,tvT,tZ,tvZ,tphi
            raise
        for jj in range(len(tacfs[0])):
            writer.writerow([tacfs[0][jj],tacfs[1][jj],tacfs[2][jj],
                             tacfs[3][jj],tacfs[4][jj],tacfs[5][jj],
                             tacfs[6][jj],tacfs[7][jj],tacfs[8][jj],
                             id[nstart+ii*nbatch+jj]])
            csvfile.flush()
    csvfile.close()
    return None
Example #28
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
Example #29
0
def fiducial_model(
    sdf_trailing="output/sdf_trailing.pkl",
    sdf_leading="output/sdf_leading.pkl",
    threshold=0.3,
    ro=REFR0,
    vo=REFV0,
):
    """Fiducial Model.

    The fiducial model assumes a spherical halo, with the best-fit
    parameters from fitting to the MWPotential2014 data

    """
    p_b15 = [
        0.60122692,
        0.36273147,
        -0.97591502,
        -3.34169377,
        0.71877924,
        -0.01519337,
        -0.01928001,
    ]

    pot = mw_pot.setup_potential(p_b15, 1.0, False, False, ro, vo)

    prog = Orbit(
        [229.018, -0.124, 23.2, -2.296, -2.257, -58.7],
        radec=True,
        ro=ro,
        vo=vo,
        solarmotion=[-11.1, 24.0, 7.25],
    )
    aAI = actionAngleIsochroneApprox(pot=pot, b=0.8)
    sigv = 0.2

    # ----------------------------------------------------------

    try:
        with open(sdf_trailing, "rb") as file:
            sdf_trailing = pickle.load(file)
    except Exception:
        sdf_trailing = streamdf(
            sigv / vo,
            progenitor=prog,
            pot=pot,
            aA=aAI,
            leading=False,
            nTrackChunks=11,
            tdisrupt=10.0 / bovy_conversion.time_in_Gyr(vo, ro),
            ro=ro,
            vo=vo,
            R0=ro,
            vsun=[-11.1, vo + 24.0, 7.25],
            custom_transform=pal5_util._TPAL5,
        )
        with open(sdf_trailing, "wb") as file:
            pickle.dump(sdf_trailing, file)

    try:
        with open(sdf_leading, "rb") as file:
            sdf_leading = pickle.load(file)
    except Exception:
        sdf_leading = streamdf(
            sigv / vo,
            progenitor=prog,
            pot=pot,
            aA=aAI,
            leading=True,
            nTrackChunks=11,
            tdisrupt=10.0 / bovy_conversion.time_in_Gyr(vo, ro),
            ro=ro,
            vo=vo,
            R0=ro,
            vsun=[-11.1, vo + 24.0, 7.25],
            custom_transform=pal5_util._TPAL5,
        )
        with open(sdf_leading, "wb") as file:
            pickle.dump(sdf_leading, file)

    # ----------------------------------------------------------

    print("Angular length: %f deg (leading,trailing)=(%f,%f) deg" % (
        sdf_leading.length(ang=True, coord="customra", threshold=threshold) +
        sdf_trailing.length(ang=True, coord="customra", threshold=threshold),
        sdf_leading.length(ang=True, coord="customra", threshold=threshold),
        sdf_trailing.length(ang=True, coord="customra", threshold=threshold),
    ))
    print("Angular width (FWHM): %f arcmin" %
          (pal5_util.width_trailing(sdf_trailing)))
    print("Velocity dispersion: %f km/s" %
          (pal5_util.vdisp_trailing(sdf_trailing)))

    # ----------------------------------------------------------

    trackRADec_trailing = bovy_coords.lb_to_radec(
        sdf_trailing._interpolatedObsTrackLB[:, 0],
        sdf_trailing._interpolatedObsTrackLB[:, 1],
        degree=True,
    )
    trackRADec_leading = bovy_coords.lb_to_radec(
        sdf_leading._interpolatedObsTrackLB[:, 0],
        sdf_leading._interpolatedObsTrackLB[:, 1],
        degree=True,
    )
    lb_sample_trailing = sdf_trailing.sample(n=10000, lb=True)
    lb_sample_leading = sdf_leading.sample(n=10000, lb=True)
    radec_sample_trailing = bovy_coords.lb_to_radec(lb_sample_trailing[0],
                                                    lb_sample_trailing[1],
                                                    degree=True)
    radec_sample_leading = bovy_coords.lb_to_radec(lb_sample_leading[0],
                                                   lb_sample_leading[1],
                                                   degree=True)

    # ----------------------------------------------------------
    # plotting

    plt.figure(figsize=(12, 4))
    plt.subplot(1, 2, 1)
    bovy_plot.bovy_plot(
        trackRADec_trailing[:, 0],
        trackRADec_trailing[:, 1],
        color=sns.color_palette()[0],
        xrange=[250.0, 210.0],
        yrange=[-15.0, 9.0],
        xlabel=r"$\mathrm{RA}\,(\mathrm{degree})$",
        ylabel=r"$\mathrm{Dec}\,(\mathrm{degree})$",
        gcf=True,
    )
    bovy_plot.bovy_plot(
        trackRADec_leading[:, 0],
        trackRADec_leading[:, 1],
        color=sns.color_palette()[0],
        overplot=True,
    )
    plt.plot(
        radec_sample_trailing[:, 0],
        radec_sample_trailing[:, 1],
        "k.",
        alpha=0.01,
        zorder=0,
    )
    plt.plot(
        radec_sample_leading[:, 0],
        radec_sample_leading[:, 1],
        "k.",
        alpha=0.01,
        zorder=0,
    )
    plt.errorbar(
        pos_radec[:, 0],
        pos_radec[:, 1],
        yerr=pos_radec[:, 2],
        ls="none",
        marker="o",
        color=sns.color_palette()[2],
    )
    plt.subplot(1, 2, 2)
    bovy_plot.bovy_plot(
        trackRADec_trailing[:, 0],
        sdf_trailing._interpolatedObsTrackLB[:, 3],
        color=sns.color_palette()[0],
        xrange=[250.0, 210.0],
        yrange=[-80.0, 0.0],
        xlabel=r"$\mathrm{RA}\,(\mathrm{degree})$",
        ylabel=r"$V_{\mathrm{los}}\,(\mathrm{km\,s}^{-1})$",
        gcf=True,
    )
    bovy_plot.bovy_plot(
        trackRADec_leading[:, 0],
        sdf_leading._interpolatedObsTrackLB[:, 3],
        color=sns.color_palette()[0],
        overplot=True,
    )
    plt.plot(
        radec_sample_trailing[:, 0],
        lb_sample_trailing[3],
        "k.",
        alpha=0.01,
        zorder=0,
    )
    plt.plot(
        radec_sample_leading[:, 0],
        lb_sample_leading[3],
        "k.",
        alpha=0.01,
        zorder=0,
    )
    plt.errorbar(
        rvel_ra[:, 0],
        rvel_ra[:, 1],
        yerr=rvel_ra[:, 2],
        ls="none",
        marker="o",
        color=sns.color_palette()[2],
    )

    plt.savefig("figures/fiducial_model.pdf")

    return
def setup_pal5model(leading=False,
                    pot=MWPotential2014,
                    orb=[229.018, -0.124, 23.2, -2.296, -2.257, -58.7],
                    timpact=None,
                    b=0.8,
                    hernquist=True,
                    age=5.,
                    singleImpact=False,
                    length_factor=1.,
                    **kwargs):
    obs = Orbit(orb, radec=True, ro=R0, vo=V0, solarmotion=[-11.1, 24., 7.25])
    aAI = actionAngleIsochroneApprox(pot=pot, b=b)
    sigv = 0.5 * (5. / age)  #km/s, adjust for diff. age
    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),
                       Rnorm=R0,
                       Vnorm=V0,
                       R0=R0,
                       vsun=[-11.1, V0 + 24., 7.25],
                       custom_transform=_TPAL5)
    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),
                          Rnorm=R0,
                          Vnorm=V0,
                          R0=R0,
                          vsun=[-11.1, V0 + 24., 7.25],
                          custom_transform=_TPAL5,
                          timpact=timpact,
                          spline_order=3,
                          hernquist=hernquist,
                          **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),
                             Rnorm=R0,
                             Vnorm=V0,
                             R0=R0,
                             vsun=[-11.1, V0 + 24., 7.25],
                             custom_transform=_TPAL5,
                             timpact=timpact,
                             spline_order=1,
                             hernquist=hernquist,
                             length_factor=length_factor)
    sdf.turn_physical_off()
    return sdf
Example #31
0
def setup_sdf(
    pot: Sequence[Potential],
    prog: Orbit,
    sigv: float,
    td: float,
    ro: float = REFR0,
    vo: float = REFV0,
    multi: Optional[Any] = None,
    nTrackChunks: int = 8,
    isob: Optional[bool] = None,
    trailing_only: bool = False,
    verbose: bool = True,
    useTM: bool = True,
    logpot: bool = False,
):
    """Simple function to setup the stream model."""
    if isob is None:
        if True or logpot:  # FIXME, "if True"
            isob = 0.75
    if isob is False:  # FIXME, was "if False"
        # Determine good one
        ts = np.linspace(0.0, 15.0, 1001)
        # Hack!
        epot = copy.deepcopy(pot)
        epot[2]._b = 1.0
        epot[2]._b2 = 1.0
        epot[2]._isNonAxi = False
        epot[2]._aligned = True
        prog.integrate(ts, pot)
        estb = estimateBIsochrone(
            epot,
            prog.R(ts, use_physical=False),
            prog.z(ts, use_physical=False),
            phi=prog.phi(ts, use_physical=False),
        )
        if estb[1] < 0.3:
            isob = 0.3
        elif estb[1] > 1.5:
            isob = 1.5
        else:
            isob = estb[1]
        if verbose:
            print(pot[2]._c, isob, estb)

    if not logpot and np.fabs(pot[2]._b - 1.0) > 0.05:
        aAI = actionAngleIsochroneApprox(pot=pot, b=isob, tintJ=1000.0, ntintJ=30000)
    else:
        ts = np.linspace(0.0, 100.0, 10000)
        aAI = actionAngleIsochroneApprox(
            pot=pot, b=isob, tintJ=100.0, ntintJ=10000, dt=ts[1] - ts[0]
        )

    if useTM:
        aAT = actionAngleTorus(pot=pot, tol=0.001, dJ=0.0001)
    else:
        aAT = False

    try:
        sdf = streamdf(
            sigv / vo,
            progenitor=prog,
            pot=pot,
            aA=aAI,
            useTM=aAT,
            approxConstTrackFreq=True,
            leading=True,
            nTrackChunks=nTrackChunks,
            tdisrupt=td / bovy_conversion.time_in_Gyr(vo, ro),
            ro=ro,
            vo=vo,
            R0=ro,
            vsun=[-11.1, vo + 24.0, 7.25],
            custom_transform=_TKOP,
            multi=multi,
            nospreadsetup=True,
        )
    except np.linalg.LinAlgError:
        sdf = streamdf(
            sigv / vo,
            progenitor=prog,
            pot=pot,
            aA=aAI,
            useTM=aAT,
            approxConstTrackFreq=True,
            leading=True,
            nTrackChunks=nTrackChunks,
            nTrackIterations=0,
            tdisrupt=td / bovy_conversion.time_in_Gyr(vo, ro),
            ro=ro,
            vo=vo,
            R0=ro,
            vsun=[-11.1, vo + 24.0, 7.25],
            custom_transform=_TKOP,
            multi=multi,
        )

    return sdf