predictor/internal/weather/gfs/wind_test.go

69 lines
1.8 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package gfs
import (
"math"
"path/filepath"
"testing"
"time"
)
// testVariant is a tiny cube (2 hours × 3 levels × 3 lat × 4 lng) used to
// exercise the sampler without allocating a multi-gigabyte real dataset.
func testVariant() *Variant {
return &Variant{
ID: "gfs-test",
ResToken: "test",
Resolution: 90, // 180/90+1 = 3 lats, 360/90 = 4 lngs
HourStep: 3,
MaxHour: 3, // 2 hours
Pressures: []int{1000, 500, 100},
PressuresPgrb2: []int{1000, 500, 100},
PressuresPgrb2b: []int{},
}
}
func TestWindSampler(t *testing.T) {
v := testVariant()
path := filepath.Join(t.TempDir(), "cube.bin")
f, err := Create(path, v)
if err != nil {
t.Fatalf("Create: %v", err)
}
// HGT increases with level so the altitude bisection has a gradient;
// U and V are constant so interpolation must return them exactly.
for h := range v.NumHours() {
for lvl := range v.NumLevels() {
for la := range v.NumLatitudes() {
for ln := range v.NumLongitudes() {
f.SetVal(h, lvl, VarHeight, la, ln, float32(lvl*1000))
f.SetVal(h, lvl, VarWindU, la, ln, 7)
f.SetVal(h, lvl, VarWindV, la, ln, 3)
}
}
}
}
f.Flush()
f.Close()
epoch := time.Date(2026, 1, 1, 0, 0, 0, 0, time.UTC)
rf, err := Open(path, v, epoch)
if err != nil {
t.Fatalf("Open: %v", err)
}
defer rf.Close()
w := NewWind(rf)
// Query at the dataset epoch, equator, lng 45, altitude 500m (between
// level 0 @ 0m and level 1 @ 1000m).
s, err := w.Wind(float64(epoch.Unix()), 0, 45, 500)
if err != nil {
t.Fatalf("Wind: %v", err)
}
if math.Abs(s.U-7) > 1e-5 || math.Abs(s.V-3) > 1e-5 {
t.Errorf("constant wind not recovered: got U=%v V=%v, want 7,3", s.U, s.V)
}
if s.AboveModel {
t.Errorf("AboveModel should be false at altitude within model range")
}
}