feat: BIO_NORMALS 33 analytes + interprétations cliniques + cohérence DAS/bio étendue

- BIO_NORMALS passe de 13 à 33 tests (cardio, infectio, métabo, thyroïde, hémato, hépatique)
- _BIO_INTERPRETATION synchronisé (33 entrées, 3 clés high/low/normal chacune)
- _DAS_BIO_CHECKS étendu de 13 à 38 patterns (sepsis, infarctus, EP, diabète, thyroïde, etc.)
- lab_value_sanity.yaml étendu avec 20 garde-fous plausibilité nouveaux tests
- tests/test_bio_normals.py : 32 tests (complétude, concordance, _is_abnormal)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
dom
2026-02-20 11:00:53 +01:00
parent 3c070f3c1d
commit 1a3c523987
4 changed files with 318 additions and 9 deletions

View File

@@ -165,18 +165,48 @@ def _build_tagged_context(dossier: DossierMedical) -> tuple[str, dict[str, str]]
# Interprétations cliniques pour le résumé bio déterministe
_BIO_INTERPRETATION: dict[str, dict[str, str]] = {
"CRP": {"high": "infection/inflammation active", "low": "normal", "normal": "pas d'inflammation"},
"Hémoglobine": {"high": "polyglobulie", "low": "anémie", "normal": "pas d'anémie"},
"Plaquettes": {"high": "thrombocytose", "low": "thrombopénie", "normal": "numération normale"},
"Leucocytes": {"high": "hyperleucocytose", "low": "leucopénie", "normal": "numération normale"},
"Créatinine": {"high": "insuffisance rénale", "low": "normal", "normal": "fonction rénale conservée"},
"Potassium": {"high": "hyperkaliémie", "low": "hypokaliémie", "normal": "kaliémie normale"},
"Sodium": {"high": "hypernatrémie", "low": "hyponatrémie", "normal": "natrémie normale"},
# --- Hépatique / digestif ---
"Lipasémie": {"high": "pancréatite probable", "low": "normal", "normal": "pas de pancréatite"},
"ASAT": {"high": "cytolyse hépatique", "low": "normal", "normal": "pas de cytolyse"},
"ALAT": {"high": "cytolyse hépatique", "low": "normal", "normal": "pas de cytolyse"},
"GGT": {"high": "cholestase/atteinte hépatique", "low": "normal", "normal": "pas de cholestase"},
"PAL": {"high": "cholestase/atteinte osseuse", "low": "normal", "normal": "pas de cholestase"},
"Bilirubine totale": {"high": "ictère/cholestase", "low": "normal", "normal": "pas d'ictère"},
"Bilirubine directe": {"high": "cholestase/obstruction biliaire", "low": "normal", "normal": "pas de cholestase"},
"LDH": {"high": "cytolyse/hémolyse", "low": "normal", "normal": "pas de cytolyse"},
# --- Inflammatoire ---
"CRP": {"high": "infection/inflammation active", "low": "normal", "normal": "pas d'inflammation"},
"VS": {"high": "inflammation", "low": "normal", "normal": "pas d'inflammation"},
# --- Ionogramme ---
"Sodium": {"high": "hypernatrémie", "low": "hyponatrémie", "normal": "natrémie normale"},
"Potassium": {"high": "hyperkaliémie", "low": "hypokaliémie", "normal": "kaliémie normale"},
# --- Hématologie ---
"Hémoglobine": {"high": "polyglobulie", "low": "anémie", "normal": "pas d'anémie"},
"Plaquettes": {"high": "thrombocytose", "low": "thrombopénie", "normal": "numération normale"},
"Leucocytes": {"high": "hyperleucocytose", "low": "leucopénie", "normal": "numération normale"},
"TP": {"high": "normal", "low": "insuffisance hépatique/CIVD", "normal": "coagulation normale"},
"TCA": {"high": "hypocoagulabilité", "low": "normal", "normal": "coagulation normale"},
"Ferritine": {"high": "surcharge en fer/inflammation", "low": "carence en fer", "normal": "réserves en fer normales"},
# --- Rénal ---
"Créatinine": {"high": "insuffisance rénale", "low": "normal", "normal": "fonction rénale conservée"},
"Urée": {"high": "insuffisance rénale/catabolisme", "low": "normal", "normal": "fonction rénale conservée"},
# --- Cardiologie ---
"Troponine": {"high": "nécrose myocardique (SCA/IDM)", "low": "normal", "normal": "pas de souffrance myocardique"},
"BNP": {"high": "insuffisance cardiaque", "low": "normal", "normal": "pas d'insuffisance cardiaque"},
"NT-proBNP": {"high": "insuffisance cardiaque", "low": "normal", "normal": "pas d'insuffisance cardiaque"},
"D-dimères": {"high": "activation coagulation (EP/TVP possible)", "low": "normal", "normal": "EP/TVP peu probable"},
"INR": {"high": "hypocoagulabilité/surdosage AVK", "low": "hypercoagulabilité", "normal": "coagulation normale"},
"Fibrinogène": {"high": "inflammation/risque thrombotique", "low": "CIVD/insuffisance hépatique", "normal": "normal"},
# --- Infectiologie ---
"Procalcitonine": {"high": "infection bactérienne", "low": "normal", "normal": "pas d'infection bactérienne"},
"Lactate": {"high": "hypoperfusion/choc", "low": "normal", "normal": "pas d'hypoperfusion"},
# --- Métabolisme ---
"Glycémie": {"high": "hyperglycémie/diabète", "low": "hypoglycémie", "normal": "glycémie normale"},
"HbA1c": {"high": "diabète mal équilibré", "low": "normal", "normal": "équilibre glycémique correct"},
"Albumine": {"high": "déshydratation", "low": "dénutrition/insuffisance hépatique", "normal": "état nutritionnel conservé"},
"Acide urique": {"high": "hyperuricémie/goutte", "low": "normal", "normal": "uricémie normale"},
# --- Thyroïde ---
"TSH": {"high": "hypothyroïdie", "low": "hyperthyroïdie", "normal": "fonction thyroïdienne normale"},
}
@@ -243,6 +273,7 @@ def _check_das_bio_coherence(dossier: DossierMedical) -> list[str]:
# Patterns DAS → (test bio attendu, direction attendue)
_DAS_BIO_CHECKS: dict[str, tuple[str, str]] = {
# Hématologie
"leucocytose": ("Leucocytes", "high"),
"leucopénie": ("Leucocytes", "low"),
"leucopenie": ("Leucocytes", "low"),
@@ -254,8 +285,42 @@ def _check_das_bio_coherence(dossier: DossierMedical) -> list[str]:
"anémie": ("Hémoglobine", "low"),
"anemie": ("Hémoglobine", "low"),
"polyglobulie": ("Hémoglobine", "high"),
"carence en fer": ("Ferritine", "low"),
"carence martiale": ("Ferritine", "low"),
# Ionogramme
"hyperkaliémie": ("Potassium", "high"),
"hypokaliémie": ("Potassium", "low"),
"hypernatrémie": ("Sodium", "high"),
"hyponatrémie": ("Sodium", "low"),
"hyponatremie": ("Sodium", "low"),
# Rénal
"insuffisance rénale": ("Créatinine", "high"),
"insuffisance renale": ("Créatinine", "high"),
# Digestif
"pancréatite": ("Lipasémie", "high"),
"pancreatite": ("Lipasémie", "high"),
# Infectiologie
"sepsis": ("CRP", "high"),
"choc septique": ("Lactate", "high"),
# Cardiologie
"infarctus": ("Troponine", "high"),
"syndrome coronarien": ("Troponine", "high"),
"embolie pulmonaire": ("D-dimères", "high"),
"insuffisance cardiaque": ("BNP", "high"),
# Métabolisme / nutrition
"dénutrition": ("Albumine", "low"),
"denutrition": ("Albumine", "low"),
"diabète": ("Glycémie", "high"),
"diabete": ("Glycémie", "high"),
"hyperuricémie": ("Acide urique", "high"),
"goutte": ("Acide urique", "high"),
# Thyroïde
"hypothyroïdie": ("TSH", "high"),
"hypothyroidie": ("TSH", "high"),
"hyperthyroïdie": ("TSH", "low"),
"hyperthyroidie": ("TSH", "low"),
# Coagulation
"civd": ("Fibrinogène", "low"),
}
# Indexer les valeurs bio disponibles

