Skip to content

🌊 Sistema de alerta temprana de tsunamis de origen lejano que combina Fortran + Python. Backend para https://github.com/totallynotdavid/picv-2025-web

Notifications You must be signed in to change notification settings

totallynotdavid/picv-2025

Repository files navigation

Orchestrator-TSDHN

Coverage Seguridad Calidad
badge CodeQL Security Report pre-commit

El Orchestrator-TSDHN es una herramienta para la estimación de parámetros de tsunamis de origen lejano mediante simulaciones numéricas. Combina el modelo TSDHN escrito en Fortran (en la carpeta /model) con una API escrita en Python (en la carpeta /orchestrator) que procesa datos sísmicos iniciales, como la ubicación y la magnitud de un terremoto, para calcular variables como: dimensiones de ruptura sísmica, momento sísmico y desplazamiento de la corteza. Estos valores son utilizados finalmente en la simulación principal, cuyo resultado incluye un informe en formato PDF con mapas de propagación, gráficos de mareógrafos y datos técnicos, además de un archivo de texto con tiempos de arribo a estaciones costeras predefinidas.

Important

La lógica de los cálculos numéricos reside en este repositorio, mientras que la interfaz web (que gestiona solicitudes y entrega el informe al usuario final) opera en un entorno separado.

A continuación, se muestra un diagrama que ilustra el flujo general del Orchestrator-TSDHN:

Loading
sequenceDiagram
    participant Aplicación as Aplicación web
    participant API
    participant Orch as Orchestrator
    participant Redis as Redis Worker
    participant TSDHN

    Aplicación->>API: - Enviar parámetros<br/>- Consultar estado<br/>- Consultar resultados
    activate API
    API->>Orch: Administrar<br/>simulaciones
    activate Orch
    Orch->>Redis: Consulta estado
    activate Redis
    Orch->>Redis: Añadir simulación<br/>a la cola
    Note over Redis,TSDHN: Preparar entorno de trabajo
    Redis->>TSDHN: Inicia simulación
    activate TSDHN
    TSDHN->>Redis: Retornar informe<br/>final
    deactivate TSDHN
    Redis->>Orch: Notificar finalización
    deactivate Redis
    Orch->>API: Actualizar el estado<br/>de la simulación
    deactivate Orch
    API->>Aplicación: Retornar resultados
    deactivate API

Instalación

El proyecto requiere Ubuntu 24.04 o superior. Usuarios de Windows deben configurar Windows Subsystem for Linux (WSL 2.0 o superior) siguiendo la guía oficial de Microsoft antes de continuar.

Prerrequisitos

Ejecuta bash utils/setup-env.sh para instalar todas las dependencias mencionadas en esta sección. Además, asegúrate de darle permisos de ejecución con chmod +x utils/setup-env.sh. Si deseas instalar manualmente, sigue los pasos a continuación.

Actualiza los paquetes del sistema antes de iniciar:

