Upload app.py
Browse files
app.py
CHANGED
@@ -42,6 +42,7 @@ default_values = {
|
|
42 |
'max_rt_val': 0.0,
|
43 |
'new_absorption': {},
|
44 |
'fig1': None,
|
|
|
45 |
'df_sound_pressure': None,
|
46 |
'noise_reduction': None,
|
47 |
'df_current_absorption': None,
|
@@ -52,6 +53,7 @@ for key, value in default_values.items():
|
|
52 |
if key not in st.session_state:
|
53 |
st.session_state[key] = value
|
54 |
|
|
|
55 |
# Helper functions
|
56 |
def calculate_absorption_area(volume, reverberation_time):
|
57 |
return 0.161 * volume / reverberation_time if reverberation_time else float('inf')
|
@@ -191,6 +193,8 @@ def display_instructions():
|
|
191 |
'4000': [48, 49]
|
192 |
})
|
193 |
|
|
|
|
|
194 |
instructions = """
|
195 |
|
196 |
## Introduction
|
@@ -331,8 +335,11 @@ def display_instructions():
|
|
331 |
st.info("After reading the instructions, get your input data ready and proceed to the next step.")
|
332 |
|
333 |
def display_initial_data_entry():
|
334 |
-
st.write('''
|
|
|
|
|
335 |
See the 'Instructions' on the left for formatting information''')
|
|
|
336 |
st.write("#### Upload current reverberation times")
|
337 |
current_rt_file = st.file_uploader("Upload CSV or Excel file for current reverberation times", type=['csv', 'xlsx'],
|
338 |
help='Go to Instructions on the sidebar for formatting information.')
|
@@ -382,7 +389,9 @@ def display_initial_data_entry():
|
|
382 |
st.warning("Please ensure all input data has been provided correctly before proceeding.")
|
383 |
|
384 |
def display_initial_rt60_compliance_check():
|
385 |
-
st.write('''
|
|
|
|
|
386 |
standard RT60 range. For the purpose of this tool, compliance is achieved if RT60 values for all frequencies are
|
387 |
within the standard range. The graph at the bottom of this page would assist you in verifying compliance.
|
388 |
If at least one frequency is not in the range, you would need to apply some acoustic treatment. See the
|
@@ -460,7 +469,9 @@ def display_initial_rt60_compliance_check():
|
|
460 |
st.warning("Please provide the current reverberation times and existing materials data before proceeding.")
|
461 |
|
462 |
def display_desired_rt60():
|
463 |
-
st.write('''
|
|
|
|
|
464 |
calculate the desired sound absorption needed to achieve the desired RT60. Compare total frequency values
|
465 |
in the table below to the calculated current room sound absorption on the Initial RT60 Compliance Check tab
|
466 |
to inform your selection of new materials in the next step of the analysis''')
|
@@ -499,7 +510,9 @@ def display_desired_rt60():
|
|
499 |
st.warning("Please complete the previous steps before proceeding to set the desired RT60 values.")
|
500 |
|
501 |
def display_acoustic_treatment():
|
502 |
-
st.write("""
|
|
|
|
|
503 |
you are aiming to achieve. You now have to start working towards achieving the target absorptions. Based on the
|
504 |
differences between the desired sound absorptions (see Desired RT60 tab) and the calculated current room
|
505 |
sound absorptions (see Initial RT60 Compliance Check tab), you would need to introduce new materials to either
|
@@ -510,6 +523,7 @@ def display_acoustic_treatment():
|
|
510 |
concrete floor) you are allowed to make. For a retrofit project, you can change non-structural elements
|
511 |
like carpet and ceiling tiles. Additionally, you can introduce new materials like curtains.
|
512 |
""")
|
|
|
513 |
st.write("#### Upload new materials data")
|
514 |
new_materials_file = st.file_uploader("Upload CSV or Excel file for new materials", type=['csv', 'xlsx'],
|
515 |
help='Go to Instructions on the sidebar for formatting information.')
|
@@ -576,11 +590,13 @@ def display_acoustic_treatment():
|
|
576 |
st.warning("Please upload new materials data before proceeding.")
|
577 |
|
578 |
def display_final_rt60_compliance_check():
|
579 |
-
st.write("""
|
|
|
580 |
This is the last step in the RT60 analysis. To pass the final compliance check, the new RT60 for each
|
581 |
frequency must be within the standard RT60 range. If compliance fails, you need to go back to the Acoustic Treatment
|
582 |
stage to revise your materials. Update your new materials spreadsheet and upload on the Acoustic Treatment tab.
|
583 |
""")
|
|
|
584 |
if st.session_state.new_absorption and st.session_state.frequencies:
|
585 |
min_rt = {freq: st.session_state.min_rt_val for freq in st.session_state.frequencies}
|
586 |
max_rt = {freq: st.session_state.max_rt_val for freq in st.session_state.frequencies}
|
@@ -614,14 +630,18 @@ def display_final_rt60_compliance_check():
|
|
614 |
fig2.update_layout(title='Current RT60 and New RT60 vs. Standard Range', xaxis_title='Frequency (Hz)',
|
615 |
yaxis_title='Reverberation Time (s)')
|
616 |
st.plotly_chart(fig2)
|
|
|
617 |
|
618 |
st.success(
|
619 |
"After reflecting on the results, decide what to do next based on the expected outcome specified in your project brief.")
|
620 |
else:
|
621 |
st.warning("Please complete the previous steps before proceeding to the final RT60 compliance check.")
|
622 |
|
|
|
623 |
def display_intelligibility_noise_reduction():
|
624 |
-
st.write('''
|
|
|
|
|
625 |
coefficients and surface areas that were provided for reverberation time analysis. The relevant data
|
626 |
have copied to this tab for ease of reference. Note that you can update the new materials data by adding new rows
|
627 |
or deleting existing rows. Your can also directly edit the current new materials data information. All updates
|
@@ -707,10 +727,11 @@ def display_intelligibility_noise_reduction():
|
|
707 |
st.session_state.noise_reduction = noise_reduction
|
708 |
st.write(f"##### Noise Reduction: {noise_reduction:.2f} dB")
|
709 |
st.info('''The above noise reduction value is calculated total sound absorption for existing and new
|
710 |
-
material above. The noise reduction formula is shown below
|
711 |
NR = 10 * Log10(new materials total absorption/existing materials total absorption)
|
712 |
|
713 |
The above formula is the same as 10 * Log10(S alpha after/S alpha before''')
|
|
|
714 |
else:
|
715 |
st.error("Current total absorption is zero, which is not possible. Please check your data.")
|
716 |
|
@@ -718,7 +739,7 @@ def display_intelligibility_noise_reduction():
|
|
718 |
st.write("#### Updated Sound Pressure Levels")
|
719 |
st.info('''The values in the table below have been updated to account for the calculated noise reduction.
|
720 |
Note that these are logarithm deductions given that sound pressure level is in decibels. Plot the
|
721 |
-
updated sound pressure levels on your speech intelligibility Dot chart''')
|
722 |
updated_df = st.session_state.df_sound_pressure.copy()
|
723 |
|
724 |
# Ensure all values are numeric and fill NaN with 0
|
@@ -734,12 +755,12 @@ def display_intelligibility_noise_reduction():
|
|
734 |
|
735 |
# PDF Download Button
|
736 |
st.write("""
|
737 |
-
|
738 |
-
|
739 |
-
|
740 |
-
|
741 |
-
|
742 |
-
|
743 |
if st.button("Download PDF Report"):
|
744 |
pdf = generate_pdf(
|
745 |
st.session_state.volume,
|
|
|
42 |
'max_rt_val': 0.0,
|
43 |
'new_absorption': {},
|
44 |
'fig1': None,
|
45 |
+
'fig2': None, # Ensure fig2 is initialized
|
46 |
'df_sound_pressure': None,
|
47 |
'noise_reduction': None,
|
48 |
'df_current_absorption': None,
|
|
|
53 |
if key not in st.session_state:
|
54 |
st.session_state[key] = value
|
55 |
|
56 |
+
|
57 |
# Helper functions
|
58 |
def calculate_absorption_area(volume, reverberation_time):
|
59 |
return 0.161 * volume / reverberation_time if reverberation_time else float('inf')
|
|
|
193 |
'4000': [48, 49]
|
194 |
})
|
195 |
|
196 |
+
st.write('## Instructions')
|
197 |
+
|
198 |
instructions = """
|
199 |
|
200 |
## Introduction
|
|
|
335 |
st.info("After reading the instructions, get your input data ready and proceed to the next step.")
|
336 |
|
337 |
def display_initial_data_entry():
|
338 |
+
st.write('''## Initial Data Entry
|
339 |
+
|
340 |
+
The primary objective here is to provide all the initial input data needed to start RT60 analysis.
|
341 |
See the 'Instructions' on the left for formatting information''')
|
342 |
+
|
343 |
st.write("#### Upload current reverberation times")
|
344 |
current_rt_file = st.file_uploader("Upload CSV or Excel file for current reverberation times", type=['csv', 'xlsx'],
|
345 |
help='Go to Instructions on the sidebar for formatting information.')
|
|
|
389 |
st.warning("Please ensure all input data has been provided correctly before proceeding.")
|
390 |
|
391 |
def display_initial_rt60_compliance_check():
|
392 |
+
st.write('''## Initial RT60 Compliance Check
|
393 |
+
|
394 |
+
The aim of initial compliance check is to compare the current RT60 values to the
|
395 |
standard RT60 range. For the purpose of this tool, compliance is achieved if RT60 values for all frequencies are
|
396 |
within the standard range. The graph at the bottom of this page would assist you in verifying compliance.
|
397 |
If at least one frequency is not in the range, you would need to apply some acoustic treatment. See the
|
|
|
469 |
st.warning("Please provide the current reverberation times and existing materials data before proceeding.")
|
470 |
|
471 |
def display_desired_rt60():
|
472 |
+
st.write('''## Desired RT60
|
473 |
+
|
474 |
+
At this point in the analysis, you would need to define your desired RT60, which would be used to
|
475 |
calculate the desired sound absorption needed to achieve the desired RT60. Compare total frequency values
|
476 |
in the table below to the calculated current room sound absorption on the Initial RT60 Compliance Check tab
|
477 |
to inform your selection of new materials in the next step of the analysis''')
|
|
|
510 |
st.warning("Please complete the previous steps before proceeding to set the desired RT60 values.")
|
511 |
|
512 |
def display_acoustic_treatment():
|
513 |
+
st.write("""## Acoustic Treatment
|
514 |
+
|
515 |
+
The desired sound absorption calculated on the Desired RT60 tab is the target sound absorption
|
516 |
you are aiming to achieve. You now have to start working towards achieving the target absorptions. Based on the
|
517 |
differences between the desired sound absorptions (see Desired RT60 tab) and the calculated current room
|
518 |
sound absorptions (see Initial RT60 Compliance Check tab), you would need to introduce new materials to either
|
|
|
523 |
concrete floor) you are allowed to make. For a retrofit project, you can change non-structural elements
|
524 |
like carpet and ceiling tiles. Additionally, you can introduce new materials like curtains.
|
525 |
""")
|
526 |
+
|
527 |
st.write("#### Upload new materials data")
|
528 |
new_materials_file = st.file_uploader("Upload CSV or Excel file for new materials", type=['csv', 'xlsx'],
|
529 |
help='Go to Instructions on the sidebar for formatting information.')
|
|
|
590 |
st.warning("Please upload new materials data before proceeding.")
|
591 |
|
592 |
def display_final_rt60_compliance_check():
|
593 |
+
st.write("""## Final RT60 Compliance Check
|
594 |
+
|
595 |
This is the last step in the RT60 analysis. To pass the final compliance check, the new RT60 for each
|
596 |
frequency must be within the standard RT60 range. If compliance fails, you need to go back to the Acoustic Treatment
|
597 |
stage to revise your materials. Update your new materials spreadsheet and upload on the Acoustic Treatment tab.
|
598 |
""")
|
599 |
+
|
600 |
if st.session_state.new_absorption and st.session_state.frequencies:
|
601 |
min_rt = {freq: st.session_state.min_rt_val for freq in st.session_state.frequencies}
|
602 |
max_rt = {freq: st.session_state.max_rt_val for freq in st.session_state.frequencies}
|
|
|
630 |
fig2.update_layout(title='Current RT60 and New RT60 vs. Standard Range', xaxis_title='Frequency (Hz)',
|
631 |
yaxis_title='Reverberation Time (s)')
|
632 |
st.plotly_chart(fig2)
|
633 |
+
st.session_state.fig2 = fig2 # Save fig2 in session state
|
634 |
|
635 |
st.success(
|
636 |
"After reflecting on the results, decide what to do next based on the expected outcome specified in your project brief.")
|
637 |
else:
|
638 |
st.warning("Please complete the previous steps before proceeding to the final RT60 compliance check.")
|
639 |
|
640 |
+
|
641 |
def display_intelligibility_noise_reduction():
|
642 |
+
st.write('''## Intelligibility Noise Reduction
|
643 |
+
|
644 |
+
On this tab, you will calculate noise reduction using existing and new materials sound absorption
|
645 |
coefficients and surface areas that were provided for reverberation time analysis. The relevant data
|
646 |
have copied to this tab for ease of reference. Note that you can update the new materials data by adding new rows
|
647 |
or deleting existing rows. Your can also directly edit the current new materials data information. All updates
|
|
|
727 |
st.session_state.noise_reduction = noise_reduction
|
728 |
st.write(f"##### Noise Reduction: {noise_reduction:.2f} dB")
|
729 |
st.info('''The above noise reduction value is calculated total sound absorption for existing and new
|
730 |
+
material above. The noise reduction formula is shown below:
|
731 |
NR = 10 * Log10(new materials total absorption/existing materials total absorption)
|
732 |
|
733 |
The above formula is the same as 10 * Log10(S alpha after/S alpha before''')
|
734 |
+
|
735 |
else:
|
736 |
st.error("Current total absorption is zero, which is not possible. Please check your data.")
|
737 |
|
|
|
739 |
st.write("#### Updated Sound Pressure Levels")
|
740 |
st.info('''The values in the table below have been updated to account for the calculated noise reduction.
|
741 |
Note that these are logarithm deductions given that sound pressure level is in decibels. Plot the
|
742 |
+
updated sound pressure levels on your speech intelligibility Dot chart.''')
|
743 |
updated_df = st.session_state.df_sound_pressure.copy()
|
744 |
|
745 |
# Ensure all values are numeric and fill NaN with 0
|
|
|
755 |
|
756 |
# PDF Download Button
|
757 |
st.write("""
|
758 |
+
**IMPORTANT NOTE ABOUT PDF REPORT:** The purpose of the PDF report is to provide you detailed record of all
|
759 |
+
your input data and the graphs generated. Graphs in PDF report are of low resolutions. Hence, remember to download
|
760 |
+
individual graphs and tables to include in your report. Hover your mouse over a graph and several icons would
|
761 |
+
appear at the top right corner of the graph, click the first icon to download the graph. Repeat the same process
|
762 |
+
to download tables.
|
763 |
+
""")
|
764 |
if st.button("Download PDF Report"):
|
765 |
pdf = generate_pdf(
|
766 |
st.session_state.volume,
|