Eliminates the external wgrib2 C tool dependency that blocked HRRR processing. Implements Lambert Conformal projection, simple packing (Template 5.0), complex packing with spatial differencing (Template 5.3), and GRIB2 section parsing — enough to extract point values from HRRR grid data using only Elixir.
70 lines
2.2 KiB
Elixir
70 lines
2.2 KiB
Elixir
defmodule Microwaveprop.Weather.Grib2.LambertConformalTest do
|
|
use ExUnit.Case, async: true
|
|
|
|
alias Microwaveprop.Weather.Grib2.LambertConformal
|
|
|
|
# HRRR grid parameters (from GRIB2 Section 3, Template 3.30)
|
|
@hrrr_params %{
|
|
nx: 1799,
|
|
ny: 1059,
|
|
la1: 21.138123,
|
|
lo1: 237.280472,
|
|
lad: 38.5,
|
|
lov: 262.5,
|
|
dx: 3000.0,
|
|
dy: 3000.0,
|
|
latin1: 38.5,
|
|
latin2: 38.5,
|
|
scan_mode: 64
|
|
}
|
|
|
|
describe "to_grid_index/3" do
|
|
test "first grid point maps to (0, 0)" do
|
|
assert {:ok, {0, 0}} = LambertConformal.to_grid_index(@hrrr_params, 21.138123, 237.280472)
|
|
end
|
|
|
|
test "first grid point with negative longitude" do
|
|
# 237.280472 in 0-360 == -122.719528 in -180..180
|
|
assert {:ok, {0, 0}} =
|
|
LambertConformal.to_grid_index(@hrrr_params, 21.138123, -122.719528)
|
|
end
|
|
|
|
test "Dallas area returns reasonable indices" do
|
|
# Dallas TX: ~32.78, -96.8 (263.2 in 0-360)
|
|
# HRRR 3km grid covers CONUS; Dallas should be roughly in the middle
|
|
assert {:ok, {i, j}} = LambertConformal.to_grid_index(@hrrr_params, 32.78, -96.8)
|
|
|
|
# Indices should be well within grid bounds
|
|
assert i > 100 and i < 1700
|
|
assert j > 100 and j < 900
|
|
end
|
|
|
|
test "handles negative longitudes correctly" do
|
|
{:ok, {i1, j1}} = LambertConformal.to_grid_index(@hrrr_params, 40.0, -105.0)
|
|
{:ok, {i2, j2}} = LambertConformal.to_grid_index(@hrrr_params, 40.0, 255.0)
|
|
|
|
assert i1 == i2
|
|
assert j1 == j2
|
|
end
|
|
|
|
test "returns error for point outside grid" do
|
|
# London, UK — well outside CONUS HRRR domain
|
|
assert {:error, :outside_grid} =
|
|
LambertConformal.to_grid_index(@hrrr_params, 51.5, -0.12)
|
|
end
|
|
|
|
test "returns error for point south of grid" do
|
|
# South America
|
|
assert {:error, :outside_grid} =
|
|
LambertConformal.to_grid_index(@hrrr_params, -10.0, -80.0)
|
|
end
|
|
|
|
test "edge of grid returns valid indices" do
|
|
# Somewhere near the grid edge — northeast CONUS
|
|
result = LambertConformal.to_grid_index(@hrrr_params, 45.0, -70.0)
|
|
assert {:ok, {i, j}} = result
|
|
assert i >= 0 and i < 1799
|
|
assert j >= 0 and j < 1059
|
|
end
|
|
end
|
|
end
|