tsunami / src /tsuwave /dashboard /wave_front_map.py
Gitdeeper4's picture
رفع جميع ملفات TSU-WAVE مع YAML
12834b7
Raw History Blame Contribute Delete
5.51 kB
"""Wave front propagation map visualization"""
import streamlit as st
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Circle
import plotly.graph_objects as go
from typing import Optional, Tuple
def create_synthetic_bathymetry(size: int = 100) -> Tuple[np.ndarray, np.ndarray, np.ndarray]:
"""Create synthetic bathymetry for demonstration"""
x = np.linspace(-500, 500, size)
y = np.linspace(-500, 500, size)
X, Y = np.meshgrid(x, y)
# Simple continental shelf profile
r = np.sqrt(X**2 + Y**2)
depth = -5000 + 0.1 * r # Depth increases with distance
depth = np.clip(depth, -6000, 0)
return X, Y, depth
def create_wave_front(r: np.ndarray, t: float, speed: float = 0.5) -> np.ndarray:
"""Create synthetic wave front"""
return 5 * np.exp(-(r - 300 - speed * t)**2 / 5000)
def display_wave_front_map(zone: str = "global",
show_bathymetry: bool = True,
show_front: bool = True,
time_step: int = 0):
"""Display interactive wave front map"""
# Create data
X, Y, depth = create_synthetic_bathymetry()
r = np.sqrt(X**2 + Y**2)
wave = create_wave_front(r, time_step)
# Create figure
fig, ax = plt.subplots(figsize=(12, 8))
if show_bathymetry:
contour = ax.contourf(X, Y, depth, levels=20, cmap='Blues_r', alpha=0.6)
plt.colorbar(contour, ax=ax, label='Depth (m)')
if show_front:
front_contour = ax.contour(X, Y, wave, levels=[2, 4, 6],
colors='red', linewidths=2)
ax.clabel(front_contour, inline=True, fontsize=10)
# Mark shoreline
ax.axhline(y=0, color='brown', linestyle='-', linewidth=2, label='Shoreline')
# Add coast
coast_x = np.linspace(-500, 500, 100)
coast_y = 50 * np.exp(-coast_x**2 / 50000)
ax.fill_between(coast_x, 0, coast_y, color='green', alpha=0.3, label='Land')
# Labels and formatting
ax.set_xlabel('Distance (km)', fontsize=12)
ax.set_ylabel('Distance (km)', fontsize=12)
ax.set_title(f'Tsunami Wave Front Propagation - {zone}', fontsize=14)
ax.grid(True, alpha=0.3)
ax.legend()
# Set limits
ax.set_xlim(-500, 500)
ax.set_ylim(-500, 200)
# Add scale bar
ax.plot([-400, -300], [-450, -450], 'k-', linewidth=3)
ax.text(-350, -470, '100 km', ha='center')
return fig
def display_interactive_map():
"""Display interactive map with Plotly"""
# Create data
x = np.linspace(-500, 500, 100)
y = np.linspace(-500, 200, 70)
X, Y = np.meshgrid(x, y)
# Bathymetry
r = np.sqrt(X**2 + Y**2)
depth = -5000 + 0.1 * r
depth = np.clip(depth, -6000, 0)
# Wave front
wave = 5 * np.exp(-(r - 300)**2 / 5000)
# Create figure
fig = go.Figure()
# Add bathymetry heatmap
fig.add_trace(go.Contour(
z=depth,
x=x, y=y,
colorscale='Blues',
showscale=True,
colorbar=dict(title="Depth (m)"),
name="Bathymetry"
))
# Add wave front contours
fig.add_trace(go.Contour(
z=wave,
x=x, y=y,
contours=dict(
coloring='none',
showlabels=True,
labelfont=dict(size=12, color='red')
),
line=dict(color='red', width=2),
showscale=False,
name="Wave Front"
))
# Add shoreline
fig.add_shape(
type="line",
x0=-500, y0=0, x1=500, y1=0,
line=dict(color="brown", width=3, dash="solid"),
name="Shoreline"
)
# Update layout
fig.update_layout(
title="Tsunami Wave Front - Interactive Map",
xaxis_title="Distance (km)",
yaxis_title="Distance (km)",
width=800,
height=600,
hovermode='closest'
)
return fig
def get_front_properties(wcc: float = 1.31,
hfsi: float = 0.63,
distance: float = 180) -> dict:
"""Get wave front properties"""
# Calculate ETA based on distance and speed
speed = 200 # m/s approximate
eta_minutes = distance * 1000 / speed / 60
return {
"celerity": wcc,
"stability": hfsi,
"distance_to_shore_km": distance,
"eta_minutes": eta_minutes,
"status": "ALERT" if hfsi < 0.6 else "MONITOR",
"front_width_km": 50,
"amplification_factor": 2.5
}
def display_front_properties_panel(properties: dict):
"""Display wave front properties panel"""
col1, col2 = st.columns(2)
with col1:
st.metric("Celerity (WCC)", f"{properties['celerity']:.2f}")
st.metric("Distance to Shore", f"{properties['distance_to_shore_km']} km")
st.metric("Front Width", f"{properties['front_width_km']} km")
with col2:
st.metric("Stability (HFSI)", f"{properties['stability']:.2f}")
st.metric("ETA to Landfall", f"{properties['eta_minutes']:.0f} min")
st.metric("Amplification", f"{properties['amplification_factor']:.1f}x")
# Status indicator
if properties['stability'] < 0.4:
st.error("⚠️ CRITICAL: Breaking imminent")
elif properties['stability'] < 0.6:
st.warning("⚠️ ALERT: Front unstable")
elif properties['stability'] < 0.8:
st.info("ℹ️ MONITOR: Weakly unstable")
else:
st.success("✅ SAFE: Stable front")