Ejemplo n.º 1
0
def observed_to_xyzuvw_orbit(obs, ts, lsr_orbit=None):
    """
    Convert six-parameter astrometric solution to XYZUVW orbit.

    Parameters
    ----------
    obs :   [RA (deg), DEC (deg), pi (mas),
             mu_ra (mas/yr), mu_dec (mas/yr), vlos (km/s)]
        Current kinematics
    ts : [ntimes] array
        times (in Myr) to traceback to

    lsr_orbit : Orbit
        the orbit of the local standard of rest for comparison, if None can
        calculate on the fly

    XYZUVW : [ntimes, 6] array
        The space position and velocities of the star in a co-rotating frame
        centred on the LSR
    """
    #convert times from Myr into bovy_time
    bovy_ts = ts / (bovy_conversion.time_in_Gyr(220.,8.)*1000) # bovy-time/Myr
    logging.info("max time in Myr: {}".format(np.max(ts)))
    logging.info("max time in Bovy time: {}".format(np.max(bovy_ts)))

    o = Orbit(vxvv=obs, radec=True, solarmotion='schoenrich')
    o.integrate(bovy_ts,mp,method='odeint')
    data = o.getOrbit()
    XYZUVW = galpy_coords_to_xyzuvw(data, bovy_ts)
    return XYZUVW
Ejemplo n.º 2
0
def sample_los(options,args,dfc):
    print "Sampling the LOS ..."
    n= 0
    out= []
    while n < options.nobjects:
        thisos= dfc.sampleLOS(los=options.los,n=options.nobjects-n)
        #add distance uncertainty
        thisout= []
        for o in thisos:
            basico= Orbit([o.R(),o.vR(),o.vT(),0.,0.,o.phi()])#HACK bc ll does not work in 2D currently
            thisd= basico.dist(obs=[1.,0.,0.],ro=1.)
            #Add uncertainty logarithmically, like photometric distance uncertainty TO DO
            thisd+= nu.random.normal()*thisd*options.distuncertainty
            thisout.append(Orbit([basico.ll(obs=[1.,0.,0.],ro=1.)[0],
                                  thisd[0],
                                  basico.pmll(obs=[1.,0.,0.,0.,1.,0.],
                                              ro=1.,vo=1.)[0],
                                  basico.vlos(obs=[1.,0.,0.,0.,1.,0.],
                                              ro=1.,vo=1.)[0]],
                                 lb=True,
                                 solarmotion=[0.,0.,0.],ro=1.,vo=1.))
        ds= nu.array([o.dist(obs=[1.,0.,0.],ro=1.) for o in thisout]).flatten()
        thisos= [thisout[ii] for ii in range(len(thisout)) \
                     if (ds[ii] < options.dmax)]
        out.extend(thisos)
        n+= len(thisos)
    if len(out) > options.nobjects:
        out= out[0:options.nobjects-1]
    #Save
    picklefile= open(args[0],'wb')
    pickle.dump(out,picklefile)
    picklefile.close()
    return None                   
Ejemplo n.º 3
0
def test_correctInitialSolarMotion():
    age = np.pi # Half a galactic revolution
    
    # For reference: the expected solar motion as provided by Schoenrich
    REFERENCE_SCHOENRICH_SOLAR_MOTION = np.array([-11.1, -12.24, -7.25])
    ntimesteps = 10

    # vxvv is in cylindrical coordinates here. [R,vR,vT(,z,vz,phi)]
    lsr_orbit = Orbit(vxvv=[1,0,1,0,0,0],vo=220,ro=8,solarmotion='schoenrich')
    lsr_orbit.integrate(np.linspace(0.,age,ntimesteps), MWPotential2014)

    U = lsr_orbit.U(0)
    V = lsr_orbit.V(0)
    W = lsr_orbit.W(0)

    results = np.array([U, V, W]).reshape(3)
    for i, vel in enumerate('UVW'):
        print("For velocity {}:".format(vel))
        print("    expected: {}".format(REFERENCE_SCHOENRICH_SOLAR_MOTION[i]))
        print("    received: {}".format(results[i]))

    assert (np.allclose(REFERENCE_SCHOENRICH_SOLAR_MOTION, results)),\
        '!!! Using galpy version {} Need galpy version 1.1 !!!'.format(
            galpy.__version__
        )
Ejemplo n.º 4
0
def test_estimateDelta():

    #_____initialize some KKSPot_____
    Delta = 1.0
    pot = KuzminKutuzovStaeckelPotential(ac=20.,Delta=Delta,normalize=True)

    #_____initialize an orbit (twice)_____
    vxvv = [1.,0.1,1.1,0.01,0.1]
    o= Orbit(vxvv=vxvv)

    #_____integrate the orbit with C_____
    ts= numpy.linspace(0,101,100)
    o.integrate(ts,pot,method='leapfrog_c')


    #____estimate Focal length Delta_____
    #for each time step individually:
    deltas_estimate = numpy.zeros(len(ts))
    for ii in range(len(ts)):
        deltas_estimate[ii] = estimateDeltaStaeckel(pot,o.R(ts[ii]),o.z(ts[ii]))

    assert numpy.all(numpy.fabs(deltas_estimate - Delta) < 10.**-8), \
            'Focal length Delta estimated along the orbit is not constant.'

    #for all time steps together:
    delta_estimate = estimateDeltaStaeckel(pot,o.R(ts),o.z(ts))
    
    assert numpy.fabs(delta_estimate - Delta) < 10.**-8, \
            'Focal length Delta estimated from the orbit is not the same as the input focal length.'

    return None
Ejemplo n.º 5
0
def traceback2(params,times):
    """Trace forward a cluster. First column of returned array is the
    position of the cluster at a given age.

    Parameters
    ----------
    times: float array
        Times to trace forward, in Myr. Note that positive numbers are going
        forward in time.
    params: float array
        [RA,DE,Plx,PM(RA),PM(DE),RV]
        RA = Right Ascension (Deg)
        DE = Declination (Deg)
        Plx = Paralax (Mas)
        PM(RA) = Proper motion (Right Ascension) (mas/yr)
        PM(DE) = Proper motion (Declination) (mas/yr)
        RV = Radial Velocity (km/s)
    age: Age of cluster, in Myr
    
    """
    #FIXME: This is very out of date and should be deleted!!!
    #Times in Myr
    ts = -(times/1e3)/bovy_conversion.time_in_Gyr(220.,8.)
    nts = len(times)

    #Positions and velocities in the co-rotating solar reference frame.
    xyzuvw = np.zeros( (1,nts,6) )

    #Trace forward the local standard of rest.
    lsr_orbit= Orbit(vxvv=[1.,0,1,0,0.,0],vo=220,ro=8)
    lsr_orbit.integrate(ts,MWPotential2014)#,method='odeint')

    xyzuvw = integrate_xyzuvw(params,ts,lsr_orbit,MWPotential2014)
    return xyzuvw
Ejemplo n.º 6
0
def trace_cartesian_orbit(xyzuvw_start, times=None, single_age=True,
                          potential=MWPotential2014, ro=8., vo=220.):
    """
    Given a star's XYZUVW relative to the LSR (at any time), project its
    orbit forward (or backward) to each of the times listed in *times*

    Positive times --> traceforward
    Negative times --> traceback

    TODO: Primary source of inefficiencies, 1366.2 (s)

    Parameters
    ----------
    xyzuvw : [pc,pc,pc,km/s,km/s,km/s]
    times : (float) or ([ntimes] float array)
        Myr - time of 0.0 must be present in the array. Times need not be
        spread linearly.
    single_age: (bool) {True}
        Set this flag if only providing a single age to trace to

    Returns
    -------
    xyzuvw_tf : [ntimes, 6] array
        [pc, pc, pc, km/s, km/s, km/s] - the traced orbit with positions
        and velocities

    Notes
    -----
    Profiling comments have been left in for future reference, but note
    that the profiling was done with previous versions of coordinate
    functions - ones that utilised astropy.units (and thus symbolic algebra)
    """
    if single_age:
        # replace 0 with some tiny number
        if times == 0.:
            times = 1e-15
        times = np.array([0., times])
    else:
        times = np.array(times)

    xyzuvw_start = np.copy(xyzuvw_start).astype(np.float)

    bovy_times = convert_myr2bovytime(times)

    # since the LSR is constant in chron coordinates, the starting point
    # is always treated as time 0
    galpy_coords = convert_cart2galpycoords(xyzuvw_start, ts=0.,
                                            ro=ro, vo=vo)
    o = Orbit(vxvv=galpy_coords, ro=ro, vo=vo)
    o.integrate(bovy_times, potential, method='odeint')

    xyzuvw = convert_galpycoords2cart(o.getOrbit(), bovy_times,
                                      ro=ro, vo=vo)
    if single_age:
        return xyzuvw[-1]
    return xyzuvw
Ejemplo n.º 7
0
Archivo: le.py Proyecto: annajur/cbp
def evolveorbit(icon, ti, tau, pot):
    global x
    global y
    o = Orbit(vxvv=icon) # [R,vR,vT,z,vz,phi]
    tf = ti+tau
    ts = np.linspace(ti,tf,100)
    o.integrate(ts, pot, method = 'leapfrog')
    x.append(o.x(ts[0]))
    y.append(o.y(ts[0]))
    return [o.R(tf),o.vR(tf),o.vT(tf),o.z(tf),o.vz(tf),o.phi(tf)]
Ejemplo n.º 8
0
def test_orbitint():
    import numpy
    from galpy.potential import MWPotential2014
    from galpy.potential import evaluatePotentials as evalPot
    from galpy.orbit import Orbit
    E, Lz= -1.25, 0.6
    o1= Orbit([0.8,0.,Lz/0.8,0.,numpy.sqrt(2.*(E-evalPot(0.8,0.,MWPotential2014)-(Lz/0.8)**2./2.)),0.])
    ts= numpy.linspace(0.,100.,2001)
    o1.integrate(ts,MWPotential2014)
    o1.plot(xrange=[0.3,1.],yrange=[-0.2,0.2],color='k')
    o2= Orbit([0.8,0.3,Lz/0.8,0.,numpy.sqrt(2.*(E-evalPot(0.8,0.,MWPotential2014)-(Lz/0.8)**2./2.-0.3**2./2.)),0.])
    o2.integrate(ts,MWPotential2014)
    o2.plot(xrange=[0.3,1.],yrange=[-0.2,0.2],color='k')
    return None
Ejemplo n.º 9
0
def get_lsr_orbit(times, Potential=MWPotential2014):
    """Integrate the local standard of rest backwards in time, in order to provide
    a reference point to our XYZUVW coordinates.
    
    Parameters
    ----------
    times: numpy float array
        Times at which we want the orbit of the local standard of rest.
        
    Potential: galpy potential object.
    """
    ts = -(times/1e3)/bovy_conversion.time_in_Gyr(220.,8.)
    lsr_orbit= Orbit(vxvv=[1.,0,1,0,0.,0],vo=220,ro=8, solarmotion='schoenrich')
    lsr_orbit.integrate(ts,Potential)#,method='odeint')
    return lsr_orbit
Ejemplo n.º 10
0
def calc_delta_MWPotential2014(savefilename,plotfilename):
    Lmin, Lmax= 0.01, 10.
    if not os.path.exists(savefilename):
        #Setup grid
        nL, nE= 101,101
        Ls= 10.**numpy.linspace(numpy.log10(Lmin),numpy.log10(Lmax),nL)
        #Integration times
        ts= numpy.linspace(0.,20.,1001)
        deltas= numpy.empty((nL,nE))
        Einf= evalPot(10.**12.,0.,MWPotential2014)
        print Einf
        for ii in range(nL):
            #Calculate Ec
            Rc= rl(MWPotential2014,Ls[ii])
            print ii, "Rc = ", Rc*8.
            Ec= evalPot(Rc,0.,MWPotential2014)+0.5*Ls[ii]**2./Rc**2.
            Es= Ec+(Einf-Ec)*10.**numpy.linspace(-2.,0.,nE)
            for jj in range(nE):
                #Setup an orbit with this energy and angular momentum
                Er= 2.*(Es[jj]-Ec) #Random energy times 2 = vR^2 + vz^2
                vR= numpy.sqrt(4./5.*Er)
                vz= numpy.sqrt(1./5.*Er)
                o= Orbit([Rc,vR,Ls[ii]/Rc,0.,vz,0.])
                o.integrate(ts,MWPotential2014,method='symplec4_c')
                deltas[ii,jj]= estimateDeltaStaeckel(o.R(ts),o.z(ts),
                                                     pot=MWPotential2014)
        #Save
        save_pickles(savefilename,deltas)
    else:
        savefile= open(savefilename,'rb')
        deltas= pickle.load(savefile)
        savefile.close()
    #Plot
    print numpy.nanmax(deltas)
    bovy_plot.bovy_print()
    bovy_plot.bovy_dens2d(deltas.T,origin='lower',cmap='jet',
                          xrange=[numpy.log10(Lmin),numpy.log10(Lmax)],
                          yrange=[-2,0.],
                          xlabel=r'$\log_{10} L$',
                          ylabel=r'$\log_{10}\left(\frac{E-E_c(L)}{E(\infty)-E_c(L)}\right)$',
                          colorbar=True,shrink=0.78,
                          zlabel=r'$\mathrm{Approximate\ focal\ length}$',
#                          interpolation='nearest',
                          vmin=0.,vmax=0.6)
    bovy_plot.bovy_end_print(plotfilename)
    return None
Ejemplo n.º 11
0
def test_actionConservation():

    #_____initialize some KKSPot_____
    Delta = 1.0
    pot = KuzminKutuzovStaeckelPotential(ac=20.,Delta=Delta,normalize=True)

    #_____initialize an orbit (twice)_____
    vxvv = [1.,0.1,1.1,0.01,0.1]
    o= Orbit(vxvv=vxvv)

    #_____integrate the orbit with C_____
    ts= numpy.linspace(0,101,100)
    o.integrate(ts,pot,method='leapfrog_c')

    #_____Setup ActionAngle object and calculate actions (Staeckel approximation)_____
    aAS = actionAngleStaeckel(pot=pot,delta=Delta,c=True)
    jrs,lzs,jzs = aAS(o.R(ts),o.vR(ts),o.vT(ts),o.z(ts),o.vz(ts))

    assert numpy.all(numpy.fabs(jrs - jrs[0]) < 10.**-8.), \
        'Radial action is not conserved along orbit.'

    assert numpy.all(numpy.fabs(lzs - lzs[0]) < 10.**-8.), \
        'Angular momentum is not conserved along orbit.'

    assert numpy.all(numpy.fabs(jzs - jzs[0]) < 10.**-8.), \
        'Vertical action is not conserved along orbit.'

    return None
Ejemplo n.º 12
0
def trace_orbit_xyzuvw(xyzuvw_then, times):
    """
    Given a star's XYZUVW relative to the LSR (at any time), project its
    orbit forward to each of the times listed in *times*

    Parameters
    ----------
    xyzuvw : [pc,pc,pc,km/s,km/s,km/s]
    times : [ntimes] array
        Myr

    Returns
    -------
    xyzuvw_tf : [ntimes, 6] array
        the traced-forward positions and velocities
    """
    XYZUVW_sun_now = np.array([0.,0.,0.025,11.1,12.24,7.25])

    # convert positions to kpc
    xyzuvw_then[:3] *= 1e-3

    # convert times from Myr to bovy units
    bovy_times = times*1e-3 / bovy_conversion.time_in_Gyr(220., 8.)
    logging.debug("Tracing up to {} Myr".format(times[-1]))
    logging.debug("Tracing up to {} Bovy yrs".format(bovy_times[-1]))

    # Galpy coordinates are from the vantage point of the sun.
    # So even though the sun wasn't where it is,  we still "observe" the star
    # from a solar height and motion
    XYZUVW_gp_tf = xyzuvw_then - XYZUVW_sun_now
    logging.debug("Galpy vector: {}".format(XYZUVW_gp_tf))

    l,b,dist = lbdist_from_XYZ(XYZUVW_gp_tf)
    vxvv = [l,b,dist,XYZUVW_gp_tf[3],XYZUVW_gp_tf[4],XYZUVW_gp_tf[5]]
    logging.debug("vxvv: {}".format(vxvv))
    otf = Orbit(vxvv=vxvv, lb=True, uvw=True, solarmotion='schoenrich')

    otf.integrate(bovy_times,mp,method='odeint')
    data_tf = otf.getOrbit()
    XYZUVW_tf = galpy_coords_to_xyzuvw(data_tf, bovy_times)
    logging.debug("Started orbit at {}".format(XYZUVW_tf[0]))
    logging.debug("Finished orbit at {}".format(XYZUVW_tf[-1]))
    return XYZUVW_tf
def get_initial_condition(to):
    """Find an initial condition near apocenter that ends up today near the end of the stream and is close to a gyrfalcon stepsize
    to= Find an apocenter that is just more recent than this time"""
    vo, ro= 220., 8.
    # Center of the stream
    o= Orbit([0.10035165,-0.81302488,0.80986668,0.58024425,0.92753945,
               0.88763126],ro=ro,vo=vo)
    #Flip for backwards integration
    of= o.flip()
    ts= numpy.linspace(0.,to/bovy_conversion.time_in_Gyr(vo,ro),10001)
    of.integrate(ts,MWPotential2014)
    # Find the closest apocenter to the time to
    rs= numpy.sqrt(of.R(ts)**2.+of.z(ts)**2.)
    drs= rs-numpy.roll(rs,1)
    nearApo= (drs < 0.)*(numpy.roll(drs,1) > 0.)
    tsNearApo= ts[nearApo]
    tsNearApo*= bovy_conversion.time_in_Gyr(vo,ro)
    tfgf= numpy.amax(tsNearApo)
    #Round to nearest 2.**-8.
    tfgf= round(tfgf/2.**-8.)*2.**-8
    tf= tfgf/bovy_conversion.time_in_Gyr(vo,ro)
    print 'Current: %s,%s,%s,%s,%s,%s' % (of.x()[0], of.y()[0], of.z(), -of.vx()[0], -of.vy()[0], -of.vz())
    print 'At %g Gyr: %s,%s,%s,%s,%s,%s' % (tf*bovy_conversion.time_in_Gyr(vo,ro),of.x(tf)[0], of.y(tf)[0], of.z(tf), -of.vx(tf,use_physical=False)[0]*bovy_conversion.velocity_in_kpcGyr(vo,ro), -of.vy(tf,use_physical=False)[0]*bovy_conversion.velocity_in_kpcGyr(vo,ro), -of.vz(tf,use_physical=False)*bovy_conversion.velocity_in_kpcGyr(vo,ro))
    return None
Ejemplo n.º 14
0
def integrate_xyzuvw(params,ts,lsr_orbit,MWPotential2014):
    """Convenience function"""
    vxvv = params.copy()
    vxvv[2]=1.0/params[2]
    o = Orbit(vxvv=vxvv, radec=True, solarmotion='schoenrich')
    o.integrate(ts,MWPotential2014,method='odeint')
    xyzuvw = np.zeros( (len(ts),6) )
    xyzuvw[:,0] = 1e3*(o.x(ts)-lsr_orbit.x(ts))
    xyzuvw[:,1] = 1e3*(o.y(ts)-lsr_orbit.y(ts))
    xyzuvw[:,2] = 1e3*(o.z(ts))
    xyzuvw[:,3] = o.U(ts) - lsr_orbit.U(ts)
    xyzuvw[:,4] = o.V(ts) - lsr_orbit.V(ts)
    xyzuvw[:,5] = o.W(ts)
    return xyzuvw
Ejemplo n.º 15
0
def test_actionAngleTorus_orbit():
    from galpy.actionAngle import actionAngleTorus
    from galpy.potential import MWPotential2014
    from galpy.orbit import Orbit
    # Set up instance
    aAT= actionAngleTorus(pot=MWPotential2014,tol=10.**-5.)
    jr,jphi,jz= 0.05,1.1,0.025
    # First calculate frequencies and the initial RvR
    RvRom= aAT.xvFreqs(jr,jphi,jz,
                       numpy.array([0.]),
                       numpy.array([1.]),
                       numpy.array([2.]))
    om= RvRom[1:]
    # Angles along an orbit
    ts= numpy.linspace(0.,100.,1001)
    angler= ts*om[0]
    anglephi= 1.+ts*om[1]
    anglez= 2.+ts*om[2]
    # Calculate the orbit using actionAngleTorus
    RvR= aAT(jr,jphi,jz,angler,anglephi,anglez).T
    # Calculate the orbit using orbit integration
    orb= Orbit([RvRom[0][:,0],RvRom[0][:,1],RvRom[0][:,2],
                RvRom[0][:,3],RvRom[0][:,4],RvRom[0][:,5]])
    orb.integrate(ts,MWPotential2014)
    # Compare
    tol= -3.
    assert numpy.all(numpy.fabs(orb.R(ts)-RvR[0]) < 10.**tol), \
        'Integrated orbit does not agree with torus orbit in R'
    assert numpy.all(numpy.fabs(orb.vR(ts)-RvR[1]) < 10.**tol), \
        'Integrated orbit does not agree with torus orbit in vR'
    assert numpy.all(numpy.fabs(orb.vT(ts)-RvR[2]) < 10.**tol), \
        'Integrated orbit does not agree with torus orbit in vT'
    assert numpy.all(numpy.fabs(orb.z(ts)-RvR[3]) < 10.**tol), \
        'Integrated orbit does not agree with torus orbit in z'
    assert numpy.all(numpy.fabs(orb.vz(ts)-RvR[4]) < 10.**tol), \
        'Integrated orbit does not agree with torus orbit in vz'
    assert numpy.all(numpy.fabs(orb.phi(ts)-RvR[5]) < 10.**tol), \
        'Integrated orbit does not agree with torus orbit in phi'
    return None
