Spaces:
Running
Running
File size: 8,229 Bytes
c0b6f8f | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 | """
app.py
Entry point for the SONARIS Streamlit application. Runs as the top-level UI
shell. At this stage it is a project dashboard showing module status, dataset
acquisition progress, and navigation scaffolding. Module-specific pages are
added here as each module reaches a usable state.
Run locally with: streamlit run app.py
"""
import sys
import os
# Ensure the project root is on sys.path regardless of where Streamlit is
# invoked from. On Hugging Face Spaces, the working directory is the repo root,
# but local invocation from a subdirectory can break relative imports.
# This block resolves that without requiring the user to set PYTHONPATH manually.
_PROJECT_ROOT = os.path.dirname(os.path.abspath(__file__))
if _PROJECT_ROOT not in sys.path:
sys.path.insert(0, _PROJECT_ROOT)
import streamlit as st
from config import settings
# =============================================================================
# Page configuration β must be the first Streamlit call in the script
# =============================================================================
st.set_page_config(
page_title="SONARIS β Ship-Ocean Noise Acoustic Radiated Intelligence System",
page_icon="π",
layout="wide",
initial_sidebar_state="expanded",
)
# =============================================================================
# Sidebar
# =============================================================================
with st.sidebar:
st.title(settings.PROJECT_NAME)
st.caption(f"v{settings.PROJECT_VERSION} | {settings.PROJECT_LICENSE} License")
st.divider()
st.subheader("Navigation")
# Navigation options are placeholders. Each option will route to a dedicated
# Streamlit page once the corresponding module is built. For now they all
# render the "under construction" message in the main body.
nav_selection = st.radio(
label="Go to",
options=[
"Overview",
"Predict URN",
"Compliance Check",
"Bioacoustic Impact",
"Mitigation Planner",
"URN Database",
],
index=0,
label_visibility="collapsed",
)
st.divider()
st.subheader("Resources")
st.markdown(
f"""
- [GitHub Repository]({settings.PROJECT_GITHUB})
- [IMO MEPC.1/Circ.906 Rev.1](https://www.imo.org/en/OurWork/Environment/Pages/Underwater-noise.aspx)
- [ShipsEar Dataset](http://www.noiseatsea.es/)
- [QiandaoEar22 Dataset](https://arxiv.org/abs/2406.04354)
"""
)
st.divider()
st.caption(
"Built by a Naval Architecture student and music composer "
"working at the intersection of ship engineering and acoustic science."
)
# =============================================================================
# Main body
# =============================================================================
# Header
st.title("SONARIS")
st.subheader(settings.PROJECT_FULL_NAME)
col_m1, col_m2, col_m3 = st.columns(3)
with col_m1:
st.metric(label="IMO Guidelines", value=settings.IMO_GUIDELINES_VERSION)
with col_m2:
st.metric(label="Core Modules", value="6")
with col_m3:
st.metric(label="Status", value="Active Development")
st.divider()
# =============================================================================
# Routing: non-Overview pages
# =============================================================================
if nav_selection != "Overview":
st.info(
f"**{nav_selection}** module is under construction. "
"Check back as development progresses or follow the "
f"[GitHub repository]({settings.PROJECT_GITHUB}) for updates."
)
st.stop()
# =============================================================================
# Overview page content
# =============================================================================
# Mission statement
st.markdown(
"""
SONARIS predicts a ship's underwater radiated noise spectrum from hull geometry,
propeller parameters, and engine data, then checks the result against IMO
MEPC.1/Circ.906 Rev.1 (2024) limits and calculates the biological interference
caused to five groups of marine mammals. It is designed for shipyards, researchers,
and environmental organisations that need design-stage acoustic assessment and cannot
access proprietary tools. The platform is open-source and free to use, modify, and
deploy anywhere in the world.
"""
)
st.divider()
# =============================================================================
# Module Status Dashboard
# =============================================================================
st.header("Module Status")
# Row 1
row1_col1, row1_col2 = st.columns(2)
with row1_col1:
st.subheader("Module 1: Design Input Engine")
st.write(
"Accepts hull form coefficients, propeller geometry, engine type, "
"rated RPM, and operational speed in knots."
)
st.success("Coming Soon") # change to st.success("Active") once built
st.caption("Tech: Python, dataclasses, Pydantic validation")
with row1_col2:
st.subheader("Module 2: URN Prediction Core")
st.write(
"Predicts the full 1/3-octave band noise spectrum from 20 Hz to 20 kHz "
"using a hybrid physics simulation and deep learning pipeline."
)
st.success("Coming Soon")
st.caption("Tech: PyTorch, OpenFOAM, libAcoustics")
# Row 2
row2_col1, row2_col2 = st.columns(2)
with row2_col1:
st.subheader("Module 3: IMO Compliance Checker")
st.write(
"Checks the predicted URN spectrum against IMO MEPC.1/Circ.906 Rev.1 "
"(2024) limit tables and generates a downloadable compliance report."
)
st.success("Coming Soon")
st.caption("Tech: IMO limit tables, ReportLab PDF generation")
with row2_col2:
st.subheader("Module 4: Marine Bioacoustic Impact")
st.write(
"Maps ship noise against published audiogram curves for five marine mammal "
"hearing groups and computes a Biological Interference Score for each."
)
st.success("Coming Soon")
st.caption("Tech: librosa, scipy.signal, MFCC analysis")
# Row 3
row3_col1, row3_col2 = st.columns(2)
with row3_col1:
st.subheader("Module 5: Mitigation Recommendation Engine")
st.write(
"Produces speed reduction targets, geographic routing avoidance zones, "
"and hull and propeller modification suggestions ranked by expected dB reduction."
)
st.success("Coming Soon")
st.caption("Tech: Rule-based recommendation engine, routing data")
with row3_col2:
st.subheader("Module 6: Open URN Database")
st.write(
"A community-contributed, publicly searchable database of ship acoustic "
"signatures. The first open-source database of its kind."
)
st.success("Coming Soon")
st.caption("Tech: SQLite (dev), PostgreSQL (prod), public query API")
st.divider()
# =============================================================================
# Dataset Acquisition Status
# =============================================================================
st.header("Dataset Acquisition β Phase 1")
with st.expander("View dataset status", expanded=True):
dataset_status = {
"ShipsEar (Santos-Dominguez et al., 2016)": "Acquisition in progress",
"QiandaoEar22 (arXiv:2406.04354)": "Pending",
"Marine mammal audiograms (Southall et al., 2019)": "Pending",
"IMO MEPC.1/Circ.906 Rev.1 limit tables": "Pending",
}
for dataset, status in dataset_status.items():
col_ds, col_st = st.columns([3, 1])
with col_ds:
st.write(dataset)
with col_st:
if status == "Acquisition in progress":
st.warning(status)
else:
st.info(status)
# =============================================================================
# Footer
# =============================================================================
st.divider()
st.markdown(
f"<center style='color: grey; font-size: 0.85em;'>"
f"SONARIS v{settings.PROJECT_VERSION} | "
f"{settings.PROJECT_LICENSE} License | "
f"github.com/deringeorge-nebula/SONARIS"
f"</center>",
unsafe_allow_html=True,
) |