Esempio n. 1
0
 def test_trace_with_geometric_objects_1(self):
     """ Only one of the geometric objects has a transformation applied.
     """
     root = Node(name="Root", geometry=Sphere(radius=10.0))
     a = Node(name="A", parent=root, geometry=Sphere(radius=1.0))
     b = Node(name="B", parent=root, geometry=Sphere(radius=1.0))
     b.translate((5.0, 0.0, 0.0))
     scene = Scene(root)
     tracer = PhotonTracer(scene)
     position = (-3.0, 0.0, 0.0)
     direction = (1.0, 0.0, 0.0)
     initial_ray = Ray(
         position=position, direction=direction, wavelength=555.0, is_alive=True
     )
     expected_history = [
         initial_ray,  # Starting ray
         replace(initial_ray, position=(-1.0, 0.0, 0.0)), # Moved to intersection
         replace(initial_ray, position=(1.0, 0.0, 0.0)),  # Moved to intersection
         replace(initial_ray, position=(4.0, 0.0, 0.0)),  # Moved to intersection
         replace(initial_ray, position=(6.0, 0.0, 0.0)),  # Moved to intersection
         replace(initial_ray, position=(10.0, 0.0, 0.0), is_alive=False),  # Exit ray
     ]
     history = tracer.follow(initial_ray)
     for pair in zip(history, expected_history):
         a, b = pair
         print("Testing {} {}".format(a.position, b.position))
         assert np.allclose(a.position, b.position)
Esempio n. 2
0
 def test_is_entering_false(self):
     a = Node(name="A", parent=None)
     b = Node(name="B", parent=a)
     b.geometry = Sphere(radius=1.0)
     surface_point = (-1.0, 0.0, 0.0)
     entering_direction = (-1.0, 0.0, 0.0)
     assert b.geometry.is_entering(surface_point, entering_direction) == False
Esempio n. 3
0
 def test_trace_with_material_object(self):
     """ Root node and test object has a material attached.
     """
     np.random.seed(1) # No reflections
     # np.random.seed(2)  # Reflection at last inteface
     root = Node(name="Root", geometry=Sphere(radius=10.0, material=Dielectric.make_constant((400, 800), 1.0)))
     b = Node(name="B", parent=root, geometry=Sphere(radius=1.0, material=Dielectric.make_constant((400, 800), 1.5)))
     b.translate((5.0, 0.0, 0.0))
     scene = Scene(root)
     tracer = PhotonTracer(scene)
     position = (-3.0, 0.0, 0.0)
     direction = (1.0, 0.0, 0.0)
     initial_ray = Ray(
         position=position, direction=direction, wavelength=555.0, is_alive=True
     )
     expected_history = [
         initial_ray,  # Starting ray
         replace(initial_ray, position=(4.0, 0.0, 0.0)), # Moved to intersection
         replace(initial_ray, position=(4.0, 0.0, 0.0)), # Refracted into A
         replace(initial_ray, position=(6.0, 0.0, 0.0)),  # Moved to intersection
         replace(initial_ray, position=(6.0, 0.0, 0.0)),  # Refracted out of A
         replace(initial_ray, position=(10.0, 0.0, 0.0), is_alive=False),  # Exit ray
     ]
     history = tracer.follow(initial_ray)
     for pair in zip(history, expected_history):
         a, b = pair
         print("Testing {} {}".format(a.position, b.position))
         assert np.allclose(a.position, b.position)
Esempio n. 4
0
 def test_is_entering_false(self):
     a = Node(name="A", parent=None)
     b = Node(name="B", parent=a)
     b.geometry = Sphere(radius=1.0)
     surface_point = (-1.0, 0.0, 0.0)
     entering_direction = (-1.0, 0.0, 0.0)
     assert b.geometry.is_entering(surface_point,
                                   entering_direction) == False
Esempio n. 5
0
 def test_intersections(self):
     a = Node(name="A", parent=None)
     b = Node(name="B", parent=a)
     b.geometry = Sphere(radius=1.0)
     loc = (-1.0, 0.0, 0.0)
     vec = (1.0, 0.0, 0.0)
     intersections = b.intersections(loc, vec)
     points = np.array([x.point for x in intersections])
     assert np.allclose(points, ((-1.0, 0.0, 0.0), (1.0, 0.0, 0.0)))
