diff --git a/anonymizer_core_refactored_onnx.py b/anonymizer_core_refactored_onnx.py index 0baf6bb..9626308 100644 --- a/anonymizer_core_refactored_onnx.py +++ b/anonymizer_core_refactored_onnx.py @@ -301,6 +301,8 @@ _MEDICAL_STOP_WORDS_SET = { "axa", "ttt", "anionique", "abdomino", "cod", "omi", "urg", "med", "10mg", "20mg", "40mg", "100mg", "300ui", "500ml", "innohep", "coaprovel", "actiskenan", "simvastatine", "forlax", + # Mots temporels / contextuels détectés comme EDS_HOPITAL + "semaine", "jour", "matin", "soir", "nuit", "midi", # Mots clés de contexte document "compétences", "maladies", "inflammatoires", "systémiques", "rares", "fret", "fax", "contexte", "résultat", "resultat", "résultats", "resultats", @@ -888,11 +890,19 @@ def _extract_trackare_identity(full_text: str) -> Tuple[set, List[PiiHit]]: if m.group(2): _add_name(m.group(2)) - # --- Noms soignants dans les Notes d'évolution --- - # Pattern: "Note d'évolution PRENOM NOM" ou "NOM HH:MM texte..." - for m in re.finditer(r"Note\s+d'[ée]volution\s+([A-ZÉÈÀÙÂÊÎÔÛ][a-zéèàùâêîôû]+)\s+([A-ZÉÈÀÙÂÊÎÔÛ]{2,})", full_text): - _add_name(m.group(1)) - _add_name(m.group(2)) + # --- Noms soignants dans les Notes d'évolution / Notes IDE / Notes médicales --- + # Pattern: "Note IDE\nPrenom NOM" ou "Note d'évolution\nPrenom NOM" + for m in re.finditer( + r"Note\s+(?:IDE|AS|d'[ée]volution|m[ée]dicale|kin[ée])\s*\n\s*" + r"([A-ZÉÈÀÙÂÊÎÔÛa-zéèàùâêîôû][a-zéèàùâêîôûäëïöüç]+)\s+" + r"([A-ZÉÈÀÙÂÊÎÔÛ][A-ZÉÈÀÙÂÊÎÔÛa-zéèàùâêîôûäëïöüç\-]+)", + full_text + ): + prenom, nom = m.group(1), m.group(2) + if prenom.lower() not in _MEDICAL_STOP_WORDS_SET: + _add_name(prenom) + if nom.lower() not in _MEDICAL_STOP_WORDS_SET: + _add_name(nom) # --- Noms soignants multi-lignes : "Prénom\nNOM" dans les tableaux de prescriptions/soins --- for m in re.finditer( @@ -1174,7 +1184,7 @@ def _mask_with_eds_pseudo(text: str, ents: List[Dict[str, Any]], cfg: Dict[str, continue # Filtrer les faux positifs NOM/PRENOM (médicaments, acronymes médicaux) label = e.get("entity_group", "EDS") - if label in ("NOM", "PRENOM"): + if label in ("NOM", "PRENOM", "HOPITAL", "VILLE"): if w.lower() in _MEDICAL_STOP_WORDS_SET: continue # Filtrer aussi les tokens multi-mots dont un composant est un stop word @@ -1309,10 +1319,10 @@ def redact_pdf_vector(original_pdf: Path, audit: List[PiiHit], out_pdf: Path) -> by_page.setdefault(h.page, []).append(h) # Kinds à ne pas chercher dans le PDF (dates masquées uniquement dans le texte, # pas dans le PDF où elles rendent les tableaux illisibles) - _VECTOR_SKIP_KINDS = {"EDS_DATE", "EDS_DATE_NAISSANCE", "EDS_SECU"} + _VECTOR_SKIP_KINDS = {"EDS_DATE", "EDS_DATE_NAISSANCE", "EDS_SECU", "EDS_TEL"} # Kinds dont les tokens courts (< 5) risquent le substring matching via page.search_for() _VECTOR_SHORT_TOKEN_KINDS = {"NOM_GLOBAL", "NOM_EXTRACTED", "EDS_NOM", "EDS_PRENOM", - "EDS_HOPITAL", "ETAB", "ETAB_GLOBAL"} + "EDS_HOPITAL", "EDS_VILLE", "ETAB", "ETAB_GLOBAL"} for pno in range(len(doc)): page = doc[pno] hits = by_page.get(pno, []) + by_page.get(-1, []) @@ -1365,9 +1375,9 @@ def redact_pdf_raster(original_pdf: Path, audit: List[PiiHit], out_pdf: Path, dp for pno in range(len(doc)): page = doc[pno] rects = [] - _RASTER_SKIP_KINDS = {"EDS_DATE", "EDS_DATE_NAISSANCE", "EDS_SECU"} + _RASTER_SKIP_KINDS = {"EDS_DATE", "EDS_DATE_NAISSANCE", "EDS_SECU", "EDS_TEL"} _RASTER_SHORT_TOKEN_KINDS = {"NOM_GLOBAL", "NOM_EXTRACTED", "EDS_NOM", "EDS_PRENOM", - "EDS_HOPITAL", "ETAB", "ETAB_GLOBAL"} + "EDS_HOPITAL", "EDS_VILLE", "ETAB", "ETAB_GLOBAL"} hits = [x for x in audit if x.page in {pno, -1}] for h in hits: token = h.original.strip()