From f20e13678f149f6c3b3e3b6b88eebb546ba56d9b Mon Sep 17 00:00:00 2001 From: michealroberts Date: Tue, 22 Oct 2024 12:17:32 +0100 Subject: [PATCH] feat: add GetRefraction() to refraction module in @observerly/sidera feat: add GetRefraction() to refraction module in @observerly/sidera --- pkg/refraction/refraction.go | 44 ++++++++++ pkg/refraction/refraction_test.go | 133 ++++++++++++++++++++++++++++++ 2 files changed, 177 insertions(+) create mode 100644 pkg/refraction/refraction.go create mode 100644 pkg/refraction/refraction_test.go diff --git a/pkg/refraction/refraction.go b/pkg/refraction/refraction.go new file mode 100644 index 0000000..daa88cf --- /dev/null +++ b/pkg/refraction/refraction.go @@ -0,0 +1,44 @@ +/*****************************************************************************************************************/ + +// @author Michael Roberts +// @package @observerly/sidera +// @license Copyright © 2021-2024 observerly + +/*****************************************************************************************************************/ + +package refraction + +/*****************************************************************************************************************/ + +import ( + "math" + + "github.com/observerly/sidera/pkg/common" +) + +/*****************************************************************************************************************/ + +func GetRefraction( + target common.HorizontalCoordinate, + pressure float64, + temperature float64, +) float64 { + alt := target.Altitude + + if alt < 0 { + return math.Inf(1) + } + + // The pressure, in Pascals: + P := pressure + + // The temperature, in Kelvin: + T := temperature + + // Get the atmospheric refraction in degrees, corrected for temperature and pressure: + R := (1.02 / math.Tan(common.Radians(alt+10.3/(alt+5.11))) / 60) * (P / 101325) * (283.15 / T) + + return R +} + +/*****************************************************************************************************************/ diff --git a/pkg/refraction/refraction_test.go b/pkg/refraction/refraction_test.go new file mode 100644 index 0000000..aad2db1 --- /dev/null +++ b/pkg/refraction/refraction_test.go @@ -0,0 +1,133 @@ +/*****************************************************************************************************************/ + +// @author Michael Roberts +// @package @observerly/sidera +// @license Copyright © 2021-2024 observerly + +/*****************************************************************************************************************/ + +package refraction + +import ( + "math" + "testing" + + "github.com/observerly/sidera/pkg/common" +) + +/*****************************************************************************************************************/ + +var target = common.HorizontalCoordinate{ + Altitude: 50.0, + Azimuth: 180.0, // For diffraction tests, the azimuthal angle does not matter. +} + +/*****************************************************************************************************************/ + +func TestRefractionAtTargetBelowHorizon(t *testing.T) { + // Test the refraction at a target below the horizon: + R := GetRefraction(common.HorizontalCoordinate{ + Altitude: -10.0, + Azimuth: 180.0, + }, 101325, 283.15) + + if R != math.Inf(1) { + t.Errorf("Expected refraction to be infinite, got %f", R) + } +} + +/*****************************************************************************************************************/ + +func TestRefractionAtTargetAboveHorizon(t *testing.T) { + // Test the refraction at a target above the horizon: + R := GetRefraction(target, 101325, 283.15) + + if R == math.Inf(1) { + t.Errorf("Expected refraction to be finite, got %f", R) + } + + if R <= 0 { + t.Errorf("Expected refraction to be positive, got %f", R) + } + + if R > 1.5 { + t.Errorf("Expected refraction to be less than 1.5, got %f", R) + } +} + +/*****************************************************************************************************************/ + +func TestRefractionAtTargetAtHorizon(t *testing.T) { + // Test the refraction at a target below the horizon: + R := GetRefraction(common.HorizontalCoordinate{ + Altitude: 0.0, + Azimuth: 180.0, + }, 101325, 283.15) + + if R <= 0 { + t.Errorf("Expected refraction to be positive, got %f", R) + } + + if R > 0.5 { + t.Errorf("Expected refraction to be less than 1.5, got %f", R) + } +} + +/*****************************************************************************************************************/ + +func TestRefractionAtTargetWithPressure(t *testing.T) { + // Test the refraction at a target above the horizon: + R := GetRefraction(target, 102325, 283.15) + + if R == math.Inf(1) { + t.Errorf("Expected refraction to be finite, got %f", R) + } + + if R <= 0 { + t.Errorf("Expected refraction to be positive, got %f", R) + } + + if R > 1.5 { + t.Errorf("Expected refraction to be less than 1.5, got %f", R) + } +} + +/*****************************************************************************************************************/ + +func TestRefractionAtTargetWithTemperature(t *testing.T) { + // Test the refraction at a target above the horizon: + R := GetRefraction(target, 101325, 286.15) + + if R == math.Inf(1) { + t.Errorf("Expected refraction to be finite, got %f", R) + } + + if R <= 0 { + t.Errorf("Expected refraction to be positive, got %f", R) + } + + if R > 1.5 { + t.Errorf("Expected refraction to be less than 1.5, got %f", R) + } +} + +/*****************************************************************************************************************/ + +func TestRefractionAtTargetWithPressureAndTemperature(t *testing.T) { + // Test the refraction at a target above the horizon: + R := GetRefraction(target, 103325, 288.15) + + if R == math.Inf(1) { + t.Errorf("Expected refraction to be finite, got %f", R) + } + + if R <= 0 { + t.Errorf("Expected refraction to be positive, got %f", R) + } + + if R > 1.5 { + t.Errorf("Expected refraction to be less than 1.5, got %f", R) + } +} + +/*****************************************************************************************************************/