Wideband autonomous SDR analysis engine forked from sdr-visual-suite
Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.

190 wiersze
5.3KB

  1. package pipeline
  2. import "strings"
  3. type BudgetQueue struct {
  4. Max int `json:"max"`
  5. IntentBias float64 `json:"intent_bias,omitempty"`
  6. Preference float64 `json:"preference,omitempty"`
  7. EffectiveMax float64 `json:"effective_max,omitempty"`
  8. Source string `json:"source,omitempty"`
  9. }
  10. type BudgetPreference struct {
  11. Refinement float64 `json:"refinement"`
  12. Record float64 `json:"record"`
  13. Decode float64 `json:"decode"`
  14. Reasons []string `json:"reasons,omitempty"`
  15. }
  16. type BudgetModel struct {
  17. Refinement BudgetQueue `json:"refinement"`
  18. Record BudgetQueue `json:"record"`
  19. Decode BudgetQueue `json:"decode"`
  20. HoldMs int `json:"hold_ms"`
  21. Intent string `json:"intent,omitempty"`
  22. Profile string `json:"profile,omitempty"`
  23. Strategy string `json:"strategy,omitempty"`
  24. Preference BudgetPreference `json:"preference,omitempty"`
  25. }
  26. func BudgetModelFromPolicy(policy Policy) BudgetModel {
  27. recordBias, decodeBias := budgetIntentBias(policy.Intent)
  28. refBudget, refSource := refinementBudgetFromPolicy(policy)
  29. preference := BudgetPreferenceFromPolicy(policy)
  30. refEffective := effectiveBudget(refBudget, preference.Refinement)
  31. recordEffective := effectiveBudget(policy.MaxRecordingStreams, preference.Record)
  32. decodeEffective := effectiveBudget(policy.MaxDecodeJobs, preference.Decode)
  33. return BudgetModel{
  34. Refinement: BudgetQueue{
  35. Max: refBudget,
  36. Preference: preference.Refinement,
  37. EffectiveMax: refEffective,
  38. Source: refSource,
  39. },
  40. Record: BudgetQueue{
  41. Max: policy.MaxRecordingStreams,
  42. IntentBias: recordBias,
  43. Preference: preference.Record,
  44. EffectiveMax: recordEffective,
  45. Source: "resources.max_recording_streams",
  46. },
  47. Decode: BudgetQueue{
  48. Max: policy.MaxDecodeJobs,
  49. IntentBias: decodeBias,
  50. Preference: preference.Decode,
  51. EffectiveMax: decodeEffective,
  52. Source: "resources.max_decode_jobs",
  53. },
  54. HoldMs: policy.DecisionHoldMs,
  55. Intent: policy.Intent,
  56. Profile: policy.Profile,
  57. Strategy: policy.RefinementStrategy,
  58. Preference: preference,
  59. }
  60. }
  61. func refinementBudgetFromPolicy(policy Policy) (int, string) {
  62. budget := policy.MaxRefinementJobs
  63. source := "resources.max_refinement_jobs"
  64. if policy.RefinementMaxConcurrent > 0 && (budget <= 0 || policy.RefinementMaxConcurrent < budget) {
  65. budget = policy.RefinementMaxConcurrent
  66. source = "refinement.max_concurrent"
  67. }
  68. return budget, source
  69. }
  70. func budgetIntentBias(intent string) (float64, float64) {
  71. if intent == "" {
  72. return 0, 0
  73. }
  74. recordBias := 0.0
  75. decodeBias := 0.0
  76. intent = strings.ToLower(intent)
  77. if strings.Contains(intent, "archive") || strings.Contains(intent, "record") {
  78. recordBias += 1.5
  79. }
  80. if strings.Contains(intent, "triage") {
  81. recordBias += 0.5
  82. decodeBias += 0.5
  83. }
  84. if strings.Contains(intent, "decode") || strings.Contains(intent, "analysis") {
  85. decodeBias += 1.0
  86. }
  87. if strings.Contains(intent, "digital") {
  88. decodeBias += 0.5
  89. }
  90. return recordBias, decodeBias
  91. }
  92. func BudgetPreferenceFromPolicy(policy Policy) BudgetPreference {
  93. pref := BudgetPreference{Refinement: 1.0, Record: 1.0, Decode: 1.0}
  94. reasons := make([]string, 0, 6)
  95. addReason := func(tag string) {
  96. if tag == "" {
  97. return
  98. }
  99. for _, r := range reasons {
  100. if r == tag {
  101. return
  102. }
  103. }
  104. reasons = append(reasons, tag)
  105. }
  106. profile := strings.ToLower(strings.TrimSpace(policy.Profile))
  107. intent := strings.ToLower(strings.TrimSpace(policy.Intent))
  108. strategy := strings.ToLower(strings.TrimSpace(policy.RefinementStrategy))
  109. if strings.Contains(profile, "archive") {
  110. pref.Record += 0.6
  111. pref.Decode += 0.2
  112. pref.Refinement += 0.15
  113. addReason("profile:archive")
  114. }
  115. if strings.Contains(profile, "digital") {
  116. pref.Decode += 0.6
  117. pref.Record += 0.1
  118. pref.Refinement += 0.15
  119. addReason("profile:digital")
  120. }
  121. if strings.Contains(profile, "aggressive") {
  122. pref.Refinement += 0.35
  123. addReason("profile:aggressive")
  124. }
  125. if strings.Contains(intent, "archive") || strings.Contains(intent, "record") {
  126. pref.Record += 0.5
  127. addReason("intent:record")
  128. }
  129. if strings.Contains(intent, "decode") || strings.Contains(intent, "analysis") || strings.Contains(intent, "classif") {
  130. pref.Decode += 0.5
  131. addReason("intent:decode")
  132. }
  133. if strings.Contains(intent, "digital") || strings.Contains(intent, "hunt") {
  134. pref.Decode += 0.25
  135. addReason("intent:digital")
  136. }
  137. if strings.Contains(intent, "wideband") || strings.Contains(intent, "surveillance") {
  138. pref.Refinement += 0.25
  139. addReason("intent:wideband")
  140. }
  141. if strings.Contains(strategy, "archive") {
  142. pref.Record += 0.2
  143. pref.Refinement += 0.1
  144. addReason("strategy:archive")
  145. }
  146. if strings.Contains(strategy, "digital") {
  147. pref.Decode += 0.2
  148. addReason("strategy:digital")
  149. }
  150. if strings.Contains(strategy, "multi") {
  151. pref.Refinement += 0.2
  152. addReason("strategy:multi-resolution")
  153. }
  154. pref.Refinement = clampPreference(pref.Refinement)
  155. pref.Record = clampPreference(pref.Record)
  156. pref.Decode = clampPreference(pref.Decode)
  157. pref.Reasons = reasons
  158. return pref
  159. }
  160. func clampPreference(value float64) float64 {
  161. if value < 0.35 {
  162. return 0.35
  163. }
  164. return value
  165. }
  166. func effectiveBudget(max int, preference float64) float64 {
  167. if max <= 0 {
  168. return 0
  169. }
  170. if preference <= 0 {
  171. preference = 1.0
  172. }
  173. return float64(max) * preference
  174. }