Skip to main content

High-performance SOLWEIG urban microclimate model (Rust + Python)

Project description

SOLWEIG

Map how hot it feels across a city — pixel by pixel.

SOLWEIG computes Mean Radiant Temperature (Tmrt) and thermal comfort indices (UTCI, PET) for urban environments. Give it a building height model and weather data, and it produces high-resolution maps showing where people experience heat stress — and where trees, shade, and cool surfaces make a difference.

Built on Rust for speed, with optional GPU acceleration. Handles everything from a single city block to an entire district.

Status: Beta (v0.1.0). The API is stabilising. Feedback and bug reports welcome — open an issue.

What can you do with it?

  • Urban planning — Compare street canyon designs, tree planting scenarios, or cool-roof strategies by mapping thermal comfort before and after.
  • Heat risk assessment — Identify the hottest spots in a neighbourhood during a heatwave, hour by hour.
  • Research — Run controlled microclimate experiments at 1 m resolution with full radiation budgets.
  • Climate services — Generate thermal comfort maps for public health warnings or outdoor event planning.

How it works (in brief)

SOLWEIG models the complete radiation budget experienced by a person standing in an urban environment:

  1. Shadows — Which pixels are shaded by buildings and trees at a given sun angle?
  2. Sky View Factor — How much sky can a person see from each point? (More sky = more incoming radiation.)
  3. Surface temperatures — How hot are the ground and surrounding walls?
  4. Radiation balance — Sum shortwave (sun) and longwave (heat) radiation from all directions.
  5. Tmrt — Convert total absorbed radiation into a single "felt temperature" metric.
  6. Thermal comfort — Optionally derive UTCI or PET, which combine Tmrt with air temperature, humidity, and wind.

Quick start

Install

pip install solweig

Minimal example (numpy arrays)

import numpy as np
import solweig
from datetime import datetime

# A flat surface with one 15 m building
dsm = np.full((200, 200), 2.0, dtype=np.float32)
dsm[80:120, 80:120] = 15.0

surface = solweig.SurfaceData(dsm=dsm, pixel_size=1.0)
# SVF is required before calculate(); compute once and reuse
surface.compute_svf()

location = solweig.Location(latitude=48.8, longitude=2.3, utc_offset=1)  # Paris
weather = solweig.Weather(
    datetime=datetime(2025, 7, 15, 14, 0),
    ta=32.0,          # Air temperature (°C)
    rh=40.0,          # Relative humidity (%)
    global_rad=850.0, # Solar radiation (W/m²)
)

result = solweig.calculate(surface, location, weather)

print(f"Sunlit Tmrt: {result.tmrt[result.shadow > 0.5].mean():.0f}°C")
print(f"Shaded Tmrt: {result.tmrt[result.shadow < 0.5].mean():.0f}°C")

calculate*() requires SVF to already be prepared (SurfaceData.prepare(...) or surface.compute_svf()). If you explicitly set use_anisotropic_sky=True, shadow matrices must also already be available.

Real-world workflow (GeoTIFFs + EPW weather)

import solweig

# 1. Load surface — prepare() computes and caches walls/SVF when missing
surface = solweig.SurfaceData.prepare(
    dsm="data/dsm.tif",
    cdsm="data/trees.tif",       # Optional: vegetation canopy heights
    working_dir="cache/",        # Expensive preprocessing cached here
)

# 2. Load weather from an EPW file (standard format from climate databases)
weather_list = solweig.Weather.from_epw(
    "data/weather.epw",
    start="2025-07-01",
    end="2025-07-03",
)
location = solweig.Location.from_epw("data/weather.epw")

# 3. Run — outputs saved as GeoTIFFs, thermal state carried between timesteps
results = solweig.calculate_timeseries(
    surface=surface,
    weather_series=weather_list,
    location=location,
    output_dir="output/",
    outputs=["tmrt", "shadow"],
)

# 4. Post-process thermal comfort (optional, runs on saved Tmrt files)
solweig.compute_utci(
    tmrt_dir="output/",
    weather_series=weather_list,
    output_dir="output_utci/",
)

