import streamlit as st import requests import pandas as pd import plotly.express as px import datetime import numpy as np import random # ===================================================================== # 1. CONFIGURACIÓN DE REPRODUCIBILIDAD (SEED 42) # ===================================================================== # En el Frontend, mantenemos la semilla para Random y Numpy para asegurar # consistencia en procesos locales de la interfaz. def set_seed(seed=42): random.seed(seed) np.random.seed(seed) set_seed(42) # ===================================================================== # 2. CONFIGURACIÓN DE PÁGINA # ===================================================================== st.set_page_config( page_title="KIM-PIWKE - Gestión Cardiovascular", page_icon="🫀", layout="wide" ) # --- ESTILOS Y CRÉDITOS EN SIDEBAR --- st.sidebar.title("KIM-PIWKE") st.sidebar.markdown("*Saber del Corazón*") st.sidebar.divider() st.sidebar.markdown(""" **Desarrollado por:** * **TM Eduardo Rojas Maturana** * **Dr. TM Neftalí Guzmán Oyarzo** *Facultad de Ciencias de la Salud, UCT.* *Laboratorio de Investigación en Salud de Precisión.* --- """) st.sidebar.info(""" **KIM-PIWKE** utiliza una arquitectura híbrida HZF para la gestión anticipatoria de recursos críticos. """) # --- LISTA DE HOSPITALES --- hospitales = [ 'Hospital Dr. Hernan Henriquez Aravena (Temuco)', 'SAR Miraflores', 'SAPU Padre Las Casas', 'SAR Pedro de Valdivia', 'SAPU Santa Rosa', 'SAR Labranza', 'SAR Conun Huenu', 'SAPU Amanecer', 'SAPU Villa Alegre', 'SAPU Pueblo Nuevo', 'Complejo Asistencial Padre las Casas', 'Hospital Makewe' ] # --- NAVEGACIÓN POR PESTAÑAS --- tab1, tab2, tab3 = st.tabs(["🚀 Predicción y Feedback", "📖 Manual de Usuario", "📊 Metodología"]) # --- PESTAÑA 1: PREDICCIÓN --- with tab1: st.title("Sistema de Estimación Cardiovascular") st.markdown("### 🏥 Panel Operativo de Urgencias") st.warning("📅 **NOTA DE CALIBRACIÓN:** Las estimaciones se calculan por semana epidemiológica (Lunes a Domingo).") # Entradas de usuario col_input, col_date = st.columns(2) with col_input: hosp_sel = st.selectbox("Seleccione Centro de Salud:", hospitales) with col_date: fecha_input = st.date_input("Seleccione semana (Cualquier día):", datetime.date.today()) # LÓGICA DE AJUSTE AL LUNES: # Se fuerza la fecha de referencia al inicio de la semana epidemiológica (Lunes) dias_a_restar = (fecha_input.weekday() + 1) % 7 domingo_semana = fecha_input - datetime.timedelta(days=dias_a_restar) if fecha_input != domingo_semana: st.info(f"Ajustado al **Domingo {domingo_semana.strftime('%d/%m/%Y')}** (Inicio de semana epidemiológica MINSAL).") else: st.success(f"Semana del domingo {domingo_semana.strftime('%d/%m/%Y')} seleccionada.") if st.button("🚀 Ejecutar Análisis", type="primary"): with st.spinner("Sincronizando con el motor de IA (HZF Layer)..."): try: # Payload para la API con el lunes forzado payload = { "EstablecimientoGlosa": hosp_sel, "fecha_referencia": domingo_semana.strftime('%Y-%m-%d') } # Llamada al backend (Ajustar puerto según corresponda) # Nota: El motor maneja internamente la semilla de Torch para Chronos. response = requests.post("http://localhost:8000/predecir", json=payload) data = response.json() if response.status_code != 200: st.error(f"Error del motor: {data.get('detail', 'Desconocido')}") else: st.success(f"📅 **Resultados para la Semana Epidemiológica {data['semana_epi']} - {data['año']}**") # Métricas destacadas m1, m2, m3 = st.columns(3) total_estimado = data["estimaciones"]["Total"] m1.metric("Consultas Semanales", total_estimado) # Nivel de alerta basado en volumen alerta = "NORMAL" if total_estimado > 40: alerta = "CRÍTICO" st.error(f"🚨 **ALERTA DE SOBRECARGA:** Se estima un volumen superior a la capacidad estándar.") m2.metric("Nivel de Alerta", alerta) m3.metric("Riesgo Ambiental (PM2.5)", f"{round(data['clima_lag2']['PM2.5_Max_Lag2'], 1)} µg/m³") # Gráficos st.divider() col_plot1, col_plot2 = st.columns(2) with col_plot1: st.markdown("#### 🩺 Desglose por Patologías (ICD-10)") causas_raw = data["estimaciones"]["Causas"] df_c = pd.DataFrame(list(causas_raw.items()), columns=["Causa", "Casos"]) df_c['Causa'] = df_c['Causa'].str.replace('_', ' ') fig_causas = px.bar(df_c, x="Casos", y="Causa", orientation='h', color="Casos", color_continuous_scale="Reds", text_auto=True) fig_causas.update_layout(showlegend=False, yaxis_title="") st.plotly_chart(fig_causas, use_container_width=True) with col_plot2: st.markdown("#### 👥 Grupos Etarios Estimados") edades_raw = data["estimaciones"]["Edades"] df_e = pd.DataFrame(list(edades_raw.items()), columns=["Grupo", "Casos"]) df_e['Grupo'] = df_e['Grupo'].str.replace('Total_Adultos_', '').str.replace('_', ' ') fig_edades = px.pie(df_e, values="Casos", names="Grupo", hole=0.4, color_discrete_sequence=px.colors.sequential.Blues_r) st.plotly_chart(fig_edades, use_container_width=True) with st.expander("🌫️ Detalle Atmosférico (Lag 2 - Hace 14 días)"): st.json(data["clima_lag2"]) st.caption("Estas variables ajustan el residuo del modelo fundacional.") except Exception as e: st.error(f"Error de conexión con el motor KIM-PIWKE: {e}") # --- PESTAÑA 2: MANUAL --- with tab2: st.header("📖 Manual de Usuario y Auditoría") st.markdown(""" ### 1. ¿Cómo utilizar esta herramienta para auditoría? Este sistema permite realizar **Backtesting**. Al seleccionar una fecha pasada, el sistema: 1. Oculta la información posterior a esa fecha. 2. Calcula la predicción basándose en la inercia previa y el clima de hace 14 días. 3. Permite comparar con los registros oficiales del **DEIS**. ### 2. Sincronización de Fechas El sistema ajusta automáticamente cualquier selección al **Lunes** de esa semana, garantizando que el volumen predicho corresponda a la semana epidemiológica completa. """) # --- PESTAÑA 3: METODOLOGÍA --- with tab3: st.header("📊 Metodología: Arquitectura Híbrida HZF") st.write("KIM-PIWKE integra un modelo fundacional de series de tiempo con corrección ambiental mediante residuos.") st.markdown("#### Componentes del Modelo:") st.write("- **Capa 1 (Chronos-T5):** Proyecta la trayectoria base univariante.") st.write("- **Capa 2 (ERC Layer):** Ajusta los residuos mediante Random Forest y PCA ambiental.") st.markdown("#### Patologías Monitoreadas:") st.markdown(""" * Accidente Vascular Encefálico * Arritmia Grave * Crisis Hipertensiva * Infarto Agudo al Miocardio * Otras Causas Circulatorias """) st.divider() st.caption("© 2026 Laboratorio de Investigación en Salud de Precisión - UCT.")