Wideband autonomous SDR analysis engine forked from sdr-visual-suite
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

114 lines
2.4KB

  1. package pipeline
  2. import (
  3. "strings"
  4. )
  5. const (
  6. PriorityTierCritical = "critical"
  7. PriorityTierHigh = "high"
  8. PriorityTierMedium = "medium"
  9. PriorityTierLow = "low"
  10. PriorityTierBackground = "background"
  11. )
  12. const (
  13. AdmissionClassPlanned = "plan"
  14. AdmissionClassAdmit = "admit"
  15. AdmissionClassHold = "hold"
  16. AdmissionClassDefer = "defer"
  17. AdmissionClassDisplace = "displace"
  18. AdmissionClassDrop = "drop"
  19. )
  20. type PriorityAdmission struct {
  21. Tier string `json:"tier,omitempty"`
  22. Class string `json:"class,omitempty"`
  23. Score float64 `json:"score,omitempty"`
  24. Cutoff float64 `json:"cutoff,omitempty"`
  25. Basis string `json:"basis,omitempty"`
  26. Reason string `json:"reason,omitempty"`
  27. }
  28. func PriorityTierFromRange(score, min, max float64) string {
  29. if max <= min {
  30. return PriorityTierHigh
  31. }
  32. norm := (score - min) / (max - min)
  33. switch {
  34. case norm >= 0.85:
  35. return PriorityTierCritical
  36. case norm >= 0.65:
  37. return PriorityTierHigh
  38. case norm >= 0.45:
  39. return PriorityTierMedium
  40. case norm >= 0.25:
  41. return PriorityTierLow
  42. default:
  43. return PriorityTierBackground
  44. }
  45. }
  46. func priorityTierRank(tier string) int {
  47. switch tier {
  48. case PriorityTierCritical:
  49. return 4
  50. case PriorityTierHigh:
  51. return 3
  52. case PriorityTierMedium:
  53. return 2
  54. case PriorityTierLow:
  55. return 1
  56. default:
  57. return 0
  58. }
  59. }
  60. func admissionReason(base string, policy Policy, holdPolicy HoldPolicy, extras ...string) string {
  61. tags := uniqueReasonTags(policy, holdPolicy, extras...)
  62. if len(tags) == 0 {
  63. return base
  64. }
  65. return base + ":" + strings.Join(tags, ":")
  66. }
  67. func uniqueReasonTags(policy Policy, holdPolicy HoldPolicy, extras ...string) []string {
  68. seen := map[string]struct{}{}
  69. tags := make([]string, 0, 6)
  70. add := func(tag string) {
  71. if tag == "" {
  72. return
  73. }
  74. if _, ok := seen[tag]; ok {
  75. return
  76. }
  77. seen[tag] = struct{}{}
  78. tags = append(tags, tag)
  79. }
  80. if policy.Profile != "" {
  81. add("profile:" + slugToken(policy.Profile))
  82. }
  83. if policy.Intent != "" {
  84. add("intent:" + slugToken(policy.Intent))
  85. }
  86. if policy.RefinementStrategy != "" {
  87. add("strategy:" + slugToken(policy.RefinementStrategy))
  88. }
  89. for _, reason := range holdPolicy.Reasons {
  90. add(reason)
  91. }
  92. for _, extra := range extras {
  93. add(extra)
  94. }
  95. return tags
  96. }
  97. func slugToken(input string) string {
  98. input = strings.TrimSpace(strings.ToLower(input))
  99. if input == "" {
  100. return ""
  101. }
  102. parts := strings.Fields(input)
  103. return strings.Join(parts, "-")
  104. }