Hierarchical counts¶
Use rfgen.planning to make a reproducible count plan before later components
select identities, event timing, or waveforms. One CountConfig distribution
is drawn for the number of systems, then once for every system’s device count,
then once for every device’s event count. The returned vectors follow that
canonical system/device order.
Quick start¶
from rfgen.planning import HierarchicalCountPlanner
counts = HierarchicalCountPlanner.resolve(
{"kind": "uniform", "min": 0, "max": 2, "seed": 42}
)
HierarchicalCountPlanner.write(counts, scene_id="demo", root="output")
API¶
class HierarchicalCountPlanner:
@staticmethod
def resolve(config: CountConfig | dict[str, object]) -> HierarchicalCounts: ...
@staticmethod
def write(counts: HierarchicalCounts | dict[str, object], *, scene_id: str, root: str | Path = ".") -> Path: ...
@staticmethod
def read(path: str | Path) -> HierarchicalCounts: ...
CountConfig uses one of these strict configurations:
Kind |
Required fields |
Draw |
|---|---|---|
|
nonnegative integer |
|
|
nonnegative integer |
inclusive integer in |
|
finite |
NumPy |
All kinds may supply nonnegative max_count. A draw above it is rejected, not
clipped, with ValidationError context
{code: "count_draw_exceeds_max", kind, draw, max_count}. Invalid
distribution configuration raises context
{code: "count_distribution_invalid", field, value}.
HierarchicalCounts contains nonnegative system_count, device_count, and
event_count; devices_per_system has exactly one entry per system and sums
to device_count; events_per_device has exactly one entry per device and
sums to event_count. Zero is valid and yields empty vectors.
The version-1 artifact is
artifacts/plans/<scene_id>/counts.json with exactly
schema_version, counts, vectors, and seed. It records quantities only; it
does not choose device identities, event timing, duration, containment, or a
waveform.