Skip to content

Calculate noise approval

Import stuff

import os
import topogenesis as tg
import pyvista as pv
import trimesh as tm
import numpy as np

#pv.set_jupyter_backend("ipyvtklink")

# convert mesh to pv_mesh
def tri_to_pv(tri_mesh):
    faces = np.pad(tri_mesh.faces, ((0, 0),(1,0)), 'constant', constant_values=3)
    pv_mesh = pv.PolyData(tri_mesh.vertices, faces)
    return pv_mesh

Import Envelope Lattice/streetnetwork

# loading the lattice from csv
lattice_path = os.path.relpath('../data/meshes/voxelized_envelope_highres.csv')
envelope_lattice = tg.lattice_from_csv(lattice_path)
envelope_lattice.shape

env_cens = envelope_lattice.centroids_threshold(-1)

print (env_cens)

# import the streetnetwork as a point cloud (workshop file, temporary)
street_path = os.path.relpath("../data/meshes/street_points.csv")
street_pc = tg.cloud_from_csv(street_path)

print (street_pc)


#importing the context mesh

context_path = os.path.relpath('../data/meshes/immediate_context.obj')
context_mesh = tm.load(context_path)

Calculate euclidean distance between voxels and the street

# extracting the centroid of all voxels
env_cens = envelope_lattice.centroids_threshold(-1)
#print(env_cens.size)
# initializing the distance matrix
dist_m = []
# for each voxel ...
for voxel_cen in env_cens:
    # initializing the distance vector (per each voxel)
    dist_v = []
    # for each street point ...
    for street_point in street_pc:
        # find the difference vector
        diff = voxel_cen - street_point
        # raise the components to the power of two
        diff_p2 = diff**2
        # sum the components
        diff_p2s = diff_p2.sum()
        # compute the square root 
        dist = diff_p2s**0.5
        # add the distance to the distance vector
        dist_v.append(dist)
    # add the distance vector to the distance matrix
    dist_m.append(dist_v)
# change the distance matrix type, from list to array
dist_m = np.array(dist_m)
#print(dist_m.size, dist_m.shape)

# find the distance to the closest street point for each voxel
min_dist = dist_m.min(axis=1)

np_lat = np.array(env_cens)

# convert the minimum distance list to a lattice
min_dist_array = min_dist.reshape(envelope_lattice.shape)
min_dist_lat = tg.to_lattice(min_dist_array, envelope_lattice)

# zero the value of the exterior voxels
envelope_eu_dist_lattice = min_dist_lat * envelope_lattice

Saving the eucledean distance between voxels and street points (min_dist_lat)

min_dist_lat.to_csv('../data/fields/euclidean_distance.csv')

Plotting

# initiating the plotter
p = pv.Plotter()

l = envelope_eu_dist_lattice * envelope_lattice

# remapping
l = 250 * (l - l.min()) / l.max()

# Create the spatial reference
grid = pv.UniformGrid()

# Set the grid dimensions: shape because we want to inject our values
grid.dimensions = l.shape
# The bottom left corner of the data set
grid.origin = l.minbound
# These are the cell sizes along each axis
grid.spacing = l.unit

# Add the data values to the cell data
grid.point_arrays["Distance"] = l.flatten(order="F")  # Flatten the Lattice

# adding the meshes
p.add_mesh(tri_to_pv(context_mesh), opacity=0.1, style='wireframe')

# fast visualization of the point cloud
street_pc.fast_notebook_vis(p)

# adding the volume
opacity = np.array([0,0.6,0.6,0.6,0.6,0.6,0.6]) * 1.5
p.add_volume(grid, cmap="coolwarm", opacity=opacity, shade=True, show_scalar_bar=False)

# plotting
p.show()

Calculating the actual loudness level that is caused by the street

str_loud_lev = 73.4 #dB(a)

#calculating the actual loudness level
# act_loud_lev = ((1 / min_dist_lat) **2) * str_loud_lev

act_loud_lev = str_loud_lev - (10 * np.log10((2 * np.pi * min_dist_lat) / 2))

