Beispiel #1
0
def test_velocity_in_kpcGyr():
    #Test the scaling, should scale as velocity
    vofid, rofid = 200., 8.
    assert numpy.fabs(
        2. * bovy_conversion.velocity_in_kpcGyr(vofid, rofid) /
        bovy_conversion.velocity_in_kpcGyr(2. * vofid, rofid) -
        1.) < 10.**-10., 'velocity_in_kpcGyr did not work as expected'
    assert numpy.fabs(
        bovy_conversion.velocity_in_kpcGyr(vofid, rofid) /
        bovy_conversion.velocity_in_kpcGyr(vofid, 2 * rofid) -
        1.) < 10.**-10., 'velocity_in_kpcGyr did not work as expected'
    return None
def calc_init_pos(duration, pot_type, Vo, Ro, q=None):

    ro = Ro
    vo = Vo
    ts   = 1001 # number of timesteps
    # we need to convert to galpy time units since its not in Gyrs
    #time = np.linspace(0., nemotime_to_actualtime(duration)/bovy_conversion.time_in_Gyr(vo,ro), ts)
    time = np.linspace(0., duration/bovy_conversion.time_in_Gyr(vo,ro), ts)
    
    if pot_type == "Log":
        p = potential.LogarithmicHaloPotential(q = q, normalize = 1)
    
    elif pot_type == "MW2014":
        p = MWPotential2014

    # the position and velocity of GD1 stream today in cartesian coordinates
    xnow, ynow, znow    = np.array([12.4,1.5,7.1])
    vxnow, vynow, vznow = np.array([107.0,-243.0,-105.0])

    # the position and velocity of GD1 stream today in cylindrical coordinates
    Ri,zcyli,phii  = xyz_to_cyl(xnow,ynow,znow)
    vri,vti,vzcyli = vxvyvz_to_vrvtvz(xnow,ynow,znow,-vxnow, -vynow, -vznow)

    # initializing the orbit
    o = Orbit(vxvv=[Ri/ro, vri/vo, vti/vo, zcyli/ro, vzcyli/vo, phii], ro=ro, vo=vo)
    o.integrate(time,p)

    #x_init = o.x(time[-1], ro = ro, obs= [ro,0.,0.])[0]
    #y_init = o.y(time[-1], ro = ro, obs= [ro,0.,0.])[0]
    #z_init = o.z(time[-1], ro = ro, obs= [ro,0.,0.])
    #vx_init = -o.vx(time[ts-1],ro = ro,obs= [ro,0.,0.], use_physical=False)[0]*bovy_conversion.velocity_in_kpcGyr(vo,ro)
    #vy_init = -o.vy(time[ts-1],ro = ro,obs= [ro,0.,0.], use_physical=False)[0]*bovy_conversion.velocity_in_kpcGyr(vo,ro)
    #vz_init = -o.vz(time[ts-1],ro = ro,obs= [ro,0.,0.], use_physical=False)*bovy_conversion.velocity_in_kpcGyr(vo,ro)


    x_init = o.x(time[-1])[0]
    y_init = o.y(time[-1])[0]
    z_init = o.z(time[-1])

    vx_init = -o.vx(time[-1],use_physical=False)[0]*bovy_conversion.velocity_in_kpcGyr(vo,ro)
    vy_init = -o.vy(time[-1],use_physical=False)[0]*bovy_conversion.velocity_in_kpcGyr(vo,ro)
    vz_init = -o.vz(time[-1],use_physical=False)*bovy_conversion.velocity_in_kpcGyr(vo,ro)


    return np.array([x_init, y_init, z_init, vx_init, vy_init, vz_init])
Beispiel #3
0
def gyrout(cluster, filename="init.nemo.dat"):
    """
    NAME:

       gyrout

    PURPOSE:

       Output a snapshot in gyrfalcon/NEMO format

    INPUT:

       cluster - a StarCluster-class object

       filename - name of file to be written to (Default: 'init.nemo.dat')

    OUTPUT:

       None

    HISTORY:

       2019 - Written - Webb (UofT)

    """
    vcon = 220.0 / bovy_conversion.velocity_in_kpcGyr(220.0, 8.0)
    mcon = 222288.4543021174

    units0, origin0 = save_cluster(cluster)
    cluster.to_galaxy()
    cluster.to_realkpc()

    np.savetxt(
        filename,
        np.column_stack([
            cluster.m / mcon,
            cluster.x,
            cluster.y,
            cluster.z,
            cluster.vx / vcon,
            cluster.vy / vcon,
            cluster.vz / vcon,
        ]),
    )

    return_cluster(cluster, units0, origin0)

    return 0
