def setup_sdf(pot,prog,sigv,td,ro,vo,multi=None,nTrackChunks=8,isob=None, trailing_only=False,verbose=True,useTM=True,logpot=False): """Simple function to setup the stream model""" if isob is None: if True or logpot: isob= 0.75 if False: # Determine good one ts= numpy.linspace(0.,15.,1001) # Hack! epot= copy.deepcopy(pot) epot[2]._b= 1. epot[2]._b2= 1. 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 numpy.fabs(pot[2]._b-1.) > 0.05: aAI= actionAngleIsochroneApprox(pot=pot,b=isob,tintJ=1000., ntintJ=30000) else: ts= numpy.linspace(0.,100.,10000) aAI= actionAngleIsochroneApprox(pot=pot,b=isob,tintJ=100., 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.,7.25], custom_transform=_TKOP, multi=multi, nospreadsetup=True) except numpy.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.,7.25], custom_transform=_TKOP, multi=multi) return sdf
def setup_gd1model(leading=True, timpact=None, hernquist=True, age=9., singleImpact=False, length_factor=1., **kwargs): lp = LogarithmicHaloPotential(normalize=1., q=0.9) aAI = actionAngleIsochroneApprox(pot=lp, b=0.8) obs = Orbit([ 1.56148083, 0.35081535, -1.15481504, 0.88719443, -0.47713334, 0.12019596 ]) sigv = 0.365 / 2. * (9. / age) #km/s, /2 bc tdis x2, adjust for diff. age if timpact is None: sdf = streamdf(sigv / 220., progenitor=obs, pot=lp, aA=aAI, leading=leading, nTrackChunks=11, tdisrupt=age / bovy_conversion.time_in_Gyr(V0, R0), Vnorm=V0, Rnorm=R0) elif singleImpact: sdf = streamgapdf(sigv / 220., progenitor=obs, pot=lp, aA=aAI, leading=leading, nTrackChunks=11, tdisrupt=age / bovy_conversion.time_in_Gyr(V0, R0), Vnorm=V0, Rnorm=R0, timpact=timpact, spline_order=3, hernquist=hernquist, **kwargs) else: sdf = streampepperdf(sigv / 220., progenitor=obs, pot=lp, aA=aAI, leading=leading, nTrackChunks=101, tdisrupt=age / bovy_conversion.time_in_Gyr(V0, R0), Vnorm=V0, Rnorm=R0, timpact=timpact, spline_order=1, hernquist=hernquist, length_factor=length_factor) sdf.turn_physical_off() return sdf
def setup_phxmodel(leading=False, timpact=None, hernquist=True, age=1.5, singleImpact=False, length_factor=1., obs = obs, sigvmod = .23, progIsTrack=False, **kwargs): #obs= Orbit([229.018,-0.124,23.2,-2.296,-2.257,-58.7], # radec=True,ro=R0,vo=V0, # solarmotion=[-11.1,24.,7.25]) aAI= actionAngleIsochroneApprox(pot=MWPotential2014,b=0.8458) sigv= sigvmod*(5./age) #km/s, adjust for diff. age if timpact is None: sdf= streamdf(sigv/V0,progenitor=obs, pot=MWPotential2014,aA=aAI, leading=leading,nTrackChunks=11, progIsTrack=progIsTrack, tdisrupt=age/bovy_conversion.time_in_Gyr(V0,R0), ro=R0,vo=V0,R0=R0, vsun=[-11.1,V0+24.,7.25],**kwargs) elif singleImpact: sdf= streamgapdf(sigv/V0,progenitor=obs, pot=MWPotential2014,aA=aAI, leading=leading,nTrackChunks=11, tdisrupt=age/bovy_conversion.time_in_Gyr(V0,R0), ro=R0,vo=V0,R0=R0, vsun=[-11.1,V0+24.,7.25], timpact= 0.3/bovy_conversion.time_in_Gyr(V0,R0), spline_order=3, hernquist=hernquist, impact_angle=0.7, impactb=0., GM= 10.**-2./bovy_conversion.mass_in_1010msol(V0,R0), rs= 0.625/R0, subhalovel=np.array([6.82200571,132.7700529,14.4174464])/V0, **kwargs) else: sdf= streampepperdf(sigv/V0,progenitor=obs, pot=MWPotential2014,aA=aAI, leading=leading,nTrackChunks=101, tdisrupt=age/bovy_conversion.time_in_Gyr(V0,R0), ro=R0,vo=V0,R0=R0, vsun=[-11.1,V0+24.,7.25], timpact=timpact, spline_order=1, hernquist=hernquist, length_factor=length_factor) sdf.turn_physical_off() return sdf
def test_sanders15_setup(): #Imports from galpy.df import streamdf, streamgapdf from galpy.orbit import Orbit from galpy.potential import LogarithmicHaloPotential from galpy.actionAngle import actionAngleIsochroneApprox from galpy.util import bovy_conversion #for unit conversions lp= LogarithmicHaloPotential(normalize=1.,q=0.9) aAI= actionAngleIsochroneApprox(pot=lp,b=0.8) prog_unp_peri= Orbit([2.6556151742081835, 0.2183747276300308, 0.67876510797240575, -2.0143395648974671, -0.3273737682604374, 0.24218273922966019]) global sdf_sanders15 V0, R0= 220., 8. sigv= 0.365*(10./2.)**(1./3.) # km/s sdf_sanders15= streamgapdf(sigv/V0,progenitor=prog_unp_peri,pot=lp,aA=aAI, leading=False,nTrackChunks=26, nTrackIterations=1, sigMeanOffset=4.5, tdisrupt=10.88\ /bovy_conversion.time_in_Gyr(V0,R0), Vnorm=V0,Rnorm=R0, impactb=0., subhalovel=numpy.array([6.82200571,132.7700529, 149.4174464])/V0, timpact=0.88/bovy_conversion.time_in_Gyr(V0,R0), impact_angle=-2.34, GM=10.**-2.\ /bovy_conversion.mass_in_1010msol(V0,R0), rs=0.625/R0) assert not sdf_sanders15 is None, 'sanders15 streamgapdf setup did not work' # Also setup the unperturbed model global sdf_sanders15_unp sdf_sanders15_unp= streamdf(sigv/V0,progenitor=prog_unp_peri,pot=lp,aA=aAI, leading=False,nTrackChunks=26, nTrackIterations=1, sigMeanOffset=4.5, tdisrupt=10.88\ /bovy_conversion.time_in_Gyr(V0,R0), Vnorm=V0,Rnorm=R0) assert not sdf_sanders15_unp is None, \ 'sanders15 unperturbed streamdf setup did not work' return None
def test_sanders15_setup(): #Imports from galpy.df import streamdf, streamgapdf from galpy.orbit import Orbit from galpy.potential import LogarithmicHaloPotential from galpy.actionAngle import actionAngleIsochroneApprox from galpy.util import conversion #for unit conversions lp = LogarithmicHaloPotential(normalize=1., q=0.9) aAI = actionAngleIsochroneApprox(pot=lp, b=0.8) prog_unp_peri = Orbit([ 2.6556151742081835, 0.2183747276300308, 0.67876510797240575, -2.0143395648974671, -0.3273737682604374, 0.24218273922966019 ]) global sdf_sanders15 V0, R0 = 220., 8. sigv = 0.365 * (10. / 2.)**(1. / 3.) # km/s sdf_sanders15= streamgapdf(sigv/V0,progenitor=prog_unp_peri,pot=lp,aA=aAI, leading=False,nTrackChunks=26, nTrackIterations=1, sigMeanOffset=4.5, tdisrupt=10.88\ /conversion.time_in_Gyr(V0,R0), Vnorm=V0,Rnorm=R0, impactb=0., subhalovel=numpy.array([6.82200571,132.7700529, 149.4174464])/V0, timpact=0.88/conversion.time_in_Gyr(V0,R0), impact_angle=-2.34, GM=10.**-2.\ /conversion.mass_in_1010msol(V0,R0), rs=0.625/R0) assert not sdf_sanders15 is None, 'sanders15 streamgapdf setup did not work' # Also setup the unperturbed model global sdf_sanders15_unp sdf_sanders15_unp= streamdf(sigv/V0,progenitor=prog_unp_peri,pot=lp,aA=aAI, leading=False,nTrackChunks=26, nTrackIterations=1, sigMeanOffset=4.5, tdisrupt=10.88\ /conversion.time_in_Gyr(V0,R0), Vnorm=V0,Rnorm=R0) assert not sdf_sanders15_unp is None, \ 'sanders15 unperturbed streamdf setup did not work' return None
def setup_pal5model(leading=False, timpact=None, hernquist=True, age=5., singleImpact=False, length_factor=1., **kwargs): obs= Orbit([229.018,-0.124,23.2,-2.296,-2.257,-58.7], radec=True,ro=R0,vo=V0, solarmotion=[-11.1,24.,7.25]) aAI= actionAngleIsochroneApprox(pot=MWPotential2014,b=0.8) sigv= 0.5*(5./age) #km/s, adjust for diff. age if timpact is None: sdf= streamdf(sigv/V0,progenitor=obs, pot=MWPotential2014,aA=aAI, leading=leading,nTrackChunks=11, tdisrupt=age/bovy_conversion.time_in_Gyr(V0,R0), Rnorm=R0,Vnorm=V0,R0=R0, vsun=[-11.1,V0+24.,7.25], custom_transform=_TPAL5) elif singleImpact: sdf= streamgapdf(sigv/V0,progenitor=obs, pot=MWPotential2014,aA=aAI, leading=leading,nTrackChunks=11, tdisrupt=age/bovy_conversion.time_in_Gyr(V0,R0), Rnorm=R0,Vnorm=V0,R0=R0, vsun=[-11.1,V0+24.,7.25], custom_transform=_TPAL5, timpact=timpact, spline_order=3, hernquist=hernquist,**kwargs) else: sdf= streampepperdf(sigv/V0,progenitor=obs, pot=MWPotential2014,aA=aAI, leading=leading,nTrackChunks=101, tdisrupt=age/bovy_conversion.time_in_Gyr(V0,R0), Rnorm=R0,Vnorm=V0,R0=R0, vsun=[-11.1,V0+24.,7.25], custom_transform=_TPAL5, timpact=timpact, spline_order=1, hernquist=hernquist, length_factor=length_factor) return sdf
def setup_gd1model(leading=True, timpact=None, hernquist=True, age=9., singleImpact=False, length_factor=1., **kwargs): lp= LogarithmicHaloPotential(normalize=1.,q=0.9) aAI= actionAngleIsochroneApprox(pot=lp,b=0.8) obs= Orbit([1.56148083,0.35081535,-1.15481504,0.88719443, -0.47713334,0.12019596]) sigv= 0.365/2.*(9./age) #km/s, /2 bc tdis x2, adjust for diff. age if timpact is None: sdf= streamdf(sigv/220.,progenitor=obs,pot=lp,aA=aAI,leading=leading, nTrackChunks=11, tdisrupt=age/bovy_conversion.time_in_Gyr(V0,R0), Vnorm=V0,Rnorm=R0) elif singleImpact: sdf= streamgapdf(sigv/220.,progenitor=obs,pot=lp,aA=aAI, leading=leading, nTrackChunks=11, tdisrupt=age/bovy_conversion.time_in_Gyr(V0,R0), Vnorm=V0,Rnorm=R0, timpact=timpact, spline_order=3, hernquist=hernquist,**kwargs) else: sdf= streampepperdf(sigv/220.,progenitor=obs,pot=lp,aA=aAI, leading=leading, nTrackChunks=101, tdisrupt=age/bovy_conversion.time_in_Gyr(V0,R0), Vnorm=V0,Rnorm=R0, timpact=timpact, spline_order=1, hernquist=hernquist, length_factor=length_factor) return sdf
def setup_gd1model(leading=True, pot=MWPotential2014, timpact=None, hernquist=True, age=9., singleImpact=False, length_factor=1., **kwargs): #lp= LogarithmicHaloPotential(normalize=1.,q=0.9) aAI = actionAngleIsochroneApprox(pot=pot, b=0.8) #obs= Orbit([1.56148083,0.35081535,-1.15481504,0.88719443, # -0.47713334,0.12019596]) #progenitor pos and vel from Bovy 1609.01298 and with corrected proper motion obs = Orbit(phi12_to_lb_6d(0, -0.82, 10.1, -8.5, -2.15, -257.), lb=True, solarmotion=[-11.1, 24., 7.25], ro=8., vo=220.) sigv = 0.365 / 2. * (9. / age) #km/s, /2 bc tdis x2, adjust for diff. age if timpact is None: sdf = streamdf(sigv / 220., progenitor=obs, pot=pot, aA=aAI, leading=leading, nTrackChunks=11, vsun=[-11.1, 244., 7.25], tdisrupt=age / bovy_conversion.time_in_Gyr(V0, R0), Vnorm=V0, Rnorm=R0) elif singleImpact: sdf = streamgapdf(sigv / 220., progenitor=obs, pot=pot, aA=aAI, leading=leading, nTrackChunks=11, vsun=[-11.1, 244., 7.25], tdisrupt=age / bovy_conversion.time_in_Gyr(V0, R0), Vnorm=V0, Rnorm=R0, timpact=timpact, spline_order=3, hernquist=hernquist, **kwargs) else: sdf = streampepperdf(sigv / 220., progenitor=obs, pot=pot, aA=aAI, leading=leading, nTrackChunks=101, vsun=[-11.1, 244., 7.25], tdisrupt=age / bovy_conversion.time_in_Gyr(V0, R0), Vnorm=V0, Rnorm=R0, timpact=timpact, spline_order=1, hernquist=hernquist, length_factor=length_factor) #sdf.turn_physical_off() #original obs.turn_physical_off() return sdf
def test_sanders15_leading_setup(): #Imports from galpy.df import streamdf, streamgapdf from galpy.orbit import Orbit from galpy.potential import LogarithmicHaloPotential, PlummerPotential from galpy.actionAngle import actionAngleIsochroneApprox from galpy.util import bovy_conversion #for unit conversions lp= LogarithmicHaloPotential(normalize=1.,q=0.9) aAI= actionAngleIsochroneApprox(pot=lp,b=0.8) prog_unp_peri= Orbit([2.6556151742081835, 0.2183747276300308, 0.67876510797240575, -2.0143395648974671, -0.3273737682604374, 0.24218273922966019]) global sdfl_sanders15 V0, R0= 220., 8. sigv= 0.365*(10./2.)**(1./3.) # km/s # Use a Potential object for the impact pp= PlummerPotential(amp=10.**-2.\ /bovy_conversion.mass_in_1010msol(V0,R0), b=0.625/R0) import warnings from galpy.util import galpyWarning with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always",galpyWarning) sdfl_sanders15= streamgapdf(sigv/V0,progenitor=prog_unp_peri, pot=lp,aA=aAI, leading=True,nTrackChunks=26, nTrackChunksImpact=29, nTrackIterations=1, sigMeanOffset=4.5, tdisrupt=10.88\ /bovy_conversion.time_in_Gyr(V0,R0), Vnorm=V0,Rnorm=R0, impactb=0., subhalovel=numpy.array([49.447319, 116.179436, 155.104156])/V0, timpact=0.88/bovy_conversion.time_in_Gyr(V0,R0), impact_angle=2.09, subhalopot=pp, nKickPoints=290, deltaAngleTrackImpact=4.5, multi=True) # test multi # Should raise warning bc of deltaAngleTrackImpact, might raise others raisedWarning= False for wa in w: raisedWarning= (str(wa.message) == "WARNING: deltaAngleTrackImpact angle range large compared to plausible value") if raisedWarning: break assert raisedWarning, 'deltaAngleTrackImpact warning not raised when it should have been' assert not sdfl_sanders15 is None, 'sanders15 trailing streamdf setup did not work' # Also setup the unperturbed model global sdfl_sanders15_unp sdfl_sanders15_unp= streamdf(sigv/V0,progenitor=prog_unp_peri, pot=lp,aA=aAI, leading=True,nTrackChunks=26, nTrackIterations=1, sigMeanOffset=4.5, tdisrupt=10.88\ /bovy_conversion.time_in_Gyr(V0,R0), Vnorm=V0,Rnorm=R0) assert not sdfl_sanders15_unp is None, \ 'sanders15 unperturbed streamdf setup did not work' return None
def setup_pal5model(leading=False, pot=MWPotential2014, orb=[229.018, -0.124, 23.2, -2.296, -2.257, -58.7], timpact=None, b=0.8, hernquist=True, age=5., singleImpact=False, length_factor=1., **kwargs): obs = Orbit(orb, radec=True, ro=R0, vo=V0, solarmotion=[-11.1, 24., 7.25]) aAI = actionAngleIsochroneApprox(pot=pot, b=b) sigv = 0.5 * (5. / age) #km/s, adjust for diff. age if timpact is None: sdf = streamdf(sigv / V0, progenitor=obs, pot=pot, aA=aAI, leading=leading, nTrackChunks=11, tdisrupt=age / bovy_conversion.time_in_Gyr(V0, R0), Rnorm=R0, Vnorm=V0, R0=R0, vsun=[-11.1, V0 + 24., 7.25], custom_transform=_TPAL5) elif singleImpact: sdf = streamgapdf(sigv / V0, progenitor=obs, pot=pot, aA=aAI, leading=leading, nTrackChunks=11, tdisrupt=age / bovy_conversion.time_in_Gyr(V0, R0), Rnorm=R0, Vnorm=V0, R0=R0, vsun=[-11.1, V0 + 24., 7.25], custom_transform=_TPAL5, timpact=timpact, spline_order=3, hernquist=hernquist, **kwargs) else: sdf = streampepperdf(sigv / V0, progenitor=obs, pot=pot, aA=aAI, leading=leading, nTrackChunks=101, tdisrupt=age / bovy_conversion.time_in_Gyr(V0, R0), Rnorm=R0, Vnorm=V0, R0=R0, vsun=[-11.1, V0 + 24., 7.25], custom_transform=_TPAL5, timpact=timpact, spline_order=1, hernquist=hernquist, length_factor=length_factor) sdf.turn_physical_off() return sdf
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, pot=pot, aA=aAI, leading=False, nTrackChunks=11, tdisrupt=10.0 / bovy_conversion.time_in_Gyr(REFV0, REFR0), ro=REFR0, vo=REFV0, R0=REFR0, vsun=[-11.1, REFV0 + 24.0, 7.25], custom_transform=pal5_util._TPAL5, ) with open("output/sdf_trailing.pkl", "wb") as file: pickle.dump(sdf_trailing, file) try: with open("output/sdf_leading.pkl", "rb") as file: sdf_leading = pickle.load(file) except Exception: sdf_leading = streamdf( sigv / REFV0,
def fiducial_model( sdf_trailing="output/sdf_trailing.pkl", sdf_leading="output/sdf_leading.pkl", threshold=0.3, ro=REFR0, vo=REFV0, ): """Fiducial Model. The fiducial model assumes a spherical halo, with the best-fit parameters from fitting to the MWPotential2014 data """ p_b15 = [ 0.60122692, 0.36273147, -0.97591502, -3.34169377, 0.71877924, -0.01519337, -0.01928001, ] pot = mw_pot.setup_potential(p_b15, 1.0, False, False, ro, vo) prog = Orbit( [229.018, -0.124, 23.2, -2.296, -2.257, -58.7], radec=True, ro=ro, vo=vo, solarmotion=[-11.1, 24.0, 7.25], ) aAI = actionAngleIsochroneApprox(pot=pot, b=0.8) sigv = 0.2 # ---------------------------------------------------------- try: with open(sdf_trailing, "rb") as file: sdf_trailing = pickle.load(file) except Exception: sdf_trailing = streamdf( sigv / vo, progenitor=prog, pot=pot, aA=aAI, leading=False, nTrackChunks=11, tdisrupt=10.0 / bovy_conversion.time_in_Gyr(vo, ro), ro=ro, vo=vo, R0=ro, vsun=[-11.1, vo + 24.0, 7.25], custom_transform=pal5_util._TPAL5, ) with open(sdf_trailing, "wb") as file: pickle.dump(sdf_trailing, file) try: with open(sdf_leading, "rb") as file: sdf_leading = pickle.load(file) except Exception: sdf_leading = streamdf( sigv / vo, progenitor=prog, pot=pot, aA=aAI, leading=True, nTrackChunks=11, tdisrupt=10.0 / bovy_conversion.time_in_Gyr(vo, ro), ro=ro, vo=vo, R0=ro, vsun=[-11.1, vo + 24.0, 7.25], custom_transform=pal5_util._TPAL5, ) with open(sdf_leading, "wb") as file: pickle.dump(sdf_leading, file) # ---------------------------------------------------------- print("Angular length: %f deg (leading,trailing)=(%f,%f) deg" % ( sdf_leading.length(ang=True, coord="customra", threshold=threshold) + sdf_trailing.length(ang=True, coord="customra", threshold=threshold), sdf_leading.length(ang=True, coord="customra", threshold=threshold), sdf_trailing.length(ang=True, coord="customra", threshold=threshold), )) print("Angular width (FWHM): %f arcmin" % (pal5_util.width_trailing(sdf_trailing))) print("Velocity dispersion: %f km/s" % (pal5_util.vdisp_trailing(sdf_trailing))) # ---------------------------------------------------------- trackRADec_trailing = bovy_coords.lb_to_radec( sdf_trailing._interpolatedObsTrackLB[:, 0], sdf_trailing._interpolatedObsTrackLB[:, 1], degree=True, ) trackRADec_leading = bovy_coords.lb_to_radec( sdf_leading._interpolatedObsTrackLB[:, 0], sdf_leading._interpolatedObsTrackLB[:, 1], degree=True, ) lb_sample_trailing = sdf_trailing.sample(n=10000, lb=True) lb_sample_leading = sdf_leading.sample(n=10000, lb=True) radec_sample_trailing = bovy_coords.lb_to_radec(lb_sample_trailing[0], lb_sample_trailing[1], degree=True) radec_sample_leading = bovy_coords.lb_to_radec(lb_sample_leading[0], lb_sample_leading[1], degree=True) # ---------------------------------------------------------- # plotting plt.figure(figsize=(12, 4)) plt.subplot(1, 2, 1) bovy_plot.bovy_plot( trackRADec_trailing[:, 0], trackRADec_trailing[:, 1], color=sns.color_palette()[0], xrange=[250.0, 210.0], yrange=[-15.0, 9.0], xlabel=r"$\mathrm{RA}\,(\mathrm{degree})$", ylabel=r"$\mathrm{Dec}\,(\mathrm{degree})$", gcf=True, ) bovy_plot.bovy_plot( trackRADec_leading[:, 0], trackRADec_leading[:, 1], color=sns.color_palette()[0], overplot=True, ) plt.plot( radec_sample_trailing[:, 0], radec_sample_trailing[:, 1], "k.", alpha=0.01, zorder=0, ) plt.plot( radec_sample_leading[:, 0], radec_sample_leading[:, 1], "k.", alpha=0.01, zorder=0, ) plt.errorbar( pos_radec[:, 0], pos_radec[:, 1], yerr=pos_radec[:, 2], ls="none", marker="o", color=sns.color_palette()[2], ) plt.subplot(1, 2, 2) bovy_plot.bovy_plot( trackRADec_trailing[:, 0], sdf_trailing._interpolatedObsTrackLB[:, 3], color=sns.color_palette()[0], xrange=[250.0, 210.0], yrange=[-80.0, 0.0], xlabel=r"$\mathrm{RA}\,(\mathrm{degree})$", ylabel=r"$V_{\mathrm{los}}\,(\mathrm{km\,s}^{-1})$", gcf=True, ) bovy_plot.bovy_plot( trackRADec_leading[:, 0], sdf_leading._interpolatedObsTrackLB[:, 3], color=sns.color_palette()[0], overplot=True, ) plt.plot( radec_sample_trailing[:, 0], lb_sample_trailing[3], "k.", alpha=0.01, zorder=0, ) plt.plot( radec_sample_leading[:, 0], lb_sample_leading[3], "k.", alpha=0.01, zorder=0, ) plt.errorbar( rvel_ra[:, 0], rvel_ra[:, 1], yerr=rvel_ra[:, 2], ls="none", marker="o", color=sns.color_palette()[2], ) plt.savefig("figures/fiducial_model.pdf") return
def setup_streammodel( obs=None, pot = MWPotential2014, leading=False, timpact=None, hernquist=True, age=5., sigv=.5, singleImpact=False, length_factor=1., vsun=[-11.1,V0+24.,7.25], b=None, **kwargs): ''' NAME: setup_streammodel PURPOSE: Initialize a streamdf or streampepperdf instance of stellar stream, depending on its impact history INPUT: obs: Orbit instance for progenitor position pot: host potential age: stream age in Gyr sigv: ~ internal velocity dispersion in km/s, controls the stream length in proportion to the age b: fit parameter for the isochrone approximation, if None it is set automatically R, R_coord: R_name: a rotation matrix for transformation to stream coordinates,the frame they are transforming from, and a name for the new coordinate system custom_transform: depreciated, superseded by the Astropy implementation below leading: if True, use leading tail, use trailing tail otherwise hernquist: if True, use Hernquist spheres for subhalos; Plummer otherwise singleImpact: force use of the streamgapdf instead of streampepperdf length_factor: consider impacts up to length_factor x length of the stream streamdf kwargs OUTPUT: object HISTORY: 2016 - Started - Bovy (UofT) 2020-05-08 - Generalized - Hendel (UofT) ''' #automatically set up potential model if b==None: obs.turn_physical_off() b = estimateBIsochrone(pot, obs.R(), obs.z()) obs.turn_physical_on() print('Using isochrone approxmation parameter of %1.3f, should typically be between 0.5 and 1'%b) aAI= actionAngleIsochroneApprox(pot=pot,b=b) if timpact is None: sdf= streamdf(sigv/V0,progenitor=obs, pot=pot,aA=aAI, leading=leading,nTrackChunks=11, tdisrupt=age/bovy_conversion.time_in_Gyr(V0,R0), ro=R0,vo=V0,R0=R0, vsun=vsun, custom_transform=None) elif singleImpact: sdf= streamgapdf(sigv/V0,progenitor=obs, pot=pot,aA=aAI, leading=leading,nTrackChunks=11, tdisrupt=age/bovy_conversion.time_in_Gyr(V0,R0), ro=R0,vo=V0,R0=R0, vsun=vsun, custom_transform=None, timpact= 0.3/bovy_conversion.time_in_Gyr(V0,R0), spline_order=3, hernquist=hernquist, impact_angle=0.7, impactb=0., GM= 10.**-2./bovy_conversion.mass_in_1010msol(V0,R0), rs= 0.625/R0, subhalovel=np.array([6.82200571,132.7700529,14.4174464])/V0, **kwargs) else: sdf= streampepperdf(sigv/V0,progenitor=obs, pot=pot,aA=aAI, leading=leading,nTrackChunks=101, tdisrupt=age/bovy_conversion.time_in_Gyr(V0,R0), ro=R0,vo=V0,R0=R0, vsun=vsun, custom_transform=None, timpact=timpact, spline_order=3, hernquist=hernquist, length_factor=length_factor) sdf.turn_physical_off() return sdf
def test_sanders15_leading_setup(): #Imports from galpy.df import streamdf, streamgapdf from galpy.orbit import Orbit from galpy.potential import LogarithmicHaloPotential, PlummerPotential from galpy.actionAngle import actionAngleIsochroneApprox from galpy.util import conversion #for unit conversions lp = LogarithmicHaloPotential(normalize=1., q=0.9) aAI = actionAngleIsochroneApprox(pot=lp, b=0.8) prog_unp_peri = Orbit([ 2.6556151742081835, 0.2183747276300308, 0.67876510797240575, -2.0143395648974671, -0.3273737682604374, 0.24218273922966019 ]) global sdfl_sanders15 V0, R0 = 220., 8. sigv = 0.365 * (10. / 2.)**(1. / 3.) # km/s # Use a Potential object for the impact pp= PlummerPotential(amp=10.**-2.\ /conversion.mass_in_1010msol(V0,R0), b=0.625/R0) import warnings from galpy.util import galpyWarning with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always", galpyWarning) sdfl_sanders15= streamgapdf(sigv/V0,progenitor=prog_unp_peri, pot=lp,aA=aAI, leading=True,nTrackChunks=26, nTrackChunksImpact=29, nTrackIterations=1, sigMeanOffset=4.5, tdisrupt=10.88\ /conversion.time_in_Gyr(V0,R0), Vnorm=V0,Rnorm=R0, impactb=0., subhalovel=numpy.array([49.447319, 116.179436, 155.104156])/V0, timpact=0.88/conversion.time_in_Gyr(V0,R0), impact_angle=2.09, subhalopot=pp, nKickPoints=290, deltaAngleTrackImpact=4.5, multi=True) # test multi # Should raise warning bc of deltaAngleTrackImpact, might raise others raisedWarning = False for wa in w: raisedWarning = ( str(wa.message) == "WARNING: deltaAngleTrackImpact angle range large compared to plausible value" ) if raisedWarning: break assert raisedWarning, 'deltaAngleTrackImpact warning not raised when it should have been' assert not sdfl_sanders15 is None, 'sanders15 trailing streamdf setup did not work' # Also setup the unperturbed model global sdfl_sanders15_unp sdfl_sanders15_unp= streamdf(sigv/V0,progenitor=prog_unp_peri, pot=lp,aA=aAI, leading=True,nTrackChunks=26, nTrackIterations=1, sigMeanOffset=4.5, tdisrupt=10.88\ /conversion.time_in_Gyr(V0,R0), Vnorm=V0,Rnorm=R0) assert not sdfl_sanders15_unp is None, \ 'sanders15 unperturbed streamdf setup did not work' return None
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 setup_mockgd1model(leading=True, pot=MWPotential2014, timpact=None, Zsun=0.025, hernquist=True, isob=0.8, age=9., sigv=0.46, singleImpact=False, length_factor=1., **kwargs): aAI = actionAngleIsochroneApprox(pot=pot, b=isob) obs = Orbit.from_name("GD1") if timpact is None: sdf = streamdf(sigv / 220., progenitor=obs, pot=pot, aA=aAI, leading=leading, nTrackChunks=11, vsun=[-11.1, 244., 7.25], Zsun=Zsun, tdisrupt=age / conversion.time_in_Gyr(V0, R0), vo=V0, ro=R0) elif singleImpact: sdf = streamgapdf(sigv / 220., progenitor=obs, pot=pot, aA=aAI, leading=leading, nTrackChunks=11, vsun=[-11.1, 244., 7.25], Zsun=Zsun, tdisrupt=age / conversion.time_in_Gyr(V0, R0), vo=V0, ro=R0, timpact=timpact, spline_order=3, hernquist=hernquist, **kwargs) else: sdf = streampepperdf(sigv / 220., progenitor=obs, pot=pot, aA=aAI, leading=leading, nTrackChunks=101, vsun=[-11.1, 244., 7.25], Zsun=Zsun, tdisrupt=age / conversion.time_in_Gyr(V0, R0), vo=V0, ro=R0, timpact=timpact, spline_order=1, hernquist=hernquist, length_factor=length_factor) sdf.turn_physical_off() #original #obs.turn_physical_off() return sdf
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