KIM-PIWKE / app.py
edurojas95's picture
Update app.py
373d78b verified
Raw History Blame Contribute Delete
8.17 kB
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.")