Beispiel #4
0
def run_orbitIntegration_comparison(orb,pot,tmax,vo,ro,isList=False,
                                    tol=0.01):
    # Integrate in galpy
    ts= numpy.linspace(0.,tmax/bovy_conversion.time_in_Gyr(vo,ro),1001)
    orb.integrate(ts,pot)
    # Now setup a NEMO snapshot in the correct units ([x] = kpc, [v] = kpc/Gyr)
    numpy.savetxt('orb.dat',
                  numpy.array([[10.**-6.,orb.x(),orb.y(),orb.z(),
                                orb.vx(use_physical=False)\
                                    *bovy_conversion.velocity_in_kpcGyr(vo,ro),
                                orb.vy(use_physical=False)\
                                    *bovy_conversion.velocity_in_kpcGyr(vo,ro),
                                orb.vz(use_physical=False)\
                                    *bovy_conversion.velocity_in_kpcGyr(vo,ro)]]))
    # Now convert to NEMO format
    try:
        convert_to_nemo('orb.dat','orb.nemo')
    finally:
        os.remove('orb.dat')
    # Integrate with gyrfalcON
    try:
        if isList:
            integrate_gyrfalcon('orb.nemo','orb_evol.nemo',tmax,
                                potential.nemo_accname(pot),
                                potential.nemo_accpars(pot,vo,ro))
        else:
            integrate_gyrfalcon('orb.nemo','orb_evol.nemo',tmax,
                                pot.nemo_accname(),pot.nemo_accpars(vo,ro))
    finally:
        os.remove('orb.nemo')
        os.remove('gyrfalcON.log')
    # Convert back to ascii
    try:
        convert_from_nemo('orb_evol.nemo','orb_evol.dat')
    finally:
        os.remove('orb_evol.nemo')
    # Read and compare
    try:
        nemodata= numpy.loadtxt('orb_evol.dat',comments='#')
        xdiff= numpy.fabs((nemodata[-1,1]-orb.x(ts[-1]))/nemodata[-1,1])
        ydiff= numpy.fabs((nemodata[-1,2]-orb.y(ts[-1]))/nemodata[-1,2])
        zdiff= numpy.fabs((nemodata[-1,3]-orb.z(ts[-1]))/nemodata[-1,3])
        vxdiff= numpy.fabs((nemodata[-1,4]-orb.vx(ts[-1],use_physical=False)*bovy_conversion.velocity_in_kpcGyr(vo,ro))/nemodata[-1,4])
        vydiff= numpy.fabs((nemodata[-1,5]-orb.vy(ts[-1],use_physical=False)*bovy_conversion.velocity_in_kpcGyr(vo,ro))/nemodata[-1,5])
        vzdiff= numpy.fabs((nemodata[-1,6]-orb.vz(ts[-1],use_physical=False)*bovy_conversion.velocity_in_kpcGyr(vo,ro))/nemodata[-1,6])
        assert xdiff < tol, 'galpy and NEMO gyrfalcON orbit integration inconsistent for x by %g' % xdiff
        assert ydiff < tol, 'galpy and NEMO gyrfalcON orbit integration inconsistent for y by %g' % ydiff
        assert zdiff < tol, 'galpy and NEMO gyrfalcON orbit integration inconsistent for z by %g' % zdiff
        assert vxdiff < tol, 'galpy and NEMO gyrfalcON orbit integration inconsistent for vx by %g' % vxdiff
        assert vydiff < tol, 'galpy and NEMO gyrfalcON orbit integration inconsistent for vy by %g' % vydiff
        assert vzdiff < tol, 'galpy and NEMO gyrfalcON orbit integration inconsistent for vz by %g' % vzdiff
    finally:
        os.remove('orb_evol.dat')
    return None