Esempio n. 6
0
 def test_intersections(self):
     a = Node(name="A", parent=None)
     b = Node(name="B", parent=a)
     b.geometry = Sphere(radius=1.0)
     loc = (-1.0, 0.0, 0.0)
     vec = (1.0, 0.0, 0.0)
     intersections = b.intersections(loc, vec)
     points = np.array([x.point for x in intersections])
     assert np.allclose(points, ((-1.0, 0.0, 0.0), (1.0, 0.0, 0.0)))
 def test_basic_scene(self):
     a = Node(name="A", parent=None)
     b = Node(name="B", parent=a)
     b.geometry = Sphere(radius=1.0)
     b.translate((2.0, 0.0, 0.0))
     s = Scene(root=a)
     r = MeshcatRenderer(zmq_url='tcp://127.0.0.1:6000')
     r.render(s)
     time.sleep(0.5)
     r.remove(s)
Esempio n. 8
0
 def test_intersection_when_on_surface(self):
     """ Make sure we return intersection points even with zero distance from ray.
     """
     a = Node(name="A", parent=None)
     a.geometry = Sphere(radius=1.0)
     loc = (-1.0, 0.0, 0.0)
     vec = (1.0, 0.0, 0.0)
     intersections = a.intersections(loc, vec)
     points = np.array([x.point for x in intersections])
     expected = np.array([(-1.0, 0.0, 0.0), (1.0, 0.0, 0.0)])
     assert np.allclose(points, expected)
Esempio n. 9
0
 def test_intersection_when_on_surface(self):
     """ Make sure we return intersection points even with zero distance from ray.
     """
     a = Node(name="A", parent=None)
     a.geometry = Sphere(radius=1.0)
     loc = (-1.0, 0.0, 0.0)
     vec = (1.0, 0.0, 0.0)
     intersections = a.intersections(loc, vec)
     points = np.array([x.point for x in intersections])
     expected = np.array([(-1.0, 0.0, 0.0), (1.0, 0.0, 0.0)])
     assert np.allclose(points, expected)
Esempio n. 10
0
def node_tree():
    b_pos = (1.0, 0.0, 0.0)
    b_axis = (0.0, 1.0, 0.0)
    b_rads = 3.14159265 / 2
    c_pos = (1.0, 0.0, 0.0)
    a = Node(name="a", parent=None)
    b = Node(name="b", parent=a)
    b.location = b_pos
    b.rotate(b_rads, b_axis)
    c = b.add_child_node(name="c")
    c.location = c_pos
    return a, b, c
Esempio n. 11
0
 def test_no_interaction(self):
     np.random.seed(0)
     mat = Dielectric.make_constant((400, 800), 1.0)
     root = Node(name="Root", parent=None)
     root.geometry = Sphere(radius=10.0, material=mat)
     a = Node(name="A", parent=root)
     a.geometry = Sphere(radius=1.0, material=mat)
     ray = Ray(position=(-1.0, 0.0, 0.0), direction=(1.0, 0.0, 0.0), wavelength=555.0, is_alive=True)
     volume = Volume(a, 2.0)
     new_ray = volume.trace(ray)
     expected = replace(ray, position=(1.0, 0.0, 0.0))
     assert new_ray == expected
Esempio n. 12
0
 def test_intersection(self):
     root = Node(name='Root')
     a = Node(name="A", parent=root)
     b = Node(name="B", parent=a)
     b.geometry = Sphere(radius=1.0)
     a.translate((1.0, 0.0, 0.0))
     loc = (-2.0, 0.0, 0.0)
     vec = (1.0, 0.0, 0.0)
     scene = Scene(root=root)
     intersections = scene.intersections(loc, vec)
     points = tuple([x.point for x in intersections])
     # In frame of a everything is shifed 1 along x
     assert points == ((0.0, 0.0, 0.0), (2.0, 0.0, 0.0))
Esempio n. 13
0
 def test_intersection_with_rotation_around_z(self):
     root = Node(name='Root')
     a = Node(name="A", parent=root)
     b = Node(name="B", parent=a)
     b.geometry = Sphere(radius=1.0)
     a.translate((1.0, 0.0, 0.0))
     # This rotation make an z translation in b becomes a -y translation in a
     a.rotate(np.pi / 2, axis=(0.0, 0.0, 1.0))
     loc = (-2.0, 0.0, 0.0)
     vec = (1.0, 0.0, 0.0)
     scene = Scene(root=root)
     intersections = scene.intersections(loc, vec)
     points = tuple([x.point for x in intersections])
     assert np.allclose(points, ((0.0, 0.0, 0.0), (2.0, 0.0, 0.0)))