def calc_progenitor_actions(savefilename):
    # Setup potential
    lp = potential.LogarithmicHaloPotential(normalize=1.0, q=0.9)
    # Setup orbit
    x, z, y, vx, vz, vy = -11.63337239, -10.631736273934635, -20.76235661, -128.8281653, 79.172383882274971, 42.88727925
    R, phi, z = bovy_coords.rect_to_cyl(x, y, z)
    vR, vT, vz = bovy_coords.rect_to_cyl_vec(vx, vy, vz, R, phi, z, cyl=True)
    R /= 8.0
    z /= 8.0
    vR /= 220.0
    vT /= 220.0
    vz /= 220.0
    o = Orbit([R, vR, vT, z, vz, phi])
    ts = numpy.linspace(0.0, 5.125 * 220.0 / 8.0, 1313)  # times of the snapshots
    o.integrate(ts, lp, method="dopr54_c")
    if "aas" in savefilename:
        aA = actionAngleStaeckel(pot=lp, delta=1.20, c=True)
    else:
        aA = actionAngleIsochroneApprox(pot=lp, b=0.8)
    # Now calculate actions, frequencies, and angles for all positions
    Rs = o.R(ts)
    vRs = o.vR(ts)
    vTs = o.vT(ts)
    zs = o.z(ts)
    vzs = o.vz(ts)
    phis = o.phi(ts)
    csvfile = open(savefilename, "wb")
    writer = csv.writer(csvfile, delimiter=",")
    for ii in range(len(ts)):
        acfs = aA.actionsFreqsAngles(Rs[ii], vRs[ii], vTs[ii], zs[ii], vzs[ii], phis[ii])
        writer.writerow(
            [acfs[0][0], acfs[1][0], acfs[2][0], acfs[3][0], acfs[4][0], acfs[5][0], acfs[6][0], acfs[7][0], acfs[8][0]]
        )
        csvfile.flush()
    csvfile.close()
    return None
Ejemplo n.º 17
0
def integrate_xyzuvw(params,times,lsr_orbit=None,Potential=MWPotential2014):
    """Convenience function. Integrates the motion of a star backwards in time.
    
    Parameters
    ----------
    params: numpy array 
        Kinematic parameters (RAdeg,DEdeg,Plx,pmRA,pmDE,RV)
        
    ts: times for back propagation, in Myr.
        
    lsr_orbit:
        WARNING: messy...
        lsr_orbit= Orbit(vxvv=[1.,0,1,0,0.,0],vo=220,ro=8, solarmotion='schoenrich')
        lsr_orbit.integrate(ts,MWPotential2014,method='odeint')
    MWPotential2014:
        WARNING: messy...
        from galpy.potential import MWPotential2014        
    """
    #We allow MWPotential and lsr_orbit to be passed for speed, but can compute/import 
    #now.
    if not lsr_orbit:
        lsr_orbit = get_lsr_orbit(times)
        
    #Convert times to galpy units:
    ts = -(times/1e3)/bovy_conversion.time_in_Gyr(220.,8.)
        
    params = np.array(params)
    vxvv = params.copy()
    #We'd prefer to pass parallax in mas, but distance in kpc is accepted. This
    #reciporical could be done elsewhere...
    vxvv[2]=1.0/params[2]   
    o = Orbit(vxvv=vxvv, radec=True, solarmotion='schoenrich')
    
    o.integrate(ts,Potential)#,method='odeint')
    xyzuvw = np.zeros( (len(ts),6) )
    xyzuvw[:,0] = 1e3*(o.x(ts)-lsr_orbit.x(ts))
    xyzuvw[:,1] = 1e3*(o.y(ts)-lsr_orbit.y(ts))
    #The lsr_orbit is zero in the z direction by definition - the local standard of 
    #rest is at the midplane of the Galaxy
    xyzuvw[:,2] = 1e3*(o.z(ts))  
    #UVW is relative to the sun. We *could* have used vx, vy and vz. Would these
    #have been relative to the LSR?
    xyzuvw[:,3] = o.U(ts) - lsr_orbit.U(ts)
    xyzuvw[:,4] = o.V(ts) - lsr_orbit.V(ts)
    xyzuvw[:,5] = o.W(ts) - lsr_orbit.W(ts) #NB This line changed !!!
    return xyzuvw
Ejemplo n.º 18
0
def test_surfacesection():
    #Preliminary code
    import numpy
    from galpy.potential import MWPotential2014
    from galpy.potential import evaluatePotentials as evalPot
    from galpy.orbit import Orbit
    E, Lz= -1.25, 0.6
    o1= Orbit([0.8,0.,Lz/0.8,0.,numpy.sqrt(2.*(E-evalPot(0.8,0.,MWPotential2014)-(Lz/0.8)**2./2.)),0.])
    ts= numpy.linspace(0.,100.,2001)
    o1.integrate(ts,MWPotential2014)
    o2= Orbit([0.8,0.3,Lz/0.8,0.,numpy.sqrt(2.*(E-evalPot(0.8,0.,MWPotential2014)-(Lz/0.8)**2./2.-0.3**2./2.)),0.])
    o2.integrate(ts,MWPotential2014)
    def surface_section(Rs,zs,vRs):
        # Find points where the orbit crosses z from - to +
        shiftzs= numpy.roll(zs,-1)
        indx= (zs[:-1] < 0.)*(shiftzs[:-1] > 0.)
        return (Rs[:-1][indx],vRs[:-1][indx])
    # Calculate and plot the surface of section
    ts= numpy.linspace(0.,1000.,20001) # long integration
    o1.integrate(ts,MWPotential2014)
    o2.integrate(ts,MWPotential2014)
    sect1Rs,sect1vRs=surface_section(o1.R(ts),o1.z(ts),o1.vR(ts))
    sect2Rs,sect2vRs=surface_section(o2.R(ts),o2.z(ts),o2.vR(ts))
    from matplotlib.pyplot import plot, xlim, ylim
    plot(sect1Rs,sect1vRs,'bo',mec='none')
    xlim(0.3,1.); ylim(-0.69,0.69)
    plot(sect2Rs,sect2vRs,'yo',mec='none')
    return None
Ejemplo n.º 19
0
def calc_es():
    savefilename= 'myes.sav'
    if os.path.exists(savefilename):
        savefile= open(savefilename,'rb')
        mye= pickle.load(savefile)
        e= pickle.load(savefile)
        savefile.close()
    else:
       #Read data
        dialect= csv.excel
        dialect.skipinitialspace=True
        reader= csv.reader(open('../data/Dierickx-etal-tab2.txt','r'),delimiter=' ',dialect=dialect)
        vxvs= []
        es= []
        vphis= []
        vxs= []
        vys= []
        vzs= []
        ls= []
        for row in reader:
            thisra= float(row[3])
            thisdec= float(row[4])
            thisd= float(row[17])/1000.
            thispmra= float(row[13])
            thispmdec= float(row[15])
            thisvlos= float(row[11])
            thise= float(row[26])
            vxvs.append([thisra,thisdec,thisd,thispmra,thispmdec,thisvlos])
            es.append(thise)
            vphis.append(float(row[25]))
            vxs.append(float(row[19]))
            vys.append(float(row[21]))
            vzs.append(float(row[23]))
            ls.append(float(row[5]))
        vxvv= nu.array(vxvs)
        e= nu.array(es)
        vphi= nu.array(vphis)
        vx= nu.array(vxs)
        vy= nu.array(vys)
        vz= nu.array(vzs)
        l= nu.array(ls)

        #Define potential
        lp= LogarithmicHaloPotential(normalize=1.)
        mp= MiyamotoNagaiPotential(a=0.5,b=0.0375,amp=1.,normalize=.6)
        np= NFWPotential(a=4.5,normalize=.35)
        hp= HernquistPotential(a=0.6/8,normalize=0.05)
        ts= nu.linspace(0.,20.,10000)
        
        mye= nu.zeros(len(e))
        for ii in range(len(e)):
           #Integrate the orbit
            o= Orbit(vxvv[ii,:],radec=True,vo=220.,ro=8.)
            o.integrate(ts,lp)
            mye[ii]= o.e()
            

        #Save
        savefile= open(savefilename,'wb')
        pickle.dump(mye,savefile)
        pickle.dump(e,savefile)
        savefile.close()

    #plot
    plot.bovy_print()
    plot.bovy_plot(nu.array([0.,1.]),nu.array([0.,1.]),'k-',
                   xlabel=r'$\mathrm{Dierickx\ et\ al.}\ e$',
                   ylabel=r'$\mathrm{galpy}\ e$')
    plot.bovy_plot(e,mye,'k,',overplot=True)
    plot.bovy_end_print('myee.png')

    plot.bovy_print()
    plot.bovy_hist(e,bins=30,xlabel=r'$\mathrm{Dierickx\ et\ al.}\ e$')
    plot.bovy_end_print('ehist.png')

    plot.bovy_print()
    plot.bovy_hist(mye,bins=30,xlabel=r'$\mathrm{galpy}\ e$')
    plot.bovy_end_print('myehist.png')
Ejemplo n.º 20
0
def test_get_physical():
    #Test that the get_physical function returns the right scaling parameters
    from galpy.util.bovy_conversion import get_physical
    # Potential and variations thereof
    from galpy.potential import MWPotential2014, DehnenBarPotential
    dp = DehnenBarPotential
    assert numpy.fabs(
        get_physical(MWPotential2014[0]).get('ro') - 8.
    ) < 1e-10, 'get_physical does not return the correct unit conversion parameter for a Potential'
    assert numpy.fabs(
        get_physical(MWPotential2014[0]).get('vo') - 220.
    ) < 1e-10, 'get_physical does not return the correct unit conversion parameter for a Potential'
    ro, vo = 9., 230.
    dp = DehnenBarPotential(ro=ro, vo=vo)
    assert numpy.fabs(
        get_physical(dp).get('ro') - ro
    ) < 1e-10, 'get_physical does not return the correct unit conversion parameter for a Potential'
    assert numpy.fabs(
        get_physical(dp).get('vo') - vo
    ) < 1e-10, 'get_physical does not return the correct unit conversion parameter for a Potential'
    assert numpy.fabs(
        get_physical(MWPotential2014).get('ro') - 8.
    ) < 1e-10, 'get_physical does not return the correct unit conversion parameter for a Potential'
    assert numpy.fabs(
        get_physical(MWPotential2014).get('vo') - 220.
    ) < 1e-10, 'get_physical does not return the correct unit conversion parameter for a Potential'
    assert numpy.fabs(
        get_physical(MWPotential2014 + dp).get('ro') - 8.
    ) < 1e-10, 'get_physical does not return the correct unit conversion parameter for a Potential'
    assert numpy.fabs(
        get_physical(MWPotential2014 + dp).get('vo') - 220.
    ) < 1e-10, 'get_physical does not return the correct unit conversion parameter for a Potential'
    assert numpy.fabs(
        get_physical(MWPotential2014 + dp).get('ro') - 8.
    ) < 1e-10, 'get_physical does not return the correct unit conversion parameter for a Potential'
    assert numpy.fabs(
        get_physical(MWPotential2014 + dp).get('vo') - 220.
    ) < 1e-10, 'get_physical does not return the correct unit conversion parameter for a Potential'
    # Orbits
    from galpy.orbit import Orbit
    ro, vo = 10., 210.
    o = Orbit(ro=ro, vo=vo)
    assert numpy.fabs(
        get_physical(o).get('ro') - ro
    ) < 1e-10, 'get_physical does not return the correct unit conversion parameter for an Orbit'
    assert numpy.fabs(
        get_physical(o).get('vo') - vo
    ) < 1e-10, 'get_physical does not return the correct unit conversion parameter for an Orbit'
    # even though one shouldn't do this, let's test a list
    assert numpy.fabs(
        get_physical([o, o]).get('ro') - ro
    ) < 1e-10, 'get_physical does not return the correct unit conversion parameter for an Orbit'
    assert numpy.fabs(
        get_physical([o, o]).get('vo') - vo
    ) < 1e-10, 'get_physical does not return the correct unit conversion parameter for an Orbit'
    # actionAngle
    from galpy.actionAngle import actionAngleStaeckel
    aAS = actionAngleStaeckel(pot=MWPotential2014, delta=0.45)
    assert numpy.fabs(
        get_physical(aAS).get('ro') - 8.
    ) < 1e-10, 'get_physical does not return the correct unit conversion parameter for an actionAngle instance'
    assert numpy.fabs(
        get_physical(aAS).get('vo') - 220.
    ) < 1e-10, 'get_physical does not return the correct unit conversion parameter for an actionAngle instance'
    # This doesn't make much sense, but let's test...
    ro, vo = 19., 130.
    dp = DehnenBarPotential(ro=ro, vo=vo)
    aAS = actionAngleStaeckel(pot=dp, delta=0.45, ro=ro, vo=vo)
    assert numpy.fabs(
        get_physical(aAS).get('ro') - ro
    ) < 1e-10, 'get_physical does not return the correct unit conversion parameter for an actionAngle instance'
    assert numpy.fabs(
        get_physical(aAS).get('vo') - vo
    ) < 1e-10, 'get_physical does not return the correct unit conversion parameter for an actionAngle instance'
    # DF
    from galpy.df import quasiisothermaldf
    aAS = actionAngleStaeckel(pot=MWPotential2014, delta=0.45)
    qdf = quasiisothermaldf(1. / 3.,
                            0.2,
                            0.1,
                            1.,
                            1.,
                            aA=aAS,
                            pot=MWPotential2014)
    assert numpy.fabs(
        get_physical(qdf).get('ro') - 8.
    ) < 1e-10, 'get_physical does not return the correct unit conversion parameter for a DF instance'
    assert numpy.fabs(
        get_physical(qdf).get('vo') - 220.
    ) < 1e-10, 'get_physical does not return the correct unit conversion parameter for a DF instance'
    # non-standard ro,vo
    from galpy.potential import MiyamotoNagaiPotential
    ro, vo = 4., 330.
    mp = MiyamotoNagaiPotential(a=0.5, b=0.1, ro=ro, vo=vo)
    aAS = actionAngleStaeckel(pot=mp, delta=0.45, ro=ro, vo=vo)
    qdf = quasiisothermaldf(1. / 3.,
                            0.2,
                            0.1,
                            1.,
                            1.,
                            aA=aAS,
                            pot=mp,
                            ro=ro,
                            vo=vo)
    assert numpy.fabs(
        get_physical(qdf).get('ro') - ro
    ) < 1e-10, 'get_physical does not return the correct unit conversion parameter for a DF instance'
    assert numpy.fabs(
        get_physical(qdf).get('vo') - vo
    ) < 1e-10, 'get_physical does not return the correct unit conversion parameter for a DF instance'
    return None
Ejemplo n.º 21
0
def star_to_orbit(star_name, radius = 1.0*u.arcsec):
    """ 
    Given the name of a star, returns a galpy.orbit.Orbit object for that 
    star using data from the Gaia dr2 catalogue. If no data on the star can
    be found from Gaia, then data from SIMBAD is used instead.
    """
    # Get data on the star from SIMBAD, for use in epoch adjustment
    custom_simbad = Simbad()
    custom_simbad.add_votable_fields('pmra', 'pmdec', 'plx', 'rv_value')
    simbad_table = custom_simbad.query_object(star_name)
    
    # Convert ra and dec from SIMBAD into a SkyCoord object
    # to transform into degrees
    simbad_coord = SkyCoord(ra = simbad_table['RA'][0], 
                            dec = simbad_table['DEC'][0],
                            unit = (u.hourangle, u.deg))
    
    # Store the SIMBAD values in a tuple of the form 
    # (ra, dec, plx, pmra, pmdec, rv)
    simbad_vals = (simbad_coord.ra.value,
                   simbad_coord.dec.value,
                   simbad_table['PLX_VALUE'][0],
                   simbad_table['PMRA'][0],
                   simbad_table['PMDEC'][0],
                   simbad_table['RV_VALUE'][0])
    
    # Circle radius to query Gaia, in degrees
    radius_deg = radius.to(u.deg)
    
    # Replace masked values from the SIMBAD table with 0.0 for epoch adjustment
    epoch_prop_vals = [val if not is_masked(val) else 0.0 for val in simbad_vals]
    
    # Perform a cone search with epoch adjustment
    query =  """
             SELECT source_id, ra, dec, pmra, pmdec, parallax, radial_velocity
             FROM gaiadr2.gaia_source
             WHERE 1=CONTAINS(
             POINT('ICRS',gaiadr2.gaia_source.ra,gaiadr2.gaia_source.dec),
             CIRCLE('ICRS', 
             COORD1(EPOCH_PROP_POS({0},{1},{2},{3},{4},{5},2000,2015.5)),
             COORD2(EPOCH_PROP_POS({0},{1},{2},{3},{4},{5},2000,2015.5)), {6}))
             """.format(*epoch_prop_vals, radius_deg.value)
             
    # Perfrom the cone search and get the result in a table
    job = Gaia.launch_job_async(query)
    gaia_table = job.get_results()
    
    # If no Gaia entries are found, use the SIMBAD entries
    if len(gaia_table) != 0:
        ra = gaia_table['ra'][0]
        dec = gaia_table['dec'][0]
        plx = gaia_table['parallax'][0]
        pmra = gaia_table['pmra'][0]
        pmdec = gaia_table['pmdec'][0]
        rv = gaia_table['radial_velocity'][0]
    else:
        ra, dec, plx, pmra, pmdec, rv = simbad_vals
        
    if is_masked(rv) and is_masked(simbad_vals[-1]):
        # Set rv to 20.0 if not available in either the Gaia or SIMBAD tables
        rv = 20.0
    elif is_masked(rv):
        # Use the SIMBAD rv if not available in GAIA
        rv = simbad_vals[5]
        
    # Generate and return a galpy.orbit.Orbit object
    orbit = Orbit(vxvv = (ra, dec, 1/plx, pmra, pmdec, rv), radec = True)
    return orbit
Ejemplo n.º 22
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
def plot_lb(i, ts, plot_extreme=False, save_name='fwd', zorder=1, **kargs):
    # integrate orbit
    if RUN:
        vxvv = [ra[i], dec[i], d[i], pmra[i], pmde[i], rv[i]]
        o = Orbit(vxvv=vxvv, radec=True, ro=ro, vo=vo, solarmotion=solarmotion)
        o.integrate(ts, pot, method='leapfrog')

        # get orbit l and b
        ll = o.ll(ts)
        bb = o.bb(ts)

        np.save("./Orbits/{}/l{}150Myr.npy".format(star_id[i], save_name), ll)
        np.save("./Orbits/{}/b{}150Myr.npy".format(star_id[i], save_name), bb)

    else:
        ll = np.load("./Orbits/{}/l{}150Myr.npy".format(star_id[i], save_name))
        bb = np.load("./Orbits/{}/b{}150Myr.npy".format(star_id[i], save_name))

    Npoints = len(ll)

    # Find boundary breaks at -180 and 180
    boundary_breaks = []

    # crossings for 180
    for j in range(1, Npoints):
        # crossings for 180+
        if (ll[j - 1] <= 180) and (ll[j] > 180):
            boundary_breaks.append(j)
        # crossings for 180-
        elif (ll[j - 1] >= 180) and (ll[j] < 180):
            boundary_breaks.append(j)

    boundary_breaks.append(Npoints)

    # fix ll > 180
    ll[ll > 180] = ll[ll > 180] - 360

    # plots
    j0 = 0
    for k in range(len(boundary_breaks)):
        jf = boundary_breaks[k]
        plt.plot(ll[j0:jf] * radconv,
                 bb[j0:jf] * radconv,
                 zorder=zorder,
                 **kargs)
        j0 = jf

    # plot extremes
    if plot_extreme == 'lower':
        lower = plt.plot(ll[-1] * radconv,
                         bb[-1] * radconv,
                         marker='x',
                         markersize=4,
                         color=colors[i],
                         alpha=1,
                         zorder=zorder + 1)
        return lower

    elif plot_extreme == 'upper':
        upper = plt.plot(ll[-1] * radconv,
                         bb[-1] * radconv,
                         marker='o',
                         markersize=4,
                         markeredgecolor=colors[i],
                         color="#FFFFFF",
                         alpha=1,
                         zorder=zorder + 1)
        return upper
Ejemplo n.º 24
0
def test_energy_momentum_of_sun():
    o = Orbit()  # create sun's orbit
    o.turn_physical_off()
    ts = np.linspace(0, 1000, 100000)
    o.integrate(ts, MWPotential2014)
    print('galpy energy = ', o.E())
    coord = np.array([o.x(), o.y(), o.z(), o.vx(), o.vy(), o.vz()])
    print('my energy = ', Energy(coord))
    print(o.E() == Energy(coord))
    print('galpy momentum = ', o.L()[0][2])
    print('my momentum = ', L_z(coord))
    print(o.L()[0][2] == L_z(coord))
Ejemplo n.º 25
0
import sys
import numpy
from galpy.orbit import Orbit
from galpy.potential import  MiyamotoNagaiPotential