Beispiel #5
0
def gyrout(cluster, filename="init.nemo.dat"):
    """Output a snapshot in gyrfalcon/NEMO format

    - Note that units are converted to Walter Dehnen units (WDunits in GYRFALCON)

    Parameters
    ----------
    cluster : class
        StarCluster
    filename : str
        name of file to be written to (default: 'init.nemo.dat')
   
    Returns
    -------
    None

    History
    -------
    2019 - Written - Webb (UofT)

    """
    vcon = 220.0 / bovy_conversion.velocity_in_kpcGyr(220.0, 8.0)
    mcon = 222288.4543021174

    units0, origin0 = save_cluster(cluster)
    cluster.to_galaxy()
    cluster.to_kpckms()

    np.savetxt(
        filename,
        np.column_stack([
            cluster.m / mcon,
            cluster.x,
            cluster.y,
            cluster.z,
            cluster.vx / vcon,
            cluster.vy / vcon,
            cluster.vz / vcon,
        ]),
    )

    return_cluster(cluster, units0, origin0)

    return 0
Beispiel #6
0
def run_orbitIntegration_comparison(orb,
                                    pot,
                                    tmax,
                                    vo,
                                    ro,
                                    isList=False,
                                    tol=0.01):
    # Integrate in galpy
    ts = numpy.linspace(0., tmax / bovy_conversion.time_in_Gyr(vo, ro), 1001)
    orb.integrate(ts, pot)
    # Now setup a NEMO snapshot in the correct units ([x] = kpc, [v] = kpc/Gyr)
    numpy.savetxt('orb.dat',
                  numpy.array([[10.**-6.,orb.x(),orb.y(),orb.z(),
                                orb.vx(use_physical=False)\
                                    *bovy_conversion.velocity_in_kpcGyr(vo,ro),
                                orb.vy(use_physical=False)\
                                    *bovy_conversion.velocity_in_kpcGyr(vo,ro),
                                orb.vz(use_physical=False)\
                                    *bovy_conversion.velocity_in_kpcGyr(vo,ro)]]))
    # Now convert to NEMO format
    try:
        convert_to_nemo('orb.dat', 'orb.nemo')
    finally:
        os.remove('orb.dat')
    # Integrate with gyrfalcON
    try:
        if isList:
            integrate_gyrfalcon('orb.nemo', 'orb_evol.nemo', tmax,
                                potential.nemo_accname(pot),
                                potential.nemo_accpars(pot, vo, ro))
        else:
            integrate_gyrfalcon('orb.nemo', 'orb_evol.nemo', tmax,
                                pot.nemo_accname(), pot.nemo_accpars(vo, ro))
    finally:
        os.remove('orb.nemo')
        os.remove('gyrfalcON.log')
    # Convert back to ascii
    try:
        convert_from_nemo('orb_evol.nemo', 'orb_evol.dat')
    finally:
        os.remove('orb_evol.nemo')
    # Read and compare
    try:
        nemodata = numpy.loadtxt('orb_evol.dat', comments='#')
        xdiff = numpy.fabs((nemodata[-1, 1] - orb.x(ts[-1])) / nemodata[-1, 1])
        ydiff = numpy.fabs((nemodata[-1, 2] - orb.y(ts[-1])) / nemodata[-1, 2])
        zdiff = numpy.fabs((nemodata[-1, 3] - orb.z(ts[-1])) / nemodata[-1, 3])
        vxdiff = numpy.fabs(
            (nemodata[-1, 4] - orb.vx(ts[-1], use_physical=False) *
             bovy_conversion.velocity_in_kpcGyr(vo, ro)) / nemodata[-1, 4])
        vydiff = numpy.fabs(
            (nemodata[-1, 5] - orb.vy(ts[-1], use_physical=False) *
             bovy_conversion.velocity_in_kpcGyr(vo, ro)) / nemodata[-1, 5])
        vzdiff = numpy.fabs(
            (nemodata[-1, 6] - orb.vz(ts[-1], use_physical=False) *
             bovy_conversion.velocity_in_kpcGyr(vo, ro)) / nemodata[-1, 6])
        assert xdiff < tol, 'galpy and NEMO gyrfalcON orbit integration inconsistent for x by %g' % xdiff
        assert ydiff < tol, 'galpy and NEMO gyrfalcON orbit integration inconsistent for y by %g' % ydiff
        assert zdiff < tol, 'galpy and NEMO gyrfalcON orbit integration inconsistent for z by %g' % zdiff
        assert vxdiff < tol, 'galpy and NEMO gyrfalcON orbit integration inconsistent for vx by %g' % vxdiff
        assert vydiff < tol, 'galpy and NEMO gyrfalcON orbit integration inconsistent for vy by %g' % vydiff
        assert vzdiff < tol, 'galpy and NEMO gyrfalcON orbit integration inconsistent for vz by %g' % vzdiff
    finally:
        os.remove('orb_evol.dat')
    return None