What you need

Input Required? What it is
DSM Yes Digital Surface Model — a height grid (metres) including buildings. GeoTIFF or numpy array.
Location Yes Latitude, longitude, and UTC offset. Can be extracted from the DSM's CRS or an EPW file.
Weather Yes Air temperature, relative humidity, and global solar radiation. Load from an EPW file or create manually.
CDSM No Canopy heights (trees). Adds vegetation shading.
DEM No Ground elevation. Separates terrain from buildings.
Land cover No Surface type grid (paved, grass, water, etc.). Affects surface temperatures.

What you get

Output Unit Description
Tmrt °C Mean Radiant Temperature — the main output. How much radiation a person absorbs.
Shadow 0–1 Shadow fraction (1 = sunlit, 0 = fully shaded).
UTCI °C Universal Thermal Climate Index — "feels like" temperature combining all factors.
PET °C Physiological Equivalent Temperature — similar to UTCI but with customisable body parameters.
Kdown / Kup W/m² Shortwave radiation (down and reflected up).
Ldown / Lup W/m² Longwave radiation (thermal, down and emitted up).

Don't have an EPW file? Download one

# Download weather data for any location (no API key needed)
epw_path = solweig.download_epw(latitude=37.98, longitude=23.73, output_path="athens.epw")
weather_list = solweig.Weather.from_epw(epw_path)

Demos

Complete working scripts you can run directly:

  • demos/athens-demo.py — Full workflow: rasterise tree vectors, load GeoTIFFs, run a multi-day timeseries, post-process UTCI.
  • demos/solweig_gbg_test.py — Gothenburg: surface preparation with SVF caching, timeseries calculation.

Documentation

QGIS Plugin

SOLWEIG is also available as a QGIS plugin for point-and-click spatial analysis:

  1. PluginsManage and Install Plugins
  2. Settings tab → Check "Show also experimental plugins"
  3. Search for "SOLWEIG"Install Plugin

Citation

Adapted from UMEP by Fredrik Lindberg, Sue Grimmond, and contributors.

If you use SOLWEIG in your research, please cite the original model paper and the UMEP platform:

  1. Lindberg F, Holmer B, Thorsson S (2008) SOLWEIG 1.0 – Modelling spatial variations of 3D radiant fluxes and mean radiant temperature in complex urban settings. International Journal of Biometeorology 52, 697–713 doi:10.1007/s00484-008-0162-7

  2. Lindberg F, Grimmond CSB, Gabey A, Huang B, Kent CW, Sun T, Theeuwes N, Järvi L, Ward H, Capel-Timms I, Chang YY, Jonsson P, Krave N, Liu D, Meyer D, Olofson F, Tan JG, Wästberg D, Xue L, Zhang Z (2018) Urban Multi-scale Environmental Predictor (UMEP) – An integrated tool for city-based climate services. Environmental Modelling and Software 99, 70-87 doi:10.1016/j.envsoft.2017.09.020

Demo data

The Athens demo dataset (demos/data/athens/) uses the following sources:

  • DSM/DEM — Derived from LiDAR data available via the Hellenic Cadastre geoportal
  • Tree vectors (trees.gpkg) — Derived from the Athens Urban Atlas and municipal open data at geodata.gov.gr
  • EPW weather (athens_2023.epw) — Generated using Copernicus Climate Change Service information [2025] via PVGIS. Contains modified Copernicus Climate Change Service information; neither the European Commission nor ECMWF is responsible for any use that may be made of the Copernicus information or data it contains.

License

GNU Affero General Public License v3.0 — see LICENSE.

Project details


Release history Release notifications | RSS feed

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

