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 calc_aA_sim(RvR,filename,snap_gc): # Calculate the action angle variables for a simulation and store if not os.path.exists(filename): aAI= actionAngleIsochroneApprox(pot=lp,b=0.8) nbatch= 20 multiOut= multi.parallel_map(\ lambda x: aAI.actionsFreqsAngles(RvR[x*nbatch:(x+1)*nbatch,0]/R0, RvR[x*nbatch:(x+1)*nbatch,1]/V0, RvR[x*nbatch:(x+1)*nbatch,2]/V0, RvR[x*nbatch:(x+1)*nbatch,3]/R0, RvR[x*nbatch:(x+1)*nbatch,4]/V0, RvR[x*nbatch:(x+1)*nbatch,5]), range(len(snap_gc)//nbatch), numcores=25) acfs= numpy.reshape(numpy.swapaxes(numpy.array(multiOut),0,1), (9,numpy.prod(numpy.array(multiOut).shape)//9)) # Write to file csvfile= open(filename,'w') writer= csv.writer(csvfile,delimiter=',') for jj in range(len(acfs[0])): writer.writerow([acfs[0][jj],acfs[1][jj],acfs[2][jj], acfs[3][jj],acfs[4][jj],acfs[5][jj], acfs[6][jj],acfs[7][jj],acfs[8][jj]]) csvfile.flush() csvfile.close() else: acfs= numpy.loadtxt(filename,delimiter=',').T return acfs
def nemo_prog_action_angle(x, y, z, vx, vy, vz, R0, V0, q, end_time, delta, C_use): """ Parameter: ------------------------------------------------------- x, y, z : initial position of the progenitor vx, vy, vz : initial velocity of the progenitor R0, V0 : radius and circular velocity q : flattening parameter end_time : time when the simulation ended delta : focal distance C_use : True/False - to use C code or not Returns: ------------------------------------------------------- action-angle coordinates and the omega (frequency) as an array array([jr,lz,jz,Omegar,Omegaphi,Omegaz,angler,anglephi,anglez]) This is for the progenitor. """ p = LogarithmicHaloPotential(q = q, normalize = 1.) xyz_to_cyl_vect = np.vectorize(xyz_to_cyl) vxvyvz_to_vrvtvz_vect = np.vectorize(vxvyvz_to_vrvtvz) R, zz , phi = xyz_to_cyl_vect(x, y, z) vR, vT, vz = vxvyvz_to_vrvtvz_vect(x, y, z, vx, vy, vz) # convert to natural units for use in galpy R /= R0 zz /= R0 vR /= V0 vT /= V0 vz /= V0 # initializing the orbit o = Orbit(vxvv=[R, vR, vT, zz, vz, phi], ro=R0, vo=V0) # to convert the time units to normal t = end_time * (V0/R0) time = np.linspace(0., t, 1e4) o.integrate(time, p) Rf = o.R(time) zzf = o.z(time) vRf = o.vR(time) vTf = o.vT(time) vzf = o.vz(time) phif = o.phi(time) aAS = actionAngleIsochroneApprox(pot=p, b=0.8) #actionAngleStaeckel(pot = p, delta = delta, c = C_use) val = aAS.actionsFreqsAngles(Rf, vRf, vTf, zzf, vzf, phif) return val
def test_trailingwleadingimpact_error(): #Imports from galpy.df import 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 ]) V0, R0 = 220., 8. sigv = 0.365 * (10. / 2.)**(1. / 3.) # km/s with pytest.raises(ValueError) as excinfo: dum= 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) return None
def test_actionAngleTorus_isochroneApprox_actions(): from galpy.potential import MWPotential2014 from galpy.actionAngle import actionAngleTorus, \ actionAngleIsochroneApprox aAIA = actionAngleIsochroneApprox(pot=MWPotential2014, b=0.8) tol = -2.5 aAT = actionAngleTorus(pot=MWPotential2014, tol=tol) jr, jphi, jz = 0.075, 1.1, 0.05 angler = numpy.array([0.]) anglephi = numpy.array([numpy.pi]) anglez = numpy.array([numpy.pi / 2.]) # Calculate position from aAT RvR = aAT(jr, jphi, jz, angler, anglephi, anglez).T # Calculate actions from aAIA ji = aAIA(*RvR) djr = numpy.fabs((ji[0] - jr) / jr) dlz = numpy.fabs((ji[1] - jphi) / jphi) djz = numpy.fabs((ji[2] - jz) / jz) assert djr < 10.**tol, 'actionAngleTorus and actionAngleIsochroneApprox applied to MWPotential2014 potential disagree for Jr at %f%%' % ( djr * 100.) assert dlz < 10.**tol, 'actionAngleTorus and actionAngleIsochroneApprox applied to MWPotential2014 potential disagree for Jr at %f%%' % ( dlz * 100.) assert djz < 10.**tol, 'actionAngleTorus and actionAngleMWPotential2014 applied to MWPotential2014 potential disagree for Jr at %f%%' % ( djz * 100.) return None
def calc_aA_sim(RvR, filename, snap_gc): # Calculate the action angle variables for a simulation and store if not os.path.exists(filename): aAI = actionAngleIsochroneApprox(pot=lp, b=0.8) nbatch = 20 multiOut= multi.parallel_map(\ lambda x: aAI.actionsFreqsAngles(RvR[x*nbatch:(x+1)*nbatch,0]/R0, RvR[x*nbatch:(x+1)*nbatch,1]/V0, RvR[x*nbatch:(x+1)*nbatch,2]/V0, RvR[x*nbatch:(x+1)*nbatch,3]/R0, RvR[x*nbatch:(x+1)*nbatch,4]/V0, RvR[x*nbatch:(x+1)*nbatch,5]), range(len(snap_gc)//nbatch), numcores=25) acfs = numpy.reshape(numpy.swapaxes(numpy.array(multiOut), 0, 1), (9, numpy.prod(numpy.array(multiOut).shape) // 9)) # Write to file csvfile = open(filename, 'w') writer = csv.writer(csvfile, delimiter=',') for jj in range(len(acfs[0])): writer.writerow([ acfs[0][jj], acfs[1][jj], acfs[2][jj], acfs[3][jj], acfs[4][jj], acfs[5][jj], acfs[6][jj], acfs[7][jj], acfs[8][jj] ]) csvfile.flush() csvfile.close() else: acfs = numpy.loadtxt(filename, delimiter=',').T return acfs
def test_setupimpact_error(): #Imports from galpy.df import 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]) V0, R0= 220., 8. sigv= 0.365*(10./2.)**(1./3.) # km/s dum= 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) # Should be including these: # GM=10.**-2.\ # /bovy_conversion.mass_in_1010msol(V0,R0), # rs=0.625/R0) return None
def nemo_coord_convert(pos, vel, q, delta, C_use, ro, vo, m, n): """ Parameter: ------------------------------------------------------- pos : x, y, z position as an array vel : vx, vy, vz velocities as an array q : flattening parameter for Logarithmic potential delta : focal distance C_use : True/False - to use C code or not ro : radius for conversio to natural units (usually 8 kpc) vo : velocity conversio to natural units(usually 220 km/s) Returns: ------------------------------------------------------- action-angle coordinates and the omega (frequency) as an array array([jr,lz,jz,Omegar,Omegaphi,Omegaz,angler,anglephi,anglez]) This is for the tail. """ # Logarithmic potential and action-angle function initiated p = LogarithmicHaloPotential(q = q, normalize = 1.) aAS = actionAngleIsochroneApprox(pot=p, b=0.8)#actionAngleStaeckel(pot = p, delta = delta, c = C_use) # position and velocity in cartesian coordinates # This flips y and z and vy and vz columns x, y, z = pos[0], pos[2], pos[1] vx, vy, vz = vel[0], vel[2], vel[1] # make these functions vectorizable to use with arrays xyz_to_cyl_vect = np.vectorize(xyz_to_cyl) vxvyvz_to_vrvtvz_vect = np.vectorize(vxvyvz_to_vrvtvz) # position and velocity in cylindrical coordinates R, zz , phi = xyz_to_cyl_vect(x, y, z) vR, vT, vz = vxvyvz_to_vrvtvz_vect(x, y, z, vx, vy, vz) ro = ro vo = vo # convert to natural units for use in galpy R /= ro zz /= ro vR /= vo vT /= vo vz /= vo # action-angle and omega values val = aAS.actionsFreqsAngles(R[m:n],vR[m:n],vT[m:n],zz[m:n],vz[m:n],phi[m:n]) return val
def aA_prog(ptype): """ Parameters ---------------------------------------------------------------------------------- ptype : potential type. It can be either "Log" for logarithmic potential or "MW" for Milky Way 2014 potential. Return ---------------------------------------------------------------------------------- action-angle values of the progenitor for GD-1 stream given the potentia type """ # setting up the action-angle instance if ptype == "Log": lp = potential.LogarithmicHaloPotential(q=0.9, normalize=1.) aAS = actionAngleIsochroneApprox(pot = lp, b=0.8) elif ptype == "MW": aAS = actionAngleIsochroneApprox(pot = MWPotential2014, b=0.6, tintJ=1000,ntintJ=2000) # current position and velocity of the GD-1 stream progenitor in cartesian coordinates x, y, z = np.array([12.4, 1.5, 7.1]) vx, vy, vz = np.array([107., -243., -105.]) # current position and velocity in cylindrical coordinate R, phi, zz = bovy_coords.rect_to_cyl(x, y, z) vR, vT, vz = bovy_coords.rect_to_cyl_vec(vx, vy, vz, x, y, z, cyl = False) ro = 8.0 vo = 220.0 # converting to galpy natural units R /= ro zz /= ro vR /= vo vT /= vo vz /= vo # computing the action-angle coordinates val = aAS.actionsFreqsAngles(R, vR, vT, zz, vz, phi) return val
def test_actionAngleTorus_isochroneApprox_freqsAngles(): from galpy.potential import MWPotential2014 from galpy.actionAngle import actionAngleTorus, \ actionAngleIsochroneApprox aAIA = actionAngleIsochroneApprox(pot=MWPotential2014, b=0.8) tol = -3.5 aAT = actionAngleTorus(pot=MWPotential2014, tol=tol) jr, jphi, jz = 0.075, 1.1, 0.05 angler = numpy.array([0.1]) + numpy.linspace(0., numpy.pi, 21) angler = angler % (2. * numpy.pi) anglephi = numpy.array([numpy.pi]) + numpy.linspace(0., numpy.pi, 21) anglephi = anglephi % (2. * numpy.pi) anglez = numpy.array([numpy.pi / 2.]) + numpy.linspace(0., numpy.pi, 21) anglez = anglez % (2. * numpy.pi) # Calculate position from aAT RvRom = aAT.xvFreqs(jr, jphi, jz, angler, anglephi, anglez) # Calculate actions, frequencies, and angles from aAI ws = aAIA.actionsFreqsAngles(*RvRom[0].T) dOr = numpy.fabs((ws[3] - RvRom[1])) dOp = numpy.fabs((ws[4] - RvRom[2])) dOz = numpy.fabs((ws[5] - RvRom[3])) dar = numpy.fabs((ws[6] - angler)) dap = numpy.fabs((ws[7] - anglephi)) daz = numpy.fabs((ws[8] - anglez)) dar[dar > numpy.pi] -= 2. * numpy.pi dar[dar < -numpy.pi] += 2. * numpy.pi dap[dap > numpy.pi] -= 2. * numpy.pi dap[dap < -numpy.pi] += 2. * numpy.pi daz[daz > numpy.pi] -= 2. * numpy.pi daz[daz < -numpy.pi] += 2. * numpy.pi assert numpy.all( dOr < 10.**tol ), 'actionAngleTorus and actionAngleIsochroneApprox applied to MWPotential2014 potential disagree for Or at %f%%' % ( numpy.nanmax(dOr) * 100.) assert numpy.all( dOp < 10.**tol ), 'actionAngleTorus and actionAngleIsochroneApprox applied to MWPotential2014 potential disagree for Ophi at %f%%' % ( numpy.nanmax(dOp) * 100.) assert numpy.all( dOz < 10.**tol ), 'actionAngleTorus and actionAngleIsochroneApprox applied to MWPotential2014 potential disagree for Oz at %f%%' % ( numpy.nanmax(dOz) * 100.) assert numpy.all( dar < 10.**tol ), 'actionAngleTorus and actionAngleIsochroneApprox applied to MWPotential2014 potential disagree for ar at %f' % ( numpy.nanmax(dar)) assert numpy.all( dap < 10.**tol ), 'actionAngleTorus and actionAngleIsochroneApprox applied to MWPotential2014 potential disagree for aphi at %f' % ( numpy.nanmax(dap)) assert numpy.all( daz < 10.**tol ), 'actionAngleTorus and actionAngleIsochroneApprox applied to MWPotential2014 potential disagree for az at %f' % ( numpy.nanmax(daz)) return None
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 test_actionAngleTorus_isochroneApprox_actions(): from galpy.potential import MWPotential2014 from galpy.actionAngle import actionAngleTorus, \ actionAngleIsochroneApprox aAIA= actionAngleIsochroneApprox(pot=MWPotential2014,b=0.8) tol= -2.5 aAT= actionAngleTorus(pot=MWPotential2014,tol=tol) jr,jphi,jz= 0.075,1.1,0.05 angler= numpy.array([0.]) anglephi= numpy.array([numpy.pi]) anglez= numpy.array([numpy.pi/2.]) # Calculate position from aAT RvR= aAT(jr,jphi,jz,angler,anglephi,anglez).T # Calculate actions from aAIA ji= aAIA(*RvR) djr= numpy.fabs((ji[0]-jr)/jr) dlz= numpy.fabs((ji[1]-jphi)/jphi) djz= numpy.fabs((ji[2]-jz)/jz) assert djr < 10.**tol, 'actionAngleTorus and actionAngleIsochroneApprox applied to MWPotential2014 potential disagree for Jr at %f%%' % (djr*100.) assert dlz < 10.**tol, 'actionAngleTorus and actionAngleIsochroneApprox applied to MWPotential2014 potential disagree for Jr at %f%%' % (dlz*100.) assert djz < 10.**tol, 'actionAngleTorus and actionAngleMWPotential2014 applied to MWPotential2014 potential disagree for Jr at %f%%' % (djz*100.) return None
def test_actionAngleTorus_isochroneApprox_freqsAngles(): from galpy.potential import MWPotential2014 from galpy.actionAngle import actionAngleTorus, \ actionAngleIsochroneApprox aAIA= actionAngleIsochroneApprox(pot=MWPotential2014,b=0.8) tol= -3.5 aAT= actionAngleTorus(pot=MWPotential2014,tol=tol) jr,jphi,jz= 0.075,1.1,0.05 angler= numpy.array([0.1])+numpy.linspace(0.,numpy.pi,21) angler= angler % (2.*numpy.pi) anglephi= numpy.array([numpy.pi])+numpy.linspace(0.,numpy.pi,21) anglephi= anglephi % (2.*numpy.pi) anglez= numpy.array([numpy.pi/2.])+numpy.linspace(0.,numpy.pi,21) anglez= anglez % (2.*numpy.pi) # Calculate position from aAT RvRom= aAT.xvFreqs(jr,jphi,jz,angler,anglephi,anglez) # Calculate actions, frequencies, and angles from aAI ws= aAIA.actionsFreqsAngles(*RvRom[0].T) dOr= numpy.fabs((ws[3]-RvRom[1])) dOp= numpy.fabs((ws[4]-RvRom[2])) dOz= numpy.fabs((ws[5]-RvRom[3])) dar= numpy.fabs((ws[6]-angler)) dap= numpy.fabs((ws[7]-anglephi)) daz= numpy.fabs((ws[8]-anglez)) dar[dar > numpy.pi]-= 2.*numpy.pi dar[dar < -numpy.pi]+= 2.*numpy.pi dap[dap > numpy.pi]-= 2.*numpy.pi dap[dap < -numpy.pi]+= 2.*numpy.pi daz[daz > numpy.pi]-= 2.*numpy.pi daz[daz < -numpy.pi]+= 2.*numpy.pi assert numpy.all(dOr < 10.**tol), 'actionAngleTorus and actionAngleIsochroneApprox applied to MWPotential2014 potential disagree for Or at %f%%' % (numpy.nanmax(dOr)*100.) assert numpy.all(dOp < 10.**tol), 'actionAngleTorus and actionAngleIsochroneApprox applied to MWPotential2014 potential disagree for Ophi at %f%%' % (numpy.nanmax(dOp)*100.) assert numpy.all(dOz < 10.**tol), 'actionAngleTorus and actionAngleIsochroneApprox applied to MWPotential2014 potential disagree for Oz at %f%%' % (numpy.nanmax(dOz)*100.) assert numpy.all(dar < 10.**tol), 'actionAngleTorus and actionAngleIsochroneApprox applied to MWPotential2014 potential disagree for ar at %f' % (numpy.nanmax(dar)) assert numpy.all(dap < 10.**tol), 'actionAngleTorus and actionAngleIsochroneApprox applied to MWPotential2014 potential disagree for aphi at %f' % (numpy.nanmax(dap)) assert numpy.all(daz < 10.**tol), 'actionAngleTorus and actionAngleIsochroneApprox applied to MWPotential2014 potential disagree for az at %f' % (numpy.nanmax(daz)) return None
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 compute_AA(self, potential, dt=0.01 * u.Myr, AAi=None, method='S'): ''' Compute action angle coordinates for a propagated orbit. ''' from galpy.orbit import Orbit if (AAi is None): AAi = range(self.size) AAi = np.atleast_1d(AAi) # Integration time step self.dt = dt nsteps = np.ceil((self.tflight / self.dt).to('1').value) nsteps[nsteps < 100] = 100 # Initialize position in cylindrical coords rho = self.r0 * np.sin(self.theta0) z = self.r0 * np.cos(self.theta0) phi = self.phi0 #... and velocity vR = self.v0 * np.sin(self.thetav0) * np.cos(self.phiv0) vT = self.v0 * np.sin(self.thetav0) * np.sin(self.phiv0) vz = self.v0 * np.cos(self.thetav0) # Initialize empty arrays to save orbit data and integration steps self.orbits = [None] * self.size AA = [np.zeros((3, int(nsteps[i]))) for i in AAi] if (method != 'S'): from galpy.actionAngle import actionAngleIsochroneApprox, actionAngleAdiabatic aAA = actionAngleIsochroneApprox(pot=potential, c=True, ro=8., vo=220.) else: from galpy.actionAngle import estimateDeltaStaeckel, actionAngleStaeckel k = 0 for i in AAi: ts = np.linspace(0, 1, nsteps[i]) * self.tflight[i] self.orbits[i] = Orbit( vxvv=[rho[i], vR[i], vT[i], z[i], vz[i], phi[i]], solarmotion=self.solarmotion) self.orbits[i].integrate(ts, potential, method='dopr54_c') if (method == 'S'): delta = estimateDeltaStaeckel(potential, self.orbits[i].R(ts) * u.kpc, self.orbits[i].z(ts) * u.kpc) aAA = actionAngleStaeckel(pot=potential, c=True, ro=8., vo=220., delta=delta) AA[k] = aAA(self.orbits[i].R(ts) * u.kpc, self.orbits[i].vR(ts) * u.km / u.s, self.orbits[i].vT(ts) * u.km / u.s, self.orbits[i].z(ts) * u.kpc, self.orbits[i].vz(ts) * u.km / u.s) #AA[k] = aAA(self.orbits[i].R(ts)/8, self.orbits[i].vR(ts)/220, self.orbits[i].vT(ts)/220, self.orbits[i].z(ts)/8, self.orbits[i].vz(ts)/220) k += 1 return AA
import astropy.units as u import scipy from astropy.coordinates import SkyCoord from matplotlib.colors import LogNorm import photErrorModel as pem from scipy.interpolate import interp1d #%pylab inline R0, V0 = 8., 220. save_figures = True prog = 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 ###################################################################### ###################################################################### ###################################################################### _RAPAL5 = 229.018 / 180. * numpy.pi _DECPAL5 = -0.124 / 180. * numpy.pi _TPAL5 = numpy.dot( numpy.array([[numpy.cos(_DECPAL5), 0., numpy.sin(_DECPAL5)], [0., 1., 0.], [-numpy.sin(_DECPAL5), 0., numpy.cos(_DECPAL5)]]), numpy.array([[numpy.cos(_RAPAL5), numpy.sin(_RAPAL5), 0.],
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
0.71877924, -0.01519337, -0.01928001, ] pot = MWPotential2014Likelihood.setup_potential(p_b15, 1.0, False, False, REFR0, REFV0) prog = Orbit( [229.018, -0.124, 23.2, -2.296, -2.257, -58.7], radec=True, ro=REFR0, vo=REFV0, solarmotion=[-11.1, 24.0, 7.25], ) 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,
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_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_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 calc_actions(snapfile=None,first=0): #Setup potential and actionAngle object lp= potential.LogarithmicHaloPotential(normalize=1.,q=0.9) aA= actionAngleIsochroneApprox(pot=lp,b=0.8) # Load snapshot and convert to cylindrical coordinates xvid= numpy.loadtxt(snapfile) xv= xvid[:,:6] id= xvid[:,6] xv= xv[numpy.argsort(id)] id= id[numpy.argsort(id)].astype(int) R,phi,Z= bovy_coords.rect_to_cyl(xv[:,0],xv[:,1],xv[:,2]) vR,vT,vZ= bovy_coords.rect_to_cyl_vec(xv[:,3],xv[:,4],xv[:,5],R,phi,Z, cyl=True) R/= 8. Z/= 8. vR/= 220. vT/= 220. vZ/= 220. if False: #Used for testing R= R[0:100] vR= vR[0:100] vT= vT[0:100] Z= Z[0:100] vZ= vZ[0:100] phi= phi[0:100] nx= len(R) if first: R= R[:nx//2] vR= vR[:nx//2] vT= vT[:nx//2] Z= Z[:nx//2] vZ= vZ[:nx//2] phi= phi[:nx//2] id= id[:nx//2] else: R= R[nx//2:] vR= vR[nx//2:] vT= vT[nx//2:] Z= Z[nx//2:] vZ= vZ[nx//2:] phi= phi[nx//2:] id= id[nx//2:] nx/= 2 #calculation actions, frequencies, and angles #Processes in batches to not run out of memory if first: csvfilename= snapfile.replace('.txt','_aA1.txt') else: csvfilename= snapfile.replace('.txt','_aA2.txt') if os.path.exists(csvfilename): #Don't recalculate those that have already been calculated nstart= int(subprocess.check_output(['wc','-l',csvfilename]).split(' ')[0]) csvfile= open(csvfilename,'ab') else: csvfile= open(csvfilename,'wb') nstart= 0 if nstart >= nx: return 1 #Done already print "Starting from %i ..." % nstart nx-= nstart writer= csv.writer(csvfile,delimiter=',') nbatch= 20 for ii in range(nx//nbatch): print "Working on batch %i out of %i ..." % (ii+1,nx//nbatch) tR= R[nstart+ii*nbatch:numpy.amin([nstart+(ii+1)*nbatch,nstart+nx])] tvR= vR[nstart+ii*nbatch:numpy.amin([nstart+(ii+1)*nbatch,nstart+nx])] tvT= vT[nstart+ii*nbatch:numpy.amin([nstart+(ii+1)*nbatch,nstart+nx])] tZ= Z[nstart+ii*nbatch:numpy.amin([nstart+(ii+1)*nbatch,nstart+nx])] tvZ= vZ[nstart+ii*nbatch:numpy.amin([nstart+(ii+1)*nbatch,nstart+nx])] tphi= phi[nstart+ii*nbatch:numpy.amin([nstart+(ii+1)*nbatch,nstart+nx])] try: tacfs= aA.actionsFreqsAngles(tR,tvR,tvT,tZ,tvZ,tphi) except numpy.linalg.linalg.LinAlgError: print tR,tvR,tvT,tZ,tvZ,tphi raise for jj in range(len(tacfs[0])): writer.writerow([tacfs[0][jj],tacfs[1][jj],tacfs[2][jj], tacfs[3][jj],tacfs[4][jj],tacfs[5][jj], tacfs[6][jj],tacfs[7][jj],tacfs[8][jj], id[nstart+ii*nbatch+jj]]) csvfile.flush() csvfile.close() return None
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 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_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
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