How Bowcast works
The physics of a
rainbow forecast
A rainbow is geometry, physics, and meteorology. This is how Bowcast turns numerical weather forecasts into an estimated hourly chance that the ingredients will align.
01 · Optics
Why a rainbow is always 42 degrees
A rainbow isn't an object, but a direction. It is the set of angles at which drops of rain throw sunlight back at you most brightly.
A ray of sunlight enters a spherical drop, then refracts and reflects once off the inner wall, and refracts again on the way out. If it enters at an angle of incidence \(i\), the total angle it is turned through is
\[ D(i) = 180^\circ + 2i - 4r, \qquad \sin i = n \sin r, \]
where \(r\) is the refraction angle inside the drop and the refractive index of water, \(n\), is \(1.333\). Rays strike the drop at every incident angle from 0 to 90 degrees, so they leave across a spread of deviations. Rainbows appear where that spread bunches up.
"Bunching up" is precise: light intensity piles up where the deviation angle \(D\) is stationary, meaning many rays leave almost parallel. Setting the derivative of the deviation with respect to the incident angle to 0, then using high-school physics, Snell's law, gives the entry angle of the minimum-deviation ray,
\[ \frac{dD}{di} = 2 - 4\frac{dr}{di} = 0 \;\Longrightarrow\; \cos^2 i = \frac{n^2 - 1}{3}, \]
which for water is \(i \approx 59.4^\circ\), giving a minimum deviation of \(138^\circ\). When looking at it, though, we look back along the incoming sunlight, so the bright ring sits at
\[ 180^\circ - 138^\circ = 42^\circ \]
from the point directly opposite the sun. This is a caustic. Think of it this way: imagine rolling marbles down a slope. Normally they scatter at the bottom with little pattern. Now put a hole at the bottom and they pile in. The same physics gathers these twice-refracted rays together into a rainbow instead of scattering them apart.
Different colors appear for a related reason. Water bends violet more than red, with \(n\) larger for violet (\(1.343\)) than red (\(1.331\)), so the caustic lands at \(40.6^\circ\) for violet and \(42.4^\circ\) for red. Red rides the outer rim, and the whole bow is under two degrees thick. A second, dimmer bow at \(51^\circ\) comes from two internal reflections, with the colors reversed. Between the two lies Alexander's dark band, spanning \(42.4^\circ\) to \(51^\circ\). Bowcast scores the primary bow, not the secondary.
The consequence the forecast actually uses
Because the bright ring is \(42^\circ\) from the antisolar point, and the antisolar point sits exactly opposite the sun at elevation \(-h_\odot\), the top of the bow is at elevation \(42^\circ - h_\odot\). Raise the sun and the bow sinks. When the sun climbs above \(42^\circ\), the entire arc is below the horizon and there is nothing to see.
The first thing Bowcast computes for every hour is the sun's elevation and azimuth from the NOAA solar position algorithm. If the sun is down or above \(42^\circ\), the hour scores exactly zero before any weather is even considered, meaning geometry is a hard gate. That leads to the next part.
02 · The model
From geometry to a number
Geometry says whether a rainbow is possible, but weather decides if the ingredients are present in that patch of sky at that moment. Bowcast scores each necessary condition between 0 and 1, then multiplies them. If any one of those conditions is zero, the score is zero.
\[ \begin{aligned} \text{score} = 100 &\cdot \underbrace{f_{\text{sun}}}_{\text{direct light}} \cdot \underbrace{f_{\text{rain}}}_{\text{drops present}} \cdot \underbrace{f_{\text{elev}}}_{\text{bow above ground}} \\ &\cdot f_{\text{conv}} \cdot f_{\text{align}} \cdot f_{\text{wind}} \cdot f_{\text{temp}} \cdot f_{\text{conf}} . \end{aligned} \]
The Conditions score /100 measures how closely one forecast matches a rainbow-producing pattern. It is not a percentage or an observed frequency. The first three factors represent direct light, liquid drops, and geometry. The remaining modifiers adjust for convection, alignment, wind, temperature, and forecast confidence.
Published studies inform which ingredients matter and their broad relationship to rainbow occurrence. For example, Liu et al. (2023) found that about 90% of observed rainbows in ZhaoSu, China, occurred during the hour after rainfall. The model has not yet been calibrated against a large, international, representative set of positive and negative observations. That is why Bowcast invites anonymous yes-or-no sighting reports: to build the evidence needed for future calibration.
\(f_{\text{sun}}\): is the disc actually shining on the drops
From the forecast's direct-beam sunshine duration, the fraction of the hour with real sun, raised to a concave power:
\[ f_{\text{sun}} = \left(\tfrac{\text{sunshine seconds}}{3600}\right)^{0.4}. \]
The exponent is a Bowcast heuristic reflecting a simple idea: a rainbow needs a sunlit moment, not a fully sunny hour. Ten minutes of sunlight is \(0.17\) of an hour and produces \(f_{\text{sun}} = 0.49\). When sunshine duration is missing, a heuristic layered-cloud fallback stands in, \(1 - 0.9\,c_{\text{low}} - 0.5\,c_{\text{mid}} - 0.15\,c_{\text{high}}\). Low cloud is weighted more heavily because it is more likely to block the solar disc at the forecast point.
\(f_{\text{rain}}\): liquid drops in the antisolar sky, just after the rain
In the ZhaoSu, China observations studied by Liu et al. (2023), about 90% of observed rainbows occurred during the hour after rainfall. That regional result supports giving clearing showers extra attention, but it is not a universal rate. Bowcast expresses the idea with a temporal maximum:
\[ f_{\text{rain}} = \max\big(1.0\,q_{-1},\; 0.9\,q_{0},\; 0.6\,q_{+1}\big), \]
Here \(q_{-1}\) is the previous hour clearing out, \(q_0\) is the current hour, and \(q_{+1}\) is the next hour approaching, all relative to the hour being scored by Bowcast. Each \(q\) scores the rain in a forecast hour using two things. How much rain falls in mm/h and what type of rain it is. Bowcast's drop-quality curve favours light-to-moderate rain, while the type weighting favours convective showers over steady rain and drizzle (following the physical patterns discussed by Businger 2021). The exact cutoffs, plateau, and type weights are Bowcast heuristics, not thresholds validated by those papers.
\(f_{\text{elev}}\) and the small refinements
Lower sun means a more elevated arc standing above the horizon, so Bowcast uses \(f_{\text{elev}} = 0.6 + 0.4(1 - h_\odot/42)\). It then applies the following modifiers: convective energy, wind alignment, precipitation confidence, strong wind, and near-freezing rain. The physical rationale is research-informed, but values such as \(1.15\), \(0.12\), and the taper shapes are model choices that require calibration.
Hard gates → 0 score
- Not daylight, or the sun is outside \((0^\circ, 42^\circ]\).
- Frozen precipitation. Ice crystals do not produce bows.
- Total cloud cover > 96%. This gate is informed by the global photographed-rainbow analysis in Carlson et al. (2022). Treating the study's relationship as a hard operational cutoff is an unvalidated model choice.
- No rain signal at all.
03 · Uncertainty
From a score to an ensemble estimate
The Conditions score /100 asks how well a forecast matches the pattern, while the headline Estimated chance summarizes uncertainty across an ensemble. It is a weighted model estimate that is not yet a probability calibrated against observed rainbow frequencies. If ensemble feeds are unavailable, Bowcast shows the deterministic Conditions score /100 instead.
The ICON ensemble provides 40 variations of the same forecast. Each one is called a member and represents a possible weather outcome, with Bowcast checking whether the sun is low enough, precipitation appears in or near the hour, the sky is not almost entirely overcast, and direct sunlight is forecast or inferred. Each member then contributes a value between 0 and 1: 0 when a required ingredient is missing, and up to 1 as direct sunlight strengthens. Bowcast averages those values to produce the Estimated chance:
\[ \widehat{p}_i(\%) = \frac{100}{N}\sum_{m=1}^{N} w_{m,i}, \qquad w_{m,i} = \mathbb{1}[\text{rain}_{m,i}]\cdot s_{m,i}. \]
Per member, rather than multiplied marginals. The quantity we want is \(E[\mathbb{1}_{\text{rain}}\,s_{\text{sun}}]\) over the joint distribution. Each member carries its own internal rain–sun correlation, so averaging the product within each member estimates it directly. Multiplying the ensemble mean \(P(\text{rain})\cdot P(\text{sun})\) instead is biased whenever rainfall and sunshine correlate. They correlate strongly because the same clearing shower can bring both the raindrops and the sunbreak. \(E[XY] \neq E[X]\,E[Y]\) unless \(X\) and \(Y\) are independent, which they are not here.
Occurrence ingredients rather than rain intensity. The member weight \(w\) is the sunlight term gated on rain, rather than a product of rain rate and sunlight. This prevents heavier rain from automatically producing a higher Estimated chance. Rain intensity still contributes to the separate Conditions score /100 through \(f_{\text{rain}}\).
The sun term uses each member's direct normal irradiance, the forecast solar beam in W/m², with Bowcast's heuristic ramp \(s = \mathrm{clamp}\!\big((\text{DNI} - 80)/240,\,0,\,1\big)\). Direct irradiance represents a sunbreak more directly than total cloud fraction. In a 2024 reanalysis comparison, this change raised estimates for Honolulu (in Hawaiʻi, which Businger (2021) describes as the rainbow capital of the world) much more than for Phoenix:
04 · Historical checks
Tests against recorded weather
Bowcast runs a production scoring function over Open-Meteo's historical archive, a reconstruction of past atmospheric conditions. The archive does not have precipitation probability nor rain-versus-showers split, so the checks for those use the production score's default confidence assumption and infer showers from weather codes and CAPE(Convective Available Potential Energy). These checks show whether Bowcast responds sensibly to historical weather or not, but do not establish forecast accuracy because the archive does not record whether a rainbow was actually seen. They are, however, supplemented with retrospective cases of well-documented rainbow events such as the following:
The London double rainbow, 8 September 2022
The famous double rainbow over Buckingham Palace appeared the evening the Queen died. Run the model over that whole week in London and ask which evening it would have flagged. Its daily-peak scores:
A climatology sanity check
A full year of Honolulu reanalysis shows when Bowcast's ingredients often align. The expected late-day and wet-season pattern is a useful check, but not a count of observed rainbows.
Across the reanalysis runs, Honolulu produces model-qualifying conditions on more days than Phoenix (200 versus 29). This agrees directionally with current published climatology.
05 · Right now
From forecast to observation
Everything so far is a forecast. At the current hour, though, Bowcast can do the one thing a forecast cannot: check whether the ingredients are actually in the sky. Two free, keyless observation feeds sit on top of the score, never folded into it, so the backtests above stay honest.
Satellite. Geostationary satellites (EUMETSAT over Europe, Africa, and South America; Himawari over Asia and Oceania) report direct normal irradiance, the real solar beam in W/m², which confirms the sun is genuinely out at a place this minute rather than merely forecast to be. NASA's GOES feed is not integrated upstream yet, so North America and the central Pacific, Hawaii included, fall back to the forecast's sun.
Radar. A global radar mosaic is sampled along the antisolar bearing, the exact direction opposite the sun where the arc would stand. An echo one to fifteen kilometres out means real rain is sitting where the bow would form, the thing a point DNI value cannot place.
When geometry, observed sun, and observed antisolar rain align, the live board marks the ingredients as observed and tells you which way to face. That is a prompt to look, not confirmation that a rainbow is visible.
06 · Honesty
What it deliberately does not do
- Sunlight is a point signal. The score uses forecast sunshine duration with cloud layers as a fallback. The ensemble estimates use each member's forecast DNI, and the live nowcast uses observed DNI where coverage exists. None ray-traces sunlight toward the specific antisolar rain shaft. The radar nowcast narrows the gap by checking the antisolar direction for real rain.
- No drop-size distribution. Numerical weather gives rain rate but does not give droplet radii, so shower-versus-drizzle is proxied from weather codes, as drop size is what separates a vivid bow from a washed-out cloudbow.
- Secondary bows, supernumeraries, fogbows, and reflection bows are ignored. Only the primary bow is accounted for.
- The model is not calibrated at scale internationally. Research informs the ingredients, but Bowcast's weights, curves, and bands have not yet been validated against large, representative sets of positive and negative sighting outcomes. Until then, read the percentage as an Estimated chance from model agreement rather than a proven frequency.
See it run
Everything above is live. On the hosted website, a shared server function runs the forecast and Monte Carlo, then caches the result for 15 minutes. The packaged mobile apps run the same browser-safe core on-device, and the website can fall back to that local path if the server is unavailable.
Bowcast is built by Shams. The model is informed by Carlson et al. 2022, Liu et al. 2023, and Businger 2021.