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.0b40.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.0b40-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.0b40-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (3.6 MB view details)

Uploaded PyPymanylinux: glibc 2.17+ ARM64

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

Uploaded PyPymanylinux: glibc 2.17+ ARM64

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

Uploaded CPython 3.9+Windows x86-64

solweig-0.1.0b40-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.0b40-cp39-abi3-musllinux_1_2_aarch64.whl (3.7 MB view details)

Uploaded CPython 3.9+musllinux: musl 1.2+ ARM64

solweig-0.1.0b40-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.0b40-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.0b40-cp39-abi3-macosx_11_0_arm64.whl (2.9 MB view details)

Uploaded CPython 3.9+macOS 11.0+ ARM64

solweig-0.1.0b40-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.0b40.tar.gz.

File metadata

  • Download URL: solweig-0.1.0b40.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.0b40.tar.gz
Algorithm Hash digest
SHA256 48e737f9ae9f2a079c09cf0464ff91a13431677252d3aa45ff24ce653109eaec
MD5 8837d351dc01a0f25a94d3991858e021
BLAKE2b-256 ade6500d59079857e8883b840521c0c7eebee08fd21dc6bf0f5d99ffa55b8ff1

See more details on using hashes here.

Provenance

The following attestation bundles were made for solweig-0.1.0b40.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.0b40-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for solweig-0.1.0b40-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 8f4f8759133da93cdafdb36b07758d17388e5e828bda7cb9f22ae70c0821cd03
MD5 fcf2756fe9fdf388619577aba72d1c40
BLAKE2b-256 77106cd18b7039ec5936b4c3833ff6b7ad09051f4547da9f245785c86f9f9c4d

See more details on using hashes here.

Provenance

The following attestation bundles were made for solweig-0.1.0b40-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.0b40-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for solweig-0.1.0b40-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 e1d0df330118f72f0cde77733fb59a73c93498d3543e7433fdb0a26f3c7c6476
MD5 fe9527da5be2ff2374d2dd3544ad64ea
BLAKE2b-256 7efb75f60c0b74e1bed46c4ab334d07f01118560dc50e8a4a3de7d8b36a9d51e

See more details on using hashes here.

Provenance

The following attestation bundles were made for solweig-0.1.0b40-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.0b40-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for solweig-0.1.0b40-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 668088b3d19f1206550b3fb3b2dfd02510865e0747fcd1d9a2f743498c41721b
MD5 7975bb92af4f6378e537c4b4f57b2e9f
BLAKE2b-256 ca6f1a1c3f623f8ae41e1402333d0875792453eb54c17b0811a1c6962d662e92

See more details on using hashes here.

Provenance

The following attestation bundles were made for solweig-0.1.0b40-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.0b40-cp39-abi3-win_amd64.whl.

File metadata

  • Download URL: solweig-0.1.0b40-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.0b40-cp39-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 18e86785c26b1649cb2cc576e0500950916f975a1a818625a989b1ccd4055c67
MD5 88d7728f66cb950ebe9fc46d2ab72a53
BLAKE2b-256 e993957ac73d3c9f5c715bac9ea2e56a77bc88fafff5f31a9a2892ebd9c5baad

See more details on using hashes here.

Provenance

The following attestation bundles were made for solweig-0.1.0b40-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.0b40-cp39-abi3-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for solweig-0.1.0b40-cp39-abi3-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 dc127bbd391c38ba2e8f592a5927b4796cedba861f8048d0547fd795b7bf3706
MD5 c6df1c8f7db4dd38ae550242a705599d
BLAKE2b-256 d5afd3671364fb056fc3c42bcbc61ff56347c720d042468ac9766e4d323e3028

See more details on using hashes here.

Provenance

The following attestation bundles were made for solweig-0.1.0b40-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.0b40-cp39-abi3-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for solweig-0.1.0b40-cp39-abi3-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 66c37f1f6155fae63b0b38b03cf9da430d9f86ca6baccc553258f50c43ee05f0
MD5 a3f41a52637ef69ffeb97405bca92021
BLAKE2b-256 7e213ddd3fe0c6846251e349706a96c196e933d8e0f50ab899177ddabb4354e6

See more details on using hashes here.

Provenance

The following attestation bundles were made for solweig-0.1.0b40-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.0b40-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for solweig-0.1.0b40-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 922e9d2fb765a6e30344614fa05171b48ba9ca3a15f4e0cf73e44018c070e438
MD5 34d1ba61c1bd1623ca7fee667506cd48
BLAKE2b-256 45503c38eb35928116a2a6e6308735808cb534cd6c6c7fb72075c45fe0eb101e

See more details on using hashes here.

Provenance

The following attestation bundles were made for solweig-0.1.0b40-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.0b40-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for solweig-0.1.0b40-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 3c44620baa274389bb5fdbf89a8c6bd9fabb711c4f1618597dc9dfe5da866701
MD5 a556278cf8b50444bf7e8b8c506e0c6a
BLAKE2b-256 89c6e5bcb6dc5e612c5e0a5204a5a35fb566a62e03335209eca90926684bb2af

See more details on using hashes here.

Provenance

The following attestation bundles were made for solweig-0.1.0b40-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.0b40-cp39-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for solweig-0.1.0b40-cp39-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 95fac790ffcffc3b9f51fbec5e4c441a2bd3cec6a455de7490258bd729c91946
MD5 c3fcedbb5ad44832d0ca1ad789e9c4df
BLAKE2b-256 92fb839a38f944046672ff525a801e231c8936a3946e1dbe28c6aeff725eeb62

See more details on using hashes here.

Provenance

The following attestation bundles were made for solweig-0.1.0b40-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.0b40-cp39-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for solweig-0.1.0b40-cp39-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 887de82dae01e1d0723073ced80692168ac592540de5c5b59bc83eb2552b2443
MD5 d01f9f9ad1f13d554120f98efceb0b6f
BLAKE2b-256 e58b2a4f025f3bcd37035cc33af4282dcd11763fb461ed8179559169f5ab22b2

See more details on using hashes here.

Provenance

The following attestation bundles were made for solweig-0.1.0b40-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