| """Materialize fail-closed data-quality evidence for a frozen split.""" |
|
|
| from __future__ import annotations |
|
|
| from pathlib import Path |
| from typing import Any |
|
|
| from .artifacts import sha256_file, write_json_immutable |
| from .config import LoadedConfig |
| from .data import ALLOWED_MODEL_INPUTS, BGCEmbeddingDataset |
| from .splits import load_split, split_summary |
|
|
|
|
| def validate_frozen_dataset( |
| config: LoadedConfig, |
| split_path: str | Path, |
| output_dir: str | Path, |
| ) -> dict[str, Any]: |
| assignments = load_split(split_path) |
| dataset = BGCEmbeddingDataset( |
| config.resolve_path("data", "embeddings_h5"), |
| config.resolve_path("data", "atlas_csv"), |
| assignments, |
| int(config.values["model"]["esm_dimension"]), |
| ) |
| output = Path(output_dir) |
| output.mkdir(parents=True, exist_ok=True) |
| exclusion_path = output / "missing_embedding_rows.csv" |
| if exclusion_path.exists(): |
| raise FileExistsError(f"Refusing to overwrite quality artifact: {exclusion_path}") |
| dataset.missing_gene_rows.to_csv(exclusion_path, index=False) |
| usable_gene_rows = sum(len(dataset.bgc_to_genes[bgc_id]) for bgc_id in dataset.bgc_ids) |
| missing_gene_rows = len(dataset.missing_gene_rows) |
| report: dict[str, Any] = { |
| "schema_version": 1, |
| "split_file_sha256": sha256_file(split_path), |
| "atlas_file_sha256": sha256_file(config.resolve_path("data", "atlas_csv")), |
| "embeddings_file_sha256": sha256_file(config.resolve_path("data", "embeddings_h5")), |
| "split": split_summary(assignments), |
| "usable_bgcs": len(dataset), |
| "usable_gene_rows": usable_gene_rows, |
| "missing_embedding_rows": missing_gene_rows, |
| "embedding_coverage": usable_gene_rows / (usable_gene_rows + missing_gene_rows), |
| "position_source": "ordered community_atlas.protein_ids", |
| "model_input_whitelist": sorted(ALLOWED_MODEL_INPUTS), |
| "zero_gene_fallback": False, |
| } |
| write_json_immutable(output / "data_quality.json", report) |
| return report |
|
|