Commit e9e82f85 authored by Eric Duminil's avatar Eric Duminil
Browse files

Updated Docs

parent c8bed3df
......@@ -6,8 +6,6 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
`simstadt` is a Python library for running and testing [SimStadt](https://simstadt.hft-stuttgart.de/) workflows programmatically. SimStadt is a city simulation tool for energy/urban analysis. The library wraps SimStadt's CLI to execute workflows against CityGML files and parse the results into pandas DataFrames.
This project is in early development. The goal is to consolidate code from two prior projects (`old/cgsc/` and `old/sektorsim/`) into a proper library under `src/simstadt/`.
## Commands
This project uses [uv](https://docs.astral.sh/uv/) as the package manager.
......@@ -16,14 +14,17 @@ This project uses [uv](https://docs.astral.sh/uv/) as the package manager.
# Install dependencies and set up venv
uv sync
# Run the CLI entry point
# Run the CLI health check
uv run simstadt
# Run tests (once added — use pytest)
# Run all tests
uv run pytest
# Run only non-integration tests (no SimStadt required)
uv run pytest -m "not integration"
# Run a single test
uv run pytest tests/test_foo.py::TestClass::test_method
uv run pytest tests/test_foo.py::test_method
```
SimStadt itself must be installed separately. Its location is resolved via:
......@@ -40,18 +41,53 @@ The library wraps SimStadt's command-line interface. The core flow is:
4. Output files written by SimStadt are detected by comparing filesystem mtimes before/after the run
5. Output files are parsed into typed `SimStadtResults` subclasses
### Key classes to port from `old/`
## Source layout
```
src/simstadt/
__init__.py # public API
runner.py # core workflow execution, SimStadt discovery
workflows.py # high-level helpers (heatdemand_simulation, etc.)
utils.py # random_id, clean_old_workflows, etc.
templates/ # bundled workflow templates shipped with the package
results/
__init__.py # factory function, re-exports
base.py # SimStadtResults ABC
kpi.py # KPI dataclass
providers.py # Providers enum
heat_demand.py
photovoltaic.py
load_profile.py
solar_potential.py
green_water.py
```
## Key design decisions
### `run_workflow_with_citygml` — main entry point
- **`SimStadtResults`** (`old/cgsc/lib/simstadt_results.py`) — Abstract base class with factory pattern. Subclasses:
- `HeatDemandResults` — parses DIN18599 CSV output
- `PhotovoltaicResults` — parses PV potential CSV output
- `GreenWaterResults` — parses hourly greenwater CSV with multi-level headers
- Each subclass exposes `.dataframe`, `.kpis`, `.diagrams`, `.csv_path`, `.to_json()`/`.from_json()`
- Provider-to-class registration via `__init_subclass__` (registry pattern)
```python
run_workflow_with_citygml(
template, # str name resolved via SIMSTADT_TEMPLATE_PATH, or full Path
citygml_path, # Path to the CityGML input file
replaces=None, # dict of XML-fragment regex replacements for params.xml
description=None, # human-readable label on the result object
destination=None, # workflow folder name; defaults to a timestamped random id
project_path=None, # see project path resolution below
)
```
Returns a typed `SimStadtResults` subclass (e.g. `HeatDemandResults`, `PhotovoltaicResults`), detected automatically from the workflow's `params.xml`.
### Project path resolution (`runner._resolve_project`)
- **`run_workflow_with_citygml()`** (`old/cgsc/lib/run_simstadt_workflow.py`) — Main entry point for running a simulation. Takes a template name/path, a CityGML path, and optional parameter replacements dict.
1. Explicit `project_path` always wins — CityGML is copied there if not already present
2. CityGML inside a `.proj` folder — its parent is used as project
3. Neither — a temporary repository is created at `SIMSTADT_TEMP_REPO` (`/tmp/simstadt_repo/`)
- **Workflow simulation helpers** (`old/cgsc/lib/simstadt_workflows.py`) — High-level functions (`photovoltaic_simulation`, `heatdemand_simulation`, `greenwater_simulation`) that call `run_workflow_with_citygml` with pre-built parameter dicts.
### Bundled templates
High-level workflow functions (`photovoltaic_simulation`, etc.) in `workflows.py` use bundled templates via `BUNDLED_TEMPLATES = Path(__file__).parent / "templates"`. `run_workflow_with_citygml` resolves templates via `SIMSTADT_TEMPLATE_PATH` env var, a local `templates/` directory, or an explicit `Path`.
### Parameter replacement convention
......@@ -60,9 +96,14 @@ Workflow parameters are replaced via regex on `params.xml` content. Keys are XML
{"<string>METEONORM_FILE</string>": "<string>Wuerzburg-hour.csv</string>"}
```
### Workflow templates
### Results registry
`SimStadtResults` subclasses register themselves via `__init_subclass__`. The factory `create_simstadt_results()` reads the workflow provider from `params.xml` and dispatches to the correct subclass automatically.
### Test markers
Templates live in a `templates/` directory alongside the project. Template names follow the pattern `NNN_WorkflowName` (e.g. `101_HeatDemand`, `103_PV`, `104_HeatDemandWithShadow`).
- `integration` — requires SimStadt installed, runs full workflows end-to-end
- `slow` — takes a long time (used together with `integration` on workflow tests)
### SimStadt project structure on disk
......
......@@ -18,7 +18,7 @@ pip install simstadt
## Usage
```python
from simstadt import heatdemand_simulation, photovoltaic_simulation
from simstadt import heatdemand_simulation, photovoltaic_simulation, clean_old_workflows
results = heatdemand_simulation("path/to/city.gml", "Wuerzburg-hour.csv")
print(results.dataframe)
......@@ -26,17 +26,45 @@ print(results.kpis)
pv = photovoltaic_simulation("path/to/city.gml", "Wuerzburg-hour.csv")
print(pv.dataframe)
# Remove workflow folders older than 1 hour from a project directory
clean_old_workflows(Path("path/to/project.proj"))
```
For more control, use `run_workflow_with_citygml` directly:
```python
from simstadt import run_workflow_with_citygml
results = run_workflow_with_citygml(
template="104_HeatDemandWithShadow", # name in templates/ or full Path
citygml_path="path/to/city.gml",
replaces={"<string>METEONORM_FILE</string>": "<string>Wuerzburg-hour.csv</string>"},
project_path=Path("path/to/project.proj"), # optional
)
print(results.kpis)
```
SimStadt is located automatically via the `SIMSTADT_FOLDER` environment variable, or by searching `~/Desktop` for a `SimStadt2_0.*/` directory.
Workflow templates are resolved via `SIMSTADT_TEMPLATE_PATH`, or a `templates/` directory in the current working directory.
Bundled workflow templates are used by default. Custom templates are resolved via `SIMSTADT_TEMPLATE_PATH`, or a `templates/` directory in the current working directory.
If no project path is specified, workflows are run in a temporary repository under `/tmp/simstadt_repo/`.
## Health check
```bash
simstadt
```
Prints the detected SimStadt installation path and version.
## Development
```bash
uv sync
uv run pytest
uv run pytest # all tests
uv run pytest -m "not integration" # skip tests requiring SimStadt
```
## AI agent
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment