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