Beispiel #7
0
o = dfc.sample(n=nsamples, returnOrbit=True, nphi=1, rrange=[0.0, 1.0])

rvals_spherical = [ e.R() for e in o ]
thetavals_spherical = [ np.arccos(1 - 2*np.random.random()) for i in range(nsamples) ]

rvals_cylindrical = [ rvals_spherical[i]*np.sin(thetavals_spherical[i]) for i in range(nsamples) ]
phivals_cylindrical = 2*np.pi * np.random.random(nsamples)
zvals_cylindrical = [ rvals_spherical[i]*np.cos(thetavals_spherical[i]) for i in range(nsamples) ]

    
#using Staeckel
aAS = actionAngleStaeckel(pot=MWPotential2014, delta=0.45, c=True)
qdfS = quasiisothermaldf(1./3., 0.2, 0.1, 1., 1., pot=MWPotential2014, aA=aAS, cutcounter=True)

#220 km/s at 8 kpc, convert back to km/s
to_kms = bovy_conversion.velocity_in_kpcGyr(220., 8.) * 0.9785

vrvals_cylindrical, vphivals_cylindrical, vzvals_cylindrical = [], [], []

for Rcoord, Zcoord in zip(rvals_cylindrical, zvals_cylindrical):
    
    vr_init, vphi_init, vz_init = qdfS.sampleV(Rcoord, Zcoord, n=1)[0,:]
    
    vrvals_cylindrical.append( vr_init * to_kms )
    vphivals_cylindrical.append( vphi_init * to_kms )
    vzvals_cylindrical.append( vz_init * to_kms )