Esempio n. 14
0
 def test_intersection_coordinate_system(self):
     root = Node(name="Root", geometry=Sphere(radius=10.0))
     a = Node(name="A", parent=root, geometry=Sphere(radius=1.0))
     a.translate((1.0, 0.0, 0.0))
     scene = Scene(root)
     initial_ray = Ray(
         position=(-2.0, 0.0, 0.0),
         direction=(1.0, 0.0, 0.0),
         wavelength=None,
         is_alive=True,
     )
     scene_intersections = scene.intersections(initial_ray.position,
                                               initial_ray.direction)
     a_intersections = tuple(map(lambda x: x.to(root), scene_intersections))
     assert scene_intersections == a_intersections
Esempio n. 15
0
 def test_zero_reflection(self):
     np.random.seed(0)
     mat1 = Dielectric.make_constant((400, 800), 1.0)
     mat2 = Dielectric.make_constant((400, 800), 1.0)
     root = Node(name="Root", parent=None)
     root.geometry = Sphere(radius=10.0, material=mat1)
     a = Node(name="A", parent=root)
     a.geometry = Sphere(radius=1.0, material=mat2)
     ray = Ray(position=(-1.0, 0.0, 0.0), direction=(0.0, 0.0, 1.0), wavelength=555.0, is_alive=True)
     from_node = root
     to_node = a
     interface = DielectricInterface(from_node, to_node)
     new_ray = interface.trace(ray)
     expected = ray  # unchanged
     assert new_ray == expected
Esempio n. 16
0
 def test_init(self):
     node = Node(name='A')
     inter = Intersection(coordsys=Node,
                          hit=Node,
                          point=(0.0, 0.0, 0.0),
                          distance=0.0)
     assert type(inter) == Intersection
Esempio n. 17
0
 def test_intersection_coordinate_system(self):
     root = Node(name="Root", geometry=Sphere(radius=10.0))
     a = Node(name="A", parent=root, geometry=Sphere(radius=1.0))
     a.translate((1.0, 0.0, 0.0))
     scene = Scene(root)
     initial_ray = Ray(
         position=(-2.0, 0.0, 0.0),
         direction=(1.0, 0.0, 0.0),
         wavelength=None,
         is_alive=True,
     )
     scene_intersections = scene.intersections(
         initial_ray.position,
         initial_ray.direction
     )
     a_intersections = tuple(map(lambda x: x.to(root), scene_intersections))
     assert scene_intersections == a_intersections
Esempio n. 18
0
 def test_intersection_with_rotation_around_x(self):
     root = Node(name='Root')
     a = Node(name="A", parent=root)
     b = Node(name="B", parent=a)
     b.geometry = Sphere(radius=1.0)
     b.translate((1.0, 0.0, 0.0))
     # Rotation around x therefore no displace in x
     b.rotate(np.pi / 2, (1.0, 0.0, 0.0))
     loc = (-2.0, 0.0, 0.0)
     vec = (1.0, 0.0, 0.0)
     scene = Scene(root=root)
     intersections = scene.intersections(loc, vec)
     points = tuple([x.point for x in intersections])
     assert points == ((0.0, 0.0, 0.0), (2.0, 0.0, 0.0))
Esempio n. 19
0
 def representation(self, from_node: Node, to_node: Node) -> Ray:
     """ Representation of the ray in another coordinate system.
     
     Parameters
     ----------
     from_node : Node
         The node which represents the ray's current coordinate system
     to_node : Node
         The node in which the new ray should be represented.
     
     Notes
     -----
     Use this method to express the ray location and direction as viewed in the 
     `to_node` coordinate system.
     """
     new_position = from_node.point_to_node(self.position, to_node)
     new_direction = from_node.vector_to_node(self.direction, to_node)
     new_ray = replace(self, position=new_position, direction=new_direction)
     return new_ray
Esempio n. 20
0
 def representation(self, from_node: Node, to_node: Node) -> Ray:
     """ Representation of the ray in another coordinate system.
     
     Parameters
     ----------
     from_node : Node
         The node which represents the ray's current coordinate system
     to_node : Node
         The node in which the new ray should be represented.
     
     Notes
     -----
     Use this method to express the ray location and direction as viewed in the 
     `to_node` coordinate system.
     """
     new_position = from_node.point_to_node(self.position, to_node)
     new_direction = from_node.vector_to_node(self.direction, to_node)
     new_ray = replace(self, position=new_position, direction=new_direction)
     return new_ray
