fig.savefig(f"diagnostic_plots/alpha_age.png") plt.close("all") o = Orbit(np.array([ f_new_vac['ra'], f_new_vac['dec'], f_new_vac['weighted_dist'] / 1000., f_new_vac['pmra'], f_new_vac['pmdec'], f_new_vac['vhelio_avg'] ]).T, ro=8.125, vo=220., zo=0.0208, solarmotion=[-11.1, 25.7, 7.25], radec=True) fig = plt.figure(dpi=200) ax = fig.gca() ax.scatter(o.R(), f_new_vac['GALR'], s=1e-2) ax.plot([0, 20], [0, 20], c='k', ls='--') ax.set_xlim(0., 20.) ax.set_ylim(0., 20.) ax.set_xlabel(r'$R\,\mathrm{Orbit}$') ax.set_ylabel(r'$R\,\mathrm{catalog}$') fig.tight_layout() fig.savefig(f"diagnostic_plots/galr_check.png") plt.close("all") X = f_new_vac['GALR'] * np.cos(f_new_vac['GALPHI']) Y = f_new_vac['GALR'] * np.sin(f_new_vac['GALPHI']) fig = plt.figure(dpi=200) ax = fig.gca() ax.hist2d(X, Y, range=((-1, 15), (-12.5, 12.5)), bins=40, norm=LogNorm())
def example_integrate_orbit(): # Use 'MWPotential2014' as an example my_potential = MWPotential2014 # integration time in units of (_R0/_V0) time_start = 0. time_end = 100. my_time_step = numpy.linspace(time_start, time_end, 1001) # read 6D astrometric data # (0) [mas] parallax # (1) [deg] ell # (2) [deg] b # (3) [km/s] heliocentric line-of-sight velocity # (4) [mas/yr] proper motion along ell direction (mu_ellstar = mu_ell * cos(b)) # (5) [mas/yr] proper motion along b direction (mu_b) my_filename = 'parallax_ell_b_heliocentricLineOfSightVelocity_properMotionEllStar_properMotionB.txt' my_file = open(my_filename, 'r') my_data = numpy.loadtxt(my_file, comments='#') my_parallax_mas = my_data[:, 0] my_ell_deg = my_data[:, 1] my_b_deg = my_data[:, 2] my_hlosv_kms = my_data[:, 3] my_muellstar_masyr = my_data[:, 4] my_mub_masyr = my_data[:, 5] # count sample size my_sample_size = len(my_ell_deg) for i in range(my_sample_size): print('star ID=%d' % (i)) # convert parallax to distance distance_kpc = 1. / my_parallax_mas[i] # convert (ell, b) to (RA, DEC) RA_deg, DEC_deg = bovy_coords.lb_to_radec(my_ell_deg[i], my_b_deg[i], degree=True, epoch=_my_epoch) # heliocentric line-of-sight velocity hlosv_kms = my_hlosv_kms[i] # convert (mu_ellstar, mu_b) to (mu_RAstar, mu_DEC) muRAstar_masyr, muDEC_masyr = bovy_coords.pmllpmbb_to_pmrapmdec( my_muellstar_masyr[i], my_mub_masyr[i], my_ell_deg[i], my_b_deg[i], degree=True, epoch=_my_epoch) # create orbit instance obs_6D = Orbit(vxvv=[ RA_deg, DEC_deg, distance_kpc, muRAstar_masyr, muDEC_masyr, hlosv_kms ], radec=True, ro=_R0, vo=_V0, zo=0., solarmotion=[_Usun, _Vsun, _Wsun]) # integrate orbit in my_potential obs_6D.integrate(my_time_step, my_potential) # file on which we write 6D data at each time step outfile_i = open("t_x_y_z_vx_vy_vz_R__orbitID%03d.txt" % (i), 'w') # For illustrative purpose, I use an explicit expression to access 6D data at each time. for j in range(len(my_time_step)): # Here I assume that # (a) Galactic Center is located at (x,y)=(0,0) kpc # (b) Sun is located at (x,y)=(-8,0) kpc # (c) Nearby disc stars with circular orbits move towards (vx,vy)=(0,220) km/s # This is why I add a minus sign (-) to x and vx. x = -obs_6D.x(my_time_step[j]) y = obs_6D.y(my_time_step[j]) z = obs_6D.z(my_time_step[j]) vx = -obs_6D.vx(my_time_step[j]) vy = obs_6D.vy(my_time_step[j]) vz = obs_6D.vz(my_time_step[j]) R = obs_6D.R(my_time_step[j]) printline = '%lf %lf %lf %lf %lf %lf %lf %lf\n' % ( my_time_step[j], x, y, z, vx, vy, vz, R) outfile_i.write(printline) # close file outfile_i.close() return None
def sample(self,n,returndt=False,integrate=True,xy=False,lb=False): """ NAME: sample PURPOSE: sample from the DF INPUT: n - number of points to return returndt= (False) if True, also return the time since the star was stripped integrate= (True) if True, integrate the orbits to the present time, if False, return positions at stripping (probably want to combine with returndt=True then to make sense of them!) xy= (False) if True, return Galactocentric rectangular coordinates lb= (False) if True, return Galactic l,b,d,vlos,pmll,pmbb coordinates OUTPUT: (R,vR,vT,z,vz,phi) of points on the stream in 6,N array HISTORY: 2018-07-31 - Written - Bovy (IAS) """ if xy or lb: raise NotImplementedError("xy=True and lb=True options currently not implemented") # First sample times dt= numpy.random.uniform(size=n)*self._tdisrupt # Build all rotation matrices rot, rot_inv= self._setup_rot(dt) # Compute progenitor position in the instantaneous frame xyzpt= numpy.einsum('ijk,ik->ij',rot, numpy.array([self._progenitor.x(-dt), self._progenitor.y(-dt), self._progenitor.z(-dt)]).T) vxyzpt= numpy.einsum('ijk,ik->ij',rot, numpy.array([self._progenitor.vx(-dt), self._progenitor.vy(-dt), self._progenitor.vz(-dt)]).T) Rpt,phipt,Zpt= bovy_coords.rect_to_cyl(xyzpt[:,0],xyzpt[:,1],xyzpt[:,2]) vRpt,vTpt,vZpt= bovy_coords.rect_to_cyl_vec(vxyzpt[:,0],vxyzpt[:,1],vxyzpt[:,2], Rpt,phipt,Zpt,cyl=True) # Sample positions and velocities in the instantaneous frame k= self._meankvec+numpy.random.normal(size=n)[:,numpy.newaxis]*self._sigkvec try: rtides= rtide(self._pot,Rpt,Zpt,phi=phipt, t=-dt,M=self._progenitor_mass,use_physical=False) vcs= numpy.sqrt(-Rpt *evaluateRforces(self._pot,Rpt,Zpt,phi=phipt,t=-dt, use_physical=False)) except (ValueError,TypeError): rtides= numpy.array([rtide(self._pot,Rpt[ii],Zpt[ii],phi=phipt[ii], t=-dt[ii],M=self._progenitor_mass,use_physical=False) for ii in range(len(Rpt))]) vcs= numpy.array([numpy.sqrt(-Rpt[ii] *evaluateRforces(self._pot,Rpt[ii],Zpt[ii],phi=phipt[ii],t=-dt[ii], use_physical=False)) for ii in range(len(Rpt))]) rtides_as_frac= rtides/Rpt RpZst= numpy.array([Rpt+k[:,0]*rtides, phipt+k[:,5]*rtides_as_frac, k[:,3]*rtides_as_frac]).T vRTZst= numpy.array([vRpt*(1.+k[:,1]), vTpt+k[:,2]*vcs*rtides_as_frac, k[:,4]*vcs*rtides_as_frac]).T # Now rotate these back to the galactocentric frame xst,yst,zst= bovy_coords.cyl_to_rect(RpZst[:,0],RpZst[:,1],RpZst[:,2]) vxst,vyst,vzst= bovy_coords.cyl_to_rect_vec(vRTZst[:,0],vRTZst[:,1],vRTZst[:,2],RpZst[:,1]) xyzs= numpy.einsum('ijk,ik->ij',rot_inv,numpy.array([xst,yst,zst]).T) vxyzs= numpy.einsum('ijk,ik->ij',rot_inv,numpy.array([vxst,vyst,vzst]).T) Rs,phis,Zs= bovy_coords.rect_to_cyl(xyzs[:,0],xyzs[:,1],xyzs[:,2]) vRs,vTs,vZs= bovy_coords.rect_to_cyl_vec(vxyzs[:,0],vxyzs[:,1],vxyzs[:,2], Rs,phis,Zs,cyl=True) out= numpy.empty((6,n)) if integrate: # Now integrate the orbits for ii in range(n): o= Orbit([Rs[ii],vRs[ii],vTs[ii],Zs[ii],vZs[ii],phis[ii]]) o.integrate(numpy.linspace(-dt[ii],0.,10001),self._pot) o= o(0.) out[:,ii]= [o.R(),o.vR(),o.vT(),o.z(),o.vz(),o.phi()] else: out[0]= Rs out[1]= vRs out[2]= vTs out[3]= Zs out[4]= vZs out[5]= phis if returndt: return (out,dt) else: return out
ts = np.linspace(0, -150, 10000) mwp = MWPotential2014 #schoenrich, hogg, dehnen sun = Orbit(vxvv=[0, 0, 0, 0, 0, 0], radec=True, ro=8., vo=220., solarmotion="schoenrich") sun.integrate(ts, mwp, method='odeint') o.integrate(ts, mwp, method='odeint') ro = 8 vo = 220 #actions delta_sun = estimateDeltaStaeckel(MWPotential2014, (sun.R(ts)) / ro, (sun.z(ts)) / vo) aAS_sun = actionAngleStaeckel(pot=MWPotential2014, delta=delta_sun) js_sun = aAS_sun((sun.R()) / ro, (sun.vR()) / vo, (sun.vT()) / vo, (sun.z()) / ro, (sun.vz()) / vo) delta_o = estimateDeltaStaeckel(MWPotential2014, (o.R(ts)) / ro, (o.z(ts)) / vo) 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) js_sun = np.array(js_sun) js_o = np.array(js_o) percentage_diffs = np.absolute((js_sun - js_o)) / js_sun
RvRl, pdtl = spdf.sample(n=N, returndt=True, integrate=False) RvRt, pdtt = spdft.sample(n=N, returndt=True, integrate=False) orb_t = np.empty((6, N)) orb_l = np.empty((6, N)) for ii in range(N): ot = Orbit(RvRt[:, ii]) ot.integrate(np.linspace(-pdtt[ii], 0., 1001), barpot) ol = Orbit(RvRl[:, ii]) ol.integrate(np.linspace(-pdtl[ii], 0., 1001), barpot) ot = ot(0.) ol = ol(0.) orb_t[:, ii] = [ot.R(), ot.vR(), ot.vT(), ot.z(), ot.vz(), ot.phi()] orb_l[:, ii] = [ol.R(), ol.vR(), ol.vT(), ol.z(), ol.vz(), ol.phi()] ftrail = args.output flead = ftrail.replace('trailing', 'leading') fo_trail = open(ftrail, 'w') fo_lead = open(flead, 'w') fo_trail.write("#R phi z vR vT vz ts" + "\n") fo_lead.write("#R phi z vR vT vz ts" + "\n") for jj in range(N): fo_trail.write( str(orb_t[0][jj]) + " " + str(orb_t[5][jj]) + " " + str(orb_t[3][jj]) + " " + str(orb_t[1][jj]) + " " +
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 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
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
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
pmra_med = -510.4469988734486 pmdec_med = -110.22479327853173 rv_med = -30.41781739548299 par = np.random.normal(par_med,0.03904992068059236, size=num_samples) # [mas] ra = np.random.normal(ra_med,0.034181020450823614, size=num_samples) # [deg] dec = np.random.normal(dec_med,0.029049724029680198, size=num_samples) # [deg] pmra = np.random.normal(pmra_med,0.07061308080526092, size=num_samples) # [mas/yr] pmdec = np.random.normal(pmdec_med,0.06383967745385508, size=num_samples) # [mas/yr] rv = np.random.normal(rv_med,0.19533398113754827, size=num_samples) # km/s ts = np.linspace(0.,2.,2500.)*u.Gyr o1 = Orbit(vxvv=[ra_med,dec_med,1/par_med,pmra_med,pmdec_med,rv_med], radec=True) o1.integrate(ts, MWPotential2014) o1.plot(color='red', linewidth=1.0) for i in np.arange(num_samples): o = Orbit(vxvv=[ra[i],dec[i],1/par[i],pmra[i],pmdec[i],rv[i]], radec=True) o.integrate(ts, MWPotential2014) o.plot(color='grey', overplot=True, alpha=0.1, linewidth=0.3) plt.plot([o1.R()],[o1.z()],'b*', zorder=2, markersize=20) plt.savefig( '{}/Dropbox/Apps/Overleaf/120066/plots/galactic_orbit.png'.format(os.path.expanduser('~')), dpi=250 )
if verbose: print "Integrating orbit" o.integrate(ts, pot, method='leapfrog') if verbose: print "Saving results to data frame." if 'ra' in o_data.keys(): o_data['ra'] = o.ra(ts) if 'dec' in o_data.keys(): o_data['dec'] = o.dec(ts) if 'd' in o_data.keys(): o_data['d'] = o.dist(ts) if 'pmra' in o_data.keys(): o_data['pmra'] = o.pmra(ts) 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)
def sample_spraydf_pal5_noprog_spiral(Nsamples, spiralpot, nospiralpot=MWPotential2014, fo='blah_trailing.dat', trailing=True): 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) if trailing: spdft = streamspraydf.streamspraydf(50000. * u.Msun, progenitor=pal5, pot=nospiralpot, leading=False, tdisrupt=5. * u.Gyr) RvR, dt = spdft.sample(n=Nsamples, returndt=True, integrate=False) R = RvR[0] vR = RvR[1] vT = RvR[2] z = RvR[3] vz = RvR[4] phi = RvR[5] fo = open(fo, 'w') else: spdf = streamspraydf.streamspraydf(50000. * u.Msun, progenitor=pal5, pot=nospiralpot, tdisrupt=5. * u.Gyr) RvR, dt = spdf.sample(n=Nsamples, returndt=True, integrate=False) R = RvR[0] vR = RvR[1] vT = RvR[2] z = RvR[3] vz = RvR[4] phi = RvR[5] fo_lead = fo.replace('trailing', 'leading') fo = open(fo_lead, 'w') finalR = numpy.empty(Nsamples) finalvR = numpy.empty(Nsamples) finalvT = numpy.empty(Nsamples) finalvz = numpy.empty(Nsamples) finalphi = numpy.empty(Nsamples) finalz = numpy.empty(Nsamples) tt = numpy.empty(Nsamples) for ii in range(Nsamples): orb = Orbit([R[ii], vR[ii], vT[ii], z[ii], vz[ii], phi[ii]]) orb.turn_physical_off() ts_future = numpy.linspace(-dt[ii], 0., 1001) #forward integrate in barred potential orb.integrate(ts_future, spiralpot) finalR[ii] = orb.R(ts_future[-1]) finalphi[ii] = orb.phi(ts_future[-1]) finalz[ii] = orb.z(ts_future[-1]) finalvR[ii] = orb.vR(ts_future[-1]) finalvT[ii] = orb.vT(ts_future[-1]) finalvz[ii] = orb.vz(ts_future[-1]) tt[ii] = dt[ii] fo.write("#R phi z vR vT vz ts" + "\n") for jj in range(Nsamples): fo.write( str(finalR[jj]) + " " + str(finalphi[jj]) + " " + str(finalz[jj]) + " " + str(finalvR[jj]) + " " + str(finalvT[jj]) + " " + str(finalvz[jj]) + " " + str(tt[jj]) + "\n") fo.close() return None
def sample_streamdf_pal5_noprog_spiral(Nsamples, spiralpot, nospiralpot=MWPotential2014, fo='spiral_trailing.dat', trailing=True): if trailing: sdf_trailing = pal5_util.setup_pal5model(pot=nospiralpot) R, vR, vT, z, vz, phi, dt = sdf_trailing.sample(n=Nsamples, returndt=True) fo = open(fo, 'w') else: sdf_leading = pal5_util.setup_pal5model(pot=nospiralpot, leading=True) R, vR, vT, z, vz, phi, dt = sdf_leading.sample(n=Nsamples, returndt=True) fo_lead = fo.replace('trailing', 'leading') fo = open(fo_lead, 'w') finalR = numpy.empty(Nsamples) finalvR = numpy.empty(Nsamples) finalvT = numpy.empty(Nsamples) finalvz = numpy.empty(Nsamples) finalphi = numpy.empty(Nsamples) finalz = numpy.empty(Nsamples) tt = numpy.empty(Nsamples) for ii in range(Nsamples): o = Orbit([R[ii], vR[ii], vT[ii], z[ii], vz[ii], phi[ii]]) o.turn_physical_off() ts = numpy.linspace(0., -dt[ii], 1001) o.integrate(ts, nospiralpot) orb = Orbit([ o.R(ts[-1]), o.vR(ts[-1]), o.vT(ts[-1]), o.z(ts[-1]), o.vz(ts[-1]), o.phi(ts[-1]) ]) ts_future = numpy.linspace(-dt[ii], 0., 1001) #forward integrate in barred potential orb.integrate(ts_future, spiralpot) finalR[ii] = orb.R(ts_future[-1]) finalphi[ii] = orb.phi(ts_future[-1]) finalz[ii] = orb.z(ts_future[-1]) finalvR[ii] = orb.vR(ts_future[-1]) finalvT[ii] = orb.vT(ts_future[-1]) finalvz[ii] = orb.vz(ts_future[-1]) tt[ii] = dt[ii] fo.write("#R phi z vR vT vz ts" + "\n") for jj in range(Nsamples): fo.write( str(finalR[jj]) + " " + str(finalphi[jj]) + " " + str(finalz[jj]) + " " + str(finalvR[jj]) + " " + str(finalvT[jj]) + " " + str(finalvz[jj]) + " " + str(tt[jj]) + "\n") fo.close() return None