def test_careful_traceback_and_forward(): """Step by step, project orbit forward, then backward""" bovy_times = np.array([0., np.pi / 3.]) chron_times = torb.convert_bovytime2myr(bovy_times) init_pos_chron = np.array([ 4000, 8000. * np.sqrt(3) / 2, 0, np.sin(np.pi / 3) * 220., -np.cos(np.pi / 3) * 220., 0 ]) init_pos_galpy = torb.convert_cart2galpycoords(init_pos_chron, ts=0.) assert np.allclose(np.array([1., 0, 1, 0, 0, np.pi / 3.]), init_pos_galpy) o = Orbit(vxvv=init_pos_galpy, ro=8., vo=220.) o.integrate(bovy_times, MWPotential2014, method='odeint') orbit_galpy = o.getOrbit() assert np.allclose(init_pos_galpy, orbit_galpy[0]) assert np.allclose( init_pos_galpy + np.array([0., 0., 0., 0., 0., bovy_times[-1]]), orbit_galpy[-1]) orbit_chron = torb.convert_galpycoords2cart(orbit_galpy, ts=bovy_times) assert np.allclose(init_pos_chron, orbit_chron[0]) assert np.allclose(init_pos_chron, orbit_chron[-1]) # Setup for backwards time integration # Currently at time of PI/3 back_init_pos_chron = orbit_chron[-1] back_init_pos_galpy = torb.convert_cart2galpycoords( back_init_pos_chron, bovy_times=bovy_times[-1], ) assert np.allclose( back_init_pos_galpy, torb.convert_cart2galpycoords(back_init_pos_chron, bovy_times=bovy_times[-1])) back_o = Orbit(vxvv=back_init_pos_galpy, ro=8., vo=220.) back_o.integrate(-1 * bovy_times, MWPotential2014, method='odeint') back_orbit_galpy = back_o.getOrbit() assert np.allclose(back_init_pos_galpy, back_orbit_galpy[0]) assert np.allclose( back_init_pos_galpy - np.array([0., 0., 0., 0., 0., bovy_times[-1]]), back_orbit_galpy[-1]) assert np.allclose(init_pos_galpy, back_orbit_galpy[-1]) back_orbit_chron = torb.convert_galpycoords2cart( back_orbit_galpy, ts=bovy_times[::-1], ) assert np.allclose(init_pos_chron, back_orbit_chron[-1])
def test_galpy_moving_conversions(): """Check if gaply conversions behave as expected where time is allowed to vary.""" lsr_chron = np.zeros(6) lsr_galpy = np.array([1.,0,1,0,0,0]) # Incorporate positive time into lsr position checks NSTEPS = 10 galpy_times = np.linspace(0., 2*np.pi, NSTEPS) lsrs_chron = np.repeat(lsr_chron, NSTEPS).reshape(6,-1).T lsrs_galpy = np.repeat(lsr_galpy, NSTEPS).reshape(6,-1).T lsrs_galpy[:,-1] = galpy_times chron_times = torb.convert_bovytime2myr(galpy_times) assert np.allclose( lsrs_chron, torb.convert_galpycoords2cart(lsrs_galpy, ts=galpy_times)) assert np.allclose( lsrs_galpy, torb.convert_cart2galpycoords(lsrs_chron, ts=chron_times) ) # Incorporate negative time into lsr position checks galpy_times = np.linspace(0., -2*np.pi, NSTEPS) lsrs_chron = np.repeat(lsr_chron, NSTEPS).reshape(6,-1).T lsrs_galpy = np.repeat(lsr_galpy, NSTEPS).reshape(6,-1).T lsrs_galpy[:,-1] = galpy_times chron_times = torb.convert_bovytime2myr(galpy_times) assert np.allclose( lsrs_chron, torb.convert_galpycoords2cart(lsrs_galpy, ts=galpy_times)) assert np.allclose( lsrs_galpy, torb.convert_cart2galpycoords(lsrs_chron, ts=chron_times) ) # Test random positions with random times SPREAD = int(1e4) # pc NSAMPLES = 100 many_pos_chron = (np.random.rand(NSAMPLES,6) - 0.5) * SPREAD # uniform between -10 and 10 many_chron_times = np.random.rand(NSAMPLES) * 100 #Myr many_pos_galpy = torb.convert_cart2galpycoords( many_pos_chron, ts=many_chron_times ) many_galpy_times = torb.convert_myr2bovytime(many_chron_times) for i in range(NSAMPLES): assert np.allclose(many_pos_chron[i], torb.convert_galpycoords2cart( many_pos_galpy[i], ts=many_galpy_times[i] ), atol=1e-2)
def test_galpy_moving_conversions(): """Check if gaply conversions behave as expected where time is allowed to vary.""" lsr_chron = np.zeros(6) lsr_galpy = np.array([1., 0, 1, 0, 0, 0]) # Incorporate positive time into lsr position checks NSTEPS = 10 galpy_times = np.linspace(0., 2 * np.pi, NSTEPS) lsrs_chron = np.repeat(lsr_chron, NSTEPS).reshape(6, -1).T lsrs_galpy = np.repeat(lsr_galpy, NSTEPS).reshape(6, -1).T lsrs_galpy[:, -1] = galpy_times chron_times = torb.convert_bovytime2myr(galpy_times) assert np.allclose( lsrs_chron, torb.convert_galpycoords2cart(lsrs_galpy, ts=galpy_times)) assert np.allclose( lsrs_galpy, torb.convert_cart2galpycoords(lsrs_chron, ts=chron_times) ) # Incorporate negative time into lsr position checks galpy_times = np.linspace(0., -2 * np.pi, NSTEPS) lsrs_chron = np.repeat(lsr_chron, NSTEPS).reshape(6, -1).T lsrs_galpy = np.repeat(lsr_galpy, NSTEPS).reshape(6, -1).T lsrs_galpy[:, -1] = galpy_times chron_times = torb.convert_bovytime2myr(galpy_times) assert np.allclose( lsrs_chron, torb.convert_galpycoords2cart(lsrs_galpy, ts=galpy_times)) assert np.allclose( lsrs_galpy, torb.convert_cart2galpycoords(lsrs_chron, ts=chron_times) ) # Test random positions with random times SPREAD = int(1e4) # pc NSAMPLES = 100 many_pos_chron = (np.random.rand(NSAMPLES, 6) - 0.5) * SPREAD # uniform between -10 and 10 many_chron_times = np.random.rand(NSAMPLES) * 100 # Myr many_pos_galpy = torb.convert_cart2galpycoords( many_pos_chron, ts=many_chron_times ) many_galpy_times = torb.convert_myr2bovytime(many_chron_times) for i in range(NSAMPLES): assert np.allclose(many_pos_chron[i], torb.convert_galpycoords2cart( many_pos_galpy[i], ts=many_galpy_times[i] ), atol=1e-2)
def test_galpy_stationary_conversions(): """Check if gaply conversions behave as expected where everything is at time 0""" # Test LSR lsr_chron = np.zeros(6) lsr_galpy = np.array([1., 0, 1, 0, 0, 0]) assert np.allclose(lsr_chron, torb.convert_galpycoords2cart(lsr_galpy, ts=0.)) assert np.allclose(lsr_galpy, torb.convert_cart2galpycoords(lsr_chron, ts=0.)) # Test galactic centre gc_chron = np.array([ 8000., 0, 0, 0, -220., 0, ]) gc_galpy = np.ones(6) * 1e-15 assert np.allclose(gc_chron, torb.convert_galpycoords2cart(gc_galpy, ts=0.)) assert np.allclose(gc_galpy, torb.convert_cart2galpycoords(gc_chron, ts=0.)) # Test simple, off origin point off_chron = np.array([ 4000, 8000. * np.sqrt(3) / 2, 0, np.sin(np.pi / 3) * 220., -np.cos(np.pi / 3) * 220., 0 ]) off_galpy = np.array([1., 0, 1, 0, 0, np.pi / 3.]) assert np.allclose(off_galpy, torb.convert_cart2galpycoords(off_chron, ts=0.)) assert np.allclose(off_chron, torb.convert_galpycoords2cart(off_galpy, ts=0.)) # Test random positions SPREAD = 100000 NSAMPLES = int(1e6) many_pos_chron = (np.random.rand(NSAMPLES, 6) - 0.5) * SPREAD # uniform between -10 and 10 many_pos_galpy = torb.convert_cart2galpycoords(many_pos_chron, ts=0.) assert np.allclose(many_pos_chron, torb.convert_galpycoords2cart(many_pos_galpy, ts=0.), atol=1e-2)
def test_misc(): POS_SPAN = 10 VEL_SPAN = 10 for i in range(100): # Generate random stars with chron coords between [SPAN, SPAN] rand_xyz = 2 * POS_SPAN * np.random.rand(3) - POS_SPAN rand_uvw = 2 * VEL_SPAN * np.random.rand(3) - VEL_SPAN rand_xyzuvw = np.hstack((rand_xyz, rand_uvw)) rand_galpy = torb.convert_cart2galpycoords(rand_xyzuvw) rand_epi = eg.convert_galpy2epi(rand_galpy) galpy_res = eg.convert_epi2galpy(rand_epi) xyzuvw_res = torb.convert_galpycoords2cart(galpy_res) try: # Positions shouldn't vary by more than 3 pc pos_atol = 2 # Velocities shouldn't vary by more than 0.05 km/s vel_atol = 0.03 assert np.allclose(rand_xyzuvw[:3], xyzuvw_res[:3], atol=pos_atol) assert np.allclose(rand_xyzuvw[3:], xyzuvw_res[3:], atol=vel_atol) # assert np.allclose(rand_galpy, eg.convert_epi2galpy(rand_epi), rtol=rtol) except AssertionError: print(i) import pdb pdb.set_trace()
def test_invertedAngle(): times = np.array([2*np.pi, 0., -2*np.pi]) lsr_galpy_plus_cycle = np.array([1,0,1,0,0,2*np.pi]) lsr_galpy = np.array([1.,0,1,0,0,0]) lsr_galpy_minus_cycle = np.array([1,0,1,0,0,-2*np.pi]) galpy_pos = np.vstack((lsr_galpy_minus_cycle, lsr_galpy, lsr_galpy_plus_cycle)) my_xyzuvw = torb.convert_galpycoords2cart(galpy_pos, times) assert np.allclose(my_xyzuvw, np.zeros((len(times), 6))) ntimes = 9 semi_times = np.linspace(-2*np.pi, 2*np.pi, ntimes) galpy_pos = np.repeat(lsr_galpy, ntimes).reshape(6,ntimes).T galpy_pos[:,-1] = semi_times my_xyzuvw = torb.convert_galpycoords2cart(galpy_pos, semi_times) assert np.allclose(my_xyzuvw, np.zeros((ntimes, 6)))
def test_galpy_stationary_conversions(): """Check if gaply conversions behave as expected where everything is at time 0""" # Test LSR lsr_chron = np.zeros(6) lsr_galpy = np.array([1.,0,1,0,0,0]) assert np.allclose(lsr_chron, torb.convert_galpycoords2cart(lsr_galpy, ts=0.)) assert np.allclose(lsr_galpy, torb.convert_cart2galpycoords(lsr_chron, ts=0.)) # Test galactic centre gc_chron = np.array([8000.,0,0,0,-220.,0,]) gc_galpy = np.ones(6) * 1e-15 assert np.allclose(gc_chron, torb.convert_galpycoords2cart(gc_galpy, ts=0.)) assert np.allclose(gc_galpy, torb.convert_cart2galpycoords(gc_chron, ts=0.)) # Test simple, off origin point off_chron = np.array([4000, 8000.*np.sqrt(3)/2, 0, np.sin(np.pi/3)*220., -np.cos(np.pi/3)*220., 0]) off_galpy = np.array([1.,0,1,0,0,np.pi/3.]) assert np.allclose(off_galpy, torb.convert_cart2galpycoords(off_chron, ts=0.)) assert np.allclose(off_chron, torb.convert_galpycoords2cart(off_galpy, ts=0.)) # Test random positions SPREAD = 100000 NSAMPLES = int(1e6) many_pos_chron = (np.random.rand(NSAMPLES,6) - 0.5) * SPREAD # uniform between -10 and 10 many_pos_galpy = torb.convert_cart2galpycoords(many_pos_chron, ts=0.) assert np.allclose(many_pos_chron, torb.convert_galpycoords2cart(many_pos_galpy, ts=0.), atol=1e-2)
def test_galpy2chron2galpy_stationary(): """ Check that converting from Galpy to Chronostar is internally consistent (you can convert back and forth) Time is fixed at 0 """ for i in range(100): xyzuvw_start = np.random.rand(6) galpy_start = torb.convert_cart2galpycoords(xyzuvw_start) xyzuvw_res = torb.convert_galpycoords2cart(galpy_start) assert np.allclose(xyzuvw_start, xyzuvw_res)
def test_evolve_chronspace(): """ Compare orbits evolved with both galpy and epicyclic, comparing in chron space """ time = 50. #Myr btime = torb.convert_myr2bovytime(time) chron_start = np.array([0., 0., 10., -2., 0., 0.]) galpy_start = torb.convert_cart2galpycoords(chron_start) epi_start = eg.convert_galpy2epi(galpy_start) # Just make sure the starting point can be transformed back and forth assert np.allclose(galpy_start, eg.convert_epi2galpy(epi_start)) assert np.allclose( chron_start, torb.convert_galpycoords2cart(eg.convert_epi2galpy(epi_start))) epi_end = eg.evolve_epi(epi_start, time)[0] galpy_end = torb.trace_galpy_orbit(galpy_start, times=time, single_age=True) chron_end = torb.trace_cartesian_orbit(chron_start, times=time, single_age=True) # Chronostar orbit end point, in galpy units chron_end_gu = torb.convert_cart2galpycoords(chron_end, ts=time) # This should be exact, because algorithmically it's the same thing. assert np.allclose(galpy_end, chron_end_gu) # Epicyclic orbit end point, in chronostar units epi_end_chron = torb.convert_galpycoords2cart( eg.convert_epi2galpy(epi_end), ts=btime) # assert position accurate within 15 pc # NOTE this is quite large... offset mainly in X. Maybe something to # investigate. assert np.allclose(chron_end[:3], epi_end_chron[:3], atol=15.) # assert velocity accurate within 0.5 km/s assert np.allclose(chron_end[3:], epi_end_chron[3:], atol=.5)
def test_galpy2chron2galpy_moving(): """ Check that converting from Galpy to Chronostar is internally consistent (you can convert back and forth) Time is allowed to vary """ # Test first LSR xyzuvw_start = np.zeros(6) time = 1. galpy_start = torb.convert_cart2galpycoords(xyzuvw_start, bovy_times=time) # import pdb; pdb.set_trace() xyzuvw_res = torb.convert_galpycoords2cart(galpy_start, ts=time) # import pdb; pdb.set_trace() assert np.allclose(xyzuvw_start, xyzuvw_res) # Now test slightly rotated LSR time = np.pi/4 galpy_stat_start = np.array([1., 0., 1., 0., 0., time]) xyzuvw_start = torb.convert_galpycoords2cart(galpy_stat_start) galpy_start = torb.convert_cart2galpycoords(xyzuvw_start, bovy_times=time) xyzuvw_res = torb.convert_galpycoords2cart(galpy_start, ts=time) assert np.allclose(xyzuvw_start, xyzuvw_res) # Now test points randomly dispersed near the LSR # but at a time range corresponding to LSR rotation of [0-1] rad for i in range(100): xyzuvw_start = np.random.rand(6) # Time is in galpy units time = np.random.rand() galpy_start = torb.convert_cart2galpycoords(xyzuvw_start, bovy_times=time) # import pdb; pdb.set_trace() xyzuvw_res = torb.convert_galpycoords2cart(galpy_start, ts=time) # import pdb; pdb.set_trace() assert np.allclose(xyzuvw_start, xyzuvw_res)
def test_rotatedLSR(): """ Check that LSRs with different azimuthal positions also remain constant """ # method_atols = {'odeint':1e-11, 'dopr54_c':1e-6} for method, atol in method_atols.items(): rot_lsr_gp_coords = np.array([1., 0., 1., 0., 0., np.pi]) xyzuvw_rot_lsr = torb.convert_galpycoords2cart(rot_lsr_gp_coords) ### xyzuvw_rot_lsr = [16000., 0, 0, 0, 0, 0,] times = np.linspace(0,100,101) xyzuvws = torb.trace_cartesian_orbit(xyzuvw_rot_lsr, times, single_age=False, method=method) # On a circular orbit, same radius as LSR, so shouldn't vary at all # assert np.allclose(xyzuvws[0,:5],xyzuvws[-1,:5]) assert np.allclose(xyzuvws[0],xyzuvws[-1], atol=atol), 'Method {}'.format(method) # Should be initialised on opposite side of galaxy (X = 16kpc) assert np.allclose(16000., xyzuvws[0,0])
dim_labels = ['R','vR','vT','z','vz','phi'] print('____ PRINTING ORBIT, DIMENSION BY DIMENSION ____') print('_____ forward _____') for i in range(6): print('----- {}:{:5} -----'.format(i, dim_labels[i])) print(orbit[:,i]) print('_____ backward _____') for i in range(6): print('----- {}:{:5} -----'.format(i, dim_labels[i])) print(back_orbit[:,i]) import sys sys.path.insert(0, '..') from chronostar import traceorbit xyzuvw = traceorbit.convert_galpycoords2cart(lsr_orbit.getOrbit(), forward_times) back_xyzuvw = traceorbit.convert_galpycoords2cart(back_lsr_orbit.getOrbit(), backward_times) dim_labels = 'XYZUVW' print('____ PRINTING ORBIT, DIMENSION BY DIMENSION ____') print('_____ forward _____') for i in range(6): print('----- {}:{:5} -----'.format(i, dim_labels[i])) print(xyzuvw[:,i]) print('_____ backward _____') for i in range(6): print('----- {}:{:5} -----'.format(i, dim_labels[i])) print(back_xyzuvw[:,i]) # assert (np.allclose(REFERENCE_SCHOENRICH_SOLAR_MOTION, results)),\ # '!!! Using galpy version {} Need galpy version 1.1 !!!'.format(
def test_careful_traceback_and_forward(): """Step by step, project orbit forward, then backward""" bovy_times = np.array([0., np.pi/3.]) chron_times = torb.convert_bovytime2myr(bovy_times) init_pos_chron = np.array([ 4000, 8000.*np.sqrt(3)/2, 0, np.sin(np.pi/3)*220., -np.cos(np.pi/3)*220., 0 ]) init_pos_galpy = torb.convert_cart2galpycoords(init_pos_chron, ts=0.) assert np.allclose(np.array([1.,0,1,0,0,np.pi/3.]), init_pos_galpy) o = Orbit(vxvv=init_pos_galpy, ro=8., vo=220.) o.integrate(bovy_times, MWPotential2014, method='odeint') orbit_galpy = o.getOrbit() assert np.allclose(init_pos_galpy, orbit_galpy[0]) assert np.allclose(init_pos_galpy + np.array([0.,0.,0.,0.,0.,bovy_times[-1]]), orbit_galpy[-1]) orbit_chron = torb.convert_galpycoords2cart(orbit_galpy, ts=bovy_times) assert np.allclose(init_pos_chron, orbit_chron[0]) assert np.allclose(init_pos_chron, orbit_chron[-1]) # Setup for backwards time integration # Currently at time of PI/3 back_init_pos_chron = orbit_chron[-1] back_init_pos_galpy = torb.convert_cart2galpycoords( back_init_pos_chron, bovy_times=bovy_times[-1], ) assert np.allclose(back_init_pos_galpy, torb.convert_cart2galpycoords( back_init_pos_chron, bovy_times=bovy_times[-1] )) back_o = Orbit(vxvv=back_init_pos_galpy, ro=8., vo=220.) back_o.integrate(-1*bovy_times, MWPotential2014, method='odeint') back_orbit_galpy = back_o.getOrbit() assert np.allclose(back_init_pos_galpy, back_orbit_galpy[0]) assert np.allclose(back_init_pos_galpy - np.array([0.,0.,0.,0.,0.,bovy_times[-1]]), back_orbit_galpy[-1]) assert np.allclose(init_pos_galpy, back_orbit_galpy[-1]) back_orbit_chron = torb.convert_galpycoords2cart( back_orbit_galpy, ts=bovy_times[::-1], ) assert np.allclose(init_pos_chron, back_orbit_chron[-1])