Skip to main content

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

Project description

SOLWEIG

High-performance urban microclimate model for computing Mean Radiant Temperature (Tmrt) and thermal comfort indices (UTCI, PET).

Rust + Python performance-critical algorithms with GPU and tiled processing support.

This package is currently in testing as a proof of concept. Please open an issue if you have any feedback or suggestions.

Documentation

Original Code

This package is adapted from the GPLv3-licensed UMEP-processing by Fredrik Lindberg, Ting Sun, Sue Grimmond, Yihao Tang, and Nils Wallenberg.

Licensed under GNU General Public License v3.0. See LICENSE for details.

Citation:

Adapted from UMEP (Urban Multi-scale Environmental Predictor) by Fredrik Lindberg, Sue Grimmond, and contributors. If you use this plugin in research, please cite:

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

Installation

# Clone and install
git clone https://github.com/UMEP-dev/solweig.git
cd solweig
uv sync                  # Install Python dependencies
maturin develop          # Build Rust extension

Quick Start

import solweig
from datetime import datetime

# Create surface from DSM array
surface = solweig.SurfaceData(dsm=my_dsm_array, pixel_size=1.0)

# Define location and weather
location = solweig.Location(latitude=57.7, longitude=12.0)
weather = solweig.Weather(
    datetime=datetime(2024, 7, 15, 12, 0),
    ta=25.0,        # Air temperature (°C)
    rh=50.0,        # Relative humidity (%)
    global_rad=800.0  # Global radiation (W/m²)
)

# Calculate Tmrt
result = solweig.calculate(surface, location, weather)
print(f"Tmrt: {result.tmrt.mean():.1f}°C")

Loading from GeoTIFFs

import solweig

# Load and prepare surface data (auto-computes walls/SVF)
surface = solweig.SurfaceData.prepare(
    dsm="data/dsm.tif",
    working_dir="cache/",       # Walls/SVF cached here
    cdsm="data/cdsm.tif",       # Optional: vegetation
)

# Load weather from EPW file
weather_list = solweig.Weather.from_epw(
    "data/weather.epw",
    start="2023-07-01",
    end="2023-07-03",
)

# Calculate timeseries
results = solweig.calculate_timeseries(
    surface=surface,
    weather_series=weather_list,
    output_dir="output/",
)

Post-Processing (UTCI/PET)

Thermal comfort indices can be computed directly from results:

# Single timestep: compute directly from result
result = solweig.calculate(surface, location, weather)
utci = result.compute_utci(weather)  # Fast polynomial
pet = result.compute_pet(weather)    # Slower iterative solver

# Batch processing: from saved Tmrt files
solweig.compute_utci(tmrt_dir="output/", weather_series=weather_list, output_dir="utci/")
solweig.compute_pet(tmrt_dir="output/", weather_series=weather_list, output_dir="pet/")

Input Validation

Validate inputs before expensive calculations:

try:
    warnings = solweig.validate_inputs(surface, location, weather)
    for w in warnings:
        print(f"Warning: {w}")
    result = solweig.calculate(surface, location, weather)
except solweig.GridShapeMismatch as e:
    print(f"Grid mismatch: {e.field}")
except solweig.MissingPrecomputedData as e:
    print(f"Missing data: {e}")

Demos

Complete working examples are in the demos/ folder:

QGIS Plugin

SOLWEIG is available as a QGIS Processing plugin for interactive spatial analysis:

  1. Open QGIS → PluginsManage and Install Plugins
  2. Go to Settings tab → Check "Show also experimental plugins"
  3. Search for "SOLWEIG" in the All tab
  4. Click Install Plugin

See qgis_plugin/ for source code and development details.

Build & Test

maturin develop          # Build Rust extension
pytest tests/            # Run all 353 tests
poe verify_project       # Full verification (format, lint, test)

Development

Project Structure

pysrc/solweig/              # Python source (modular architecture)
  api.py                    # Public API re-exports
  models/                   # Dataclass package (~3,080 lines)
  components/               # Modular component functions
  computation.py            # Core orchestration logic
  timeseries.py             # Batch time series processing
  tiling.py                 # Large raster tiling support
rust/                       # Rust extensions via maturin
qgis_plugin/                # QGIS Processing plugin
tests/                      # 353 tests (100% pass rate)
  golden/                   # Reference data validation
  spec/                     # Physical property tests
docs/                       # MkDocs documentation site
specs/                      # Markdown specifications

Development Setup

