> 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.

# Calibration

Calibration runs tune selected scenario parameters against measured link data.
The AODT client workflow first runs the base EM simulation to populate the
database and exported result tables, then reloads the same scenario with
calibration settings and calls `run_calibration()`.

Use this workflow when you have measured RU/UE link data and want the worker to
optimize calibration targets such as UE settings, RU settings, beams, building
materials, or vegetation materials.

## Workflow

The typical calibration workflow is:

1. Create a `dt_client.DigitalTwinClient`.
2. Generate or load a base EM simulation YAML with `RAYPATHS` output enabled.
3. Start the base scenario with `client.start(...)`.
4. Run `client.run_full_simulation()` to write the baseline outputs.
5. Generate or load a calibration YAML for the same scenario, keeping the
   `sim`, `db`, and `gis` sections aligned with the base YAML.
6. Start the calibration scenario with `client.start(...)`.
7. Call `client.run_calibration()`.

The base simulation run is required because calibration reads the exported
simulation data back from the configured database and S3/Iceberg storage. The
base scenario must enable full `RAYPATHS` output before running calibration.

## Example

Run the calibration example:

```bash
python client/examples/example_calibration.py \
  --server_address localhost:50051 \
  --s3_endpoint http://minio:9000
```

The example generates two YAML configurations:

* A simulation YAML, used to load and run the base EM scenario.
* A calibration YAML, used to add calibration targets, measurements, timeline,
  and output location.

You can override the scene, asset config, S3 settings, and Iceberg catalog:

```bash
python client/examples/example_calibration.py \
  --server_address localhost:50051 \
  --scene test_data/maps/hels \
  --asset_config client/examples/example_client_assets.yml \
  --s3_endpoint http://minio:9000 \
  --s3_bucket aerial-data \
  --iceberg_uri http://nessie:19120/iceberg
```

The core client pattern is:

```python
import dt_client

client = dt_client.DigitalTwinClient("localhost:50051")
client.start_server_log_streaming("dt_server.log", "INFO")

client.start(simulation_yaml_content)
client.run_full_simulation()

client.start(calibration_yaml_content)
result = client.run_calibration()

print(result["stage"])
print(result["total_time_seconds"])
print(result["message"])
```

`run_calibration()` is a blocking streaming RPC. It reports coarse progress
stages such as `started`, `building_edges`, `running`, and `completed`, then
returns a dictionary with `stage`, `total_time_seconds`, and `message`.

## Calibration Configuration

Calibration settings are emitted in the top-level `cal` section of the scenario
YAML. When building YAML with the Config Builder API, configure the calibration
section after the base simulation, storage, panels, nodes, mobility, and result
tables are defined.

The calibration YAML should describe the same scenario that produced the
baseline results. Keep the `sim`, `db`, and `gis` sections the same between the
base simulation YAML and the calibration YAML so calibration reads from the same
database, exported tables, scene, and GIS assets.

When you already have a generated base YAML file, prefer loading it with
`SimConfig.from_yaml_file(...)` and then adding the calibration section. This
reduces drift between the base simulation YAML and the calibration YAML:

```python
from _config import SimConfig

config = SimConfig.from_yaml_file("base_simulation.yml")

# Add the top-level cal section for the calibration run.
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")
```

The required calibration settings are:

* `set_calibration_targets(...)`: choose which groups calibration should tune.
* `add_calibration_measurement(...)`: add measured data for each RU/UE link.
* `set_calibration_timeline(...)`: choose the time indices used for calibration.
* `set_calibration_output(...)`: set the output folder key under the configured
  S3 bucket.

For example:

```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")
```

The shipped example calibrates UE settings only. Other target flags support
building materials, vegetation materials, RU settings, and RU beam settings when
the scenario and measurement data provide the required inputs.

## Inputs And Outputs

Before running calibration, make sure the scenario has:

* Valid S3 settings with Parquet export enabled.
* An Iceberg catalog configuration if your deployment reads exported tables
  through Iceberg.
* `DBTable.RAYPATHS` enabled with the `full` table option.
* Calibration measurement CSV files for the RU/UE links being calibrated.
* A calibration output folder key under the configured S3 bucket.

Calibration writes its artifacts under the configured output folder. Use server
logs, the returned `message`, and the configured S3 location to inspect the
result of a run.

## When To Use

Use Calibration when:

* You have measurement data for one or more RU/UE links.
* You need to tune selected scenario parameters against those measurements.
* You can first run the base EM scenario to produce the exported data that
  calibration reads.

Use [Batched Mode](/batched-mode) for a regular full EM simulation that does not
need calibration. Use [Interactive Mode](/dynamic-mode) when application logic
needs selected time steps or NumPy CIR arrays during the run.

## API Reference

See the [DigitalTwinClient API](/api/client) for `start`,
`run_full_simulation`, `run_calibration`, and server log streaming methods.

See the [Config Builder API](/api/config) for simulation YAML construction,
including `SimConfig`, `S3Config`, `DBTable`, panels, nodes, material
calibration helpers, and calibration run settings.