Saltar a contenido

Guía Rápida - Testing Sistema de Posturografía

Inicio Rápido

1. Instalación de Dependencias

# Crear entorno virtual (recomendado)
python3 -m venv venv
source venv/bin/activate  # En Windows: venv\Scripts\activate

# Instalar dependencias
pip install pytest numpy scipy matplotlib

2. Ejecutar Tests

# Ejecutar todos los tests
pytest python/test_matlab_integration.py -v

# Ejecutar con reporte de cobertura
pytest python/test_matlab_integration.py -v --cov

# Ejecutar un test específico
pytest python/test_matlab_integration.py::TestVistaAnterior::test_calibracion -v

3. Explorar Marcadores

# Leer archivos .mat y ver coordenadas
python python/read_mat_markers.py

Ejemplos de Uso

Ejemplo 1: Calcular Factor de Calibración

from python.test_matlab_integration import calcular_factor_calibracion

# Dos puntos en la grilla separados 10 cm
punto1 = (100, 500)  # (x, y) en píxeles
punto2 = (200, 500)  # (x, y) en píxeles

fc = calcular_factor_calibracion(punto1, punto2, distancia_real_cm=10.0)
print(f"Factor de calibración: {fc:.4f} cm/pixel")
# Output: Factor de calibración: 0.1000 cm/pixel

Ejemplo 2: Calcular Inclinación de Cabeza

from python.test_matlab_integration import calcular_angulo_inclinacion

# Coordenadas de los tragus
tragus_izq = (1150.0, 400.0)  # Lado izquierdo de la foto
tragus_der = (850.0, 410.0)   # Lado derecho de la foto (más abajo)

grados, diagnostico = calcular_angulo_inclinacion(tragus_izq, tragus_der)
print(f"Ángulo: {grados:.2f}°")
print(f"Diagnóstico: {diagnostico}")
# Output:
# Ángulo: 3.43°
# Diagnóstico: derecha

Ejemplo 3: Calcular Rotación de Escotadura Esternal

from python.test_matlab_integration import calcular_rotacion_punto

# Factor de calibración y LRV
fc = 0.1  # cm/pixel
lrv_x = 1000.0  # píxeles

# Coordenada X de escotadura esternal
escotadura_x = 985.0  # píxeles

distancia, diagnostico = calcular_rotacion_punto(escotadura_x, lrv_x, fc)
print(f"Distancia a LRV: {distancia:.2f} cm")
print(f"Diagnóstico: {diagnostico}")
# Output:
# Distancia a LRV: 1.50 cm
# Diagnóstico: derecha

Ejemplo 4: Calcular Ángulo Q

from python.test_matlab_integration import calcular_angulo_q

# Coordenadas de los puntos
eias = (900.0, 1550.0)          # Espina ilíaca anterosuperior
rotula = (920.0, 1950.0)        # Centro de rótula
tat = (925.0, 2050.0)           # Tuberosidad anterior de tibia

angulo, diagnostico = calcular_angulo_q(eias, rotula, tat)
print(f"Ángulo Q: {angulo:.2f}°")
print(f"Diagnóstico: {diagnostico}")
# Output:
# Ángulo Q: 15.23°
# Diagnóstico: normal

Ejemplo 5: Diagnóstico de Miembro Inferior

from python.test_matlab_integration import diagnosticar_miembro_inferior

# Distancias medidas en cm
dist_maleolos = 5.0   # Maleolos separados
dist_condilos = 2.0   # Cóndilos juntos
dist_gemelos = 3.0

diagnostico = diagnosticar_miembro_inferior(dist_maleolos, dist_condilos, dist_gemelos)
print(f"Diagnóstico: {diagnostico}")
# Output: Diagnóstico: Genu Valgo

Ejemplo 6: Calcular Lordosis

from python.test_matlab_integration import calcular_lordosis

# Coordenadas en píxeles y factor de calibración
x_apex = 520.0
x_tangente = 480.0
fc = 0.1

