After the occlusion labels landed, it's useful to see at a glance which camera is most occluded in a manifest without hand-rolling the loop.
Add Manifest.coverage_summary() on the Manifest model (src/multicam_sim/manifest.py:380) returning, per camera id, the fraction of (entity, frame, point) observations with visible == True and the mean occ_frac (skipping None).
Pointer: iterate self.entities[*].frames[*].points[*].per_cam[*] (the PerCamObs fields cam/visible/occ_frac are already there, manifest.py:127-131); return e.g. dict[int, tuple[float, float]] or a small typed model.
Acceptance criteria
- Pure read-only aggregation, no new dependency, numpy-free.
- Returns one entry per camera id; visible-fraction in
[0,1]; mean occ_frac ignores None.
- Test on
build_smoke_scene()'s manifest asserts the occluded camera has the lowest visible fraction.
mypy/ruff/pytest green.
After the occlusion labels landed, it's useful to see at a glance which camera is most occluded in a manifest without hand-rolling the loop.
Add
Manifest.coverage_summary()on theManifestmodel (src/multicam_sim/manifest.py:380) returning, per camera id, the fraction of (entity, frame, point) observations withvisible == Trueand the meanocc_frac(skippingNone).Pointer: iterate
self.entities[*].frames[*].points[*].per_cam[*](thePerCamObsfieldscam/visible/occ_fracare already there,manifest.py:127-131); return e.g.dict[int, tuple[float, float]]or a small typed model.Acceptance criteria
[0,1]; mean occ_frac ignoresNone.build_smoke_scene()'s manifest asserts the occluded camera has the lowest visible fraction.mypy/ruff/pytestgreen.