View File

@@ -6,20 +6,48 @@ from __future__ import annotations
# Plages de référence biologiques (min, max) — utilisées par _is_abnormal()
# et exportées pour le formatage du contexte LLM dans rag_search.py
BIO_NORMALS: dict[str, tuple[float, float]] = {
# --- Hépatique / digestif ---
"Lipasémie": (0, 60),
"CRP": (0, 5),
"ASAT": (0, 40),
"ALAT": (0, 40),
"GGT": (0, 60),
"PAL": (0, 150),
"Bilirubine totale": (0, 17),
# Ionogramme (fallback adulte ; les règles de décision utilisent reference_ranges.yaml)
"Bilirubine directe": (0, 5), # µmol/L
"LDH": (120, 250), # UI/L
# --- Inflammatoire ---
"CRP": (0, 5),
"VS": (0, 20), # mm/h
# --- Ionogramme (fallback adulte ; les règles de décision utilisent reference_ranges.yaml) ---
"Sodium": (135, 145),
"Potassium": (3.5, 5.0),
# --- Hématologie ---
"Hémoglobine": (12, 17),
"Plaquettes": (150, 400),
"Leucocytes": (4, 10),
"TP": (70, 100), # %
"TCA": (25, 35), # secondes
"Ferritine": (20, 300), # µg/L
# --- Rénal ---
"Créatinine": (50, 120),
"Urée": (2.5, 7.5), # mmol/L
# --- Cardiologie ---
"Troponine": (0, 0.04), # ng/mL (seuil hs-TnI)
"BNP": (0, 100), # pg/mL
"NT-proBNP": (0, 300), # pg/mL
"D-dimères": (0, 500), # ng/mL
"INR": (0.8, 1.2), # ratio
"Fibrinogène": (2, 4), # g/L
# --- Infectiologie ---
"Procalcitonine": (0, 0.5), # ng/mL
"Lactate": (0.5, 2.0), # mmol/L
# --- Métabolisme ---
"Glycémie": (3.9, 5.5), # mmol/L (à jeun)
"HbA1c": (4.0, 6.0), # %
"Albumine": (35, 50), # g/L
"Acide urique": (150, 420), # µmol/L
# --- Thyroïde ---
"TSH": (0.4, 4.0), # mUI/L
}