Skip to content

City Configuration

URBADAPT-HEAT is designed to operate across any European city with a single city-specific YAML configuration file and a corresponding data manifest. The same analytical code runs everywhere — only the config changes.


Config file structure

City configs live in urban-heat/configs/<city>.yml. The YAML is divided into named sections, each consumed by the corresponding notebook stage. The same city-agnostic notebooks read whichever config is selected by the CITY environment variable. Below is an annotated representative excerpt (see rome.yml for a full example — real configs also carry inline calibration provenance comments):

# ── Identity ────────────────────────────────────────────────
slug: rome
city_name: Rome
wp_iso3: ITA
wp_country: Italy
base_dir: data/Rome
drive_manifest: data_manifests/rome_gdrive.json

# ── Demographic scenario ─────────────────────────────────────
# Available: SSP1, SSP2, SSP3, SSP4, SSP5, SSP2DM, SSP2ZM
exp_scenario: SSP2

# ── Spatial layers ───────────────────────────────────────────
layers:
  fua: fua           # Functional Urban Area boundary
  cap: cap           # Capital/core boundary
  regions: regions   # Sub-city policy regions
  muni: muni         # Municipal boundaries

# ── Air conditioning module ──────────────────────────────────
ac:
  ssp: 2
  years: [2020, 2030, 2040, 2050]
  penetration_file: ACgridded/ac_penetration_NUTSregions.csv
  kwh_file: ACgridded/ac_kwh_NUTSregions.csv
  nuts_id: ITI43                        # NUTS3 region identifier (penetration)
  tariff_eur_per_kwh: 0.17
  capex_per_user: 1498                  # installed cost, PLI-adjusted
  maint_rate: 0.04
  lifetime_years: 12
  waste_heat:
    enabled: true
    lut_case_default: central           # low / central / high
    dailymean_from_night_default: 0.50
    dailymean_from_night_range: [0.33, 0.67]
    activation:                         # thermally-weighted activation of waste heat
      method: kou_cdd_share
      t_on_c: 18.0
      t_full_c: 25.0
    lut:                                # Salamanca 2014: penetration → nighttime ΔT (°C)
      0.00: {low: 0.00, central: 0.00,  high: 0.00}
      0.35: {low: 0.25, central: 0.375, high: 0.50}
      0.65: {low: 0.50, central: 0.750, high: 1.00}
      1.00: {low: 1.00, central: 1.250, high: 1.50}
    cop_degradation:                    # Kou et al. 2026
      enabled: true
      sensitivity_per_C: {low: 0.04, central: 0.065, high: 0.09}
      cop_ref: 3.0

# ── Trees / vegetation module ────────────────────────────────
# CAPEX/O&M are city-specific (PLI-adjusted): Rome €680/€63, Athens €612/€57,
# Lisbon €606/€56, Copenhagen €978/€91.
trees:
  capex_per_index_pt_eur: 10000000  # € per +1 GVI point
  capex_per_tree_eur: 680
  om_per_tree_per_year_eur: 63
  lifetime_years: 25
  ramp_years: 12                    # maturity ramp in years
  focus_year: 2050
  veg_regions: regions              # policy geography: regions | zones
  veg_emulator_bundle: "emulator/bundles/emulator_bundle_pooled_all_quadratic_holdout_safe.json"

# ── Vegetation → AC electricity co-benefit (Falchetta, De Cian & Lunghi 2026) ─
electricity_feedback:
  enabled: true
  pct_reduction_per_gvi_point: 0.008   # % AC electricity saved per GVI point
  summer_months: 3
  co2_intensity_gCO2_per_kwh: 180

