# Programme d'anonymisation de documents PDF

**Fichier principal** : `anonymizer_core_refactored_onnx.py`

Pipeline de pseudonymisation combinant extraction de texte multi-passes,
detection par expressions regulieres, reconnaissance d'entites nommees (NER)
et propagation globale des donnees personnelles.

Produit trois fichiers : texte anonymise, journal d'audit et PDF caviarde.

---

<div style="page-break-before: always;"></div>

## Pipeline de traitement

```
                           ┌─────────────────┐
                           │   PDF d'entree   │
                           └────────┬────────┘
                                    │
                                    ▼
                 ┌──────────────────────────────────────┐
                 │  1. EXTRACTION DE TEXTE              │
                 │                                      │
                 │  pdfplumber ─► pdfminer ─► PyMuPDF   │
                 │         ─► docTR OCR ─► tesseract    │
                 │                                      │
                 │  (5 passes, meilleur resultat retenu) │
                 └──────────────────┬───────────────────┘
                                    │
                                    ▼
                 ┌──────────────────────────────────────┐
                 │  2. ANONYMISATION REGEX              │
                 │                                      │
                 │  EMAIL · TEL · IBAN · NIR · IPP/ADM  │
                 │  FINESS · RPPS · OGC · dates         │
                 │  adresses · force-mask YAML          │
                 └──────────────────┬───────────────────┘
                                    │
                                    ▼
                 ┌──────────────────────────────────────┐
                 │  3. NER (optionnel)                  │
                 │                                      │
                 │  EDS-Pseudo (AP-HP, F1=0.97)         │
                 │  ou distilcamembert ONNX             │
                 └──────────────────┬───────────────────┘
                                    │
                                    ▼
                 ┌──────────────────────────────────────┐
                 │  4. EXTRACTION TRACKARE              │
                 │                                      │
                 │  Identite patient + soignants         │
                 │  N° episode · pattern Prenom/NOM     │
                 └──────────────────┬───────────────────┘
                                    │
                                    ▼
                 ┌──────────────────────────────────────┐
                 │  5. CONSOLIDATION GLOBALE            │
                 │                                      │
                 │  Propagation des PII sur toutes les  │
                 │  pages · noms compagnons · noms      │
                 │  composes traites en bloc            │
                 └──────────────────┬───────────────────┘
                                    │
                                    ▼
                 ┌──────────────────────────────────────┐
                 │  6. RESCAN SELECTIF + NETTOYAGE      │
                 │                                      │
                 │  TEL fragmentes · CP orphelins       │
                 │  tokens globaux sur texte final      │
                 └──────────────────┬───────────────────┘
                                    │
                                    ▼
                 ┌──────────────────────────────────────┐
                 │          FICHIERS DE SORTIE          │
                 │                                      │
                 │  .pseudonymise.txt    texte anonymise │
                 │  .audit.jsonl         journal audit   │
                 │  .redacted_raster.pdf PDF caviarde    │
                 └──────────────────────────────────────┘
```

---

<div style="page-break-before: always;"></div>

## Detail des etapes

### 1. Extraction de texte

Fonction : `extract_text_with_fallback_ocr`

5 passes successives, chaque passe sert de fallback si la precedente
ne produit pas assez de contenu :

| Passe | Moteur       | Role                                         |
|-------|--------------|----------------------------------------------|
| 1     | pdfplumber   | Extraction textuelle native                  |
| 2     | pdfminer     | Extraction alternative (LAParams)            |
| 3     | PyMuPDF      | Fallback si artefacts `(cid:xx)`             |
| 4     | docTR OCR    | OCR deep learning pour PDF scannes           |
| 5     | tesseract    | OCR complementaire                           |

Pour les PDF scannes, docTR et tesseract sont executes en parallele ;
le meilleur resultat est retenu page par page.

### 2. Anonymisation regex

Fonction : `_mask_line_by_regex`

| Type          | Placeholder    | Exemple              |
|---------------|----------------|----------------------|
| Email         | `[EMAIL]`      | nom@domaine.fr       |
| Telephone     | `[TEL]`        | 01 23 45 67 89       |
| IBAN          | `[IBAN]`       | FR76 3000 ...        |
| NIR (secu)    | `[NIR]`        | 1 85 05 78 ...       |
| IPP / ADM     | `[IPP]`        | IPP : 123456         |
| FINESS        | `[FINESS]`     | FINESS : 750000001   |
| RPPS          | `[RPPS]`       | RPPS : 12345678901   |
| OGC           | `[OGC]`        | N OGC : ABC-123      |
| Dates         | `[DATE]`       | 12/03/2024           |
| Adresses      | `[ADRESSE]`    | 12 rue de la Paix    |

Configuration :
- `config/dictionnaires.default.yml` : template versionne, source de verite des valeurs par defaut
- `config/dictionnaires.yml` : surcharge locale chargee par defaut, contenant uniquement les ecarts site/runtime

### 3. Reconnaissance d'entites nommees (NER)

S'applique sur le texte narratif (hors tableaux) apres les regles regex.

- **EDS-Pseudo** (`eds_pseudo_manager.py`) : modele AP-HP (F1=0.97) via edsnlp.
  13 labels : NOM, PRENOM, MAIL, TEL, SECU, ADRESSE, ZIP, VILLE,
  HOPITAL, DATE, DATE_NAISSANCE, IPP, NDA.
- **ONNX fallback** : `cmarkea/distilcamembert-base-ner` via onnxruntime.

### 4. Extraction Trackare

Fonction : `_extract_trackare_identity`

Pour les documents Trackare (logiciel medical), extraction des champs
d'identite structures : nom/prenom patient, adresse, date de naissance,
numeros d'episode (NDA), et noms des soignants.
Gere le pattern multi-lignes "Prenom\nNOM" courant dans ces documents.

### 5. Consolidation globale

Les PII detectes sont propages sur l'ensemble du document :

- **NOM_GLOBAL** : chaque token de nom masque dans toutes les pages.
  Detection de "noms compagnons" (mot en majuscules adjacent a un nom connu).
- **TEL_GLOBAL, EMAIL_GLOBAL, ADRESSE_GLOBAL**, etc. : propagation globale
  des valeurs uniques.
- Noms composes (ex: JEAN-PIERRE) traites comme un bloc.

### 6. Rescan selectif et nettoyage

Rescan des PII critiques (EMAIL, TEL, IBAN, NIR) ayant echappe
au premier passage. Nettoyage des codes postaux orphelins
et numeros de telephone fragmentes sur plusieurs lignes.
Application des tokens globaux sur le texte pseudonymise final.

---

## Generation du PDF caviarde

Pour les PDF textuels, les coordonnees des zones sensibles sont obtenues
via `page.search_for()` (PyMuPDF). Pour les PDF scannes (image only),
un fallback OCR est utilise :

- **docTR** : localisation mot par mot avec decoupe sur changement de casse
  (tokens OCR fusionnes comme "GUILNGARAnne") + reconstruction de lignes
  pour detecter les patterns TEL et IPP.
- **tesseract** : complement sur copie propre de l'image pour les numeros
  de telephone (non detectes par docTR).

---

## Configuration et utilisation

| Element                       | Description                                    |
|-------------------------------|------------------------------------------------|
| `config/dictionnaires.default.yml` | Valeurs par defaut completes et versionnees |
| `config/dictionnaires.yml`    | Surcharge locale optionnelle (ecarts uniquement) |
| `Pseudonymisation_Gui_V5.py` | Interface graphique (traitement par lots)       |
| Ligne de commande             | `python anonymizer_core_refactored_onnx.py fichier.pdf --hf --raster` |
