def plotlinearPotentials(Pot, t=0., min=-15., max=15, ns=21, savefilename=None): """ NAME: plotlinearPotentials PURPOSE: plot a combination of potentials INPUT: t - time to evaluate potential at min - minimum x max - maximum x ns - grid in x savefilename - save to or restore from this savefile (pickle) OUTPUT: plot to output device HISTORY: 2010-07-13 - Written - Bovy (NYU) """ Pot = flatten(Pot) if not savefilename == None and os.path.exists(savefilename): print("Restoring savefile " + savefilename + " ...") savefile = open(savefilename, 'rb') potx = pickle.load(savefile) xs = pickle.load(savefile) savefile.close() else: xs = nu.linspace(min, max, ns) potx = nu.zeros(ns) for ii in range(ns): potx[ii] = evaluatelinearPotentials(Pot, xs[ii], t=t) if not savefilename == None: print("Writing savefile " + savefilename + " ...") savefile = open(savefilename, 'wb') pickle.dump(potx, savefile) pickle.dump(xs, savefile) savefile.close() return plot.bovy_plot(xs, potx, xlabel=r"$x/x_0$", ylabel=r"$\Phi(x)$", xrange=[min, max])
def LinShuReductionFactor(axiPot,R,sigmar,nonaxiPot=None, k=None,m=None,OmegaP=None): """ NAME: LinShuReductionFactor PURPOSE: Calculate the Lin & Shu (1966) reduction factor: the reduced linear response of a kinematically-warm stellar disk to a perturbation INPUT: axiPot - The background, axisymmetric potential R - Cylindrical radius (can be Quantity) sigmar - radial velocity dispersion of the population (can be Quantity) Then either provide: 1) m= m in the perturbation's m x phi (number of arms for a spiral) k= wavenumber (see Binney & Tremaine 2008) OmegaP= pattern speed (can be Quantity) 2) nonaxiPot= a non-axisymmetric Potential instance (such as SteadyLogSpiralPotential) that has functions that return OmegaP, m, and wavenumber OUTPUT: reduction factor HISTORY: 2014-08-23 - Written - Bovy (IAS) """ axiPot= flatten(axiPot) from galpy.potential import omegac, epifreq if nonaxiPot is None and (OmegaP is None or k is None or m is None): raise IOError("Need to specify either nonaxiPot= or m=, k=, OmegaP= for LinShuReductionFactor") elif not nonaxiPot is None: OmegaP= nonaxiPot.OmegaP() k= nonaxiPot.wavenumber(R) m= nonaxiPot.m() tepif= epifreq(axiPot,R) s= m*(OmegaP-omegac(axiPot,R))/tepif chi= sigmar**2.*k**2./tepif**2. return (1.-s**2.)/nu.sin(nu.pi*s)\ *integrate.quad(lambda t: nu.exp(-chi*(1.+nu.cos(t)))\ *nu.sin(s*t)*nu.sin(t), 0.,nu.pi)[0]
def plotlinearPotentials(Pot,t=0.,min=-15.,max=15,ns=21,savefilename=None): """ NAME: plotlinearPotentials PURPOSE: plot a combination of potentials INPUT: t - time to evaluate potential at min - minimum x max - maximum x ns - grid in x savefilename - save to or restore from this savefile (pickle) OUTPUT: plot to output device HISTORY: 2010-07-13 - Written - Bovy (NYU) """ Pot= flatten(Pot) if not savefilename == None and os.path.exists(savefilename): print("Restoring savefile "+savefilename+" ...") savefile= open(savefilename,'rb') potx= pickle.load(savefile) xs= pickle.load(savefile) savefile.close() else: xs= nu.linspace(min,max,ns) potx= nu.zeros(ns) for ii in range(ns): potx[ii]= evaluatelinearPotentials(Pot,xs[ii],t=t) if not savefilename == None: print("Writing savefile "+savefilename+" ...") savefile= open(savefilename,'wb') pickle.dump(potx,savefile) pickle.dump(xs,savefile) savefile.close() return plot.bovy_plot(xs,potx, xlabel=r"$x/x_0$",ylabel=r"$\Phi(x)$", xrange=[min,max])
def toPlanarPotential(Pot): """ NAME: toPlanarPotential PURPOSE: convert an Potential to a planarPotential in the mid-plane (z=0) INPUT: Pot - Potential instance or list of such instances (existing planarPotential instances are just copied to the output) OUTPUT: planarPotential instance(s) HISTORY: 2016-06-11 - Written - Bovy (UofT) """ Pot= flatten(Pot) if isinstance(Pot,list): out= [] for pot in Pot: if isinstance(pot,planarPotential): out.append(pot) elif pot.isNonAxi: out.append(planarPotentialFromFullPotential(pot)) else: out.append(planarPotentialFromRZPotential(pot)) return out elif isinstance(Pot,Potential) and Pot.isNonAxi: return planarPotentialFromFullPotential(Pot) elif isinstance(Pot,Potential): return planarPotentialFromRZPotential(Pot) elif isinstance(Pot,planarPotential): return Pot else: raise PotentialError("Input to 'toPlanarPotential' is neither an Potential-instance or a list of such instances")
def RZToplanarPotential(RZPot): """ NAME: RZToplanarPotential PURPOSE: convert an RZPotential to a planarPotential in the mid-plane (z=0) INPUT: RZPot - RZPotential instance or list of such instances (existing planarPotential instances are just copied to the output) OUTPUT: planarPotential instance(s) HISTORY: 2010-07-13 - Written - Bovy (NYU) """ RZPot= flatten(RZPot) if isinstance(RZPot,list): out= [] for pot in RZPot: if isinstance(pot,planarPotential): out.append(pot) else: out.append(planarPotentialFromRZPotential(pot)) return out elif isinstance(RZPot,Potential): return planarPotentialFromRZPotential(RZPot) elif isinstance(RZPot,planarPotential): return RZPot else: raise PotentialError("Input to 'RZToplanarPotential' is neither an RZPotential-instance or a list of such instances")
def plotplanarPotentials(Pot,*args,**kwargs): """ NAME: plotplanarPotentials PURPOSE: plot a planar potential INPUT: Rrange - range (can be Quantity) xrange, yrange - if relevant (can be Quantity) grid, gridx, gridy - number of points to plot savefilename - save to or restore from this savefile (pickle) ncontours - number of contours to plot (if applicable) +bovy_plot(*args,**kwargs) or bovy_dens2d(**kwargs) OUTPUT: plot to output device HISTORY: 2010-07-13 - Written - Bovy (NYU) """ Pot= flatten(Pot) Rrange= kwargs.pop('Rrange',[0.01,5.]) xrange= kwargs.pop('xrange',[-5.,5.]) yrange= kwargs.pop('yrange',[-5.,5.]) if _APY_LOADED: if hasattr(Pot,'_ro'): tro= Pot._ro else: tro= Pot[0]._ro if isinstance(Rrange[0],units.Quantity): Rrange[0]= Rrange[0].to(units.kpc).value/tro if isinstance(Rrange[1],units.Quantity): Rrange[1]= Rrange[1].to(units.kpc).value/tro if isinstance(xrange[0],units.Quantity): xrange[0]= xrange[0].to(units.kpc).value/tro if isinstance(xrange[1],units.Quantity): xrange[1]= xrange[1].to(units.kpc).value/tro if isinstance(yrange[0],units.Quantity): yrange[0]= yrange[0].to(units.kpc).value/tro if isinstance(yrange[1],units.Quantity): yrange[1]= yrange[1].to(units.kpc).value/tro grid= kwargs.pop('grid',100) gridx= kwargs.pop('gridx',100) gridy= kwargs.pop('gridy',gridx) savefilename= kwargs.pop('savefilename',None) isList= isinstance(Pot,list) nonAxi= ((isList and Pot[0].isNonAxi) or (not isList and Pot.isNonAxi)) if not savefilename is None and os.path.exists(savefilename): print("Restoring savefile "+savefilename+" ...") savefile= open(savefilename,'rb') potR= pickle.load(savefile) if nonAxi: xs= pickle.load(savefile) ys= pickle.load(savefile) else: Rs= pickle.load(savefile) savefile.close() else: if nonAxi: xs= nu.linspace(xrange[0],xrange[1],gridx) ys= nu.linspace(yrange[0],yrange[1],gridy) potR= nu.zeros((gridx,gridy)) for ii in range(gridx): for jj in range(gridy): thisR= nu.sqrt(xs[ii]**2.+ys[jj]**2.) if xs[ii] >= 0.: thisphi= nu.arcsin(ys[jj]/thisR) else: thisphi= -nu.arcsin(ys[jj]/thisR)+nu.pi potR[ii,jj]= evaluateplanarPotentials(Pot,thisR, phi=thisphi, use_physical=False) else: Rs= nu.linspace(Rrange[0],Rrange[1],grid) potR= nu.zeros(grid) for ii in range(grid): potR[ii]= evaluateplanarPotentials(Pot,Rs[ii], use_physical=False) if not savefilename is None: print("Writing planar savefile "+savefilename+" ...") savefile= open(savefilename,'wb') pickle.dump(potR,savefile) if nonAxi: pickle.dump(xs,savefile) pickle.dump(ys,savefile) else: pickle.dump(Rs,savefile) savefile.close() if nonAxi: if not 'orogin' in kwargs: kwargs['origin']= 'lower' if not 'cmap' in kwargs: kwargs['cmap']= 'gist_yarg' if not 'contours' in kwargs: kwargs['contours']= True if not 'xlabel' in kwargs: kwargs['xlabel']= r"$x / R_0$" if not 'ylabel' in kwargs: kwargs['ylabel']= "$y / R_0$" if not 'aspect' in kwargs: kwargs['aspect']= 1. if not 'cntrls' in kwargs: kwargs['cntrls']= '-' ncontours= kwargs.pop('ncontours',10) if not 'levels' in kwargs: kwargs['levels']= nu.linspace(nu.nanmin(potR),nu.nanmax(potR),ncontours) return plot.bovy_dens2d(potR.T, xrange=xrange, yrange=yrange,**kwargs) else: kwargs['xlabel']=r"$R/R_0$" kwargs['ylabel']=r"$\Phi(R)$" kwargs['xrange']=Rrange return plot.bovy_plot(Rs,potR,*args,**kwargs)