Skip to content

Merge

merge_simulation_files combines multiple scene JSON files that share the same bodies/terrain into one scene with extra batches, resampling every file but the first onto the first file's timeline by nearest timestamp. Pass selections to take only some of a file's batches (the CLI spells this file.json#1,3). See Comparing multiple runs for the CLI-facing version of this.

simview.merge.merge_simulation_files

merge_simulation_files(
    paths: Sequence[str | Path],
    selections: Sequence[str | Sequence[int] | None]
    | None = None,
) -> dict

Load and merge paths into a single {"model": ..., "states": ...} dict where each file's batches are concatenated into the output's batch dimension.

selections, if given, must be parallel to paths: each entry is None (contribute every batch of that file) or a batch selector -- a string like "1", "0,2", "1-3", "-1" or a batch name, or an explicit sequence of indices (see parse_batch_selection). Selecting a subset is what lets several files that each carry the same ground-truth batch be merged without duplicating it, and it is the one case where a single file is a valid merge input.

simview.merge.parse_batch_selection

parse_batch_selection(
    selector: str | Sequence[int],
    batch_size: int,
    batch_names: Sequence[str] | None,
    label: str,
) -> list[int]

Resolve one file's batch selector to a list of that file's batch indices.

selector is either an explicit sequence of indices or a comma-separated string whose entries are an index (2), a negative index counting from the end (-1), an inclusive range (0-3), or one of the file's own batchNames. Anything that parses as an index or a range is read as such, so a batch named "2" can only be selected by its index. The selected order is the merged order, and selecting the same batch twice is rejected as a typo rather than silently duplicating it.

simview.merge.split_batch_spec

split_batch_spec(spec: str) -> tuple[str, str | None]

Split a CLI input like scene.json#1,3 into ("scene.json", "1,3"), or return (spec, None) when it names no batch subset.

Purely syntactic apart from one filesystem check: an existing local file wins over the selector reading (mirroring remote.is_remote_spec), so a file literally named odd#name.json still opens as itself.