# convert the minimum distance list to a lattice
min_loud_array = act_loud_lev.reshape(envelope_lattice.shape)
min_loud_lat = tg.to_lattice(min_loud_array, envelope_lattice)

# zero the value of the exterior voxels
envelope_eu_loud_lattice = min_loud_lat * envelope_lattice

Import Football field points

# import the football field border as a point cloud, fifa being football
fifa = tg.cloud_from_csv('../data/meshes/football_field_points.csv')
# initiating the plotter
p = pv.Plotter()

# fast visualization of the lattice
envelope_lattice.fast_vis(p)

# fast visualization of the point cloud
fifa.fast_notebook_vis(p)

# adding the meshes
p.add_mesh(tri_to_pv(context_mesh), color='#aaaaaa')

# plotting
p.show(use_ipyvtk=False)

Calculate the eucledean distance between the voxels and the football field

# extracting the centroid of all voxels
env_cens = envelope_lattice.centroids_threshold(-1)

# initializing the distance matrix
dist_fifa_m = []
# for each voxel ...
for voxel_cen in env_cens:
    # initializing the distance vector (per each voxel)
    dist_v = []
    # for each street point ...
    for fifa_point in fifa:
        # find the difference vector
        diff = voxel_cen - fifa_point
        # raise the components to the power of two
        diff_p2 = diff**2
        # sum the components
        diff_p2s = diff_p2.sum()
        # compute the square root 
        dist = diff_p2s**0.5
        # add the distance to the distance vector
        dist_v.append(dist)
    # add the distance vector to the distance matrix
    dist_fifa_m.append(dist_v)
# change the distance matrix type, from list to array
dist_fifa_m = np.array(dist_fifa_m)

# find the distance to the closest street point for each voxel
min_dist = dist_fifa_m.min(axis=1)

np_lat = np.array(env_cens)

# convert the minimum distance list to a lattice
min_dist_array = min_dist.reshape(envelope_lattice.shape)
min_fifa_dist_lat = tg.to_lattice(min_dist_array, envelope_lattice)

# zero the value of the exterior voxels
envelope_fifa_eu_dist_lattice = min_dist_lat * envelope_lattice
# initiating the plotter
p = pv.Plotter()

l = envelope_fifa_eu_dist_lattice * envelope_lattice

# remapping
l = 250 * (l - l.min()) / l.max()

# Create the spatial reference
grid = pv.UniformGrid()

# Set the grid dimensions: shape because we want to inject our values
grid.dimensions = l.shape
# The bottom left corner of the data set
grid.origin = l.minbound
# These are the cell sizes along each axis
grid.spacing = l.unit

# Add the data values to the cell data
grid.point_arrays["Distance"] = l.flatten(order="F")  # Flatten the Lattice

# adding the meshes
p.add_mesh(tri_to_pv(context_mesh), opacity=0.1, style='wireframe')

# fast visualization of the point cloud
fifa.fast_notebook_vis(p)

# adding the volume
opacity = np.array([0,0.6,0.6,0.6,0.6,0.6,0.6]) * 1.5
p.add_volume(grid, cmap="coolwarm", opacity=opacity, shade=True, show_scalar_bar=False)

# plotting
p.show()

Calculate the noise that is caused by the football field

fifa_loud_lev = 73.4 #dB(a)

#calculating the actual loudness level
# act_loud_lev = ((1 / min_dist_lat) **2) * str_loud_lev

act_loud_fifa_lev = fifa_loud_lev - (10 * np.log10((2 * np.pi * min_fifa_dist_lat) / 2))

# convert the minimum distance list to a lattice
min_loud_array = act_loud_fifa_lev.reshape(envelope_lattice.shape)
min_loud_lat = tg.to_lattice(min_loud_array, envelope_lattice)

# zero the value of the exterior voxels
envelope_fifa_eu_loud_lattice = min_loud_lat * envelope_lattice

choice between Street Noise or Football field noise

# street noise lattice
envelope_eu_dist_lattice
# Football Field noise lattice
envelope_fifa_eu_loud_lattice
# Calculate the relative loudness level
act_loud_lev = np.maximum(envelope_eu_loud_lattice,envelope_fifa_eu_loud_lattice)

