astro/low_precision_regression_test.go

176 lines
8.5 KiB
Go
Raw Normal View History

package astro_test
import (
"encoding/json"
"math"
"os"
"testing"
"b612.me/astro/basic"
"b612.me/astro/planet"
)
type lowPrecisionSunSnapshot struct {
LoBits uint64 `json:"lo_bits"`
MBits uint64 `json:"m_bits"`
EccBits uint64 `json:"ecc_bits"`
PeriBits uint64 `json:"peri_bits"`
MidBits uint64 `json:"mid_bits"`
TrueLoBits uint64 `json:"true_lo_bits"`
ApparentLoBits uint64 `json:"apparent_lo_bits"`
ApparentRaBits uint64 `json:"apparent_ra_bits"`
ApparentDecBits uint64 `json:"apparent_dec_bits"`
TrueRaBits uint64 `json:"true_ra_bits"`
TrueDecBits uint64 `json:"true_dec_bits"`
DistanceBits uint64 `json:"distance_bits"`
}
type lowPrecisionMoonSnapshot struct {
LoBits uint64 `json:"lo_bits"`
SunAngleBits uint64 `json:"sun_angle_bits"`
MBits uint64 `json:"m_bits"`
LonXBits uint64 `json:"lonx_bits"`
IBits uint64 `json:"i_bits"`
RBits uint64 `json:"r_bits"`
BBits uint64 `json:"b_bits"`
TrueLoBits uint64 `json:"true_lo_bits"`
TrueBoBits uint64 `json:"true_bo_bits"`
AwayBits uint64 `json:"away_bits"`
ApparentLoBits uint64 `json:"apparent_lo_bits"`
TrueRaBits uint64 `json:"true_ra_bits"`
TrueDecBits uint64 `json:"true_dec_bits"`
}
type lowPrecisionSample struct {
UTC string `json:"utc"`
TTJD float64 `json:"tt_jd"`
Sun lowPrecisionSunSnapshot `json:"sun"`
Moon lowPrecisionMoonSnapshot `json:"moon"`
}
func loadLowPrecisionSamples(t *testing.T) []lowPrecisionSample {
t.Helper()
data, err := os.ReadFile("testdata/low_precision_sun_moon_baseline.json")
if err != nil {
t.Fatal(err)
}
var samples []lowPrecisionSample
if err := json.Unmarshal(data, &samples); err != nil {
t.Fatal(err)
}
if len(samples) == 0 {
t.Fatal("empty low precision baseline samples")
}
return samples
}
func TestLowPrecisionSunMoonBaselineRegression(t *testing.T) {
samples := loadLowPrecisionSamples(t)
assertBits := func(t *testing.T, name, utc string, got float64, want uint64) {
t.Helper()
if math.Float64bits(got) != want {
t.Fatalf("%s regression at %s", name, utc)
}
}
for _, sample := range samples {
jd := sample.TTJD
assertBits(t, "planet.SunLo", sample.UTC, planet.SunLo(jd), sample.Sun.LoBits)
assertBits(t, "basic.SunLo", sample.UTC, basic.SunLo(jd), sample.Sun.LoBits)
assertBits(t, "planet.SunM", sample.UTC, planet.SunM(jd), sample.Sun.MBits)
assertBits(t, "basic.SunM", sample.UTC, basic.SunM(jd), sample.Sun.MBits)
assertBits(t, "planet.Earthe", sample.UTC, planet.Earthe(jd), sample.Sun.EccBits)
assertBits(t, "basic.Earthe", sample.UTC, basic.Earthe(jd), sample.Sun.EccBits)
assertBits(t, "planet.EarthPI", sample.UTC, planet.EarthPI(jd), sample.Sun.PeriBits)
assertBits(t, "basic.EarthPI", sample.UTC, basic.EarthPI(jd), sample.Sun.PeriBits)
assertBits(t, "planet.SunMidFun", sample.UTC, planet.SunMidFun(jd), sample.Sun.MidBits)
assertBits(t, "basic.SunMidFun", sample.UTC, basic.SunMidFun(jd), sample.Sun.MidBits)
assertBits(t, "planet.SunTrueLo", sample.UTC, planet.SunTrueLo(jd), sample.Sun.TrueLoBits)
assertBits(t, "basic.SunTrueLo", sample.UTC, basic.SunTrueLo(jd), sample.Sun.TrueLoBits)
assertBits(t, "planet.SunApparentLo", sample.UTC, planet.SunApparentLo(jd), sample.Sun.ApparentLoBits)
assertBits(t, "basic.SunApparentLo", sample.UTC, basic.SunApparentLo(jd), sample.Sun.ApparentLoBits)
assertBits(t, "basic.SunApparentRa", sample.UTC, basic.SunApparentRa(jd), sample.Sun.ApparentRaBits)
assertBits(t, "basic.SunApparentDec", sample.UTC, basic.SunApparentDec(jd), sample.Sun.ApparentDecBits)
assertBits(t, "basic.SunTrueRa", sample.UTC, basic.SunTrueRa(jd), sample.Sun.TrueRaBits)
assertBits(t, "basic.SunTrueDec", sample.UTC, basic.SunTrueDec(jd), sample.Sun.TrueDecBits)
assertBits(t, "planet.Distance", sample.UTC, planet.Distance(jd), sample.Sun.DistanceBits)
assertBits(t, "basic.Distance", sample.UTC, basic.Distance(jd), sample.Sun.DistanceBits)
assertBits(t, "planet.MoonLo", sample.UTC, planet.MoonLo(jd), sample.Moon.LoBits)
assertBits(t, "basic.MoonLo", sample.UTC, basic.MoonLo(jd), sample.Moon.LoBits)
assertBits(t, "planet.SunMoonAngle", sample.UTC, planet.SunMoonAngle(jd), sample.Moon.SunAngleBits)
assertBits(t, "basic.SunMoonAngle", sample.UTC, basic.SunMoonAngle(jd), sample.Moon.SunAngleBits)
assertBits(t, "planet.MoonM", sample.UTC, planet.MoonM(jd), sample.Moon.MBits)
assertBits(t, "basic.MoonM", sample.UTC, basic.MoonM(jd), sample.Moon.MBits)
assertBits(t, "planet.MoonLonX", sample.UTC, planet.MoonLonX(jd), sample.Moon.LonXBits)
assertBits(t, "basic.MoonLonX", sample.UTC, basic.MoonLonX(jd), sample.Moon.LonXBits)
assertBits(t, "planet.MoonI", sample.UTC, planet.MoonI(jd), sample.Moon.IBits)
assertBits(t, "basic.MoonI", sample.UTC, basic.MoonI(jd), sample.Moon.IBits)
assertBits(t, "planet.MoonR", sample.UTC, planet.MoonR(jd), sample.Moon.RBits)
assertBits(t, "basic.MoonR", sample.UTC, basic.MoonR(jd), sample.Moon.RBits)
assertBits(t, "planet.MoonB", sample.UTC, planet.MoonB(jd), sample.Moon.BBits)
assertBits(t, "basic.MoonB", sample.UTC, basic.MoonB(jd), sample.Moon.BBits)
assertBits(t, "planet.MoonTrueLo", sample.UTC, planet.MoonTrueLo(jd), sample.Moon.TrueLoBits)
assertBits(t, "basic.MoonTrueLo", sample.UTC, basic.MoonTrueLo(jd), sample.Moon.TrueLoBits)
assertBits(t, "planet.MoonTrueBo", sample.UTC, planet.MoonTrueBo(jd), sample.Moon.TrueBoBits)
assertBits(t, "basic.MoonTrueBo", sample.UTC, basic.MoonTrueBo(jd), sample.Moon.TrueBoBits)
assertBits(t, "planet.MoonAway", sample.UTC, planet.MoonAway(jd), sample.Moon.AwayBits)
assertBits(t, "basic.MoonAway", sample.UTC, basic.MoonAway(jd), sample.Moon.AwayBits)
assertBits(t, "basic.MoonApparentLo", sample.UTC, basic.MoonApparentLo(jd), sample.Moon.ApparentLoBits)
assertBits(t, "basic.MoonTrueRa", sample.UTC, basic.MoonTrueRa(jd), sample.Moon.TrueRaBits)
assertBits(t, "basic.MoonTrueDec", sample.UTC, basic.MoonTrueDec(jd), sample.Moon.TrueDecBits)
}
}
func TestDerivedHighPrecisionTruncationFullMatchesDefault(t *testing.T) {
jd := 2469808.7654321
lon := 116.391
lat := 39.907
tz := 8.0
assertSame := func(name string, got, want float64) {
t.Helper()
if math.Float64bits(got) != math.Float64bits(want) {
t.Fatalf("%s full-n mismatch", name)
}
}
assertSamePair := func(name string, got1, got2, want1, want2 float64) {
t.Helper()
assertSame(name+".1", got1, want1)
assertSame(name+".2", got2, want2)
}
assertSame("HSunTrueLo", basic.HSunTrueLo(jd), basic.HSunTrueLoN(jd, -1))
assertSame("HSunTrueBo", basic.HSunTrueBo(jd), basic.HSunTrueBoN(jd, -1))
assertSame("HSunApparentLo", basic.HSunApparentLo(jd), basic.HSunApparentLoN(jd, -1))
assertSame("SunLoGXC", basic.SunLoGXC(jd), basic.SunLoGXCN(jd, -1))
assertSame("EarthAway", basic.EarthAway(jd), basic.EarthAwayN(jd, -1))
assertSame("HSunApparentRa", basic.HSunApparentRa(jd), basic.HSunApparentRaN(jd, -1))
assertSame("HSunTrueRa", basic.HSunTrueRa(jd), basic.HSunTrueRaN(jd, -1))
assertSame("HSunApparentDec", basic.HSunApparentDec(jd), basic.HSunApparentDecN(jd, -1))
assertSame("HSunTrueDec", basic.HSunTrueDec(jd), basic.HSunTrueDecN(jd, -1))
ra1, dec1 := basic.HSunApparentRaDec(jd)
ra2, dec2 := basic.HSunApparentRaDecN(jd, -1)
assertSamePair("HSunApparentRaDec", ra1, dec1, ra2, dec2)
assertSame("HMoonTrueLo", basic.HMoonTrueLo(jd), basic.HMoonTrueLoN(jd, -1))
assertSame("HMoonTrueBo", basic.HMoonTrueBo(jd), basic.HMoonTrueBoN(jd, -1))
assertSame("HMoonAway", basic.HMoonAway(jd), basic.HMoonAwayN(jd, -1))
assertSame("HMoonApparentLo", basic.HMoonApparentLo(jd), basic.HMoonApparentLoN(jd, -1))
assertSame("HMoonTrueRa", basic.HMoonTrueRa(jd), basic.HMoonTrueRaN(jd, -1))
assertSame("HMoonTrueDec", basic.HMoonTrueDec(jd), basic.HMoonTrueDecN(jd, -1))
ra1, dec1 = basic.HMoonTrueRaDec(jd)
ra2, dec2 = basic.HMoonTrueRaDecN(jd, -1)
assertSamePair("HMoonTrueRaDec", ra1, dec1, ra2, dec2)
ra1, dec1 = basic.HMoonApparentRaDec(jd, lon, lat, tz)
ra2, dec2 = basic.HMoonApparentRaDecN(jd, lon, lat, tz, -1)
assertSamePair("HMoonApparentRaDec", ra1, dec1, ra2, dec2)
assertSame("HMoonApparentRa", basic.HMoonApparentRa(jd, lon, lat, tz), basic.HMoonApparentRaN(jd, lon, lat, tz, -1))
assertSame("HMoonApparentDec", basic.HMoonApparentDec(jd, lon, lat, tz), basic.HMoonApparentDecN(jd, lon, lat, tz, -1))
assertSame("HMoonAzimuth", basic.HMoonAzimuth(jd, lon, lat, tz), basic.HMoonAzimuthN(jd, lon, lat, tz, -1))
assertSame("HMoonHeight", basic.HMoonHeight(jd, lon, lat, tz), basic.HMoonHeightN(jd, lon, lat, tz, -1))
}