distancia, diagnostico = calcular_lordosis(x_apex, x_tangente, fc)
print(f"Distancia al apex: {distancia:.2f} cm")
print(f"Diagnóstico: {diagnostico}")
# Output:
# Distancia al apex: 4.00 cm
# Diagnóstico: Distancia al apex normal

Ejemplo 7: Flujo Completo - Vista Anterior

from python.test_matlab_integration import (
    calcular_factor_calibracion,
    calcular_angulo_inclinacion,
    calcular_rotacion_punto,
    calcular_angulo_q,
    diagnosticar_miembro_inferior,
    find_marker,
    create_test_markers
)

# 1. Crear datos de prueba
marcadores = create_test_markers()
print(f"Sujeto ID: {marcadores['ID']}")
print(f"Total de marcadores: {len(marcadores['marcadores'])}")

# 2. Calibración
fc = calcular_factor_calibracion((100, 500), (200, 500))
print(f"\nFactor de calibración: {fc:.4f} cm/pixel")

# 3. Línea de referencia vertical
lrv_x = 1000.0

# 4. Análisis Cérvico-Cefálico
tragus_izq = find_marker(marcadores['marcadores'], 'Tragus Izq.')
tragus_der = find_marker(marcadores['marcadores'], 'Tragus Der.')
grados_cc, diag_cc = calcular_angulo_inclinacion(
    (tragus_izq['x'], tragus_izq['y']),
    (tragus_der['x'], tragus_der['y'])
)
print(f"\n=== Cérvico-Cefálica ===")
print(f"Inclinación de cabeza: {grados_cc:.2f}° - {diag_cc}")

# 5. Análisis Tronco-Columna
escotadura = find_marker(marcadores['marcadores'], 'Escotadura Esternal')
dist_ee, diag_ee = calcular_rotacion_punto(escotadura['x'], lrv_x, fc)
print(f"\n=== Tronco-Columna ===")
print(f"Rotación escotadura esternal: {dist_ee:.2f} cm - {diag_ee}")

# 6. Análisis Hombros
acromion_izq = find_marker(marcadores['marcadores'], 'Punto Acromion Izq.')
acromion_der = find_marker(marcadores['marcadores'], 'Punto Acromion Der.')
grados_hombros, diag_hombros = calcular_angulo_inclinacion(
    (acromion_izq['x'], acromion_izq['y']),
    (acromion_der['x'], acromion_der['y'])
)
print(f"\n=== Cintura Escapular ===")
print(f"Inclinación de hombros: {grados_hombros:.2f}° - {diag_hombros}")

# 7. Análisis Pelvis
eias_izq = find_marker(marcadores['marcadores'], 'Espina Iliaca Anterosuperior Izq.')
eias_der = find_marker(marcadores['marcadores'], 'Espina Iliaca Anterosuperior Der.')
grados_pelvis, diag_pelvis = calcular_angulo_inclinacion(
    (eias_izq['x'], eias_izq['y']),
    (eias_der['x'], eias_der['y'])
)
print(f"\n=== Cintura Pélvica ===")
print(f"Inclinación de pelvis: {grados_pelvis:.2f}° - {diag_pelvis}")

print("\n✓ Análisis completo realizado")

Integración con API

Ejemplo de Endpoint - Calibración

from flask import Flask, request, jsonify
from python.test_matlab_integration import calcular_factor_calibracion

app = Flask(__name__)

@app.route('/api/calibration', methods=['POST'])
def calibration():
    """
    Endpoint para calcular el factor de calibración.

    Request Body:
    {
        "punto1": {"x": 100, "y": 500},
        "punto2": {"x": 200, "y": 500},
        "distancia_real_cm": 10.0
    }

    Response:
    {
        "factor_calibracion": 0.1,
        "unidad": "cm/pixel"
    }
    """
    data = request.json
    punto1 = (data['punto1']['x'], data['punto1']['y'])
    punto2 = (data['punto2']['x'], data['punto2']['y'])
    distancia_real = data.get('distancia_real_cm', 10.0)

    fc = calcular_factor_calibracion(punto1, punto2, distancia_real)

    return jsonify({
        'factor_calibracion': fc,
        'unidad': 'cm/pixel'
    })

