Background réaliste CsI(Tl) + hybridation mesuré/synthétique + dashboard continuum

- Remplace le continuum exponentiel par un modèle réaliste CsI(Tl) dans
  l'entraînement (bosse asymétrique ~110 keV + queue Compton)
- Ajoute l'injection de background mesuré (70% mesuré / 30% synthétique)
  via --measured_background et MEASURED_BACKGROUND_PATH
- Ajoute l'endpoint /api/background/continuum et le toggle "Continuum CsI"
  sur le dashboard background
- Exclut le canal 1023 (overflow bin) de l'affichage web (NUM_CHANNELS=1023)
- Corrige le lissage Gaussien du background (normalisation locale aux bords)
- Met à jour README.md, CLAUDE.md, TUTORIEL.md, TOTO.md, vega_ml/README.md

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Jacquin Antoine
2026-05-19 18:14:00 +02:00
parent 1e0c1a5ea5
commit 75d271c696
17 changed files with 917 additions and 224 deletions

120
README.md
View File

@ -20,6 +20,14 @@ Radiacode 103 (USB)
│ └── Rapport quotidien a 00h00 │
│ │
│ Modele: vega_best.pt (entraite sur RTX 5060 Ti) │
└─────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
│ Conteneur web (FastAPI + Chart.js) │
│ │
│ Dashboard :8080 — Spectre en temps reel, │
│ background, CPS, historique, isotopes detectes │
└─────────────────────────────────────────────────────────┘
```
@ -35,25 +43,48 @@ docker compose run --rm train
# 3. Capturer le bruit de fond (24h, sans source radioactive)
docker compose run --rm -d --name radiacode-bg detect python capture_background.py
# 4. Lancer la detection continue
docker compose up detect
# 4. Lancer la detection continue + dashboard
docker compose up detect web
```
## Configuration
Variables d'environnement (dans `docker-compose.yml`) :
### Entrainement (service `train`)
| Variable | Defaut | Description |
|----------|--------|-------------|
| `NUM_SAMPLES` | `50000` | Nombre de spectres synthetiques |
| `EPOCHS` | `100` | Epochs max d'entrainement |
| `BATCH_SIZE` | `64` | Taille de batch |
| `LEARNING_RATE` | `0.001` | Taux d'apprentissage initial |
| `DETECTOR` | `radiacode_103` | Config du detecteur |
| `MIN_DURATION` | `43200` | Duree min des spectres (12h en s) |
| `MAX_DURATION` | `86400` | Duree max des spectres (24h en s) |
| `SEED` | `42` | Graine aleatoire |
| `MEASURED_BACKGROUND_PATH` | `/data/background_24h.npy` | Background mesure pour entrainement hybride |
### Detection (service `detect`)
| Variable | Defaut | Description |
|----------|--------|-------------|
| `MODEL_PATH` | `/models/vega_best.pt` | Chemin du modele PyTorch |
| `ISOTOPE_INDEX_PATH` | `/models/vega_isotope_index.txt` | Index des 82 isotopes |
| `BACKGROUND_PATH` | `/data/background_24h.npy` | Fichier background de reference |
| `THRESHOLD` | `0.5` | Seuil de probabilite pour la detection |
| `SAMPLE_INTERVAL` | `60` | Intervalle d'echantillonnage (secondes) |
| `SAMPLE_INTERVAL` | `60` | Intervalle d'echantillonnage (s) |
| `REPORT_HOUR` | `0` | Heure du rapport quotidien |
| `MIN_LIVE_TIME` | `3600` | Live time minimum pour un rapport (secondes) |
| `MIN_LIVE_TIME` | `3600` | Live time minimum pour un rapport (s) |
| `VEGA_DEVICE` | `cpu` | Device PyTorch (`cpu` ou `cuda`) |
### Dashboard (service `web`)
| Variable | Defaut | Description |
|----------|--------|-------------|
| `ENERGY_CALIBRATION_OFFSET` | `0.33` | Calibration energetique (offset keV) |
| `ENERGY_CALIBRATION_SLOPE` | `2.97` | Calibration energetique (pente keV/canal) |
## Bruit Poissonnien et modele
### Physique du bruit
@ -76,12 +107,19 @@ Le VegaModel est un CNN-FCNN multi-tache inspire de l'architecture Vega d'Open-R
- **Classification** : 82 neurones avec sigmoid (presence/absence de chaque isotope)
- **Regression** : 82 neurones (activite estimee en Bq, normalisee a max_activity_bq=1000)
- **Architecture** :
- 3 blocs CNN (64, 128, 256 canaux) avec BatchNorm + ReLU + MaxPool
- 3 blocs CNN (64, 128, 256 canaux) avec BatchNorm + LeakyReLU + MaxPool
- 2 couches FC (512, 256) avec Dropout(0.3)
- **34 493 156 parametres** au total
- **Fonction de perte** : VegaLoss = classification_weight * BCE + regression_weight * MSE (ponderee pour ne penaliser l'activite que sur les isotopes presents)
- **Fonction de perte** : VegaLoss = classification_weight * BCE + regression_weight * Huber (ponderee pour ne penaliser l'activite que sur les isotopes presents)
- **Entrainement** : 50 000 spectres synthetiques, 100 epochs, AMP (mixed precision), early stopping (patience=10)
- **Background dans les donnees synthetiques** : K-40, radon (Pb-214, Bi-214), thorium (Ac-228, Pb-212, Tl-208) simules avec des activites aleatoires realistes
### Background d'entrainement
Le background synthetique utilise un modele realiste calibre sur les mesures du Radiacode 103 :
- **Continuum CsI(Tl)** : Bosse asymetrique a ~110 keV (sigma_gauche=55 keV, sigma_droite=50 keV) + queue Compton exponentielle (0.45*exp(-E/240) + 0.04*exp(-E/700)) + plancher de bruit. Ce modele remplace l'ancien continuum exponentiel qui ne reproduisait pas la forme reelle du spectre CsI(Tl).
- **Pics environnementaux** : K-40 (1460 keV), Pb-214 (295, 352 keV), Bi-214 (609, 1120, 1764 keV), Ac-228 (911 keV), Pb-212 (239 keV), Tl-208 (583, 2614 keV), avec activites aleatoires realistes
- **Entrainement hybride** : Si le fichier `background_24h.npy` est disponible, 70% du background est issu de la mesure reelle (mélange 70% mesuré / 30% synthétique) et 30% du modele synthetique, avec variation stochastique des pics par-dessus. Ceci ameliore la robustesse du modele face aux variations locales du background.
### Spectres synthetiques
@ -89,8 +127,8 @@ Les donnees d'entrainement simulent la physique complete :
1. **Pics photoelectriques** : Gaussiennes avec FWHM dependant de l'energie (8.4% a 662 keV pour le CsI(Tl))
2. **Continuum Compton** : distribution de Klein-Nishina simplifiee sous chaque pic
3. **Bruit Poissonnien** : echantillonnage Poisson(N) pour chaque canal, simulant les fluctuations de comptage reelles
4. **Background environnemental** : continuum exponentiel + pics de K-40, radon, thorium avec activites aleatoires
5. **Efficacite du detecteur** : modele phenomenologique qui decroit avec l'energie (absorption basse energie + penetration haute energie)
4. **Background environnemental** : Continuum CsI(Tl) realiste + pics de K-40, radon, thorium avec activites aleatoires
5. **Efficacite du detecteur** : modele phenomenologique qui decroit avec l'energie
6. **Durees de 12-24h** : suffisamment longues pour que le rapport signal/bruit soit comparable aux mesures reelles
### Soustraction du background a l'inference
@ -105,8 +143,8 @@ normalized = net_rate / net_rate.max() # normalisation pour le mod
```
Cette approche hybride est optimale :
- Le modele apprend a ignorer les pics du background (K-40, radon, thorium) pendant l'entrainement
- La soustraction reelle elimine les variations locales du background (emplacement, altitude, materiaux)
- Le modele apprend a ignorer les pics du background pendant l'entrainement
- La soustraction reelle elimine les variations locales du background
- Resultat : meilleure sensibilite et moins de faux positifs
Le conteneur `train` execute deux phases :
@ -134,6 +172,20 @@ Le rapport contient :
- CPS moyen
- Isotopes detectes avec probabilite et activite estimee (Bq)
## Dashboard web
Le conteneur `web` expose un dashboard sur le port 8080 avec :
- **Onglet Spectre** : Spectre cumule en temps reel (lineaire ou log), soustraction du background, lignes d'energie des isotopes detectes, overlay du background de reference
- **Onglet Background** : Spectre du bruit de fond (live et 24h), modele theorique CsI(Tl), pics detectes, statistiques (duree, CPS, comptages)
- **Onglet CPS** : Evolution du comptage par seconde dans le temps, de 1h a 30 jours
- **Onglet Historique** : Liste des rapports quotidiens avec isotopes detectes
### Points techniques du dashboard
- Le canal 1024 (bin de debordement) est exclu de l'affichage — seuls les 1023 premiers canaux sont utilises (20-3036 keV)
- Le lissage du spectre (Gaussienne sigma=8 canaux) utilise une normalisation locale aux bords pour eviter les artefacts
## Capture du bruit de fond
Avant la detection, capturer le background pendant 24h sans source radioactive a proximite :
@ -155,30 +207,54 @@ cat data/background_snapshot.json
```
radiacode_103/
├── docker-compose.yml # Orchestration des conteneurs
├── CLAUDE.md # Guide pour Claude Code
├── TUTORIEL.md # Tutoriel detaille
├── TOTO.md # Suivi des taches
├── README.md
├── train/
│ ├── Dockerfile # PyTorch 2.7.0 + CUDA 12.8 (Blackwell)
│ ├── requirements.txt
│ ├── entrypoint.sh # Generation + entrainement
── vega_ml/ # Code VegaModel (copie d'Open-RadiaCode-Android)
── requirements.txt
│ └── vega_ml/ # Code VegaModel
│ ├── synthetic_spectra/ # Generateur de spectres synthetiques
│ │ ├── config.py # Configurations detecteur (Radiacode 101-110)
│ │ ├── generator.py # Generateur principal (SpectrumConfig)
│ │ ├── physics/
│ │ │ └── spectrum_physics.py # Physique + background realiste CsI(Tl)
│ │ └── ground_truth/ # Base de donnees 82 isotopes
│ ├── training/vega/ # Modele, dataset, trainer
│ └── inference/
│ └── inference/ # Inference
├── detect/
│ ├── Dockerfile # Python 3.11-slim + radiacode + torch CPU
│ ├── requirements.txt
│ ├── radiacode_monitor.py # Moniteur principal
│ └── capture_background.py # Capture du bruit de fond 24h
│ ├── radiacode_monitor.py # Moniteur principal
│ └── capture_background.py # Capture du bruit de fond 24h
├── web/
│ ├── Dockerfile # Python 3.11-slim + FastAPI
│ ├── requirements.txt
│ ├── app/
│ │ ├── main.py # FastAPI app + routes
│ │ ├── config.py # Config (canaux, calibration energetique)
│ │ ├── routers/
│ │ │ ├── status.py # /api/status
│ │ │ ├── spectrum.py # /api/spectrum/current, /api/spectrum/difference
│ │ │ ├── background.py # /api/background/*, background theorique
│ │ │ ├── cps.py # /api/cps/timeline
│ │ │ └── history.py # /api/history, /api/history/{date}
│ │ └── theoretical_bg.py # Modele theorique CsI(Tl) pour le dashboard
│ └── static/
│ ├── index.html # Dashboard SPA
│ ├── css/style.css
│ └── js/ # app.js, spectrum.js, background.js, cps.js, history.js
├── data/
│ ├── synthetic/spectra/ # 50 000 spectres synthetiques (~4.2 Go)
│ ├── synthetic/spectra/ # 50 000 spectres synthetiques (~4.2 Go)
│ └── background_snapshot.json
├── models/
│ ├── vega_best.pt # Meilleur modele (395 Mo)
│ ├── vega_final.pt # Modele final
│ ├── vega_history.json # Metriques d'entrainement
│ └── vega_isotope_index.txt # 82 isotopes
└── logs/ # Rapports quotidiens JSON
│ ├── vega_best.pt # Meilleur modele (395 Mo)
│ ├── vega_final.pt # Modele final
│ ├── vega_history.json # Metriques d'entrainement
│ └── vega_isotope_index.txt # 82 isotopes
└── logs/ # Rapports quotidiens JSON
```
## Materiel