Read a city street as the grids that actually govern comfort, UTCI, wind and solar, then test one design question with real data.
Position carries meaning. The top row holds the principles, the centre cell is the live probe you run, and the foot of the grid is praxis: real cities, the honest counter-case, and where to go next. Read it top to bottom and you walk from idea to practice.
▲ general / principle · the vertical axis is an abstraction gradient · special / praxis ▼
Whether added canopy cools a street or traps its heat depends on the street's form, its density and its geometry.
The Universal Thermal Climate Index folds air temperature, radiation, wind and humidity into one felt temperature.
A regenerative microclimate is a diverse mosaic of thermal zones. Alberti's lens reads that mosaic, made grid-native.
Install infrared-sdk 0.4.9, hold your key in .env, and preview a site for free before you spend anything.
Submit a polygon, get back an AreaResult grid for UTCI, wind or solar. Baseline first, then the same site with trees.
Heat-stress %, severe-heat %, the Thermal Assembly Complexity Index and thermal-zone diversity, straight off the grid.
A dense canyon plus canopy can trap radiant heat and cut ventilation. The honest failure mode, measured.
Marseille, Cork, Rome and London run through the same probe. The deltas disagree, and that is the point.
The scorecard, the QGIS export, and the simSPACE serious game where the finding becomes playable.
The thesis the whole module tests.
Frames: Alberti (2016); Oke (1988), street-canyon energetics.
Urban greening is sold as cooling. Often it is. But canopy changes a microclimate for better or for worse, and which one depends on the street's form. A broad crown over an open plaza shades a hot surface and cools it. The same crown packed into a narrow, deep canyon can trap the longwave heat the buildings radiate and choke the wind that would carry it away.
So the regenerative question is not "how many trees" but "what does this canopy do to this street's heat and air". That is a measurement question, and this module is how you measure it.
The single number this module reads off every grid.
Source: Bröde et al. (2012); Błażejczyk et al. (2013), the UTCI assessment scale.
The Universal Thermal Climate Index answers "what does a body feel here", folding air temperature, mean radiant temperature, wind speed and humidity into one equivalent temperature in °C. It is the index the infrared.city thermal-comfort model returns.
The assessment scale sorts that number into stress bands. The module uses these exact thresholds (Błażejczyk et al. 2013):
Two figures drive the whole assessment:
Why a varied microclimate is itself a quality.
Frames: Alberti (2016), Cities That Think Like Planets; Shannon (1948), diversity.
A single mean flattens a street into one verdict. Alberti's planetary-urbanism lens asks a richer question: how many distinct thermal conditions does a place offer, and how evenly are they mixed. A street with shade pockets, sunny edges and ventilated gaps gives a body somewhere to move to. The module operationalises this as the Thermal Assembly Complexity Index (TACI), grid-native.
It is built from the UTCI band map of the grid:
Install, authenticate, and preview for free.
Package: infrared-sdk 0.4.9 (supersedes the old hand-rolled REST client).
One install, one key. The client reads INFRARED_API_KEY from your
environment and auto-loads a local .env on import. Treat the key as a
password; never commit it (the toolkit's .gitignore already excludes .env).
# pip install infrared-sdk numpy matplotlib import infrared_sdk as ir # reads INFRARED_API_KEY from your .env automatically client = ir.InfraredClient() # a square around your site, lon/lat, closed ring polygon = [[-8.486,51.897],[-8.482,51.897], [-8.482,51.899],[-8.486,51.899],[-8.486,51.897]] # PREVIEW: tiles the area, no job is submitted, nothing is billed. # always pass analysis_type (wind grid = 256 m, solar/thermal = 512 m) preview = client.preview_area(polygon, analysis_type="solar") print(preview.tile_count, "tiles ready, 0 cost")
preview_area never submits a
job. Use it to frame your polygon and pick a resolution before you run anything billable.The hands-on core. Baseline, then the same site with trees.
Returns: an AreaResult with .merged_grid (numpy, NaN outside the polygon), .bounds and a legend.
A real run submits a model request over your polygon and waits for the grid. This is the billable step, so the module teaches it with the cost guard switched on from the start.
from infrared_sdk.models import TimePeriod import regenerative_metrics as rm # a solar run needs no weather file; UTCI does (see the toolkit's fetch helper) request = ir.SolarModelRequest(time_period=TimePeriod.SUMMER) # BILLABLE. run_area_and_wait submits a real job. cap tiles while learning. baseline = client.run_area_and_wait( request, polygon, on_progress=lambda p: print(f" {p:.0%}"), ) grid = baseline.merged_grid # numpy array, NaN outside the site print(rm.utci_stats(grid).line())
Now run the same polygon again with vegetation injected, so the only thing that changed is the trees:
# real street trees, fetched and shaped by the SDK's vegetation service veg = client.vegetation.get_area(polygon) print(veg.total_trees, "trees on this site") intervention = client.run_area_and_wait(request, polygon, vegetation=veg) print(rm.utci_stats(intervention.merged_grid).line())
run_area_and_wait bills. The toolkit's
scorecard.py only previews unless you pass --run, and
--max-tiles N caps the spend. Never launch an area run without meaning to.Grid in, comparable numbers out.
Module: regenerative_metrics.py (UTCI bands, heat-stress %, TACI).
The metrics module reads a numpy grid and returns the figures the scorecard compares. Nothing here is billed; it is pure post-processing of grids you already have.
import regenerative_metrics as rm base = rm.utci_stats(baseline.merged_grid) trees = rm.utci_stats(intervention.merged_grid) print(f"heat-stress {base.heat_stress_pct:.1f}% -> {trees.heat_stress_pct:.1f}%") print(f"mean UTCI {base.mean:.1f} -> {trees.mean:.1f} °C") # the assembly view: did the street gain thermal-zone diversity? taci = rm.assembly_index(intervention.merged_grid) print(f"zone diversity (Shannon) {taci.spatial_diversity:.2f}")
The failure mode that proves the finding.
Frames: Oke (1988), canyon radiation trapping & reduced sky-view factor.
Run the probe on a deep, narrow Mediterranean street and add a broad canopy, and the heat-stress fraction goes up. The crowns lower the sky-view factor, so the longwave heat the walls radiate at night is trapped under the leaves, and the same crowns slow the cross-street wind that would have flushed it.
This is not a bug in the model. It is the model telling you the truth about that street. Marseille below is the worked example: heat-stress rises from 79.1% to 83.0% after planting, because the intervention was canopy in a canyon.
The same probe, four very different answers.
Data: the live toolkit run; values from kpis.json.
These are the measured deltas from running the probe over each city's site. They are not tidy. That is the honest result, and the teaching point: the method is constant, the verdict is local.
| City | Heat-stress (base → +trees) | Mean UTCI | What it shows |
|---|---|---|---|
| Marseille | 79.1% → 83.0% | 27.3 → 27.5 °C | Canyon + canopy traps heat (1.1% tree-cover site) |
| Cork | 0% → 0% | 15.6 → 15.2 °C | Mild maritime; +7.6% thermal-zone diversity |
| Rome | 96.9% → 97.6% | 30.0 → 30.1 °C | 757 city trees / 33 species: a data-provenance proof, with a near-flat delta |
Cork is the regenerative case: no heat stress to begin with, and planting widened the mix of thermal zones (the assembly gain). Marseille and Rome are the cautionary cases, where dense form and sparse ground make canopy a weaker lever than airflow. Same code, three different streets, three different truths.
Where the skill goes after the module.
All live on the AT6012 site and the GitHub Pages mirror.
The module is the front door. Each of these takes the same finding somewhere concrete:
Connect to the SDK, preview a site for free, run a real UTCI / wind / solar grid, inject real vegetation, compute heat-stress, severe-heat and thermal-assembly metrics, and judge honestly whether a planting helped, including the cases where it did not.
Alberti, M. (2016). Cities That Think Like Planets. · Bröde, P. et al. (2012). Deriving the operational procedure for the UTCI. Int. J. Biometeorol. · Błażejczyk, K. et al. (2013). An introduction to the UTCI. Geographia Polonica. · Oke, T. R. (1988). Street design and urban canopy layer climate. Energy and Buildings. · Shannon, C. (1948). A mathematical theory of communication.