# Install dependencies
uv sync

# Build Rust extension for development
maturin develop

# Run tests with coverage
pytest tests/ --cov=pysrc/solweig

# Format and lint
ruff format pysrc/ tests/
ruff check pysrc/ tests/ --fix

# Type checking
ty pysrc/

# Full verification pipeline
poe verify_project

Building Documentation

# Serve docs locally
mkdocs serve

# Build static site
mkdocs build

QGIS Plugin Bundle Preparation

To prepare the QGIS plugin for distribution:

1. Update Plugin Metadata

Edit qgis_plugin/metadata.txt:

[general]
name=SOLWEIG
version=0.1.0              # Increment version
experimental=True          # Set to False when stable
description=Urban microclimate model for thermal comfort analysis
qgisMinimumVersion=3.0
author=Your Name
email=your.email@example.com
repository=https://github.com/UMEP-dev/solweig
tracker=https://github.com/UMEP-dev/solweig/issues

2. Create Distribution ZIP

# Create a clean build directory
cd /Users/gareth/dev/umep/solweig
mkdir -p build/solweig

# Copy plugin files (excluding build artifacts)
cp -r qgis_plugin/* build/solweig/

# Create ZIP with correct structure
cd build
zip -r solweig.zip solweig/ -x "*.pyc" -x "*__pycache__*" -x "*.DS_Store"

3. Test Plugin Locally

Before uploading, test the plugin in QGIS:

# Copy to QGIS plugins directory (macOS)
cp -r build/solweig ~/Library/Application\ Support/QGIS/QGIS3/profiles/default/python/plugins/

# Or use symlink for development
ln -s /Users/gareth/dev/umep/solweig/qgis_plugin ~/Library/Application\ Support/QGIS/QGIS3/profiles/default/python/plugins/solweig

Then:

  1. Open QGIS
  2. PluginsManage and Install PluginsInstalled
  3. Enable SOLWEIG
  4. Test in Processing ToolboxSOLWEIG

4. Upload to QGIS Plugin Repository

  1. Register at https://plugins.qgis.org/
  2. Log in → My PluginsUpload a plugin
  3. Select build/solweig.zip
  4. Check "Experimental" for pre-release versions
  5. Add changelog/release notes
  6. Click Upload

Review typically takes 1-3 days.

Release Checklist

  • Version incremented in qgis_plugin/metadata.txt
  • All tests passing (pytest tests/)
  • Documentation updated
  • CHANGELOG.md updated
  • Plugin tested in QGIS locally
  • ZIP bundle created and validated
  • Uploaded to plugins.qgis.org

Tooling Preferences

Tool Use For Instead Of
uv Package management pip, poetry, pipenv
ruff Linting and formatting black, isort, flake8, pylint
ty Type checking mypy, pyright

Code Metrics

  • api.py: 403 lines (simplified from 3,976)
  • models/ package: ~3,080 lines (6 modules)
  • Component functions: All ≤ 455 lines
  • Test count: 353 tests (100% pass rate)
  • Legacy code removed: 6,100 lines

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.0b3.tar.gz (218.1 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.0b3-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (3.4 MB view details)

Uploaded PyPymanylinux: glibc 2.17+ x86-64

solweig-0.1.0b3-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (3.4 MB view details)

Uploaded PyPymanylinux: glibc 2.17+ ARM64

solweig-0.1.0b3-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (3.4 MB view details)

Uploaded PyPymanylinux: glibc 2.17+ ARM64

solweig-0.1.0b3-cp39-abi3-win_amd64.whl (3.3 MB view details)

Uploaded CPython 3.9+Windows x86-64

solweig-0.1.0b3-cp39-abi3-musllinux_1_2_x86_64.whl (3.7 MB view details)

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

solweig-0.1.0b3-cp39-abi3-musllinux_1_2_aarch64.whl (3.6 MB view details)

Uploaded CPython 3.9+musllinux: musl 1.2+ ARM64

solweig-0.1.0b3-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (3.4 MB view details)

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

solweig-0.1.0b3-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (3.4 MB view details)

Uploaded CPython 3.9+manylinux: glibc 2.17+ ARM64

solweig-0.1.0b3-cp39-abi3-macosx_11_0_arm64.whl (2.7 MB view details)

Uploaded CPython 3.9+macOS 11.0+ ARM64

solweig-0.1.0b3-cp39-abi3-macosx_10_12_x86_64.whl (2.8 MB view details)

Uploaded CPython 3.9+macOS 10.12+ x86-64

File details

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

File metadata

  • Download URL: solweig-0.1.0b3.tar.gz
  • Upload date:
  • Size: 218.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: maturin/1.11.5

File hashes

Hashes for solweig-0.1.0b3.tar.gz
Algorithm Hash digest
SHA256 3bb9a8d3b6d9af032085b0e4937a480a41283eb5c83cd57c6e692c4b79a11321
MD5 bfdbe4836d78c034bb0dce84c1ab304e
BLAKE2b-256 60524ad886c1e67b35622dd507c801570fa770b6710862100a29df46bd261d47

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for solweig-0.1.0b3-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 0c8b27ae29075811067d427bdf0ffabc9eb0aff9b728ae05436ac6a958bd3e75
MD5 d546eee280dc691e7bb1b7feb8af35ba
BLAKE2b-256 5b2b4f25f8f50cce1098b72d04a64041afdbe42b185465b26b75238dee71987e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for solweig-0.1.0b3-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 b5067fa6bc6a2f2a5d875b9e45ae504c5de30589af3b99afd4acac75d176d04a
MD5 963b57a25179a63bb1c59738e1dbe940
BLAKE2b-256 d699948a2ac8e53c3b43661cff63888b32fad89c2e333d51162107bf176944cc

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for solweig-0.1.0b3-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 631050a238a9350706757db5dabd9f9664d3c1ef6ece6265710f62c18e0d92f2
MD5 479d9e053eef07edd22872aa621517e5
BLAKE2b-256 042165e63e356e5587e0c034a9e1612d1304701dbf0c539de898598e0474f2f3

See more details on using hashes here.

File details

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

File metadata

  • Download URL: solweig-0.1.0b3-cp39-abi3-win_amd64.whl
  • Upload date:
  • Size: 3.3 MB
  • Tags: CPython 3.9+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: maturin/1.11.5

File hashes

Hashes for solweig-0.1.0b3-cp39-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 cf7374ec6b4834b94455e89107599695dbf4b663755b4738aa13a98dc80b918c
MD5 1e4cf691e3d4934b13275d84d9c34ba0
BLAKE2b-256 d9e4df1466d17cc32cfe93a5e7115b5940ef7e5076ad15b0f6578eeafec3b43c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for solweig-0.1.0b3-cp39-abi3-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 96c074c195bc2cdbd45fb58b98917fe379ad598059f4bf21c030fc3213fbb296
MD5 7ab8e28bb88a89fad1dbcb61550e6dfb
BLAKE2b-256 efd450395d2b8b34b6bfd0db292facae8bf02875c8731a48f6637a62361f82b6

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for solweig-0.1.0b3-cp39-abi3-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 6e71bebe8187704a623d8296db925f32c25e0aa61c4458c9429244104533f60a
MD5 8a190dcefe4d2313871866eaa5e788d3
BLAKE2b-256 e4574f73c4cf22bfa3bc6cce10c521920123e0ed91ac59b8592795f004906a86

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for solweig-0.1.0b3-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 0f680b309b1bb6a9780d352e8876f1a2f1180591669bc1cd6eaf501ff47e3632
MD5 c34324e1b5d2425bdf38b9e2666c7e1a
BLAKE2b-256 719ab26ffc42a70bb361e983c873b2265b067619d92ac381418dfd2f8d5c6b30

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for solweig-0.1.0b3-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 d5d55ede0eb18534f15eaf4d43e72badf23b48efb3378bdb539befa3a5dcc208
MD5 baa6079f387b384ba06aa13da34d8be1
BLAKE2b-256 03d4450828cd80dadbedb47c191fb65dfc5769cc742c19ac6205c784dd26be62

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for solweig-0.1.0b3-cp39-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 93c4425cc84bdf10c70f717308f2ac306e94dc1b180fb59b0c1e497310093611
MD5 87d1afeef3fc1204024487f6c8be7c90
BLAKE2b-256 55222b7b2d730d15f8ff863efcdb9965e696cae1bec60e46e9e89d6e38110edd

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for solweig-0.1.0b3-cp39-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 7665720d381888a6ea3976acb9bf0e47b72b6b0e387af897df81526790618c29
MD5 491c0c82a46e9e54b2b9c3391e296fb6
BLAKE2b-256 2fc63f0f535cf1b30bf986154d459c3994c38b452dc4357f934b13e1fff892f4

See more details on using hashes here.

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