First step toward physics-based HF / sporadic-E scoring. Polls GIRO's DIDBase tabular endpoint every 10 minutes for two US ionosondes (Millstone Hill MHJ45, Alpena AL945), parses the plain-text response into observation rows, and upserts into a new ionosonde_observations table keyed on (station_code, valid_time). This gets foEs (E-layer sporadic critical frequency) into the database as a direct measurement — the key input for predicting 144 MHz Es openings via ITU-R P.534-6. foF2 + MUFD are the F2-layer inputs for HF MUF predictions. Not yet wired into scoring. Boulder/Wallops/Austin/Idaho/Point Arguello are in the GIRO catalog but were silent when probed — add them back if/when they come online. Next steps: SWPC JSON (Kp, F10.7, sunspot), GOES X-ray flux, D-RAP text, and the P.534-6 Es scoring factor that uses foEs at midpoint for the 144/440 band configs.
39 lines
1.2 KiB
Elixir
39 lines
1.2 KiB
Elixir
defmodule Microwaveprop.Ionosphere.Observation do
|
|
@moduledoc """
|
|
A single ionosonde measurement for one station at one time. Populated
|
|
from GIRO's DIDBase scaled-characteristic feed and used by the
|
|
propagation scorer for sporadic-E and HF MUF predictions.
|
|
"""
|
|
use Ecto.Schema
|
|
|
|
import Ecto.Changeset
|
|
|
|
@primary_key {:id, :binary_id, autogenerate: true}
|
|
@foreign_key_type :binary_id
|
|
|
|
schema "ionosonde_observations" do
|
|
field :station_code, :string
|
|
field :valid_time, :utc_datetime
|
|
field :confidence_score, :integer
|
|
field :fo_f2_mhz, :float
|
|
field :fo_e_mhz, :float
|
|
field :fo_es_mhz, :float
|
|
field :hm_f2_km, :float
|
|
field :mufd_mhz, :float
|
|
|
|
timestamps(type: :utc_datetime)
|
|
end
|
|
|
|
@type t :: %__MODULE__{}
|
|
|
|
@required_fields ~w(station_code valid_time)a
|
|
@optional_fields ~w(confidence_score fo_f2_mhz fo_e_mhz fo_es_mhz hm_f2_km mufd_mhz)a
|
|
|
|
@spec changeset(t() | Ecto.Changeset.t(), map()) :: Ecto.Changeset.t()
|
|
def changeset(observation, attrs) do
|
|
observation
|
|
|> cast(attrs, @required_fields ++ @optional_fields)
|
|
|> validate_required(@required_fields)
|
|
|> unique_constraint([:station_code, :valid_time])
|
|
end
|
|
end
|