if __name__ == '__main__':
    app.run(debug=True)

Ejemplo de Endpoint - Análisis Cervico-Cefálico

@app.route('/api/cervico-cefalica', methods=['POST'])
def cervico_cefalica():
    """
    Endpoint para análisis cérvico-cefálico.

    Request Body:
    {
        "marcadores": [
            {"nombre": "Tragus Izq.", "x": 1150, "y": 400},
            {"nombre": "Tragus Der.", "x": 850, "y": 400},
            {"nombre": "Escotadura Esternal", "x": 1000, "y": 900}
        ],
        "lrv_x": 1000,
        "fc": 0.1
    }

    Response:
    {
        "inclinacion_cabeza": {
            "angulo_grados": 0.5,
            "diagnostico": "neutro"
        },
        "rotacion_escotadura": {
            "distancia_cm": 0.0,
            "diagnostico": "neutro"
        }
    }
    """
    from python.test_matlab_integration import (
        calcular_angulo_inclinacion,
        calcular_rotacion_punto,
        find_marker
    )

    data = request.json
    marcadores = data['marcadores']
    lrv_x = data['lrv_x']
    fc = data['fc']

    # Buscar marcadores
    tragus_izq = find_marker(marcadores, 'Tragus Izq.')
    tragus_der = find_marker(marcadores, 'Tragus Der.')
    escotadura = find_marker(marcadores, 'Escotadura Esternal')

    # Calcular inclinación de cabeza
    angulo_cabeza, diag_cabeza = calcular_angulo_inclinacion(
        (tragus_izq['x'], tragus_izq['y']),
        (tragus_der['x'], tragus_der['y'])
    )

    # Calcular rotación de escotadura
    dist_escotadura, diag_escotadura = calcular_rotacion_punto(
        escotadura['x'], lrv_x, fc
    )

    return jsonify({
        'inclinacion_cabeza': {
            'angulo_grados': round(angulo_cabeza, 2),
            'diagnostico': diag_cabeza
        },
        'rotacion_escotadura': {
            'distancia_cm': round(dist_escotadura, 2),
            'diagnostico': diag_escotadura
        }
    })

Testing con Pytest

Ejecutar Tests Específicos

# Solo tests de vista anterior
pytest python/test_matlab_integration.py::TestVistaAnterior -v

# Solo tests de vista perfil
pytest python/test_matlab_integration.py::TestVistaPerfil -v

# Solo tests de integración
pytest python/test_matlab_integration.py::TestIntegracion -v

# Test específico con output detallado
pytest python/test_matlab_integration.py::TestVistaAnterior::test_angulo_q_normal -vv

# Ejecutar con markers
pytest -m "not slow" python/test_matlab_integration.py -v

Crear Tests Personalizados

# En un archivo nuevo: test_custom.py

import pytest
from python.test_matlab_integration import calcular_angulo_q

def test_mi_caso_especifico():
    """Test para un caso específico de mi paciente."""
    # Coordenadas de mi paciente
    eias = (895.0, 1545.0)
    rotula = (925.0, 1955.0)
    tat = (930.0, 2055.0)

    angulo, diagnostico = calcular_angulo_q(eias, rotula, tat)

    # Verificar que el ángulo está en el rango esperado
    assert 10 < angulo < 20
    assert diagnostico == 'normal'

# Ejecutar: pytest test_custom.py -v

Automatización de UI

Ejemplo con Selenium

from selenium import webdriver
from selenium.webdriver.common.by import By
from python.test_matlab_integration import calcular_factor_calibracion

# Inicializar driver
driver = webdriver.Chrome()
driver.get("http://localhost:3000/posturografia")

