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:
78
CLAUDE.md
Normal file
78
CLAUDE.md
Normal file
@ -0,0 +1,78 @@
|
||||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## Project Overview
|
||||
|
||||
Radiacode 103 is a gamma-ray spectrometer isotope identification pipeline. It captures spectra from a Radiacode 103 USB detector, subtracts background radiation, and identifies isotopes using a CNN-FCNN multi-task PyTorch model (VegaModel, 34.5M params, 82 isotopes). The project runs as Docker containers orchestrated by docker-compose.
|
||||
|
||||
## Architecture
|
||||
|
||||
Three Docker containers, each with its own Dockerfile:
|
||||
|
||||
- **train/** — Generates 50k synthetic spectra and trains VegaModel on GPU. Entrypoint runs generation then training sequentially. Code lives in `train/vega_ml/` (synthetic_spectra, training/vega).
|
||||
- **detect/** — Production monitor. Connects to Radiacode 103 via USB, samples every 60s, accumulates spectrum, subtracts background, runs inference, writes JSON state and daily reports. Two scripts: `radiacode_monitor.py` (main loop) and `capture_background.py` (24h background capture).
|
||||
- **web/** — FastAPI dashboard on port 8080. Serves a single-page HTML/JS frontend with tabs for spectrum, background, CPS timeline, and history. Reads monitor state from JSON files written by the detect container.
|
||||
|
||||
Data flow: `detect` writes `monitor_state.json` + `cps_log.jsonl` + daily reports to `/data/` and `/logs/` → `web` reads them (read-only volume mounts). The `train` container reads/writes `/data/synthetic/` and `/models/`.
|
||||
|
||||
### Web API Routes
|
||||
|
||||
- `/api/status` — monitor status (connected, CPS, staleness)
|
||||
- `/api/spectrum/current` — accumulated spectrum (1023 channels, overflow channel excluded)
|
||||
- `/api/spectrum/difference` — background-subtracted spectrum
|
||||
- `/api/background`, `/api/background/spectrum`, `/api/background/reference`, `/api/background/theoretical` — background data (live, 24h reference, theoretical CsI(Tl) model)
|
||||
- `/api/cps/timeline` — CPS time series
|
||||
- `/api/history`, `/api/history/{date}` — daily detection reports
|
||||
|
||||
### Key Physics Constants
|
||||
|
||||
Energy calibration: `E(keV) = 0.33 + 2.97 * channel_index` (env vars `ENERGY_CALIBRATION_OFFSET` and `ENERGY_CALIBRATION_SLOPE`). The detector has 1024 raw channels but channel 1023 is an overflow bin — only the first 1023 channels (20–3036 keV) are used for display and inference. CsI(Tl) crystal with 8.4% FWHM at 662 keV.
|
||||
|
||||
## Commands
|
||||
|
||||
```bash
|
||||
# Build all images
|
||||
docker compose build
|
||||
|
||||
# Train model (GPU required, ~45 min on RTX 5060 Ti)
|
||||
docker compose run --rm train
|
||||
|
||||
# Capture 24h background (leave running, no radioactive source nearby)
|
||||
docker compose run --rm -d --name radiacode-bg detect python capture_background.py
|
||||
|
||||
# Start continuous detection monitor
|
||||
docker compose up detect
|
||||
|
||||
# Start web dashboard
|
||||
docker compose up web
|
||||
|
||||
# Run both detect and web
|
||||
docker compose up detect web
|
||||
```
|
||||
|
||||
No test suite exists in this project. No linter is configured.
|
||||
|
||||
## VegaModel
|
||||
|
||||
Defined in `train/vega_ml/training/vega/model.py`. Input: 1D spectrum (1023 channels, normalized to max). Output: classification logits (82 isotopes, apply sigmoid for probabilities) + activity predictions (Bq, scaled by max_activity_bq=1000). Loss: `VegaLoss = BCE(logits) + 0.1 * Huber(activities * mask)` — regression only penalizes present isotopes.
|
||||
|
||||
The model checkpoint (`models/vega_best.pt`) stores `model_config` and `model_state_dict`. At inference, the detect container dynamically imports `VegaModel` and `IsotopeIndex` from the mounted `vega_ml` volume.
|
||||
|
||||
## Synthetic Background Model
|
||||
|
||||
The training background uses a realistic CsI(Tl) continuum shape (not a simple exponential):
|
||||
|
||||
- **Continuum**: Asymmetric hump at ~110 keV (sigma_left=55, sigma_right=50 keV) + Compton tail (`0.45*exp(-E/240) + 0.04*exp(-E/700)`) + noise floor. Calibrated against real Radiacode 103 measurements. Implemented in `spectrum_physics.py::generate_realistic_continuum()`.
|
||||
- **Isotope peaks**: 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) — with stochastic activity variation per sample.
|
||||
- **Hybrid training**: If `MEASURED_BACKGROUND_PATH` points to a valid `.npy` file, 70% measured + 30% synthetic continuum is used. This is controlled by `SpectrumConfig.measured_background_path` and the `--measured_background` CLI argument.
|
||||
|
||||
## Configuration
|
||||
|
||||
All config is via environment variables in `docker-compose.yml`. Key variables:
|
||||
- `MODEL_PATH`, `ISOTOPE_INDEX_PATH`, `BACKGROUND_PATH` — file paths (container-mounted volumes)
|
||||
- `VEGA_DEVICE` — `cpu` or `cuda`
|
||||
- `THRESHOLD` — detection probability threshold (default 0.5)
|
||||
- `SAMPLE_INTERVAL` — seconds between samples (default 60)
|
||||
- `ENERGY_CALIBRATION_OFFSET/SLOPE` — energy calibration constants
|
||||
- `MEASURED_BACKGROUND_PATH` — path to measured background `.npy` for hybrid training (default: `/data/background_24h.npy`)
|
||||
Reference in New Issue
Block a user