Esempio n. 21
0
def make_touching_scene(n1=1.5, n2=1.5, n3=1.5):
    world = Node(
        name="world (air)",
        geometry=Sphere(
            radius=10.0,
            material=Dielectric.air()
        )
    )
    box1 = Node(
        name="box one (glass)",
        geometry=Box(
            (1.0, 1.0, 1.0),
            material=Dielectric.make_constant(
                x_range=(300.0, 4000.0), refractive_index=n1
            )
        ),
        parent=world
    )
    box2 = Node(
        name="box two (glass)",
        geometry=Box(
            (1.0, 1.0, 1.0),
            material=Dielectric.make_constant(
                x_range=(300.0, 4000.0), refractive_index=n2
            )
        ),
        parent=world
    )
    box2.translate((0.0, 0.0, 1.0))
    box3 = Node(
        name="box three (glass)",
        geometry=Box(
            (1.0, 1.0, 1.0),
            material=Dielectric.make_constant(
                x_range=(300.0, 4000.0), refractive_index=n3
            )
        ),
        parent=world
    )
    box3.translate((0.0, 0.0, 2.0))
    scene = Scene(world)
    return scene, world, box1, box2, box3
Esempio n. 22
0
def make_embedded_scene(n1=1.5):
    world = Node(
        name="world (air)",
        geometry=Sphere(
            radius=10.0,
            material=Dielectric.air()
        )
    )
    box = Node(
        name="box (glass)",
        geometry=Box(
            (1.0, 1.0, 1.0),
            material=Dielectric.make_constant(
                x_range=(300.0, 4000.0), refractive_index=n1
            )
        ),
        parent=world
    )
    scene = Scene(world)
    return scene, world, box
Esempio n. 23
0
 def test_intersection(self):
     root = Node(name='Root')
     a = Node(name="A", parent=root)
     b = Node(name="B", parent=a)
     b.geometry = Sphere(radius=1.0)
     a.translate((1.0, 0.0, 0.0))
     loc = (-2.0, 0.0, 0.0)
     vec = (1.0, 0.0, 0.0)
     scene = Scene(root=root)
     intersections = scene.intersections(loc, vec)
     points = tuple([x.point for x in intersections])
     # In frame of a everything is shifed 1 along x
     assert points == ((0.0, 0.0, 0.0), (2.0, 0.0, 0.0))
Esempio n. 24
0
 def test_equality(self):
     node = Node(name='A')
     inter1 = Intersection(coordsys=Node,
                           hit=Node,
                           point=(0.0, 0.0, 0.0),
                           distance=0.0)
     inter2 = Intersection(coordsys=Node,
                           hit=Node,
                           point=(0.0, 0.0, 0.0),
                           distance=0.0)
     assert inter1 == inter2
Esempio n. 25
0
 def test_ray_reflecting_interaction(self):
     # low > very high refractive index
     np.random.seed(2)
     mat1 = Dielectric.make_constant((400, 800), 1.0)
     mat2 = Dielectric.make_constant((400, 800), 6.0)
     root = Node(name="Root", parent=None)
     root.geometry = Sphere(radius=10.0, material=mat1)
     a = Node(name="A", parent=root)
     a.geometry = Sphere(radius=1.0, material=mat2)
     ray = Ray(position=(-1.0, 0.0, 0.0), direction=norm((-0.2, 0.2, 1.0)), wavelength=555.0, is_alive=True)
     from_node = root
     to_node = a
     interface = DielectricInterface(from_node, to_node)
     new_ray = interface.trace(ray)
     assert np.sign(ray.direction[0]) != np.sign(new_ray.direction[0])  # Reflected
     # Direction should be different after refracting interface
     assert all([not np.allclose(new_ray.direction, ray.direction),
                 np.allclose(new_ray.position, ray.position),
                 new_ray.wavelength == ray.wavelength,
                 new_ray.is_alive == ray.is_alive])
