diagram_ph/tests_notebook/diagnose_diagram.py

313 lines
10 KiB
Python

#!/usr/bin/env python3
"""
Script de diagnostic pour identifier et corriger le problème des diagrammes vides
"""
import sys
import os
import json
import base64
import matplotlib
matplotlib.use('Agg') # Backend non-interactif
import matplotlib.pyplot as plt
import numpy as np
# Ajouter le répertoire parent pour importer les modules
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
def test_basic_matplotlib():
"""Test si matplotlib fonctionne correctement."""
print("=== TEST MATPLOTLIB DE BASE ===")
try:
# Créer un graphique simple
fig, ax = plt.subplots(figsize=(10, 6))
x = np.linspace(0, 10, 100)
y = np.sin(x)
ax.plot(x, y, 'b-', linewidth=2)
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_title('Test Matplotlib')
ax.grid(True)
# Sauvegarder
plt.savefig('test_matplotlib.png', dpi=100, bbox_inches='tight')
plt.close(fig)
# Vérifier le fichier
if os.path.exists('test_matplotlib.png'):
size = os.path.getsize('test_matplotlib.png')
print(f"✅ Matplotlib fonctionne - Fichier : {size} octets")
return True
else:
print("❌ Fichier non généré")
return False
except Exception as e:
print(f"❌ Erreur matplotlib : {e}")
return False
def test_refrigerant_loading():
"""Test le chargement du réfrigérant R290."""
print("\n=== TEST CHARGEMENT R290 ===")
try:
from app.core.refrigerant_loader import get_refrigerant
refrigerant = get_refrigerant("R290")
if refrigerant:
print(f"✅ R290 chargé : {refrigerant.refrig_name}")
# Test fonctions de base
try:
h_l = refrigerant.hsl_px(1.0, 0) / 1000 # kJ/kg
h_v = refrigerant.hsv_px(1.0, 1) / 1000 # kJ/kg
T_sat = refrigerant.T_px(1.0, 0.5)
print(f" h_l(1 bar) : {h_l:.2f} kJ/kg")
print(f" h_v(1 bar) : {h_v:.2f} kJ/kg")
print(f" T_sat(1 bar) : {T_sat - 273.15:.2f} °C")
if h_l is not None and h_v is not None and T_sat is not None:
print("✅ Fonctions thermodynamiques OK")
return True
else:
print("❌ Valeurs None retournées")
return False
except Exception as e:
print(f"❌ Erreur fonctions thermodynamiques : {e}")
return False
else:
print("❌ R290 non chargé")
return False
except Exception as e:
print(f"❌ Erreur chargement R290 : {e}")
return False
def test_saturation_curve():
"""Test la génération de la courbe de saturation."""
print("\n=== TEST COURBE DE SATURATION ===")
try:
from app.core.refrigerant_loader import get_refrigerant
refrigerant = get_refrigerant("R290")
Hsl, Hsv, Psat, Tsat = [], [], [], []
# Calculer quelques points
for p_bar in [0.5, 1.0, 2.0, 5.0, 10.0, 20.0]:
try:
h_l = refrigerant.hsl_px(p_bar, 0) / 1000
h_v = refrigerant.hsv_px(p_bar, 1) / 1000
T_sat = refrigerant.T_px(p_bar, 0.5)
if h_l is not None and h_v is not None and T_sat is not None:
Hsl.append(h_l)
Hsv.append(h_v)
Psat.append(p_bar)
Tsat.append(T_sat)
except Exception:
continue
print(f"✅ Points calculés : {len(Hsl)}")
if len(Hsl) > 2:
# Créer le graphique
fig, ax = plt.subplots(figsize=(10, 6))
ax.plot(Hsl, Psat, 'b-', linewidth=2, label='Liquide saturé')
ax.plot(Hsv, Psat, 'r-', linewidth=2, label='Vapeur saturée')
ax.set_xlabel('Enthalpie [kJ/kg]')
ax.set_ylabel('Pression [bar]')
ax.set_title('Courbe de Saturation R290')
ax.set_yscale('log')
ax.grid(True, which='both', alpha=0.3)
ax.legend()
plt.savefig('test_saturation.png', dpi=100, bbox_inches='tight')
plt.close(fig)
if os.path.exists('test_saturation.png'):
size = os.path.getsize('test_saturation.png')
print(f"✅ Courbe générée - Fichier : {size} octets")
return True
else:
print("❌ Fichier non généré")
return False
else:
print("❌ Pas assez de points")
return False
except Exception as e:
print(f"❌ Erreur courbe saturation : {e}")
import traceback
traceback.print_exc()
return False
def test_complete_diagram():
"""Test la génération complète du diagramme."""
print("\n=== TEST DIAGRAMME COMPLET ===")
try:
from app.core.refrigerant_loader import get_refrigerant
from app.services.diagram_generator import DiagramGenerator
# Créer le générateur
refrigerant = get_refrigerant("R290")
diagram_gen = DiagramGenerator(refrigerant)
# Générer le diagramme
fig = diagram_gen.plot_diagram(
p_min=0.1,
p_max=20.0,
h_min=-100,
h_max=600,
include_isotherms=True,
title="Test Complet R290"
)
# Sauvegarder
fig.savefig('test_complete.png', dpi=100, bbox_inches='tight')
plt.close(fig)
if os.path.exists('test_complete.png'):
size = os.path.getsize('test_complete.png')
print(f"✅ Diagramme complet généré - Fichier : {size} octets")
# Vérifier si le fichier est valide
if size > 1000: # Au moins 1 Ko
print("✅ Fichier semble valide")
return True
else:
print("❌ Fichier trop petit - probablement vide")
return False
else:
print("❌ Fichier non généré")
return False
except Exception as e:
print(f"❌ Erreur diagramme complet : {e}")
import traceback
traceback.print_exc()
return False
def test_api_direct():
"""Test l'API directement."""
print("\n=== TEST API DIRECT ===")
try:
import requests
# Charger la requête
with open('request_r290.json', 'r') as f:
request_data = json.load(f)
# Appeler l'API
response = requests.post("http://localhost:8001/api/v1/diagrams/ph",
json=request_data, timeout=30)
if response.status_code == 200:
result = response.json()
if 'image' in result and result['image']:
# Décoder et sauvegarder
image_data = base64.b64decode(result['image'])
with open('test_api.png', 'wb') as f:
f.write(image_data)
size = len(image_data)
print(f"✅ API fonctionne - Image : {size} octets")
if size > 1000:
print("✅ Image API valide")
return True
else:
print("❌ Image API trop petite")
return False
else:
print("❌ Pas d'image dans la réponse API")
return False
else:
print(f"❌ Erreur API : {response.status_code}")
return False
except Exception as e:
print(f"❌ Erreur API : {e}")
return False
def main():
"""Fonction principale de diagnostic."""
print("🔍 DIAGNOSTIC COMPLET - API DIAGRAMMES PH")
print("=" * 50)
# Tests progressifs
tests = [
("Matplotlib de base", test_basic_matplotlib),
("Chargement R290", test_refrigerant_loading),
("Courbe de saturation", test_saturation_curve),
("Diagramme complet", test_complete_diagram),
("API directe", test_api_direct),
]
results = []
for test_name, test_func in tests:
print(f"\n🧪 {test_name}")
print("-" * 30)
try:
result = test_func()
results.append((test_name, result))
except Exception as e:
print(f"❌ Erreur inattendue : {e}")
results.append((test_name, False))
# Rapport final
print("\n" + "=" * 50)
print("📊 RAPPORT FINAL")
print("=" * 50)
success_count = 0
for test_name, success in results:
status = "✅ SUCCÈS" if success else "❌ ÉCHEC"
print(f"{status} - {test_name}")
if success:
success_count += 1
total_tests = len(results)
success_rate = (success_count / total_tests) * 100
print(f"\n📈 Résumé : {success_count}/{total_tests} tests réussis ({success_rate:.1f}%)")
if success_rate == 100:
print("\n🎉 TOUS LES TESTS RÉUSSIS !")
print("✅ Le système fonctionne parfaitement")
elif success_rate >= 60:
print("\n🟡 CERTAINS TESTS RÉUSSIS")
print("⚠️ Des problèmes subsistent")
else:
print("\n🔴 NOMBREUX ÉCHECS")
print("🚨 Des corrections majeures sont nécessaires")
# Recommandations
print("\n💡 RECOMMANDATIONS :")
if not any(r[1] for r in results[:2]): # Matplotlib ou R290
print("- Vérifier l'installation de matplotlib")
print("- Vérifier les fichiers DLL/SO dans libs/so/")
if results[2][1] and not results[3][1]: # Saturation OK mais diagramme complet KO
print("- Problème dans le service DiagramGenerator")
print("- Vérifier les calculs d'isothermes")
if results[3][1] and not results[4][1]: # Diagramme local OK mais API KO
print("- Problème dans l'endpoint API")
print("- Vérifier les logs de l'API")
print("\n📁 Fichiers générés dans le répertoire courant")
if __name__ == "__main__":
main()