Wideband autonomous SDR analysis engine forked from sdr-visual-suite
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

136 строки
3.4KB

  1. package main
  2. import (
  3. "sort"
  4. "sdr-wideband-suite/internal/pipeline"
  5. )
  6. type SurveillanceLevelSummary struct {
  7. Name string `json:"name"`
  8. Role string `json:"role,omitempty"`
  9. Truth string `json:"truth,omitempty"`
  10. SampleRate int `json:"sample_rate,omitempty"`
  11. FFTSize int `json:"fft_size,omitempty"`
  12. BinHz float64 `json:"bin_hz,omitempty"`
  13. Decimation int `json:"decimation,omitempty"`
  14. SpanHz float64 `json:"span_hz,omitempty"`
  15. CenterHz float64 `json:"center_hz,omitempty"`
  16. Source string `json:"source,omitempty"`
  17. SpectrumBins int `json:"spectrum_bins,omitempty"`
  18. }
  19. type CandidateEvidenceSummary struct {
  20. Level string `json:"level"`
  21. Provenance string `json:"provenance,omitempty"`
  22. Count int `json:"count"`
  23. }
  24. func buildSurveillanceLevelSummaries(set pipeline.SurveillanceLevelSet, spectra []pipeline.SurveillanceLevelSpectrum) map[string]SurveillanceLevelSummary {
  25. if set.Primary.Name == "" && len(set.Derived) == 0 && set.Presentation.Name == "" && len(set.All) == 0 {
  26. return nil
  27. }
  28. bins := map[string]int{}
  29. for _, spec := range spectra {
  30. if spec.Level.Name == "" || len(spec.Spectrum) == 0 {
  31. continue
  32. }
  33. bins[spec.Level.Name] = len(spec.Spectrum)
  34. }
  35. levels := set.All
  36. if len(levels) == 0 {
  37. if set.Primary.Name != "" {
  38. levels = append(levels, set.Primary)
  39. }
  40. if len(set.Derived) > 0 {
  41. levels = append(levels, set.Derived...)
  42. }
  43. if set.Presentation.Name != "" {
  44. levels = append(levels, set.Presentation)
  45. }
  46. }
  47. out := make(map[string]SurveillanceLevelSummary, len(levels))
  48. for _, level := range levels {
  49. name := level.Name
  50. if name == "" {
  51. continue
  52. }
  53. binHz := level.BinHz
  54. if binHz == 0 && level.SampleRate > 0 && level.FFTSize > 0 {
  55. binHz = float64(level.SampleRate) / float64(level.FFTSize)
  56. }
  57. out[name] = SurveillanceLevelSummary{
  58. Name: name,
  59. Role: level.Role,
  60. Truth: level.Truth,
  61. SampleRate: level.SampleRate,
  62. FFTSize: level.FFTSize,
  63. BinHz: binHz,
  64. Decimation: level.Decimation,
  65. SpanHz: level.SpanHz,
  66. CenterHz: level.CenterHz,
  67. Source: level.Source,
  68. SpectrumBins: bins[name],
  69. }
  70. }
  71. if len(out) == 0 {
  72. return nil
  73. }
  74. return out
  75. }
  76. func buildCandidateSourceSummary(candidates []pipeline.Candidate) map[string]int {
  77. if len(candidates) == 0 {
  78. return nil
  79. }
  80. out := map[string]int{}
  81. for _, cand := range candidates {
  82. if cand.Source == "" {
  83. continue
  84. }
  85. out[cand.Source]++
  86. }
  87. if len(out) == 0 {
  88. return nil
  89. }
  90. return out
  91. }
  92. func buildCandidateEvidenceSummary(candidates []pipeline.Candidate) []CandidateEvidenceSummary {
  93. if len(candidates) == 0 {
  94. return nil
  95. }
  96. type key struct {
  97. level string
  98. provenance string
  99. }
  100. counts := map[key]int{}
  101. for _, cand := range candidates {
  102. for _, ev := range cand.Evidence {
  103. name := ev.Level.Name
  104. if name == "" {
  105. name = "unknown"
  106. }
  107. k := key{level: name, provenance: ev.Provenance}
  108. counts[k]++
  109. }
  110. }
  111. if len(counts) == 0 {
  112. return nil
  113. }
  114. out := make([]CandidateEvidenceSummary, 0, len(counts))
  115. for k, v := range counts {
  116. out = append(out, CandidateEvidenceSummary{Level: k.level, Provenance: k.provenance, Count: v})
  117. }
  118. sort.Slice(out, func(i, j int) bool {
  119. if out[i].Count == out[j].Count {
  120. if out[i].Level == out[j].Level {
  121. return out[i].Provenance < out[j].Provenance
  122. }
  123. return out[i].Level < out[j].Level
  124. }
  125. return out[i].Count > out[j].Count
  126. })
  127. return out
  128. }