sadickam commited on
Commit
048d340
·
verified ·
1 Parent(s): 0865ad2

Upload 2 files

Browse files
Files changed (2) hide show
  1. app.py +229 -0
  2. requirements.txt +8 -0
app.py ADDED
@@ -0,0 +1,229 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import pandas as pd
3
+ import plotly.graph_objects as go
4
+ from fpdf import FPDF
5
+ import tempfile
6
+ import kaleido
7
+
8
+ # Set page configuration
9
+ st.set_page_config(
10
+ page_title="Building Acoustics Analysis Tool",
11
+ page_icon="🏫",
12
+ initial_sidebar_state="expanded" # Set sidebar to be expanded by default
13
+ )
14
+
15
+ # Title and instructional information
16
+ st.title("🔊 Building Acoustics Analysis (RT60)")
17
+
18
+ # Helper functions
19
+ def calculate_absorption_area(volume, reverberation_time):
20
+ if reverberation_time == 0:
21
+ return float('inf')
22
+ return 0.161 * volume / reverberation_time
23
+
24
+ def generate_pdf(volume, current_rt, existing_materials, min_rt, max_rt, desired_rt, new_materials, fig1, fig2):
25
+ pdf = FPDF()
26
+ pdf.add_page()
27
+ pdf.set_font("Arial", size=12)
28
+ pdf.cell(200, 10, txt="Room Acoustics Analysis Report", ln=True, align="C")
29
+ pdf.cell(200, 10, txt="Room Volume: {:.2f} m³".format(volume), ln=True)
30
+ pdf.cell(200, 10, txt="Current Reverberation Times (s):", ln=True)
31
+ for freq, rt in current_rt.items():
32
+ pdf.cell(200, 10, txt="{} Hz: {:.2f}".format(freq, rt), ln=True)
33
+ pdf.cell(200, 10, txt="Existing Materials and Absorption Coefficients:", ln=True)
34
+ for material in existing_materials:
35
+ pdf.cell(200, 10, txt="Material: {}, Area: {:.2f} m²".format(material['name'], material['area']), ln=True)
36
+ for freq, coeff in material['coefficients'].items():
37
+ pdf.cell(200, 10, txt="{} Hz: {:.2f}".format(freq, coeff), ln=True)
38
+ pdf.cell(200, 10, txt="Standard Reverberation Time Range (s):", ln=True)
39
+ for freq in min_rt.keys():
40
+ pdf.cell(200, 10, txt="{} Hz: {:.2f} - {:.2f}".format(freq, min_rt[freq], max_rt[freq]), ln=True)
41
+ pdf.cell(200, 10, txt="Desired Reverberation Times (s):", ln=True)
42
+ for freq, rt in desired_rt.items():
43
+ pdf.cell(200, 10, txt="{} Hz: {:.2f}".format(freq, rt), ln=True)
44
+ pdf.cell(200, 10, txt="New Materials and Absorption Coefficients:", ln=True)
45
+ for material in new_materials:
46
+ pdf.cell(200, 10, txt="Material: {}, Area: {:.2f} m²".format(material['name'], material['area']), ln=True)
47
+ for freq, coeff in material['coefficients'].items():
48
+ pdf.cell(200, 10, txt="{} Hz: {:.2f}".format(freq, coeff), ln=True)
49
+ # Save the figures as temporary files and add to the PDF
50
+ with tempfile.NamedTemporaryFile(delete=False, suffix=".png") as tmpfile1:
51
+ fig1.write_image(tmpfile1.name, engine='kaleido')
52
+ pdf.image(tmpfile1.name, x=10, y=None, w=180)
53
+ with tempfile.NamedTemporaryFile(delete=False, suffix=".png") as tmpfile2:
54
+ fig2.write_image(tmpfile2.name, engine='kaleido')
55
+ pdf.image(tmpfile2.name, x=10, y=None, w=180)
56
+ return pdf.output(dest='S').encode('latin1')
57
+
58
+ # Layout customizations
59
+ hide_menu_style = """
60
+ <style>
61
+ #MainMenu {visibility: hidden;}
62
+ footer {visibility: hidden;}
63
+ </style>
64
+ """
65
+ st.markdown(hide_menu_style, unsafe_allow_html=True)
66
+
67
+ # Sidebar with tabs
68
+ with st.sidebar:
69
+ st.header("Tabs")
70
+ tab = st.radio("Choose a tab", ["Instructions", "Initial Data Entry", "Initial RT60 Compliance Check",
71
+ "Desired RT60", "Acoustic Treatment", "Final RT60 Compliance Check"])
72
+
73
+ if tab == "Instructions":
74
+ st.write("""
75
+ ### Instructions for formatting input data
76
+ #### Current reverberation times
77
+ **File must be:** `current_reverberation_times.csv` or `current_reverberation_times.xlsx`\n
78
+ **Data format in file:**
79
+ - The first row should contain the frequency values as column headings.
80
+ - The second row should contain the reverberation times corresponding to each frequency.\n
81
+ **Example:**
82
+ ```
83
+ 125,250,500,1000,2000,4000
84
+ 0.8,0.7,0.6,0.5,0.4,0.3
85
+ ```
86
+ #### Existing materials absorption coefficients and areas
87
+ **File must be:** `existing_materials.csv` or `existing_materials.xlsx`\n
88
+ **Data format in file:**
89
+ - The first column should contain the material names.
90
+ - The second column should contain the surface areas of the materials (in square meters).
91
+ - The subsequent columns should contain absorption coefficients for different frequencies.\n
92
+ **Example:**
93
+ ```
94
+ Material Name,Area (m²),125,250,500,1000,2000,4000
95
+ Carpet,50,0.1,0.15,0.2,0.3,0.4,0.5
96
+ Curtain,30,0.2,0.25,0.3,0.35,0.45,0.55
97
+ ```
98
+ #### New materials absorption coefficients and areas
99
+ **File Name:** `new_materials.csv` or `new_materials.xlsx`\n
100
+ **Format:**
101
+ - The first column should contain the material names.
102
+ - The second column should contain the surface areas of the materials (in square meters).
103
+ - The subsequent columns should contain absorption coefficients for different frequencies.\n
104
+ **Example:**
105
+ ```
106
+ Material Name,Area (m²),125,250,500,1000,2000,4000
107
+ Acoustic Panel,40,0.3,0.35,0.4,0.45,0.5,0.6
108
+ Foam,20,0.25,0.3,0.35,0.4,0.45,0.55
109
+ ```
110
+ ### General tips
111
+ - Ensure the files are saved in CSV or Excel format.
112
+ - The column headings must be spelled correctly and consistently.
113
+ - Avoid including any extra rows or columns outside of the specified format.
114
+ - Check for and correct any typographical errors in the column headings.
115
+ ### Uploading the files
116
+ - **Current Reverberation Times:** Upload the file in the "Upload Current Reverberation Times" section on Initial Data Entry tab.
117
+ - **Existing Materials Data:** Upload the file in the "Upload Existing Materials Data" section on Initial Data Entry tab.
118
+ - **New Materials Data:** Upload the file in the "Upload New Materials Data" section on the Acoustic Treatment tab.
119
+ """)
120
+
121
+ elif tab == "Initial Data Entry":
122
+ st.write('''The primary objective here is to provide all the initial input data needed to start RT60 analysis.
123
+ See the 'Instructions' on the left for formatting information''')
124
+ st.write("#### Upload current reverberation times")
125
+ current_rt_file = st.file_uploader("Upload CSV or Excel file for current reverberation times", type=['csv', 'xlsx'],
126
+ help='Go to Instructions on the sidebar for formatting information.')
127
+
128
+ current_rt = {}
129
+ frequencies = []
130
+ if current_rt_file:
131
+ try:
132
+ if current_rt_file.name.endswith('.csv'):
133
+ df_current_rt = pd.read_csv(current_rt_file, header=None)
134
+ else:
135
+ df_current_rt = pd.read_excel(current_rt_file, header=None)
136
+ frequencies = df_current_rt.iloc[0].tolist()
137
+ current_rt = dict(zip(frequencies, df_current_rt.iloc[1].tolist()))
138
+ st.write("Current reverberation times:")
139
+ st.dataframe(df_current_rt, use_container_width=True)
140
+ except Exception as e:
141
+ st.error(f"Error reading current reverberation times file: {e}")
142
+
143
+ st.write("#### Upload existing materials data")
144
+ existing_materials_file = st.file_uploader("Upload CSV or Excel file for existing materials", type=['csv', 'xlsx'],
145
+ help='Go to Instructions on the sidebar for formatting information.')
146
+
147
+ existing_materials = []
148
+ if existing_materials_file:
149
+ try:
150
+ if existing_materials_file.name.endswith('.csv'):
151
+ df_existing_materials = pd.read_csv(existing_materials_file)
152
+ else:
153
+ df_existing_materials = pd.read_excel(existing_materials_file)
154
+ st.write("Existing Materials Data:")
155
+ st.dataframe(df_existing_materials, use_container_width=True)
156
+ for _, row in df_existing_materials.iterrows():
157
+ material = {
158
+ 'name': row[0],
159
+ 'area': row[1],
160
+ 'coefficients': dict(zip(frequencies, row[2:].tolist()))
161
+ }
162
+ existing_materials.append(material)
163
+ except Exception as e:
164
+ st.error(f"Error reading existing materials file: {e}")
165
+
166
+ elif tab == "Initial RT60 Compliance Check":
167
+ st.write("Performing initial RT60 compliance check...")
168
+ if not current_rt:
169
+ st.warning("Please upload current reverberation times in the Initial Data Entry tab.")
170
+ else:
171
+ min_rt = {freq: 0.2 for freq in frequencies} # Placeholder values
172
+ max_rt = {freq: 0.6 for freq in frequencies} # Placeholder values
173
+ out_of_bounds = {freq: rt for freq, rt in current_rt.items() if rt < min_rt.get(freq, 0) or rt > max_rt.get(freq, 0)}
174
+ st.write("Initial RT60 Compliance Check Results:")
175
+ if out_of_bounds:
176
+ st.warning("Some frequencies are out of the standard RT60 range:")
177
+ st.write(out_of_bounds)
178
+ else:
179
+ st.success("All frequencies are within the standard RT60 range.")
180
+
181
+ elif tab == "Desired RT60":
182
+ st.write("Specify the desired reverberation times for different frequencies.")
183
+ desired_rt = {}
184
+ for freq in frequencies:
185
+ rt = st.number_input(f"Desired RT60 at {freq} Hz", value=0.5, format="%.2f")
186
+ desired_rt[freq] = rt
187
+ st.write("Desired RT60 Values:")
188
+ st.write(desired_rt)
189
+
190
+ elif tab == "Acoustic Treatment":
191
+ st.write("Upload new materials data for acoustic treatment.")
192
+ new_materials_file = st.file_uploader("Upload CSV or Excel file for new materials", type=['csv', 'xlsx'],
193
+ help='Go to Instructions on the sidebar for formatting information.')
194
+
195
+ new_materials = []
196
+ if new_materials_file:
197
+ try:
198
+ if new_materials_file.name.endswith('.csv'):
199
+ df_new_materials = pd.read_csv(new_materials_file)
200
+ else:
201
+ df_new_materials = pd.read_excel(new_materials_file)
202
+ st.write("New Materials Data:")
203
+ st.dataframe(df_new_materials, use_container_width=True)
204
+ for _, row in df_new_materials.iterrows():
205
+ material = {
206
+ 'name': row[0],
207
+ 'area': row[1],
208
+ 'coefficients': dict(zip(frequencies, row[2:].tolist()))
209
+ }
210
+ new_materials.append(material)
211
+ except Exception as e:
212
+ st.error(f"Error reading new materials file: {e}")
213
+
214
+ elif tab == "Final RT60 Compliance Check":
215
+ st.write("Perform final RT60 compliance check after applying acoustic treatment.")
216
+ if not desired_rt:
217
+ st.warning("Please specify desired RT60 values in the Desired RT60 tab.")
218
+ elif not new_materials:
219
+ st.warning("Please upload new materials data in the Acoustic Treatment tab.")
220
+ else:
221
+ # Placeholder calculations
222
+ final_rt = {freq: 0.5 for freq in frequencies} # Replace with actual calculation
223
+ st.write("Final RT60 Compliance Check Results:")
224
+ out_of_bounds = {freq: rt for freq, rt in final_rt.items() if rt < 0.2 or rt > 0.6}
225
+ if out_of_bounds:
226
+ st.warning("Some frequencies are out of the desired RT60 range:")
227
+ st.write(out_of_bounds)
228
+ else:
229
+ st.success("All frequencies are within the desired RT60 range.")
requirements.txt ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ streamlit==1.24.0
2
+ pandas==2.0.3
3
+ plotly==5.15.0
4
+ fpdf==1.7.2
5
+ matplotlib==3.7.1
6
+ altair<5
7
+ openpyxl==3.1.2
8
+ kaleido==0.2.1