Add Krea2 atlas coverage report
This commit is contained in:
@@ -23,6 +23,10 @@ the existing Position Pool / Action Filter / Insta-OF chain. Pair it with
|
|||||||
`SxCP Krea2 Variant Evidence` to display the fixed-seed eval entry, image paths,
|
`SxCP Krea2 Variant Evidence` to display the fixed-seed eval entry, image paths,
|
||||||
and generator decision behind that variant.
|
and generator decision behind that variant.
|
||||||
|
|
||||||
|
For command-line planning, `python tools/krea2_tuning_report.py` shows which
|
||||||
|
catalog variants are proven or pending and which atlas pose folders are still
|
||||||
|
unmapped by the catalog.
|
||||||
|
|
||||||
## Inventory
|
## Inventory
|
||||||
|
|
||||||
| Family | Pose images | Control images | First sample |
|
| Family | Pose images | Control images | First sample |
|
||||||
|
|||||||
+87
-1
@@ -1,6 +1,7 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from collections import Counter
|
from collections import Counter
|
||||||
|
from pathlib import Path
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -66,6 +67,76 @@ def coverage_summary() -> dict[str, Any]:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def _catalog_atlas_root() -> Path:
|
||||||
|
catalog = krea2_pose_variant_catalog.load_catalog()
|
||||||
|
return Path(str(catalog.get("atlas_root") or ""))
|
||||||
|
|
||||||
|
|
||||||
|
def _mapped_atlas_folders() -> dict[str, list[str]]:
|
||||||
|
mapped: dict[str, list[str]] = {}
|
||||||
|
for variant in krea2_pose_variant_catalog.variants():
|
||||||
|
key = str(variant.get("key") or "")
|
||||||
|
for folder in variant.get("atlas_folders") or []:
|
||||||
|
folder_name = str(folder)
|
||||||
|
if not folder_name:
|
||||||
|
continue
|
||||||
|
mapped.setdefault(folder_name, []).append(key)
|
||||||
|
return mapped
|
||||||
|
|
||||||
|
|
||||||
|
def _is_background_or_control_folder(folder_name: str) -> bool:
|
||||||
|
lower = folder_name.lower()
|
||||||
|
return (
|
||||||
|
lower == "bg"
|
||||||
|
or lower == "woman"
|
||||||
|
or lower.endswith("_control")
|
||||||
|
or lower.endswith("_bg")
|
||||||
|
or lower.endswith("_control_bg")
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def atlas_folder_rows(atlas_root: str | Path | None = None) -> list[dict[str, Any]]:
|
||||||
|
root = Path(atlas_root) if atlas_root is not None else _catalog_atlas_root()
|
||||||
|
if not root.is_dir():
|
||||||
|
return []
|
||||||
|
mapped = _mapped_atlas_folders()
|
||||||
|
rows: list[dict[str, Any]] = []
|
||||||
|
for folder in sorted(root.iterdir(), key=lambda path: path.name.lower()):
|
||||||
|
if not folder.is_dir():
|
||||||
|
continue
|
||||||
|
folder_name = folder.name
|
||||||
|
if _is_background_or_control_folder(folder_name):
|
||||||
|
continue
|
||||||
|
image_count = sum(1 for _ in folder.glob("*.png"))
|
||||||
|
if image_count <= 0:
|
||||||
|
continue
|
||||||
|
control_folder = root / f"{folder_name}_control"
|
||||||
|
variant_keys = mapped.get(folder_name, [])
|
||||||
|
if not variant_keys and not control_folder.is_dir():
|
||||||
|
continue
|
||||||
|
rows.append(
|
||||||
|
{
|
||||||
|
"folder": folder_name,
|
||||||
|
"image_count": image_count,
|
||||||
|
"mapped": bool(variant_keys),
|
||||||
|
"variant_keys": list(variant_keys),
|
||||||
|
"control_folder": str(control_folder) if control_folder.is_dir() else "",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return rows
|
||||||
|
|
||||||
|
|
||||||
|
def atlas_coverage_summary(atlas_root: str | Path | None = None) -> dict[str, Any]:
|
||||||
|
rows = atlas_folder_rows(atlas_root=atlas_root)
|
||||||
|
unmapped = [str(row.get("folder")) for row in rows if not row.get("mapped")]
|
||||||
|
return {
|
||||||
|
"pose_folder_count": len(rows),
|
||||||
|
"mapped_folder_count": len(rows) - len(unmapped),
|
||||||
|
"unmapped_folder_count": len(unmapped),
|
||||||
|
"unmapped_folders": unmapped,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def next_test_plans() -> list[dict[str, Any]]:
|
def next_test_plans() -> list[dict[str, Any]]:
|
||||||
rows_by_key = {str(row.get("key")): row for row in coverage_rows()}
|
rows_by_key = {str(row.get("key")): row for row in coverage_rows()}
|
||||||
plans: list[dict[str, Any]] = []
|
plans: list[dict[str, Any]] = []
|
||||||
@@ -94,7 +165,7 @@ def next_test_plans() -> list[dict[str, Any]]:
|
|||||||
return plans
|
return plans
|
||||||
|
|
||||||
|
|
||||||
def markdown_report() -> str:
|
def markdown_report(atlas_root: str | Path | None = None) -> str:
|
||||||
lines = [
|
lines = [
|
||||||
"# Krea2 Pose Variant Coverage",
|
"# Krea2 Pose Variant Coverage",
|
||||||
"",
|
"",
|
||||||
@@ -132,4 +203,19 @@ def markdown_report() -> str:
|
|||||||
*[f" - {cue}" for cue in plan["avoid_cues"]],
|
*[f" - {cue}" for cue in plan["avoid_cues"]],
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
atlas_summary = atlas_coverage_summary(atlas_root=atlas_root)
|
||||||
|
if atlas_summary["pose_folder_count"]:
|
||||||
|
unmapped = atlas_summary["unmapped_folders"]
|
||||||
|
lines.extend(
|
||||||
|
[
|
||||||
|
"",
|
||||||
|
"## Atlas Folder Coverage",
|
||||||
|
"",
|
||||||
|
f"- Pose folders: {atlas_summary['pose_folder_count']}",
|
||||||
|
f"- Mapped folders: {atlas_summary['mapped_folder_count']}",
|
||||||
|
f"- Unmapped folders: {atlas_summary['unmapped_folder_count']}",
|
||||||
|
]
|
||||||
|
)
|
||||||
|
if unmapped:
|
||||||
|
lines.extend(["", "Unmapped atlas folders:", *[f"- {folder}" for folder in unmapped]])
|
||||||
return "\n".join(lines)
|
return "\n".join(lines)
|
||||||
|
|||||||
@@ -6878,6 +6878,27 @@ def smoke_krea2_tuning_report_policy() -> None:
|
|||||||
any(str(path).endswith("ballsucking/101_ballsucking.png") for path in ballsucking_plan.get("reference_paths") or []),
|
any(str(path).endswith("ballsucking/101_ballsucking.png") for path in ballsucking_plan.get("reference_paths") or []),
|
||||||
"Ballsucking test plan lost atlas reference path",
|
"Ballsucking test plan lost atlas reference path",
|
||||||
)
|
)
|
||||||
|
with tempfile.TemporaryDirectory() as tmpdir:
|
||||||
|
atlas_root = Path(tmpdir)
|
||||||
|
for folder in ("doggy", "doggy_control", "custom_pose", "custom_pose_control", "bg", "woman", "doggy_bg"):
|
||||||
|
folder_path = atlas_root / folder
|
||||||
|
folder_path.mkdir()
|
||||||
|
(folder_path / f"{folder}_sample.png").write_bytes(b"")
|
||||||
|
atlas_rows = krea2_tuning_report.atlas_folder_rows(atlas_root=atlas_root)
|
||||||
|
atlas_by_folder = {row.get("folder"): row for row in atlas_rows}
|
||||||
|
_expect(atlas_by_folder.get("doggy", {}).get("mapped") is True, "Atlas report should mark catalog folders as mapped")
|
||||||
|
_expect(atlas_by_folder.get("custom_pose", {}).get("mapped") is False, "Atlas report should expose unmapped pose folders")
|
||||||
|
_expect("doggy_control" not in atlas_by_folder, "Atlas report should exclude control folders")
|
||||||
|
_expect("doggy_bg" not in atlas_by_folder, "Atlas report should exclude background folders")
|
||||||
|
_expect("bg" not in atlas_by_folder, "Atlas report should exclude shared bg folder")
|
||||||
|
_expect("woman" not in atlas_by_folder, "Atlas report should exclude non-pose woman folder")
|
||||||
|
atlas_summary = krea2_tuning_report.atlas_coverage_summary(atlas_root=atlas_root)
|
||||||
|
_expect(atlas_summary.get("pose_folder_count") == 2, "Atlas report should count only pose folders")
|
||||||
|
_expect(atlas_summary.get("mapped_folder_count") == 1, "Atlas report should count mapped pose folders")
|
||||||
|
_expect(atlas_summary.get("unmapped_folders") == ["custom_pose"], "Atlas report should identify unmapped pose folders")
|
||||||
|
atlas_markdown = krea2_tuning_report.markdown_report(atlas_root=atlas_root)
|
||||||
|
_expect("Atlas Folder Coverage" in atlas_markdown, "Krea2 tuning report markdown lost atlas coverage section")
|
||||||
|
_expect("custom_pose" in atlas_markdown, "Krea2 tuning report markdown lost unmapped atlas folder")
|
||||||
markdown = krea2_tuning_report.markdown_report()
|
markdown = krea2_tuning_report.markdown_report()
|
||||||
_expect("pov_ballsucking_low_head" in markdown, "Krea2 tuning report markdown lost candidate variant")
|
_expect("pov_ballsucking_low_head" in markdown, "Krea2 tuning report markdown lost candidate variant")
|
||||||
_expect("needs_fixed_seed_tests" in markdown, "Krea2 tuning report markdown lost coverage state")
|
_expect("needs_fixed_seed_tests" in markdown, "Krea2 tuning report markdown lost coverage state")
|
||||||
|
|||||||
Reference in New Issue
Block a user