Pipeline complet Radiacode 103 - identification automatique d'isotopes
- VegaModel CNN-FCNN 34.5M params, 82 isotopes, val acc 99.89% - Generation 50k spectres synthetiques 1D (12-24h durees) - Entrainement 100 epochs sur RTX 5060 Ti (CUDA 12.8, Blackwell) - Detection continue avec soustraction du background - Capture background 24h avec gestion deconnexion - Docker Compose : conteneur train (GPU) + detect (CPU/USB) - Modele entraite inclus (vega_best.pt, 395 Mo) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
88
detect/capture_background.py
Normal file
88
detect/capture_background.py
Normal file
@ -0,0 +1,88 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Capture le bruit de fond du détecteur sur 24h (sans source).
|
||||
Gère le débranchement/rebranchement du détecteur.
|
||||
À lancer séparément avant le moniteur :
|
||||
docker-compose run --rm detect python capture_background.py
|
||||
"""
|
||||
import numpy as np
|
||||
import time
|
||||
import json
|
||||
import os
|
||||
|
||||
SAMPLE_INTERVAL = int(os.environ.get("SAMPLE_INTERVAL", "60"))
|
||||
TARGET_DURATION = int(os.environ.get("TARGET_DURATION", str(86400))) # 24h
|
||||
OUTPUT_PATH = os.environ.get("BACKGROUND_PATH", "/data/background_24h.npy")
|
||||
SNAPSHOT_PATH = os.environ.get("SNAPSHOT_PATH", "/data/background_snapshot.json")
|
||||
|
||||
BG_COUNTS = np.zeros(1024, dtype=np.float64)
|
||||
BG_LIVE_TIME = 0.0
|
||||
device = None
|
||||
|
||||
def save_snapshot():
|
||||
"""Save a human-readable snapshot of current background."""
|
||||
cps = BG_COUNTS.sum() / BG_LIVE_TIME if BG_LIVE_TIME > 0 else 0
|
||||
# Approximate energy calibration for RC-103: E ≈ 0.33 + 2.97*ch
|
||||
peaks = []
|
||||
max_c = BG_COUNTS.max()
|
||||
if max_c > 0:
|
||||
for i, c in enumerate(BG_COUNTS):
|
||||
if c > max_c * 0.03:
|
||||
energy = 0.33 + 2.97 * i
|
||||
peaks.append({"channel": i, "energy_kev": round(energy, 1), "counts": round(float(c), 1)})
|
||||
|
||||
snapshot = {
|
||||
"elapsed_hours": round((time.time() - start) / 3600, 2),
|
||||
"live_time_s": round(BG_LIVE_TIME, 1),
|
||||
"total_counts": round(float(BG_COUNTS.sum()), 0),
|
||||
"cps": round(cps, 2),
|
||||
"top_peaks": sorted(peaks, key=lambda x: -x["counts"])[:15],
|
||||
"spectrum": [round(float(c), 1) for c in BG_COUNTS],
|
||||
}
|
||||
with open(SNAPSHOT_PATH, "w") as f:
|
||||
json.dump(snapshot, f, indent=2)
|
||||
|
||||
print(f"Capture du bruit de fond pendant {TARGET_DURATION/3600:.0f}h...")
|
||||
print("Assurez-vous qu'aucune source radioactive n'est a proximite du detecteur.")
|
||||
print()
|
||||
|
||||
start = time.time()
|
||||
while (time.time() - start) < TARGET_DURATION:
|
||||
time.sleep(SAMPLE_INTERVAL)
|
||||
try:
|
||||
if device is None:
|
||||
from radiacode import RadiaCode
|
||||
|
||||
device = RadiaCode()
|
||||
device.spectrum_reset()
|
||||
print("Radiacode connecte.")
|
||||
|
||||
spectrum = device.spectrum()
|
||||
BG_COUNTS += np.array(spectrum.counts, dtype=np.float64)
|
||||
BG_LIVE_TIME += spectrum.duration.total_seconds()
|
||||
device.spectrum_reset()
|
||||
elapsed = time.time() - start
|
||||
cps = BG_COUNTS.sum() / BG_LIVE_TIME if BG_LIVE_TIME > 0 else 0
|
||||
print(
|
||||
f"Background : {elapsed/3600:.1f}h / {TARGET_DURATION/3600:.1f}h "
|
||||
f"({BG_LIVE_TIME:.0f}s live, {BG_COUNTS.sum():.0f} coups, {cps:.1f} CPS)",
|
||||
flush=True,
|
||||
)
|
||||
save_snapshot()
|
||||
except Exception as e:
|
||||
print(f"\nErreur : {e}, reconnexion...")
|
||||
device = None
|
||||
|
||||
os.makedirs(os.path.dirname(OUTPUT_PATH) if os.path.dirname(OUTPUT_PATH) else ".", exist_ok=True)
|
||||
np.save(
|
||||
OUTPUT_PATH,
|
||||
{
|
||||
"counts": BG_COUNTS,
|
||||
"duration": BG_LIVE_TIME,
|
||||
"timestamp": time.time(),
|
||||
},
|
||||
)
|
||||
print(f"\n\nBackground sauvegarde : {OUTPUT_PATH}")
|
||||
print(f" Duree live : {BG_LIVE_TIME/3600:.1f}h")
|
||||
print(f" Total coups : {BG_COUNTS.sum():.0f}")
|
||||
print(f" CPS moyen : {BG_COUNTS.sum()/BG_LIVE_TIME:.1f}")
|
||||
Reference in New Issue
Block a user