feat(manifest): add Manifest.coverage_summary()#56
Conversation
After the occlusion labels landed, seeing which camera is most occluded in a manifest meant hand-rolling the loop. Add coverage_summary() returning per camera id (visible_fraction, mean_occ_frac): the fraction of that camera's (entity, frame, point) observations with visible=True, and the mean of the non-None occ_frac values. Pure read-only aggregation, numpy-free. Fixes bamdadd#53
|
Thanks @dchaudhari7177, the aggregation is right (None-skipping for occ_frac, all typed, numpy-free) and it's close. One thing to fix before merge: a camera with zero observations currently disappears from the summary, because Fix (roughly one line): seed the summary from |
|
Thanks for the update @dchaudhari7177 — CI's green, but the re-push didn't yet fix the core issue I flagged: a camera with zero observations still disappears from the summary. |
|
Fixed properly this time — thanks for the patience. |
What
After the occlusion labels landed, seeing which camera is most occluded in a manifest meant hand-rolling the loop over
entities[*].frames[*].points[*].per_cam[*].Adds
Manifest.coverage_summary() -> dict[int, tuple[float, float]], mapping each camera id to(visible_fraction, mean_occ_frac):visible_fraction— fraction of that camera's observations withvisible == True, in[0, 1]mean_occ_frac— mean of the non-Noneocc_fracvalues (0.0when none recorded)Acceptance criteria
[0, 1]; mean occ_frac ignoresNonebuild_smoke_scene()'s manifest asserts the most-occluded camera (highest mean occ_frac) has the lowest visible fractionruff/mypy/pytestgreen; the golden-manifest test is unaffected (method only, no serialization change)Tests
test_coverage_summary_flags_the_occluded_camera(one entry per camera, all fractions in range, most-occluded == least-visible) andtest_coverage_summary_mean_occ_ignores_none.Fixes #53