# ── EWS module ───────────────────────────────────────────────
ews:
  archetype: mature_hhwws
  operational_trigger_mode: epi_deaths_file
  warning_season: {mode: exact_dates, start_md: "05-01", end_md: "09-30"}
  threshold_method: epi_deaths_file   # epi_deaths_file | event_mask
  target_activation_days: 23          # options: 15 / 23 / 30
  threshold_recalib_interval: 5       # years; options: 3 / 5 / 7
  interpretation: marginal            # marginal | counterfactual
  efficacy_counterfactual: {low: 0.2, central: 0.35, high: 0.5}
  efficacy_marginal:                  # age-differentiated (sensitivity)
    "65+": {low: 0.08, central: 0.15, high: 0.25}
  ramp_years: 3
  ac_overlap_factor: {low: 0.3, central: 0.5, high: 0.7}
  cost_model: pavanello               # pavanello | chiabai

# ── Income (drives AC downscaling geography) ─────────────────
income:
  source: observed                    # observed | emulator (see cityheat.income_source)
  aggregation: weighted

zones:                                # geography at which income exists
  source: shapefile                   # shapefile | osm
  shapefile: "CAPZONE/CAPZONE.shp"
regions:                              # coarser reporting geography (optional)
  enabled: true
  source: osm

# ── Vulnerability ─────────────────────────────────────────────
vulnerability:
  enabled: true
  weights: {thermal: 0.333, foreign_born: 0.333, unemployment: 0.333}
  files:
    ghs_age: "vulnerability/GHS_AGE_..._100_V1_0.tif"
    census_oth: "vulnerability/ESTAT_OBS-VALUE-OTH_2021_V2.tiff"
    census_emp: "vulnerability/ESTAT_OBS-VALUE-EMP_2021_V2.tiff"
  dynamic:
    enabled: true
    baseline_year: 2021
    drmkc: {file: "vulnerability/drmkc_vulnerability_projection.csv", region_id: ITI43}
    gvi:   {file: "vulnerability/gvi_projections.csv", country_code: ITA}
    k:   {default: 0.85}
    phi: {default_2030: 0.92, default_2050: 0.75}
    thermal_projection:
      retrofit_rate_per_year: 0.0138
      new_build_vulnerability: 0.15

# ── Climate / hazard ─────────────────────────────────────────
climate:
  t2m_clim_scen_default: CurPol       # default scenario
  t2m_clim_scen_options: [CurPol, GS, SP, ssp585]
  t2m_baseline_mode_default: climatology_mean   # climatology_mean | pixelwise_doy_max |
                                                # domain_peak_day | warmest_summer
  t2m_delta_pct_band_default: central  # low | central | high (GCM spread)
  t2m_var: tas
  years: [2020, 2030, 2040, 2050]
  urbclim_api:                         # historical UrbClim download (NB01)
    enabled: true
    t2m_url: "https://provide.marvin.vito.be/ftp/compressed_daily/Rome/"
    years: [2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017]

# ── Impact-function efficacy (AC attenuation) ────────────────
efficacy: {"<15": 0.20, "15-64": 0.30, "65+": 0.40, default: 0.30}

# ── CBA ──────────────────────────────────────────────────────
cba:
  discount_rate: 0.03
  horizon_years: 25

Track A vs Track B (hazard track). Most cities run on the standard daily-mean hazard (Track A). Cool/maritime cities where daily-mean T2M carries little heat signal use the extreme-event (heatwave) track (Track B), enabled with an extreme_hazard: block. NB08 reads the selected track via HAZARD_TRACK. For Copenhagen:

extreme_hazard:
  enabled: true
  run_standard_track: true      # kept for comparability (policies disabled)
  run_extreme_track: true       # the policy-analysis track for this city
  standard_track: {name: standard_dailymean, run_policies: false}
  event_track:
    name: heatwave_extreme
    season: {mode: exact_dates, start_md: "05-15", end_md: "09-30"}
    threshold_percentile_default: 95      # options: 95 / 93 / 92 / 90
    min_duration_default: 3               # options: 3 / 2 (days)
    intensity_method: exceedance
    t_ref_mode_default: local_p90
    cold_city_if_variant: true
