# wri/cities-thermal-comfort-modeling architecture

> Architecture diagram of the GitHub repository wri/cities-thermal-comfort-modeling, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-11-11). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/wri/cities-thermal-comfort-modeling
- Repository: https://github.com/wri/cities-thermal-comfort-modeling

## Overview

CTCM is a city-scale thermal-comfort processing framework: users configure an area, input rasters and meteorology, validate the setup, then generate tiled SOLWEIG results and review or publish outputs. Its runtime also retrieves CIF data, prepares ERA5 inputs, supports UMEP and UPenn processing, and validates staged or completed results. The graph follows the visible entry point and worker dispatch; some subsystem links rely on SOURCE INDEX references or README descriptions because their implementation was not excerpted.

Main entry points: [`src/worker_manager/job_manager.py`](https://github.com/wri/cities-thermal-comfort-modeling/blob/main/src/worker_manager/job_manager.py) (Job manager), [`main.py`](https://github.com/wri/cities-thermal-comfort-modeling/blob/main/main.py) (CLI entry), [`src/workers/worker_tile_processor.py`](https://github.com/wri/cities-thermal-comfort-modeling/blob/main/src/workers/worker_tile_processor.py) (Tile processor), [`src/data_validation/manager.py`](https://github.com/wri/cities-thermal-comfort-modeling/blob/main/src/data_validation/manager.py) (Validation manager)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_orchestration["Run orchestration"]
  node_entry["CLI entry<br/>[main.py]"]
  node_city["City configuration<br/>[city_data.py]"]
  node_jobs["Job manager<br/>[job_manager.py]"]
  node_tile["Tile processor"]
end

subgraph group_validation["Configuration validation"]
  node_validate["Validation manager<br/>[manager.py]"]
  node_aoi["AOI evaluation<br/>[aoi_evaluator.py]"]
  node_metvalidate["Meteorology checks"]
end

subgraph group_inputs["Inputs and staging"]
  node_cif["CIF retrieval"]
  node_umepmet["UMEP ERA5 prep"]
  node_upennmet["UPenn ERA5 prep"]
  node_dao[("Raster and S3 data<br/>[worker_dao.py]")]
  node_staging["CTCM staging"]
end

subgraph group_models["Thermal models"]
  node_umep["UMEP plugin"]
  node_upenn["UPenn model"]
  node_svf["Vegetation SVF"]
  node_weather["Mean radiant temperature"]
  node_solweig["SOLWEIG library<br/>[solweiglib.py]"]
end

subgraph group_outputs["Results and review"]
  node_ancillary["Ancillary outputs<br/>[ancillary_files.py]"]
  node_reporter["Run reporting<br/>[reporter.py]"]
  node_postvalidate["Result validation"]
  node_operator["QGIS results viewer<br/>[ancillary_files.py]"]
end

node_user(("City operator"))

node_user -->|"runs"| node_entry
node_entry -->|"builds configuration"| node_city
node_entry -->|"validates setup"| node_validate
node_entry -->|"starts processing"| node_jobs
node_entry -->|"checks or publishes"| node_staging
node_entry -->|"validates results"| node_postvalidate
node_validate -->|"evaluates AOI"| node_aoi
node_validate -->|"checks meteorology"| node_metvalidate
node_jobs -->|"validates configuration"| node_validate
node_jobs -->|"dispatches tiles"| node_tile
node_jobs -->|"prepares outputs"| node_ancillary
node_jobs -->|"reports status"| node_reporter
node_jobs -->|"prepares UMEP meteorology"| node_umepmet
node_jobs -->|"prepares UPenn meteorology"| node_upennmet
node_tile -->|"retrieves CIF data"| node_cif
node_tile -->|"runs UMEP steps"| node_umep
node_tile -->|"runs UPenn model"| node_upenn
node_upenn -->|"calculates vegetation SVF"| node_svf
node_upenn -->|"computes radiant temperature"| node_weather
node_weather -->|"uses library"| node_solweig
node_staging -->|"reads or writes data"| node_dao
node_postvalidate -->|"checks stored results"| node_dao
node_ancillary -->|"creates QGIS viewer"| node_operator

click node_entry "https://github.com/wri/cities-thermal-comfort-modeling/blob/main/main.py"
click node_city "https://github.com/wri/cities-thermal-comfort-modeling/blob/main/src/workers/city_data.py"
click node_jobs "https://github.com/wri/cities-thermal-comfort-modeling/blob/main/src/worker_manager/job_manager.py"
click node_tile "https://github.com/wri/cities-thermal-comfort-modeling/blob/main/src/workers/worker_tile_processor.py"
click node_validate "https://github.com/wri/cities-thermal-comfort-modeling/blob/main/src/data_validation/manager.py"
click node_aoi "https://github.com/wri/cities-thermal-comfort-modeling/blob/main/src/data_validation/aoi_evaluator.py"
click node_metvalidate "https://github.com/wri/cities-thermal-comfort-modeling/blob/main/src/data_validation/meteorological_data_validator.py"
click node_cif "https://github.com/wri/cities-thermal-comfort-modeling/blob/main/src/workers/source_cif_data_downloader.py"
click node_umepmet "https://github.com/wri/cities-thermal-comfort-modeling/blob/main/src/workers/model_umep/worker_umep_met_processor.py"
click node_upennmet "https://github.com/wri/cities-thermal-comfort-modeling/blob/main/src/workers/model_upenn/worker_upenn_met_processor.py"
click node_dao "https://github.com/wri/cities-thermal-comfort-modeling/blob/main/src/workers/worker_dao.py"
click node_staging "https://github.com/wri/cities-thermal-comfort-modeling/blob/main/src/worker_manager/ctcm_layer_staging.py"
click node_umep "https://github.com/wri/cities-thermal-comfort-modeling/blob/main/src/workers/model_umep/umep_plugin_processor.py"
click node_upenn "https://github.com/wri/cities-thermal-comfort-modeling/blob/main/src/workers/model_upenn/upenn_module_processor.py"
click node_svf "https://github.com/wri/cities-thermal-comfort-modeling/blob/main/src/workers/model_upenn/svfsCalculator_veg.py"
click node_weather "https://github.com/wri/cities-thermal-comfort-modeling/blob/main/src/workers/model_upenn/weather_meanRadiantT.py"
click node_solweig "https://github.com/wri/cities-thermal-comfort-modeling/blob/main/src/workers/model_upenn/libraries/solweiglib.py"
click node_ancillary "https://github.com/wri/cities-thermal-comfort-modeling/blob/main/src/worker_manager/ancillary_files.py"
click node_reporter "https://github.com/wri/cities-thermal-comfort-modeling/blob/main/src/worker_manager/reporter.py"
click node_postvalidate "https://github.com/wri/cities-thermal-comfort-modeling/blob/main/src/data_validation/s3_postproc_results_validation.py"
click node_operator "https://github.com/wri/cities-thermal-comfort-modeling/blob/main/src/worker_manager/ancillary_files.py"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_entry,node_city,node_jobs,node_tile toneBlue
class node_validate,node_aoi,node_metvalidate toneAmber
class node_cif,node_umepmet,node_upennmet,node_dao,node_staging toneMint
class node_umep,node_upenn,node_svf,node_weather,node_solweig toneRose
class node_ancillary,node_reporter,node_postvalidate,node_operator,node_user toneIndigo
```

## Components

### Run orchestration

- [CLI entry](https://github.com/wri/cities-thermal-comfort-modeling/blob/main/main.py): `main.py`
- [City configuration](https://github.com/wri/cities-thermal-comfort-modeling/blob/main/src/workers/city_data.py): `src/workers/city_data.py`
- [Job manager](https://github.com/wri/cities-thermal-comfort-modeling/blob/main/src/worker_manager/job_manager.py): `src/worker_manager/job_manager.py`
- [Tile processor](https://github.com/wri/cities-thermal-comfort-modeling/blob/main/src/workers/worker_tile_processor.py): `src/workers/worker_tile_processor.py`

### Configuration validation

- [Validation manager](https://github.com/wri/cities-thermal-comfort-modeling/blob/main/src/data_validation/manager.py): `src/data_validation/manager.py`
- [AOI evaluation](https://github.com/wri/cities-thermal-comfort-modeling/blob/main/src/data_validation/aoi_evaluator.py): `src/data_validation/aoi_evaluator.py`
- [Meteorology checks](https://github.com/wri/cities-thermal-comfort-modeling/blob/main/src/data_validation/meteorological_data_validator.py): `src/data_validation/meteorological_data_validator.py`

### Inputs and staging

- [CIF retrieval](https://github.com/wri/cities-thermal-comfort-modeling/blob/main/src/workers/source_cif_data_downloader.py): `src/workers/source_cif_data_downloader.py`
- [UMEP ERA5 prep](https://github.com/wri/cities-thermal-comfort-modeling/blob/main/src/workers/model_umep/worker_umep_met_processor.py): `src/workers/model_umep/worker_umep_met_processor.py`
- [UPenn ERA5 prep](https://github.com/wri/cities-thermal-comfort-modeling/blob/main/src/workers/model_upenn/worker_upenn_met_processor.py): `src/workers/model_upenn/worker_upenn_met_processor.py`
- [Raster and S3 data](https://github.com/wri/cities-thermal-comfort-modeling/blob/main/src/workers/worker_dao.py): `src/workers/worker_dao.py`
- [CTCM staging](https://github.com/wri/cities-thermal-comfort-modeling/blob/main/src/worker_manager/ctcm_layer_staging.py): `src/worker_manager/ctcm_layer_staging.py`

### Thermal models

- [UMEP plugin](https://github.com/wri/cities-thermal-comfort-modeling/blob/main/src/workers/model_umep/umep_plugin_processor.py): `src/workers/model_umep/umep_plugin_processor.py`
- [UPenn model](https://github.com/wri/cities-thermal-comfort-modeling/blob/main/src/workers/model_upenn/upenn_module_processor.py): `src/workers/model_upenn/upenn_module_processor.py`
- [Vegetation SVF](https://github.com/wri/cities-thermal-comfort-modeling/blob/main/src/workers/model_upenn/svfsCalculator_veg.py): `src/workers/model_upenn/svfsCalculator_veg.py`
- [Mean radiant temperature](https://github.com/wri/cities-thermal-comfort-modeling/blob/main/src/workers/model_upenn/weather_meanRadiantT.py): `src/workers/model_upenn/weather_meanRadiantT.py`
- [SOLWEIG library](https://github.com/wri/cities-thermal-comfort-modeling/blob/main/src/workers/model_upenn/libraries/solweiglib.py): `src/workers/model_upenn/libraries/solweiglib.py`

### Results and review

- [Ancillary outputs](https://github.com/wri/cities-thermal-comfort-modeling/blob/main/src/worker_manager/ancillary_files.py): `src/worker_manager/ancillary_files.py`
- [Run reporting](https://github.com/wri/cities-thermal-comfort-modeling/blob/main/src/worker_manager/reporter.py): `src/worker_manager/reporter.py`
- [Result validation](https://github.com/wri/cities-thermal-comfort-modeling/blob/main/src/data_validation/s3_postproc_results_validation.py): `src/data_validation/s3_postproc_results_validation.py`
- [QGIS results viewer](https://github.com/wri/cities-thermal-comfort-modeling/blob/main/src/worker_manager/ancillary_files.py): `src/worker_manager/ancillary_files.py`

### Other components

- **City operator**

## Connections

- City operator → CLI entry: runs
- CLI entry → City configuration: builds configuration (evidence: `main.py`)
- CLI entry → Validation manager: validates setup (evidence: `main.py`)
- CLI entry → Job manager: starts processing (evidence: `main.py`)
- CLI entry → CTCM staging: checks or publishes (evidence: `main.py`)
- CLI entry → Result validation: validates results (evidence: `main.py`)
- Validation manager → AOI evaluation: evaluates AOI (evidence: `src/data_validation/manager.py`)
- Validation manager → Meteorology checks: checks meteorology (evidence: `src/data_validation/manager.py`)
- Job manager → Validation manager: validates configuration (evidence: `src/worker_manager/job_manager.py`)
- Job manager → Tile processor: dispatches tiles (evidence: `src/worker_manager/job_manager.py`)
- Job manager → Ancillary outputs: prepares outputs (evidence: `src/worker_manager/job_manager.py`)
- Job manager → Run reporting: reports status (evidence: `src/worker_manager/job_manager.py`)
- Job manager → UMEP ERA5 prep: prepares UMEP meteorology (evidence: `src/worker_manager/job_manager.py`)
- Job manager → UPenn ERA5 prep: prepares UPenn meteorology (evidence: `src/worker_manager/job_manager.py`)
- Tile processor → CIF retrieval: retrieves CIF data (evidence: `src/workers/worker_tile_processor.py`)
- Tile processor → UMEP plugin: runs UMEP steps (evidence: `src/workers/worker_tile_processor.py`)
- Tile processor → UPenn model: runs UPenn model (evidence: `src/workers/worker_tile_processor.py`)
- UPenn model → Vegetation SVF: calculates vegetation SVF (evidence: `src/workers/model_upenn/upenn_module_processor.py`)
- UPenn model → Mean radiant temperature: computes radiant temperature (evidence: `src/workers/model_upenn/upenn_module_processor.py`)
- Mean radiant temperature → SOLWEIG library: uses library (evidence: `src/workers/model_upenn/weather_meanRadiantT.py`)
- CTCM staging → Raster and S3 data: reads or writes data (evidence: `src/worker_manager/ctcm_layer_staging.py`)
- Result validation → Raster and S3 data: checks stored results (evidence: `src/data_validation/s3_postproc_results_validation.py`)
- Ancillary outputs → QGIS results viewer: creates QGIS viewer (evidence: `src/worker_manager/ancillary_files.py`)
