204 lines
6.7 KiB
Python
204 lines
6.7 KiB
Python
"""
|
|
A collection of delightfully unique chunk specimens, for science.
|
|
|
|
IMPORTANT: the viewer should be set with `RERUN_CHUNK_MAX_BYTES=0` to disable the compactor.
|
|
|
|
To add new specimens to the zoo, add a function whose name starts with "specimen_".
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
from typing import TYPE_CHECKING
|
|
|
|
import numpy as np
|
|
|
|
import rerun as rr
|
|
|
|
if TYPE_CHECKING:
|
|
from collections.abc import Sequence
|
|
|
|
|
|
def frame_times(t: int | Sequence[int], *args: int) -> list[rr.TimeColumn]:
|
|
if isinstance(t, int):
|
|
t = [t]
|
|
else:
|
|
t = list(t)
|
|
if args:
|
|
t.extend(args)
|
|
return [rr.TimeColumn("frame", sequence=t)]
|
|
|
|
|
|
def set_frame_time(t: int) -> None:
|
|
rr.set_time("frame", sequence=t)
|
|
|
|
|
|
def specimen_two_rows_span_two_chunks() -> None:
|
|
"""Two rows spanning two chunks."""
|
|
|
|
rr.send_columns("/rows_span_two_chunks", frame_times(0, 2), rr.Points2D.columns(positions=[(0, 1), (2, 3)]))
|
|
rr.send_columns("/rows_span_two_chunks", frame_times(0, 2), rr.Points2D.columns(radii=[10, 11]))
|
|
|
|
|
|
def specimen_two_rows_span_two_chunks_sparse() -> None:
|
|
"""Two rows spanning two chunks with partially matching timestamps (so sparse results)."""
|
|
|
|
rr.send_columns(
|
|
"/rows_span_two_chunks_sparse",
|
|
frame_times(0, 2, 3),
|
|
rr.Points2D.columns(positions=[(0, 1), (2, 3), (4, 5)]),
|
|
)
|
|
rr.send_columns("/rows_span_two_chunks_sparse", frame_times(0, 2, 4), rr.Points2D.columns(radii=[10, 11, 12]))
|
|
|
|
|
|
def specimen_archetype_with_clamp_join_semantics() -> None:
|
|
"""Single row of an archetype with clamp join semantics (Points2D)."""
|
|
rr.send_columns(
|
|
"/archetype_with_clamp_join_semantics",
|
|
frame_times(0),
|
|
[
|
|
*rr.Points2D.columns(
|
|
positions=[(i, i) for i in range(10)],
|
|
).partition([10]),
|
|
*rr.Points2D.columns(radii=2),
|
|
],
|
|
)
|
|
|
|
|
|
def specimen_archetype_with_latest_at_semantics() -> None:
|
|
"""Archetype spread over a multi-row chunk and a single row chunk, with latest-at semantics."""
|
|
rr.send_columns(
|
|
"/archetype_chunk_with_latest_at_semantics",
|
|
frame_times(range(10)),
|
|
rr.Points2D.columns(positions=[(i, i) for i in range(10)], class_ids=range(10)),
|
|
)
|
|
|
|
set_frame_time(5)
|
|
rr.log("/archetype_chunk_with_latest_at_semantics", rr.Points2D.from_fields(radii=2))
|
|
|
|
|
|
def specimen_archetype_with_clamp_join_semantics_two_chunks() -> None:
|
|
"""Single row of an archetype with clamp join semantics (Points2D), across two chunks."""
|
|
rr.send_columns(
|
|
"/archetype_with_clamp_join_semantics_two_batches",
|
|
frame_times(0),
|
|
rr.Points2D.columns(positions=[(i, i) for i in range(10)]).partition([10]),
|
|
)
|
|
|
|
rr.send_columns(
|
|
"/archetype_with_clamp_join_semantics_two_batches",
|
|
frame_times(0),
|
|
rr.Points2D.columns(radii=2),
|
|
)
|
|
|
|
|
|
def specimen_archetype_without_clamp_join_semantics() -> None:
|
|
"""Single row of an archetype without clamp join semantics (Mesh3D)."""
|
|
rr.send_columns(
|
|
"/archetype_without_clamp_join_semantics",
|
|
frame_times(0),
|
|
[
|
|
*rr.Mesh3D.columns(
|
|
vertex_positions=[(0, 0, 0), (0, 1, 0), (1, 1, 0), (1, 0, 0)],
|
|
vertex_colors=[(255, 0, 0), (0, 255, 0), (0, 0, 255), (255, 255, 0)],
|
|
).partition([4]),
|
|
*rr.Mesh3D.columns(triangle_indices=[(0, 1, 2), (0, 2, 3)]).partition([2]),
|
|
],
|
|
)
|
|
|
|
|
|
def specimen_many_rows_with_mismatched_instance_count() -> None:
|
|
"""Points2D across many timestamps with varying and mismatch instance counts."""
|
|
|
|
# Useful for dataframe view row expansion testing.
|
|
|
|
np.random.seed(0)
|
|
positions_partitions = np.random.randint(
|
|
3,
|
|
15,
|
|
size=100,
|
|
)
|
|
batch_size = int(np.sum(positions_partitions))
|
|
|
|
# Shuffle the color partitions to induce the mismatch
|
|
colors_partitions = positions_partitions.copy()
|
|
np.random.shuffle(colors_partitions)
|
|
|
|
positions = np.random.rand(batch_size, 2)
|
|
colors = np.random.randint(0, 255, size=(batch_size, 4))
|
|
|
|
rr.send_columns(
|
|
"/many_rows_with_mismatched_instance_count",
|
|
frame_times(range(len(positions_partitions))),
|
|
[
|
|
*rr.Points2D.columns(positions=positions).partition(positions_partitions),
|
|
*rr.Points2D.columns(colors=colors).partition(colors_partitions),
|
|
],
|
|
)
|
|
|
|
|
|
# TODO(ab): add variants (unordered, overlapping timestamps, etc.)
|
|
def specimen_scalars_interlaced_in_two_chunks() -> None:
|
|
"""Scalar column stored in two chunks, with interlaced timestamps."""
|
|
rr.send_columns(
|
|
"/scalars_interlaced_in_two_chunks",
|
|
frame_times(0, 2, 5, 6, 8),
|
|
rr.Scalars.columns(scalars=[0, 2, 5, 6, 8]),
|
|
)
|
|
rr.send_columns(
|
|
"/scalars_interlaced_in_two_chunks",
|
|
frame_times(1, 3, 7),
|
|
rr.Scalars.columns(scalars=[1, 3, 7]),
|
|
)
|
|
|
|
|
|
def specimen_archetype_chunk_with_clear() -> None:
|
|
"""Archetype spread on multi-row and single-row chunks, with a `Clear` in the middle."""
|
|
rr.send_columns(
|
|
"/archetype_chunk_with_clear",
|
|
frame_times(range(10)),
|
|
rr.Points2D.columns(positions=[(i, i) for i in range(10)], class_ids=range(10)),
|
|
)
|
|
|
|
set_frame_time(0)
|
|
rr.log("/archetype_chunk_with_clear", rr.Points2D.from_fields(radii=2))
|
|
|
|
set_frame_time(5)
|
|
rr.log("/archetype_chunk_with_clear", rr.Clear(recursive=False))
|
|
|
|
|
|
def main() -> None:
|
|
parser = argparse.ArgumentParser(
|
|
description="Logs a bunch of chunks of various typologies. Use `RERUN_CHUNK_MAX_BYTES=0`!",
|
|
)
|
|
parser.add_argument("--filter", type=str, help="Only run specimens whose name contains this substring")
|
|
rr.script_add_args(parser)
|
|
args = parser.parse_args()
|
|
|
|
rr.script_setup(args, "rerun_example_chunk_zoo", default_blueprint=rr.blueprint.TextDocumentView(origin="/info"))
|
|
|
|
# Round up the specimens
|
|
specimens = [
|
|
globals()[name]
|
|
for name in globals()
|
|
if name.startswith("specimen_") and callable(globals()[name]) and (not args.filter or args.filter in name)
|
|
]
|
|
|
|
specimen_list = "\n".join([f"| {s.__name__.removeprefix('specimen_')} | {s.__doc__} |" for s in specimens])
|
|
markdown = (
|
|
"# Chunk Zoo\n\n"
|
|
"This recording contains a variety of chunks of various typologies, for testing purposes.\n\n"
|
|
"**IMPORTANT**: The viewer should be set with `RERUN_CHUNK_MAX_BYTES=0` to disable the compactor.\n\n"
|
|
"### Specimens\n\n"
|
|
f"| **Item** | **Description** |\n| --- | --- |\n{specimen_list}"
|
|
)
|
|
rr.log("info", rr.TextDocument(text=markdown, media_type="text/markdown"), static=True)
|
|
|
|
# Set the specimens loose
|
|
for specimen in specimens:
|
|
specimen()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|