Copenhagen's EWS also sets nonpositive_threshold_fallback: event_mask so that when the deaths-based threshold is non-positive (too few heat deaths to calibrate), warnings fall back to the extreme event-day mask.


Data requirements per city

Data layer Source Notes
UrbClim T2M (2008–2017) PROVIDE/VITO API ~100 m, EPSG:3035, daily NetCDF
GHS-FUA boundary GHSL JRC FUA identifier needed
WorldPop age-structured rasters (2020, 2030) worldpop.org Three age groups
GHS-AGE raster GHSL JRC (2025 release) 100 m, epoch codes 1–10
EUROSTAT Census 2021 Eurostat Foreign-born share + employment rasters
Green View Index (GVI) Huisman et al. (2025) dataset 356-city dataset
Local Climate Zone (LCZ) raster LCZ global map lcz_filter_v3.tif
AC penetration (NUTS3) National/regional statistics City-level aggregate
Income data (sub-municipal) National tax records For logistic AC downscaling
CMIP6 warming deltas PROVIDE climate service Monthly, per scenario
WCDE demographics Wittgenstein Centre Age-specific, SSP-consistent
DRMKC trend indicators Risk Data Hub NUTS3, for SVI short-run projection

Adding a new city

Because the notebooks are city-agnostic, adding a city is mostly a config + data task — no notebook editing is required.

  1. Identify the GHS-FUA boundary and NUTS3 code for your target city.
  2. Download all required data layers (see table above) and place them under the path given by base_dir: (e.g. urban-heat/data/MyCity/).
  3. Create a data manifest JSON file in urban-heat/data_manifests/<city>_gdrive.json pointing to your Drive files, and reference it from the config's drive_manifest: key.
  4. Copy an existing city YAML and adjust all parameters:
    cp urban-heat/configs/rome.yml urban-heat/configs/mycity.yml
    
  5. Point the template notebooks at your city by setting one line near the top of NB01:
    os.environ["CITY"] = "MyCity"   # resolves configs/mycity.yml
    
    (Optionally, copy template/ to a per-city folder if you want a pinned copy with the CITY line pre-set.)
  6. Run NB01 (01_setup_0126.ipynb) to verify paths and sync data.
  7. Execute notebooks 02 through 08 in order.
  8. Optionally run 09_uncertainty and 10_summary for uncertainty quantification and reporting.

Note on Track B: For maritime or northern-latitude climates where daily-mean T2M carries limited heat signal, add an extreme_hazard: block (see above) to activate the event-exceedance hazard representation and the event-mask EWS fallback. Copenhagen is the reference Track-B implementation. There is no top-level track_b: flag — the track is controlled by extreme_hazard and read at runtime via HAZARD_TRACK.


Configured cities

Over 40 European cities ship with a config and a Drive manifest, e.g. Amsterdam, Athens, Barcelona, Berlin, Bologna, Bratislava, Brussels, Bucharest, Budapest, Cologne, Copenhagen, Dublin, Genova, Hamburg, Helsinki, Lisbon, Ljubljana, Lyon, Madrid, Marseille, Milan, Munich, Nantes, Naples, Palermo, Paris, Porto, Prague, Riga, Rome, Rotterdam, Sevilla, Sofia, Stockholm, Tallinn, Thessaloniki, Varna, Vienna, Vilnius, Warsaw, Zagreb (see urban-heat/configs/).

Four cities are demonstrated end-to-end (full pipeline including uncertainty and summary):

City Config file Country Climate Hazard track
Rome rome.yml Italy Hot-summer Mediterranean A (standard)
Athens athens.yml Greece Hot-summer Mediterranean A (standard)
Lisbon lisbon.yml Portugal Warm-summer Mediterranean A (standard)
Copenhagen copenhagen.yml Denmark Oceanic B (extreme-event)

This page is maintained in the URBADAPT-HEAT wiki and synced automatically. Edit it there, not in the website repository.