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:
109
TUTORIEL.md
109
TUTORIEL.md
@ -80,29 +80,40 @@ Les spectres synthetiques simulent des acquisitions de 12 a 24 heures (43200-864
|
||||
- **Pics photoelectriques** : Gaussiennes dont la largeur (FWHM) depend de l'energie. Pour le CsI(Tl) du Radiacode 103, FWHM = 8.4% a 662 keV, avec la relation FWHM(E) = FWHM_662 * sqrt(E/662).
|
||||
- **Continuum Compton** : Distribution de Klein-Nishina simplifiee sous chaque pic, simulant la diffusion des photons gamma.
|
||||
- **Bruit Poissonnien** : Chaque canal est echantillonne depuis une loi Poisson(lambda), ce qui reproduit exactement les fluctuations statistiques reelles.
|
||||
- **Background environnemental** : Continuum exponentiel + pics de 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 des activites aleatoires realistes.
|
||||
- **Background environnemental** : Continuum CsI(Tl) realiste (bosse asymetrique a ~110 keV + queue Compton exponentielle) + pics de 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 des activites aleatoires realistes.
|
||||
- **Efficacite du detecteur** : Modele phenomenologique tenant compte de l'absorption basse energie et de la penetration haute energie du scintillateur CsI(Tl) de 1 cm3.
|
||||
|
||||
**Entrainement hybride (optionnel mais recommande) :**
|
||||
|
||||
Si vous avez capture un fichier `background_24h.npy`, le generateur peut l'utiliser pour rendre les spectres synthetiques plus realistes. Le background mesure est melange a 70% avec le modele synthetique (30%), et les pics isotopiques sont ajoutes avec variation aleatoire par-dessus.
|
||||
|
||||
```bash
|
||||
# Avec background mesure (recommande si disponible)
|
||||
docker compose run --rm train
|
||||
# Le fichier /data/background_24h.npy est automatiquement utilise
|
||||
# grace a MEASURED_BACKGROUND_PATH dans docker-compose.yml
|
||||
```
|
||||
|
||||
### Phase 2 : Entrainement du VegaModel (~35 min sur RTX 5060 Ti)
|
||||
|
||||
Le modele VegaModel est un CNN-FCNN multi-tache :
|
||||
|
||||
```
|
||||
Entree : spectre 1D (1023 canaux, 20-3000 keV)
|
||||
│
|
||||
├── Bloc CNN 1 : Conv1d(1, 64, 7) → BN → ReLU → MaxPool
|
||||
├── Bloc CNN 2 : Conv1d(64, 128, 5) → BN → ReLU → MaxPool
|
||||
├── Bloc CNN 3 : Conv1d(128, 256, 3) → BN → ReLU → MaxPool
|
||||
│
|
||||
├── Tete classification : FC(256→512→256→82) → Sigmoid
|
||||
│ 82 isotopes, probabilite de presence [0, 1]
|
||||
│
|
||||
└── Tete regression : FC(256→512→256→82)
|
||||
|
|
||||
|-- Bloc CNN 1 : Conv1d(1, 64, 7) -> BN -> LeakyReLU -> MaxPool
|
||||
|-- Bloc CNN 2 : Conv1d(64, 128, 5) -> BN -> LeakyReLU -> MaxPool
|
||||
|-- Bloc CNN 3 : Conv1d(128, 256, 3) -> BN -> LeakyReLU -> MaxPool
|
||||
|
|
||||
|-- Tete classification : FC(256->512->256->82) -> Sigmoid
|
||||
| 82 isotopes, probabilite de presence [0, 1]
|
||||
|
|
||||
+-- Tete regression : FC(256->512->256->82)
|
||||
Activite estimee en Bq pour chaque isotope
|
||||
```
|
||||
|
||||
- **34 493 156 parametres** au total
|
||||
- **Fonction de perte** : BCE (classification) + MSE ponderee (regression sur isotopes presents uniquement)
|
||||
- **Fonction de perte** : BCE (classification) + Huber ponderee (regression sur isotopes presents uniquement)
|
||||
- **Mixed precision (AMP)** : Acceleration sur GPU via float16
|
||||
- **Early stopping** : Patience de 10 epochs sans amelioration
|
||||
|
||||
@ -196,61 +207,55 @@ Le fichier `data/background_24h.npy` est genere avec :
|
||||
|
||||
---
|
||||
|
||||
## 5. Lancer la detection continue
|
||||
## 5. Lancer la detection continue + dashboard
|
||||
|
||||
```bash
|
||||
docker compose up detect
|
||||
docker compose up detect web
|
||||
```
|
||||
|
||||
Le dashboard est accessible sur `http://localhost:8080` avec quatre onglets :
|
||||
- **Spectre** : Spectre cumule en temps reel, soustraction du background, lignes d'energie des isotopes detectes
|
||||
- **Background** : Spectre du bruit de fond (live et 24h), modele theorique CsI(Tl), pics detectes
|
||||
- **CPS** : Evolution du comptage par seconde dans le temps (1h a 30 jours)
|
||||
- **Historique** : Liste des rapports quotidiens avec isotopes detectes
|
||||
|
||||
### Comment ca marche
|
||||
|
||||
Toutes les 60 secondes, le moniteur :
|
||||
|
||||
```
|
||||
┌──────────────────────────────────────────────────────────────┐
|
||||
│ 1. Echantillonnage │
|
||||
│ Radiacode.spectrum() → 1024 canaux + duree │
|
||||
│ cumulated_counts += counts │
|
||||
│ cumulated_live_time += duration.total_seconds() │
|
||||
│ Radiacode.spectrum_reset() │
|
||||
│ │
|
||||
│ 2. A 00h00 chaque jour : Rapport │
|
||||
│ Si live_time > 1h : │
|
||||
│ rate = cumulated_counts / cumulated_live_time │
|
||||
│ bg_rate = bg_counts / bg_live_time │
|
||||
│ net_rate = clip(rate - bg_rate, 0, None) │
|
||||
│ normalized = net_rate / net_rate.max() │
|
||||
│ logits, activities = model(normalized) │
|
||||
│ probs = sigmoid(logits) │
|
||||
│ Pour chaque isotope avec prob > 0.5 : │
|
||||
│ rapport[name, prob%, activite_bq] │
|
||||
│ Sauvegarder dans logs/report_YYYY-MM-DD.json │
|
||||
│ Reset cumulateurs │
|
||||
│ │
|
||||
│ 3. Si detecteur debranche : │
|
||||
│ Attendre 60s, retenter la connexion │
|
||||
│ Les donnees cumulees sont conservees │
|
||||
└──────────────────────────────────────────────────────────────┘
|
||||
1. Echantillonnage
|
||||
Radiacode.spectrum() -> 1024 canaux + duree
|
||||
cumulated_counts += counts
|
||||
cumulated_live_time += duration.total_seconds()
|
||||
Radiacode.spectrum_reset()
|
||||
|
||||
2. A 00h00 chaque jour : Rapport
|
||||
Si live_time > 1h :
|
||||
rate = cumulated_counts / cumulated_live_time
|
||||
bg_rate = bg_counts / bg_live_time
|
||||
net_rate = clip(rate - bg_rate, 0, None)
|
||||
normalized = net_rate / net_rate.max()
|
||||
logits, activities = model(normalized)
|
||||
probs = sigmoid(logits)
|
||||
Pour chaque isotope avec prob > 0.5 :
|
||||
rapport[name, prob%, activite_bq]
|
||||
Sauvegarder dans logs/report_YYYY-MM-DD.json
|
||||
Reset cumulateurs
|
||||
|
||||
3. Si detecteur debranche :
|
||||
Attendre 60s, retenter la connexion
|
||||
Les donnees cumulees sont conservees
|
||||
```
|
||||
|
||||
### Pourquoi soustraire le background ?
|
||||
|
||||
Le modele est entraite avec du background synthetique, mais le background reel varie selon l'emplacement. La soustraction reelle ameliore la detection :
|
||||
Le modele est entraite avec du background synthetique realiste (continuum CsI(Tl) + pics environnementaux), mais le background reel varie selon l'emplacement. La soustraction reelle ameliore la detection :
|
||||
|
||||
- **Sans soustraction** : Le modele voit K-40 a 1460 keV et peut le signaler comme isotope detecte, meme si c'est juste du background
|
||||
- **Avec soustraction** : Le pic de K-40 du background est elimine, seul un signal supplementaire est analyse
|
||||
- **Resultat** : Moins de faux positifs, meilleure sensibilite pour les isotopes faibles
|
||||
|
||||
### Debranchement et rebranchement
|
||||
|
||||
Le moniteur gere les deconnexions USB proprement :
|
||||
- Si le Radiacode est debranche, `try_connect()` echoue et retourne `None`
|
||||
- Le moniteur attend 60 secondes et retente
|
||||
- Les compteurs cumules ne sont pas reinitialises
|
||||
- Quand le detecteur est rebranche, l'accumulation reprend
|
||||
|
||||
Cela permet de prendre le detecteur avec soi pendant la journee sans perdre les donnees de la nuit.
|
||||
|
||||
---
|
||||
|
||||
## 6. Interpreter les rapports
|
||||
@ -393,6 +398,7 @@ L'inference CPU sur Pi 4 prend environ 0.5-1 seconde par spectre, ce qui est suf
|
||||
| `MAX_DURATION` | `86400` | Duree max des spectres (24h en secondes) |
|
||||
| `NVIDIA_VISIBLE_DEVICES` | `1` | GPU a utiliser (0 ou 1) |
|
||||
| `CUDA_VISIBLE_DEVICES` | `1` | GPU visible par CUDA |
|
||||
| `MEASURED_BACKGROUND_PATH` | `/data/background_24h.npy` | Background mesure pour entrainement hybride |
|
||||
|
||||
### Detection (`docker-compose.yml` - service `detect`)
|
||||
|
||||
@ -407,6 +413,13 @@ L'inference CPU sur Pi 4 prend environ 0.5-1 seconde par spectre, ce qui est suf
|
||||
| `REPORT_HOUR` | `0` | Heure du rapport quotidien |
|
||||
| `MIN_LIVE_TIME` | `3600` | Live time min pour rapport (s) |
|
||||
|
||||
### Dashboard (`docker-compose.yml` - service `web`)
|
||||
|
||||
| Variable | Defaut | Description |
|
||||
|----------|--------|-------------|
|
||||
| `ENERGY_CALIBRATION_OFFSET` | `0.33` | Calibration energetique offset (keV) |
|
||||
| `ENERGY_CALIBRATION_SLOPE` | `2.97` | Calibration energetique pente (keV/canal) |
|
||||
|
||||
### Capture de background
|
||||
|
||||
| Variable | Defaut | Description |
|
||||
|
||||
Reference in New Issue
Block a user