| """ |
| Dynamic Analytical Brief tab for the Sri Lanka Disaster Dashboard. |
| |
| Provides AI-powered trend analysis using LLM (DeepSeek/OpenAI). |
| """ |
|
|
| import streamlit as st |
| from datetime import datetime |
| from pathlib import Path |
|
|
|
|
| def render_analytics_tab(sitreps_dir: Path, floods_dir: Path, landslide_dir: Path, generate_trend_summary_func): |
| """ |
| Render the Dynamic Analytical Brief tab with AI-powered analysis. |
| |
| Args: |
| sitreps_dir: Path to the sitreps data directory |
| floods_dir: Path to the floods data directory |
| landslide_dir: Path to the landslide data directory |
| generate_trend_summary_func: Function to call for generating trend summary |
| """ |
| st.header("π€ Dynamic Analytical Brief") |
| st.markdown(""" |
| AI-powered descriptive analysis of the current disaster situation in Sri Lanka. |
| The analysis covers: |
| - **Impact on People and Infrastructure** - Latest situation report data |
| - **Hazards Overview** - Current flood and landslide warnings |
| - **Trend Analysis** - Evolution of the situation over time |
| """) |
| |
| st.divider() |
| |
| |
| if "trend_summary" not in st.session_state: |
| st.session_state.trend_summary = None |
| if "trend_summary_error" not in st.session_state: |
| st.session_state.trend_summary_error = None |
| |
| |
| col_btn, col_warning = st.columns([1, 3]) |
| |
| with col_btn: |
| generate_clicked = st.button( |
| "π€ Generate AI Analysis", |
| use_container_width=True, |
| type="primary", |
| help="Generates a comprehensive trend analysis using AI" |
| ) |
| |
| with col_warning: |
| st.info( |
| "β οΈ **Please use responsibly:** Only regenerate after several new situation reports " |
| "have been published to avoid unnecessary API usage." |
| ) |
| |
| if generate_clicked: |
| with st.spinner("π Analyzing situation reports, flood and landslide data..."): |
| result = generate_trend_summary_func(sitreps_dir, floods_dir, landslide_dir) |
| |
| if result["success"]: |
| st.session_state.trend_summary = result["summary"] |
| st.session_state.trend_summary_meta = { |
| "provider": result.get("provider", "Unknown"), |
| "num_reports": result.get("num_reports", 0), |
| "date_range": result.get("date_range", {}), |
| "sitrep_date": result.get("sitrep_date", ""), |
| "flood_date": result.get("flood_date", ""), |
| "landslide_date": result.get("landslide_date", ""), |
| "generated_at": datetime.now().strftime("%Y-%m-%d %H:%M") |
| } |
| st.session_state.trend_summary_error = None |
| else: |
| st.session_state.trend_summary = None |
| st.session_state.trend_summary_error = result.get("error", "Unknown error occurred") |
| |
| st.divider() |
| |
| |
| if st.session_state.trend_summary: |
| meta = st.session_state.get("trend_summary_meta", {}) |
| |
| |
| st.subheader("π
Data Sources") |
| col1, col2, col3, col4 = st.columns(4) |
| with col1: |
| st.metric("Sitrep Date", meta.get('sitrep_date', 'N/A')[:20] if meta.get('sitrep_date') else 'N/A') |
| with col2: |
| st.metric("Flood Report", meta.get('flood_date', 'N/A')[:20] if meta.get('flood_date') else 'N/A') |
| with col3: |
| st.metric("Landslide Report", meta.get('landslide_date', 'N/A')[:20] if meta.get('landslide_date') else 'N/A') |
| with col4: |
| st.metric("Sitreps for Trends", meta.get('num_reports', '?')) |
| |
| |
| col_ai, col_gen = st.columns(2) |
| with col_ai: |
| st.caption(f"π€ AI Provider: {meta.get('provider', 'Unknown')}") |
| with col_gen: |
| st.caption(f"π Generated: {meta.get('generated_at', 'Unknown')}") |
| |
| st.divider() |
| |
| |
| st.subheader("π Analysis Report") |
| with st.container(): |
| st.markdown(st.session_state.trend_summary) |
| |
| elif st.session_state.trend_summary_error: |
| st.error(f"β {st.session_state.trend_summary_error}") |
| |
| else: |
| |
| st.markdown( |
| """ |
| <div style="padding: 40px; background-color: #f0f2f6; border-radius: 10px; text-align: center; margin-top: 20px;"> |
| <h3 style="color: #333; margin-bottom: 10px;">π No Analysis Generated Yet</h3> |
| <p style="color: #666; margin: 0;"> |
| Click <strong>"Generate AI Analysis"</strong> above to generate a comprehensive analytical brief. |
| </p> |
| <p style="color: #888; font-size: 14px; margin-top: 15px;"> |
| The analysis includes: |
| </p> |
| <ul style="color: #888; font-size: 14px; text-align: left; display: inline-block;"> |
| <li>π Situation and Hazards overview (floods + landslides)</li> |
| <li>π₯ Impact on Population (affected, deaths, displaced)</li> |
| <li>π Impact on Infrastructure (house damage)</li> |
| <li>π Trend Analysis across all available reports</li> |
| </ul> |
| </div> |
| """, |
| unsafe_allow_html=True |
| ) |
| |
| |
| st.divider() |
| with st.expander("βΉοΈ About This Analysis"): |
| st.markdown(""" |
| ### Analysis Structure |
| |
| **π SITUATION and HAZARDS** |
| - Overall context of the disaster situation |
| - Current flood alerts (Major/Minor/Alert/Normal levels) |
| - Active landslide warnings (Level 1/2/3 by district) |
| |
| **π₯ IMPACT ON POPULATION** |
| - People affected with changes from previous report |
| - Deaths and missing persons |
| - Displaced populations and top affected districts |
| |
| **π IMPACT ON INFRASTRUCTURE** |
| - Houses fully destroyed and partially damaged |
| - Most affected districts for infrastructure damage |
| |
| **π TREND ANALYSIS** |
| - Evolution of the situation over time |
| - Whether conditions are improving, worsening, or stabilizing |
| - Key metric changes between reports |
| |
| ### Data Sources |
| - **Situation Reports**: Official DMC situation reports (PDF extracted) |
| - **Flood Data**: Water level and rainfall reports |
| - **Landslide Data**: Early warning bulletins from NBRO |
| |
| ### AI Providers |
| - **Primary**: DeepSeek AI (cost-effective, high quality) |
| - **Fallback**: OpenAI GPT-4o-mini (if DeepSeek is unavailable) |
| """) |
|
|