Update src/streamlit_app.py
Browse files- src/streamlit_app.py +86 -70
src/streamlit_app.py
CHANGED
|
@@ -1397,7 +1397,7 @@ Ready for validation simulation!"""
|
|
| 1397 |
|
| 1398 |
|
| 1399 |
def show_validation():
|
| 1400 |
-
"""
|
| 1401 |
st.markdown('<h2 class="section-header">✅ Validation</h2>', unsafe_allow_html=True)
|
| 1402 |
|
| 1403 |
if not st.session_state.processed_data:
|
|
@@ -1419,61 +1419,62 @@ def show_validation():
|
|
| 1419 |
|
| 1420 |
st.subheader("🔬 Simulation vs Experimental Comparison")
|
| 1421 |
|
|
|
|
| 1422 |
col1, col2 = st.columns([2, 1])
|
| 1423 |
|
| 1424 |
with col2:
|
| 1425 |
-
|
| 1426 |
-
|
| 1427 |
-
|
| 1428 |
-
|
| 1429 |
-
|
| 1430 |
-
|
| 1431 |
-
|
| 1432 |
-
|
| 1433 |
-
|
| 1434 |
-
|
| 1435 |
-
|
| 1436 |
-
|
| 1437 |
-
|
| 1438 |
-
|
| 1439 |
-
|
| 1440 |
-
|
|
|
|
|
|
|
| 1441 |
run_simulation = st.button("🚀 Run Validation Simulation", type="primary", key="validation_button")
|
| 1442 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1443 |
if run_simulation:
|
| 1444 |
-
# Check required data
|
| 1445 |
if st.session_state.lambda_max_mean is None:
|
| 1446 |
-
|
| 1447 |
else:
|
| 1448 |
-
#
|
| 1449 |
-
|
| 1450 |
-
|
| 1451 |
-
|
| 1452 |
-
|
| 1453 |
-
|
| 1454 |
-
|
| 1455 |
-
# Extract values exactly like desktop GUI
|
| 1456 |
-
G_value = st.session_state.pred_G[0][0] if st.session_state.pred_G.ndim > 1 else \
|
| 1457 |
-
st.session_state.pred_G[0]
|
| 1458 |
-
mu_value = st.session_state.pred_mu[0][0] if st.session_state.pred_mu.ndim > 1 else \
|
| 1459 |
-
st.session_state.pred_mu[0]
|
| 1460 |
-
|
| 1461 |
-
# Initialize simulation
|
| 1462 |
-
bubble_sim = OptimizedBubbleSimulation()
|
| 1463 |
|
| 1464 |
-
|
| 1465 |
-
|
| 1466 |
-
|
| 1467 |
-
|
| 1468 |
|
| 1469 |
-
|
| 1470 |
-
|
| 1471 |
|
| 1472 |
-
|
| 1473 |
-
|
| 1474 |
-
|
| 1475 |
|
| 1476 |
-
|
|
|
|
|
|
|
| 1477 |
fig, ax = plt.subplots(figsize=(10, 6))
|
| 1478 |
|
| 1479 |
ax.plot(st.session_state.t_interp_newunit, st.session_state.R_interp_newunit,
|
|
@@ -1486,7 +1487,8 @@ def show_validation():
|
|
| 1486 |
ax.grid(True, alpha=0.3)
|
| 1487 |
ax.legend()
|
| 1488 |
|
| 1489 |
-
# Calculate error metrics
|
|
|
|
| 1490 |
if len(t_sim) > 0 and len(st.session_state.t_interp_newunit) > 0:
|
| 1491 |
t_min = max(st.session_state.t_interp_newunit[0], t_sim[0])
|
| 1492 |
t_max = min(st.session_state.t_interp_newunit[-1], t_sim[-1])
|
|
@@ -1512,24 +1514,41 @@ def show_validation():
|
|
| 1512 |
plt.tight_layout()
|
| 1513 |
st.pyplot(fig)
|
| 1514 |
|
| 1515 |
-
#
|
| 1516 |
-
|
| 1517 |
-
|
| 1518 |
-
|
| 1519 |
-
|
| 1520 |
-
|
| 1521 |
-
|
| 1522 |
-
|
| 1523 |
-
|
| 1524 |
-
|
| 1525 |
-
|
| 1526 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1527 |
|
| 1528 |
**Predicted Values:**
|
| 1529 |
- Shear Modulus (G): {G_value:.2e} Pa
|
| 1530 |
- Viscosity (μ): {mu_value:.4f} Pa·s
|
| 1531 |
- Lambda Max: {st.session_state.lambda_max_mean:.3f} (from .mat file)
|
| 1532 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1533 |
**Simulation Performance:**
|
| 1534 |
- Simulation Time: {simulation_time:.2f} seconds (ultra-fast!)
|
| 1535 |
- Simulated Points: {len(R_sim)}
|
|
@@ -1537,20 +1556,17 @@ def show_validation():
|
|
| 1537 |
|
| 1538 |
The plot shows comparison between experimental (dots) and
|
| 1539 |
simulated (line) R-t curves using predicted material properties.
|
| 1540 |
-
Note: This uses ultra-optimized simulation with ZERO UI updates during execution."""
|
| 1541 |
|
| 1542 |
-
|
| 1543 |
-
|
| 1544 |
-
|
| 1545 |
-
|
| 1546 |
-
|
| 1547 |
-
st.
|
| 1548 |
-
|
| 1549 |
-
|
| 1550 |
-
|
| 1551 |
-
st.write(f"**G value:** {G_value if 'G_value' in locals() else 'N/A'}")
|
| 1552 |
-
st.write(f"**μ value:** {mu_value if 'mu_value' in locals() else 'N/A'}")
|
| 1553 |
-
st.write(f"**Lambda:** {st.session_state.get('lambda_max_mean', 'N/A')}")
|
| 1554 |
|
| 1555 |
|
| 1556 |
def show_results():
|
|
|
|
| 1397 |
|
| 1398 |
|
| 1399 |
def show_validation():
|
| 1400 |
+
"""FIXED Validation interface - No trembling for Predicted Values and Metrics"""
|
| 1401 |
st.markdown('<h2 class="section-header">✅ Validation</h2>', unsafe_allow_html=True)
|
| 1402 |
|
| 1403 |
if not st.session_state.processed_data:
|
|
|
|
| 1419 |
|
| 1420 |
st.subheader("🔬 Simulation vs Experimental Comparison")
|
| 1421 |
|
| 1422 |
+
# FIXED: Create completely static layout - render predicted values once and never change
|
| 1423 |
col1, col2 = st.columns([2, 1])
|
| 1424 |
|
| 1425 |
with col2:
|
| 1426 |
+
# STATIC CONTAINER: Predicted values - never re-renders
|
| 1427 |
+
predicted_values_container = st.container()
|
| 1428 |
+
with predicted_values_container:
|
| 1429 |
+
st.markdown("**Predicted Values:**")
|
| 1430 |
+
# Extract values once and display statically
|
| 1431 |
+
G_value = st.session_state.pred_G[0][0] if st.session_state.pred_G.ndim > 1 else st.session_state.pred_G[0]
|
| 1432 |
+
mu_value = st.session_state.pred_mu[0][0] if st.session_state.pred_mu.ndim > 1 else st.session_state.pred_mu[0]
|
| 1433 |
+
|
| 1434 |
+
# CRITICAL FIX: Use static markdown instead of dynamic st.write to prevent trembling
|
| 1435 |
+
st.markdown(f"""
|
| 1436 |
+
**G:** `{G_value:.2e} Pa`
|
| 1437 |
+
**μ:** `{mu_value:.4f} Pa·s`
|
| 1438 |
+
**λ_max:** `{st.session_state.lambda_max_mean:.3f}`
|
| 1439 |
+
""")
|
| 1440 |
+
|
| 1441 |
+
# ISOLATED BUTTON: Completely separate from other content
|
| 1442 |
+
button_container = st.container()
|
| 1443 |
+
with button_container:
|
| 1444 |
run_simulation = st.button("🚀 Run Validation Simulation", type="primary", key="validation_button")
|
| 1445 |
|
| 1446 |
+
# SEPARATE CONTAINERS: Isolate dynamic content
|
| 1447 |
+
status_container = st.empty()
|
| 1448 |
+
results_container = st.empty()
|
| 1449 |
+
|
| 1450 |
if run_simulation:
|
| 1451 |
+
# Check required data
|
| 1452 |
if st.session_state.lambda_max_mean is None:
|
| 1453 |
+
status_container.error("No lambda_max_mean loaded. Please load data first.")
|
| 1454 |
else:
|
| 1455 |
+
# Show simple status message
|
| 1456 |
+
status_container.info("🔄 Running simulation... Please wait.")
|
| 1457 |
+
|
| 1458 |
+
try:
|
| 1459 |
+
# Use already extracted values - no re-computation
|
| 1460 |
+
# Initialize simulation
|
| 1461 |
+
bubble_sim = OptimizedBubbleSimulation()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1462 |
|
| 1463 |
+
# Run simulation (NO UI UPDATES inside simulation)
|
| 1464 |
+
start_time = time.time()
|
| 1465 |
+
t_sim, R_sim = bubble_sim.run_optimized_simulation(G_value, mu_value, st.session_state.lambda_max_mean)
|
| 1466 |
+
simulation_time = time.time() - start_time
|
| 1467 |
|
| 1468 |
+
# Clear status
|
| 1469 |
+
status_container.empty()
|
| 1470 |
|
| 1471 |
+
# Store simulation results
|
| 1472 |
+
st.session_state.t_sim = t_sim
|
| 1473 |
+
st.session_state.R_sim = R_sim
|
| 1474 |
|
| 1475 |
+
# Show ALL results in one container to prevent trembling
|
| 1476 |
+
with results_container.container():
|
| 1477 |
+
# Create comparison plot
|
| 1478 |
fig, ax = plt.subplots(figsize=(10, 6))
|
| 1479 |
|
| 1480 |
ax.plot(st.session_state.t_interp_newunit, st.session_state.R_interp_newunit,
|
|
|
|
| 1487 |
ax.grid(True, alpha=0.3)
|
| 1488 |
ax.legend()
|
| 1489 |
|
| 1490 |
+
# Calculate error metrics
|
| 1491 |
+
rmse = mae = max_error = 0
|
| 1492 |
if len(t_sim) > 0 and len(st.session_state.t_interp_newunit) > 0:
|
| 1493 |
t_min = max(st.session_state.t_interp_newunit[0], t_sim[0])
|
| 1494 |
t_max = min(st.session_state.t_interp_newunit[-1], t_sim[-1])
|
|
|
|
| 1514 |
plt.tight_layout()
|
| 1515 |
st.pyplot(fig)
|
| 1516 |
|
| 1517 |
+
# CRITICAL FIX: Use static markdown instead of st.metric() to prevent trembling
|
| 1518 |
+
st.markdown("### 📊 Validation Metrics")
|
| 1519 |
+
|
| 1520 |
+
metric_col1, metric_col2, metric_col3 = st.columns(3)
|
| 1521 |
+
with metric_col1:
|
| 1522 |
+
st.markdown(f"""
|
| 1523 |
+
**RMSE**
|
| 1524 |
+
`{rmse:.3f}`
|
| 1525 |
+
""")
|
| 1526 |
+
with metric_col2:
|
| 1527 |
+
st.markdown(f"""
|
| 1528 |
+
**MAE**
|
| 1529 |
+
`{mae:.3f}`
|
| 1530 |
+
""")
|
| 1531 |
+
with metric_col3:
|
| 1532 |
+
st.markdown(f"""
|
| 1533 |
+
**Max Error**
|
| 1534 |
+
`{max_error:.3f}`
|
| 1535 |
+
""")
|
| 1536 |
+
|
| 1537 |
+
# Show detailed results using static markdown
|
| 1538 |
+
st.success("✅ Validation simulation completed!")
|
| 1539 |
+
|
| 1540 |
+
st.info(f"""**Validation Results (Ultra-Optimized):**
|
| 1541 |
|
| 1542 |
**Predicted Values:**
|
| 1543 |
- Shear Modulus (G): {G_value:.2e} Pa
|
| 1544 |
- Viscosity (μ): {mu_value:.4f} Pa·s
|
| 1545 |
- Lambda Max: {st.session_state.lambda_max_mean:.3f} (from .mat file)
|
| 1546 |
|
| 1547 |
+
**Error Metrics:**
|
| 1548 |
+
- RMSE: {rmse:.3f}
|
| 1549 |
+
- MAE: {mae:.3f}
|
| 1550 |
+
- Max Error: {max_error:.3f}
|
| 1551 |
+
|
| 1552 |
**Simulation Performance:**
|
| 1553 |
- Simulation Time: {simulation_time:.2f} seconds (ultra-fast!)
|
| 1554 |
- Simulated Points: {len(R_sim)}
|
|
|
|
| 1556 |
|
| 1557 |
The plot shows comparison between experimental (dots) and
|
| 1558 |
simulated (line) R-t curves using predicted material properties.
|
| 1559 |
+
Note: This uses ultra-optimized simulation with ZERO UI updates during execution.""")
|
| 1560 |
|
| 1561 |
+
except Exception as e:
|
| 1562 |
+
status_container.empty()
|
| 1563 |
+
results_container.error(f"Simulation failed: {str(e)}")
|
| 1564 |
+
|
| 1565 |
+
with results_container.expander("🔍 Debug Information"):
|
| 1566 |
+
st.write(f"**Error:** {str(e)}")
|
| 1567 |
+
st.write(f"**G value:** {G_value if 'G_value' in locals() else 'N/A'}")
|
| 1568 |
+
st.write(f"**μ value:** {mu_value if 'mu_value' in locals() else 'N/A'}")
|
| 1569 |
+
st.write(f"**Lambda:** {st.session_state.get('lambda_max_mean', 'N/A')}")
|
|
|
|
|
|
|
|
|
|
| 1570 |
|
| 1571 |
|
| 1572 |
def show_results():
|