def make_nondefault_pal5stream(chain_ind,leading=False,timpact=None,b=0.8,hernquist=False,td=5.): orb,pot,sigv,tvo=set_prog_potential(chain_ind) try : sdf= pal5_util.setup_pal5model_MWfit(ro=_REFR0,vo=tvo,timpact=timpact,pot=pot,orb=orb,hernquist=hernquist,leading=leading,age=td,sigv=sigv) except numpy.linalg.LinAlgError: print ("using estimateBIsochrone") ts= numpy.linspace(0.,td,1001)/bovy_conversion.time_in_Gyr(_REFV0, _REFR0) prog = Orbit(orb,radec=True,ro=_REFR0,vo=tvo,solarmotion=[-11.1,24.,7.25]) prog.integrate(ts,pot) estb= estimateBIsochrone(pot,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] print ("b=%f"%isob) sdf=pal5_util.setup_pal5model_MWfit(ro=_REFR0,vo=tvo,leading=leading,pot=pot,orb=orb,timpact=timpact,b=isob,hernquist=hernquist,age=td,sigv=sigv) return sdf
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 plot_aaspher_conservation(plotfilename1,plotfilename2): #Setup orbit E, Lz= -1.25, 0.6 o= Orbit([0.8,0.3,Lz/0.8,0.,numpy.sqrt(2.*(E-evalPot(0.8,0.,MWPotential2014)-(Lz/0.8)**2./2.-0.3**2./2.)),0.]) #Integrate the orbit to estimate an equivalent b nt= 1001 ts= numpy.linspace(0.,20.,nt) o.integrate(ts,MWPotential2014,method='symplec4_c') b= estimateBIsochrone(o.R(ts),o.z(ts),pot=MWPotential2014) print b b= 0.3 #Now integrate the orbit in the isochronePotential ip= IsochronePotential(normalize=1.,b=b) aAI= actionAngleIsochrone(ip=ip) orbt= 2.*numpy.pi/aAI.actionsFreqs(o)[4] norb= 200. nt= 20001 ts= numpy.linspace(0.,norb*orbt,nt) o.integrate(ts,ip,method='symplec4_c') #Calculate actions, frequencies, and angles jfa= aAI.actionsFreqsAngles(o.R(ts),o.vR(ts),o.vT(ts), o.z(ts),o.vz(ts),o.phi(ts)) dJs= numpy.fabs((jfa[0]-numpy.mean(jfa[0]))/numpy.mean(jfa[0])) dOrs= numpy.fabs((jfa[3]-numpy.mean(jfa[3]))/numpy.mean(jfa[3])) dOzs= numpy.fabs((jfa[5]-numpy.mean(jfa[5]))/numpy.mean(jfa[5])) print "frequencies", numpy.mean(dOrs), numpy.mean(dOzs) ar= dePeriod(numpy.reshape(jfa[6],(1,len(ts)))).flatten() az= dePeriod(numpy.reshape(jfa[8],(1,len(ts)))).flatten() danglers= numpy.fabs(ar-numpy.mean(jfa[3])*ts-jfa[6][0])/2./numpy.pi danglezs= numpy.fabs(az-numpy.mean(jfa[5])*ts-jfa[8][0])/2./numpy.pi #Break up breakt= 50. pts= parse_break(ts,ts < breakt) pdJs= parse_break(dJs,ts < breakt) pdanglers= parse_break(danglers,ts < breakt) pdanglezs= parse_break(danglezs,ts < breakt) #dAngles bovy_plot.bovy_print() pyplot.subplot(2,1,1) bovy_plot.bovy_plot(pts/orbt, pdJs, color='k',loglog=True,gcf=True, xrange=[0.5,norb], yrange=[10.**-12.,1.]) bovy_plot.bovy_text(r'$\texttt{actionAngleIsochrone}$', top_left=True,size=14.) ax= pyplot.gca() ax.yaxis.set_ticks([10.**-12.,10.**-8.,10.**-4.,1.]) nullfmt = NullFormatter() # no labels ax.xaxis.set_major_formatter(nullfmt) #Same for actionAngleSpherical aAS= actionAngleSpherical(pot=ip) tts= ts[::1] jfa= aAS.actionsFreqsAngles(o.R(tts),o.vR(tts),o.vT(tts), o.z(tts),o.vz(tts),o.phi(tts), fixed_quad=True) #dJr dJs= numpy.fabs((jfa[0]-numpy.mean(jfa[0]))/numpy.mean(jfa[0])) dOrs= numpy.fabs((jfa[3]-numpy.mean(jfa[3]))/numpy.mean(jfa[3])) dOzs= numpy.fabs((jfa[5]-numpy.mean(jfa[5]))/numpy.mean(jfa[5])) print "frequencies", numpy.mean(dOrs), numpy.mean(dOzs) #dAngles ar= dePeriod(numpy.reshape(jfa[6],(1,len(tts)))).flatten() az= dePeriod(numpy.reshape(jfa[8],(1,len(tts)))).flatten() danglers= numpy.fabs(ar-numpy.mean(jfa[3])*tts-jfa[6][0])/2./numpy.pi danglezs= numpy.fabs(az-numpy.mean(jfa[5])*tts-jfa[8][0])/2./numpy.pi print numpy.mean(danglers) print numpy.mean(danglezs) ptts= parse_break(tts,tts < breakt) pdJs= parse_break(dJs,tts < breakt) pyplot.subplot(2,1,2) bovy_plot.bovy_plot(ptts/orbt, pdJs, color='k',loglog=True,gcf=True, xrange=[0.5,norb], yrange=[10.**-12.,1.], xlabel=r'$\mathrm{Number\ of\ orbital\ periods}$') bovy_plot.bovy_text(r'$\texttt{actionAngleSpherical}$', top_left=True,size=14.) bovy_plot.bovy_text(0.175,10.**2.,r'$\left|\Delta J_R / J_R\right|$', fontsize=16., rotation='vertical') ax= pyplot.gca() ax.xaxis.set_major_formatter(ticker.FormatStrFormatter(r'$%0.f$')) ax.yaxis.set_ticks([10.**-12.,10.**-8.,10.**-4.,1.]) bovy_plot.bovy_end_print(plotfilename1) #Now plot the deviations in the angles bovy_plot.bovy_print() pyplot.subplot(2,1,1) liner= bovy_plot.bovy_plot(pts/orbt, pdanglers, color='k',ls='-',loglog=True,gcf=True, xrange=[0.5,norb], yrange=[10.**-12.,1.]) linez= bovy_plot.bovy_plot(pts/orbt, pdanglezs, color='k',ls='--',overplot=True) legend1= pyplot.legend((liner[0],linez[0]), (r'$\theta_R$', r'$\theta_z$'), loc='lower right',#bbox_to_anchor=(.91,.375), numpoints=2, prop={'size':14}, frameon=False) bovy_plot.bovy_text(r'$\texttt{actionAngleIsochrone}$', top_left=True,size=14.) ax= pyplot.gca() ax.yaxis.set_ticks([10.**-12.,10.**-8.,10.**-4.,1.]) nullfmt = NullFormatter() # no labels ax.xaxis.set_major_formatter(nullfmt) #Same for Spherical pdanglers= parse_break(danglers,tts < breakt) pdanglezs= parse_break(danglezs,tts < breakt) pyplot.subplot(2,1,2) bovy_plot.bovy_plot(ptts/orbt, pdanglers, color='k',ls='-',loglog=True,gcf=True, xrange=[0.5,norb], yrange=[10.**-12.,1.], xlabel=r'$\mathrm{Number\ of\ orbital\ periods}$') bovy_plot.bovy_plot(ptts/orbt, pdanglezs, color='k',ls='--',overplot=True) bovy_plot.bovy_text(r'$\texttt{actionAngleSpherical}$', top_left=True,size=14.) bovy_plot.bovy_text(0.175,10.**4.,r'$\left|\Delta \theta_{R,z} / 2\,\pi\right|$', fontsize=16., rotation='vertical') ax= pyplot.gca() ax.xaxis.set_major_formatter(ticker.FormatStrFormatter(r'$%0.f$')) ax.yaxis.set_ticks([10.**-12.,10.**-8.,10.**-4.,1.]) bovy_plot.bovy_end_print(plotfilename2) 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
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 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