def peculiar(ra, dec, d, pm_ra, pm_dec, V): 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
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__ )
def pass_v(ra, dec, d, pm_ra, pm_dec, V, time, numpoints): 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
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
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
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
def trace_forward(xyzuvw, time_in_past, Potential=MWPotential2014, solarmotion=None): """Trace forward one star in xyzuvw coords Parameters ---------- xyzuvw: numpy float array xyzuvw relative to the local standard of rest at some point in the past. time_in_past: float Time in the past that we want to trace forward to the present. """ if solarmotion == None: xyzuvw_sun = np.zeros(6) elif solarmotion == 'schoenrich': xyzuvw_sun = [0, 0, 25, 11.1, 12.24, 7.25] else: raise UserWarning if time_in_past == 0: time_in_past = 1e-5 # print("Time in past must be nonzero: {}".format(time_in_past)) # raise UserWarning times = np.linspace(0, time_in_past, 2) # Start off with an LSR orbit... lsr_orbit = get_lsr_orbit(times) # Convert times to galpy units: ts = -(times / 1e3) / bovy_conversion.time_in_Gyr(220., 8.) # Add on the lsr_orbit to get the times in the past. xyzuvw_gal = np.zeros(6) xyzuvw_gal[0] = xyzuvw[0] / 1e3 + lsr_orbit.x(ts[-1]) - lsr_orbit.x(ts[0]) xyzuvw_gal[1] = xyzuvw[1] / 1e3 + lsr_orbit.y(ts[-1]) - lsr_orbit.y(ts[0]) # Relative to a zero-height orbit, excluding the solar motion. xyzuvw_gal[2] = xyzuvw[2] / 1e3 xyzuvw_gal[3] = xyzuvw[3] + lsr_orbit.U(ts[-1]) - lsr_orbit.U(ts[0]) xyzuvw_gal[4] = xyzuvw[4] + lsr_orbit.V(ts[-1]) - lsr_orbit.V(ts[0]) xyzuvw_gal[5] = xyzuvw[5] + lsr_orbit.W(ts[-1]) - lsr_orbit.W(ts[0]) # Now convert to units that galpy understands by default. # FIXME: !!! Reverse [0] sign here. l = np.degrees(np.arctan2(xyzuvw_gal[1], -xyzuvw_gal[0])) b = np.degrees( np.arctan2(xyzuvw_gal[2], np.sqrt(np.sum(xyzuvw_gal[:2]**2)))) dist = np.sqrt(np.sum(xyzuvw_gal[:3]**2)) # As we are already in LSR co-ordinates, put in zero for solar motion and # zo. o = Orbit([l, b, dist, xyzuvw_gal[3], xyzuvw_gal[4], xyzuvw_gal[5]], solarmotion=[0, 0, 0], zo=0, lb=True, uvw=True, vo=220, ro=8) # Integrate this orbit forwards in time. o.integrate(-ts, Potential) # ,method='odeint') # Add in the solar z and the solar motion. xyzuvw_now = np.zeros(6) xyzuvw_now[0] = 1e3 * (o.x(-ts[-1]) - lsr_orbit.x(0)) xyzuvw_now[1] = 1e3 * o.y(-ts[-1]) xyzuvw_now[2] = 1e3 * o.z(-ts[-1]) - xyzuvw_sun[2] xyzuvw_now[3] = o.U(-ts[-1]) - xyzuvw_sun[3] xyzuvw_now[4] = o.V(-ts[-1]) - xyzuvw_sun[4] xyzuvw_now[5] = o.W(-ts[-1]) - xyzuvw_sun[5] # pdb.set_trace() return xyzuvw_now
def estimate_orbit_parameters(star_index, orbit_calculation_input): """ Estimate orbit parameters from the given MC sample of 6D information for the Nr of stars and save it into orbit_information """ # We are creating a dictionary for each star star_i = dict() ra = orbit_calculation_input['ra'] *u.deg dec = orbit_calculation_input['dec'] *u.deg dist = orbit_calculation_input['distance'] *u.pc pm_ra = orbit_calculation_input['pmra'] *u.mas/u.year pm_dec = orbit_calculation_input['pmdec'] *u.mas/u.year v_los = orbit_calculation_input['vrad'] *u.km/u.s # Create the Orbit instance o = Orbit( vxvv=[ra,dec,dist,pm_ra, pm_dec,v_los], ro=r_galactic_centre, vo=v_circular, zo=z_galactic_plane, solarmotion=[-11.1, 15.17, 7.25]*u.km/u.s, radec=True ) star_i = dict() #Galactocentric coordinates: star_i['X_XYZ'] = o.helioX()#*u.kpc star_i['Y_XYZ'] = o.helioY()#*u.kpc star_i['Z_XYZ'] = o.helioZ()#*u.kpc star_i['U_UVW'] = o.U()#*u.km/u.s star_i['V_UVW'] = o.V()#*u.km/u.s star_i['W_UVW'] = o.W()#*u.km/u.s star_i['R_Rzphi'] = o.R()#*u.kpc star_i['phi_Rzphi'] = o.phi()#*u.rad star_i['z_Rzphi'] = o.z()#*u.kpc star_i['vR_Rzphi'] = o.vR()#*u.km/u.s star_i['vT_Rzphi'] = o.vT()#*u.km/u.s star_i['vz_Rzphi'] = o.vz()#*u.km/u.s try: star_i['J_R'], star_i['L_Z'],star_i['J_Z'], star_i['omega_R'], star_i['omega_phi'], star_i['omega_z'], star_i['angle_R'], star_i['angle_phi'], star_i['angle_z'] = aAS.actionsFreqsAngles( #R,vR,vT,z,vz[,phi] star_i['R_Rzphi']*u.kpc, star_i['vR_Rzphi']*u.km/u.s, star_i['vT_Rzphi']*u.km/u.s, star_i['z_Rzphi']*u.kpc, star_i['vz_Rzphi']*u.km/u.s, star_i['phi_Rzphi']*u.rad, ro=r_galactic_centre,vo=v_circular ) except: star_i['omega_R'] = [np.nan] star_i['omega_phi'] = [np.nan] star_i['omega_z'] = [np.nan] star_i['angle_R'] = [np.nan] star_i['angle_phi'] = [np.nan] star_i['angle_z'] = [np.nan] try: star_i['J_R'], star_i['L_Z'],star_i['J_Z'] = aAS( #R,vR,vT,z,vz[,phi] star_i['R_Rzphi']*u.kpc, star_i['vR_Rzphi']*u.km/u.s, star_i['vT_Rzphi']*u.km/u.s, star_i['z_Rzphi']*u.kpc, star_i['vz_Rzphi']*u.km/u.s, star_i['phi_Rzphi']*u.rad, ro=r_galactic_centre,vo=v_circular ) except: star_i['J_R'] = [np.nan] star_i['L_Z'] = [np.nan] star_i['J_Z'] = [np.nan] try: star_i['ecc'], star_i['zmax'], star_i['R_peri'], star_i['R_ap'] = aAS.EccZmaxRperiRap( #R,vR,vT,z,vz[,phi] star_i['R_Rzphi']*u.kpc, star_i['vR_Rzphi']*u.km/u.s, star_i['vT_Rzphi']*u.km/u.s, star_i['z_Rzphi']*u.kpc, star_i['vz_Rzphi']*u.km/u.s, star_i['phi_Rzphi']*u.rad, ro=r_galactic_centre,vo=v_circular ) star_i['zmax'] star_i['R_peri'] star_i['R_peri'] except: star_i['ecc'] = [np.nan] star_i['zmax'] = [np.nan] star_i['R_peri'] = [np.nan] star_i['R_ap'] = [np.nan] star_i['Energy'] = o.E(pot=pot,ro=r_galactic_centre,vo=v_circular,zo=z_galactic_plane) return(star_i)
o = Orbit( #ra, dec, dist, pm_ra, pm_dec, v_los vxvv=[0.*u.deg,0.*u.deg,0.*u.kpc,0.*u.mas/u.yr, 0.*u.mas/u.yr,0.*u.km/u.s], ro=r_galactic_centre, vo=v_circular, zo=z_galactic_plane, solarmotion=[-11.1, 15.17, 7.25]*u.km/u.s, #solarmotion='schoenrich', radec=True ) #Galactocentric coordinates: sun['X_XYZ'] = o.helioX()#*u.kpc sun['Y_XYZ'] = o.helioY()#*u.kpc sun['Z_XYZ'] = o.helioZ()#*u.kpc sun['U_UVW'] = o.U()#*u.km/u.s sun['V_UVW'] = o.V()#*u.km/u.s sun['W_UVW'] = o.W()#*u.km/u.s sun['R_Rzphi'] = o.R()#*u.kpc sun['phi_Rzphi'] = o.phi()#*u.rad sun['z_Rzphi'] = o.z()#*u.kpc sun['vR_Rzphi'] = o.vR()#*u.km/u.s sun['vT_Rzphi'] = o.vT()#*u.km/u.s sun['vz_Rzphi'] = o.vz()#*u.km/u.s try: sun['J_R'], sun['L_Z'],sun['J_Z'], sun['omega_R'], sun['omega_phi'], sun['omega_z'], sun['angle_R'], sun['angle_phi'], sun['angle_z'] = aAS.actionsFreqsAngles( #R,vR,vT,z,vz[,phi] sun['R_Rzphi']*u.kpc, sun['vR_Rzphi']*u.km/u.s, sun['vT_Rzphi']*u.km/u.s,
if 'pmde' in o_data.keys(): o_data['pmde'] = o.pmdec(ts) if 'rv' in o_data.keys(): o_data['rv'] = o.vlos(ts) if 'x' in o_data.keys(): o_data['x'] = o.x(ts) if 'y' in o_data.keys(): o_data['y'] = o.y(ts) if 'z' in o_data.keys(): o_data['z'] = o.z(ts) if 'r' in o_data.keys(): o_data['r'] = o.R(ts) if 'phi' in o_data.keys(): o_data['phi'] = o.phi(ts) if 'vx' in o_data.keys(): o_data['vx'] = o.vx(ts) if 'vy' in o_data.keys(): o_data['vy'] = o.vy(ts) if 'vz' in o_data.keys(): o_data['vz'] = o.vz(ts) if 'vr' in o_data.keys(): o_data['vr'] = o.vR(ts) if 'vphi' in o_data.keys(): o_data['vphi'] = o.vT(ts) if 'U' in o_data.keys(): o_data['U'] = o.U(ts) if 'V' in o_data.keys(): o_data['V'] = o.V(ts) if 'W' in o_data.keys(): o_data['W'] = o.W(ts) if 'l' in o_data.keys(): o_data['l'] = o.ll(ts) if 'b' in o_data.keys(): o_data['b'] = o.bb(ts) if 'pml' in o_data.keys(): o_data['pml'] = o.pmll(ts) if 'pmb' in o_data.keys(): o_data['pmb'] = o.pmbb(ts) ################################################################################ # SAVE DATA #################################################################### savefiles = not args.notsave # Prepare savefile