solweig-0.1.0b42.tar.gz (275.8 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

solweig-0.1.0b42-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (3.6 MB view details)

Uploaded PyPymanylinux: glibc 2.17+ x86-64

solweig-0.1.0b42-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (3.6 MB view details)

Uploaded PyPymanylinux: glibc 2.17+ ARM64

solweig-0.1.0b42-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (3.6 MB view details)

Uploaded PyPymanylinux: glibc 2.17+ ARM64

solweig-0.1.0b42-cp39-abi3-win_amd64.whl (3.4 MB view details)

Uploaded CPython 3.9+Windows x86-64

solweig-0.1.0b42-cp39-abi3-musllinux_1_2_x86_64.whl (3.8 MB view details)

Uploaded CPython 3.9+musllinux: musl 1.2+ x86-64

solweig-0.1.0b42-cp39-abi3-musllinux_1_2_aarch64.whl (3.7 MB view details)

Uploaded CPython 3.9+musllinux: musl 1.2+ ARM64

solweig-0.1.0b42-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (3.6 MB view details)

Uploaded CPython 3.9+manylinux: glibc 2.17+ x86-64

solweig-0.1.0b42-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (3.6 MB view details)

Uploaded CPython 3.9+manylinux: glibc 2.17+ ARM64

solweig-0.1.0b42-cp39-abi3-macosx_11_0_arm64.whl (2.9 MB view details)

Uploaded CPython 3.9+macOS 11.0+ ARM64

solweig-0.1.0b42-cp39-abi3-macosx_10_12_x86_64.whl (3.0 MB view details)

Uploaded CPython 3.9+macOS 10.12+ x86-64

File details

Details for the file solweig-0.1.0b42.tar.gz.

File metadata

  • Download URL: solweig-0.1.0b42.tar.gz
  • Upload date:
  • Size: 275.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for solweig-0.1.0b42.tar.gz
Algorithm Hash digest
SHA256 b872b701c0ed4dafb49c0d1d399b69bb238abd140e57ed42d3cced4e76e13cdb
MD5 97e19ea77e978d6a6a0fa80c74ec590f
BLAKE2b-256 a14aa60a72f1806ef3868ab073043cd40a03db090d5cb4bbc2bae25b305c3cb4

See more details on using hashes here.

Provenance

The following attestation bundles were made for solweig-0.1.0b42.tar.gz:

Publisher: python-publish.yml on UMEP-dev/solweig

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file solweig-0.1.0b42-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for solweig-0.1.0b42-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 0bc7c970d1736c27e263551d24d5ce0d635618564779dc16aea70354d8dac94a
MD5 a5dbcc8eae6a0f6bce427f145462330f
BLAKE2b-256 ae04fbdccdec2bf5afe1f478090b83d7edcee0f36c7ab1fd7475060e3a303e2c

See more details on using hashes here.

Provenance

The following attestation bundles were made for solweig-0.1.0b42-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: python-publish.yml on UMEP-dev/solweig

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file solweig-0.1.0b42-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for solweig-0.1.0b42-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 cc0c57fc659d09ed4cb164846e2de68a512d3396e79ab9f02c2803ac7aec60bd
MD5 6c8510e793adf2ffe41ae5c73bdfc7a3
BLAKE2b-256 f898d6830fa33d56bee00ec3e24bc46d14efbb8a5ea47d943ccd6ae9fa249332

See more details on using hashes here.

Provenance

The following attestation bundles were made for solweig-0.1.0b42-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: python-publish.yml on UMEP-dev/solweig

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file solweig-0.1.0b42-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for solweig-0.1.0b42-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 52f40c8b4ae1c94bde9f54cc8ff8f2dd93b53a0e76ba0fd7b0261635a53b6d1e
MD5 515e161502d8dd9f12c9b68507edc91c
BLAKE2b-256 0c77d9c3fc9fb1a11151aaceb558dd29eafed3ab820768b29c6617f2509c20b3

See more details on using hashes here.

Provenance

The following attestation bundles were made for solweig-0.1.0b42-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: python-publish.yml on UMEP-dev/solweig

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file solweig-0.1.0b42-cp39-abi3-win_amd64.whl.

File metadata

  • Download URL: solweig-0.1.0b42-cp39-abi3-win_amd64.whl
  • Upload date:
  • Size: 3.4 MB
  • Tags: CPython 3.9+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for solweig-0.1.0b42-cp39-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 ff18d15b9c12087074079bc9a4aa546369fda67388879a9cb95a8a5c73c66e4d
MD5 3090deb013d4562389fa12b20f6918e8
BLAKE2b-256 e3cb71762a4706b21740f6ec148e3364da468fff16b564226bed2cf870942765

See more details on using hashes here.

Provenance

The following attestation bundles were made for solweig-0.1.0b42-cp39-abi3-win_amd64.whl:

Publisher: python-publish.yml on UMEP-dev/solweig

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file solweig-0.1.0b42-cp39-abi3-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for solweig-0.1.0b42-cp39-abi3-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 c2e752240442e210594ac2c0fa55bd82d41fed3359c880456bbf3415969f6d70
MD5 55d8ccdadca2ec5e6ec6fe326494938b
BLAKE2b-256 a52e24c4c3c7f13061161fd4f1e61b877c3b5730c1b42213981a177c13fbeada

See more details on using hashes here.

Provenance

The following attestation bundles were made for solweig-0.1.0b42-cp39-abi3-musllinux_1_2_x86_64.whl:

Publisher: python-publish.yml on UMEP-dev/solweig

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file solweig-0.1.0b42-cp39-abi3-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for solweig-0.1.0b42-cp39-abi3-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 74d8b5b6a09e3850f3c21346f8d46fbecfcf20c292e312e8b90276929bb60cdf
MD5 72329fa7dd78d1f806b5e9eb48f54b47
BLAKE2b-256 f3cdee32ef6401795a5f8d0afb4feaa7b2579548b3e1e78037b61b22aede5f40

See more details on using hashes here.

Provenance

The following attestation bundles were made for solweig-0.1.0b42-cp39-abi3-musllinux_1_2_aarch64.whl:

Publisher: python-publish.yml on UMEP-dev/solweig

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file solweig-0.1.0b42-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for solweig-0.1.0b42-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 573950f9b8951aed2dcc1ffa6f0801c56d34f112db8dadba74c64625dcdb7b8f
MD5 6cf05a6e2f64f9936fdfa9c1fc46d213
BLAKE2b-256 c0e7910533dbaf28fd73e2a01706cd023afa2c3f652644b9c4418cbf2d5753a4

See more details on using hashes here.

Provenance

The following attestation bundles were made for solweig-0.1.0b42-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: python-publish.yml on UMEP-dev/solweig

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file solweig-0.1.0b42-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for solweig-0.1.0b42-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 fb8f87ca48d4beb088c7ac6152fb7c2031c1ae0a7002d7abb6ac1da634c29091
MD5 c06ae7e11c0eb9596e700d7102dbe156
BLAKE2b-256 4f0042a545c4ed0c3679ba8b085bdcb81938a54c456acc9481f86d5bbdb04ca1

See more details on using hashes here.

Provenance

The following attestation bundles were made for solweig-0.1.0b42-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: python-publish.yml on UMEP-dev/solweig

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file solweig-0.1.0b42-cp39-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for solweig-0.1.0b42-cp39-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 327fba29fea696d2b91dab99d58eaa377f3c43de815fead568021531b4291674
MD5 6efdca693e1916a581a62e1b08054f72
BLAKE2b-256 509ab542949db0c8266e3c3675fe9bb7bb85a41ed06e14684b5f4b6a3007209f

See more details on using hashes here.

Provenance

The following attestation bundles were made for solweig-0.1.0b42-cp39-abi3-macosx_11_0_arm64.whl:

Publisher: python-publish.yml on UMEP-dev/solweig

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file solweig-0.1.0b42-cp39-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for solweig-0.1.0b42-cp39-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 095c296eaf57090eadaa4173d71d222a030c3e05a797cce29c6bfac2a5e99133
MD5 283c4cd74b5c01e01e4a064a71d1709d
BLAKE2b-256 69ff1295ff5dc67008d0deab2447548b8524c151d8cf763a4235d3db4547a8b5

See more details on using hashes here.

Provenance

The following attestation bundles were made for solweig-0.1.0b42-cp39-abi3-macosx_10_12_x86_64.whl:

Publisher: python-publish.yml on UMEP-dev/solweig

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page