Every number, and where it comes from
This page exists because a mountain forecast that you cannot check is just a confident-looking guess. Below is every data source with its licence, the terms this site operates under, and each formula it applies — including the ones that are approximations, labelled as such.
1 · Sources and licences
Every forecast value on this site originates from a national weather service and is fetched through Open-Meteo, which aggregates their open data. Nothing is scraped. A scheduled job fetches it a few times a day and publishes the processed result here, so your browser never talks to Open-Meteo itself.
Aggregator, ensemble and reanalysis
Required attribution
All of the above is served under CC BY 4.0 (except NOAA's, which is public domain). That licence requires three things: credit the source, link the licence, and state that changes were made. This site does all three, here and in the footer of every page:
Typefaces
2 · Terms this site operates under
Open-Meteo free tier
- Non-commercial use only. No subscriptions, no advertising, nothing sold. If this site ever carried ads or a paywall it would need a paid Open-Meteo plan.
- SMHI asks the same of its open data: use the documented APIs, do not mass-download per location, and do not fetch the same data twice. The station readings are therefore requested once for the whole country per parameter and reused for every mountain and both pages, rather than once per peak.
- Under 10 000 API calls per day. This used to be every visitor’s own problem, because the requests came from each browser. Now a single scheduled job makes them: about 25 a day for the forecast, two more for the daily retraining, and a handful a month for the climatology and the projections. The number no longer grows with the number of visitors.
- No API key, and therefore no key of mine embedded in the page for anyone to lift.
- Attribution required, as above.
The schedule is deliberately frugal. The forecast is rebuilt every three hours — about as often as the high-resolution models update, so more often would just fetch the same numbers twice. The bias model is retrained once a day, the 30-year climatology once a month and the climate projections once a quarter. Your browser asks this site for the result and checks on each visit whether it has changed; an unchanged file costs nothing.
Exactly which requests are made
So you can audit it rather than take my word:
Privacy
- No analytics, no cookies, no fingerprinting, no accounts, no logs — I have no server to log anything with.
- Exactly one external host is contacted from your browser:
opendata-download-metobs.smhi.se, for the live station observations. The forecast itself is served from this site. No analytics, no embeds, no third-party fonts or scripts of any kind — typefaces are self-hosted precisely so that loading this page does not hand your IP address to a font CDN. - Everything remembered is in your own browser: your unit and language choice, the latest SMHI readings and the verification log in
localStorage, and a copy of the site and the last forecast in the service worker’s cache so the page still opens offline. Clearing site data erases all of it. Nothing is ever sent anywhere. - Open-Meteo receives the summit’s coordinates from the scheduled job — a fixed position from a public list. It never sees you, your IP address or your location. SMHI receives no coordinates at all: the station request is for the whole country and the nearest ones are picked in your browser. This app never asks for or uses geolocation.
3 · The pipeline
Six raw model forecasts go in; one elevation-resolved forecast comes out. This runs every three hours in a scheduled GitHub Actions job (pipeline/ in the repository), not in your browser. In order:
- Fetch — surface fields from six models at summit height, pressure-level fields from two, and an ensemble for spread.
- Weight — combine the six into one estimate using weights learned from measured error at this exact point.
- Correct — apply the learned temperature and wind bias correction at the anchor height, if it passed hold-out validation.
- Build the sounding — assemble a vertical profile from pressure-level data.
- Downscale — interpolate to every m band between valley and summit, anchored to the corrected surface estimate.
- Derive — wet bulb, phase, snow line, cloud base, wind chill, drift index.
- Score — turn all of it into two verdicts with named limiting factors.
4 · Combining models
Weighted mean
Scalars are combined with a straight weighted mean over whichever models returned a value for that hour:
- xᵢ
- model i's value for this hour
- wᵢ
- that model's skill weight (below); models with no value drop out of both sums
Wind is a vector, not a number
Averaging wind directions is a classic way to produce nonsense — the mean of 350° and 10° is 180°, exactly backwards. Wind is decomposed into components first:
- V, θ
- wind speed and the direction it blows from, in degrees
- u, v
- eastward and northward components, which average correctly
Skill weights
Each model's weight is a softmax over its measured mean absolute error, gently tilted by a prior that reflects native grid resolution:
- MAEᵢ
- mean absolute temperature error of model i against ERA5-Land over the training window
- pᵢ
- prior, 0.90–1.35, higher for finer native grids
- τ
- temperature of the softmax: a model 0.7 °C worse than the best gets ~1/e of its weight
5 · The sounding, and why not a lapse rate
The usual shortcut for mountain temperature is to subtract a fixed 0.65 °C per 100 m. That is right on average and badly wrong exactly when it matters. On a clear, calm winter night in Jämtland, cold air drains into the valley and the profile inverts: Åre village sits at −18 °C while the summit of Åreskutan is at −6 °C. A fixed lapse rate does not just miss this — it gets the sign backwards, by twelve degrees.
So instead the app requests temperature, humidity, wind and geopotential height at pressure levels hPa from ICON and GFS, giving a genuine vertical profile above the mountain. Heights are averaged across whichever models answered; the profile is sorted by height and interpolated linearly:
- z
- target elevation in metres
- k
- the first sounding level above z
Anchoring
The sounding knows the shape of the atmosphere; the six-model surface ensemble knows the best value at summit height. Both are kept: the offset between them is applied in full at the anchor and decays with distance, so near the mountain you get the ensemble and far above it you get the free atmosphere.
- Tsnd
- temperature interpolated from the sounding
- Tanchor
- skill-weighted, bias-corrected surface ensemble at anchor height
- za
- anchor elevation — the summit height passed to the API
- L
- m decay scale
Wind with height
Near the ground the surface forecast wins — it knows about roughness and the boundary layer. Higher up, the free-atmosphere sounding takes over. Then terrain accelerates the flow towards an exposed summit, which is why a ridge feels twice as windy as the plateau below it.
- Lw
- m blend scale
- Emax
- terrain exposure factor at the summit, 1.34 for Åreskutan (see the mountain table)
- G
- the surface model's own gust ratio, clamped to 1.15–2.30
Precipitation with height
- k
- per kilometre of ascent — forced ascent wrings more water out of the same air
6 · Thermodynamics
Dew point — Magnus-Tetens
- T
- air temperature, °C
- RH
- relative humidity, %
Wet-bulb temperature — Stull (2011)
This is the variable that actually decides whether precipitation reaches you as snow. Air at +2 °C and 40 % humidity has a wet bulb near −1 °C, and it snows — which is why a forecast that places the snow line by air temperature puts it hundreds of metres too low.
Precipitation phase and the snow line
Snow ratio — millimetres of water to centimetres of snow
Ten to one is the folk rule and it is wrong at both ends: warm snow packs dense, and the driest cold smoke sits near −12 °C. A step function of air temperature:
Wind chill — Environment Canada / JAG-TI
- V
- wind speed in km/h at 10 m
Humidex, and one "feels like" number
Cloud base — Espy's rule
Wind loading index
Not an avalanche forecast — only the meteorological half of the question: is there loose snow available, and is the wind strong enough to move it?
- newSnow
- last 6 hours in full, plus a quarter of the last 24
- V
- summit wind, m/s — m/s is roughly where dry loose snow starts moving
7 · The machine learning
All of it trains once a day in the scheduled pipeline, from public data, and is published with the forecast — weights, scores and all — so the learning log on the forecast page shows exactly what was learned and how well it held up.
Training data
Every archived forecast from every model since January 2023 — what each one predicted at the time — against ERA5-Land reanalysis for the same hours and the same point. The pipeline keeps this record and adds to it each day, so the training set grows rather than slides: tens of thousands of hours, where the browser could only ever afford about a thousand. It ends six days ago, because the reanalysis takes that long to catch up.
Standardisation
Ridge regression on the residual
The target is not temperature — it is what the weighted ensemble got wrong. Solved in closed form by Gaussian elimination with partial pivoting; the intercept is not penalised.
- Z
- standardised feature matrix, tens of thousands of rows × 9 columns
- λ
- ridge penalty — keeps the coefficients modest, so one odd month cannot swing them
Features
Nine, each with a physical reason to be there. This is the baseline candidate — the two below see a good deal more:
The contest: trees and a neural network
A straight line through nine features cannot say “the models are too warm on calm, clear nights” or “they miss the lee warming when the westerly is strong” — those are interactions, and the valley cold pool and the summit’s lee side are exactly what a mountain forecast gets wrong. So two heavier models compete with the ridge for each correction: gradient-boosted trees (LightGBM, trained on absolute error, stopped early on a validation block) and a neural network (a multilayer perceptron, two hidden layers of 64 and 32 units, also stopped early).
They see more than the ridge: each model’s own temperature as its departure from the ensemble, the wind direction, and what the forecast was doing in the 24 hours around the hour in question — warming, cooling, a front arriving. The features are built by one function for training and for the live forecast, so a model is never shown numbers in production that it did not see in training.
Every candidate trains on the same older 75 % of the history and is scored on the same newest 25 %. To be used at all it must beat the uncorrected forecast by 0.5 %. The lowest error wins — unless a simpler candidate is within 1 % of it, in which case the simpler one does: a more complicated model has to be clearly better, not marginally lucky. The winner is refitted on all the history before it is used, and the published scores are the ones from before that refit.
Precipitation probability — logistic regression
- features
- √(ensemble precipitation), fraction of models that are wet, humidity, cloud cover
Validation, and the right to switch itself off
The last 25 % of the window is held out as a contiguous block — not a random split, which would leak information across neighbouring hours. Each learned component must beat the baseline it replaces on that block by at least 0.5 %, or it is disabled and the app tells you so on the learning-log card.
Checking against thermometers
Everything above is model output corrected against another model's best estimate of the past. The ground-truth panel on the forecast page closes that loop with actual instruments: SMHI's automatic stations, read live.
Stations are ranked by distance with a penalty for being at a very different height, since a valley station 5 km away says less about a summit than a ridge station 12 km away:
The forecast is then interpolated down the sounding to that station's exact elevation and the hour it reported, and the two are put side by side. Every comparison is appended to a rolling log in your browser — deduplicated by station and hour, capped at entries — so that after a few days of use the app can show you its own measured bias at that peak, against a thermometer rather than a reanalysis grid.
The scorecard, and when a thermometer may train
The pipeline keeps a longer memory than your browser can. Once a day it writes down what the published forecast says at the best-ranked SMHI station’s height for each of the next 168 hours, both with the learned correction and without it, and as the hours pass it scores both against what the station measured. The learning log shows the result by lead day over the last days. It is the only number on the site that answers “how good is this forecast” with an instrument rather than another model.
A station replaces ERA5-Land as the training target only if it stands within km of the summit and within m of its height. Then the summit correction learns from a thermometer instead of a reanalysis grid — temperature and wind; precipitation stays with ERA5-Land. Any other station only keeps score. A thermometer in a valley knows a great deal about that valley’s cold pools and nothing about the summit ridge, and training the summit on it would be teaching the forecast the wrong mountain.
Worth looking up: northern lights and a sea of clouds
Northern lights. For every hour of every night: how likely activity at NOAA’s forecast Kp reaches Åre (a logistic curve, half-way at Kp ), times the share of ensemble members with less than % cloud, times darkness (sun below °, half credit down to °), with up to taken off weak nights under a full moon. The night’s figure is its best hour. NOAA forecasts Kp three days ahead and no further, so the later nights say so instead of guessing. NOAA SWPC data is in the public domain.
Sea of clouds. A daylight hour counts when the summit is dry (humidity under %), at least two bands between and m are saturated (over %), and mid and high cloud together stay under %. A day is marked when or more hours count. It is a heuristic on a 100 m grid, and a cloud sea can sit a hundred metres higher or lower than any model puts it.
Ensemble spread
8 · The zones
The front page tells the week in five parts of Åreskutan rather than one number for the mountain. Each zone is read straight off one of the 100 m bands above — never interpolated a second time — and labelled with a landmark so a reader knows which bit of hill a number belongs to.
One day, one zone
A zone's day is the highest and lowest temperature of that calendar day at that band, the coldest feels-like, the strongest sustained wind and gust (with the direction of the windiest hour), and the total precipitation split into rain and snow by the wet-bulb phase. Cloud is the daylight mean; a zone counts as in cloud when, for more than half of the daylight hours, its humidity is above 92 % or the cloud base sits below it under more than 60 % cover.
The icon
Decided from the zone's own numbers, in this order: thunder risk (CAPE above 700 J/kg in any hour), then precipitation of 0.3 mm or more — snow when at least 70 % of it fell as snow, sleet from 30 %, otherwise rain — then in cloud, then cloud cover: clear under 25 %, partly cloudy under 70 %, cloudy above. The summit and the village can and do get different icons on the same day.
The headline
The sentence at the top picks, at the summit, the coldest day, the windiest day and the day
with most new snow, and in the village the wettest day. The day to aim for is the one with
the lowest of 2 × wind + 4 × precipitation + cloud ÷ 10, plus 15 if the summit is in
cloud. That is a way of pointing at a day, not a score anyone should quote, and it is never
shown as a number.
9 · Constants and the mountain
Read live from the running configuration.
Physical tunables
The mountain
10 · Probabilities and the outlook
Everything behind the odds page.
What counts as what
Each row is a test applied to one member's own day at the chosen elevation.
Calibration
Exactly one figure on that page is calibrated.
Phase, without humidity
Ensemble members do not carry humidity.
10 · Climate projections
Everything behind the winter ahead page: which models, which scenario, and every threshold a number on that page is counted against.
The models
Seven CMIP6 HighResMIP models, daily, 1950–2050, statistically downscaled to 10 km and bias-corrected against ERA5 by Open-Meteo. Historical runs cover 1950–2014; from 2015 the projections follow SSP5-8.5, the only scenario these high-resolution experiments were run under.
Thresholds
Every one of these is a judgement call. They are listed here so the judgement can be argued with rather than inferred.
The snowpack model
The climate data carries snowfall but not snow depth, so season length and every figure involving a 30 cm cover come from a degree-day model written for this site. Precipitation phase is decided at each elevation from the wet-bulb temperature, exactly as in the forecast; what falls as snow is added to a water-equivalent store, and each day melt = 3.5 × max(0, Tmean) millimetres are taken back out. Depth is water equivalent at a settled density of 300 kg/m³.
Why one point
These grid cells are 20–50 km before downscaling — wider than the distance from Åre to Storlien. The massif is read at one point, and elevation is applied afterwards with the same lapse rate the forecast uses. Height is the variable that actually matters here, and it is the one the models can support.
10 · What this is not
- Not a weather station. Every number is a model output, downscaled. No observation from the mountain itself enters the calculation.
- Not validated against summit observations. The reported skill is against reanalysis, which is the best free reference available but not ground truth.
- Coordinates and elevations are approximate summit positions, hand-entered.
- Terrain exposure factors are hand-set, not fitted to anything.
- The forecast degrades with range. Beyond about three days the ensemble spread on the hourly chart is more informative than the line through it.
The source is public: every formula on this page is in
js/physics.js, js/ml.js and js/forecast.js, and
tools/selftest.mjs checks them against known cases offline.
11 · Contact
Wrong forecast, broken chart, a zone that sits at the wrong height, or an exposure factor you think is nonsense — all of it is welcome. There are two ways to reach me.
Bugs and suggestions — the better channel
The source is public, so an issue is easier to act on than an email: it keeps the discussion attached to the code and anyone else hitting the same thing can find it.
The address is not written anywhere in this page's source — only a ciphertext is. The key is derived from the answer below, so answering is what produces the address. It costs you five seconds and costs an address-harvesting crawler more than it is willing to spend.
Proton Mail, so it is end-to-end encrypted if you write from Proton too. I answer when I am not on a mountain, which in winter can take a few days.
If you are reporting a forecast that was wrong
This is the useful kind of bug report, and the hardest to act on without detail. Include:
- Which mountain, and the exact hour — the forecast changes every hour and I cannot reconstruct what you saw without it.
- What the app said and what actually happened — "it said −4 °C and 8 m/s at the summit at 09:00, it was more like −12 °C and blowing hard".
- Roughly when you loaded it, since a forecast made three days out is a different claim from one made that morning.
- Whether the learning log said the correction was active or disabled.
Systematic errors are the interesting ones. If the summit is always too warm, or the wind is always understated at the tree line, that is a fixable bug in the exposure factor or the downscaling — not just weather being weather.