Fix map detail panel: update weights, add PWAT, show duct info
- Update all 9 hardcoded weights to match recalibrated values - Add missing PWAT factor (11.3% weight) to FACTOR_META and FACTOR_ORDER - Reorder factors by weight (highest first) - Fix pressure explanation (low pressure is better, not rising) - Add PWAT factor explanation (beneficial vs harmful by band) - Show duct info panel when native data detects ducting layers (count, thickness, minimum trapped frequency)
This commit is contained in:
parent
a1d787b26f
commit
58a99de3cd
1 changed files with 42 additions and 14 deletions
|
|
@ -1,21 +1,24 @@
|
|||
import topbar from "../vendor/topbar"
|
||||
import { updateGridOverlay } from "./maidenhead_grid"
|
||||
|
||||
// Weights must match BandConfig.weights() in band_config.ex
|
||||
// Recalibrated 2026-04-11 via gradient descent (loss 0.42 → 0.12)
|
||||
const FACTOR_META = {
|
||||
humidity: { label: "Humidity", weight: 0.20, unit: "g/m\u00b3" },
|
||||
time_of_day: { label: "Time of Day", weight: 0.20, unit: "" },
|
||||
td_depression: { label: "Td Depression", weight: 0.12, unit: "\u00b0F" },
|
||||
refractivity: { label: "Refractivity", weight: 0.10, unit: "N/km" },
|
||||
sky: { label: "Sky Cover", weight: 0.10, unit: "%" },
|
||||
season: { label: "Season", weight: 0.10, unit: "" },
|
||||
rain: { label: "Rain", weight: 0.08, unit: "" },
|
||||
wind: { label: "Wind", weight: 0.06, unit: "kts" },
|
||||
pressure: { label: "Pressure", weight: 0.04, unit: "mb" }
|
||||
rain: { label: "Rain", weight: 0.1362, unit: "" },
|
||||
humidity: { label: "Humidity", weight: 0.1243, unit: "g/m\u00b3" },
|
||||
pwat: { label: "PWAT", weight: 0.1128, unit: "mm" },
|
||||
season: { label: "Season", weight: 0.1112, unit: "" },
|
||||
refractivity: { label: "Refractivity", weight: 0.1049, unit: "N/km" },
|
||||
pressure: { label: "Pressure", weight: 0.1032, unit: "mb" },
|
||||
td_depression: { label: "Td Depression", weight: 0.0978, unit: "\u00b0F" },
|
||||
sky: { label: "Sky Cover", weight: 0.08, unit: "%" },
|
||||
wind: { label: "Wind", weight: 0.08, unit: "kts" },
|
||||
time_of_day: { label: "Time of Day", weight: 0.0496, unit: "" }
|
||||
}
|
||||
|
||||
const FACTOR_ORDER = [
|
||||
"humidity", "time_of_day", "td_depression", "refractivity",
|
||||
"sky", "season", "rain", "wind", "pressure"
|
||||
"rain", "humidity", "pwat", "season", "refractivity",
|
||||
"pressure", "td_depression", "sky", "wind", "time_of_day"
|
||||
]
|
||||
|
||||
function scoreTier(score) {
|
||||
|
|
@ -90,10 +93,20 @@ function factorExplanation(key, score, detail) {
|
|||
if (score >= 90) return "No rain — no path attenuation"
|
||||
if (score >= 50) return "Light rain — minor attenuation"
|
||||
return "Heavy rain — significant path loss"
|
||||
case "pwat":
|
||||
if (beneficial) {
|
||||
if (score >= 80) return "High column moisture — strong refractivity"
|
||||
if (score >= 50) return "Moderate PWAT — some refractivity enhancement"
|
||||
return "Low PWAT — limited moisture for ducting"
|
||||
} else {
|
||||
if (score >= 80) return "Low column moisture — minimal absorption"
|
||||
if (score >= 50) return "Moderate PWAT"
|
||||
return "High PWAT — significant absorption at this frequency"
|
||||
}
|
||||
case "pressure":
|
||||
if (score >= 70) return "Rising pressure — increasing stability favors inversions"
|
||||
if (score >= 55) return "Steady pressure — stable conditions"
|
||||
return "Falling pressure — instability weakens inversions"
|
||||
if (score >= 70) return "Low pressure — frontal boundaries favor ducting"
|
||||
if (score >= 45) return "Normal pressure — average conditions"
|
||||
return "High pressure — stable ridge, inversions cap at wrong altitude"
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
|
|
@ -344,11 +357,26 @@ function buildPopupHTML(detail, viewshedLoading) {
|
|||
<div style="font-size:10px;font-weight:700;opacity:0.5;margin-bottom:4px;text-transform:uppercase;letter-spacing:0.5px;">Analysis</div>
|
||||
${explanations}
|
||||
</div>
|
||||
${detail.factors.duct_info ? buildDuctInfoHTML(detail.factors.duct_info) : ""}
|
||||
${detail.forecast ? buildForecastSvg(detail.forecast) : ""}
|
||||
${viewshedStatus}
|
||||
</div>`
|
||||
}
|
||||
|
||||
function buildDuctInfoHTML(duct) {
|
||||
const freq = duct.best_duct_freq_ghz != null ? `${duct.best_duct_freq_ghz.toFixed(1)} GHz` : "—"
|
||||
const thick = duct.max_duct_thickness_m != null ? `${Math.round(duct.max_duct_thickness_m)} m` : "—"
|
||||
return `
|
||||
<div style="padding:4px 10px 6px;border-top:1px solid rgba(255,255,255,0.15);">
|
||||
<div style="font-size:10px;font-weight:700;opacity:0.5;margin-bottom:3px;text-transform:uppercase;letter-spacing:0.5px;">Ducting</div>
|
||||
<div style="font-size:12px;display:flex;gap:12px;">
|
||||
<span><strong>${duct.duct_count}</strong> layer${duct.duct_count !== 1 ? "s" : ""}</span>
|
||||
<span>Thickness: <strong>${thick}</strong></span>
|
||||
<span>Traps \u2265 <strong>${freq}</strong></span>
|
||||
</div>
|
||||
</div>`
|
||||
}
|
||||
|
||||
// --- Hook ---
|
||||
|
||||
export const PropagationMap = {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue