Configuration Reference¶
PASSAGE is configured through config/config.yaml. The shipped file is the configuration that built PASSAGE v1.0. This page documents every key, in the order of the generation workflow.
How generate Reads This File¶
The key generation.dataset_version selects the generator that built PASSAGE v1.0 (the release generator). Keep the value shipped in config/config.yaml: another value stops passage generate with an error, and without the key passage generate runs another generation path, which the v1.0 release does not use.
The release generator also checks three rules before it starts:
- exactly three solvers, with unique names and the objectives
elevation,energyandslope_uphill; diagonal_movement: alwaysfor every solver;obstacles.impassable: true.
Some keys stay in the file but are not read by the v1.0 release generator:
| Key | Why it is not used |
|---|---|
splits.enabled | The release generator always uses splits.ratios and splits.seed |
generation.preview_images.* | Preview rows come from export.sample.num_samples; passage compress renders their images |
solvers[].backend, solver, heuristic, max_marker_retries | Copied into each scene's metadata, but the labels come from the exact reference A* solver |
obstacles.obstacle_penalty | Applies only when impassable: false, which the release generator refuses |
solvers[].diagonal_movement is read only to check that it is always.
Resolutions¶
List of crop sizes to generate. A resolution \(R\) produces scenes of \(R \times R\) cells. With 30 m cells, the nominal side is \(R \times 30\) m; the actual ground spacing varies with latitude.
| Resolution | Nominal side |
|---|---|
| 64 | 1.92 km |
| 128 | 3.84 km |
| 256 | 7.68 km |
| 512 | 15.36 km |
| 1024 | 30.72 km |
| 2048 | 61.44 km |
| 4096 | 122.88 km |
A source tile holds 3600 × 3600 cells. A crop is cut wherever it falls, so it can span two tiles per axis; a 4096 crop, wider than one tile, can span three.
Sample Counts¶
num_samples:
64: 1000000
128: 1000000
256: 1000000
512: 1000000
1024: 250000
2048: 100000
4096: 50000
Number of scenes to generate per resolution: 4,400,000 in total. The value can be a single integer (applied to every resolution) or a per-resolution mapping.
Tip
CLI --num-samples overrides the config value for all selected resolutions.
Splits¶
| Key | Description |
|---|---|
ratios | Target shares for scene counts and weights for assigning geographic blocks. With the hold-out mask, only the non-test splits share blocks outside the mask |
seed | Seeds both the scene-to-split assignment and the geographic block assignment |
enabled | Not read by the v1.0 release generator |
See Splits for the geographic rules.
Hold-Out Region¶
The mask is a 181 × 361 pixel PNG with one pixel per degree: row 0 is latitude +90°, column 0 is longitude −180°. Non-zero pixels mark hold-out tiles. Tiles inside the mask belong to the test split only, and every test scene comes from them. Supply an authorised mask at the configured path; it is not included in every source distribution. For the legacy generator, use a 1-bit, grayscale, RGB or RGBA PNG; RGB channels must agree. When hold-out filtering is enabled, a missing, unreadable or invalid mask stops generation.
The public PASSAGE v1.0 hold-out mask is available separately from the dataset repository. To obtain it manually at the default path and verify its bytes before generation:
mkdir -p assets
test ! -e assets/hold_out_mask.png && test ! -L assets/hold_out_mask.png || { echo "Mask path already exists; verify it separately"; exit 1; }
curl --fail --location --output assets/hold_out_mask.png \
https://huggingface.co/datasets/thalesgroup/passage/resolve/v1.0/assets/hold_out_mask.png
printf '%s %s\n' \
d53526b04dfa23767b8558126a4372cf7ab96c593079e149a63c497df633715d \
assets/hold_out_mask.png | sha256sum --check
Do not proceed if the download or hash check fails. The mask is a geographic control, not a test scene; obtaining it does not read the test split. Review the dataset terms and datasheet for the applicable use conditions. Generation does not download the mask automatically.
Generation¶
generation:
dataset_version: passage-successor-v1
seed: 42
max_scene_attempts: 100
max_reference_expansions: null
geographic_policy:
block_degrees: 5
buffer_tiles: 1
preview_images:
enabled: true
resolutions: [64, 128, 256, 512, 1024, 2048, 4096]
num_samples_per_split: 64
| Key | Description |
|---|---|
dataset_version | Selects the release generator. Keep the shipped value |
seed | Seeds each scene: blake2b(seed, resolution, index, split) sets its tile, crop, markers and obstacles |
max_scene_attempts | Crops tried for one scene before it is recorded as rejected |
max_reference_expansions | Search budget of the reference solver. null means no budget; with a budget, an unfinished search is recorded as failed |
geographic_policy.block_degrees | Side of the geographic blocks, in degrees. It must divide 180 and exceed twice buffer_tiles |
geographic_policy.buffer_tiles | Width of the guard ring around a crop's tiles, in tiles |
preview_images.* | Not read by the v1.0 release generator |
Solvers¶
solvers:
- name: astar_elevation
backend: grid
diagonal_movement: always
max_marker_retries: 10
solver: astar
cost_model: elevation
weight: 62.4
heuristic: euclidean
- name: astar_energy
backend: grid
diagonal_movement: always
max_marker_retries: 10
solver: astar
cost_model: energy
weight: 1125.3
heuristic: euclidean
- name: astar_slope
backend: grid
diagonal_movement: always
max_marker_retries: 10
solver: astar
cost_model: slope_uphill
weight: 8886.2
heuristic: euclidean
Each entry of the list defines one objective:
| Key | Options | Description |
|---|---|---|
name | text | Solver name, used in column names (path_<name>_free, path_<name>_obstacles) and folder names |
cost_model | elevation, slope_uphill, energy | Edge cost function. distance and absolute_elevation also exist but are not used by the v1.0 release |
weight | float | Weight \(w\) of the objective |
diagonal_movement | always | Eight-connected grid; a diagonal step is checked against its destination cell only |
backend, solver, heuristic, max_marker_retries | Recorded in the metadata; not used by the v1.0 release generator |
Every label comes from an exact A* reference that computes in float64. See Cost Models for the formulas and Solvers & Heuristics for the solvers.
Obstacles¶
obstacles:
enabled: true
ratio_max: 0.30
shape:
size:
min_ratio: 0.02
max_ratio: 0.25
n:
min: 1.0
max: 80.0
distribution:
type: log_uniform
generation:
max_attempts: 50
candidates_per_mask: 200
impassable: true
obstacle_penalty: 1e8
| Key | Description |
|---|---|
enabled | Add obstacles to each scene |
ratio_max | Upper bound of the obstacle coverage. Each mask draws its target coverage uniformly between 0 and ratio_max |
shape.size.min_ratio / max_ratio | Full width and height of a superellipse, as a fraction of the crop side; its semi-axes are half of these |
shape.n.min / max | Exponent range (\(n=1\): diamond, \(n=2\): ellipse, large \(n\): close to a rectangle) |
shape.n.distribution.type | Distribution of the exponent: log_uniform (shipped), uniform, beta (parameters a, b) or exponential (parameter lambda) |
generation.max_attempts | Maximum complete mask attempts before falling back to an empty mask. Marker checks on each proposal normally make the first attempt sufficient |
generation.candidates_per_mask | Maximum placement rounds per mask. A round stops after 10 proposals that cover an endpoint |
impassable | true: obstacle cells are blocked, and a crop whose obstacles disconnect the start from the goal is rejected. The release generator requires true |
obstacle_penalty | Elevation penalty added to obstacle cells when impassable: false; not used by the v1.0 release |
Obstacles never cover the start or the goal. See Obstacle Generation for the superellipse math.
Export¶
export:
default: 1024x1024_samples
sample:
num_samples: 64
compression_level: 12
chunk_size:
64: 20000
128: 10000
256: 2500
512: 1500
1024: 250
2048: 75
4096: 25
| Key | Description |
|---|---|
default | Default Hugging Face configuration named in the dataset card |
sample.num_samples | Rows per split in each <R>x<R>_samples configuration: the lowest scene IDs of the split, with rendered preview images |
compression_level | Zstandard level of the Parquet files written by passage compress |
chunk_size | Rows per Parquet shard, per resolution |
Full Example¶
Complete config/config.yaml (comments removed)
resolutions: [64, 128, 256, 512, 1024, 2048, 4096]
export:
default: 1024x1024_samples
sample:
num_samples: 64
compression_level: 12
chunk_size:
64: 20000
128: 10000
256: 2500
512: 1500
1024: 250
2048: 75
4096: 25
num_samples:
64: 1000000
128: 1000000
256: 1000000
512: 1000000
1024: 250000
2048: 100000
4096: 50000
splits:
enabled: true
ratios:
train: 0.9
calibration: 0.02
validation: 0.04
test: 0.04
seed: 42
generation:
dataset_version: passage-successor-v1
seed: 42
max_scene_attempts: 100
max_reference_expansions: null
geographic_policy:
block_degrees: 5
buffer_tiles: 1
preview_images:
enabled: true
resolutions: [64, 128, 256, 512, 1024, 2048, 4096]
num_samples_per_split: 64
hold_out:
enabled: true
mask_path: assets/hold_out_mask.png
solvers:
- name: astar_elevation
backend: grid
diagonal_movement: always
max_marker_retries: 10
solver: astar
cost_model: elevation
weight: 62.4
heuristic: euclidean
- name: astar_energy
backend: grid
diagonal_movement: always
max_marker_retries: 10
solver: astar
cost_model: energy
weight: 1125.3
heuristic: euclidean
- name: astar_slope
backend: grid
diagonal_movement: always
max_marker_retries: 10
solver: astar
cost_model: slope_uphill
weight: 8886.2
heuristic: euclidean
obstacles:
enabled: true
ratio_max: 0.30
shape:
size:
min_ratio: 0.02
max_ratio: 0.25
n:
min: 1.0
max: 80.0
distribution:
type: log_uniform
generation:
max_attempts: 50
candidates_per_mask: 200
impassable: true
obstacle_penalty: 1e8