pyodide/packages/galpy/test_galpy.py

126 lines
3.4 KiB
Python

from functools import reduce
import pytest
from pytest_pyodide import run_in_pyodide
# Need to skip_refcount_check because we use matplotlib
DECORATORS = [
pytest.mark.xfail_browsers(
node="galpy loads matplotlib and there are no supported matplotlib backends on node"
),
pytest.mark.skip_refcount_check,
]
def galpy_test_decorator(f):
return reduce(lambda x, g: g(x), DECORATORS, f)
@galpy_test_decorator
@run_in_pyodide(
packages=[
"galpy",
]
)
def test_integrate(selenium):
import numpy
from galpy.orbit import Orbit
from galpy.potential import MWPotential2014
ts = numpy.linspace(0.0, 100.0, 1001)
o = Orbit()
o.integrate(ts, MWPotential2014)
assert (
numpy.fabs(numpy.std(o.E(ts)) / numpy.mean(o.E(ts))) < 1e-10
), "Orbit integration does not conserve energy"
return None
@galpy_test_decorator
@run_in_pyodide(
packages=[
"galpy",
]
)
def test_actionAngle(selenium):
import numpy
from galpy.orbit import Orbit
from galpy.potential import MWPotential2014
ts = numpy.linspace(0.0, 100.0, 1001)
o = Orbit()
o.integrate(ts, MWPotential2014)
all_os = o(ts)
jrs = all_os.jr(pot=MWPotential2014)
jzs = all_os.jz(pot=MWPotential2014)
assert (
numpy.fabs(numpy.std(jrs) / numpy.mean(jrs)) < 1e-4
), "Actions not conserved during orbit integration"
assert (
numpy.fabs(numpy.std(jzs) / numpy.mean(jzs)) < 1e-3
), "Actions not conserved during orbit integration"
return None
@galpy_test_decorator
@run_in_pyodide(
packages=[
"galpy",
]
)
def test_isotropic_hernquist_sigmar(selenium):
import numpy
from galpy import potential
from galpy.df import isotropicHernquistdf, jeans
def check_sigmar_against_jeans(
samp, pot, tol, beta=0.0, dens=None, rmin=None, rmax=None, bins=31
):
"""Check that sigma_r(r) obtained from a sampling agrees with that
coming from the Jeans equation
Does this by logarithmically binning in r between rmin and rmax"""
vrs = (samp.vR() * samp.R() + samp.vz() * samp.z()) / samp.r()
logrs = numpy.log(samp.r())
if rmin is None:
numpy.exp(numpy.amin(logrs))
if rmax is None:
numpy.exp(numpy.amax(logrs))
w, e = numpy.histogram(
logrs,
range=(numpy.log(rmin), numpy.log(rmax)),
bins=bins,
weights=numpy.ones_like(logrs),
)
mv2, _ = numpy.histogram(
logrs,
range=(numpy.log(rmin), numpy.log(rmax)),
bins=bins,
weights=vrs**2.0,
)
samp_sigr = numpy.sqrt(mv2 / w)
brs = numpy.exp((numpy.roll(e, -1) + e)[:-1] / 2.0)
for ii, br in enumerate(brs):
assert (
numpy.fabs(
samp_sigr[ii] / jeans.sigmar(pot, br, beta=beta, dens=dens) - 1.0
)
< tol
), "sigma_r(r) from samples does not agree with that obtained from the Jeans equation"
return None
pot = potential.HernquistPotential(amp=2.3, a=1.3)
dfh = isotropicHernquistdf(pot=pot)
numpy.random.seed(10)
samp = dfh.sample(n=300000)
tol = 0.05
check_sigmar_against_jeans(
samp,
pot,
tol,
beta=0.0,
rmin=pot._scale / 10.0,
rmax=pot._scale * 10.0,
bins=31,
)
return None