def test_same_wall_false3D(self): w1 = pra.wall_factory( wall_corners_3D[0], absorptions_3D[:1], scatterings_3D[:1] ) w2 = pra.wall_factory( wall_corners_3D[1], absorptions_3D[:1], scatterings_3D[:1] ) self.assertTrue(not w1.same_as(w2))
def test_same_wall_false3D_more_corners(self): # Modification of wall_corners_3D[0]: adding a corner => 5 corners wall c1 = np.array([[0, 3, 3, 1.5, 0], [0, 0, 0, 0, 0], [0, 0, 2, 1.5, 2]]) w1 = pra.wall_factory(wall_corners_3D[0], absorptions_3D[:1], scatterings_3D[:1]) w2 = pra.wall_factory(c1, absorptions_3D[:1], scatterings_3D[:1]) self.assertTrue(not w1.same_as(w2))
def test_wall_3d_normal_0(): """Tests direction of normal wrt to point arrangement""" w_info = walls[0] wall1 = pra.wall_factory(w_info["corners"], [0.2], [0.1]) # the same wall with normal pointing the other way wall2 = pra.wall_factory(w_info["corners"][:, ::-1], [0.2], [0.1]) err = np.linalg.norm(wall1.normal + wall2.normal) assert err < eps, "The error is {}".format(err)
def test_wall_3d_normal_1(): ''' Tests direction of normal wrt to point arrangement ''' w_info = walls[1] wall1 = pra.wall_factory(w_info['corners'], [0.2], [0.1]) # the same wall with normal pointing the other way wall2 = pra.wall_factory(w_info['corners'][:, ::-1], [0.2], [0.1]) err = np.linalg.norm(wall1.normal + wall2.normal) assert err < eps, 'The error is {}'.format(err)
def test_scat_ray_ok(self): walls = [ pra.wall_factory(c, [a], [s]) for c, a, s in zip( wall_corners_2D_non_convex, absorptions_2D, scatterings_2D) ] obstructing_walls = [1, 2] microphones = np.array([[0.5], [0.2]]) room = room_factory(walls, obstructing_walls, microphones) room.set_params( pra.constants.get("c"), 2, # order of ISM 0.001, # energy threshold for rays 200.0, # time threshold for rays 0.1, # detector radius 0.004, # histogram time resolution True, # hybrid model ) prev_wall = room.get_wall(0) prev_last_hit = [2, 0.2] last_hit = [0, 1.9] total_dist = 0.0 energy = [1000000.0] scatter_coef = scatterings_2D[0] output = [[pra.libroom.Hit(1)] ] # arbitrary initialisation to have the correct shape self.assertTrue( room.scat_ray(energy, prev_wall, prev_last_hit, last_hit, total_dist))
def test_max_dist_3D(self): walls = [ pra.wall_factory(c, [a], [s]) for c, a, s in zip(wall_corners_3D, absorptions_3D, scatterings_2D) ] obstructing_walls = [] microphones = np.array([ [ 1, ], [ 1, ], [ 1, ], ]) room = room_factory(walls, obstructing_walls, microphones) eps = 0.001 result = room.get_max_distance() correct = np.sqrt(116) + 1 self.assertTrue(abs(result - correct) < eps)
def create_walls(obstacle_faces, materials): """Returns a list of Wall objects that can be used in the Room constructor Args: obstacle_faces (array/list of Nx3 numpy 2D matrices): Same as the output of make_polygon. Each element of this is a 2D matrix representing a wall, each row is a coordinate of a vertex. material (pra.Material): Material of the wall Returns: list of Wall objects: Can be directly use in Room constructor """ material_list = False if isinstance(materials, list): if len(materials) != len(obstacle_faces): raise TypeError( "list of materials should be same length as obstacle_faces") else: material_list = True elif not isinstance(materials, pra.Material): raise TypeError( "materials should be pra.Material or list of pra.Material") walls = [] for i in range(len(obstacle_faces)): m = materials[i] if material_list else materials walls.append( pra.wall_factory(obstacle_faces[i].T, m.energy_absorption["coeffs"], m.scattering["coeffs"])) return walls
def test_reflected_end3D(self): eps = 0.001 start = [1, 1, 1] hit = [-1, 1, 3] #normal = [1, 0, 0] corners = np.array([ [ -1, -1, -1, -1, ], [ 0, 2, 2, 0, ], [ 2, 2, 4, 4, ], ]) wall = pra.wall_factory(corners, [0.1], [0.1]) length = 2 * np.sqrt(2) res = wall.normal_reflect(start, hit, length) self.assertTrue(np.allclose(res, [1, 1, 5], atol=eps))
def test_wall_3d_area_1(): """Tests the area computation""" w_info = walls[1] wall = pra.wall_factory(w_info["corners"], w_info["absorption"], w_info["scattering"]) err = abs(wall.area() - w_info["area"]) assert err < 1, "The error is {}".format(err)
def test_wall_3d_area_1(): ''' Tests the area computation ''' w_info = walls[1] wall = pra.wall_factory(w_info['corners'], w_info['absorption'], w_info['scattering']) err = abs(wall.area() - w_info['area']) assert err < 1, 'The error is {}'.format(err)
def test_next_wall_nohit(self): walls = [ pra.wall_factory(c, [a], [s]) for c, a, s in zip(wall_corners_3D, absorptions_3D, scatterings_3D) ] obstructing_walls = [] microphones = np.array([ [ 1, ], [ 1, ], [ 1, ], ]) room = room_factory(walls, obstructing_walls, microphones) eps = 0.001 # start outside the room start = [-1, -1, -1] # end outside the room end = [-2, -3, -1] ttuple = np.array(room.next_wall_hit(start, end, False)) self.assertTrue(ttuple[1] == -1)
def test_room_construct(): walls = [ pra.wall_factory(c, [a], [s]) for c, a, s in zip(wall_corners, absorptions, scatterings) ] obstructing_walls = [] microphones = np.array([[1], [2], [1]]) room = pra.libroom.Room( walls, [], [], pra.constants.get("c"), # speed of sound 3, 1e-7, # energy_thres 1.0, # time_thres 0.5, # receiver_radius 0.004, # hist_bin_size True, # a priori we will always use a hybrid model ) print(room.max_dist) return room
def run_side(label): p = points[label]['p'] r_exp = points[label]['expect'] d = points[label]['d'] wall = pra.wall_factory(corners[d], [0.1], [0.1]) r = wall.side(p) print('{}: returned={} expected={}'.format(label, r, r_exp)) return r == r_exp
def run_side(label): p = points[label]["p"] r_exp = points[label]["expect"] d = points[label]["d"] wall = pra.wall_factory(corners[d], [0.1], [0.1]) r = wall.side(p) print("{}: returned={} expected={}".format(label, r, r_exp)) return r == r_exp
def test_notcontains_3D(self): walls = [ pra.wall_factory(c, [a], [s]) for c, a, s in zip(wall_corners_3D, absorptions_3D, scatterings_3D) ] obstructing_walls = [] microphones = np.array([[5.0], [7.0], [40]]) room = room_factory(walls, obstructing_walls, microphones) self.assertTrue(not room.contains(microphones[:, 0]))
def test_contains_2D(self): walls = [ pra.wall_factory(c, [a], [s]) for c, a, s in zip( wall_corners_2D_non_convex, absorptions_2D, scatterings_2D) ] obstructing_walls = [] microphones = np.array([[0.5], [0.2]]) room = room_factory(walls, obstructing_walls, microphones) self.assertTrue(room.contains(microphones[:, 0]))
def test_reflected_end2D(self): eps = 0.001 start = [1, 3] hit = [5, 3] #normal = [-1, -1] corners = np.array([ [6, 4], [4, 6], ]) wall = pra.wall_factory(corners, [0.1], [0.1]) length = 4 res = wall.normal_reflect(start, hit, length) self.assertTrue(np.allclose(res, [5., -1.], atol=eps))
def run_reflect(label): p = points[label]['p'] p_refl = np.array(points[label]['reflect']) r_exp = points[label]['expect'] d = points[label]['d'] wall = pra.wall_factory(corners[d], [0.1], [0.1]) x = np.zeros(wall.dim, dtype=np.float32) wall.reflect(p, x) err = np.linalg.norm(x - p_refl) < eps print('{}: error={}'.format(label, err)) return err
def test_next_wall_hit(self): walls = [ pra.wall_factory(c, [a], [s]) for c, a, s in zip(wall_corners_3D, absorptions_3D, scatterings_3D) ] obstructing_walls = [] microphones = np.array([ [ 1.0, ], [ 1.0, ], [ 1.0, ], ]) room = room_factory(walls, obstructing_walls, microphones) eps = 0.001 # start on one empty space start = [-2, 4, 1] # end at the same (x,y) but very high in the sky end = [5, -3, 1] # correct intersection result = np.array([0, 2, 1]) ttuple = np.array(room.next_wall_hit(start, end, False)) correct_result = np.allclose(ttuple[0], result, atol=eps) correct_next_wall = ttuple[1] == 4 correct_distance = np.allclose(ttuple[2], np.linalg.norm(result - start)) self.assertTrue(correct_next_wall and correct_result and correct_distance)
def test_max_dist_2D(self): walls = [ pra.wall_factory(c, [a], [s]) for c, a, s in zip(wall_corners_2D, absorptions_2D, scatterings_2D) ] obstructing_walls = [] microphones = np.array([ [ 1, ], [ 1, ], ]) room = room_factory(walls, obstructing_walls, microphones) eps = 0.001 result = room.get_max_distance() self.assertEqual(result, np.sqrt(25) + 1)
def load_room(inpath): with open(inpath, 'r') as file: # get room dict rdin = yaml.load(file, Loader=yaml.FullLoader) walls = [] for w in rdin['walls']: # TODO: checks for value and type of attributes wcorners = np.array(w['corners']).T mat = pra.Material(w['material']['absorption'], w['material']['scattering']) walls.append( pra.wall_factory(wcorners, mat.energy_absorption['coeffs'], mat.scattering['coeffs'])) room = pra.Room(walls, fs=rdin['fs'], max_order=rdin['max_order'], air_absorption=rdin['air_absorption'], ray_tracing=rdin['ray_tracing']) return room
path_to_musis_stl_file = "./data/raw/MUSIS_3D_no_mics_simple.stl" material = pra.Material(energy_absorption=0.2, scattering=0.1) # with numpy-stl the_mesh = mesh.Mesh.from_file(args.file) ntriang, nvec, npts = the_mesh.vectors.shape size_reduc_factor = 500.0 # to get a realistic room size (not 3km) # create one wall per triangle walls = [] for w in range(ntriang): walls.append( pra.wall_factory( the_mesh.vectors[w].T / size_reduc_factor, material.energy_absorption["coeffs"], material.scattering["coeffs"], )) room = (pra.Room( walls, fs=16000, max_order=3, ray_tracing=True, air_absorption=True, ).add_source([-2.0, 2.0, 1.8]).add_microphone_array(np.c_[[-6.5, 8.5, 3 + 0.1], [-6.5, 8.1, 3 + 0.1]])) # compute the rir room.image_source_model()
def add_obstacle(box, obstacle_faces, material): for face in obstacle_faces: box.walls.append( pra.wall_factory(face.T, material.energy_absorption["coeffs"], material.scattering["coeffs"]))
def test_square_room(self): """ This is a cubic room of 2x2x2 meters. The source is placed at [0.5,0.5, 1] and the receiver at [1.5, 1.5, 1]. A ray is launched towards [1, 0, 1] so that the first receiver hit is after travel distance of 2*sqrt(2) and each subsequent hit travels a further 4*sqrt(2) until the threshold energy is reached. """ energy_absorption = 0.07 round_trip = 4 * np.sqrt(2) energy_thresh = 1e-7 detector_radius = 0.15 hist_bin_size = 0.004 # resolution of histogram [s] histogram_gt = SimpleHistogram(hist_bin_size * pra.constants.get("c")) # Create the groundtruth list of energy and travel time initial_energy = 2.0 # defined in libroom.Room.get_rir_entries transmitted = 1.0 * (1.0 - energy_absorption)**2 * initial_energy distance = round_trip / 2.0 while transmitted / distance > energy_thresh: r_sq = distance**2 p_hit = 1.0 - np.sqrt(1.0 - detector_radius**2 / r_sq) histogram_gt.add(distance, transmitted / (r_sq * p_hit)) transmitted *= (1.0 - energy_absorption)**4 # 4 wall hits distance += round_trip print("Creating the python room (polyhedral)") walls_corners = [ np.array([[0, 2, 2, 0], [0, 0, 0, 0], [0, 0, 2, 2]]), # left np.array([[0, 0, 2, 2], [2, 2, 2, 2], [0, 2, 2, 0]]), # right np.array([[0, 0, 0, 0], [0, 2, 2, 0], [0, 0, 2, 2]]), # front` np.array([[2, 2, 2, 2], [0, 0, 2, 2], [0, 2, 2, 0]]), # back np.array([ [0, 2, 2, 0], [0, 0, 2, 2], [0, 0, 0, 0], ]), # floor np.array([ [0, 0, 2, 2], [0, 2, 2, 0], [2, 2, 2, 2], ]), # ceiling ] walls = [ pra.wall_factory(c, [energy_absorption], [0.0]) for c in walls_corners ] room_poly = pra.Room(walls, fs=16000) # room = pra.Room(walls, fs=16000) room_poly.add_source([0.5, 0.5, 1]) room_poly.add_microphone_array( pra.MicrophoneArray(np.c_[[1.5, 1.5, 1.0]], room_poly.fs)) room_poly.room_engine.set_params( room_poly.c, 0, energy_thresh, # energy threshold for rays 5.0, # time threshold for rays detector_radius, # detector radius hist_bin_size, # resolution of histogram [s] False, # is it hybrid model ? ) print("Running ray tracing (polyhedral)") room_poly.room_engine.ray_tracing( np.c_[[-np.pi / 4.0, np.pi / 2.0]], room_poly.sources[0].position, # source loc ) print("Creating the python room (shoebox)") room_cube = pra.ShoeBox([2, 2, 2], fs=16000, materials=pra.Material(energy_absorption)) # room = pra.Room(walls, fs=16000) room_cube.add_source([0.5, 0.5, 1]) room_cube.add_microphone_array( pra.MicrophoneArray(np.c_[[1.5, 1.5, 1.0]], room_poly.fs)) room_cube.room_engine.set_params( room_poly.c, 0, energy_thresh, # energy threshold for rays 5.0, # time threshold for rays detector_radius, # detector radius hist_bin_size, # resolution of histogram [s] False, # is it hybrid model ? ) print("Running ray tracing (shoebox)") room_cube.room_engine.ray_tracing( np.c_[[-np.pi / 4.0, np.pi / 2.0]], room_cube.sources[0].position, # source loc ) h_poly = room_poly.room_engine.microphones[0].histograms[0].get_hist() h_cube = room_cube.room_engine.microphones[0].histograms[0].get_hist() histogram_rt_poly = np.array(h_poly[0])[:len(histogram_gt)] histogram_rt_cube = np.array(h_cube[0])[:len(histogram_gt)] self.assertTrue(np.allclose(histogram_rt_poly, histogram_gt)) self.assertTrue(np.allclose(histogram_rt_cube, histogram_gt))
def test_wall_3d_construct_1(): ''' Tests construction of a wall ''' w_info = walls[1] wall = pra.wall_factory(w_info['corners'], [0.2], [0.1]) return wall
def test_wall_3d_construct_1(): """Tests construction of a wall""" w_info = walls[1] wall = pra.wall_factory(w_info["corners"], [0.2], [0.1]) return wall