← Herramienta ← Tool Guía rápida Quick guide Manual de cielo Sky manual Portada Home

Manual de uso

Niebla para fotografía: índice físico y fusión bayesiana multimodelo.

1. Qué es y qué no es

Es una página HTML autónoma que consulta la API pública de Open‑Meteo y estima el riesgo de niebla o bruma en las próximas horas y en la ventana del próximo amanecer, pensada para decidir si merece la pena salir a fotografiar. No es un modelo de capa límite ni sustituye al aviso oficial: es una herramienta de favorabilidad, con una segunda capa bayesiana que aprende de tus observaciones locales.

Dos pestañas. La primera, “Índice de niebla”, usa un único modelo numérico y muestra el índice hora a hora con toda la física visible. La segunda, “Fusión bayesiana”, descarga varios modelos en paralelo, convierte cada uno en una probabilidad y los combina en un posterior, ponderando cada modelo según lo bien que ha acertado en tu registro.

2. Instalación

No hay nada que instalar. Tres formas de usarla:

Local. Guarda niebla.html y manual-niebla.html en una carpeta y abre niebla.html con el navegador. Funciona con doble clic (origen file://).

GitHub Pages. Sube los dos archivos a un repositorio, activa Pages en Settings → Pages (rama main, carpeta raíz) y accede a https://usuario.github.io/repositorio/. El archivo se llama niebla.html precisamente para que sea la página de entrada.

Móvil. Abre la URL de Pages en el navegador del teléfono y añádela a la pantalla de inicio. El botón “Usar mi posición” pide permiso de geolocalización; en Pages funciona porque el sitio se sirve por HTTPS.

Requisitos: conexión a Internet (la previsión se descarga en cada cálculo) y un navegador moderno. Se cargan dos fuentes desde Google Fonts; si no hay red, se usan las del sistema.

3. Controles comunes

ControlFunción
Latitud, LongitudPunto para el que se pide la previsión. Se puede escribir a mano (formato decimal, longitud oeste negativa) o rellenar con “Usar mi posición”.
EntornoCostero activa el término de niebla de advección y descarga la temperatura superficial del mar (SST). Interior lo desactiva y ahorra una petición.
Acimut hacia el marSolo aparece en modo Costero. Rumbo en grados desde el punto hacia el mar abierto. No entra en el índice: sirve para que la ficha etiquete cada hora con viento “del mar” o “de tierra”, contando como del mar la dirección que cae a menos de 60° del acimut. Déjalo vacío si no lo sabes.
ES / ENCambia el idioma de la interfaz y del manual. La elección se recuerda.
ManualAbre este documento.

4. Pestaña 1: índice de niebla

Selector de modelo

“Mejor disponible” deja que Open‑Meteo elija el modelo de mayor resolución para el punto (en Europa occidental suele ser ICON‑EU o AROME). Los demás fuerzan un modelo concreto; útil para comparar.

Tarjetas

Próximas 6 horas: máximo del índice en ese intervalo y a qué hora. Amanecer: máximo en la ventana de 2.5 h antes a 1.5 h después de la salida del sol, que es cuando la niebla de radiación alcanza su desarrollo y cuando interesa estar en el sitio. Mínima depresión del punto de rocío: el valor de ΔT = T − Td más bajo previsto esta noche, con T, Td, viento, nubes, SST y presión en ese instante. Es el dato físico más directo: si no baja de 1 °C, difícilmente habrá niebla de radiación.

Ventana fotográfica

Dentro de la tarjeta del amanecer, la línea “Ventana fotográfica” contesta a la pregunta práctica: de qué hora a qué hora hay algo que fotografiar. Busca el máximo del índice entre el amanecer −4 h y +6 h y recorta el tramo continuo que se mantiene por encima de 50 puntos, interpolando entre horas en los dos bordes, así que devuelve un intervalo con minutos y una duración. Si el pico llega a 75 la etiqueta es “niebla plena”; entre 50 y 74, “solo bruma”; si no se pasa de 50 en ninguna hora, no hay niebla que defender. Avisa además cuando el tramo dura menos de una hora y cuando el máximo cae más de media hora después del amanecer. La misma tarjeta da la dirección del viento (y si es del mar o de tierra, cuando has puesto el acimut), enlaza con la ficha de luz natural para la hora dorada y recuerda que el tramo posterior al amanecer descansa sobre el factor heurístico 0.85, la parte menos firme del cálculo.

Comparar con otro sitio (A o B)

El botón “Comparar con otro sitio” abre un segundo juego de latitud, longitud y entorno, y descarga el sitio B con el mismo modelo y la misma tubería que el A. La sección “A o B” pone las dos tarjetas del próximo amanecer una junto a otra, dibuja las dos curvas del índice y da un veredicto: ve a A, ve a B, o empate práctico si la diferencia es menor de 8 puntos, en cuyo caso deciden el acceso, la composición y la hora de salida. La comparación vive solo en esta pestaña: la fusión bayesiana y el registro de observaciones siguen siendo de un único emplazamiento, el de las coordenadas de arriba, porque mezclar dos sitios estropearía el aprendizaje.

Próximas mañanas

Una fila por amanecer, hasta siete días, con el máximo del índice dentro de la ventana −2.5 h/+1.5 h, el veredicto, la mínima depresión del punto de rocío de esa noche y el viento, las nubes medias y altas y la visibilidad de la hora del máximo. La última columna es la confianza según el plazo: los dos primeros amaneceres son la previsión de verdad, el tercero y el cuarto son orientativos y del quinto en adelante es una tendencia, no una previsión. Debajo, una frase dice cuál es la mejor mañana de la semana o que ninguna pasa de 50. Es la única vista que llega a siete días; la banda, las gráficas y la tabla horaria siguen cubriendo 48 horas.

Banda horaria

Una barra por hora, 48 horas. Altura = índice. Fondo gris = noche. Hora en rojo = amanecer. Color ámbar = bruma posible (50 a 74), rojizo = niebla probable (≥ 75). Al pasar el ratón se ven las señales activas. Las horas que caen dentro de la ventana fotográfica quedan recuadradas en ámbar.

De qué se compone el índice

Una barra apilada por hora con los puntos que aporta cada término, en el mismo orden en que se calculan; la lluvia se dibuja hacia abajo porque resta. La marca negra corta al valor final del índice, ya con el factor diurno aplicado y saturado a 100, y una marca gris en lo alto señala las horas en que la suma bruta se pasaba de 100. Sirve para ver qué término limita cada hora: si la barra se queda corta por el segmento de nubes, el freno es la nubosidad media y alta y no la humedad; si el segmento de ΔT es alto y el total sigue bajo, el freno es el viento. El recuadro ámbar marca la ventana fotográfica.

Gráfica de convergencia

T y Td en °C sobre el eje izquierdo; viento en km/h sobre el derecho. Las franjas rosadas marcan las horas con ΔT < 2 °C (más intensas si < 1 °C). La línea discontinua roja es el amanecer. La imagen que buscas: T y Td acercándose durante la noche, viento por debajo de 10 km/h y fondo gris sin nubes. Al pie, una barra morada marca las horas con visibilidad prevista por debajo de 2 km, más saturada por debajo de 1 km.

Qué vas a ver: contraste, distancia y focal

Una calculadora de contraste por visibilidad, para saber qué encuadre aguanta la niebla que se espera. Por la ley de Koschmieder, un objeto oscuro sobre el fondo del cielo conserva un contraste C/C₀ = exp(−3.912·d/V), de donde el 20 % de contraste queda a 0.41·V y el 5 % a 0.77·V. Los dos deslizadores recorren la visibilidad de 0.2 a 10 km y la distancia al sujeto de 20 m a 3 km, y el selector cubre de 28 a 135 mm. Las tarjetas dan el contraste residual con su lectura (volumen y textura, plano, apenas insinuado, desaparecido) y el campo horizontal, 36·d/f en formato 24×36: a 200 m un 43 mm abarca 167 m y un 135 mm, 53 m. Debajo, la curva completa y una tabla a 50, 150, 500 y 1000 m. La visibilidad arranca en la que el modelo da para el máximo del amanecer, o en un escenario supuesto a partir del índice si ese modelo no publica visibilidad; “Volver a la previsión” deshace los ajustes a mano.

Tabla horaria

Todas las variables usadas más dirección del viento (con la etiqueta del mar o de tierra si has puesto el acimut), nubes bajas, SST y presión. La columna “Vis km” es la visibilidad que pronostica el propio modelo: es su diagnóstico más directo de niebla, pero también la variable menos fiable de Open‑Meteo, así que léela como un escenario y no como una medida. Por debajo de 3 km apoya al resto de señales; por sí sola no decide, y de ahí que pese como mucho 20 puntos frente a los 40 de ΔT.

Fórmula del índice

TérminoPuntosJustificación
ΔT = T − Td40 si ≤ 0.5 °C; lineal a 0 en 4 °CSaturación. Condición necesaria.
Viento 10 m<2: 14 · 2–8: 20 · 8–15: 8 · 15–20: 3 · >20: 0Niebla de radiación: algo de mezcla turbulenta la profundiza; calma absoluta da rocío; viento fuerte la impide.
Nubosidad sobre la capa (medias y altas)<25 %: 20 · 25–60 %: 8 · >60 %: 0 (mitad de día)Cielo despejado por encima = enfriamiento radiativo del suelo. Se usa máx(medias, 0.6·altas), no el total: la nubosidad baja de un modelo suele ser la propia niebla y no debe penalizar. Solo cuenta como estratos (y penaliza) si la visibilidad prevista es buena.
Visibilidad modelo<1 km: 20 · <3 km: 10 · <6 km: 4 · sin dato: 5Diagnóstico directo del modelo. Los modelos que no la publican reciben un valor neutro para no quedar sistemáticamente por debajo.
Persistencia+2 por hora nocturna previa consecutiva con ΔT < 1.5 °C y viento < 12 km/h, máximo +8La niebla necesita horas de enfriamiento: una saturación mantenida desde medianoche vale más que un instante a las 06:00.
HR ≥ 97 %+10Redundante con ΔT pero robusto a redondeos.
Lluvia > 0.5 mm−15Precipitación activa suele ir con nubes y viento.
Advección (costero)hasta +30 si Td − SST > 0 y viento 8–30 km/hAire húmedo sobre mar más frío se enfría hasta saturar. No necesita calma ni cielo despejado.
Día× 0.65; × 0.85 en las dos horas siguientes al amanecerLa radiación solar disipa la capa, pero tarda; justo después del amanecer la niebla suele seguir y es el mejor momento fotográfico.

5. Pestaña 2: fusión bayesiana

Selección de modelos

Cada casilla es un modelo. Se descargan en paralelo con un límite de 12 s cada uno; los que no llegan a tiempo se descartan y se indica “timeout”. Tras cada cálculo aparece el tiempo de respuesta de cada modelo. Si alguno es sistemáticamente lento en tu conexión, desmárcalo: la selección se recuerda. Por defecto están activos ICON, GFS, AROME/ARPEGE, ECMWF y UKMO.

Cómo se combina: consenso y contracción

Primero se forma un consenso de los modelos como media ponderada en log‑odds: logit p̄ = Σ w_m · logit p_m / Σ w_m. Esta media está garantizadamente dentro de la envolvente: nunca por encima del modelo más alto ni por debajo del más bajo. Después el posterior se obtiene contrayendo ese consenso hacia la climatología local: logit P = logit π + γ · (logit p̄ − logit π). El resultado queda siempre entre tu tasa local π y el consenso p̄.

Parámetro γ

Cuánto te fías de los modelos frente a la climatología, entre 0.1 y 1 (defecto 0.7). Con γ = 1 el posterior es el consenso puro; con valores bajos se pega a la frecuencia histórica de tu registro. Mantener γ por debajo de 1 es razonable mientras la conversión de índice a probabilidad no esté contrastada con tus observaciones; la recalibración automática (ver más abajo) va supliendo este ajuste a mano a medida que acumulas noches.

Fuentes ensemble (EPS/ENS)

Además de los modelos deterministas hay fuentes de conjunto: el mismo modelo ejecutado 30 a 50 veces con perturbaciones. Para ellas la probabilidad no sale de la logística, sino de los propios miembros (media de las probabilidades de los miembros), lo que refleja la incertidumbre real de la atmósfera esa noche. ICON EPS viene activada por defecto; GFS ENS y ECMWF ENS son más pesadas y están desmarcadas.

Recalibración automática

Con 12 o más noches registradas, la aplicación ajusta una corrección de Platt q = σ(a·logit P + b) sobre los pares (posterior congelado, resultado observado), con prior a ≈ 1, b ≈ 0 para que pocas noches no la distorsionen. Corrige el sesgo sistemático del posterior; cuando está activa, la línea de estado muestra "recalibrado (n, a, b)".

Tarjetas

Posterior para las próximas 6 horas y para la ventana del amanecer, con el rango mínimo a máximo entre modelos y la probabilidad individual de cada uno. La tercera tarjeta da la desviación típica entre modelos en el amanecer: acuerdo alto (< 10 pp), moderado o desacuerdo. Un posterior del 40 % con acuerdo alto es una previsión más útil que un 55 % con desacuerdo. La tarjeta del amanecer trae además su propia ventana fotográfica, medida sobre el posterior con umbral del 25 % (“niebla plena” a partir del 50 %), y, para las fuentes de conjunto, la banda p10–p90 y cuántos miembros dan niebla.

Gráfica

Una línea fina por modelo, banda gris con el rango y línea gruesa negra con el posterior. Eje vertical en %.

Tablas

“Estado del amanecer por modelo” muestra, para cada modelo, su probabilidad máxima en la ventana y el estado físico previsto en esa hora. “Pesos bayesianos y prior” muestra w_m, el Brier, el porcentaje de aciertos (con el número de noches congeladas entre paréntesis), la log‑verosimilitud acumulada y el prior Beta actual. La log‑verosimilitud es lo que fija el peso; Brier y aciertos son la misma información en unidades legibles.

6. Entrenamiento: registro de observaciones

El aprendizaje consiste en comparar lo que cada modelo predijo con lo que tú viste. Para que la comparación sea honesta, la predicción tiene que quedar fijada antes de conocer el resultado. La herramienta lo hace sola:

Congelación automática. Cada vez que pulsas “Calcular” en la pestaña 2, las probabilidades de cada modelo para la ventana del próximo amanecer se guardan asociadas a la fecha de esa noche (la noche se identifica por la fecha de la tarde, es decir, el día anterior al amanecer). Si calculas varias veces, se conserva la última, que es la previsión más reciente antes del amanecer. La línea de estado indica “Previsión congelada para la noche del …”.

Por la mañana. El campo “Noche del” aparece ya con la fecha de la noche recién terminada (antes de las 14:00 propone ayer; después, hoy). Elige lo observado (Niebla si la visibilidad fue inferior a 1 km; Bruma o neblina si hubo reducción notable pero superior a 1 km; Nada) y pulsa “Guardar observación”. La observación se empareja con la previsión que se congeló la víspera para esa fecha. No importa que a esa hora ya exista una previsión nueva para mañana: no se usa.

Si esa noche no calculaste. No hay previsión congelada para esa fecha. La observación se guarda igualmente (aparece como “pendiente” en la columna posterior) y actualiza el prior climatológico, que solo necesita saber si hubo niebla o no; pero no modifica los pesos de los modelos, porque no hay predicción con la que compararla. Si más tarde ese mismo día calculas antes de que el amanecer cambie de fecha, la fila se completa automáticamente.

Rutina mínima: por la tarde o noche, abrir la página y pulsar Calcular en la pestaña 2 (dos segundos). Por la mañana, elegir lo observado y Guardar. Nada más.

Con cada observación ocurren dos cosas. El prior Beta se actualiza (a += y, b += 1 − y, con y = 1, 0.5 o 0), de modo que la tasa base deja de ser el 12 % genérico y pasa a ser tu frecuencia local. Y la log‑verosimilitud de cada modelo acumula log P_m(y): un modelo que daba 80 % y hubo niebla suma log 0.8; uno que daba 10 % suma log 0.1. Los pesos w_m se recalculan como exp(0.7 · log‑verosimilitud) normalizado.

Debajo de la tabla del registro, “Lecciones de tu registro” resume tus umbrales locales a partir de las noches con rasgos congelados: con qué ΔT y qué viento previstos ha llegado a haber niebla o bruma en tu sitio, con cuánta nubosidad media y con qué visibilidad prevista, y cuál fue la noche sin nada con menor ΔT. Es la parte del registro que más deprisa cambia lo que haces en el campo.

Orientación sobre cantidad: con 10 noches los pesos ya empiezan a separarse; con 40 o 50 tienen significado; con más de 100 merece la pena pasar a una regresión logística sobre las variables crudas.

7. Datos y privacidad: dónde se guarda el registro

Todo el registro (observaciones, probabilidades, selección de modelos, idioma) se guarda con localStorage en el navegador desde el que se usa la página. Nada se envía a ningún servidor; GitHub solo sirve el HTML estático y no recibe ni conserva tus datos. Implicaciones concretas:

SituaciónQué pasa con el registro
Misma URL, mismo navegador, mismo dispositivoPersiste indefinidamente, aunque cierres el navegador o hagas push de una nueva versión del HTML.
Otro navegador u otro dispositivoNo está: localStorage es por navegador y por origen. Usa Exportar e Importar JSON.
Abrir el archivo en local (file://) y también desde Pages (https://)Son orígenes distintos; cada uno tiene su propio registro. Exporta de uno e importa en el otro.
Borrar datos de navegación o “datos de sitios”Se pierde. Exporta el JSON de vez en cuando y guárdalo en el propio repositorio, por ejemplo.
Modo incógnitoSe borra al cerrar la ventana.
Otras páginas en el mismo origen (usuario.github.io)Comparten el espacio de localStorage; las claves de datos usadas aquí empiezan por niebla_ (niebla_bayes, niebla_models, niebla_lang) para no colisionar. La única excepción es pn-lang, la preferencia de idioma compartida a propósito con las demás páginas del sitio.
Recomendación: tras cada sesión de anotaciones, pulsa “Exportar JSON” y sube el archivo al repositorio. Así el historial queda versionado y reimportable en cualquier dispositivo.

8. Interpretación y buenas prácticas

Señal fuerte de niebla de radiación: ΔT previsto por debajo de 1 °C a partir de medianoche, viento entre 2 y 8 km/h, nubes por debajo del 25 %, presión alta y en ascenso, y visibilidad modelada menor de 3 km (esta última, la variable menos fiable del lote: apoya, no arbitra). Si además varios modelos coinciden (desacuerdo < 10 pp), la probabilidad es alta.

Señal de niebla de advección (costa): punto de rocío del aire uno o dos grados por encima de la SST, viento moderado del mar, humedad alta. Puede darse con cielo nublado y viento de 15 o 20 km/h; en esos casos la pestaña 1 en modo interior la infravalora.

Cuándo desconfiar: valles estrechos, zonas con suelo muy húmedo tras lluvia reciente o embalses y ríos, donde la niebla local se forma con ΔT previsto de 2 o 3 °C. Los modelos no resuelven esa escala; tu registro sí la captura, de ahí la importancia del prior local.

Calibración: la pestaña 2 dibuja ahora este diagrama de fiabilidad por ti, en la sección «Calibración» junto a la tabla de pesos: agrupa las filas del registro por posterior congelado (0–25 %, 25–50 %, 50–75 %, 75–100 %) y pinta cada grupo como un punto (posterior medio, frecuencia real de niebla) sobre la diagonal de calibración perfecta, con área proporcional al número de noches. La lectura sigue siendo la misma que harías a mano: si las frecuencias reales son sistemáticamente más extremas que el posterior, sube γ; si son menos extremas, bájalo; si los puntos se pegan a la diagonal, deja γ como está. La herramienta orienta a partir de unas 10 noches; la lectura es fiable a partir de 30.

9. Ajustes avanzados (editar el HTML)

Todas las constantes están al principio de la sección de la pestaña 2 en niebla.html:

const PI0=0.12, A0=1.2, B0=8.8  // prior Beta inicial (media 0.12)
const LAMBDA=0.7                // tempering de los pesos
const TH=70, KAP=11             // logística p = σ((s − TH)/KAP)
const RECAL_N=12, RECAL_TAU=6   // noches mínimas y anchura del prior de Platt
const TIMEOUT=12000             // ms por modelo (los ensembles usan +8 s)

En el archivo van todas en una sola línea const; aquí se abren para poder comentarlas.

El parámetro γ se cambia desde la propia interfaz. Los pesos w_m y el consenso se calculan en run2(); la contracción hacia la climatología es la línea logit P = logit π + γ·(logit p̄ − logit π).

Los pesos del índice están en la función score(), común a ambas pestañas. Para añadir un modelo, amplía el array MODELS con el identificador de Open‑Meteo (por ejemplo jma_seamless). Las coordenadas por defecto están en los atributos value de los campos de latitud y longitud, y de latitud B y longitud B para el sitio de comparación. La ventana fotográfica se recorta en winRange() y sus umbrales viajan en las llamadas a winTxt() (50 y 75 en la pestaña 1; 0.25 y 0.5 en la pestaña 2). La tabla de próximas mañanas está en morn(), el desglose en brk1() y la calculadora de contraste en renderK().

10. Problemas frecuentes

SíntomaCausa y solución
“Ningún modelo respondió a tiempo”Open‑Meteo saturado o conexión lenta. Reintenta, reduce la selección o sube TIMEOUT.
Un modelo siempre en “timeout”Desmárcalo; la fusión funciona con los que respondan.
“sin SST, advección desactivada”El punto está tierra adentro para la API marina o la petición falló. En interior es lo esperado; en costa, prueba a mover el punto unos cientos de metros hacia el mar.
“Vis km” en blanco para algún modeloEse modelo no publica visibilidad (ECMWF, por ejemplo). El índice se calcula sin ese término.
El registro desaparecióCambio de navegador, de dispositivo, de origen (file → https) o borrado de datos. Importa el JSON exportado.
“Usar mi posición” no hace nadaPermiso denegado o página servida sin HTTPS. Escribe las coordenadas a mano.

User manual

Fog for photography: physical index and multi‑model Bayesian fusion.

1. What it is and what it is not

A self‑contained HTML page that queries the public Open‑Meteo API and estimates the risk of fog or mist over the next hours and in the next sunrise window, meant to help decide whether a photo outing is worth it. It is not a boundary‑layer model and does not replace official warnings: it is a favourability tool, with a second Bayesian layer that learns from your local observations.

Two tabs. The first, “Fog index”, uses a single numerical model and shows the hourly index with all the physics visible. The second, “Bayesian fusion”, downloads several models in parallel, turns each one into a probability and combines them into a posterior, weighting each model by how well it has scored in your log.

2. Setup

Nothing to install. Three ways to use it:

Local. Save niebla.html and manual-niebla.html in a folder and open niebla.html in the browser. Double click works (file:// origin).

GitHub Pages. Push both files to a repository, enable Pages under Settings → Pages (main branch, root folder) and visit https://user.github.io/repo/. The file is named niebla.html so it is the entry page.

Mobile. Open the Pages URL on the phone and add it to the home screen. “Use my location” asks for geolocation permission; it works on Pages because the site is served over HTTPS.

Requirements: an Internet connection (the forecast is downloaded on each compute) and a modern browser. Two fonts are loaded from Google Fonts; without network the system fonts are used.

3. Common controls

ControlFunction
Latitude, LongitudePoint for which the forecast is requested. Type them (decimal, west negative) or fill them with “Use my location”.
SettingCoastal enables the advection fog term and downloads sea surface temperature (SST). Inland disables it and saves one request.
Azimuth towards the seaShown only in Coastal mode. Bearing in degrees from the point towards open sea. It does not enter the index: it lets the tool label each hour as “onshore” or “offshore” wind, counting as onshore any direction within 60° of the azimuth. Leave it empty if you do not know it.
ES / ENSwitches the interface and manual language. The choice is remembered.
ManualOpens this document.

4. Tab 1: fog index

Model selector

“Best available” lets Open‑Meteo pick the highest‑resolution model for the point (in western Europe usually ICON‑EU or AROME). The others force a specific model; useful for comparison.

Cards

Next 6 hours: maximum index in that interval and when. Sunrise: maximum in the window from 2.5 h before to 1.5 h after sunrise, when radiation fog is fully developed and when you want to be on site. Minimum dew point depression: the lowest forecast ΔT = T − Td tonight, with T, Td, wind, clouds, SST and pressure at that hour. It is the most direct physical datum: if it does not drop below 1 °C, radiation fog is unlikely.

Photographic window

Inside the sunrise card, the “Photographic window” line answers the practical question: from what time to what time is there anything to photograph. It finds the index peak between sunrise −4 h and +6 h and clips the continuous stretch that stays above 50 points, interpolating between hours at both edges, so it returns an interval with minutes and a duration. If the peak reaches 75 the label is “full fog”; between 50 and 74, “mist only”; if no hour clears 50, there is no fog to chase. It also warns when the stretch lasts under an hour and when the peak falls more than half an hour after sunrise. The same card gives wind direction (and onshore or offshore, once you set the azimuth), links to the natural-light page for the golden hour, and reminds you that the stretch after sunrise rests on the heuristic 0.85 factor, the least firm part of the calculation.

Comparing two sites (A or B)

The “Compare with another site” button opens a second set of latitude, longitude and setting, and downloads site B with the same model and the same pipeline as A. The “A or B” section puts both next-sunrise cards side by side, draws both index curves and gives a verdict: go to A, go to B, or a practical tie when the difference is under 8 points, in which case access, composition and departure time decide. The comparison lives only in this tab: the Bayesian fusion and the observation log still belong to a single site, the coordinates at the top, because mixing two sites would spoil the learning.

Next mornings

One row per sunrise, up to seven days, with the peak index inside the −2.5 h/+1.5 h window, the verdict, the minimum dew point depression of that night, and the wind, mid and high cloud and visibility of the peak hour. The last column is confidence by lead time: the first two sunrises are the actual forecast, the third and fourth are indicative and from the fifth on it is a trend, not a forecast. Below it, one sentence names the best morning of the week, or says none clears 50. It is the only view that reaches seven days; the strip, the charts and the hourly table still cover 48 hours.

Hourly strip

One bar per hour, 48 hours. Height = index. Grey background = night. Red hour = sunrise. Amber = mist possible (50 to 74), reddish = fog likely (≥ 75). Hover to see the active signals. The hours falling inside the photographic window are outlined in amber.

What the index is made of

One stacked bar per hour with the points each term contributes, in the order they are computed; rain is drawn downwards because it subtracts. The black tick marks the final index, with the daytime factor already applied and saturated at 100, and a grey mark on top flags the hours whose raw sum exceeded 100. It shows which term limits each hour: if the bar falls short because of the cloud segment, the brake is mid and high cloud, not humidity; if the ΔT segment is tall and the total still low, the brake is the wind. The amber outline marks the photographic window.

Convergence chart

T and Td in °C on the left axis; wind in km/h on the right. Pink bands mark hours with ΔT < 2 °C (stronger below 1 °C). The dashed red line is sunrise. The picture you are looking for: T and Td converging overnight, wind below 10 km/h and a cloud‑free grey background. A purple bar along the bottom marks the hours with forecast visibility under 2 km, more saturated below 1 km.

What you will see: contrast, distance and focal length

A contrast-by-visibility calculator, to know which framing survives the fog you expect. By the Koschmieder law a dark object against the sky keeps a contrast C/C₀ = exp(−3.912·d/V), so 20 % contrast sits at 0.41·V and 5 % at 0.77·V. The two sliders sweep visibility from 0.2 to 10 km and subject distance from 20 m to 3 km, and the selector covers 28 to 135 mm. The cards give the residual contrast with its reading (volume and texture, flat, barely hinted, gone) and the horizontal field, 36·d/f on 24×36: at 200 m a 43 mm covers 167 m and a 135 mm covers 53 m. Below them, the full curve and a table at 50, 150, 500 and 1000 m. Visibility starts at whatever the model gives for the sunrise peak, or at a scenario assumed from the index when that model publishes none; “Back to the forecast” undoes any manual tweak.

Hourly table

All variables used plus wind direction (labelled onshore or offshore once you set the azimuth), low clouds, SST and pressure. “Vis km” is the visibility forecast by the model itself: it is its most direct fog diagnostic, but also the least reliable variable in Open‑Meteo, so read it as a scenario rather than a measurement. Below 3 km it backs the other signals; on its own it does not decide, which is why it is worth at most 20 points against the 40 of ΔT.

Index formula

TermPointsRationale
ΔT = T − Td40 if ≤ 0.5 °C; linear to 0 at 4 °CSaturation. Necessary condition.
10 m wind<2: 14 · 2–8: 20 · 8–15: 8 · 15–20: 3 · >20: 0Radiation fog: some turbulent mixing deepens it; dead calm gives dew; strong wind prevents it.
Cloud above the layer (mid and high)<25 %: 20 · 25–60 %: 8 · >60 %: 0 (halved by day)Clear sky above = radiative cooling of the ground. Uses max(mid, 0.6·high), not the total: a model’s low cloud is often the fog itself and must not penalise. It counts as stratus (and penalises) only if forecast visibility is good.
Model visibility<1 km: 20 · <3 km: 10 · <6 km: 4 · missing: 5Direct model diagnostic. Models that do not publish it get a neutral value so they are not systematically low.
Persistence+2 per preceding consecutive night hour with ΔT < 1.5 °C and wind < 12 km/h, up to +8Fog needs hours of cooling: sustained saturation since midnight is worth more than a single hour at 06:00.
RH ≥ 97 %+10Redundant with ΔT but robust to rounding.
Rain > 0.5 mm−15Active precipitation usually comes with cloud and wind.
Advection (coastal)up to +30 if Td − SST > 0 and wind 8–30 km/hMoist air over colder sea cools to saturation. Needs neither calm nor clear sky.
Daytime× 0.65; × 0.85 in the two hours after sunriseSolar radiation dissipates the layer, but slowly; right after sunrise fog usually lingers and that is the best photographic moment.

5. Tab 2: Bayesian fusion

Model selection

Each checkbox is a model. They are downloaded in parallel with a 12 s limit each; those that do not answer in time are dropped and marked “timeout”. After each compute the response time of each model is shown. If one is consistently slow on your connection, untick it; the selection is remembered. Default: ICON, GFS, AROME/ARPEGE, ECMWF and UKMO.

How it combines: consensus and shrinkage

First a model consensus is formed as a weighted mean in log‑odds: logit p̄ = Σ w_m · logit p_m / Σ w_m. This mean is guaranteed to stay inside the envelope: never above the highest model nor below the lowest. The posterior then shrinks that consensus towards local climatology: logit P = logit π + γ · (logit p̄ − logit π). The result always lies between your local rate π and the consensus p̄.

Parameter γ

How much you trust the models versus climatology, between 0.1 and 1 (default 0.7). With γ = 1 the posterior is the pure consensus; low values pull it towards the historical frequency in your log. Keeping γ below 1 is sensible while the index‑to‑probability mapping is untested against your observations; the automatic recalibration (below) gradually replaces this manual tuning as nights accumulate.

Ensemble sources (EPS/ENS)

Besides deterministic models there are ensemble sources: the same model run 30 to 50 times with perturbations. For these the probability does not come from the logistic but from the members themselves (mean of member probabilities), reflecting the real atmospheric uncertainty that night. ICON EPS is on by default; GFS ENS and ECMWF ENS are heavier and unticked.

Automatic recalibration

With 12 or more logged nights, the app fits a Platt correction q = σ(a·logit P + b) on (frozen posterior, observed outcome) pairs, with prior a ≈ 1, b ≈ 0 so few nights cannot distort it. It corrects systematic posterior bias; when active, the status line shows "recalibrated (n, a, b)".

Cards

Posterior for the next 6 hours and for the sunrise window, with the min to max range across models and each model’s individual probability. The third card gives the standard deviation across models at sunrise: high agreement (< 10 pp), moderate, or disagreement. A 40 % posterior with high agreement is a more useful forecast than 55 % with disagreement. The sunrise card also carries its own photographic window, measured on the posterior with a 25 % threshold (“full fog” from 50 %), and, for ensemble sources, the p10–p90 band and how many members give fog.

Chart

One thin line per model, a grey band for the range and a thick black line for the posterior. Vertical axis in %.

Tables

“Sunrise state per model” shows, for each model, its maximum probability in the window and the forecast physical state at that hour. “Bayesian weights and prior” shows w_m, the Brier score, the hit rate (with the number of frozen nights in brackets), the cumulative log‑likelihood and the current Beta prior. The log‑likelihood is what sets the weight; Brier and hits are the same information in readable units.

6. Training: the observation log

Learning means comparing what each model predicted with what you saw. For the comparison to be honest, the prediction must be fixed before the outcome is known. The tool does that by itself:

Automatic freezing. Every time you press “Compute” in tab 2, each model’s probability for the next sunrise window is stored under the date of that night (a night is identified by the date of its evening, i.e. the day before the sunrise). If you compute several times, the last one is kept, being the most recent forecast before sunrise. The status line reads “Forecast frozen for the night of …”.

In the morning. The “Night of” field already shows the date of the night that has just ended (before 14:00 it proposes yesterday; after, today). Choose what you observed (Fog if visibility was under 1 km; Mist or haze if there was a noticeable reduction above 1 km; Nothing) and press “Save observation”. The observation is paired with the forecast frozen the evening before for that date. It does not matter that a new forecast for tomorrow already exists at that time: it is not used.

If you did not compute that night. There is no frozen forecast for that date. The observation is saved anyway (shown as “pending” in the posterior column) and updates the climatological prior, which only needs to know whether fog occurred; but it does not change the model weights, since there is no prediction to compare against. If later the same day you compute before the sunrise date rolls over, the row is completed automatically.

Minimal routine: in the evening, open the page and press Compute in tab 2 (two seconds). In the morning, choose what you observed and Save. Nothing else.

Each observation does two things. The Beta prior is updated (a += y, b += 1 − y, with y = 1, 0.5 or 0), so the base rate stops being the generic 12 % and becomes your local frequency. And each model’s log‑likelihood accumulates log P_m(y): a model that gave 80 % when fog occurred adds log 0.8; one that gave 10 % adds log 0.1. Weights w_m are recomputed as normalized exp(0.7 · log‑likelihood).

Under the log table, “Lessons from your log” summarises your local thresholds from the nights with frozen features: with what forecast ΔT and wind fog or mist has actually shown up at your site, with how much mid cloud and what forecast visibility, and which fog-free night had the lowest ΔT. It is the part of the log that changes what you do in the field the fastest.

How many: with 10 nights the weights start to separate; with 40 or 50 they mean something; beyond 100 it is worth moving to a logistic regression on raw variables.

7. Data and privacy: where the log is stored

The whole log (observations, probabilities, model selection, language) is stored with localStorage in the browser you use the page from. Nothing is sent to any server; GitHub only serves the static HTML and neither receives nor keeps your data. Concrete implications:

SituationWhat happens to the log
Same URL, same browser, same devicePersists indefinitely, even if you close the browser or push a new version of the HTML.
Another browser or deviceNot there: localStorage is per browser and per origin. Use Export and Import JSON.
Opening the file locally (file://) and also from Pages (https://)Different origins; each has its own log. Export from one and import into the other.
Clearing browsing data or “site data”Lost. Export the JSON from time to time and keep it in the repository itself, for instance.
Private / incognito modeErased when the window closes.
Other pages on the same origin (user.github.io)Share the localStorage space; the data keys used here start with niebla_ (niebla_bayes, niebla_models, niebla_lang) to avoid collisions. The one exception is pn-lang, the language preference deliberately shared with the rest of the site.
Recommendation: after each logging session press “Export JSON” and commit the file to the repository. The history stays versioned and can be re‑imported on any device.

8. Interpretation and good practice

Strong radiation‑fog signal: forecast ΔT below 1 °C from midnight on, wind between 2 and 8 km/h, clouds under 25 %, high and rising pressure, model visibility under 3 km (that last one being the least reliable variable of the set: it backs the others, it does not arbitrate). If several models agree (spread < 10 pp), probability is high.

Advection‑fog signal (coast): air dew point one or two degrees above SST, moderate onshore wind, high humidity. It can occur with overcast skies and 15 to 20 km/h wind; in such cases tab 1 in inland mode underestimates it.

When to be sceptical: narrow valleys, very wet soils after recent rain, reservoirs and rivers, where local fog forms with a forecast ΔT of 2 or 3 °C. Models do not resolve that scale; your log does, hence the importance of the local prior.

Calibration: tab 2 now draws this reliability diagram for you, in the “Calibration” section next to the weights table: it groups the log rows by frozen posterior (0–25 %, 25–50 %, 50–75 %, 75–100 %) and plots each group as a point (mean posterior, actual fog frequency) against the perfect-calibration diagonal, with area proportional to the number of nights. The reading is still the one you would do by hand: if actual frequencies are systematically more extreme than the posterior, raise γ; if less extreme, lower it; if the points hug the diagonal, leave γ as it is. The tool gives guidance from about 10 nights; the reading is reliable from 30.

9. Advanced settings (edit the HTML)

All constants sit at the top of the tab‑2 section in niebla.html:

const PI0=0.12, A0=1.2, B0=8.8  // initial Beta prior (mean 0.12)
const LAMBDA=0.7                // weight tempering
const TH=70, KAP=11             // logistic p = σ((s − TH)/KAP)
const RECAL_N=12, RECAL_TAU=6   // minimum nights and width of the Platt prior
const TIMEOUT=12000             // ms per model (ensembles use +8 s)

In the file they all sit on a single const line; they are split here so each can be commented.

γ is changed from the interface itself. Weights w_m and the consensus are computed in run2(); the shrinkage towards climatology is the line logit P = logit π + γ·(logit p̄ − logit π).

Index weights live in score(), shared by both tabs. To add a model, extend the MODELS array with the Open‑Meteo identifier (e.g. jma_seamless). Default coordinates are the value attributes of the latitude and longitude fields, and of latitude B and longitude B for the comparison site. The photographic window is clipped in winRange() and its thresholds travel in the calls to winTxt() (50 and 75 in tab 1; 0.25 and 0.5 in tab 2). The next-mornings table is in morn(), the breakdown in brk1() and the contrast calculator in renderK().

10. Troubleshooting

SymptomCause and fix
“No model answered in time”Open‑Meteo overloaded or slow connection. Retry, reduce the selection or raise TIMEOUT.
A model always shows “timeout”Untick it; fusion works with whatever responds.
“no SST, advection disabled”The point is inland for the marine API or the request failed. Expected inland; on the coast, try moving the point a few hundred metres seaward.
“Vis km” blank for some modelThat model does not publish visibility (ECMWF, for instance). The index is computed without that term.
The log disappearedDifferent browser, device, origin (file → https) or cleared data. Import the exported JSON.
“Use my location” does nothingPermission denied or page not served over HTTPS. Type the coordinates.