Phase 2.5: Add turbulence backtest feature wrappers

bulk_richardson, theta_e_jump, and shear_at_top feature functions
pull derived fields from the nearest hrrr_native_profile. Ready for
mix backtest once sufficient data is backfilled.
This commit is contained in:
Graham McIntire 2026-04-10 08:22:43 -05:00
parent 864a91fc5c
commit 3d58582754

View file

@ -113,6 +113,52 @@ defmodule Microwaveprop.Backtest.Features do
end
end
@doc """
Bulk Richardson number at the inversion top from the nearest native profile.
Ri < 0.25 turbulent (bad for propagation)
Ri > 1.0 laminar (good for propagation)
Returns nil if no inversion detected or no native profile available.
"""
@spec bulk_richardson(float, float, DateTime.t()) :: float | nil
def bulk_richardson(lat, lon, valid_time) do
with %HrrrNativeProfile{bulk_richardson: ri} when is_float(ri) <-
find_nearest_native(lat, lon, valid_time) do
ri
else
_ -> nil
end
end
@doc """
θ jump (K) across the inversion from the nearest native profile.
Larger positive values indicate stronger thermodynamic decoupling.
"""
@spec theta_e_jump(float, float, DateTime.t()) :: float | nil
def theta_e_jump(lat, lon, valid_time) do
with %HrrrNativeProfile{theta_e_jump_k: jump} when is_float(jump) <-
find_nearest_native(lat, lon, valid_time) do
jump
else
_ -> nil
end
end
@doc """
Wind shear magnitude (m/s) at the inversion top from the nearest native profile.
"""
@spec shear_at_top(float, float, DateTime.t()) :: float | nil
def shear_at_top(lat, lon, valid_time) do
with %HrrrNativeProfile{shear_at_top_ms: shear} when is_float(shear) <-
find_nearest_native(lat, lon, valid_time) do
shear
else
_ -> nil
end
end
defp find_nearest_native(lat, lon, valid_time) do
dlat = 0.07
dlon = 0.07