def test_follow_lossy_embedded_scene_1(): ray = Ray( position=(0.0, 0.0, -1.0), direction=(0.0, 0.0, 1.0), wavelength=555.0, is_alive=True ) scene, world, box = make_embedded_lossy_scene() np.random.seed(0) path = follow(ray, scene) path, decisions = zip(*path) positions = [x.position for x in path] expected_positions = [ (0.00, 0.00, -1.00), # Starting (0.00, 0.00, -0.50), # Hit box (0.00, 0.00, -0.50), # Reflection (0.00, 0.00, -0.3744069237034118), # Absorbed ] expected_decisions = [ Decision.EMIT, Decision.TRAVEL, Decision.TRANSIT, Decision.ABSORB, ] for expected_point, point, expected_decision, decision in zip( expected_positions, positions, expected_decisions, decisions): assert expected_decision == decision assert np.allclose(expected_point, point, atol=EPS_ZERO)
def test_follow_embedded_scene_2(): ray = Ray( position=(0.0, 0.0, -1.0), direction=(0.0, 0.0, 1.0), wavelength=555.0, is_alive=True ) scene, world, box = make_embedded_scene(n1=100.0) np.random.seed(0) path = follow(ray, scene) path, decisions = zip(*path) positions = [x.position for x in path] expected_positions = [ (0.00, 0.00, -1.00), # Starting (0.00, 0.00, -0.50), # Hit box (0.00, 0.00, -0.50), # Reflection (0.00, 0.00, -10.0), # Hit world node (0.00, 0.00, -10.0) # Ray killed ] expected_decisions = [ Decision.EMIT, Decision.TRAVEL, Decision.RETURN, Decision.TRAVEL, Decision.KILL ] for expected_point, point, expected_decision, decision in zip(expected_positions, positions, expected_decisions, decisions): assert expected_decision == decision assert np.allclose(expected_point, point, atol=EPS_ZERO)
def test_follow_touching_scene(): ray = Ray( position=(0.0, 0.0, -1.0), direction=(0.0, 0.0, 1.0), wavelength=555.0, is_alive=True ) scene, world, box1, box2, box3 = make_touching_scene() np.random.seed(0) path = follow(ray, scene) path, decisions = zip(*path) positions = [x.position for x in path] print(decisions) expected_positions = [ (0.00, 0.00, -1.00), # Starting (0.00, 0.00, -0.50), # Hit box (0.00, 0.00, -0.50), # Refraction into box (0.00, 0.00, 0.50), # Hit box (0.00, 0.00, 0.50), # Refraction (0.00, 0.00, 1.50), # Hit box (0.00, 0.00, 1.50), # Refraction (0.00, 0.00, 2.50), # Hit box (0.00, 0.00, 2.50), # Refraction (0.00, 0.00, 10.0), # Hit world node (0.00, 0.00, 10.0) # Kill ] expected_decisions = [ Decision.EMIT, Decision.TRAVEL, Decision.TRANSIT, Decision.TRAVEL, Decision.TRANSIT, Decision.TRAVEL, Decision.TRANSIT, Decision.TRAVEL, Decision.TRANSIT, Decision.TRAVEL, Decision.KILL ] for expected_point, point, expected_decision, decision in zip( expected_positions, positions, expected_decisions, decisions): assert np.allclose(expected_point, point, atol=EPS_ZERO) assert expected_decision == decision
def simulate(self, n, progress=None, emit_method="kT"): if self._scene is None: self._make_scene() scene = self._scene # Simulate can be called multiple time to append rays to the store if self._store is None: store = {"entrance_rays": [], "exit_rays": []} vis = self._renderer count = 0 for ray in scene.emit(n): history = photon_tracer.follow(scene, ray, emit_method=emit_method) rays, events = zip(*history) store["entrance_rays"].append((rays[1], events[1])) if events[-1] in (Event.ABSORB, Event.KILL): # final event is a lost store path information at final event store["exit_rays"].append((rays[-1], events[-1])) elif events[-1] == Event.EXIT: # final event hits the world node. Store path information at # penultimate location store["exit_rays"].append((rays[-2], events[-2])) # Update visualiser if vis: vis.add_history(history, **self._add_history_kwargs) # Progress callback if progress: count += 1 progress(count) self._store = store print("Tracing finished.") print("Preparing results.") df = self._make_dataframe() df = self.expand_coords(df, "direction") df = self.expand_coords(df, "position") df = self.label_facets(df, *self.size) self._df = df
def test_follow_embedded_lumophore_scene_1(): ray = Ray( position=(0.0, 0.0, -1.0), direction=(0.0, 0.0, 1.0), wavelength=555.0, is_alive=True ) scene, world, box = make_embedded_lumophore_scene() np.random.seed(0) path = follow(ray, scene) path, decisions = zip(*path) positions = [x.position for x in path] # First two are before box expected_positions = [ (0.00, 0.00, -1.00), # Starting (0.00, 0.00, -0.50), # Refraction into box ] assert len(expected_positions) < len(positions[:-1]) print("Expected: {}".format(expected_positions)) assert all([ np.allclose(expected, actual, atol=EPS_ZERO) for (expected, actual) in zip(expected_positions, positions[0:2]) ])
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)) # Make a renderer object and scene for tracing viewer = MeshcatRenderer(open_browser=True) scene = Scene(world) viewer.render(scene) # Generate some rays from the light source and trace them through the scene for ray in light.emit(10): info = photon_tracer.follow(ray, scene) rays, events = zip(*info) viewer.add_ray_path(rays) # Wait for Ctrl-C to terminate the script; keep the window open print("Ctrl-C to close") while True: try: time.sleep(.3) except KeyboardInterrupt: print("Bye") sys.exit()
) # Light source light = Light( divergence_delegate=functools.partial( Light.cone_divergence, np.radians(20) ) ) light_node = Node( name='light', parent=world_node, location=(0.0, 0.0, 1.0) ) light_node.rotate(np.radians(180), (1, 0, 0)) light_node.light = light scene = Scene(root=world_node) renderer = MeshcatRenderer(max_histories=None, open_browser=True) renderer.render(scene) if __name__ == "__main__": np.random.seed(1) for light_node in scene.light_nodes: for ray in light.emit(20): ray = ray.representation(light_node, world_node) steps = photon_tracer.follow(ray, scene, renderer=renderer) path, decisions = zip(*steps) print(decisions) renderer.add_ray_path(path)