> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.nvidia.com/aerial/aodt/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.nvidia.com/aerial/aodt/_mcp/server.

# Configuring Sim YAML

Simulation YAML defines the scenario that the AODT client loads before running
[Interactive Mode](/dynamic-mode), [Batched Mode](/batched-mode), or
[Calibration](/calibration) workflows. You can write YAML directly, but the
recommended path is to generate it with the `_config` Python module so object
relationships and required fields are checked before the run starts.

After generating the YAML, pass its contents to `client.start(yaml_content)` to
load the scenario on the worker.

## Recommended Workflow

Use the Config Builder when creating YAML in code:

1. Create a `SimConfig` with the scene, simulation mode, and asset config.
2. Set the simulation ID and database connection.
3. Configure S3 storage.
4. Set the timeline and selected result tables.
5. Enable Parquet export and, when needed, configure the catalog.
6. Define panels, DUs, RUs, UEs, and mobility.
7. Optionally add calibration settings when the YAML will be used for a calibration run.
8. Export the configuration to YAML.

```python
from _config import SimConfig, SimMode, DBTable, S3Config
from omegaconf import OmegaConf

config = SimConfig("test_data/maps/tokyo", SimMode.EM, "examples/example_client_assets.yml")
config.set_simulation_id("my_sim")

s3 = S3Config(
    bucket="aerial-data",
    provider="minio",
    endpoint_url="http://minio:9000",
    access_key="minioadmin",
    secret_key="minioadmin",
)
config.set_s3_config(s3)

config.set_num_batches(1)
config.set_timeline(slots_per_batch=12, realizations_per_slot=1)
config.add_tables_to_db(DBTable.CIRS)
config.add_tables_to_db(DBTable.CFRS)

config.enable_parquet_export(timesteps_per_file=100)
config.add_parquet_s3_config(s3)

OmegaConf.save(config.to_dict(), "output.yml")
```

For a complete example, see `client/examples/example_client_yaml_config.py`.

## Calibration YAML

Calibration uses the same base scenario as a regular EM simulation, with an
additional top-level `cal` section. The `cal` section is not required for normal
simulation YAML; add it only when the scenario will be loaded for
`client.run_calibration()`. The usual calibration workflow is to run the base
simulation YAML first, then reload the scenario with calibration settings and call
`client.run_calibration()`.

Before adding calibration settings, make sure the base simulation config:

* Uses valid S3 settings and enables Parquet export.
* Configures an Iceberg catalog when your deployment reads exported tables
  through Iceberg.
* Adds `DBTable.RAYPATHS` and sets the `full` raypaths table option, because
  calibration reads the exported ray-path data.

```python
config.add_tables_to_db(DBTable.RAYPATHS)
config.add_table_option("raypaths", "full")
```

Then add the calibration section:

```python
config.set_calibration_targets(
    materials=False,
    veg_materials=False,
    rus=False,
    rus_beams=False,
    ues=True,
)

config.add_calibration_measurement(
    ru_id=1,
    ue_id=1,
    measurement_file="/opt/nvidia/aodt_sim/measurements/ru1_ue1.csv",
)

config.set_calibration_timeline(start=0, step=1, end=640)
config.set_calibration_output("test_calibration_run/output")
```

`set_calibration_targets(...)` must be called before adding measurements,
timeline, or output settings. Each measurement identifies the RU/UE link and the
measurement CSV that calibration should compare against. The output folder key
is written under the configured S3 bucket.

For a complete generated-YAML example, see
`client/examples/example_client_calibration_yaml_config.py`. For the runtime
client workflow, see [Calibration](/calibration).

## Timeline Modes

The timeline determines how simulations are indexed:

* **Duration/interval:** use `config.set_timeline(duration=..., interval=...)`.
* **Slots/symbols:** use `config.set_timeline(slots_per_batch=..., realizations_per_slot=...)`.

Do not mix both timeline styles in the same configuration. RAN mode requires the
slots/symbols style.

## Ordering Rules

The builder validates common configuration mistakes. Examples include:

* A timeline must use either duration/interval or slots/symbols, not both.
* S3 configs must include a bucket and supported provider, and MinIO configs need an endpoint URL.
* An RU must reference an existing DU and a valid panel, and its frequency must match the assigned panel.
* A UE must have at least one waypoint or a GPX source before calling `add_ue()`.
* Calibration details require `set_calibration_targets(...)` first, at least one measurement, a positive timeline step, and a non-empty output folder key.

## API Reference

See the [Config Builder API](/api/config) for all configuration classes,
including `SimConfig`, `S3Config`, `Panel`, `Nodes`, `DU`, `RU`, `UE`,
`SimMode`, and `DBTable`.

See [AODT Client](/aodt-client) for workflows that consume the generated YAML.