|
- package cfar
-
- // cellAvg implements CA-CFAR with a sliding sum window.
- type cellAvg struct {
- guard int
- train int
- scaleDb float64
- wrapAround bool
- }
-
- func newCA(cfg Config) CFAR {
- return &cellAvg{
- guard: cfg.GuardCells,
- train: cfg.TrainCells,
- scaleDb: cfg.ScaleDb,
- wrapAround: cfg.WrapAround,
- }
- }
-
- func (c *cellAvg) Thresholds(spectrum []float64) []float64 {
- n := len(spectrum)
- if n == 0 {
- return nil
- }
- out := make([]float64, n)
- train := c.train
- guard := c.guard
- total := 2 * train
- if total == 0 {
- return out
- }
-
- at := func(i int) float64 {
- if c.wrapAround {
- return spectrum[((i%n)+n)%n]
- }
- if i < 0 || i >= n {
- return spectrum[clampInt(i, 0, n-1)]
- }
- return spectrum[i]
- }
-
- var leftSum, rightSum float64
- for k := 1; k <= train; k++ {
- leftSum += at(0 - guard - k)
- rightSum += at(0 + guard + k)
- }
-
- invN := 1.0 / float64(total)
- out[0] = (leftSum+rightSum)*invN + c.scaleDb
-
- for i := 1; i < n; i++ {
- leftSum -= at(i - 1 - guard - train)
- leftSum += at(i - guard - 1)
-
- rightSum -= at(i - 1 + guard + 1)
- rightSum += at(i + guard + train)
-
- out[i] = (leftSum+rightSum)*invN + c.scaleDb
- }
- return out
- }
-
- func clampInt(v, lo, hi int) int {
- if v < lo {
- return lo
- }
- if v > hi {
- return hi
- }
- return v
- }
|