Esempio n. 26
0
 def test_intersection_with_translation(self):
     a = Node(name="A", parent=None)
     b = Node(name="B", parent=a)
     b.geometry = Sphere(radius=1.0)
     b.translate((1.0, 0.0, 0.0))
     aloc = (-2.0, 0.0, 0.0)
     avec = (1.0, 0.0, 0.0)
     bloc = b.point_to_node(aloc, b)
     bvec = b.vector_to_node(avec, b)
     intersections = b.intersections(bloc, bvec)
     points = tuple(x.point for x in intersections)
     assert np.allclose(points, ((-1.0, 0.0, 0.0), (1.0, 0.0, 0.0)))
     # In local frame of b sphere is at origin
     intersections = a.intersections(aloc, avec)
     points = np.array(tuple(x.to(a).point for x in intersections))
     expected = np.array(((0.0, 0.0, 0.0), (2.0, 0.0, 0.0)))
     # In frame of a everything is shifed 1 along x
     assert np.allclose(points, expected)
Esempio n. 27
0
 def test_trace_with_translated_geometric_object(self):
     """ Single translated geometric objects.
     """
     root = Node(name="Root", geometry=Sphere(radius=10.0))
     a = Node(name="A", parent=root, geometry=Sphere(radius=1.0))
     a.translate((5.0, 0.0, 0.0))
     scene = Scene(root)
     tracer = PhotonTracer(scene)
     position = (-2.0, 0.0, 0.0)
     direction = (1.0, 0.0, 0.0)
     initial_ray = Ray(
         position=position, direction=direction, wavelength=555.0, is_alive=True
     )
     expected_history = [
         initial_ray,  # Starting ray
         replace(initial_ray, position=(4.0, 0.0, 0.0)),  # First intersection
         replace(initial_ray, position=(6.0, 0.0, 0.0)),  # Second intersection
         replace(initial_ray, position=(10.0, 0.0, 0.0), is_alive=False),  # Exit ray
     ]
     history = tracer.follow(initial_ray)
     for pair in zip(history, expected_history):
         assert pair[0] == pair[1]
Esempio n. 28
0
def make_embedded_lumophore_scene(n1=1.5):
    world = Node(
        name="world (air)",
        geometry=Sphere(
            radius=10.0,
            material=Dielectric.air()
        )
    )
    box = Node(
        name="box (lumophore)",
        geometry=Box(
            (1.0, 1.0, 1.0),
            material=Lumophore.make_lumogen_f_red(
                x=np.linspace(300.0, 4000.0),
                absorption_coefficient=10.0,
                quantum_yield=1.0
            )
        ),
        parent=world
    )
    scene = Scene(world)
    return scene, world, box
Esempio n. 29
0
 def test_trace_raises_trace_error(self):
     """ Tests interface between objects in which only one of them has a material.
     This should raise a RuntimeError because it cannot be traced in a physically
     correct way.
     """
     np.random.seed(2)
     root = Node(name="Root", geometry=Sphere(radius=10.0))
     b = Node(name="B", parent=root, geometry=Sphere(radius=1.0, material=Dielectric.make_constant((400, 800), 1.5)))
     b.translate((5.0, 0.0, 0.0))
     scene = Scene(root)
     tracer = PhotonTracer(scene)
     position = (-3.0, 0.0, 0.0)
     direction = (1.0, 0.0, 0.0)
     initial_ray = Ray(
         position=position, direction=direction, wavelength=555.0, is_alive=True
     )
     did_raise = False
     try:
         tracer.follow(initial_ray)
     except TraceError as err:
         did_raise = True
     assert did_raise
Esempio n. 30
0
def node_tree():
    b_pos = (1.0, 0.0, 0.0)
    b_axis = (0.0, 1.0, 0.0)
    b_rads = 3.14159265 / 2
    c_pos = (1.0, 0.0, 0.0)
    a = Node(name="a", parent=None)
    b = Node(name="b", parent=a)
    b.location = b_pos
    b.rotate(b_rads, b_axis)
    c = b.add_child_node(name="c")
    c.location = c_pos
    return a, b, c
Esempio n. 31
0
 def test_basic_scene(self):
     a = Node(name="A", parent=None)
     b = Node(name="B", parent=a)
     b.geometry = Sphere(radius=1.0)
     b.translate((2.0, 0.0, 0.0))
     s = Scene(root=a)
     r = MeshcatRenderer()
     r.render(s)
     time.sleep(0.5)
     r.remove(s)