np.savetxt('dehnen_rvals.txt', rvals_cylindrical)
np.savetxt('dehnen_phivals.txt', phivals_cylindrical)
np.savetxt('dehnen_zvals.txt', zvals_cylindrical)
Beispiel #8
0
def _get_gyrfalcon(filein,
                   units="WDunits",
                   origin="galaxy",
                   ofile=None,
                   advance=False,
                   **kwargs):
    """Extract a single snapshot from an ascii file output from a gyrfalcon simulation

    Parameters
    ----------
    filein : file
        opened gyrfalcon file
    units : str
        units of data (default:'WDunits')
    ofile : file
        opened file containing orbital information
    advance : bool
        is this a snapshot that has been advanced to from initial  load_cluster? (default: False)

    Returns
    -------
    cluster : class
        StarCluster

    Other Parameters
    ----------------
    Same as load_cluster

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

    if units == "WDunits":
        vcon = 220.0 / bovy_conversion.velocity_in_kpcGyr(220.0, 8.0)
        mcon = 222288.4543021174
        units = "kpckms"
    else:
        vcon = 1.0
        mcon = 1.0

    # Default **kwargs
    skiprows = kwargs.pop("skiprows", 13)

    i_d = []
    m = []
    x = []
    y = []
    z = []
    vx = []
    vy = []
    vz = []

    over_head = False
    ntot = 0
    tphys = 0.0

    for j in range(0, skiprows):
        data = filein.readline().split()
        if "#" not in data:
            over_head = True
            print("OVER HEAD")
            break
        if len(data) == 0:
            print("END OF FILE")
            return StarCluster(0.0, ctype="gyrfalcon", **kwargs)
        if any("Ntot" in dat for dat in data):
            sntot = data[2]
            ntot = int(sntot[:-1])
        if any("time" in dat for dat in data):
            tphys = float(data[2]) * 1000.0

    cluster = StarCluster(ntot,
                          tphys,
                          units=units,
                          origin=origin,
                          ctype="gyrfalcon",
                          sfile=filein,
                          bfile=None,
                          skiprows=skiprows,
                          **kwargs)

    for j in range(ntot):
        if over_head:
            over_head = False
        else:
            data = filein.readline().split()
        if "#" in data:
            break

        i_d.append(j + 1)
        m.append(float(data[0]) * mcon)
        x.append(float(data[1]))
        y.append(float(data[2]))
        z.append(float(data[3]))
        vx.append(float(data[4]) * vcon)
        vy.append(float(data[5]) * vcon)
        vz.append(float(data[6]) * vcon)

    if ntot > 0:

        cluster.add_stars(x, y, z, vx, vy, vz, m, i_d)

        if ofile == None:
            cluster.find_centre()
        else:
            _get_cluster_orbit(cluster, ofile, advance=advance, **kwargs)

        if kwargs.get("do_key_params", True):
            do_order = kwargs.get("do_key_params", True)
            cluster.to_cluster()
            cluster.find_centre()
            cluster.to_centre(do_key_params=True, do_order=do_order)
            cluster.to_galaxy()

    return cluster
Beispiel #9
0
def _get_snapshot(filename=None,
                  tphys=0.0,
                  ctype="snapshot",
                  col_names=["m", "x", "y", "z", "vx", "vy", "vz"],
                  col_nums=[0, 1, 2, 3, 4, 5, 6],
                  units="pckms",
                  origin="cluster",
                  ofile=None,
                  advance=False,
                  **kwargs):
    """Load a generic snapshot where column names and numbers can be manually assigned

    Parameters
    ----------
    ctype : str
        code used to generate data (nbody6/nbody6se/gyrfalcon/...)
    filename : str
        name of file
    col_names : str
        names corresponding to mass, position, and velocity
    col_nums : int
        column numbers corresponding to each column name
    units : str
        units of input data (default: kpckms)
    origin : str
        origin of input data (default: cluster)
    ofile : file
        opened file containing orbital information
    advance : bool
        is this a snapshot that has been advanced to from initial  load_cluster? (default: False)

    Returns
    -------
    cluster : class
        StarCluster

    Other Parameters
    ----------------
    Same as load_cluster

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

    col_names = np.array(col_names)
    col_nums = np.array(col_nums)

    nsnap = int(kwargs.get("nsnap", "0"))
    nzfill = int(kwargs.get("nzfill", 5))
    delimiter = kwargs.get("delimiter", None)
    wdir = kwargs.get("wdir", "./")
    snapdir = kwargs.get("snapdir", "snaps/")
    snapbase = kwargs.get("snapbase", "")
    snapend = kwargs.get("snapend", ".dat")
    skiprows = kwargs.get("skiprows", 0)

    if units == "WDunits":
        vcon = 220.0 / bovy_conversion.velocity_in_kpcGyr(220.0, 8.0)
        mcon = 222288.4543021174
        units = "kpckms"
    else:
        vcon = 1.0
        mcon = 1.0

    if filename != None:
        if os.path.isfile("%s%s%s" % (wdir, snapdir, filename)):
            data = np.loadtxt(
                "%s%s%s" % (wdir, snapdir, filename),
                delimiter=delimiter,
                skiprows=skiprows,
            )
        elif os.path.isfile("%s%s" % (wdir, filename)):
            data = np.loadtxt("%s%s" % (wdir, filename),
                              delimiter=delimiter,
                              skiprows=skiprows)
        else:
            print("NO FILE FOUND: %s, %s, %s" % (wdir, snapdir, filename))
            cluster = StarCluster(0., ctype=ctype, **kwargs)
            print(cluster.ntot)
            return cluster
    elif os.path.isfile(
            "%s%s%s%s%s" %
        (wdir, snapdir, snapbase, str(nsnap).zfill(nzfill), snapend)):
        filename = "%s%s%s%s%s" % (
            wdir,
            snapdir,
            snapbase,
            str(nsnap).zfill(nzfill),
            snapend,
        )
        data = np.loadtxt(
            ("%s%s%s%s%s" %
             (wdir, snapdir, snapbase, str(nsnap).zfill(nzfill), snapend)),
            delimiter=delimiter,
            skiprows=skiprows,
        )
    elif os.path.isfile("%s%s%s%s" %
                        (wdir, snapbase, str(nsnap).zfill(nzfill), snapend)):
        filename = "%s%s%s%s" % (wdir, snapbase, str(nsnap).zfill(nzfill),
                                 snapend)
        data = np.loadtxt(
            ("%s%s%s%s" % (wdir, snapbase, str(nsnap).zfill(nzfill), snapend)),
            delimiter=delimiter,
            skiprows=skiprows,
        )
    else:
        print("NO FILE FOUND - %s%s%s%s%s" %
              (wdir, snapdir, snapbase, str(nsnap).zfill(nzfill), snapend))
        filename = "%s%s%s%s%s" % (
            wdir,
            snapdir,
            snapbase,
            str(nsnap).zfill(nzfill),
            snapend,
        )
        cluster = StarCluster(0., ctype=ctype, **kwargs)
        print(cluster.ntot)
        return cluster

    mindx = np.argwhere(col_names == "m")[0][0]
    m = data[:, col_nums[mindx]] * mcon

    xindx = np.argwhere(col_names == "x")[0][0]
    x = data[:, col_nums[xindx]]
    yindx = np.argwhere(col_names == "y")[0][0]
    y = data[:, col_nums[yindx]]
    zindx = np.argwhere(col_names == "z")[0][0]
    z = data[:, col_nums[zindx]]
    vxindx = np.argwhere(col_names == "vx")[0][0]
    vx = data[:, col_nums[vxindx]] * vcon
    vyindx = np.argwhere(col_names == "vy")[0][0]
    vy = data[:, col_nums[vyindx]] * vcon
    vzindx = np.argwhere(col_names == "vz")[0][0]
    vz = data[:, col_nums[vzindx]] * vcon

    if "id" in col_names:
        idindx = np.argwhere(col_names == "id")[0][0]
        i_d = data[:, col_nums[idindx]]
    else:
        i_d = np.linspace(0, len(x), len(x)) + 1

    if "kw" in col_names:
        kwindx = np.argwhere(col_names == "kw")[0][0]
        kw = data[:, col_nums[kwindx]]
    else:
        kw = np.zeros(len(x))

    nbnd = len(m)

    cluster = StarCluster(nbnd,
                          tphys,
                          units=units,
                          origin=origin,
                          ctype=ctype,
                          **kwargs)
    cluster.add_stars(x, y, z, vx, vy, vz, m, i_d)
    cluster.kw = kw

    if origin == "galaxy":
        if ofile == None:
            cluster.find_centre()
        else:
            _get_cluster_orbit(cluster, ofile, advance=advance, **kwargs)

        if kwargs.get("do_key_params", True):
            do_order = kwargs.get("do_key_params", True)

            cluster.to_cluster()
            cluster.find_centre()
            cluster.to_centre(do_key_params=True, do_order=do_order)
            cluster.to_galaxy()

    elif origin == "cluster":
        if kwargs.get("do_key_params", True):
            do_order = kwargs.get("do_key_params", True)
            # Estimate centre of distribution
            cluster.find_centre()
            cluster.to_centre(do_key_params=True, do_order=do_order)
            cluster.to_cluster()

        if ofile != None:
            _get_cluster_orbit(cluster, ofile, advance=advance, **kwargs)

    return cluster
Beispiel #10
0
 def kms_to_kpcGyr_wrapper(*args,**kwargs):
     return func(args[0],velocity_in_kpcGyr(args[1],1.),args[2],**kwargs)
def test_velocity_in_kpcGyr():
    #Test the scaling, should scale as velocity
    vofid, rofid= 200., 8.
    assert numpy.fabs(2.*bovy_conversion.velocity_in_kpcGyr(vofid,rofid)/bovy_conversion.velocity_in_kpcGyr(2.*vofid,rofid)-1.) < 10.**-10., 'velocity_in_kpcGyr did not work as expected'
    assert numpy.fabs(bovy_conversion.velocity_in_kpcGyr(vofid,rofid)/bovy_conversion.velocity_in_kpcGyr(vofid,2*rofid)-1.) < 10.**-10., 'velocity_in_kpcGyr did not work as expected'
    return None
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