# Path: batoid/medium.py
# class ConstMedium(Medium):
#     """A `Medium` with wavelength-independent refractive index.
# 
#     Parameters
#     ----------
#     n : float
#         The refractive index.
#     """
#     def __init__(self, n):
#         self.n = n
#         self._medium = _batoid.CPPConstMedium(n)
# 
#     def __eq__(self, rhs):
#         if type(rhs) == type(self):
#             return self.n == rhs.n
#         return False
# 
#     def __getstate__(self):
#         return self.n
# 
#     def __setstate__(self, n):
#         self.n = n
#         self._medium = _batoid.CPPConstMedium(n)
# 
#     def __hash__(self):
#         return hash(("batoid.ConstMedium", self.n))
# 
#     def __repr__(self):
#         return f"ConstMedium({self.n})"
# 
# Path: batoid/optic.py
# class RefractiveInterface(Interface):
#     """Specialization for refractive interfaces.
# 
#     Rays will interact with this surface by refracting through it.
#     """
#     def __init__(self, *args, **kwargs):
#         Interface.__init__(self, *args, **kwargs)
#         self.forwardCoating = SimpleCoating(
#             reflectivity=0.0, transmissivity=1.0
#         )
#         self.reverseCoating = SimpleCoating(
#             reflectivity=0.0, transmissivity=1.0
#         )
# 
#     def interact(self, rv, reverse=False):
#         if reverse:
#             m1, m2 = self.outMedium, self.inMedium
#         else:
#             m1, m2 = self.inMedium, self.outMedium
#         return self.surface.refract(rv, m1, m2, coordSys=self.coordSys)
# 
#     def rSplit(self, rv, reverse=False):
#         # always return in order: refracted, reflected
#         if reverse:
#             m1 = self.outMedium
#             m2 = self.inMedium
#             coating = self.forwardCoating
#         else:
#             m1 = self.inMedium
#             m2 = self.outMedium
#             coating = self.reverseCoating
# 
#         return self.surface.rSplit(rv, m1, m2, coating, coordSys=self.coordSys)


from batoid.medium import ConstMedium
from batoid.optic import RefractiveInterface
from test_helpers import timer, rays_allclose
import batoid
import numpy as np
        pupilSize=1.0,
        backDist=1.0,
        inMedium=batoid.ConstMedium(1.0)
    )
    telescope['L1_entrance'].forwardCoating = batoid.SimpleCoating(0.02, 0.98)
    telescope['L1_entrance'].reverseCoating = batoid.SimpleCoating(0.02, 0.98)
    telescope['L1_exit'].forwardCoating = batoid.SimpleCoating(0.02, 0.98)
    telescope['L1_exit'].reverseCoating = batoid.SimpleCoating(0.02, 0.98)
    telescope['detector'].forwardCoating = batoid.SimpleCoating(0.02, 0.98)
    rays = batoid.RayVector.asPolar(
        telescope,
        wavelength=500e-9,
        theta_x=np.deg2rad(1.0),
        theta_y=0.0,
        nrad=10, naz=60
    )
    rForward, rReverse = telescope.traceSplit(rays.copy(), minFlux=1e-4)

    for r in rForward:
        r2 = telescope.trace(rays.copy(), path=r.path)
        w = ~r2.vignetted
        np.testing.assert_allclose(r.r, r2.r[w])
        np.testing.assert_allclose(r.v, r2.v[w])
        np.testing.assert_allclose(r.t, r2.t[w])

        tf = telescope.traceFull(rays.copy(), path=r.path)
        keys = []
        for item in r.path:
            j = 0
            key = f"{item}_{j}"

# Path: batoid/medium.py
# class ConstMedium(Medium):
#     """A `Medium` with wavelength-independent refractive index.
# 
#     Parameters
#     ----------
#     n : float
#         The refractive index.
#     """
#     def __init__(self, n):
#         self.n = n
#         self._medium = _batoid.CPPConstMedium(n)
# 
#     def __eq__(self, rhs):
#         if type(rhs) == type(self):
#             return self.n == rhs.n
#         return False
# 
#     def __getstate__(self):
#         return self.n
# 
#     def __setstate__(self, n):
#         self.n = n
#         self._medium = _batoid.CPPConstMedium(n)
# 
#     def __hash__(self):
#         return hash(("batoid.ConstMedium", self.n))
# 
#     def __repr__(self):
#         return f"ConstMedium({self.n})"
# 
# Path: batoid/optic.py
# class RefractiveInterface(Interface):
#     """Specialization for refractive interfaces.
# 
#     Rays will interact with this surface by refracting through it.
#     """
#     def __init__(self, *args, **kwargs):
#         Interface.__init__(self, *args, **kwargs)
#         self.forwardCoating = SimpleCoating(
#             reflectivity=0.0, transmissivity=1.0
#         )
#         self.reverseCoating = SimpleCoating(
#             reflectivity=0.0, transmissivity=1.0
#         )
# 
#     def interact(self, rv, reverse=False):
#         if reverse:
#             m1, m2 = self.outMedium, self.inMedium
#         else:
#             m1, m2 = self.inMedium, self.outMedium
#         return self.surface.refract(rv, m1, m2, coordSys=self.coordSys)
# 
#     def rSplit(self, rv, reverse=False):
#         # always return in order: refracted, reflected
#         if reverse:
#             m1 = self.outMedium
#             m2 = self.inMedium
#             coating = self.forwardCoating
#         else:
#             m1 = self.inMedium
#             m2 = self.outMedium
#             coating = self.reverseCoating
# 
#         return self.surface.rSplit(rv, m1, m2, coating, coordSys=self.coordSys)


# Path: tests/test_rsplit.py
from batoid.medium import ConstMedium
from batoid.optic import RefractiveInterface
from test_helpers import timer, rays_allclose
import batoid
import numpy as np

        pupilSize=1.0,
        backDist=1.0,
        inMedium=batoid.ConstMedium(1.0)
    )
    telescope['L1_entrance'].forwardCoating = batoid.SimpleCoating(0.02, 0.98)
    telescope['L1_entrance'].reverseCoating = batoid.SimpleCoating(0.02, 0.98)
    telescope['L1_exit'].forwardCoating = batoid.SimpleCoating(0.02, 0.98)
    telescope['L1_exit'].reverseCoating = batoid.SimpleCoating(0.02, 0.98)
    telescope['detector'].forwardCoating = batoid.SimpleCoating(0.02, 0.98)
    rays = batoid.RayVector.asPolar(
        telescope,
        wavelength=500e-9,
        theta_x=np.deg2rad(1.0),
        theta_y=0.0,
        nrad=10, naz=60
    )
    rForward, rReverse = telescope.traceSplit(rays.copy(), minFlux=1e-4)

    for r in rForward:
        r2 = telescope.trace(rays.copy(), path=r.path)
        w = ~r2.vignetted
        np.testing.assert_allclose(r.r, r2.r[w])
        np.testing.assert_allclose(r.v, r2.v[w])
        np.testing.assert_allclose(r.t, r2.t[w])

        tf = telescope.traceFull(rays.copy(), path=r.path)
        keys = []
        for item in r.path:
            j = 0
            key = f"{item}_{j}"

            while key in keys: