Wideband autonomous SDR analysis engine forked from sdr-visual-suite
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

145 行
3.6KB

  1. package pipeline
  2. import "sdr-wideband-suite/internal/config"
  3. func NormalizeMonitorWindows(goals config.PipelineGoalConfig, centerHz float64) []MonitorWindow {
  4. if len(goals.MonitorWindows) > 0 {
  5. windows := make([]MonitorWindow, 0, len(goals.MonitorWindows))
  6. for _, raw := range goals.MonitorWindows {
  7. if win, ok := normalizeGoalWindow(raw, centerHz); ok {
  8. windows = append(windows, win)
  9. }
  10. }
  11. if len(windows) > 0 {
  12. return windows
  13. }
  14. }
  15. if goals.MonitorStartHz > 0 && goals.MonitorEndHz > goals.MonitorStartHz {
  16. start := goals.MonitorStartHz
  17. end := goals.MonitorEndHz
  18. span := end - start
  19. return []MonitorWindow{{
  20. Label: "primary",
  21. StartHz: start,
  22. EndHz: end,
  23. CenterHz: (start + end) / 2,
  24. SpanHz: span,
  25. Source: "goals:bounds",
  26. }}
  27. }
  28. if goals.MonitorSpanHz > 0 && centerHz != 0 {
  29. half := goals.MonitorSpanHz / 2
  30. start := centerHz - half
  31. end := centerHz + half
  32. return []MonitorWindow{{
  33. Label: "primary",
  34. StartHz: start,
  35. EndHz: end,
  36. CenterHz: centerHz,
  37. SpanHz: goals.MonitorSpanHz,
  38. Source: "goals:span",
  39. }}
  40. }
  41. return nil
  42. }
  43. func MonitorWindowBounds(windows []MonitorWindow) (float64, float64, bool) {
  44. minStart := 0.0
  45. maxEnd := 0.0
  46. ok := false
  47. for _, w := range windows {
  48. if w.StartHz <= 0 || w.EndHz <= 0 || w.EndHz <= w.StartHz {
  49. continue
  50. }
  51. if !ok || w.StartHz < minStart {
  52. minStart = w.StartHz
  53. }
  54. if !ok || w.EndHz > maxEnd {
  55. maxEnd = w.EndHz
  56. }
  57. ok = true
  58. }
  59. return minStart, maxEnd, ok
  60. }
  61. func normalizeGoalWindow(raw config.MonitorWindow, fallbackCenter float64) (MonitorWindow, bool) {
  62. if raw.StartHz > 0 && raw.EndHz > raw.StartHz {
  63. span := raw.EndHz - raw.StartHz
  64. return MonitorWindow{
  65. Label: raw.Label,
  66. StartHz: raw.StartHz,
  67. EndHz: raw.EndHz,
  68. CenterHz: (raw.StartHz + raw.EndHz) / 2,
  69. SpanHz: span,
  70. Source: "goals:window:start_end",
  71. }, true
  72. }
  73. center := raw.CenterHz
  74. if center == 0 {
  75. center = fallbackCenter
  76. }
  77. if center != 0 && raw.SpanHz > 0 {
  78. half := raw.SpanHz / 2
  79. source := "goals:window:center_span"
  80. if raw.CenterHz == 0 {
  81. source = "goals:window:span_default"
  82. }
  83. return MonitorWindow{
  84. Label: raw.Label,
  85. StartHz: center - half,
  86. EndHz: center + half,
  87. CenterHz: center,
  88. SpanHz: raw.SpanHz,
  89. Source: source,
  90. }, true
  91. }
  92. return MonitorWindow{}, false
  93. }
  94. func monitorBounds(policy Policy) (float64, float64, bool) {
  95. if len(policy.MonitorWindows) > 0 {
  96. return MonitorWindowBounds(policy.MonitorWindows)
  97. }
  98. start := policy.MonitorStartHz
  99. end := policy.MonitorEndHz
  100. if start != 0 && end != 0 && end > start {
  101. return start, end, true
  102. }
  103. if policy.MonitorSpanHz > 0 && policy.MonitorCenterHz != 0 {
  104. half := policy.MonitorSpanHz / 2
  105. return policy.MonitorCenterHz - half, policy.MonitorCenterHz + half, true
  106. }
  107. return 0, 0, false
  108. }
  109. func candidateInMonitor(policy Policy, candidate Candidate) bool {
  110. if len(policy.MonitorWindows) > 0 {
  111. left, right := candidateBounds(candidate)
  112. for _, win := range policy.MonitorWindows {
  113. if win.StartHz <= 0 || win.EndHz <= 0 || win.EndHz <= win.StartHz {
  114. continue
  115. }
  116. if right >= win.StartHz && left <= win.EndHz {
  117. return true
  118. }
  119. }
  120. return false
  121. }
  122. start, end, ok := monitorBounds(policy)
  123. if !ok {
  124. return true
  125. }
  126. left, right := candidateBounds(candidate)
  127. return right >= start && left <= end
  128. }
  129. func candidateBounds(candidate Candidate) (float64, float64) {
  130. left := candidate.CenterHz
  131. right := candidate.CenterHz
  132. if candidate.BandwidthHz > 0 {
  133. left = candidate.CenterHz - candidate.BandwidthHz/2
  134. right = candidate.CenterHz + candidate.BandwidthHz/2
  135. }
  136. return left, right
  137. }