Esempio n. 32
0
 def test_intersection_with_rotation_around_z(self):
     root = Node(name='Root')
     a = Node(name="A", parent=root)
     b = Node(name="B", parent=a)
     b.geometry = Sphere(radius=1.0)
     a.translate((1.0, 0.0, 0.0))
     # This rotation make an z translation in b becomes a -y translation in a
     a.rotate(np.pi/2, axis=(0.0, 0.0, 1.0))
     loc = (-2.0, 0.0, 0.0)
     vec = (1.0, 0.0, 0.0)
     scene = Scene(root=root)
     intersections = scene.intersections(loc, vec)
     points = tuple([x.point for x in intersections])
     assert np.allclose(points, ((0.0, 0.0, 0.0), (2.0, 0.0, 0.0)))
Esempio n. 33
0
 def test_intersection_with_rotation_around_x(self):
     root = Node(name='Root')
     a = Node(name="A", parent=root)
     b = Node(name="B", parent=a)
     b.geometry = Sphere(radius=1.0)
     b.translate((1.0, 0.0, 0.0))
     # Rotation around x therefore no displace in x
     b.rotate(np.pi/2, (1.0, 0.0, 0.0))
     loc = (-2.0, 0.0, 0.0)
     vec = (1.0, 0.0, 0.0)
     scene = Scene(root=root)
     intersections = scene.intersections(loc, vec)
     points = tuple([x.point for x in intersections])
     assert points == ((0.0, 0.0, 0.0), (2.0, 0.0, 0.0))
Esempio n. 34
0
from pvtrace.scene.renderer import MeshcatRenderer
from pvtrace.geometry.utils import magnitude
import logging

# We want to see pvtrace logging here
#logging.getLogger('pvtrace').setLevel(logging.CRITICAL)
logging.getLogger('trimesh').setLevel(logging.CRITICAL)
logging.getLogger('matplotlib').setLevel(logging.CRITICAL)

wavelength_range = (200, 800)
wavelength = np.linspace(*wavelength_range, 1000)
lumogen = Lumophore.make_lumogen_f_red(wavelength, 1000, 1.0)
linear_background = Lumophore.make_linear_background(wavelength, 1.0)

# Make a world coordinate system
world_node = Node(name='world')
world_node.geometry = Sphere(
    radius=10.0,
    material=Dielectric.make_constant((300, 1000.0), 1.0)
)

