Skip to content

feat(manifest): add Manifest.coverage_summary()#56

Merged
bamdadd merged 1 commit into
bamdadd:mainfrom
dchaudhari7177:feat/manifest-coverage-summary
Jul 24, 2026
Merged

feat(manifest): add Manifest.coverage_summary()#56
bamdadd merged 1 commit into
bamdadd:mainfrom
dchaudhari7177:feat/manifest-coverage-summary

Conversation

@dchaudhari7177

Copy link
Copy Markdown
Contributor

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 with visible == True, in [0, 1]
  • mean_occ_frac — mean of the non-None occ_frac values (0.0 when none recorded)

Acceptance criteria

  • ✅ Pure read-only aggregation, no new dependency, numpy-free
  • ✅ One entry per camera id; visible-fraction in [0, 1]; mean occ_frac ignores None
  • ✅ Test on build_smoke_scene()'s manifest asserts the most-occluded camera (highest mean occ_frac) has the lowest visible fraction
  • ruff/mypy/pytest green; 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) and test_coverage_summary_mean_occ_ignores_none.

Fixes #53

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
@bamdadd

bamdadd commented Jul 22, 2026

Copy link
Copy Markdown
Owner

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 counts is only populated inside the per-observation loop and the summary is built from counts.items(). That contradicts the docstring ("0.0 if it has no observations"), the issue AC ("one entry per camera id"), and even your own test assert set(summary) == {cam.id for cam in manifest.cameras} — which only passes because the smoke scene happens to have every camera observing.

Fix (roughly one line): seed the summary from manifest.cameras so every camera id gets an entry, defaulting to (0.0, 0.0). A quick way to catch this in a test: strip all observations for one camera and assert it's still present at 0.0. Nice work otherwise — ping me when it's updated and I'll merge.

@bamdadd

bamdadd commented Jul 22, 2026

Copy link
Copy Markdown
Owner

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. summary is built from counts.items() (manifest.py ~L421), and counts only gets keys for cameras that observed something. So stripping cam 0's observations gives [1, 2], not [0, 1, 2] — which still contradicts the docstring ("0.0 if it has no observations") and issue #53's AC ("one entry per camera id"). The tests pass only because the smoke scene happens to have every camera observing. Fix: seed summary from self.cameras defaulting to (0.0, 0.0), and add a regression test that strips one camera's observations and asserts it's still present at 0.0. Almost there — ping me when it's in.

@dchaudhari7177

Copy link
Copy Markdown
Contributor Author

Fixed properly this time — thanks for the patience. coverage_summary now seeds the result from self.cameras and defaults an unobserved camera to (0.0, 0.0), instead of building from counts.items(). Added a regression test (test_coverage_summary_includes_a_camera_with_zero_observations) that strips the highest-id camera's observations and asserts it's still present at (0.0, 0.0) and that every camera id remains in the summary. ruff, mypy, and the manifest/camera tests are green.

@bamdadd
bamdadd merged commit e622a0f into bamdadd:main Jul 24, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add Manifest.coverage_summary(): per-camera visible fraction + mean occ_frac

3 participants