sudo apt update -y && sudo apt upgrade -y
  1. Python (con pyenv): Usamos pyenv porque nos permite gestionar múltiples versiones de Python. Ejecuta:

    curl -fsSL https://pyenv.run | bash

    Si estás usando WSL, ejecuta lo siguiente [1]:

    cat << 'EOF' >> ~/.bashrc
    export PYENV_ROOT="$HOME/.pyenv"
    export PATH="$PYENV_ROOT/bin:$PATH"
    eval "$(pyenv init -)"
    EOF

    Si estás usando Ubuntu de forma nativa, ejecuta lo siguiente [2]:

    cat << 'EOF' >> ~/.bashrc
    export PYENV_ROOT="$HOME/.pyenv"
    [[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"
    eval "$(pyenv init - bash)"
    EOF

    En cualquiera de los dos casos, aplica los cambios con:

    source ~/.bashrc

    pyenv compila Python a partir del código fuente durante la instalación, por lo que resulta necesario instalar previamente las dependencias de compilación [3] [4] y, luego, instala Python:

    sudo apt install -y build-essential zlib1g-dev libffi-dev libssl-dev libbz2-dev libreadline-dev libsqlite3-dev liblzma-dev libncurses-dev tk-dev
    pyenv install 3.12 && pyenv global 3.12

    Si deseas usar Python del sistema en lugar de pyenv, solo necesitas instalar pip3:

    sudo apt install -y python3-pip

    En cualquiera de los dos casos, verifica la instalación:

    python3 -V
    pip3 -V
  2. Poetry nos ayuda a gestionar nuestras dependencias de forma consistente entre dispositivos. Poetry se encarga de instalar las librerías que usamos.

    curl -sSL https://install.python-poetry.org | python3 -
    echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
    source ~/.bashrc

    Verifica la instalación:

    poetry --version
  3. TTT SDK (Tsunami Travel Time) calcula los tiempos de arribo de un tsunami a partir de la batimetría de una cuadrícula geográfica (el océano Pacífico en nuestro caso). Para instalarlo, necesitas git-lfs para clonar los archivos de datos grandes del repositorio y cmake para compilar e instalar el software:

    sudo apt install -y git-lfs cmake

    Para instalar el TTT SDK:

    git clone https://gitlab.com/totallynotdavid/tttapi/
    cd tttapi && make config compile && sudo make install datadir docs
    make test clean

    Nota: Almacenamos el SDK en GitLab para aprovechar su política de LFS gratuito y para reducir la carga en los servidores de los autores durante pruebas CI/CD.

  4. TeXLive es utilizado para la generación de los informes. Para simplificar el proceso, se opta por una instalación mínima. Ejecute:

    cd /tmp
    wget https://mirror.ctan.org/systems/texlive/tlnet/install-tl-unx.tar.gz
    zcat < install-tl-unx.tar.gz | tar xf -
    cd install-tl-2*

    Crea un perfil de instalación (texlive.profile) con el siguiente contenido:

    cat > texlive.profile << EOF
    selected_scheme scheme-basic
    tlpdbopt_autobackup 0
    tlpdbopt_install_docfiles 0
    tlpdbopt_install_srcfiles 0
    EOF

    La instalación se realiza en el directorio del usuario para evitar problemas relacionados a permisos y evitar el modo usuario de TeXLive [5]:

    perl ./install-tl --profile=texlive.profile \
                      --texdir "$HOME/texlive" \
                      --texuserdir "$HOME/.texlive" \
                      --no-interaction

    Configuración del PATH:

    echo -e '\nexport PATH="$HOME/texlive/bin/x86_64-linux:$PATH"' >> ~/.bashrc
    source ~/.bashrc

    Instalación de paquetes LaTeX necesarios:

    tlmgr update --self && tlmgr install babel-spanish hyphen-spanish booktabs
  5. Dependencias adicionales: gfortran, redis-server, gmt1, ps2eps, csh. Ejecute:

    sudo apt install -y gfortran redis-server gmt gmt-dcw gmt-gshhg ps2eps csh

    pygmt requiere un enlace simbólico para funcionar correctamente:

    sudo ln -s /lib/x86_64-linux-gnu/libgmt.so.6 /lib/x86_64-linux-gnu/libgmt.so

    Configura Redis para usar systemd:

    sudo sed -i 's/^# \?supervised \(no\|auto\)/supervised systemd/' /etc/redis/redis.conf
    sudo systemctl restart redis-server
  6. Opcional: Si necesitas ejecutar la interfaz gráfica original (tsunami.m), puedes instalar MATLAB R2014.

Iniciar el proyecto

  1. Clona el repositorio e instala las dependencias:

    git clone https://github.com/totallynotdavid/picv-2025
    cd picv-2025 && poetry install
  2. Valida la instalación con:

    poetry run pytest # Todos los tests deben pasar
  3. Para iniciar la API, ejecuta:

    poetry run start

    La API estará disponible en http://localhost:8000.

    Si estás modificando el código y quieres que la aplicación se recargue automáticamente cuando hagas cambios, entonces usa el siguiente comando en lugar de poetry run start:

    poetry poe dev

    En un nuevo terminal, ejecuta el siguiente comando para iniciar el RQ worker:

    poetry run rq worker tsdhn_queue

Tip

Si deseas probar el modelo con condiciones específicas, consulta la sección de pruebas personalizadas.

Estructura del proyecto

El repositorio se organiza en dos componentes principales:

picv-2025/
├── orchestrator/
│   ├── core/
│   │   ├── calculator.py        # Clase TsunamiCalculator y lógica del cálculo inicial
│   │   ├── config.py            # Constantes globales y configuración del pipeline
│   │   └── queue.py             # Gestión de cola de simulaciones
│   ├── main.py                  # Punto de entrada de la API y definiciones de endpoints
│   ├── models/
│   │   └── schemas.py           # Schemas de validación y transformación de datos
│   ├── modules/
│   │   ├── maxola.py            # Generación de mapa de máxima altura de propagación del tsunami
│   │   ├── point_ttt.py         # Generación del mapa de tiempos de arribo
│   │   ├── reporte.py           # Generación del informe final
│   │   ├── ttt_inverso.py       #
│   │   └── ttt_max.py           # Generación de los mareogramas
│   └── utils/
│       └── geo.py               # Cálculos geográficos (distancias, formatos, etc.)
└── model/                       # Archivos de datos y recursos del modelo
    ├── pacifico.mat             # Datos de batimetría del Océano Pacífico
    ├── maper1.mat               # Datos de puntos costeros
    ├── mecfoc.dat               # Base de datos histórica de mecanismos focales
    ├── puertos.txt              # Lista de puertos para cálculos de tiempo de llegada
    └── job.run                  # (Deprecated) Script de ejecución de simulación en C Shell

Endpoints de la API

El servicio expone varios endpoints para la gestión de simulaciones sísmicas. Todas las solicitudes deben incluir el encabezado HTTP Content-Type: application/json y utilizan identificadores UUIDv4 para gestionar las simulaciones.

  1. POST /run-simulation inicia una nueva simulación. Requiere un cuerpo JSON con parámetros sísmicos validados mediante modelos Pydantic (schemas.py).

    Los parámetros requeridos incluyen:

    Parámetro Tipo Descripción
    Mw decimal (6.5 a 9.5) Magnitud de momento sísmico
    h decimal (>0) Profundidad hipocentral en kilómetros
    lat0 decimal (-90 a 90) Latitud epicentral en grados decimales
    lon0 decimal (-180 a 180) Longitud epicentral en grados decimales
    dia string (formato DD con cero inicial) Día del evento (ej. "07")
    hhmm string (formato HHMM) Hora del evento (ej. "1430" para 2:30 PM UTC)

    Un ejemplo de solicitud sería:

    Ejemplo de solicitud
    {
      "Mw": 7.5,
      "h": 10.0,
      "lat0": -20.5,
      "lon0": -70.5,
      "dia": "15",
      "hhmm": "1430"
    }

    La respuesta esperada para esta solicitud contiene el identificador único de la simulación:

    Ejemplo de respuesta esperada (HTTP 201)
    {
      "job_id": "dee661ec-1c39-47e5-bb50-3926fa70bb8e"
    }
  2. GET /job-status/{job_id} provee información detallada sobre simulaciones en curso o finalizadas. La respuesta incluye:

    • El estado actual de la simulación (queued, running, completed, failed)
    • Los parámetros de ruptura sísmica calculados
    • Los tiempos de arribo a estaciones definidas en puertos.txt
    • Las coordenadas del rectángulo del plano de falla para visualización geoespacial
    • Los metadatos temporales y URL de descarga (disponible 72 horas post-completado)

    Un ejemplo de solicitud sería:

    Ejemplo de solicitud
    {
      "job_id": "dee661ec-1c39-47e5-bb50-3926fa70bb8e"
    }

    Un ejemplo de respuesta esperada sería:

    Ejemplo de respuesta esperada
    {
      "status": "completed",
      "calculation": {
        "length": 575.44,
        "width": 144.54,
        "dislocation": 10.64,
        "seismic_moment": 3.98e22,
        "tsunami_warning": "Genera un tsunami grande...",
        "distance_to_coast": 10439.47,
        "rectangle_corners": [
          { "lat": 56.44, "lon": -153.34 }
          { "__comment": "Otras coordenadas, omitidas por brevedad" }
        ]
      },
      "travel_times": {
        "arrival_times": {
          "-80.58, -03.0": "12:09 23Mar",
          "__comment": "Otras estaciones, omitidas por brevedad"
        },
        "distances": {
          "-80.58, -03.0": 9445.79,
          "__comment": "Otras distancias, omitidas por brevedad"
        },
        "epicenter_info": {
          "date": "23",
          "time": "0000",
          "latitude": "56.00",
          "longitude": "-156.00"
        }
      },
      "details": "Job completed successfully",
      "error": null,
      "created_at": "2025-02-17T19:46:08.171522",
      "started_at": "2025-02-17T19:46:08.345851",
      "ended_at": "2025-02-17T20:27:44.304036",
      "download_url": "/job-result/dee661ec-1c39-47e5-bb50-3926fa70bb8e/reporte.pdf"
    }

Tip

Los objetos calculation y travel_times se añaden inmediatamente después de ser calculados. No es necesario esperar a que finalice la simulación para obtener estos datos.

  1. GET /job-result/{job_id}permite descargar el informe técnico en formato PDF cuando el estado es completed. Requiere el encabezado Accept: application/pdf.

    Un ejemplo de uso directo sería:

    http://localhost:8000/job-result/dee661ec-1c39-47e5-bb50-3926fa70bb8e
    
  2. GET /health verifica la disponibilidad del servicio y su conexión con Redis.

    Una respuesta esperada sería:

    Ejemplo de respuesta esperada
    {
      "status": "healthy",
      "timestamp": "2025-03-05T14:26:45.150833",
      "redis_connected": true
    }

Todas las respuestas de error siguen el formato RFC 7807 con códigos HTTP semánticos. Los recursos generados se purgan automáticamente tras 72 horas de inactividad.

Pruebas personalizadas

Además de las pruebas unitarias ubicadas en orchestrator/tests/, el repositorio incluye una interfaz de línea de comandos (CLI) para ejecutar simulaciones directamente mediante la API. Esta herramienta resulta particularmente útil para validaciones rápidas en entornos con recursos limitados o para realizar pruebas preliminares.

Para iniciar el CLI en modo estándar, ejecute:

poetry run python -m cli.cli

El CLI utiliza los parámetros predeterminados definidos en cli/constants.py, los cuales pueden modificarse interactivamente al usar el CLI. Durante el proceso, para mantener los valores predeterminados, simplemente presiona Enter para continuar.

El flujo de ejecución sigue tres etapas secuenciales:

  1. Verificación de conectividad con la API (URL predeterminada: http://localhost:8000).
  2. Búsqueda del archivo configuracion_simulacion.json en el directorio raíz. Si no existe, se genera automáticamente con los valores predeterminados o los proporcionados por el usuario.
  3. Ejecución secuencial de los endpoints /calculate (parámetros iniciales), /tsunami-travel-times (cálculo de tiempos de arribo) y /run-tsdhn (simulación completa).

Tras iniciar el endpoint run-tsdhn, el CLI genera en el directorio raíz el archivo last_job_id.txt con un identificador único de la simulación. Cuando el parámetro save_results está activado (valor predeterminado: true), el informe PDF resultante se almacenará en este mismo directorio una vez finalizado el proceso.

También puedes personalizar la configuración editando manualmente el archivo configuracion_simulacion.json. Este archivo solo se regenera automáticamente durante la primera ejecución o si ha sido eliminado previamente.

Modo de desarrollo

Para escenarios de depuración o desarrollo, el CLI ofrece un modo avanzado que permite controlar etapas específicas del pipeline de procesamiento (por ahora, solo run-tsdhn es compatible).

Para iniciar el CLI en modo de desarrollo, ejecute:

poetry run python -m cli.cli --dev

Este modo permite omitir componentes específicos de la cadena de procesamiento definida en PROCESSING_PIPELINE en orchestrator/core/queue.py. Esta funcionalidad resulta especialmente útil considerando que la ejecución completa del modelo TSDHN puede requerir entre 25 y 50 minutos.

La(s) etapa(s) omitida(s) se guardan en configuracion_simulacion.json en el campo skip_steps. Este registro es temporal y no persiste entre ejecuciones del CLI, incluso en modo desarrollo. Deberás especificar nuevamente las etapas a omitir en cada ejecución.

Caution

Omitir etapas invalida los resultados. Use esta función solo para diagnóstico técnico. Los informes generados no son válidos para análisis científico ni toma de decisiones.

Notas adicionales

  • La API guarda automáticamente algunos eventos en tsunami_api.log. Puedes configurar el logger en config.py si deseas. El archivo de logs se crea cuando inicias la API.

  • Si estás haciendo pruebas y quieres ver los logs en tu terminal mientras usas pytest, solo necesitas cambiar una línea en pyproject.toml:

    [tool.pytest.ini_options]
    log_cli = true

    Es recomendable usar logger.debug() en vez de print() o sino pytest lo ignorará.

  • Cuando termines de hacer cambios en el código, y antes de hacer commit, ejecuta:

    poetry run pytest
    poetry poe format

    para formatear el código y asegurarte de todo sigue funcionando correctamente.

Footnotes

  1. GMT 6.0.0 está en APT, pero pygmt requiere ≥6.4.0. Ubuntu 24.04 incluye la versión 6.5.0. Actualiza o compila los ejecutables siguiendo: https://github.com/GenericMappingTools/gmt/blob/master/BUILDING.md. ↩