refractive_index = np.column_stack(
    (wavelength, np.ones(wavelength.shape) * 1.5)
)
# Add LSC
size = (1.0, 1.0, 0.02)
lsc = Node(name="LSC", parent=world_node)
lsc.geometry = Box(
    size, 
    material=Host(
        refractive_index,  # LSC refractive index
Esempio n. 35
0
 def test_init(self):
     assert type(Node()) == Node
Esempio n. 36
0
 def test_name(self):
     assert Node(name="a").name == 'a'
Esempio n. 37
0
material = Host(
    np.column_stack( # refractive index spectrum
        (wavelength,
         np.ones(wavelength.size) * 1.5)
    ), 
    [lumophore],  # list of lumophores, reuse the one we already have.
)

# Make the cylinder node with length 5cm and radius 0.02cm and give the material we 
# just made.

cylinder = Node(
    name="cylinder (glass)",
    geometry=Cylinder(
        length=5.0,
        radius=0.02,
        material=material
    ),
    parent=world
)

# Make a light source. This is a laser emitting light along the whole length of the
# cylinder. We need to translate and rotate the light source to get it to fire along
# the axis. We use the position delegate to generate photons along the same length
# as the cylinder.

light = Node(
    name="light (555nm laser)",
    light=Light(position_delegate=lambda : (np.random.uniform(-2.5, 2.5), 0.0, 0.0)),
    parent=world
)
Esempio n. 38
0
 def test_parent(self):
     a = Node()
     b = Node(parent=a)
     assert a.parent == None
     assert b.parent == a
Esempio n. 39
0
"""
from pvtrace.geometry.cylinder import Cylinder
from pvtrace.geometry.sphere import Sphere
from pvtrace.scene.renderer import MeshcatRenderer
from pvtrace.scene.scene import Scene
from pvtrace.scene.node import Node
from pvtrace.light.light import Light
from pvtrace.algorithm import photon_tracer
from pvtrace.material.dielectric import Dielectric
import numpy as np
import functools
import sys
import time

# World node contains the simulation; large sphere filled with air
world = Node(name="world (air)",
             geometry=Sphere(radius=10.0, material=Dielectric.air()))

# A small cylinder shape made from glass
cylinder = Node(name="cylinder (glass)",
                geometry=Cylinder(length=1.0,
                                  radius=1.0,
                                  material=Dielectric.glass()),
                parent=world)

# A light source with 60-deg divergence
light = Node(name="light (555nm laser)",
             light=Light(divergence_delegate=functools.partial(
                 Light.cone_divergence, np.radians(60))),
             parent=world)
light.translate((0.0, 0.0, -1.0))
Esempio n. 40
0
 def test_coodinate_system_conversions(self):
     a = Node(name='a')
     b = Node(name='b', parent=a)
     c = Node(name='c', parent=b)
     d = Node(name='d', parent=a)
     b.translate((1, 1, 1))
     c.translate((0, 1, 1))
     d.translate((-1, -1, -1))
     theta = 0.5 * np.pi
     b.rotate(theta, (0, 0, 1))
     c.rotate(theta, (1, 0, 0))
     d.rotate(theta, (0, 1, 0))
     # Points in node d to a require just travelling up the nodes.
     assert np.allclose(d.point_to_node((0, 0, 0), a), (-1, -1, -1))
     assert np.allclose(d.point_to_node((1, 1, 1), a), (0, 0, -2))
     # Directions in node d to a require just travelling up the nodes.
     assert np.allclose(d.vector_to_node((1, 0, 0), a), (0, 0, -1))
     assert np.allclose(d.vector_to_node((0, 1, 0), a), (0, 1, 0))
     assert np.allclose(d.vector_to_node((0, 0, 1), a), (1, 0, 0))
     # Points in node d to c requires going up and down nodes
     assert np.allclose(c.point_to_node((0, 0, 0), d), (-3, 2, 1))
     assert np.allclose(c.point_to_node((1, 1, 1), d), (-4, 3, 2))
     # Directions in node d to c require going up and down nodes
     assert np.allclose(c.vector_to_node((1, 0, 0), d), (0, 1, 0))
     assert np.allclose(c.vector_to_node((0, 1, 0), d), (-1, 0, 0))
     assert np.allclose(c.vector_to_node((0, 0, 1), d), (0, 0, 1))
Esempio n. 41
0
        radius=10.0,
        material=Dielectric.air()
    )
)
cylinder = Node(
    name="cylinder (glass)",
    geometry=Cylinder(
        length=1.0,
        radius=1.0,
        material=Dielectric.glass()
    ),
    parent=world
)
light = Node(
    name="light (555nm laser)",
    light=Light(divergence_delegate=functools.partial(Light.cone_divergence, np.radians(60))),
    parent=world
)
light.translate((0.0, 0.0, -1.0))
rend = MeshcatRenderer()
scene = Scene(world)
tracer = PhotonTracer(scene)
rend.render(scene)
for ray in light.emit(10):
    path = tracer.follow(ray)
    print(path)
    rend.add_ray_path(path)

while True:
    try:
        time.sleep(.3)
Esempio n. 42
0
 def test_intersection_with_translation(self):
     a = Node(name="A", parent=None)
     b = Node(name="B", parent=a)
     b.geometry = Sphere(radius=1.0)
     b.translate((1.0, 0.0, 0.0))
     aloc = (-2.0, 0.0, 0.0)
     avec = (1.0, 0.0, 0.0)
     bloc = b.point_to_node(aloc, b)
     bvec = b.vector_to_node(avec, b)
     intersections = b.intersections(bloc, bvec)
     points = tuple(x.point for x in intersections)
     assert np.allclose(points, ((-1.0, 0.0, 0.0), (1.0, 0.0, 0.0)))
     # In local frame of b sphere is at origin
     intersections = a.intersections(aloc, avec)
     points = np.array(tuple(x.to(a).point for x in intersections))
     expected = np.array(((0.0, 0.0, 0.0), (2.0, 0.0, 0.0)))
     # In frame of a everything is shifed 1 along x
     assert np.allclose(points, expected)
Esempio n. 43
0
from pvtrace.scene.node import Node
from pvtrace.scene.scene import Scene
from pvtrace.scene.renderer import MeshcatRenderer
from pvtrace.geometry.sphere import Sphere
from pvtrace.material.dielectric import Dielectric
from pvtrace.light.light import Light
from pvtrace.algorithm import photon_tracer
import time
import functools
import numpy as np

# Add nodes to the scene graph
world = Node(name="world (air)",
             geometry=Sphere(radius=10.0, material=Dielectric.air()))
sphere = Node(name="sphere (glass)",
              geometry=Sphere(radius=1.0, material=Dielectric.glass()),
              parent=world)
sphere.translate((0, 0, 2))

# Add source of photons
light = Node(name="Light (555nm)",
             light=Light(divergence_delegate=functools.partial(
                 Light.cone_divergence, np.radians(20))))

# Use meshcat to render the scene (optional)
viewer = MeshcatRenderer(open_browser=True)
scene = Scene(world)
for ray in light.emit(100):
    # Do something with the photon trace information...
    info = photon_tracer.follow(ray, scene)
    rays, events = zip(*info)
Esempio n. 44
0
 def test_coodinate_system_conversions(self):
     a = Node(name='a')
     b = Node(name='b', parent=a)
     c = Node(name='c', parent=b)
     d = Node(name='d', parent=a)
     b.translate((1,1,1))
     c.translate((0,1,1))
     d.translate((-1, -1, -1))
     theta = 0.5 * np.pi
     b.rotate(theta, (0, 0, 1))
     c.rotate(theta, (1, 0, 0))
     d.rotate(theta, (0, 1, 0))
     # Points in node d to a require just travelling up the nodes.
     assert np.allclose(d.point_to_node((0, 0, 0), a), (-1, -1, -1))
     assert np.allclose(d.point_to_node((1, 1, 1), a), (0, 0, -2))
     # Directions in node d to a require just travelling up the nodes.
     assert np.allclose(d.vector_to_node((1, 0, 0), a), (0, 0, -1))
     assert np.allclose(d.vector_to_node((0, 1, 0), a), (0, 1, 0))
     assert np.allclose(d.vector_to_node((0, 0, 1), a), (1, 0, 0))
     # Points in node d to c requires going up and down nodes
     assert np.allclose(c.point_to_node((0, 0, 0), d), (-3, 2, 1))
     assert np.allclose(c.point_to_node((1, 1, 1), d), (-4, 3, 2))
     # Directions in node d to c require going up and down nodes
     assert np.allclose(c.vector_to_node((1, 0, 0), d), (0, 1, 0))
     assert np.allclose(c.vector_to_node((0, 1, 0), d), (-1, 0, 0))
     assert np.allclose(c.vector_to_node((0, 0, 1), d), (0, 0, 1))
Esempio n. 45
0
    def _make_scene(self):
        """ Creates the scene based on configuration values.
        """
        # Make world node
        (l, w, d) = self.size
        world = Node(
            name="World",
            geometry=Box((l * 100, w * 100, d * 100),
                         material=Material(refractive_index=self.n0)),
        )

        # Create components (Absorbers, Luminophores and Scatteres)
        if len(self._user_components) == 0:
            self._user_components = self._make_default_components()
        components = []
        for component_data in self._user_components:
            cls = component_data.pop("cls")
            coefficient = component_data.pop("coefficient")
            component = cls(coefficient, **component_data)
            components.append(component)

        # Create LSC node
        lsc = Node(
            name="LSC",
            geometry=Box(
                (l, w, d),
                material=Material(
                    refractive_index=self.n1,
                    components=components,
                    surface=Surface(delegate=OptionalMirrorAndSolarCell(self)),
                ),
            ),
            parent=world,
        )

        if self._air_gap_mirror_info["want_air_gap_mirror"]:
            sheet_thickness = 0.25 * d  # make it appear thinner than the LSC
            air_gap_mirror = Node(
                name="Air Gap Mirror",
                geometry=Box(
                    (l, w, sheet_thickness),  # same surface air but very thin
                    material=Material(
                        refractive_index=self.n0,
                        components=[],
                        surface=Surface(delegate=AirGapMirror(self)),
                    ),
                ),
                parent=world,
            )
            # Move adjacent to bottom surface with a small air gap
            air_gap_mirror.translate((0.0, 0.0, -(0.5 * d + sheet_thickness)))

        # Use user light if any have been given, otherwise use default values.
        if len(self._user_lights) == 0:
            self._user_lights = self._make_default_lights()

        # Create light nodes
        for light_data in self._user_lights:
            name = light_data["name"]
            light = Light(
                name=name,
                direction=light_data["direction"],
                wavelength=light_data["wavelength"],
                position=light_data["position"],
            )
            light_node = Node(name=name, light=light, parent=world)
            light_node.location = light_data["location"]
            if light_data["rotation"]:
                light_node.rotate(*light_data["rotation"])

        self._scene = Scene(world)