Przeglądaj źródła

feat: expose refinement window stats

master
Jan Svabenik 9 godzin temu
rodzic
commit
45b019d913
4 zmienionych plików z 63 dodań i 9 usunięć
  1. +6
    -1
      cmd/sdrd/dsp_loop.go
  2. +11
    -8
      cmd/sdrd/http_handlers.go
  3. +9
    -0
      cmd/sdrd/types.go
  4. +37
    -0
      cmd/sdrd/window_stats.go

+ 6
- 1
cmd/sdrd/dsp_loop.go Wyświetl plik

@@ -106,8 +106,10 @@ func runDSP(ctx context.Context, srcMgr *sourceManager, cfg config.Config, det *
}
var debugInfo *SpectrumDebug
plan := state.refinementInput.Plan
windowStats := buildWindowStats(state.refinementInput.Windows)
hasPlan := plan.TotalCandidates > 0 || plan.Budget > 0 || plan.DroppedBySNR > 0 || plan.DroppedByBudget > 0
if len(thresholds) > 0 || len(displaySignals) > 0 || noiseFloor != 0 || hasPlan {
hasWindows := windowStats != nil && windowStats.Count > 0
if len(thresholds) > 0 || len(displaySignals) > 0 || noiseFloor != 0 || hasPlan || hasWindows {
scoreDebug := make([]map[string]any, 0, len(displaySignals))
for _, s := range displaySignals {
if s.Class == nil || len(s.Class.Scores) == 0 {
@@ -130,6 +132,9 @@ func runDSP(ctx context.Context, srcMgr *sourceManager, cfg config.Config, det *
if hasPlan {
debugInfo.RefinementPlan = &plan
}
if hasWindows {
debugInfo.Windows = windowStats
}
}
h.broadcast(SpectrumFrame{Timestamp: art.now.UnixMilli(), CenterHz: rt.cfg.CenterHz, SampleHz: rt.cfg.SampleRate, FFTSize: rt.cfg.FFTSize, Spectrum: art.spectrum, Signals: displaySignals, Debug: debugInfo})
}


+ 11
- 8
cmd/sdrd/http_handlers.go Wyświetl plik

@@ -15,8 +15,8 @@ import (
"sdr-wideband-suite/internal/config"
"sdr-wideband-suite/internal/detector"
"sdr-wideband-suite/internal/events"
"sdr-wideband-suite/internal/pipeline"
fftutil "sdr-wideband-suite/internal/fft"
"sdr-wideband-suite/internal/pipeline"
"sdr-wideband-suite/internal/recorder"
"sdr-wideband-suite/internal/runtime"
)
@@ -138,13 +138,16 @@ func registerAPIHandlers(mux *http.ServeMux, cfgPath string, cfgManager *runtime
cfg := cfgManager.Snapshot()
policy := pipeline.PolicyFromConfig(cfg)
recommend := map[string]any{
"mode": policy.Mode,
"intent": policy.Intent,
"monitor_span_hz": policy.MonitorSpanHz,
"signal_priorities": policy.SignalPriorities,
"auto_record_classes": policy.AutoRecordClasses,
"auto_decode_classes": policy.AutoDecodeClasses,
"refinement_jobs": policy.MaxRefinementJobs,
"mode": policy.Mode,
"intent": policy.Intent,
"monitor_span_hz": policy.MonitorSpanHz,
"signal_priorities": policy.SignalPriorities,
"auto_record_classes": policy.AutoRecordClasses,
"auto_decode_classes": policy.AutoDecodeClasses,
"refinement_jobs": policy.MaxRefinementJobs,
"refinement_auto_span": policy.RefinementAutoSpan,
"refinement_min_span_hz": policy.RefinementMinSpanHz,
"refinement_max_span_hz": policy.RefinementMaxSpanHz,
}
_ = json.NewEncoder(w).Encode(recommend)
})


+ 9
- 0
cmd/sdrd/types.go Wyświetl plik

@@ -18,6 +18,15 @@ type SpectrumDebug struct {
NoiseFloor float64 `json:"noise_floor,omitempty"`
Scores []map[string]any `json:"scores,omitempty"`
RefinementPlan *pipeline.RefinementPlan `json:"refinement_plan,omitempty"`
Windows *RefinementWindowStats `json:"refinement_windows,omitempty"`
}

type RefinementWindowStats struct {
Count int `json:"count"`
MinSpan float64 `json:"min_span_hz"`
MaxSpan float64 `json:"max_span_hz"`
AvgSpan float64 `json:"avg_span_hz"`
Sources map[string]int `json:"sources,omitempty"`
}

type SpectrumFrame struct {


+ 37
- 0
cmd/sdrd/window_stats.go Wyświetl plik

@@ -0,0 +1,37 @@
package main

import "sdr-wideband-suite/internal/pipeline"

func buildWindowStats(windows []pipeline.RefinementWindow) *RefinementWindowStats {
if len(windows) == 0 {
return nil
}
stats := &RefinementWindowStats{Sources: map[string]int{}}
minSpan := 0.0
maxSpan := 0.0
sum := 0.0
for i, w := range windows {
span := w.SpanHz
if span <= 0 {
continue
}
if i == 0 || span < minSpan {
minSpan = span
}
if i == 0 || span > maxSpan {
maxSpan = span
}
sum += span
stats.Count++
if w.Source != "" {
stats.Sources[w.Source]++
}
}
if stats.Count == 0 {
return nil
}
stats.MinSpan = minSpan
stats.MaxSpan = maxSpan
stats.AvgSpan = sum / float64(stats.Count)
return stats
}

Ładowanie…
Anuluj
Zapisz