act_loud_lev_flat=act_loud_lev.flatten()
act_loud_lev_flat
dist_id=[]
for i in range(len(act_loud_lev_flat)):
    if act_loud_lev_flat[i] != 0:
        dist_id.append(i)
act_loud_lev_full=act_loud_lev_flat[act_loud_lev_flat>0]
act_loud_lev_norm=1-(act_loud_lev_full-act_loud_lev_full.min())/(act_loud_lev_full.max()-act_loud_lev_full.min())


for i in range(len(dist_id)):
    act_loud_lev_flat[dist_id[i]]=act_loud_lev_norm[i]


# reshape and construct a lattice from the football field network distance list
rel_loud_lev = act_loud_lev_flat.reshape(act_loud_lev.shape)
rel_loud_lev=rel_loud_lev*envelope_lattice

Plotting the actual loudness level (work in progress)

# initiating the plotter
p = pv.Plotter()

l = rel_loud_lev

# remapping
# l = 250 * (l - l.min()) / l.max()

# Create the spatial reference
grid = pv.UniformGrid()

# Set the grid dimensions: shape because we want to inject our values
grid.dimensions = l.shape
# The bottom left corner of the data set
grid.origin = l.minbound
# These are the cell sizes along each axis
grid.spacing = l.unit

# Add the data values to the cell data
grid.point_arrays["Distance"] = l.flatten(order="F")  # Flatten the Lattice

# adding the meshes
p.add_mesh(tri_to_pv(context_mesh), opacity=0.1, style='wireframe')

# fast visualization of the point cloud
street_pc.fast_notebook_vis(p)

# fast visualization of the football points
fifa.fast_notebook_vis(p)

# adding the volume
opacity = np.array([0,0.6,0.6,0.6,0.6,0.6,0.6]) * 1.5
p.add_volume(grid, cmap="coolwarm", opacity=opacity, shade=True, show_scalar_bar=False)

# plotting
p.show(use_ipyvtk=False)

saving the actual loudness level (work in progress)

Normalise and Inverse rel_loud_lev

# rel_loud_lev2 = rel_loud_lev
# # normalizing loudness
# min = rel_loud_lev2.min()
# rel_loud_lev2[rel_loud_lev2 == 1.] = 0.
# max = rel_loud_lev2.max()
# rel_loud_lev2 = (rel_loud_lev2 - min) / (max - min)
# # removing all voxels that are outside of mesh
# rel_loud_lev2[rel_loud_lev2 <= 0.] = 0.
# # set the lattice to be visualized
# l = rel_loud_lev
# # remapping
# # l =(l - l.min()) / (l.max()-l.min())

# # initiating the plotter
# p = pv.Plotter(notebook=True)

# # Create the spatial reference
# grid = pv.UniformGrid()

# # Set the grid dimensions: shape because we want to inject our values
# grid.dimensions = l.shape
# # The bottom left corner of the data set
# grid.origin = l.minbound
# # These are the cell sizes along each axis
# grid.spacing = l.unit

# # Add the data values to the cell data
# grid.point_arrays["football field distance"] = l.flatten(order="F")  # Flatten the Lattice

# # adding the meshes
# p.add_mesh(tri_to_pv(context_mesh), opacity=0.1, style='wireframe')

# # fast visualization of the point cloud
# fifa.fast_notebook_vis(p)

# # p.set_background("royalblue", top="aliceblue")
# # p.background = 'green'

# # adding the volume
# opacity = np.array([0,0.6,0.6,0.6,0.6,0.6,0.6])*1.5
# p.add_volume(grid, cmap="coolwarm",opacity=opacity, shade=True)

# #plotting
# cpos = [(314.348192231551, 283.381630231551, 296.74455709155103),
#  (65.08283250000001, -12.333572500000002, 21.07374465),
#  (0.0, 0.0, 1.0)]
# p.camera_position = cpos
# p.window_size = 2000, 1000
# p.show(use_ipyvtk=True)

Save the relative loudness

rel_loud_lev.to_csv('../data/fields/noise_approval.csv')