# 1. Cargar imagen
upload = driver.find_element(By.ID, "upload-image")
upload.send_keys("/path/to/imagen_anterior.jpg")

# 2. Calibrar
# Simular clicks en la grilla
calibration_area = driver.find_element(By.ID, "calibration-area")
# Click en punto 1 (100, 500)
driver.execute_script(
    "arguments[0].dispatchEvent(new MouseEvent('click', {clientX: 100, clientY: 500}));",
    calibration_area
)
# Click en punto 2 (200, 500)
driver.execute_script(
    "arguments[0].dispatchEvent(new MouseEvent('click', {clientX: 200, clientY: 500}));",
    calibration_area
)

# Verificar FC calculado
fc_display = driver.find_element(By.ID, "fc-value")
fc_esperado = calcular_factor_calibracion((100, 500), (200, 500))
assert float(fc_display.text) == pytest.approx(fc_esperado, rel=0.01)

print("✓ Test de UI pasó correctamente")
driver.quit()

Depuración

Imprimir Valores Intermedios

import numpy as np
from python.test_matlab_integration import calcular_angulo_inclinacion

# Activar modo debug
tragus_izq = (1150.0, 400.0)
tragus_der = (850.0, 410.0)

x1, y1 = tragus_izq
x2, y2 = tragus_der

print(f"Tragus Izq: ({x1}, {y1})")
print(f"Tragus Der: ({x2}, {y2})")

# Cálculo paso a paso
if y2 < y1:
    print("\nCaso: Cae a la derecha")
    A = np.array([x1 - x2, y2 - y2])
    B = np.array([x1 - x2, y1 - y2])
    print(f"Vector A: {A}")
    print(f"Vector B: {B}")

    dot_product = np.dot(A, B)
    norm_A = np.linalg.norm(A)
    norm_B = np.linalg.norm(B)

    print(f"Producto punto: {dot_product}")
    print(f"Norma A: {norm_A}")
    print(f"Norma B: {norm_B}")

    cos_theta = dot_product / (norm_A * norm_B)
    print(f"cos(θ): {cos_theta}")

    theta_rad = np.arccos(cos_theta)
    print(f"θ (radianes): {theta_rad}")

    theta_deg = np.rad2deg(theta_rad)
    print(f"θ (grados): {theta_deg}")

# Ahora con la función
grados, diagnostico = calcular_angulo_inclinacion(tragus_izq, tragus_der)
print(f"\nResultado final: {grados:.2f}° - {diagnostico}")

Recursos Adicionales

  • Documentación Completa: Ver TEST_CASES.md
  • Resumen Ejecutivo: Ver TESTING_SUMMARY.md
  • Código Fuente MATLAB: Ver datos/data/matlab/
  • Marcadores de Ejemplo: Ver datos/data/marcadores/

Comandos Útiles

# Ver estructura de tests
pytest --collect-only python/test_matlab_integration.py

# Ejecutar con output detallado
pytest python/test_matlab_integration.py -vv -s

# Ejecutar y detener en primera falla
pytest python/test_matlab_integration.py -x

# Ejecutar solo tests que fallaron la última vez
pytest --lf python/test_matlab_integration.py

# Generar reporte HTML
pytest python/test_matlab_integration.py --html=report.html

# Ver tiempo de ejecución de cada test
pytest python/test_matlab_integration.py --durations=10

Troubleshooting

Error: ModuleNotFoundError: No module named 'scipy'

pip install scipy

Error: No se encuentra el archivo .mat

Los tests funcionan sin archivos .mat usando datos de prueba. Para usar archivos reales, asegúrate de que estén en datos/data/marcadores/.

Error: Valores no coinciden con MATLAB

Verifica: 1. Factor de calibración (FC) es correcto 2. Coordenadas de LRV son correctas 3. Orden de los puntos en la función (izquierdo vs derecho) 4. Unidades (píxeles vs cm)


Última actualización: 2025-10-07