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

Uploaded PyPymanylinux: glibc 2.17+ ARM64

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

Uploaded PyPymanylinux: glibc 2.17+ ARM64

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

Uploaded CPython 3.9+Windows x86-64

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

Uploaded CPython 3.9+musllinux: musl 1.2+ ARM64

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

Uploaded CPython 3.9+macOS 11.0+ ARM64

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

File metadata

  • Download URL: solweig-0.1.0b41.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.0b41.tar.gz
Algorithm Hash digest
SHA256 608bbfbd2c89bb0ca9e079b2bcd8a078885b457595ca66abd3f6b2da82d6d24f
MD5 ca6b4f3c89daa08e0a311c3020cf3047
BLAKE2b-256 57fe7ad0eef01bd4f345dee64f5fd70de0ab229dea07a67fe2c56cfcfc8b3261

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for solweig-0.1.0b41-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 4ce01c23508f423e17f436ad3fb16b164073a578d1534a7ee9aff3ea1464c1f3
MD5 425db5ce376b0fd112522a4ebff650a1
BLAKE2b-256 94ff870a22051df53e7d1075f23acc3c71f4ed18a33f2cb9d7dbd928d4d70793

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for solweig-0.1.0b41-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 4d76bec7dd90779ff957963c10daa25b2079181b78e82a61592ff618e1e8ffec
MD5 908e47d4bbed6cf3721c3c51d4a2eacc
BLAKE2b-256 7c50b6c59e442ccbce7b56134eab10da2ee13146695253d12fa732623a2a8b40

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for solweig-0.1.0b41-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 bff88e3f9bac61aa3970ccda3da12113827b9200d81476444bac0361c28395dc
MD5 7c7b81e56c2f76d612d7de110cf88634
BLAKE2b-256 e090a1831d42cf681af9214bbe1ead5a27342b53d6623f1f2dba3b7d044f2180

See more details on using hashes here.

Provenance

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

File metadata

  • Download URL: solweig-0.1.0b41-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.0b41-cp39-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 41944237af46b408f7925afe5c09b15fb873ce5c91fc179399562886a66aff98
MD5 9f9e14706b651c1caac8e275556a208d
BLAKE2b-256 ac3e342f343e3a4184a2ed472a091da9797ce4301c4c5d62b420130b55c6ad0d

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for solweig-0.1.0b41-cp39-abi3-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 a94638e0af9bd28f1d6ba87bbc968f0613290b649f6ecdc30479acac3389b959
MD5 04cbfc28e03e14199f3104ce4bf93e8d
BLAKE2b-256 f5419dc56f51de57ed10e9f125024e2e179976ea4d43cacf731ef2f9c0d4dcbf

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for solweig-0.1.0b41-cp39-abi3-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 989c8d9b72c4072148573bb2f808a7d6e3fc155559410b1ca936c643a8d429aa
MD5 a216e1ee1ba422d1d04803056866342e
BLAKE2b-256 4a4c904d9ac404afa277e92f84a220b811444f62e2fa63209309b474d2ac0c99

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for solweig-0.1.0b41-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 a93bd6cdd83ebe05cabf62d9dc76b26371d0a33ec3e5a475c070b6aae83ce1ca
MD5 8608769882f6ef801bc4849226b45d9b
BLAKE2b-256 0be955f45a0ef9a8d4b90a4bd11ad8c3dda38555426bbdc6f614b0413edcc534

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for solweig-0.1.0b41-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 8f3d816334c79291f1eedfafebc85ae62058da4d7abfec339ccee8d657d046d0
MD5 a303e726270195610bfc50924fbf30ae
BLAKE2b-256 88c64fcd4e5266a8793cd71d311f6f0013e722f0d8de215bc743774ac3a9974a

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for solweig-0.1.0b41-cp39-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 0aae266c564eddaf137a693fde292ea25e9be0818eb7db20c604bd0acb42682c
MD5 fafdb7f6e31d8de2f0607a5a67fc5565
BLAKE2b-256 1fe42adaa78090bb2eb6a809de5595401aee9da9eed07180e3ddfcdbce5a0131

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for solweig-0.1.0b41-cp39-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 4ffaa2073c945ba4af586675a919424d205dd10b260035efa93d81b465d69057
MD5 6eb0b0d4a2e9d7130f882204c9767e35
BLAKE2b-256 af480046c5d9fa1481adf39ecf539fb9e0edf68adf2dd71acf138429b288c063

See more details on using hashes here.

Provenance

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