def estimateDeltaStaeckel(R,z,pot=None): """ NAME: estimateDeltaStaeckel PURPOSE: Estimate a good value for delta using eqn. (9) in Sanders (2012) INPUT: R,z = coordinates (if these are arrays, the median estimated delta is returned, i.e., if this is an orbit) pot= Potential instance or list thereof OUTPUT: delta HISTORY: 2013-08-28 - Written - Bovy (IAS) """ if pot is None: raise IOError("pot= needs to be set to a Potential instance or list thereof") if isinstance(R,nu.ndarray): delta2= nu.array([(z[ii]**2.-R[ii]**2. #eqn. (9) has a sign error +(3.*R[ii]*evaluatezforces(R[ii],z[ii],pot) -3.*z[ii]*evaluateRforces(R[ii],z[ii],pot) +R[ii]*z[ii]*(evaluateR2derivs(R[ii],z[ii],pot) -evaluatez2derivs(R[ii],z[ii],pot)))/evaluateRzderivs(R[ii],z[ii],pot)) for ii in range(len(R))]) indx= (delta2 < 0.)*(delta2 > -10.**-10.) delta2[indx]= 0. delta2= nu.median(delta2[True-nu.isnan(delta2)]) else: delta2= (z**2.-R**2. #eqn. (9) has a sign error +(3.*R*evaluatezforces(R,z,pot) -3.*z*evaluateRforces(R,z,pot) +R*z*(evaluateR2derivs(R,z,pot) -evaluatez2derivs(R,z,pot)))/evaluateRzderivs(R,z,pot)) if delta2 < 0. and delta2 > -10.**-10.: delta2= 0. return nu.sqrt(delta2)
def estimateDeltaStaeckel(pot,R,z): """ NAME: estimateDeltaStaeckel PURPOSE: Estimate a good value for delta using eqn. (9) in Sanders (2012) INPUT: pot - Potential instance or list thereof R,z- coordinates (if these are arrays, the median estimated delta is returned, i.e., if this is an orbit) OUTPUT: delta HISTORY: 2013-08-28 - Written - Bovy (IAS) 2016-02-20 - Changed input order to allow physical conversions - Bovy (UofT) """ if isinstance(R,nu.ndarray): delta2= nu.array([(z[ii]**2.-R[ii]**2. #eqn. (9) has a sign error +(3.*R[ii]*_evaluatezforces(pot,R[ii],z[ii]) -3.*z[ii]*_evaluateRforces(pot,R[ii],z[ii]) +R[ii]*z[ii]*(evaluateR2derivs(pot,R[ii],z[ii], use_physical=False) -evaluatez2derivs(pot,R[ii],z[ii], use_physical=False)))/evaluateRzderivs(pot,R[ii],z[ii],use_physical=False)) for ii in range(len(R))]) indx= (delta2 < 0.)*(delta2 > -10.**-10.) delta2[indx]= 0. delta2= nu.median(delta2[True-nu.isnan(delta2)]) else: delta2= (z**2.-R**2. #eqn. (9) has a sign error +(3.*R*_evaluatezforces(pot,R,z) -3.*z*_evaluateRforces(pot,R,z) +R*z*(evaluateR2derivs(pot,R,z,use_physical=False) -evaluatez2derivs(pot,R,z,use_physical=False)))/evaluateRzderivs(pot,R,z,use_physical=False)) if delta2 < 0. and delta2 > -10.**-10.: delta2= 0. return nu.sqrt(delta2)
def fdotdotSB1cal(ldeg, bdeg, dkpc, mul, mub, Rpkpc, zkpc, vrad, coslam, alpha, appl, apz, aspl, aT, MWPot): Rskpc = par.Rskpc Vs = par.Vs conversion = par.conversion yrts = par.yrts c = par.c kpctom = par.kpctom Rs = Rskpc * kpctom mastorad = par.mastorad normpottoSI = par.normpottoSI normForcetoSI = par.normForcetoSI normjerktoSI = par.normjerktoSI b = bdeg * par.degtorad l = ldeg * par.degtorad muT = (mub**2. + mul**2.)**0.5 zdot = (1000.0 * vrad) * math.sin(b) + (mastorad / yrts) * mub * ( dkpc * kpctom) * math.cos(b) Rpdot = (1. / (Rpkpc * kpctom)) * ( ((dkpc * kpctom) * (math.cos(b)**2.) - Rs * math.cos(b) * math.cos(l)) * (1000.0 * vrad) + (Rs * (dkpc * kpctom) * math.sin(b) * math.cos(l) - ((dkpc * kpctom)**2.) * math.cos(b) * math.sin(b)) * ((mastorad / yrts) * mub) + Rs * (dkpc * kpctom) * math.sin(l) * ((mastorad / yrts) * mul)) #phiR2a = evaluateR2derivs(MWPot,Rpkpc/Rskpc,zkpc/Rskpc) phiR2 = normjerktoSI * evaluateR2derivs(MWPot, Rpkpc / Rskpc, zkpc / Rskpc) phiz2 = normjerktoSI * evaluatez2derivs(MWPot, Rpkpc / Rskpc, zkpc / Rskpc) phiRz = normjerktoSI * evaluateRzderivs(MWPot, Rpkpc / Rskpc, zkpc / Rskpc) phiR2sun = normjerktoSI * evaluateR2derivs(MWPot, Rskpc / Rskpc, 0.0 / Rskpc) phiRzsun = normjerktoSI * evaluateRzderivs(MWPot, Rskpc / Rskpc, 0.0 / Rskpc) aspldot = phiR2sun * Rpdot + phiRzsun * zdot appldot = phiR2 * Rpdot + phiRz * zdot apzdot = phiRz * Rpdot + phiz2 * zdot #if coslam != 0.0 and Rpkpc != 0.0 and math.cos(b) != 0.0: lamdot = (1. / coslam) * ((Rs * math.cos(l) * ((mastorad / yrts) * mul)) / ((Rpkpc * kpctom) * math.cos(b)) - (Rs * math.sin(l) / ((Rpkpc * kpctom)**2.)) * Rpdot) ardot1 = math.sin(b) * (appl * coslam + aspl * math.cos(l)) * ( (mastorad / yrts) * mub) ardot2 = math.cos(b) * (appldot * coslam + aspldot * math.cos(l)) ardot3 = apzdot * math.sin(b) ardot4 = appl * math.cos(b) * (Rskpc * math.sin(l) / Rpkpc) * lamdot ardot5 = aspl * math.sin(l) * ((mastorad / yrts) * mul) ardot6 = apz * math.cos(b) * ((mastorad / yrts) * mub) ardot = ardot1 - ardot2 - ardot3 + ardot4 + ardot5 - ardot6 jerkt = (1. / c) * (ardot - aT * ((mastorad / yrts) * muT) * math.cos(alpha)) return jerkt
def gamma(R, z): if not isinstance(R, u.Quantity): R = R * u.kpc if not isinstance(z, u.Quantity): z = z * u.kpc r = numpy.sqrt(R**2. + z**2.) return numpy.sqrt(3. + r**2. / (220. * u.km / u.s)**2. * evaluateR2derivs(MWPotential2014, R, z, ro=8., vo=220.)) / 1.9 * 1.5
def estimateDeltaStaeckel(pot, R, z, no_median=False): """ NAME: estimateDeltaStaeckel PURPOSE: Estimate a good value for delta using eqn. (9) in Sanders (2012) INPUT: pot - Potential instance or list thereof R,z- coordinates (if these are arrays, the median estimated delta is returned, i.e., if this is an orbit) no_median - (False) if True, and input is array, return all calculated values of delta (useful for quickly estimating delta for many phase space points) OUTPUT: delta HISTORY: 2013-08-28 - Written - Bovy (IAS) 2016-02-20 - Changed input order to allow physical conversions - Bovy (UofT) """ if isinstance(R, nu.ndarray): delta2 = nu.array([ ( z[ii]**2. - R[ii]**2. #eqn. (9) has a sign error + (3. * R[ii] * _evaluatezforces(pot, R[ii], z[ii]) - 3. * z[ii] * _evaluateRforces(pot, R[ii], z[ii]) + R[ii] * z[ii] * (evaluateR2derivs(pot, R[ii], z[ii], use_physical=False) - evaluatez2derivs(pot, R[ii], z[ii], use_physical=False))) / evaluateRzderivs(pot, R[ii], z[ii], use_physical=False)) for ii in range(len(R)) ]) indx = (delta2 < 0.) * (delta2 > -10.**-10.) delta2[indx] = 0. if not no_median: delta2 = nu.median(delta2[True ^ nu.isnan(delta2)]) else: delta2 = ( z**2. - R**2. #eqn. (9) has a sign error + (3. * R * _evaluatezforces(pot, R, z) - 3. * z * _evaluateRforces(pot, R, z) + R * z * (evaluateR2derivs(pot, R, z, use_physical=False) - evaluatez2derivs(pot, R, z, use_physical=False))) / evaluateRzderivs(pot, R, z, use_physical=False)) if delta2 < 0. and delta2 > -10.**-10.: delta2 = 0. return nu.sqrt(delta2)
def gamma(R, z): if not isinstance(R, u.Quantity): R = R * u.kpc if not isinstance(z, u.Quantity): z = z * u.kpc r = numpy.sqrt(R**2. + z**2.) #not sure if the value thing here is right return numpy.sqrt( 3. + (r**2. / (220. * u.km / u.s)**2.).value * evaluateR2derivs(MWPotential2014, R, z, ro=8., vo=220.)) / 1.9 * 1.5
def estimateDeltaStaeckel(R, z, pot=None): """ NAME: estimateDeltaStaeckel PURPOSE: Estimate a good value for delta using eqn. (9) in Sanders (2012) INPUT: R,z = coordinates (if these are arrays, the median estimated delta is returned, i.e., if this is an orbit) pot= Potential instance or list thereof OUTPUT: delta HISTORY: 2013-08-28 - Written - Bovy (IAS) """ if pot is None: #pragma: no cover raise IOError( "pot= needs to be set to a Potential instance or list thereof") if isinstance(R, nu.ndarray): delta2 = nu.array([ ( z[ii]**2. - R[ii]**2. #eqn. (9) has a sign error + (3. * R[ii] * evaluatezforces(R[ii], z[ii], pot) - 3. * z[ii] * evaluateRforces(R[ii], z[ii], pot) + R[ii] * z[ii] * (evaluateR2derivs(R[ii], z[ii], pot) - evaluatez2derivs(R[ii], z[ii], pot))) / evaluateRzderivs(R[ii], z[ii], pot)) for ii in range(len(R)) ]) indx = (delta2 < 0.) * (delta2 > -10.**-10.) delta2[indx] = 0. delta2 = nu.median(delta2[True - nu.isnan(delta2)]) else: delta2 = ( z**2. - R**2. #eqn. (9) has a sign error + (3. * R * evaluatezforces(R, z, pot) - 3. * z * evaluateRforces(R, z, pot) + R * z * (evaluateR2derivs(R, z, pot) - evaluatez2derivs(R, z, pot))) / evaluateRzderivs(R, z, pot)) if delta2 < 0. and delta2 > -10.**-10.: delta2 = 0. return nu.sqrt(delta2)
def fdotdotSB1cal(ldeg, bdeg, dkpc, mul, mub, vrad): Rskpc = par.Rskpc Vs = par.Vs conversion = par.conversion yrts = par.yrts c = par.c kpctom = par.kpctom Rs = Rskpc * kpctom mastorad = par.mastorad normpottoSI = par.normpottoSI normForcetoSI = par.normForcetoSI normjerktoSI = par.normjerktoSI b = bdeg * par.degtorad l = ldeg * par.degtorad Rpkpc = par.Rpkpc(ldeg, bdeg, dkpc) zkpc = par.z(ldeg, bdeg, dkpc) fex_pl = excGal.Expl(ldeg, bdeg, dkpc) fex_z = excGal.Exz(ldeg, bdeg, dkpc) fex_shk = Shk.Exshk(dkpc, mul, mub) fex_tot = fex_pl + fex_z + fex_shk #mub = mu_alpha #mas/yr #mul = mu_delta muT = (mub**2. + mul**2.)**0.5 #MWPotential2014= [MWPotential2014,KeplerPotential(amp=4*10**6./bovy_conversion.mass_in_msol(par.Vs,par.Rskpc))] MWPot = MWPotential2014 appl = -evaluateRforces(MWPot, Rpkpc / Rskpc, zkpc / Rskpc) * normForcetoSI aspl = -evaluateRforces(MWPot, Rskpc / Rskpc, 0.0 / Rskpc) * normForcetoSI apz = evaluatezforces(MWPot, Rpkpc / Rskpc, zkpc / Rskpc) * normForcetoSI be = (dkpc / Rskpc) * math.cos(b) - math.cos(l) coslam = be * (Rskpc / Rpkpc) coslpluslam = math.cos(l) * coslam - (Rskpc * math.sin(l) / Rpkpc) * math.sin(l) aTl1 = -(appl * (Rskpc * math.sin(l) / Rpkpc) - aspl * math.sin(l)) aTb1 = appl * coslam * math.sin(b) + apz * math.cos(b) + aspl * math.cos( l) * math.sin(b) aTnet1 = (aTl1**2. + aTb1**2.)**(0.5) alphaV1 = math.atan2(mub, mul) / par.degtorad alphaA1 = math.atan2(aTb1, aTl1) / par.degtorad if alphaV1 < 0.: alphaV = 360. + alphaV1 else: alphaV = alphaV1 if alphaA1 < 0.: alphaA = 360. + alphaA1 else: alphaA = alphaA1 alpha = abs(alphaA - alphaV) aT1 = 2. * appl * aspl * coslpluslam aT2 = (c * (fex_pl + fex_z))**2. aTsq = appl**2. + aspl**2. + aT1 + apz**2. - aT2 #if aTsq < 0.0: aT = (appl**2. + aspl**2. + aT1 + apz**2. - aT2)**0.5 zdot = (1000.0 * vrad) * math.sin(b) + (mastorad / yrts) * mub * ( dkpc * kpctom) * math.cos(b) Rpdot = (1. / (Rpkpc * kpctom)) * ( ((dkpc * kpctom) * (math.cos(b)**2.) - Rs * math.cos(b) * math.cos(l)) * (1000.0 * vrad) + (Rs * (dkpc * kpctom) * math.sin(b) * math.cos(l) - ((dkpc * kpctom)**2.) * math.cos(b) * math.sin(b)) * ((mastorad / yrts) * mub) + Rs * (dkpc * kpctom) * math.sin(l) * ((mastorad / yrts) * mul)) phiR2 = normjerktoSI * evaluateR2derivs(MWPot, Rpkpc / Rskpc, zkpc / Rskpc) phiz2 = normjerktoSI * evaluatez2derivs(MWPot, Rpkpc / Rskpc, zkpc / Rskpc) phiRz = normjerktoSI * evaluateRzderivs(MWPot, Rpkpc / Rskpc, zkpc / Rskpc) phiR2sun = normjerktoSI * evaluateR2derivs(MWPot, Rskpc / Rskpc, 0.0 / Rskpc) phiRzsun = normjerktoSI * evaluateRzderivs(MWPot, Rskpc / Rskpc, 0.0 / Rskpc) aspldot = phiR2sun * Rpdot + phiRzsun * zdot appldot = phiR2 * Rpdot + phiRz * zdot if b > 0: apzdot = phiRz * Rpdot + phiz2 * zdot else: apzdot = -(phiRz * Rpdot + phiz2 * zdot) #if coslam != 0.0 and Rpkpc != 0.0 and math.cos(b) != 0.0: lamdot = (1. / coslam) * ((Rs * math.cos(l) * ((mastorad / yrts) * mul)) / ((Rpkpc * kpctom) * math.cos(b)) - (Rs * math.sin(l) / ((Rpkpc * kpctom)**2.)) * Rpdot) ardot1 = math.sin(b) * (appl * coslam + aspl * math.cos(l)) * ( (mastorad / yrts) * mub) ardot2 = math.cos(b) * (appldot * coslam + aspldot * math.cos(l)) ardot3 = apzdot * math.sin(abs(b)) ardot4 = appl * math.cos(b) * (Rskpc * math.sin(l) / Rpkpc) * lamdot ardot5 = aspl * math.sin(l) * ((mastorad / yrts) * mul) ardot6 = abs(apz) * math.cos(b) * ((mastorad / yrts) * mub) * (b / abs(b)) ardot = ardot1 - ardot2 - ardot3 + ardot4 + ardot5 - ardot6 jerkt = (1. / c) * (ardot - aT * ((mastorad / yrts) * muT) * math.cos(alpha)) return jerkt
def plhalo_from_dlnvcdlnr(dlnvcdlnr,diskpot,bulgepot,fh): """Calculate the halo's shape corresponding to this rotation curve derivative""" #First calculate the derivatives dvc^2/dR of disk and bulge dvcdr_disk= -potential.evaluateRforces(1.,0.,diskpot)+potential.evaluateR2derivs(1.,0.,diskpot) dvcdr_bulge= -potential.evaluateRforces(1.,0.,bulgepot)+potential.evaluateR2derivs(1.,0.,bulgepot) return 2.-(2.*dlnvcdlnr-dvcdr_disk-dvcdr_bulge)/fh