if __name__ == '__main__':
    # python orbitint4sigint.py symplec4_c full
    mp= MiyamotoNagaiPotential(normalize=1.,a=0.5,b=0.05)
    ts= numpy.linspace(0.,10000000.,1000001)
    if sys.argv[2] == 'full' or sys.argv[2] == 'planar':
        if sys.argv[2] == 'full':
            o= Orbit([1.,0.1,1.1,0.1,0.1,0.])
        elif sys.argv[2] == 'planar':
            o= Orbit([1.,0.1,1.1,0.1])
        o.integrate(ts,mp,method=sys.argv[1])
    elif sys.argv[2] == 'planardxdv':
        o= Orbit([1.,0.1,1.1,0.1])
        o.integrate_dxdv([0.1,0.1,0.1,0.1],ts,mp,method=sys.argv[1])
    sys.exit(0)
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
def pal5_dpmguess(
    pot: PotentialType,
    doras: Optional[float] = None,
    dodecs: Optional[float] = None,
    dovloss: Optional[float] = None,
    dmin: float = 21.0,
    dmax: float = 25.0,
    dstep: float = 0.02,
    pmmin: float = -0.36,
    pmmax: float = 0.36,
    pmstep: float = 0.01,
    alongbfpm: bool = False,
    ro: float = REFR0,
    vo: float = REFV0,
) -> tuple:
    """pal5_dpmguess.

    Parameters
    ----------
    pot: Potential
    doras : float or None, optional
        default None
    dodecs : float or None, optional
        default None
    dovloss : float or None, optional
        default None
    dmin=21 : float or None, optional
        default 0
    dmax=25 : float or None, optional
        default 0
    dstep=0 : float or None, optional
        default 02
    pmmin=-0 : float or None, optional
        default 36
    pmmax=0 : float or None, optional
        default 36
    pmstep=0 : float or None, optional
        default 01
    alongbfpm : float or None, optional
        default False
    ro : float or None, optional
        default REFR0
    vo : float or None, optional
        default REFV0

    Returns
    -------
    bestd
    bestpmoff
    lnl
    ds
    pmoffs

    """
    if doras is None:
        with open("pal5_stream_orbit_offset.pkl", "rb") as savefile:
            doras = pickle.load(savefile)
            dodecs = pickle.load(savefile)
            dovloss = pickle.load(savefile)

    ds = np.arange(dmin, dmax + dstep / 2.0, dstep)
    pmoffs = np.arange(pmmin, pmmax + pmstep / 2.0, pmstep)
    lnl = np.zeros((len(ds), len(pmoffs)))

    pos_radec, rvel_ra = pal5_data_total()

    print("Determining good distance and parallel proper motion...")

    for ii, d in tqdm(enumerate(ds)):
        for jj, pmoff in enumerate(pmoffs):
            if alongbfpm:
                pm = (d - 24.0) * 0.099 + 0.0769 + pmoff
            else:
                pm = pmoff
            progt = Orbit(
                [
                    229.11,
                    0.3,
                    d + 0.3,
                    -2.27 + pm,
                    -2.22 + pm * 2.257 / 2.296,
                    -58.5,
                ],
                radec=True,
                ro=ro,
                vo=vo,
                solarmotion=[-11.1, 24.0, 7.25],
            ).flip()
            ts = np.linspace(0.0, 3.0, 1001)
            progt.integrate(ts, pot)
            progt._orb.orbit[:, 1] *= -1.0
            progt._orb.orbit[:, 2] *= -1.0
            progt._orb.orbit[:, 4] *= -1.0
            toras, todecs, tovloss = (
                progt.ra(ts),
                progt.dec(ts),
                progt.vlos(ts),
            )
            # Interpolate onto common RA
            ipdec = interpolate.InterpolatedUnivariateSpline(toras, todecs)
            ipvlos = interpolate.InterpolatedUnivariateSpline(toras, tovloss)
            todecs = ipdec(doras) - dodecs
            tovloss = ipvlos(doras) - dovloss
            est_trackRADec_trailing = np.zeros((1, len(doras), 2))
            est_trackRADec_trailing[0, :, 0] = doras
            est_trackRADec_trailing[0, :, 1] = todecs
            est_trackRAVlos_trailing = np.zeros((1, len(doras), 2))
            est_trackRAVlos_trailing[0, :, 0] = doras
            est_trackRAVlos_trailing[0, :, 1] = tovloss
            lnl[ii, jj] = (
                np.sum(
                    pal5_lnlike(
                        pos_radec,
                        rvel_ra,
                        est_trackRADec_trailing,
                        est_trackRADec_trailing,  # hack
                        est_trackRAVlos_trailing,
                        est_trackRAVlos_trailing,  # hack
                        np.array([0.0]),
                        np.array([0.0]),
                        None,
                    )[0, :3:2]) - 0.5 * pm**2.0 / 0.186**2.0)  # pm measurement

        # /for
    # /for

    bestd = ds[np.unravel_index(np.argmax(lnl), lnl.shape)[0]]

    if alongbfpm:
        bestpmoff = ((bestd - 24.0) * 0.099 + 0.0769 +
                     pmoffs[np.unravel_index(np.argmax(lnl), lnl.shape)[1]])
    else:
        bestpmoff = pmoffs[np.unravel_index(np.argmax(lnl), lnl.shape)[1]]
    # /if

    return bestd, bestpmoff, lnl, ds, pmoffs
def predict_pal5obs(
    pot_params: list,
    c: float,
    b: float = 1.0,
    pa: float = 0.0,
    sigv: Union[float, list] = 0.2,
    td: float = 10.0,
    dist: float = 23.2,
    pmra: float = -2.296,
    pmdec: float = -2.257,
    vlos: float = -58.7,
    ro: float = REFR0,
    vo: float = REFV0,
    singlec: bool = False,
    interpcs: Optional[float] = None,
    interpk: Optional[float] = None,
    isob: Optional[float] = None,
    nTrackChunks: int = 8,
    multi: Optional = None,
    trailing_only: bool = False,
    useTM: bool = False,
    verbose: bool = True,
) -> TrackTuple:
    """Predict Pal 5 Observed.

    Function that generates the location and velocity of the Pal 5 stream,
    its width, and its length for a given potential and progenitor
    phase-space position

    Parameters
    ----------
    pot_params: array
        parameters of a potential model
        (see mw_pot.setup_potential; only the basic
         parameters of the disk and halo are used,
         flattening is specified separately)
    c : float
        halo flattening
    b : float, optional
        (1.) halo-squashed
    pa: float, optional
        (0.) halo PA
    sigv : float, optional
        (0.4) velocity dispersion in km/s
        (can be array of same len as interpcs)
    td : float, optional
        (5.) stream age in Gyr (can be array of same len as interpcs)
    dist : float, optional
        (23.2) progenitor distance in kpc
    pmra : float, optional
        (-2.296) progenitor proper motion in RA * cos(Dec) in mas/yr
    pmdec : float, optional
        (-2.257) progenitor proper motion in Dec in mas/yr
    vlos : float, optional
        (-58.7) progenitor line-of-sight velocity in km/s
    ro : float, optional
        (project default) distance to the GC in kpc
    vo : float, optional
        (project default) circular velocity at R0 in km/s
    singlec : bool, optional
        (False) if True, just compute the observables for a single c
    interpcs : float or None, optional
        (None) values of c at which to compute the model for interpolation
    nTrackChunks : int, optional
        (8) nTrackChunks input to streamdf
    multi : float or None, optional
        (None) multi input to streamdf
    isob : float or None, optional
        (None) if given, b parameter of actionAngleIsochroneApprox
    trailing_only : bool, optional
        (False) if True, only predict the trailing arm
    useTM : bool, optional
        (True) use the TorusMapper to compute the track
    verbose : bool, optional
        (True) print messages


    Returns
    -------
    trackRADec_trailing_out : array
        trailing track in RA, Dec
        all arrays with the shape of c
    trackRADec_leading_out : array
        leading track in RA, Dec
        all arrays with the shape of c
    trackRAVlos_trailing_out : array
        trailing track in RA, Vlos
        all arrays with the shape of c
    trackRAVlos_leading_out : array
        leading track in RA, Vlos
        all arrays with the shape of c
    width_out : float
        trailing width in arcmin
    length_out : float
        trailing length in deg
    interpcs : array
    success : bool

    """

    # First compute the model for all cs at which we will interpolate
    interpcs: list
    if singlec:
        interpcs = [c]
    elif interpcs is None:
        interpcs = [
            0.5,
            0.75,
            1.0,
            1.25,
            1.55,
            1.75,
            2.0,
            2.25,
            2.5,
            2.75,
            3.0,
        ]
    else:
        interpcs = copy.deepcopy(interpcs)  # bc we might want to remove some
    if isinstance(sigv, float):
        sigv: list = [sigv for i in interpcs]
    if isinstance(td, float):
        td: list = [td for i in interpcs]
    if isinstance(isob, float) or isob is None:
        isob: list = [isob for i in interpcs]

    prog: Orbit = Orbit(
        [229.018, -0.124, dist, pmra, pmdec, vlos],
        radec=True,
        ro=ro,
        vo=vo,
        solarmotion=[-11.1, 24.0, 7.25],
    )

    # Setup the model
    sdf_trailing_varyc: list = []
    sdf_leading_varyc: list = []
    ii: int = 0
    ninterpcs: int = len(interpcs)
    this_useTM: bool = copy.deepcopy(useTM)
    this_nTrackChunks: int = nTrackChunks
    ntries: int = 0

    while ii < ninterpcs:
        ic = interpcs[ii]
        pot = mw_pot.setup_potential(pot_params,
                                     ic,
                                     False,
                                     False,
                                     ro,
                                     vo,
                                     b=b,
                                     pa=pa)
        success: bool = True
        # wentIn = ntries != 0
        # Make sure this doesn't run forever
        signal.signal(signal.SIGALRM, timeout_handler)
        signal.alarm(300)
        try:
            tsdf_trailing, tsdf_leading = setup_sdf(
                pot,
                prog,
                sigv[ii],
                td[ii],
                ro,
                vo,
                multi=multi,
                isob=isob[ii],
                nTrackChunks=this_nTrackChunks,
                trailing_only=trailing_only,
                verbose=verbose,
                useTM=this_useTM,
            )
        except Exception:
            # Catches errors and time-outs
            success = False
        signal.alarm(0)
        # Check for calc. issues
        if not success or (not this_useTM
                           and looks_funny(tsdf_trailing, tsdf_leading)):
            # Try again with TM
            this_useTM = True
            this_nTrackChunks = 21  # might as well

            # wentIn= True
            # print("Here",ntries,success)
            # sys.stdout.flush()

            ntries += 1
        else:
            success = not this_useTM
            # if wentIn:
            #    print(success)
            #    sys.stdout.flush()
            ii += 1
            # reset
            this_useTM = useTM
            this_nTrackChunks = nTrackChunks
            ntries = 0
            # Add to the list
            sdf_trailing_varyc.append(tsdf_trailing)
            sdf_leading_varyc.append(tsdf_leading)

    if not singlec and len(sdf_trailing_varyc) <= 1:
        # Almost everything bad!!
        return (
            np.zeros((len(c), 1001, 2)),
            np.zeros((len(c), 1001, 2)),
            np.zeros((len(c), 1001, 2)),
            np.zeros((len(c), 1001, 2)),
            np.zeros((len(c))),
            np.zeros((len(c))),
            [],
            success,
        )
    # Compute the track properties for each model
    trackRADec_trailing: np.ndarray = np.zeros(
        (len(interpcs), sdf_trailing_varyc[0].nInterpolatedTrackChunks, 2))
    trackRADec_leading: np.ndarray = np.zeros(
        (len(interpcs), sdf_trailing_varyc[0].nInterpolatedTrackChunks, 2))
    trackRAVlos_trailing: np.ndarray = np.zeros(
        (len(interpcs), sdf_trailing_varyc[0].nInterpolatedTrackChunks, 2))
    trackRAVlos_leading: np.ndarray = np.zeros(
        (len(interpcs), sdf_trailing_varyc[0].nInterpolatedTrackChunks, 2))
    # TODO put in distances (can use _interpolatedObsTrackLB[:,2],)
    width: np.ndarray = np.zeros(len(interpcs))
    length: np.ndarray = np.zeros(len(interpcs))
    for ii in range(len(interpcs)):
        trackRADec_trailing[ii] = bovy_coords.lb_to_radec(
            sdf_trailing_varyc[ii]._interpolatedObsTrackLB[:, 0],
            sdf_trailing_varyc[ii]._interpolatedObsTrackLB[:, 1],
            degree=True,
        )
        if not trailing_only:
            trackRADec_leading[ii] = bovy_coords.lb_to_radec(
                sdf_leading_varyc[ii]._interpolatedObsTrackLB[:, 0],
                sdf_leading_varyc[ii]._interpolatedObsTrackLB[:, 1],
                degree=True,
            )
        trackRAVlos_trailing[ii][:, 0] = trackRADec_trailing[ii][:, 0]
        trackRAVlos_trailing[ii][:, 1] = sdf_trailing_varyc[
            ii]._interpolatedObsTrackLB[:, 3]
        if not trailing_only:
            trackRAVlos_leading[ii][:, 0] = trackRADec_leading[ii][:, 0]
            trackRAVlos_leading[ii][:, 1] = sdf_leading_varyc[
                ii]._interpolatedObsTrackLB[:, 3]
        width[ii] = width_trailing(sdf_trailing_varyc[ii])
        length[ii] = sdf_trailing_varyc[ii].length(ang=True,
                                                   coord="customra",
                                                   threshold=0.3)
    if singlec:
        # if wentIn:
        #    print(success)
        #    sys.stdout.flush()
        return (
            trackRADec_trailing,
            trackRADec_leading,
            trackRAVlos_trailing,
            trackRAVlos_leading,
            width,
            length,
            interpcs,
            success,
        )
    # Interpolate; output grids
    trackRADec_trailing_out: np.ndarray = np.zeros(
        (len(c), sdf_trailing_varyc[0].nInterpolatedTrackChunks, 2))
    trackRADec_leading_out: np.ndarray = np.zeros(
        (len(c), sdf_trailing_varyc[0].nInterpolatedTrackChunks, 2))
    trackRAVlos_trailing_out: np.ndarray = np.zeros(
        (len(c), sdf_trailing_varyc[0].nInterpolatedTrackChunks, 2))
    trackRAVlos_leading_out: np.ndarray = np.zeros(
        (len(c), sdf_trailing_varyc[0].nInterpolatedTrackChunks, 2))

    if interpk is None:
        interpk = np.amin([len(interpcs) - 1, 3])

    for ii in range(sdf_trailing_varyc[0].nInterpolatedTrackChunks):
        ip = interpolate.InterpolatedUnivariateSpline(interpcs,
                                                      trackRADec_trailing[:,
                                                                          ii,
                                                                          0],
                                                      k=interpk,
                                                      ext=0)
        trackRADec_trailing_out[:, ii, 0] = ip(c)
        ip = interpolate.InterpolatedUnivariateSpline(interpcs,
                                                      trackRADec_trailing[:,
                                                                          ii,
                                                                          1],
                                                      k=interpk,
                                                      ext=0)
        trackRADec_trailing_out[:, ii, 1] = ip(c)
        ip = interpolate.InterpolatedUnivariateSpline(interpcs,
                                                      trackRAVlos_trailing[:,
                                                                           ii,
                                                                           0],
                                                      k=interpk,
                                                      ext=0)
        trackRAVlos_trailing_out[:, ii, 0] = ip(c)
        ip = interpolate.InterpolatedUnivariateSpline(interpcs,
                                                      trackRAVlos_trailing[:,
                                                                           ii,
                                                                           1],
                                                      k=interpk,
                                                      ext=0)
        trackRAVlos_trailing_out[:, ii, 1] = ip(c)

        if not trailing_only:
            ip = interpolate.InterpolatedUnivariateSpline(
                interpcs, trackRADec_leading[:, ii, 0], k=interpk, ext=0)
            trackRADec_leading_out[:, ii, 0] = ip(c)
            ip = interpolate.InterpolatedUnivariateSpline(
                interpcs, trackRADec_leading[:, ii, 1], k=interpk, ext=0)
            trackRADec_leading_out[:, ii, 1] = ip(c)
            ip = interpolate.InterpolatedUnivariateSpline(
                interpcs, trackRAVlos_leading[:, ii, 0], k=interpk, ext=0)
            trackRAVlos_leading_out[:, ii, 0] = ip(c)
            ip = interpolate.InterpolatedUnivariateSpline(
                interpcs, trackRAVlos_leading[:, ii, 1], k=interpk, ext=0)
            trackRAVlos_leading_out[:, ii, 1] = ip(c)
    # /for

    ip = interpolate.InterpolatedUnivariateSpline(interpcs,
                                                  width,
                                                  k=interpk,
                                                  ext=0)
    width_out = ip(c)
    ip = interpolate.InterpolatedUnivariateSpline(interpcs,
                                                  length,
                                                  k=interpk,
                                                  ext=0)
    length_out = ip(c)

    return TrackTuple(
        trackRADec_trailing_out=trackRADec_trailing_out,
        trackRADec_leading_out=trackRADec_leading_out,
        trackRAVlos_trailing_out=trackRAVlos_trailing_out,
        trackRAVlos_leading_out=trackRAVlos_leading_out,
        width_out=width_out,
        length_out=length_out,
        interpcs=interpcs,
        success=success,
    )
Ejemplo n.º 29
0
def calc_es():
    savefilename = 'myes.sav'
    if os.path.exists(savefilename):
        savefile = open(savefilename, 'rb')
        mye = pickle.load(savefile)
        e = pickle.load(savefile)
        savefile.close()
    else:
        #Read data
        dialect = csv.excel
        dialect.skipinitialspace = True
        reader = csv.reader(open('../data/Dierickx-etal-tab2.txt', 'r'),
                            delimiter=' ',
                            dialect=dialect)
        vxvs = []
        es = []
        vphis = []
        vxs = []
        vys = []
        vzs = []
        ls = []
        for row in reader:
            thisra = float(row[3])
            thisdec = float(row[4])
            thisd = float(row[17]) / 1000.
            thispmra = float(row[13])
            thispmdec = float(row[15])
            thisvlos = float(row[11])
            thise = float(row[26])
            vxvs.append(
                [thisra, thisdec, thisd, thispmra, thispmdec, thisvlos])
            es.append(thise)
            vphis.append(float(row[25]))
            vxs.append(float(row[19]))
            vys.append(float(row[21]))
            vzs.append(float(row[23]))
            ls.append(float(row[5]))
        vxvv = nu.array(vxvs)
        e = nu.array(es)
        vphi = nu.array(vphis)
        vx = nu.array(vxs)
        vy = nu.array(vys)
        vz = nu.array(vzs)
        l = nu.array(ls)

        #Define potential
        lp = LogarithmicHaloPotential(normalize=1.)
        mp = MiyamotoNagaiPotential(a=0.5, b=0.0375, amp=1., normalize=.6)
        np = NFWPotential(a=4.5, normalize=.35)
        hp = HernquistPotential(a=0.6 / 8, normalize=0.05)
        ts = nu.linspace(0., 20., 10000)

        mye = nu.zeros(len(e))
        for ii in range(len(e)):
            #Integrate the orbit
            o = Orbit(vxvv[ii, :], radec=True, vo=220., ro=8.)
            o.integrate(ts, lp)
            mye[ii] = o.e()

        #Save
        savefile = open(savefilename, 'wb')
        pickle.dump(mye, savefile)
        pickle.dump(e, savefile)
        savefile.close()

    #plot
    plot.bovy_print()
    plot.bovy_plot(nu.array([0., 1.]),
                   nu.array([0., 1.]),
                   'k-',
                   xlabel=r'$\mathrm{Dierickx\ et\ al.}\ e$',
                   ylabel=r'$\mathrm{galpy}\ e$')
    plot.bovy_plot(e, mye, 'k,', overplot=True)
    plot.bovy_end_print('myee.png')

    plot.bovy_print()
    plot.bovy_hist(e, bins=30, xlabel=r'$\mathrm{Dierickx\ et\ al.}\ e$')
    plot.bovy_end_print('ehist.png')

    plot.bovy_print()
    plot.bovy_hist(mye, bins=30, xlabel=r'$\mathrm{galpy}\ e$')
    plot.bovy_end_print('myehist.png')
Ejemplo n.º 30
0
    return lbd[0], lbd[1], lbd[2]


Mbar = 10**10.
pat_speed = 40.
ang = 27.

Ac, As = SCFbar_util.compute_Acos_Asin()
barpot, nobarpot = SCFbar_util.Particle_Spray_MWPotentialSCFbar(mbar=Mbar,
                                                                Acos=Ac,
                                                                Asin=As,
                                                                t_on=-2.)

p5 = Orbit([229.018, -0.124, 23.2, -2.296, -2.257, -58.7],
           radec=True,
           ro=ro,
           vo=vo,
           solarmotion=[-11.1, 24., 7.25])

#convert to galpy units
pal5 = Orbit(p5._orb.vxvv)

#mass of Pal 5 from Dehnen https://arxiv.org/pdf/astro-ph/0401422.pdf
spdf = streamspraydf.streamspraydf(60000. * units.Msun,
                                   progenitor=pal5,
                                   pot=nobarpot,
                                   tdisrupt=5. * units.Gyr)
spdft = streamspraydf.streamspraydf(60000. * units.Msun,
                                    progenitor=pal5,
                                    pot=nobarpot,
                                    leading=False,
Ejemplo n.º 31
0
        0.60122692,
        0.36273147,
        -0.97591502,
        -3.34169377,
        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,
Ejemplo n.º 32
0
def test_orbitint():
    import numpy
    from galpy.potential import MWPotential2014
    from galpy.potential import evaluatePotentials as evalPot
    from galpy.orbit import Orbit
    E, Lz = -1.25, 0.6
    o1 = Orbit([
        0.8, 0., Lz / 0.8, 0.,
        numpy.sqrt(2. * (E - evalPot(MWPotential2014, 0.8, 0.) -
                         (Lz / 0.8)**2. / 2.)), 0.
    ])
    ts = numpy.linspace(0., 100., 2001)
    o1.integrate(ts, MWPotential2014)
    o1.plot(xrange=[0.3, 1.], yrange=[-0.2, 0.2], color='k')
    o2 = Orbit([
        0.8, 0.3, Lz / 0.8, 0.,
        numpy.sqrt(2. * (E - evalPot(MWPotential2014, 0.8, 0.) -
                         (Lz / 0.8)**2. / 2. - 0.3**2. / 2.)), 0.
    ])
    o2.integrate(ts, MWPotential2014)
    o2.plot(xrange=[0.3, 1.], yrange=[-0.2, 0.2], color='k')
    return None
Ejemplo n.º 33
0
def calc_eccentricity(args, options):
    table = os.path.join(args[0],'table2.dat')
    readme = os.path.join(args[0],'ReadMe')
    dierickx = ascii.read(table, readme=readme)
    vxvv = np.dstack([dierickx['RAdeg'], dierickx['DEdeg'], dierickx['Dist']/1e3, dierickx['pmRA'], dierickx['pmDE'], dierickx['HRV']])[0]
    ro, vo, zo = 8., 220., 0.025
    ra, dec= vxvv[:,0], vxvv[:,1]
    lb= bovy_coords.radec_to_lb(ra,dec,degree=True)
    pmra, pmdec= vxvv[:,3], vxvv[:,4]
    pmllpmbb= bovy_coords.pmrapmdec_to_pmllpmbb(pmra,pmdec,ra,dec,degree=True)
    d, vlos= vxvv[:,2], vxvv[:,5]
    rectgal= bovy_coords.sphergal_to_rectgal(lb[:,0],lb[:,1],d,vlos,pmllpmbb[:,0], pmllpmbb[:,1],degree=True)
    vsolar= np.array([-10.1,4.0,6.7])
    vsun= np.array([0.,1.,0.,])+vsolar/vo
    X = rectgal[:,0]/ro
    Y = rectgal[:,1]/ro
    Z = rectgal[:,2]/ro
    vx = rectgal[:,3]/vo
    vy = rectgal[:,4]/vo
    vz = rectgal[:,5]/vo
    vsun= np.array([0.,1.,0.,])+vsolar/vo
    Rphiz= bovy_coords.XYZ_to_galcencyl(X,Y,Z,Zsun=zo/ro)
    vRvTvz= bovy_coords.vxvyvz_to_galcencyl(vx,vy,vz,Rphiz[:,0],Rphiz[:,1],Rphiz[:,2],vsun=vsun,Xsun=1.,Zsun=zo/ro,galcen=True)
    #do the integration and individual analytic estimate for each object
    ts= np.linspace(0.,20.,10000)
    lp= LogarithmicHaloPotential(normalize=1.)
    e_ana = numpy.zeros(len(vxvv))
    e_int = numpy.zeros(len(vxvv))
    print('Performing orbit integration and analytic parameter estimates for Dierickx et al. sample...')
    for i in tqdm(range(len(vxvv))):
        try:
            orbit = Orbit(vxvv[i], radec=True, vo=220., ro=8.)
            e_ana[i] = orbit.e(analytic=True, pot=lp, c=True)
        except UnboundError:
            e_ana[i] = np.nan
        orbit.integrate(ts, lp)
        e_int[i] = orbit.e(analytic=False)
    fig = plt.figure()
    fig.set_size_inches(1.5*columnwidth, 1.5*columnwidth)
    plt.scatter(e_int, e_ana,  s=1, color='Black', lw=0.)
    plt.xlabel(r'$\mathrm{galpy\ integrated}\ e$')
    plt.ylabel(r'$\mathrm{galpy\ analytic}\ e$')
    plt.xlim(0.,1.)
    plt.ylim(0.,1.)
    fig.tight_layout()
    plt.savefig(os.path.join(args[0],'dierickx-integratedeanalytice.png'), format='png', dpi=200)
    fig = plt.figure()
    fig.set_size_inches(1.5*columnwidth, 1.5*columnwidth)
    plt.hist(e_int, bins=30)
    plt.xlim(0.,1.)
    plt.xlabel(r'$\mathrm{galpy}\ e$')
    fig.tight_layout()
    plt.savefig(os.path.join(args[0], 'dierickx-integratedehist.png'), format='png', dpi=200)
    fig = plt.figure()
    fig.set_size_inches(1.5*columnwidth, 1.5*columnwidth)
    plt.scatter(dierickx['e'], e_int,  s=1, color='Black', lw=0.)
    plt.xlabel(r'$\mathrm{Dierickx\ et\ al.}\ e$')
    plt.ylabel(r'$\mathrm{galpy\ integrated}\ e$')
    plt.xlim(0.,1.)
    plt.ylim(0.,1.)
    fig.tight_layout()
    plt.savefig(os.path.join(args[0],'dierickx-integratedee.png'), format='png', dpi=200)
    fig = plt.figure()
    fig.set_size_inches(1.5*columnwidth, 1.5*columnwidth)
    plt.scatter(dierickx['e'], e_ana,  s=1, color='Black', lw=0.)
    plt.xlabel(r'$\mathrm{Dierickx\ et\ al.}\ e$')
    plt.ylabel(r'$\mathrm{galpy\ estimated}\ e$')
    plt.xlim(0.,1.)
    plt.ylim(0.,1.)
    fig.tight_layout()
    plt.savefig(os.path.join(args[0],'dierickx-analyticee.png'), format='png', dpi=200)
    arr = numpy.recarray(len(e_ana), dtype=[('analytic_e', float), ('integrated_e', float)])
    arr['analytic_e'] = e_ana
    arr['integrated_e'] = e_int
    with open(os.path.join(args[0],'eccentricities.dat'), 'w') as file:
        pickle.dump(arr, file)
        file.close()
Ejemplo n.º 34
0
def test_orbmethods():
    from galpy.orbit import Orbit
    from galpy.potential import MWPotential2014
    # 8/17/2019: added explicit z=0.025, because that was the default at the
    # time of the galpy paper, but the default has been changed
    o = Orbit([0.8, 0.3, 0.75, 0., 0.2, 0.],
              zo=0.025)  # setup R,vR,vT,z,vz,phi
    times = numpy.linspace(0., 10., 1001)  # Output times
    o.integrate(times, MWPotential2014)  # Integrate
    o.E()  # Energy
    assert numpy.fabs(o.E() + 1.2547650648697966
                      ) < 10.**-5., 'Orbit method does not work as expected'
    o.L()  # Angular momentum
    assert numpy.all(
        numpy.fabs(o.L() - numpy.array([[0., -0.16, 0.6]])) < 10.**-5.
    ), 'Orbit method does not work as expected'
    o.Jacobi(OmegaP=0.65)  #Jacobi integral E-OmegaP Lz
    assert numpy.fabs(o.Jacobi(OmegaP=0.65) - numpy.array([-1.64476506])
                      ) < 10.**-5., 'Orbit method does not work as expected'
    o.ER(times[-1]), o.Ez(times[-1])  # Rad. and vert. E at end
    assert numpy.fabs(o.ER(times[-1]) + 1.27601734263047
                      ) < 10.**-5., 'Orbit method does not work as expected'
    assert numpy.fabs(o.Ez(times[-1]) - 0.021252201847851909
                      ) < 10.**-5., 'Orbit method does not work as expected'
    o.rperi(), o.rap(), o.zmax()  # Peri-/apocenter r, max. |z|
    assert numpy.fabs(o.rperi() - 0.44231993168097
                      ) < 10.**-5., 'Orbit method does not work as expected'
    assert numpy.fabs(o.rap() - 0.87769030382105
                      ) < 10.**-5., 'Orbit method does not work as expected'
    assert numpy.fabs(o.zmax() - 0.077452357289016
                      ) < 10.**-5., 'Orbit method does not work as expected'
    o.e()  # eccentricity (rap-rperi)/(rap+rperi)
    assert numpy.fabs(o.e() - 0.32982348199330563
                      ) < 10.**-5., 'Orbit method does not work as expected'
    o.R(2., ro=8.)  # Cylindrical radius at time 2. in kpc
    assert numpy.fabs(o.R(2., ro=8.) - 3.5470772876920007
                      ) < 10.**-3., 'Orbit method does not work as expected'
    o.vR(5., vo=220.)  # Cyl. rad. velocity at time 5. in km/s
    assert numpy.fabs(o.vR(5., vo=220.) - 45.202530965094553
                      ) < 10.**-3., 'Orbit method does not work as expected'
    o.ra(1.), o.dec(1.)  # RA and Dec at t=1. (default settings)
    # 5/12/2016: test weakened, because improved galcen<->heliocen
    #            transformation has changed these, but still close
    assert numpy.fabs(o.ra(1.) - numpy.array([288.19277])
                      ) < 10.**-1., 'Orbit method does not work as expected'
    assert numpy.fabs(o.dec(1.) - numpy.array([18.98069155])
                      ) < 10.**-1., 'Orbit method does not work as expected'
    o.jr(type='adiabatic'), o.jz()  # R/z actions (ad. approx.)
    assert numpy.fabs(o.jr(type='adiabatic') - 0.05285302231137586
                      ) < 10.**-3., 'Orbit method does not work as expected'
    assert numpy.fabs(o.jz() - 0.006637988850751242
                      ) < 10.**-3., 'Orbit method does not work as expected'
    # Rad. period w/ Staeckel approximation w/ focal length 0.5,
    o.Tr(type='staeckel', delta=0.5, ro=8., vo=220.)  # in Gyr
    assert numpy.fabs(
        o.Tr(type='staeckel', delta=0.5, ro=8., vo=220.) - 0.1039467864018446
    ) < 10.**-3., 'Orbit method does not work as expected'
    o.plot(d1='R', d2='z')  # Plot the orbit in (R,z)
    o.plot3d()  # Plot the orbit in 3D, w/ default [x,y,z]
    return None
Ejemplo n.º 35
0
parser = get_options()
options, args = parser.parse_args()

Mbar = 10**10.
pat_speed = options.pat_speed
ang = 27.
td = options.td
t_on = options.t_on

Ac, As = SCFbar_util.compute_Acos_Asin()
barpot, nobarpot = SCFbar_util.Particle_Spray_MWPotentialSCFbar(
    mbar=Mbar, Acos=Ac, Asin=As, t_on=t_on, pat_speed=pat_speed, tstream=td)

p5 = Orbit([229.018, -0.124, 23.2, -2.296, -2.257, -58.7],
           radec=True,
           ro=ro,
           vo=vo,
           solarmotion=[-11.1, 24., 7.25])

#convert to galpy units
pal5 = Orbit(p5._orb.vxvv)

#mass of Pal 5 from Dehnen https://arxiv.org/pdf/astro-ph/0401422.pdf
spdf = streamspraydf.streamspraydf(50000. * units.Msun,
                                   progenitor=pal5,
                                   pot=barpot,
                                   tdisrupt=td * units.Gyr)
spdft = streamspraydf.streamspraydf(50000. * units.Msun,
                                    progenitor=pal5,
                                    pot=barpot,
                                    leading=False,
Ejemplo n.º 36
0
def test_surfacesection():
    #Preliminary code
    import numpy
    from galpy.potential import MWPotential2014
    from galpy.potential import evaluatePotentials as evalPot
    from galpy.orbit import Orbit
    E, Lz = -1.25, 0.6
    o1 = Orbit([
        0.8, 0., Lz / 0.8, 0.,
        numpy.sqrt(2. * (E - evalPot(MWPotential2014, 0.8, 0.) -
                         (Lz / 0.8)**2. / 2.)), 0.
    ])
    ts = numpy.linspace(0., 100., 2001)
    o1.integrate(ts, MWPotential2014)
    o2 = Orbit([
        0.8, 0.3, Lz / 0.8, 0.,
        numpy.sqrt(2. * (E - evalPot(MWPotential2014, 0.8, 0.) -
                         (Lz / 0.8)**2. / 2. - 0.3**2. / 2.)), 0.
    ])
    o2.integrate(ts, MWPotential2014)

    def surface_section(Rs, zs, vRs):
        # Find points where the orbit crosses z from - to +
        shiftzs = numpy.roll(zs, -1)
        indx = (zs[:-1] < 0.) * (shiftzs[:-1] > 0.)
        return (Rs[:-1][indx], vRs[:-1][indx])

    # Calculate and plot the surface of section
    ts = numpy.linspace(0., 1000., 20001)  # long integration
    o1.integrate(ts, MWPotential2014)
    o2.integrate(ts, MWPotential2014)
    sect1Rs, sect1vRs = surface_section(o1.R(ts), o1.z(ts), o1.vR(ts))
    sect2Rs, sect2vRs = surface_section(o2.R(ts), o2.z(ts), o2.vR(ts))
    from matplotlib.pyplot import plot, xlim, ylim
    plot(sect1Rs, sect1vRs, 'bo', mec='none')
    xlim(0.3, 1.)
    ylim(-0.69, 0.69)
    plot(sect2Rs, sect2vRs, 'yo', mec='none')
    return None
Ejemplo n.º 37
0
def pass_v(ra, dec, d, pm_ra, pm_dec, V, time, numpoints):
    """
    Function to estimate system velocity everytime it passes through the galactic plane.
    This velocity is a proxy for system's natal kick. For details, assumptions and caveats
    see Atri et al. 2019.

    -----
    ra,dec,d,pm_ra,pm_dec,V are source orbit parameters for Galpy
    
    time is the age to integrate (Gyr)
        
    numpoints is the number of points in the orbit to integrate.
    
    """
    o = Orbit([
        ra * u.deg, dec * u.deg, d * u.kpc, pm_ra * u.mas / u.yr,
        pm_dec * u.mas / u.yr, V * u.km / u.s
    ],
              radec=True)
    lp = MWPotential2014
    ts = np.linspace(0, time, numpoints) * u.Gyr
    o.integrate(ts, lp)

    pass_t_array = ts[np.where(
        np.sign(o.z(ts)[:-1]) - np.sign(o.z(ts)[1:]) != 0)[0]]
    results = []
    for pass_t in pass_t_array:
        o2 = Orbit(vxvv=[o.R(pass_t) / 8.0, 0., 1., 0., 0.,
                         o.phi(pass_t)],
                   ro=8.,
                   vo=220.)
        #results.append(np.sqrt((o.U(pass_t)-o2.U(0)+11.1)**2 + (o.V(pass_t)-o2.V(0)+12.24)**2 + (o.W(pass_t)-o2.W(0)+7.25)**2))
        results.append(
            np.sqrt((o.U(pass_t) - o2.U(0))**2 + (o.V(pass_t) - o2.V(0))**2 +
                    (o.W(pass_t) - o2.W(0))**2))

    return results
Ejemplo n.º 38
0
def test_adinvariance():
    from galpy.potential import IsochronePotential
    from galpy.orbit import Orbit
    from galpy.actionAngle import actionAngleIsochrone
    # Initialize two different IsochronePotentials
    ip1 = IsochronePotential(normalize=1., b=1.)
    ip2 = IsochronePotential(normalize=0.5, b=1.)
    # Use TimeInterpPotential to interpolate smoothly
    tip = TimeInterpPotential(ip1, ip2, dt=100., tform=50.)
    # Integrate: 1) Orbit in the first isochrone potential
    o1 = Orbit([1., 0.1, 1.1, 0.0, 0.1, 0.])
    ts = numpy.linspace(0., 50., 1001)
    o1.integrate(ts, tip)
    o1.plot(d1='x', d2='y', xrange=[-1.6, 1.6], yrange=[-1.6, 1.6], color='b')
    # 2) Orbit in the transition
    o2 = o1(ts[-1])  # Last time step => initial time step
    ts2 = numpy.linspace(50., 150., 1001)
    o2.integrate(ts2, tip)
    o2.plot(d1='x', d2='y', overplot=True, color='g')
    # 3) Orbit in the second isochrone potential
    o3 = o2(ts2[-1])
    ts3 = numpy.linspace(150., 200., 1001)
    o3.integrate(ts3, tip)
    o3.plot(d1='x', d2='y', overplot=True, color='r')
    # Now we calculate energy, maximum height, and mean radius
    print(o1.E(pot=ip1), (o1.rperi() + o1.rap()) / 2, o1.zmax())
    assert numpy.fabs(
        o1.E(pot=ip1) + 2.79921356237
    ) < 10.**-4., 'Energy in the adiabatic invariance test is different'
    assert numpy.fabs(
        (o1.rperi() + o1.rap()) / 2 - 1.07854158141
    ) < 10.**-4., 'mean radius in the adiabatic invariance test is different'
    assert numpy.fabs(
        o1.zmax() - 0.106331362938
    ) < 10.**-4., 'zmax in the adiabatic invariance test is different'
    print(o3.E(pot=ip2), (o3.rperi() + o3.rap()) / 2, o3.zmax())
    assert numpy.fabs(
        o3.E(pot=ip2) + 1.19677002624
    ) < 10.**-4., 'Energy in the adiabatic invariance test is different'
    assert numpy.fabs(
        (o3.rperi() + o3.rap()) / 2 - 1.39962036137
    ) < 10.**-4., 'mean radius in the adiabatic invariance test is different'
    assert numpy.fabs(
        o3.zmax() - 0.138364269321
    ) < 10.**-4., 'zmax in the adiabatic invariance test is different'
    # The orbit has clearly moved to larger radii,
    # the actions are however conserved from beginning to end
    aAI1 = actionAngleIsochrone(ip=ip1)
    print(aAI1(o1))
    js = aAI1(o1)
    assert numpy.fabs(
        js[0] - numpy.array([0.00773779])
    ) < 10.**-4., 'action in the adiabatic invariance test is different'
    assert numpy.fabs(
        js[1] - numpy.array([1.1])
    ) < 10.**-4., 'action in the adiabatic invariance test is different'
    assert numpy.fabs(
        js[2] - numpy.array([0.0045361])
    ) < 10.**-4., 'action in the adiabatic invariance test is different'
    aAI2 = actionAngleIsochrone(ip=ip2)
    print(aAI2(o3))
    js = aAI2(o3)
    assert numpy.fabs(
        js[0] - numpy.array([0.00773812])
    ) < 10.**-4., 'action in the adiabatic invariance test is different'
    assert numpy.fabs(
        js[1] - numpy.array([1.1])
    ) < 10.**-4., 'action in the adiabatic invariance test is different'
    assert numpy.fabs(
        js[2] - numpy.array([0.0045361])
    ) < 10.**-4., 'action in the adiabatic invariance test is different'
    return None
Ejemplo n.º 39
0
def test_physical_compatible_combos():
    # Test that physical_compatible acts as expected for combinations of
    # different types of objects
    from galpy.util.bovy_conversion import physical_compatible
    from galpy.potential import HernquistPotential
    from galpy.orbit import Orbit
    from galpy.actionAngle import actionAngleSpherical
    from galpy.df import quasiisothermaldf
    # Set up different objects for possible cases
    # Potentials
    pot_default_phys = HernquistPotential(amp=0.55, a=2., ro=8., vo=220.)
    pot_nonstandardro = HernquistPotential(amp=0.55, a=2., ro=9., vo=220.)
    pot_nonstandardvo = HernquistPotential(amp=0.55, a=2., ro=8., vo=230.)
    pot_nonstandardrovo = HernquistPotential(amp=0.55, a=2., ro=9., vo=230.)
    pot_nophys = HernquistPotential(amp=0.55)
    pot_default_noro = HernquistPotential(amp=0.55, vo=220.)
    pot_default_novo = HernquistPotential(amp=0.55, ro=8.)
    pot_nonstandardro_novo = HernquistPotential(amp=0.55, ro=9.)
    pot_nonstandardvo_noro = HernquistPotential(amp=0.55, vo=230.)
    pot_nonstandardvo_noro = HernquistPotential(amp=0.55, vo=230.)
    # Orbits
    orb_default_phys = Orbit([1., 0.1, 1.1, 0.1, 0.3, -0.9], ro=8., vo=220.)
    orb_nonstandardro = Orbit([1., 0.1, 1.1, 0.1, 0.3, -0.9], ro=9., vo=220.)
    orb_nonstandardvo = Orbit([1., 0.1, 1.1, 0.1, 0.3, -0.9], ro=8., vo=230.)
    orb_nonstandardrovo = Orbit([1., 0.1, 1.1, 0.1, 0.3, -0.9], ro=9., vo=230.)
    orb_nophys = Orbit([1., 0.1, 1.1, 0.1, 0.3, -0.9])
    orb_default_noro = Orbit([1., 0.1, 1.1, 0.1, 0.3, -0.9], vo=220.)
    orb_nonstandardvo_noro = Orbit([1., 0.1, 1.1, 0.1, 0.3, -0.9], vo=230.)
    # aAs
    aA_default_phys = actionAngleSpherical(pot=pot_default_phys,
                                           ro=8.,
                                           vo=220.)
    aA_nonstandardro = actionAngleSpherical(pot=pot_nonstandardro,
                                            ro=9.,
                                            vo=220.)
    aA_nonstandardvo = actionAngleSpherical(pot=pot_nonstandardvo,
                                            ro=8.,
                                            vo=230.)
    aA_nonstandardrovo = actionAngleSpherical(pot=pot_nonstandardrovo,
                                              ro=9.,
                                              vo=230.)
    aA_nophys = actionAngleSpherical(pot=pot_nophys)
    aA_default_novo = actionAngleSpherical(pot=pot_default_novo, ro=8.)
    aA_nonstandardvo_noro = actionAngleSpherical(pot=pot_nonstandardvo_noro,
                                                 vo=230.)
    # DFs
    qdf_default_phys = quasiisothermaldf(1. / 3.,
                                         0.2,
                                         0.1,
                                         1.,
                                         1.,
                                         pot=pot_default_phys,
                                         aA=aA_default_phys,
                                         ro=8.,
                                         vo=220.)
    qdf_nonstandardro = quasiisothermaldf(1. / 3.,
                                          0.2,
                                          0.1,
                                          1.,
                                          1.,
                                          pot=pot_nonstandardro,
                                          aA=aA_nonstandardro,
                                          ro=9.,
                                          vo=220.)
    qdf_nonstandardvo = quasiisothermaldf(1. / 3.,
                                          0.2,
                                          0.1,
                                          1.,
                                          1.,
                                          pot=pot_nonstandardvo,
                                          aA=aA_nonstandardvo,
                                          ro=8.,
                                          vo=230.)
    qdf_nonstandardrovo = quasiisothermaldf(1. / 3.,
                                            0.2,
                                            0.1,
                                            1.,
                                            1.,
                                            pot=pot_nonstandardrovo,
                                            aA=aA_nonstandardrovo,
                                            ro=9.,
                                            vo=230.)
    qdf_nophys = quasiisothermaldf(1. / 3.,
                                   0.2,
                                   0.1,
                                   1.,
                                   1.,
                                   pot=pot_nophys,
                                   aA=aA_nophys)
    # Now do some tests!
    assert physical_compatible(pot_default_phys,orb_default_phys), \
        "pot_default_phys does not behave as expected for combinations of different objects"
    assert physical_compatible(pot_default_phys,aA_default_phys), \
        "pot_default_phys does not behave as expected for combinations of different objects"
    assert physical_compatible(pot_default_phys,qdf_default_phys), \
        "pot_default_phys does not behave as expected for combinations of different objects"
    assert physical_compatible(pot_nonstandardro,orb_nonstandardro), \
        "pot_default_phys does not behave as expected for combinations of different objects"
    assert physical_compatible(pot_nonstandardro,aA_nonstandardro), \
        "pot_default_phys does not behave as expected for combinations of different objects"
    assert physical_compatible(pot_nonstandardro,qdf_nonstandardro), \
        "pot_default_phys does not behave as expected for combinations of different objects"
    assert not physical_compatible(pot_default_phys,orb_nonstandardro), \
        "pot_default_phys does not behave as expected for combinations of different objects"
    assert not physical_compatible(pot_default_phys,aA_nonstandardro), \
        "pot_default_phys does not behave as expected for combinations of different objects"
    assert not physical_compatible(pot_default_phys,qdf_nonstandardro), \
        "pot_default_phys does not behave as expected for combinations of different objects"
    assert not physical_compatible(pot_default_phys,orb_nonstandardvo), \
        "pot_default_phys does not behave as expected for combinations of different objects"
    assert not physical_compatible(pot_default_phys,aA_nonstandardvo), \
        "pot_default_phys does not behave as expected for combinations of different objects"
    assert not physical_compatible(pot_default_phys,qdf_nonstandardvo), \
        "pot_default_phys does not behave as expected for combinations of different objects"
    assert not physical_compatible(pot_default_phys,orb_nonstandardrovo), \
        "pot_default_phys does not behave as expected for combinations of different objects"
    assert not physical_compatible(pot_default_phys,aA_nonstandardrovo), \
        "pot_default_phys does not behave as expected for combinations of different objects"
    assert not physical_compatible(pot_default_phys,qdf_nonstandardrovo), \
        "pot_default_phys does not behave as expected for combinations of different objects"
    assert physical_compatible([pot_nophys,pot_nophys],orb_nonstandardrovo), \
        "pot_default_phys does not behave as expected for combinations of different objects"
    assert physical_compatible(pot_nophys,aA_nonstandardrovo), \
        "pot_default_phys does not behave as expected for combinations of different objects"
    assert physical_compatible(pot_nophys,qdf_nonstandardrovo), \
        "pot_default_phys does not behave as expected for combinations of different objects"
    assert physical_compatible(pot_nophys,orb_default_phys), \
        "pot_default_phys does not behave as expected for combinations of different objects"
    assert physical_compatible(pot_nophys,aA_default_phys), \
        "pot_default_phys does not behave as expected for combinations of different objects"
    assert physical_compatible(pot_nophys,qdf_default_phys), \
        "pot_default_phys does not behave as expected for combinations of different objects"
    assert physical_compatible(pot_nophys,orb_nophys), \
        "pot_default_phys does not behave as expected for combinations of different objects"
    assert physical_compatible(pot_nophys,orb_nophys), \
        "pot_default_phys does not behave as expected for combinations of different objects"
    assert physical_compatible(pot_nophys,qdf_nophys), \
        "pot_default_phys does not behave as expected for combinations of different objects"
    assert physical_compatible(pot_default_noro,qdf_nonstandardro), \
        "pot_default_phys does not behave as expected for combinations of different objects"
    assert physical_compatible(pot_nonstandardro_novo,orb_default_noro), \
        "pot_default_phys does not behave as expected for combinations of different objects"
    assert physical_compatible(aA_nonstandardvo_noro,orb_nonstandardvo_noro), \
        "pot_default_phys does not behave as expected for combinations of different objects"
    assert not physical_compatible(aA_default_novo,qdf_nonstandardrovo), \
        "pot_default_phys does not behave as expected for combinations of different objects"
    # Also test agained None!
    assert physical_compatible(None,pot_default_phys), \
        "pot_default_phys does not behave as expected for combinations of different objects"
    assert physical_compatible(None,orb_default_phys), \
        "pot_default_phys does not behave as expected for combinations of different objects"
    assert physical_compatible(None,aA_default_phys), \
        "pot_default_phys does not behave as expected for combinations of different objects"
    assert physical_compatible(None,qdf_default_phys), \
        "pot_default_phys does not behave as expected for combinations of different objects"
    assert physical_compatible(pot_default_phys,None), \
        "pot_default_phys does not behave as expected for combinations of different objects"
    assert physical_compatible(orb_default_phys,None), \
        "pot_default_phys does not behave as expected for combinations of different objects"
    assert physical_compatible(aA_default_phys,None), \
        "pot_default_phys does not behave as expected for combinations of different objects"
    assert physical_compatible(qdf_default_phys,None), \
        "pot_default_phys does not behave as expected for combinations of different objects"
    return None
Ejemplo n.º 40
0
def test_diskdf():
    from galpy.df import dehnendf
    # Init. dehnendf w/ flat rot., hr=1/3, hs=1, and sr(1)=0.2
    df = dehnendf(beta=0., profileParams=(1. / 3., 1.0, 0.2))
    # Same, w/ correction factors to scale profiles
    dfc = dehnendf(beta=0.,
                   profileParams=(1. / 3., 1.0, 0.2),
                   correct=True,
                   niter=20)
    if True:
        # Log. diff. between scale and DF surf. dens.
        numpy.log(df.surfacemass(0.5) / df.targetSurfacemass(0.5))
        assert numpy.fabs(
            numpy.log(df.surfacemass(0.5) / df.targetSurfacemass(0.5)) +
            0.056954077791649592
        ) < 10.**-4., 'diskdf does not behave as expected'
        # Same for corrected DF
        numpy.log(dfc.surfacemass(0.5) / dfc.targetSurfacemass(0.5))
        assert numpy.fabs(
            numpy.log(dfc.surfacemass(0.5) / dfc.targetSurfacemass(0.5)) +
            4.1440377205802041e-06
        ) < 10.**-4., 'diskdf does not behave as expected'
        # Log. diff between scale and DF sr
        numpy.log(df.sigmaR2(0.5) / df.targetSigma2(0.5))
        assert numpy.fabs(
            numpy.log(df.sigmaR2(0.5) / df.targetSigma2(0.5)) +
            0.12786083001363127
        ) < 10.**-4., 'diskdf does not behave as expected'
        # Same for corrected DF
        numpy.log(dfc.sigmaR2(0.5) / dfc.targetSigma2(0.5))
        assert numpy.fabs(
            numpy.log(dfc.sigmaR2(0.5) / dfc.targetSigma2(0.5)) +
            6.8065001252214986e-06
        ) < 10.**-4., 'diskdf does not behave as expected'
        # Evaluate DF w/ R,vR,vT
        df(numpy.array([0.9, 0.1, 0.8]))
        assert numpy.fabs(
            df(numpy.array([0.9, 0.1, 0.8])) - numpy.array(0.1740247246180417)
        ) < 10.**-4., 'diskdf does not behave as expected'
        # Evaluate corrected DF w/ Orbit instance
        from galpy.orbit import Orbit
        dfc(Orbit([0.9, 0.1, 0.8]))
        assert numpy.fabs(
            dfc(Orbit([0.9, 0.1, 0.8])) - numpy.array(0.16834863725552207)
        ) < 10.**-4., 'diskdf does not behave as expected'
        # Calculate the mean velocities
        df.meanvR(0.9), df.meanvT(0.9)
        assert numpy.fabs(
            df.meanvR(0.9)) < 10.**-4., 'diskdf does not behave as expected'
        assert numpy.fabs(df.meanvT(0.9) - 0.91144428051168291
                          ) < 10.**-4., 'diskdf does not behave as expected'
        # Calculate the velocity dispersions
        numpy.sqrt(dfc.sigmaR2(0.9)), numpy.sqrt(dfc.sigmaT2(0.9))
        assert numpy.fabs(numpy.sqrt(dfc.sigmaR2(0.9)) - 0.22103383792719539
                          ) < 10.**-4., 'diskdf does not behave as expected'
        assert numpy.fabs(numpy.sqrt(dfc.sigmaT2(0.9)) - 0.17613725303902811
                          ) < 10.**-4., 'diskdf does not behave as expected'
        # Calculate the skew of the velocity distribution
        df.skewvR(0.9), df.skewvT(0.9)
        assert numpy.fabs(
            df.skewvR(0.9)) < 10.**-4., 'diskdf does not behave as expected'
        assert numpy.fabs(df.skewvT(0.9) + 0.47331638366025863
                          ) < 10.**-4., 'diskdf does not behave as expected'
        # Calculate the kurtosis of the velocity distribution
        df.kurtosisvR(0.9), df.kurtosisvT(0.9)
        assert numpy.fabs(df.kurtosisvR(0.9) + 0.13561300880237059
                          ) < 10.**-4., 'diskdf does not behave as expected'
        assert numpy.fabs(df.kurtosisvT(0.9) - 0.12612702099300721
                          ) < 10.**-4., 'diskdf does not behave as expected'
        # Calculate a higher-order moment of the velocity DF
        df.vmomentsurfacemass(1., 6., 2.) / df.surfacemass(1.)
        assert numpy.fabs(
            df.vmomentsurfacemass(1., 6., 2.) / df.surfacemass(1.) -
            0.00048953492205559054
        ) < 10.**-4., 'diskdf does not behave as expected'
        # Calculate the Oort functions
        dfc.oortA(1.), dfc.oortB(1.), dfc.oortC(1.), dfc.oortK(1.)
        assert numpy.fabs(dfc.oortA(1.) - 0.40958989067012197
                          ) < 10.**-4., 'diskdf does not behave as expected'
        assert numpy.fabs(dfc.oortB(1.) + 0.49396172114486514
                          ) < 10.**-4., 'diskdf does not behave as expected'
        assert numpy.fabs(
            dfc.oortC(1.)) < 10.**-4., 'diskdf does not behave as expected'
        assert numpy.fabs(
            dfc.oortK(1.)) < 10.**-4., 'diskdf does not behave as expected'
    # Sample Orbits from the DF, returns list of Orbits
    numpy.random.seed(1)
    os = dfc.sample(n=100, returnOrbit=True, nphi=1)
    # check that these have the right mean radius = 2hr=2/3
    rs = numpy.array([o.R() for o in os])
    assert numpy.fabs(numpy.mean(rs) - 2. / 3.) < 0.1
    # Sample vR and vT at given R, check their mean
    vrvt = dfc.sampleVRVT(0.7, n=500, target=True)
    vt = vrvt[:, 1]
    assert numpy.fabs(numpy.mean(vrvt[:, 0])) < 0.05
    assert numpy.fabs(numpy.mean(vt) - dfc.meanvT(0.7)) < 0.01
    # Sample Orbits along a given line-of-sight
    os = dfc.sampleLOS(45., n=1000)
    return None
Ejemplo n.º 41
0
print('Using galpy version {}'.format(galpy.__version__))

FORWARD_THROUGH_TIME = False

# Purely for reference: the expected solar motion as provided by Schoenrich
REFERENCE_SCHOENRICH_SOLAR_MOTION = np.array([-11.1, -12.24, -7.25])

# Set the age to be a full galactic revolution
age = 2*np.pi # galpy time units
ntimesteps = 10
forward_times = np.linspace(0.,age,ntimesteps)
backward_times = np.linspace(0.,-age,ntimesteps)

# vxvv is in cylindrical coordinates here. [R,vR,vT(,z,vz,phi)]
lsr_orbit = Orbit(vxvv=[1,0,1,0,0,0],vo=220,ro=8,solarmotion='schoenrich')
back_lsr_orbit = Orbit(vxvv=[1,0,1,0,0,0],vo=220,ro=8,solarmotion='schoenrich')
lsr_orbit.integrate(forward_times, MWPotential2014)
back_lsr_orbit.integrate(backward_times, MWPotential2014)

# # Manually extract the initial velocities
# U = lsr_orbit.U(0)
# V = lsr_orbit.V(0)
# W = lsr_orbit.W(0)
#
# results = np.array([U, V, W]).reshape(3)
# print('-- Inspecting the initialised velocities --')
# for i, vel in enumerate('UVW'):
#     print("For velocity {}:".format(vel))
#     print("    expected: {}".format(REFERENCE_SCHOENRICH_SOLAR_MOTION[i]))
#     print("    received: {}".format(results[i]))
Ejemplo n.º 42
0
    def likelihood_orbit(self,
                         potential,
                         ejmodel,
                         index,
                         dt=0.005 * u.Myr,
                         xi=0,
                         individual=False,
                         weights=None,
                         tint_max=None):
        '''
        Same as likelihood, but returns the lnLikelihood for a single orbit, together with the entire orbit.

        Parameters
        ----------
            index : int
                Index of the star to propagate

            See self.likelihood() for other parameters
        Returns
        -------
        log likelihood values : numpy.array or float
            Returns the ln-likelihood of the entire sample or the log-likelihood for every single star if individual
            is True.
        x, y, z, vx, vy, vz : Quantity
            Position and velocity in Galactocentric coordinates.

        '''
        from galpy.orbit import Orbit
        import astropy.coordinates as coord
        from hvs.utils import t_MS

        if (self.cattype == 0):
            raise ValueError(
                "The likelihood can be computed only for a propagated sample.")

        if (self.size > 1e3):
            print(
                "You are computing the likelihood of a large sample. This might take a while."
            )

        weights = np.array(weights)
        if ((weights != None) and (weights.size != self.size)):
            raise ValueError(
                'The length of weights must be equal to the number of HVS in the sample.'
            )

        self.backwards_orbits = [None] * self.size
        self.back_dt = dt
        self.lnlike = np.ones(self.size) * (-np.inf)

        if (tint_max is None):
            lifetime = t_MS(self.m, xi)
            lifetime[lifetime > self.T_MW] = self.T_MW
        else:
            lifetime = np.ones(self.size) * tint_max
        nsteps = np.ceil((lifetime / self.back_dt).to('1').value)
        nsteps[nsteps < 100] = 100

        vSun = [
            -self.solarmotion[0], self.solarmotion[1], self.solarmotion[2]
        ] * u.km / u.s  # (U, V, W)
        vrot = [0., 220., 0.] * u.km / u.s

        RSun = 8. * u.kpc
        zSun = 0.025 * u.kpc

        v_sun = coord.CartesianDifferential(vrot + vSun)
        gc = coord.Galactocentric(galcen_distance=RSun,
                                  z_sun=zSun,
                                  galcen_v_sun=v_sun)

        for i in [index]:
            ts = np.linspace(0, 1, nsteps[i]) * lifetime[i]
            self.backwards_orbits[i] = Orbit(vxvv = [self.ra[i], self.dec[i], self.dist[i], \
                                    self.pmra[i], self.pmdec[i], self.vlos[i]], \
                                    solarmotion=self.solarmotion, radec=True).flip()
            self.backwards_orbits[i].integrate(ts,
                                               potential,
                                               method='dopr54_c')

            dist, ll, bb, pmll, pmbb, vlos = self.backwards_orbits[i].dist(ts, use_physical=True) * u.kpc, \
                                                self.backwards_orbits[i].ll(ts, use_physical=True) * u.deg, \
                                                self.backwards_orbits[i].bb(ts, use_physical=True) * u.deg, \
                                                self.backwards_orbits[i].pmll(ts, use_physical=True) *u.mas/u.year, \
                                                self.backwards_orbits[i].pmbb(ts, use_physical=True) * u.mas/u.year, \
                                                self.backwards_orbits[i].vlos(ts, use_physical=True) * u.km/u.s

            galactic = coord.Galactic(l=ll,
                                      b=bb,
                                      distance=dist,
                                      pm_l_cosb=pmll,
                                      pm_b=pmbb,
                                      radial_velocity=vlos)
            gal = galactic.transform_to(gc)
            vx, vy, vz = gal.v_x, gal.v_y, gal.v_z
            x, y, z = gal.x, gal.y, gal.z

            self.lnlike[i] = np.log(
                (ejmodel.R(self.m[i], vx, vy, vz, x, y, z) *
                 ejmodel.g(np.linspace(0, 1, nsteps[i]))).sum())

            return self.lnlike[i], x, y, z, vx, vy, vz
Ejemplo n.º 43
0
def test_orbmethods():
    from galpy.orbit import Orbit
    from galpy.potential import MWPotential2014
    o= Orbit([0.8,0.3,0.75,0.,0.2,0.]) # setup R,vR,vT,z,vz,phi
    times= numpy.linspace(0.,10.,1001) # Output times
    o.integrate(times,MWPotential2014) # Integrate
    o.E() # Energy
    assert numpy.fabs(o.E()+1.2547650648697966) < 10.**-5., 'Orbit method does not work as expected'
    o.L() # Angular momentum
    assert numpy.all(numpy.fabs(o.L()-numpy.array([[ 0.  , -0.16,  0.6 ]])) < 10.**-5.), 'Orbit method does not work as expected'
    o.Jacobi(OmegaP=0.65) #Jacobi integral E-OmegaP Lz
    assert numpy.fabs(o.Jacobi(OmegaP=0.65)-numpy.array([-1.64476506])) < 10.**-5., 'Orbit method does not work as expected'
    o.ER(times[-1]), o.Ez(times[-1]) # Rad. and vert. E at end
    assert numpy.fabs(o.ER(times[-1])+1.27601734263047) < 10.**-5., 'Orbit method does not work as expected'
    assert numpy.fabs(o.Ez(times[-1])-0.021252201847851909) < 10.**-5.,  'Orbit method does not work as expected'
    o.rperi(), o.rap(), o.zmax() # Peri-/apocenter r, max. |z|
    assert numpy.fabs(o.rperi()-0.44231993168097) < 10.**-5., 'Orbit method does not work as expected'
    assert numpy.fabs(o.rap()-0.87769030382105) < 10.**-5., 'Orbit method does not work as expected'
    assert numpy.fabs(o.zmax()-0.077452357289016) < 10.**-5., 'Orbit method does not work as expected'
    o.e() # eccentricity (rap-rperi)/(rap+rperi)
    assert numpy.fabs(o.e()-0.32982348199330563) < 10.**-5., 'Orbit method does not work as expected'
    o.R(2.,ro=8.) # Cylindrical radius at time 2. in kpc
    assert numpy.fabs(o.R(2.,ro=8.)-3.5470772876920007) < 10.**-3., 'Orbit method does not work as expected'
    o.vR(5.,vo=220.) # Cyl. rad. velocity at time 5. in km/s
    assert numpy.fabs(o.vR(5.,vo=220.)-45.202530965094553) < 10.**-3., 'Orbit method does not work as expected'
    o.ra(1.), o.dec(1.) # RA and Dec at t=1. (default settings)
    assert numpy.fabs(o.ra(1.)-numpy.array([ 288.19277])) < 10.**-3., 'Orbit method does not work as expected'
    assert numpy.fabs(o.dec(1.)-numpy.array([ 18.98069155])) < 10.**-3., 'Orbit method does not work as expected'
    o.jr(type='adiabatic'), o.jz() # R/z actions (ad. approx.)
    assert numpy.fabs(o.jr(type='adiabatic')-0.05285302231137586) < 10.**-3., 'Orbit method does not work as expected'
    assert numpy.fabs(o.jz()-0.006637988850751242) < 10.**-3., 'Orbit method does not work as expected'
    # Rad. period w/ Staeckel approximation w/ focal length 0.5,
    o.Tr(type='staeckel',delta=0.5,ro=8.,vo=220.) # in Gyr  
    assert numpy.fabs(o.Tr(type='staeckel',delta=0.5,ro=8.,vo=220.)-0.1039467864018446) < 10.**-3., 'Orbit method does not work as expected'
    o.plot(d1='R',d2='z') # Plot the orbit in (R,z)
    o.plot3d() # Plot the orbit in 3D, w/ default [x,y,z]
    return None
Ejemplo n.º 44
0
def compute_impact_parameters(timp,
                              a,
                              xs,
                              ys,
                              zs,
                              pot=MWPotential2014,
                              nchunks=16,
                              sampling_low=128,
                              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
    
    '''

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

    #integrate their orbits 5 Gyr back,
    t_age = np.linspace(0., 5., 1001) / bovy_conversion.time_in_Gyr(vo, ro)

    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 nchunks > 1:
        #just to get timpacts
        with open(
                'pkl_files/pal5pepper_{}sampling_Plummer_MW2014.pkl'.format(
                    sampling_low), '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] / ro

            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] / ro)
                M_mc.append(M[ii] / bovy_conversion.mass_in_msol(vo, ro))
                #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] / ro

            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] / ro)
                M_mc.append(M[ii] / bovy_conversion.mass_in_msol(vo, ro))
                #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)
Ejemplo n.º 45
0
def test_adinvariance():
    from galpy.potential import IsochronePotential
    from galpy.orbit import Orbit
    from galpy.actionAngle import actionAngleIsochrone
    # Initialize two different IsochronePotentials
    ip1= IsochronePotential(normalize=1.,b=1.)
    ip2= IsochronePotential(normalize=0.5,b=1.)
    # Use TimeInterpPotential to interpolate smoothly
    tip= TimeInterpPotential(ip1,ip2,dt=100.,tform=50.)
    # Integrate: 1) Orbit in the first isochrone potential
    o1= Orbit([1.,0.1,1.1,0.0,0.1,0.])
    ts= numpy.linspace(0.,50.,1001)
    o1.integrate(ts,tip)
    o1.plot(d1='x',d2='y',xrange=[-1.6,1.6],yrange=[-1.6,1.6],
            color='b')
    # 2) Orbit in the transition
    o2= o1(ts[-1]) # Last time step => initial time step
    ts2= numpy.linspace(50.,150.,1001)
    o2.integrate(ts2,tip)
    o2.plot(d1='x',d2='y',overplot=True,color='g')
    # 3) Orbit in the second isochrone potential
    o3= o2(ts2[-1])
    ts3= numpy.linspace(150.,200.,1001)
    o3.integrate(ts3,tip)
    o3.plot(d1='x',d2='y',overplot=True,color='r')
    # Now we calculate energy, maximum height, and mean radius
    print(o1.E(pot=ip1), (o1.rperi()+o1.rap())/2, o1.zmax())
    assert numpy.fabs(o1.E(pot=ip1)+2.79921356237) < 10.**-4., 'Energy in the adiabatic invariance test is different'
    assert numpy.fabs((o1.rperi()+o1.rap())/2-1.07854158141) < 10.**-4., 'mean radius in the adiabatic invariance test is different'
    assert numpy.fabs(o1.zmax()-0.106331362938) < 10.**-4., 'zmax in the adiabatic invariance test is different'
    print(o3.E(pot=ip2), (o3.rperi()+o3.rap())/2, o3.zmax())
    assert numpy.fabs(o3.E(pot=ip2)+1.19677002624) < 10.**-4., 'Energy in the adiabatic invariance test is different'
    assert numpy.fabs((o3.rperi()+o3.rap())/2-1.39962036137) < 10.**-4., 'mean radius in the adiabatic invariance test is different'
    assert numpy.fabs(o3.zmax()-0.138364269321) < 10.**-4., 'zmax in the adiabatic invariance test is different'
    # The orbit has clearly moved to larger radii,
    # the actions are however conserved from beginning to end
    aAI1= actionAngleIsochrone(ip=ip1); print(aAI1(o1))
    js= aAI1(o1)
    assert numpy.fabs(js[0]-numpy.array([ 0.00773779])) < 10.**-4., 'action in the adiabatic invariance test is different'
    assert numpy.fabs(js[1]-numpy.array([ 1.1])) < 10.**-4., 'action in the adiabatic invariance test is different'
    assert numpy.fabs(js[2]-numpy.array([ 0.0045361])) < 10.**-4., 'action in the adiabatic invariance test is different'
    aAI2= actionAngleIsochrone(ip=ip2); print(aAI2(o3))  
    js= aAI2(o3)
    assert numpy.fabs(js[0]-numpy.array([ 0.00773812])) < 10.**-4., 'action in the adiabatic invariance test is different'
    assert numpy.fabs(js[1]-numpy.array([ 1.1])) < 10.**-4., 'action in the adiabatic invariance test is different'
    assert numpy.fabs(js[2]-numpy.array([ 0.0045361])) < 10.**-4., 'action in the adiabatic invariance test is different'
    return None
def create_frames(basefilename):
    """Create Frames.

    Parameters
    ----------
    basefilename : str

    Returns
    -------
    None

    """
    pot = IsochronePotential(normalize=1.0, b=1.2)
    aAT = actionAngleIsochrone(ip=pot)
    bmock = 0.8
    aAF = actionAngleIsochrone(b=bmock)

    o = Orbit([1.0, 0.3, 0.9, 0.2, 1.0, 0.1])
    tfac, skip = 10, 1
    ndesired = 30 * 25
    times = numpy.linspace(0.0, 7.0, tfac * ndesired) * u.Gyr

    # Subsample
    otimesIndices = (numpy.arange(len(times)) /
                     float(len(times) - 1))**10 * (len(times) - 2)
    otimesIndices = numpy.unique(numpy.floor(otimesIndices).astype("int"))
    if len(otimesIndices) > ndesired:
        sfac = int(numpy.floor(len(otimesIndices) / float(ndesired)))
        otimesIndices = otimesIndices[::sfac]
    otimes = times[otimesIndices]
    o.integrate(times, pot)

    # Compute all actions in the wrong potential
    acfs = aAF.actionsFreqsAngles(
        o.R(times),
        o.vR(times),
        o.vT(times),
        o.z(times),
        o.vz(times),
        o.phi(times),
    )
    js = (acfs[0], acfs[1], acfs[2])
    danglerI = ((numpy.roll(acfs[6], -1) - acfs[6]) % (2.0 * numpy.pi))[:-1]
    jrC = numpy.cumsum(acfs[0][:-1] * danglerI) / numpy.cumsum(danglerI)

    # And also the actions in the true potential
    jsT = aAT(o.R(times), o.vR(times), o.vT(times), o.z(times), o.vz(times))
    jrT = numpy.median(jsT[0]) * _RO * _VO

    # ---------------------------------------------------------------
    # Plotting

    # Setup gridspec
    gs = gridspec.GridSpec(1, 3, wspace=0.325, bottom=0.2, left=0.075)

    # For each time step, plot: orbit, Jr, <Jr>
    for ii in tqdm(range(len(otimes))):
        bovy_plot.bovy_print(
            fig_width=11.2,
            fig_height=4.0,
            axes_labelsize=17.0,
            text_fontsize=12.0,
            xtick_labelsize=13.0,
            ytick_labelsize=13.0,
        )
        pyplot.figure()
        pyplot.subplot(gs[0])
        minIndx = otimesIndices[ii] - 100

        if minIndx < 0:
            minIndx = 0
        bovy_plot.bovy_plot(
            [o.x(otimes[ii:ii + 1]) * _RO],
            [o.z(otimes[ii:ii + 1]) * _RO],
            "o",
            ms=15.0,
            gcf=True,
            xrange=[-19.0, 19.0],
            yrange=[-19.0, 19.0],
            xlabel=r"$X\,(\mathrm{kpc})$",
            ylabel=r"$z\,(\mathrm{kpc})$",
        )

        if ii > 0:
            bovy_plot.bovy_plot(
                o.x(times[minIndx:otimesIndices[ii]:skip]) * _RO,
                o.z(times[minIndx:otimesIndices[ii]:skip]) * _RO,
                "-",
                overplot=True,
            )

        pyplot.subplot(gs[1])
        bovy_plot.bovy_plot(
            [times[otimesIndices[ii]].value],
            [js[0][otimesIndices[ii]] * _RO * _VO],
            "o",
            ms=15.0,
            gcf=True,
            xrange=[0.0, 1.0 + times[otimesIndices[ii]].value],
            yrange=[0.0, 349.0],
            xlabel=r"$\mathrm{time}\,(\mathrm{Gyr})$",
            ylabel=r"$J_R\,(\mathrm{kpc\,km\,s}^{-1})$",
        )

        if ii > 0:
            bovy_plot.bovy_plot(
                times[:otimesIndices[ii]:skip].value,
                js[0][:otimesIndices[ii]:skip] * _RO * _VO,
                "-",
                overplot=True,
            )

        pyplot.axhline(jrT, ls="--", color="k")
        pyplot.subplot(gs[2])
        bovy_plot.bovy_plot(
            [otimes[ii].value],
            [jrC[otimesIndices[ii]] * _RO * _VO],
            "o",
            ms=15.0,
            gcf=True,
            xrange=[0.0, 1.0 + times[otimesIndices[ii]].value],
            yrange=[
                (otimes[ii] / times[-1])**0.3 * (jrT - 3),
                349.0 + (otimes[ii] / times[-1])**0.3 * (jrT + 3 - 349.0),
            ],
            xlabel=r"$\mathrm{time}\,(\mathrm{Gyr})$",
            ylabel=r"$J_R\,(\mathrm{kpc\,km\,s}^{-1})$",
        )

        if ii > 0:
            bovy_plot.bovy_plot(
                times[:otimesIndices[ii]:skip].value,
                jrC[:otimesIndices[ii]:skip] * _RO * _VO,
                "-",
                overplot=True,
            )

        pyplot.axhline(jrT, ls="--", color="k")
        bovy_plot.bovy_end_print(basefilename + "_%05d.png" % ii)

    return None
Ejemplo n.º 47
0
def plot_aagrid(plotfilename1,plotfilename2):
    #Setup orbit
    E, Lz= -1.25, 0.6
    o= Orbit([0.8,0.3,Lz/0.8,0.,numpy.sqrt(2.*(E-evalPot(0.8,0.,MWPotential2014)-(Lz/0.8)**2./2.-0.3**2./2.)),0.])
    delta= 0.434
    #Integrate the orbit, setup Staeckel already to calculate the period
    aAS= actionAngleStaeckel(pot=MWPotential2014,delta=delta,c=True)
    orbt= 2.*numpy.pi/aAS.actionsFreqs(o)[4]  
    norb= 5.
    nt= 501
    ts= numpy.linspace(0.,norb*orbt,nt)
    o.integrate(ts,MWPotential2014,method='symplec4_c')
    #First do adiabatic
    aAA= actionAngleAdiabatic(pot=MWPotential2014,gamma=1.,c=True)
    aAAG= actionAngleAdiabaticGrid(pot=MWPotential2014,gamma=1.,c=True,
                                   nR=31,nEz=31,nEr=51,nLz=51)
    jfa= aAA(o.R(ts),o.vR(ts),o.vT(ts),o.z(ts),o.vz(ts),o.phi(ts))
    jfag= aAAG(o.R(ts),o.vR(ts),o.vT(ts),o.z(ts),o.vz(ts),o.phi(ts))
    #First do adiabatic
    #aAS already setup
    aASG= actionAngleStaeckelGrid(pot=MWPotential2014,delta=delta,c=True,
                                  nE=51,npsi=51,nLz=51)
    jfs= aAS(o.R(ts),o.vR(ts),o.vT(ts),o.z(ts),o.vz(ts),o.phi(ts))
    jfsg= aASG(o.R(ts),o.vR(ts),o.vT(ts),o.z(ts),o.vz(ts),o.phi(ts))
    bovy_plot.bovy_print()
    line1= bovy_plot.bovy_plot(jfa[0],jfa[2],'r.',
                               xrange=[0.045,0.055],
                               yrange=[0.0075,0.011],
                               xlabel=r'$J_R$',ylabel=r'$J_z$',zorder=2)
    line2= bovy_plot.bovy_plot(jfag[0],jfag[2],'rx',overplot=True,zorder=1)
    bovy_plot.bovy_plot(jfs[0],jfs[2],'k,',overplot=True)
    pyplot.legend((line1[0],line2[0]),
                  (r'$\mathrm{\texttt{actionAngleAdiabatic}}$',
                   r'$\mathrm{\texttt{actionAngleAdiabaticGrid}}$',),
                  loc='upper right',#bbox_to_anchor=(.91,.375),
                  numpoints=1,
                  prop={'size':14},
                  frameon=False)
    bovy_plot.bovy_end_print(plotfilename1)
    #Zoom of Staeckel
    line1= bovy_plot.bovy_plot(jfs[0],jfs[2],'k.',
                               xrange=[0.05025,0.05145],
                               yrange=[0.0086,0.00933],
                               xlabel=r'$J_R$',ylabel=r'$J_z$')
    line2= bovy_plot.bovy_plot(jfsg[0],jfsg[2],'kx',overplot=True)
    pyplot.legend((line1[0],line2[0]),
                  (r'$\mathrm{\texttt{actionAngleStaeckel}}$',
                   r'$\mathrm{\texttt{actionAngleStaeckelGrid}}$',),
                  loc='upper right',#bbox_to_anchor=(.91,.375),
                  numpoints=1,
                  prop={'size':14},
                  frameon=False)
    bovy_plot.bovy_end_print(plotfilename2)
    return None
Ejemplo n.º 48
0
        # If we have parallax, then take Gaia proper motions. Otherwise, UCAC5.
        if np.isfinite(star["parallax"]):
            pmra, e_pmra = ("pmra_gaia", "pmra_error")
            pmdec, e_pmdec = ("pmdec_gaia", "pmdec_error")

        else:
            pmra, e_pmra = ("pmRA", "e_pmRA")
            pmdec, e_pmdec = ("pmDE", "e_pmDE")

        pm_ra = np.random.normal(star[pmra], star[e_pmra])
        pm_dec = np.random.normal(star[pmdec], star[e_pmdec])
        v_hel = np.random.normal(star["vrad"], star["e_vrad"])

        orbit = Orbit(
            vxvv=[star["RA"], star["DEC"], distance, pm_ra, pm_dec, v_hel],
            radec=True,
            ro=ro,
            vo=vo)
        orbit.integrate(ts, mw)
        orbits.append(orbit)

    # Save the xyrz values.
    positions \
        = np.array([[o.x(ts), o.y(ts), o.z(ts), o.R(ts)] for o in orbits])
    properties = np.array([[o.rap(), o.rperi(),
                            o.e(), o.zmax()] for o in orbits])

    with open(output_path, "wb") as fp:
        pickle.dump((positions, properties), fp, -1)

    # Print some summary things.
Ejemplo n.º 49
0
def calcOrbits(parser):
    options,args= parser.parse_args()
    #Read data
    XYZ,vxvyvz,cov_vxvyvz,rawdata= readData(metal='allall',
                                            sample=options.sample,
                                            loggmin=4.2,
                                            snmin=15.,
                                            select=options.select)
    #Define potential
    if options.logp:
        pot= LogarithmicHaloPotential(normalize=1.)
    else:
        pot= MWPotential
    ts= numpy.linspace(0.,_MAXT,10000) #times to integrate
    if os.path.exists(args[0]):#Load savefile
        savefile= open(args[0],'rb')
        orbits= pickle.load(savefile)
        _ORBITSLOADED= True
        try:
            samples= pickle.load(savefile)
        except EORError:
            _SAMPLESLOADED= False
        else:
            _SAMPLESLOADED= True
        finally:
            savefile.close()
    else:
        _ORBITSLOADED= False
    if not _ORBITSLOADED:
        #First calculate orbits
        es, rmeans, rperis, raps, zmaxs = [], [], [], [], []
        densrmeans, vzrmeans= [], []
        for ii in range(len(rawdata)):
            sys.stdout.write('\r'+"Working on object %i/%i" % (ii,len(rawdata)))
            sys.stdout.flush()
            #Integrate the orbit
            data= rawdata[ii]
            o= Orbit([data.ra,data.dec,data.dist,data.pmra,data.pmdec,data.vr],
                     radec=True,vo=220.,ro=8.,zo=_ZSUN)
            o.integrate(ts,pot)
            es.append(o.e())
            rperis.append(o.rperi())
            raps.append(o.rap())
            zmaxs.append(o.zmax())
            rmeans.append(0.5*(o.rperi()+o.rap()))
            Rs= o.R(ts)
            vz2= o.vz(ts)**2.
            dens= evaluateDensities(Rs,0.*Rs,pot)
            densrmeans.append(numpy.sum(dens*Rs)/numpy.sum(dens))
            vzrmeans.append(numpy.sum(vz2*Rs)/numpy.sum(vz2))
#            print " ", rmeans[-1], densrmeans[-1], vzrmeans[-1]
        sys.stdout.write('\r'+_ERASESTR+'\r')
        sys.stdout.flush()
        es= numpy.array(es)
        rmeans= numpy.array(rmeans)
        rperis= numpy.array(rperis)
        raps= numpy.array(raps)
        zmaxs= numpy.array(zmaxs)
        orbits= _append_field_recarray(rawdata,'e',es)
        orbits= _append_field_recarray(orbits,'rmean',rmeans)
        orbits= _append_field_recarray(orbits,'rperi',rperis)
        orbits= _append_field_recarray(orbits,'rap',raps)
        orbits= _append_field_recarray(orbits,'zmax',zmaxs)
        orbits= _append_field_recarray(orbits,'densrmean',densrmeans)
        orbits= _append_field_recarray(orbits,'vzrmean',vzrmeans)
        #Pickle
        savefile= open(args[0],'wb')
        pickle.dump(orbits,savefile)
        savefile.close()
    return None
Ejemplo n.º 50
0
def illustrate_adiabatic_invariance(plotfilename1,plotfilename2):
    # Initialize two different IsochronePotentials
    ip1= IsochronePotential(normalize=1.,b=1.)
    ip2= IsochronePotential(normalize=0.5,b=1.)
    # Use TimeInterpPotential to interpolate smoothly between the two
    tip= TimeInterpPotential(ip1,ip2,dt=100.,tform=50.)
    # Integrate the orbit, in three parts
    # 1) Orbit in the first isochrone potential
    o1= Orbit([1.,0.1,1.1,0.0,0.1,0.])
    ts= numpy.linspace(0.,50.,1001)
    o1.integrate(ts,tip)
    bovy_plot.bovy_print()
    o1.plot(d1='x',d2='y',xrange=[-1.6,1.6],yrange=[-1.6,1.6],color='b',
            gcf=True)
    # 2) Orbit in the transition
    o2= o1(ts[-1]) # Last time step = initial time step of the next integration
    ts2= numpy.linspace(50.,150.,1001)
    o2.integrate(ts2,tip)
    o2.plot(d1='x',d2='y',overplot=True,color='g')
    # 3) Orbit in the second isochrone potential
    o3= o2(ts2[-1])
    ts3= numpy.linspace(150.,200.,1001)
    o3.integrate(ts3,ip2)
    o3.plot(d1='x',d2='y',overplot=True,color='r')
    bovy_plot.bovy_end_print(plotfilename1)
    # Also plot the R,z projection
    bovy_plot.bovy_print(fig_height=2.3333)
    o1.plot(d1='R',d2='z',xrange=[0.9,1.65],yrange=[-.175,.175],color='b',
            gcf=True)
    o2.plot(d1='R',d2='z',overplot=True,color='g')
    o3.plot(d1='R',d2='z',overplot=True,color='r')
    bovy_plot.bovy_end_print(plotfilename2)   
    # Now we calculate the energy, eccentricity, mean radius, and maximum height
    print o1.E(pot=ip1), o1.e(), 0.5*(o1.rperi()+o1.rap()), o1.zmax()
    print o3.E(pot=ip2), o3.e(), 0.5*(o3.rperi()+o3.rap()), o3.zmax()
   # The orbit has clearly moved to larger radii, the actions are however conserved
    aAI1= actionAngleIsochrone(ip=ip1)
    aAI2= actionAngleIsochrone(ip=ip2)
    print aAI1(o1)
    print aAI2(o3)
    return None
def plot_stream_xz(plotfilename):
    #Read stream
    data= numpy.loadtxt(os.path.join(_STREAMSNAPDIR,'gd1_evol_hitres_00800.dat'),
                        delimiter=',')
    aadata= numpy.loadtxt(os.path.join(_STREAMSNAPAADIR,
                                       'gd1_evol_hitres_aa_00800.dat'),
                        delimiter=',')
    thetar= aadata[:,6]
    thetar= (numpy.pi+(thetar-numpy.median(thetar))) % (2.*numpy.pi)
    if 'sim' in plotfilename:
        sindx= numpy.fabs(thetar-numpy.pi) > (4.*numpy.median(numpy.fabs(thetar-numpy.median(thetar))))
    else:
        sindx= numpy.fabs(thetar-numpy.pi) > (1.5*numpy.median(numpy.fabs(thetar-numpy.median(thetar))))
    includeorbit= True
    if includeorbit:
        npts= 201
        pot= potential.LogarithmicHaloPotential(normalize=1.,q=0.9)
        pts= numpy.linspace(0.,4.,npts)
        #Calculate progenitor orbit around this point
        pox= numpy.median(data[:,1])
        poy= numpy.median(data[:,3])
        poz= numpy.median(data[:,2])
        povx= numpy.median(data[:,4])
        povy= numpy.median(data[:,6])
        povz= numpy.median(data[:,5])
        pR,pphi,pZ= bovy_coords.rect_to_cyl(pox,poy,poz)
        pvR,pvT,pvZ= bovy_coords.rect_to_cyl_vec(povx,povy,povz,pR,
                                                 pphi,pZ,cyl=True)
        ppo= Orbit([pR/8.,pvR/220.,pvT/220.,pZ/8.,pvZ/220.,pphi])
        pno= Orbit([pR/8.,-pvR/220.,-pvT/220.,pZ/8.,-pvZ/220.,pphi])
        ppo.integrate(pts,pot)
        pno.integrate(pts,pot)
        pvec= numpy.zeros((3,npts*2-1))
        pvec[0,:npts-1]= pno.x(pts)[::-1][:-1]
        pvec[1,:npts-1]= pno.z(pts)[::-1][:-1]
        pvec[2,:npts-1]= pno.y(pts)[::-1][:-1]
        pvec[0,npts-1:]= ppo.x(pts)
        pvec[1,npts-1:]= ppo.z(pts)
        pvec[2,npts-1:]= ppo.y(pts)
        pvec*= 8.
    includetrack= True
    if includetrack:
        #Setup stream model
        lp= potential.LogarithmicHaloPotential(q=0.9,normalize=1.)
        aAI= actionAngleIsochroneApprox(b=0.8,pot=lp)
        obs= numpy.array([1.56148083,0.35081535,-1.15481504,
                          0.88719443,-0.47713334,0.12019596])
        #Obs is at time 1312, need to go back 2 Gyr to time 800
        obs[1]*= -1.
        obs[2]*= -1.
        obs[4]*= -1.
        o= Orbit(obs)
        ts= numpy.linspace(0.,2.*977.7922212082034/1000./bovy_conversion.time_in_Gyr(220.,8.),1001)
        o.integrate(ts,lp)
        obs= o(ts[-1])._orb.vxvv
        obs[1]*= -1.
        obs[2]*= -1.
        obs[4]*= -1.       
        tdisrupt= 4.5-2.*977.7922212082034/1000.
        sdf= streamdf(_SIGV/220.,progenitor=Orbit(obs),pot=lp,aA=aAI,
                      leading=True,nTrackChunks=_NTRACKCHUNKS,
                      tdisrupt=tdisrupt/bovy_conversion.time_in_Gyr(220.,8.),
                      deltaAngleTrack=1.5*3./5.,multi=_NTRACKCHUNKS)
        sdft= streamdf(_SIGV/220.,progenitor=Orbit(obs),pot=lp,aA=aAI,
                       leading=False,nTrackChunks=_NTRACKCHUNKS,
                       tdisrupt=tdisrupt/bovy_conversion.time_in_Gyr(220.,8.),
                       deltaAngleTrack=1.5*3./5.,multi=_NTRACKCHUNKS)
    if 'sim' in plotfilename:
        #Replace data with simulated data
        forwardXY= sdf.sample(int(round(numpy.sum(sindx)/2.)),
                              xy=True)
        backwardXY= sdft.sample(int(round(numpy.sum(sindx)/2.)),
                                xy=True)
        data= numpy.empty((forwardXY.shape[1]+backwardXY.shape[1],7))
        data[:forwardXY.shape[1],1]= forwardXY[0]*8.
        data[:forwardXY.shape[1],2]= forwardXY[2]*8.
        data[:forwardXY.shape[1],3]= forwardXY[1]*8.
        data[:forwardXY.shape[1],4]= forwardXY[3]*220.
        data[:forwardXY.shape[1],5]= forwardXY[5]*220.
        data[:forwardXY.shape[1],6]= forwardXY[4]*220.
        data[forwardXY.shape[1]:,1]= backwardXY[0]*8.
        data[forwardXY.shape[1]:,2]= backwardXY[2]*8.
        data[forwardXY.shape[1]:,3]= backwardXY[1]*8.
        data[forwardXY.shape[1]:,4]= backwardXY[3]*220.
        data[forwardXY.shape[1]:,5]= backwardXY[5]*220.
        data[forwardXY.shape[1]:,6]= backwardXY[4]*220.
        sindx= numpy.ones(data.shape[0],dtype='bool')      
    #Plot
    bovy_plot.bovy_print()
    bovy_plot.bovy_plot(data[sindx,1],data[sindx,2],'k,',ms=2.,
                        xlabel=r'$X\,(\mathrm{kpc})$',
                        ylabel=r'$Z\,(\mathrm{kpc})$',
                        xrange=[-12.5,-3.],
                        yrange=[-12.5,-7.])
    if numpy.sum(True-sindx) > 0:
        #Also plot progenitor
        pindx= copy.copy(True-sindx)
        pindx[0:9900]= False #subsample
        bovy_plot.bovy_plot(data[pindx,1],data[pindx,2],
                            'k,',overplot=True)
    if includeorbit:
        bovy_plot.bovy_plot(pox,poz,'o',color='0.5',mec='none',overplot=True,ms=8)
        bovy_plot.bovy_plot(pvec[0,:],pvec[1,:],'k--',overplot=True,lw=1.)
    if 'sim' in plotfilename:
        bovy_plot.bovy_text(r'$\mathrm{mock\ stream}$',
                            bottom_left=True,size=16.)
    else:
        bovy_plot.bovy_text(r'$N\!\!-\!\!\mathrm{body\ stream}$',
                            bottom_left=True,size=16.)
    if includetrack:
        d1= 'x'
        d2= 'z'
        sdf.plotTrack(d1=d1,d2=d2,interp=True,color='k',spread=0,
                      overplot=True,lw=1.,scaleToPhysical=True)
        sdft.plotTrack(d1=d1,d2=d2,interp=True,color='k',spread=0,
                       overplot=True,lw=1.,scaleToPhysical=True)
        #Also create inset
        pyplot.plot([-9.,-9.],[-11.75,-10.3],'k-')
        pyplot.plot([-6.,-6.],[-11.75,-10.3],'k-')
        pyplot.plot([-9.,-6.],[-11.75,-11.75],'k-')
        pyplot.plot([-9.,-6.],[-10.3,-10.3],'k-')
        pyplot.plot([-6.,-3.4],[-10.3,-10.],'k:')
        pyplot.plot([-9.,-8.85],[-10.3,-10.],'k:')
        insetAxes= pyplot.axes([0.42,0.47,0.45,0.42])
        pyplot.sca(insetAxes)
        bovy_plot.bovy_plot(data[sindx,1],data[sindx,2],'k.',ms=2.,zorder=0.,
                            overplot=True)
        if numpy.sum(True-sindx) > 0:
            pindx= copy.copy(True-sindx)
            pindx[0:9700]= False #subsample
            bovy_plot.bovy_plot(data[pindx,1],data[pindx,2],'k,',
                                zorder=0.,
                                overplot=True)
        bovy_plot.bovy_plot(pvec[0,:],pvec[1,:],'k--',overplot=True,lw=1.,
                            zorder=1)
        sdf.plotTrack(d1=d1,d2=d2,interp=True,color='k',spread=0,
                      overplot=True,lw=1.,scaleToPhysical=True,zorder=2)
        nullfmt   = NullFormatter()         # no labels
        insetAxes.xaxis.set_major_formatter(nullfmt)
        insetAxes.yaxis.set_major_formatter(nullfmt)
        insetAxes.set_xlim(-9.,-6.)
        insetAxes.set_ylim(-11.75,-10.3)
        pyplot.tick_params(\
            axis='both',          # changes apply to the x-axis
            which='both',      # both major and minor ticks are affected
            bottom='off',      # ticks along the bottom edge are off
            top='off',         # ticks along the top edge are off
            left='off',      # ticks along the bottom edge are off
            right='off')         # ticks along the top edge are off
    bovy_plot.bovy_end_print(plotfilename)
Ejemplo n.º 52
0
def plot_liouville(plotfilename):
    E, Lz= -1.25, 0.6
    aAS= actionAngleStaeckel(pot=MWPotential2014,c=True,delta=0.5)
    #planarOrbit w/ the same energy
    o= Orbit([0.8,numpy.sqrt(2.*(E-evalPot(0.8,0.,MWPotential2014)-(Lz/0.8)**2./2.)),Lz/0.8,0.])
    #For the orbital period
    fo= Orbit([0.8,numpy.sqrt(2.*(E-evalPot(0.8,0.,MWPotential2014)-(Lz/0.8)**2./2.)),Lz/0.8,0.,0.001,0.])
    orbt= 2.*numpy.pi/aAS.actionsFreqs(fo)[4]
    norb= 200.
    nt= 20001
    ts= numpy.linspace(0.,norb*orbt,nt)
    start= time.time()
    integrator= 'dopr54_c'
    o.integrate_dxdv([1.,0.,0.,0.],ts,MWPotential2014,
                     method=integrator,
                     rectIn=True,rectOut=True)
    dx= o.getOrbit_dxdv()[:,:]
    o.integrate_dxdv([0.,1.,0.,0.],ts,MWPotential2014,
                     method=integrator,
                     rectIn=True,rectOut=True)
    dy= o.getOrbit_dxdv()[:,:]
    o.integrate_dxdv([0.,0.,1.,0.],ts,MWPotential2014,
                     method=integrator,
                     rectIn=True,rectOut=True)
    dvx= o.getOrbit_dxdv()[:,:]
    o.integrate_dxdv([0.,0.,0.,1.],ts,MWPotential2014,
                     method=integrator,
                     rectIn=True,rectOut=True)
    dvy= o.getOrbit_dxdv()[:,:]
    print integrator, time.time()-start
    #Calculate Jacobian
    jacs= numpy.array([numpy.linalg.det(numpy.array([dx[ii],dy[ii],
                                                     dvx[ii],dvy[ii]])) for ii in range(nt)])
    breakt= 8.
    pts= list(ts[ts < breakt])
    pts.extend(list((ts[ts >= breakt])[::10]))
    pts= numpy.array(pts)
    pjacs= list(jacs[ts < breakt])
    pjacs.extend(list((jacs[ts >= breakt])[::10]))
    pjacs= numpy.array(pjacs)
    print integrator, numpy.mean(jacs)-1.
    bovy_plot.bovy_print(fig_width=3.25,fig_height=4.5)
    pyplot.subplot(4,1,4)
    bovy_plot.bovy_plot(pts/orbt,numpy.fabs(pjacs-1.),color='k',
                        loglog=True,gcf=True,
                        xrange=[0.5,norb],
                        yrange=[10.**-12.,10.**0.],
                        xlabel=r'$\mathrm{Number\ of\ orbital\ periods}$')
    bovy_plot.bovy_text(r'$\texttt{dopr54\_c}$',
                        top_left=True,size=14.)
    bovy_plot.bovy_text(0.1,10.**44.5,
                        r'$|\mathrm{Determinant\ of\ volume\ transformation}-1|$',
                        fontsize=16.,
                        rotation='vertical')
    ax= pyplot.gca()
    ax.xaxis.set_major_formatter(ticker.FormatStrFormatter(r'$%0.f$'))
    ax.yaxis.set_ticks([10.**-12.,10.**-8.,10.**-4.,1.])
    nullfmt   = NullFormatter()         # no labels
    other_integrators= ['odeint',
                        'rk4_c','rk6_c']
    for ii,integrator in enumerate(other_integrators):
        start= time.time()
        o.integrate_dxdv([1.,0.,0.,0.],ts,MWPotential2014,
                         method=integrator,
                         rectIn=True,rectOut=True)
        dx= o.getOrbit_dxdv()[:,:]
        o.integrate_dxdv([0.,1.,0.,0.],ts,MWPotential2014,
                         method=integrator,
                         rectIn=True,rectOut=True)
        dy= o.getOrbit_dxdv()[:,:]
        o.integrate_dxdv([0.,0.,1.,0.],ts,MWPotential2014,
                         method=integrator,
                         rectIn=True,rectOut=True)
        dvx= o.getOrbit_dxdv()[:,:]
        o.integrate_dxdv([0.,0.,0.,1.],ts,MWPotential2014,
                         method=integrator,
                         rectIn=True,rectOut=True)
        dvy= o.getOrbit_dxdv()[:,:]
        print integrator, time.time()-start
        jacs= numpy.array([numpy.linalg.det(numpy.array([dx[jj],dy[jj],
                                                         dvx[jj],dvy[jj]])) for jj in range(nt)])
        pts= list(ts[ts < breakt])
        pts.extend(list((ts[ts >= breakt])[::10]))
        pts= numpy.array(pts)
        pjacs= list(jacs[ts < breakt])
        pjacs.extend(list((jacs[ts >= breakt])[::10]))
        pjacs= numpy.array(pjacs)
        print integrator, numpy.mean(jacs)-1.
        pyplot.subplot(4,1,ii+1)
        if integrator == 'odeint':
            yrange=[10.**-8.,10.**4.]
            yticks= [10.**-8.,10.**-4.,1.,10.**4.]
        else:
            yrange=[10.**-12.,10.**0.]
            yticks= [10.**-12.,10.**-8.,10.**-4.,1.]
        bovy_plot.bovy_plot(pts/orbt,numpy.fabs(pjacs-1.),color='k',
                            loglog=True,gcf=True,
                            xrange=[0.5,norb],
                            yrange=yrange)
        thisax= pyplot.gca()
        thisax.xaxis.set_major_formatter(nullfmt)
        thisax.yaxis.set_ticks(yticks)
        bovy_plot.bovy_text(r'$\texttt{%s}$' % (integrator.replace('_','\_')),
                            top_left=True,size=14.)
    bovy_plot.bovy_end_print(plotfilename)
    return None
Ejemplo n.º 53
0
cluster = args[1]
N = int(args[2])
dwarves = int(args[3])

print("Started")
print("Including dwarves: ", dwarves == True)

ts = np.linspace(0., -12 * conv, 1201)
dt = (ts[1] - ts[0]) / 250

# SAGITTARIUS
sgr_M = 1.4E10 * u.Msun
sgr_a = 7 * u.kpc  # 6.5kpc from https://arxiv.org/pdf/1608.04743.pdf
sgr_pot = HernquistPotential(amp=sgr_M, a=sgr_a, ro=8., vo=220.)
sgr_orbit = Orbit(vxvv=[283.8313, -30.5453, 26.67, -2.692, -1.359, 140],
                  radec=True,
                  ro=8.,
                  vo=220.)
sgr_orbit.integrate(ts, MWPotential2014, dt=dt)
sgr_potential = MovingObjectPotential(sgr_orbit, pot=sgr_pot)

# LMC
lmc_M = 1E11 * u.Msun  # https://arxiv.org/pdf/1608.04743.pdf
lmc_a = 10.2 * u.kpc  # https://iopscience.iop.org/article/10.1088/2041-8205/721/2/L97/pdf
lmc_pot = HernquistPotential(amp=lmc_M, a=lmc_a, ro=8., vo=220.)
lmc_orbit = Orbit(vxvv=[78.77, -69.01, 50.1, 1.850, 0.234, 262.2],
                  radec=True,
                  ro=8.,
                  vo=220.)
lmc_orbit.integrate(ts, MWPotential2014, dt=dt)
lmc_potential = MovingObjectPotential(lmc_orbit, pot=lmc_pot)
Ejemplo n.º 54
0
def action_analysis(cls):
    try:
        fd = open("data/db_9cl_orbits_good.pkl", "rb")
        all_orbits = cp.load(fd)
        fd.close()
    except:
        ucac_dict = ucac_pms()
        position_dict = grab_other_spatials(cls)[0]
        distance_dict = grab_other_spatials(cls)[1]
        all_orbits = []
        for cl in cls:
            cluster_orbits = []
            for star in cl:
                try:
                    ra = float(position_dict[star][0])
                    dec = float(position_dict[star][1])
                    dist = float(distance_dict[star])
                    pmRA = float(ucac_dict[star][0])
                    pmDec = float(ucac_dict[star][2])
                    Vlos = float(position_dict[star][2])
                    #only attach where proper motions are available
                    if ucac_dict[star][-1] == '1':
                        cluster_orbits.append(Orbit(vxvv=[ra,dec,dist,pmRA,pmDec,Vlos],radec=True,ro=8.,vo=220., solarmotion = "schoenrich"))
                except:
                    print("bad egg, spitting out")
                    continue
                #only attach where proper motions are available
            all_orbits.append(cluster_orbits)
            print("ticking: ", len(all_orbits))
        fd = open("data/db_9cl_orbits_good.pkl", "wb")
        cp.dump(all_orbits, fd)
        fd.close()
    
    ts = np.linspace(0,100,10000)
    mwp= MWPotential2014
    #action angles yay!
    #the following gets confusing because we speak of "means" twice
    #we want the mean J over each individual orbit, but to measure the spread in the cluster
    #we compare to the mean of each J
    ro = 8
    vo = 220
    all_actions = []
    fig = 1
    for cluster_orbits in all_orbits:
        all_js = np.array([])
        for o in cluster_orbits:
            o.integrate(ts,mwp,method='odeint')
#            plt.plot(o.R(ts), o.z(ts))
            try:
                delta_o = estimateDeltaStaeckel(MWPotential2014,(o.R(ts))/ro,(o.z(ts))/ro)
                aAS = actionAngleStaeckel(pot=MWPotential2014,delta = delta_o)
                js_o = aAS((o.R())/ro,(o.vR())/vo,(o.vT())/vo,(o.z())/ro,(o.vz())/vo)
#                delta_b = estimateBIsochrone(MWPotential2014, (o.R(ts))/ro,(o.z(ts))/ro)
#                delta_b = delta_b[1]
#                aAIA = actionAngleIsochroneApprox(pot=MWPotential2014,b = delta_b)
#                js_o = aAIA((o.R())/ro,(o.vR())/vo,(o.vT())/vo,(o.z())/ro,(o.vz())/vo, nonaxi = True)
#                print(js_o)
                if all_js.shape == (0,):
                    all_js = js_o
                else:
                    all_js = np.vstack([all_js, js_o])
            except:
                print("found unbound, discarded")    
        print(np.array(all_js).shape)
        all_actions.append(all_js)
#        plt.xlabel("R distance (kpc)")
#        plt.ylabel("z distance (kpc)")
#        plt.xlim(0, 20)
#        plt.ylim(-5, 5)
#        plt.title("Cluster " + str(fig)+ " Rz" + " Orbits")
#        fn = open("dbcl_" + str(fig) + "_Rz" + ".png", "wb")
#        plt.savefig("dbcl_" + str(fig) + "_Rz" + ".png")
#        fn.close()
#        plt.close()
        fig += 1
    return all_actions
Ejemplo n.º 55
0
def predict_gd1obs(
    pot_params: Sequence[float],
    c: float,
    b: float = 1.0,
    pa: float = 0.0,
    sigv: float = 0.4,
    td: float = 10.0,
    dist: float = 10.2,
    pmphi1: float = -8.5,
    pmphi2: float = -2.05,
    phi1: float = 0.0,
    phi2: float = -1.0,
    vlos: float = -285.0,
    ro: float = REFR0,
    vo: float = REFV0,
    isob: Optional[bool] = None,
    nTrackChunks: int = 8,
    multi: Optional[Any] = None,
    useTM: bool = False,
    logpot: bool = False,
    verbose: bool = True,
):
    """Predict GD1-observed.

    Function that generates the location and velocity of the GD-1 stream,
    its width, and its length for a given potential
    and progenitor phase-space position.

    Parameters
    ----------
    pot_params
        array with the parameters of a potential model
        (see mw_pot.setup_potential;
         only the basic parameters of the disk and halo are used,
         flattening is specified separately)
    c
        halo flattening
    b
        (1.) halo-squashed
    pa
        (0.) halo PA
    sigv
        (0.365) velocity dispersion in km/s
    td
        (10.) stream age in Gyr
    phi1
        (0.) Progenitor's phi1 position
    phi2
        (-1.) Progenitor's phi2 position
    dist
        (10.2) progenitor distance in kpc
    pmphi1
        (-8.5) progenitor proper motion in phi1 in mas/yr
    pmphi2
        (-2.) progenitor proper motion in phi2 in mas/yr
    vlos
        (-250.) progenitor line-of-sight velocity in km/s
    ro
        (project default) distance to the GC in kpc
    vo
        (project default) circular velocity at R0 in km/s
    nTrackChunks
        (8) nTrackChunks input to streamdf
    multi
        (None) multi input to streamdf
    logpot
        (False) if True, use a logarithmic potential instead
    isob
        (None) if given, b parameter of actionAngleIsochroneApprox
    useTM
        (True) use the TorusMapper to compute the track
    verbose
        (True) print messages

    Notes
    -----
    2016-08-12 - Written - Bovy (UofT)

    """
    # Convert progenitor's phase-space position to l,b,...
    prog = Orbit(
        phi12_to_lb_6d(phi1, phi2, dist, pmphi1, pmphi2, vlos),
        lb=True,
        ro=ro,
        vo=vo,
        solarmotion=[-11.1, 24.0, 7.25],
    )
    if logpot:
        pot = potential.LogarithmicHaloPotential(normalize=1.0, q=c)
    else:
        pot = mw_pot.setup_potential(pot_params,
                                     c,
                                     False,
                                     False,
                                     ro,
                                     vo,
                                     b=b,
                                     pa=pa)
    success: bool = True
    this_useTM = useTM

    try:
        sdf = setup_sdf(
            pot,
            prog,
            sigv,
            td,
            ro,
            vo,
            multi=multi,
            isob=isob,
            nTrackChunks=nTrackChunks,
            verbose=verbose,
            useTM=useTM,
            logpot=logpot,
        )
    except:
        # Catches errors and time-outs
        success: bool = False

    # Check for calc. issues
    if not success:
        return (np.zeros((1001, 6)) - 1000000.0, False)
        # Try again with TM
        this_useTM = True
        this_nTrackChunks = 21  # might as well
        sdf = setup_sdf(
            pot,
            prog,
            sigv,
            td,
            ro,
            vo,
            multi=multi,
            isob=isob,
            nTrackChunks=this_nTrackChunks,
            verbose=verbose,
            useTM=this_useTM,
            logpot=logpot,
        )
    else:
        success: bool = not this_useTM

    # Compute the track and convert it to phi12
    track_phi = convert_track_lb_to_phi12(sdf._interpolatedObsTrackLB)

    return track_phi, success
def calc_eccentricity(args, options):
    table = os.path.join(args[0], 'table2.dat')
    readme = os.path.join(args[0], 'ReadMe')
    dierickx = ascii.read(table, readme=readme)
    vxvv = np.dstack([
        dierickx['RAdeg'], dierickx['DEdeg'], dierickx['Dist'] / 1e3,
        dierickx['pmRA'], dierickx['pmDE'], dierickx['HRV']
    ])[0]
    ro, vo, zo = 8., 220., 0.025
    ra, dec = vxvv[:, 0], vxvv[:, 1]
    lb = bovy_coords.radec_to_lb(ra, dec, degree=True)
    pmra, pmdec = vxvv[:, 3], vxvv[:, 4]
    pmllpmbb = bovy_coords.pmrapmdec_to_pmllpmbb(pmra,
                                                 pmdec,
                                                 ra,
                                                 dec,
                                                 degree=True)
    d, vlos = vxvv[:, 2], vxvv[:, 5]
    rectgal = bovy_coords.sphergal_to_rectgal(lb[:, 0],
                                              lb[:, 1],
                                              d,
                                              vlos,
                                              pmllpmbb[:, 0],
                                              pmllpmbb[:, 1],
                                              degree=True)
    vsolar = np.array([-10.1, 4.0, 6.7])
    vsun = np.array([
        0.,
        1.,
        0.,
    ]) + vsolar / vo
    X = rectgal[:, 0] / ro
    Y = rectgal[:, 1] / ro
    Z = rectgal[:, 2] / ro
    vx = rectgal[:, 3] / vo
    vy = rectgal[:, 4] / vo
    vz = rectgal[:, 5] / vo
    vsun = np.array([
        0.,
        1.,
        0.,
    ]) + vsolar / vo
    Rphiz = bovy_coords.XYZ_to_galcencyl(X, Y, Z, Zsun=zo / ro)
    vRvTvz = bovy_coords.vxvyvz_to_galcencyl(vx,
                                             vy,
                                             vz,
                                             Rphiz[:, 0],
                                             Rphiz[:, 1],
                                             Rphiz[:, 2],
                                             vsun=vsun,
                                             Xsun=1.,
                                             Zsun=zo / ro,
                                             galcen=True)
    #do the integration and individual analytic estimate for each object
    ts = np.linspace(0., 20., 10000)
    lp = LogarithmicHaloPotential(normalize=1.)
    e_ana = numpy.zeros(len(vxvv))
    e_int = numpy.zeros(len(vxvv))
    print(
        'Performing orbit integration and analytic parameter estimates for Dierickx et al. sample...'
    )
    for i in tqdm(range(len(vxvv))):
        try:
            orbit = Orbit(vxvv[i], radec=True, vo=220., ro=8.)
            e_ana[i] = orbit.e(analytic=True, pot=lp, c=True)
        except UnboundError:
            e_ana[i] = np.nan
        orbit.integrate(ts, lp)
        e_int[i] = orbit.e(analytic=False)
    fig = plt.figure()
    fig.set_size_inches(1.5 * columnwidth, 1.5 * columnwidth)
    plt.scatter(e_int, e_ana, s=1, color='Black', lw=0.)
    plt.xlabel(r'$\mathrm{galpy\ integrated}\ e$')
    plt.ylabel(r'$\mathrm{galpy\ analytic}\ e$')
    plt.xlim(0., 1.)
    plt.ylim(0., 1.)
    fig.tight_layout()
    plt.savefig(os.path.join(args[0], 'dierickx-integratedeanalytice.png'),
                format='png',
                dpi=200)
    fig = plt.figure()
    fig.set_size_inches(1.5 * columnwidth, 1.5 * columnwidth)
    plt.hist(e_int, bins=30)
    plt.xlim(0., 1.)
    plt.xlabel(r'$\mathrm{galpy}\ e$')
    fig.tight_layout()
    plt.savefig(os.path.join(args[0], 'dierickx-integratedehist.png'),
                format='png',
                dpi=200)
    fig = plt.figure()
    fig.set_size_inches(1.5 * columnwidth, 1.5 * columnwidth)
    plt.scatter(dierickx['e'], e_int, s=1, color='Black', lw=0.)
    plt.xlabel(r'$\mathrm{Dierickx\ et\ al.}\ e$')
    plt.ylabel(r'$\mathrm{galpy\ integrated}\ e$')
    plt.xlim(0., 1.)
    plt.ylim(0., 1.)
    fig.tight_layout()
    plt.savefig(os.path.join(args[0], 'dierickx-integratedee.png'),
                format='png',
                dpi=200)
    fig = plt.figure()
    fig.set_size_inches(1.5 * columnwidth, 1.5 * columnwidth)
    plt.scatter(dierickx['e'], e_ana, s=1, color='Black', lw=0.)
    plt.xlabel(r'$\mathrm{Dierickx\ et\ al.}\ e$')
    plt.ylabel(r'$\mathrm{galpy\ estimated}\ e$')
    plt.xlim(0., 1.)
    plt.ylim(0., 1.)
    fig.tight_layout()
    plt.savefig(os.path.join(args[0], 'dierickx-analyticee.png'),
                format='png',
                dpi=200)
    arr = numpy.recarray(len(e_ana),
                         dtype=[('analytic_e', float),
                                ('integrated_e', float)])
    arr['analytic_e'] = e_ana
    arr['integrated_e'] = e_int
    with open(os.path.join(args[0], 'eccentricities.dat'), 'w') as file:
        pickle.dump(arr, file)
        file.close()
Ejemplo n.º 57
0
def test_orbitIntegrationC():

    #_____initialize some KKSPot_____
    Delta = 1.0
    pot = KuzminKutuzovStaeckelPotential(ac=20.,Delta=Delta,normalize=True)

    #_____initialize an orbit (twice)_____
    vxvv = [1.,0.1,1.1,0.,0.1]
    o_P= Orbit(vxvv=vxvv)
    o_C= Orbit(vxvv=vxvv)

    #_____integrate the orbit with python and C_____
    ts= numpy.linspace(0,100,101)
    o_P.integrate(ts,pot,method='leapfrog')  #python
    o_C.integrate(ts,pot,method='leapfrog_c')#C

    for ii in range(5):
        exp3= -1.7
        if   ii == 0: Python, CC, string, exp1, exp2 = o_P.R(ts) , o_C.R(ts) , 'R' , -5., -10.
        elif ii == 1: Python, CC, string, exp1, exp2 = o_P.z(ts) , o_C.z(ts) , 'z' , -3.25, -4.
        elif ii == 2: Python, CC, string, exp1, exp2 = o_P.vR(ts), o_C.vR(ts), 'vR', -3., -10.
        elif ii == 3: Python, CC, string, exp1, exp2, exp3 = o_P.vz(ts), o_C.vz(ts), 'vz', -3., -4., -1.3
        elif ii == 4: Python, CC, string, exp1, exp2 = o_P.vT(ts), o_C.vT(ts), 'vT', -5., -10.

        rel_diff = numpy.fabs((Python-CC)/CC) < 10.**exp1
        abs_diff = (numpy.fabs(Python-CC) < 10.**exp2) * (numpy.fabs(Python) < 10.**exp3)
        assert numpy.all(rel_diff+abs_diff), \
            'Orbit integration for '+string+' coordinate different in ' + \
            'C and Python implementation.'

    return None
Ejemplo n.º 58
0
def plot_sat_cluster(sat_galaxy, name_sat, sat_potential, xaxis_dim, yaxis_dim,
                     sat_mass, sat_size, x_satgal, y_satgal, z_satgal,
                     vx_satgal, vy_satgal, vz_satgal, tform, tsteady):

    # Function plots orbits of satellite galaxy as well as a star cluster within the satellite galaxy - simulates accretion onto MW
    #
    # Input:
    # sat_galaxy: an orbit object for a given satellite galaxy of the MW
    # name_sat: string of the satellite galaxy's name
    # sat_potential: potential object modelling the satellite's potential
    # x and y axis dimensions to plot in (strings)
    # x_satgal, y_satgal, z_satgal: x,y,z positions of the star_cluster within the satellite galaxy's frame of reference
    # vx_satgal, vy_satgal, vz_satgal: x,y,z velocities of the star_cluster within the satellite galaxy's frame of reference
    # mass and size of satellite to model dynamical friction effects (quantities with units attached)
    # tform, tsteady: parameters of the potential, models tidal disruption of satellite galaxy (quantities with units attached)
    #
    # Output:
    #
    # end_pos_cluster: the coordinates for star cluster at end of integration (@ time tend: tform+5*units.Gyr)
    # end_pos_gal: the coordinates for satellite galaxy at tend
    # dswp: wrapper potential object that modifies satelltie galaxy to begin disrupting at tform
    # cdf: model for dynamical friction force

    t_back = 10.
    ts = numpy.linspace(0., -t_back, 1000) * units.Gyr
    cdf = ChandrasekharDynamicalFrictionForce(GMs=sat_mass,
                                              rhm=sat_size,
                                              dens=mw)
    sat_galaxy.integrate(ts, mw + cdf)
    '''
    R_sat = sat_galaxy.R(-t_back*units.Gyr)  #cylindrical radius at time t
    vR_sat = sat_galaxy.vR(-t_back*units.Gyr) #radial velocity at time t 
    vT_sat = sat_galaxy.vT(-t_back*units.Gyr) #tangential velocity at time t 
    z_sat = sat_galaxy.z(-t_back*units.Gyr) #vertical height at time t
    vz_sat = sat_galaxy.vz(-t_back*units.Gyr) #vertical velocity at time t 
    phi_sat = sat_galaxy.phi(-t_back*units.Gyr) #azimuth at time t 
    '''
    # Rectangular coordinates and velocities
    coord = [
        sat_galaxy.x(-t_back * units.Gyr),
        sat_galaxy.y(-t_back * units.Gyr),
        sat_galaxy.z(-t_back * units.Gyr)
    ]
    vcoord = [
        sat_galaxy.vx(-t_back * units.Gyr),
        sat_galaxy.vy(-t_back * units.Gyr),
        sat_galaxy.vz(-t_back * units.Gyr)
    ]

    t_fwrd = 15
    ts_f = numpy.linspace(-t_back, -t_back + t_fwrd, 1000) * units.Gyr
    sat_galaxy = sat_galaxy(-t_back * units.Gyr)
    sat_galaxy.integrate(ts_f, mw + cdf)
    sat_galaxy.plot(
        d1=xaxis_dim,
        d2=yaxis_dim,
        linestyle=':',
        color='black',
        label='satellite'
    )  #plots orbit of the satellite galaxy in MW frame of reference

    #!!sat_pot = HernquistPotential(amp = 2*sat_mass, a = sat_size, ro = 8., vo=220.)
    sat_movingpot = MovingObjectPotential(sat_galaxy, sat_potential)

    # Transform from satellite galaxy's frame of reference to Milky Way Galaxy's frame of reference (using Cartesian coordinates)
    # Rectangular coordinates of the star cluster in galactocentric frame
    x_gal = coord[0] + x_satgal
    y_gal = coord[1] + y_satgal
    z_gal = coord[2] + z_satgal
    # Velocity of the star cluster in galactocentric frame
    vx_gal = vcoord[0] + vx_satgal
    vy_gal = vcoord[1] + vy_satgal
    vz_gal = vcoord[2] + vz_satgal
    # Transform to cylindrical coordinate system: R, phi, z
    R, phi, z = rect_to_cyl(x_gal, y_gal, z_gal)
    vR, vT, vz = rect_to_cyl_vec(vx_gal,
                                 vy_gal,
                                 vz_gal,
                                 x_gal,
                                 y_gal,
                                 z_gal,
                                 cyl=False)

    star_cluster = Orbit(vxvv=[R, vR, vT, z, vz, phi], ro=8., vo=220.)
    star_cluster.integrate(ts_f, mw + sat_movingpot)
    star_cluster.plot(
        d1=xaxis_dim,
        d2=yaxis_dim,
        linestyle='-',
        overplot=True,
        color='blue',
        alpha=0.6,
        label='star cluster'
    )  #plots orbit of the star_cluster in MW frame of reference
    plt.title('Orbit of Star Cluster Within Satellite Galaxy: ' + name_sat +
              ' in Galactocentric Frame')
    plt.legend()
    plt.show()
    plt.close()

    # Implement wrapper potential to simulate tidal disruption of satellite galaxy
    # Plot orbit of the satellite galaxy and star cluster within sat galaxy in MW frame of reference:
    plt.figure(figsize=(12., 10.))
    tstart = tform - 5. * units.Gyr
    tend = tform + 5. * units.Gyr
    time_int = numpy.linspace(tstart.to_value(units.Gyr),
                              tend.to_value(units.Gyr), 1000) * units.Gyr

    if tstart < -t_back * units.Gyr:
        # re-integrate satellite galaxy from current time back to tstart
        re_time = numpy.linspace(-t_back, tstart.to_value(units.Gyr),
                                 1000) * units.Gyr
        sat_galaxy.integrate(re_time, mw + cdf)

        # initialize star cluster on orbit in satellite galaxy at time tstart:
        # Rectangular coordinates and velocities
        coord = [
            sat_galaxy.x(tstart),
            sat_galaxy.y(tstart),
            sat_galaxy.z(tstart)
        ]
        vcoord = [
            sat_galaxy.vx(tstart),
            sat_galaxy.vy(tstart),
            sat_galaxy.vz(tstart)
        ]

        # Transform from satellite galaxy's frame of reference to Milky Way Galaxy's frame of reference (using Cartesian coordinates)
        # Rectangular coordinates of the star cluster in galactocentric frame
        x_gal = coord[0] + x_satgal
        y_gal = coord[1] + y_satgal
        z_gal = coord[2] + z_satgal
        # Velocity of the star cluster in galactocentric frame
        vx_gal = vcoord[0] + vx_satgal
        vy_gal = vcoord[1] + vy_satgal
        vz_gal = vcoord[2] + vz_satgal
        # Transform to cylindrical coordinate system: R, phi, z
        R, phi, z = rect_to_cyl(x_gal, y_gal, z_gal)
        vR, vT, vz = rect_to_cyl_vec(vx_gal,
                                     vy_gal,
                                     vz_gal,
                                     x_gal,
                                     y_gal,
                                     z_gal,
                                     cyl=False)

        # Re-initialize star cluster on orbit at time tstart
        star_cluster = Orbit(vxvv=[R, vR, vT, vz, z, phi], ro=8., vo=220.)
    else:
        # default: star cluster is initialized at -10Gyr in given satellite galaxy
        star_cluster = star_cluster(tstart)

    sat_galaxy = sat_galaxy(
        tstart)  #make copy of sat_galaxy orbit at time tstart
    sat_galaxy.integrate(time_int,
                         mw + cdf)  # integrate sat_galaxy forward for 10Gyrs
    sat_galaxy.plot(d1=xaxis_dim,
                    d2=yaxis_dim,
                    linestyle=':',
                    color='black',
                    label='satellite galaxy')
    sat_movingpot = MovingObjectPotential(sat_galaxy, sat_potential)
    dswp = DehnenSmoothWrapperPotential(amp=1.0,
                                        pot=sat_movingpot,
                                        tform=tform,
                                        tsteady=tsteady,
                                        decay=True)
    star_cluster.integrate(time_int, mw + dswp)
    # star cluster in combined potential: MW galaxy & moving potential of satellite galaxy
    star_cluster.plot(d1 =  xaxis_dim, d2= yaxis_dim, linestyle = '-', overplot = True, color = 'blue', alpha = 0.6,\
                      label = 'star cluster')
    #plots orbit of the star_cluster in MW frame of reference
    plt.legend()
    plt.title('Star Cluster Orbit Within: ' + name_sat + ' for Tform = ' +
              str(tform) + ' & Tsteady = ' + str(tsteady) +
              ' in Galactocentric Frame')
    plt.savefig('WrapperPotential-Decaying Mass.pdf')
    plt.show()
    plt.close()

    # Figure out where star cluster is at end of integration: at tend
    end_pos_cluster = [
        star_cluster.R(tend),
        star_cluster.vR(tend),
        star_cluster.vT(tend),
        star_cluster.z(tend),
        star_cluster.vz(tend),
        star_cluster.phi(tend)
    ]
    # [R,vT,vT,z,vz,phi]
    end_pos_gal = [
        sat_galaxy.R(tend),
        sat_galaxy.vR(tend),
        sat_galaxy.vT(tend),
        sat_galaxy.z(tend),
        sat_galaxy.vz(tend),
        sat_galaxy.phi(tend)
    ]
    '''
    # Used for finding dswp when integrating satellite galaxy backward in previous version of code
    time_intb = numpy.linspace(tend.to_value(units.Gyr), tstart.to_value(units.Gyr), 1000)*units.Gyr
    star_cluster_b = Orbit(vxvv = end_pos_cluster, ro=8., vo =220.) #full 6 coordinates
    sat_galaxy_b = Orbit(vxvv=end_pos_gal, ro=8., vo =220.)
    sat_galaxy_b.integrate(time_intb, mw + cdf)
    sat_galaxy_b.plot(d1 =  xaxis_dim, d2= yaxis_dim,linestyle = ':', color = 'black', label = 'satellite galaxy')
    sat_movingpot_b = MovingObjectPotential(sat_galaxy_b, sat_potential)
    #new_tform = tform - end_t
    #dswp_back = DehnenSmoothWrapperPotential(amp=1.0, pot = sat_movingpot_b, tform=tform, tsteady=tsteady, decay = True)
    star_cluster_b.integrate(time_intb, mw + dswp) # star cluster is in combined potential of MW galaxy and the moving potential of satellite galaxy 
    star_cluster_b.plot(d1 =  xaxis_dim, d2= yaxis_dim, linestyle = '-', overplot = True, color = 'blue', alpha = 0.6,\
                      label = 'star cluster') # galactocentric radius as a function of time
    plt.legend()
    plt.title('Orbit of Star Cluster Within Satellite Galaxy for Tform = ' + str(tform) + ' & Tsteady = ' + str(tsteady) + ' (in Galactocentric Frame)')
    plt.show()
    plt.close()
    '''

    return end_pos_cluster, end_pos_gal, dswp, cdf
Ejemplo n.º 59
0
def test_qdf():
    from galpy.df import quasiisothermaldf
    from galpy.potential import MWPotential2014
    from galpy.actionAngle import actionAngleStaeckel
    # Setup actionAngle instance for action calcs
    aAS = actionAngleStaeckel(pot=MWPotential2014, delta=0.45, c=True)
    # Quasi-iso df w/ hr=1/3, hsr/z=1, sr(1)=0.2, sz(1)=0.1
    df = quasiisothermaldf(1. / 3.,
                           0.2,
                           0.1,
                           1.,
                           1.,
                           aA=aAS,
                           pot=MWPotential2014)
    # Evaluate DF w/ R,vR,vT,z,vz
    df(0.9, 0.1, 0.8, 0.05, 0.02)
    assert numpy.fabs(
        df(0.9, 0.1, 0.8, 0.05, 0.02) - numpy.array([123.57158928])
    ) < 10.**-4., 'qdf does not behave as expected'
    # Evaluate DF w/ Orbit instance, return ln
    from galpy.orbit import Orbit
    df(Orbit([0.9, 0.1, 0.8, 0.05, 0.02]), log=True)
    assert numpy.fabs(
        df(Orbit([0.9, 0.1, 0.8, 0.05, 0.02]), log=True) - numpy.array(
            [4.81682066])) < 10.**-4., 'qdf does not behave as expected'
    # Evaluate DF marginalized over vz
    df.pvRvT(0.1, 0.9, 0.9, 0.05)
    assert numpy.fabs(df.pvRvT(0.1, 0.9, 0.9, 0.05) - 2. * 23.273310451852243
                      ) < 10.**-4., 'qdf does not behave as expected'
    #NOTE: The pvRvT() function has changed with respect to the version used in Bovy (2015).
    #      As of January 2018, a prefactor of 2 has been added (=nsigma/2 with default nsigma=4),
    #      to account for the correct Gauss-Legendre integration normalization.
    # Evaluate DF marginalized over vR,vT
    df.pvz(0.02, 0.9, 0.05)
    assert numpy.fabs(df.pvz(0.02, 0.9, 0.05) - 50.949586235238172
                      ) < 10.**-4., 'qdf does not behave as expected'
    # Calculate the density
    df.density(0.9, 0.05)
    assert numpy.fabs(df.density(0.9, 0.05) - 12.73725936526167
                      ) < 10.**-4., 'qdf does not behave as expected'
    # Estimate the DF's actual density scale length at z=0
    df.estimate_hr(0.9, 0.)
    assert numpy.fabs(df.estimate_hr(0.9, 0.) - 0.322420336223
                      ) < 10.**-2., 'qdf does not behave as expected'
    # Estimate the DF's actual surface-density scale length
    df.estimate_hr(0.9, None)
    assert numpy.fabs(df.estimate_hr(0.9, None) - 0.38059909132766462
                      ) < 10.**-4., 'qdf does not behave as expected'
    # Estimate the DF's density scale height
    df.estimate_hz(0.9, 0.02)
    assert numpy.fabs(df.estimate_hz(0.9, 0.02) - 0.064836202345657207
                      ) < 10.**-4., 'qdf does not behave as expected'
    # Calculate the mean velocities
    df.meanvR(0.9, 0.05), df.meanvT(0.9, 0.05),
    df.meanvz(0.9, 0.05)
    assert numpy.fabs(df.meanvR(0.9, 0.05) - 3.8432265354618213e-18
                      ) < 10.**-4., 'qdf does not behave as expected'
    assert numpy.fabs(df.meanvT(0.9, 0.05) - 0.90840425173325279
                      ) < 10.**-4., 'qdf does not behave as expected'
    assert numpy.fabs(df.meanvz(0.9, 0.05) + 4.3579787517991084e-19
                      ) < 10.**-4., 'qdf does not behave as expected'
    # Calculate the velocity dispersions
    from numpy import sqrt
    sqrt(df.sigmaR2(0.9, 0.05)), sqrt(df.sigmaz2(0.9, 0.05))
    assert numpy.fabs(sqrt(df.sigmaR2(0.9, 0.05)) - 0.22695537077102387
                      ) < 10.**-4., 'qdf does not behave as expected'
    assert numpy.fabs(sqrt(df.sigmaz2(0.9, 0.05)) - 0.094215523962105044
                      ) < 10.**-4., 'qdf does not behave as expected'
    # Calculate the tilt of the velocity ellipsoid
    # 2017/10-28: CHANGED bc tilt now returns angle in rad, no longer in deg
    df.tilt(0.9, 0.05)
    assert numpy.fabs(
        df.tilt(0.9, 0.05) - 2.5166061974413765 / 180. *
        numpy.pi) < 10.**-4., 'qdf does not behave as expected'
    # Calculate a higher-order moment of the velocity DF
    df.vmomentdensity(0.9, 0.05, 6., 2., 2., gl=True)
    assert numpy.fabs(
        df.vmomentdensity(0.9, 0.05, 6., 2., 2., gl=True) -
        0.0001591100892366438) < 10.**-4., 'qdf does not behave as expected'
    # Sample velocities at given R,z, check mean
    numpy.random.seed(1)
    vs = df.sampleV(0.9, 0.05, n=500)
    mvt = numpy.mean(vs[:, 1])
    assert numpy.fabs(numpy.mean(vs[:, 0])) < 0.05  # vR
    assert numpy.fabs(mvt - df.meanvT(0.9, 0.05)) < 0.01  #vT
    assert numpy.fabs(numpy.mean(vs[:, 2])) < 0.05  # vz
    return None
Ejemplo n.º 60
0
def pec_v(ra, dec, d, pm_ra, pm_dec, V):
    """
    Function to estimate system peculiar velocity distribution as a function of distance.
    
    ra,dec,d,pm_ra,pm_dec,V are source orbit parameters for Galpy
            
    numpoints is the number of points in the orbit to integrate.
    
    """
    o = Orbit([
        ra * u.deg, dec * u.deg, d * u.kpc, pm_ra * u.mas / u.yr,
        pm_dec * u.mas / u.yr, V * u.km / u.s
    ],
              radec=True)
    o2 = Orbit(vxvv=[o.R(0.) / 8.0, 0., 1., 0., 0., o.phi(0.)], ro=8., vo=220.)
    current_vel = np.sqrt((o.U(0.) - o2.U(0) + 11.1)**2 +
                          (o.V(0.) - o2.V(0) + 12.24)**2 +
                          (o.W(0.) - o2.W(0) + 7.25)**2)
    return current_vel