Remove release manifest bookkeeping
Browse files- data/release_manifest.json +0 -77
- validate_data.py +0 -61
data/release_manifest.json
DELETED
|
@@ -1,77 +0,0 @@
|
|
| 1 |
-
{
|
| 2 |
-
"figure_set": "Figures 2-5 and Supplementary Figures 1-27",
|
| 3 |
-
"latent_coordinate_spaces": [
|
| 4 |
-
"per_session_whitened_reference_aligned_3d"
|
| 5 |
-
],
|
| 6 |
-
"manuscript_working_version": "manuscript_v8",
|
| 7 |
-
"schema_version": 1,
|
| 8 |
-
"source": "paper/results, active consistency and feature-attribution artifacts, benchmark dataset arrays, and Figure 5 prediction sidecars",
|
| 9 |
-
"source_git_revision": "1779782610eeb1d09d7eec2a181a513e77ae5de3",
|
| 10 |
-
"source_repository": "https://github.com/TangLab-UBC/behavior_benchmarking",
|
| 11 |
-
"tables": {
|
| 12 |
-
"clean_prediction_summary.csv": {
|
| 13 |
-
"rows": 115,
|
| 14 |
-
"sha256": "7f91e3b06c3f9015dafecd8d3d33ad162a12eafb798728c8f8f179def93ab511"
|
| 15 |
-
},
|
| 16 |
-
"consistency_summary.csv": {
|
| 17 |
-
"rows": 54,
|
| 18 |
-
"sha256": "7039c0d38c288576e39ea6a1147a41eb2d395559b1d9b1de1b14eac3b3801b7f"
|
| 19 |
-
},
|
| 20 |
-
"dataset_example_neural.csv": {
|
| 21 |
-
"rows": 43110,
|
| 22 |
-
"sha256": "d42387c65325728657bb3aca12a54f4ca7df7ac225b765e4d0b5552a2e7eb815"
|
| 23 |
-
},
|
| 24 |
-
"dataset_example_targets.csv": {
|
| 25 |
-
"rows": 214,
|
| 26 |
-
"sha256": "e91f6bca5096ddd604ed53a69c2f258731c33001fb7daa9ee8339ea543650f5c"
|
| 27 |
-
},
|
| 28 |
-
"dataset_overview.csv": {
|
| 29 |
-
"rows": 5,
|
| 30 |
-
"sha256": "c8b616a738e033d63cac781c956349a135ce7970bf44ebeddfb7b51c002386bb"
|
| 31 |
-
},
|
| 32 |
-
"dataset_targets.csv": {
|
| 33 |
-
"rows": 72260,
|
| 34 |
-
"sha256": "13fb909fde8919ae9a9818b6fb81bfa8986f0d6bfa18fe7df4dc8432187dc3b4"
|
| 35 |
-
},
|
| 36 |
-
"feature_example_raster.csv": {
|
| 37 |
-
"rows": 1057,
|
| 38 |
-
"sha256": "8474b69e3857faf3235cef27324b147050c2c8d2709ce199d1aeb5a7e39bd5b6"
|
| 39 |
-
},
|
| 40 |
-
"latent_samples.csv": {
|
| 41 |
-
"rows": 31140,
|
| 42 |
-
"sha256": "bb484c47b78bd7a7d0a2bfea94296e726aa80034f87368b32302aaba0c5aa622"
|
| 43 |
-
},
|
| 44 |
-
"latent_trajectories.csv": {
|
| 45 |
-
"rows": 75040,
|
| 46 |
-
"sha256": "d15a19b50d7dbc517b4bf5de60a550fda6870327e5e59fb4a5ec37f01921abf5"
|
| 47 |
-
},
|
| 48 |
-
"neuron_attributions.csv": {
|
| 49 |
-
"rows": 21906,
|
| 50 |
-
"sha256": "bcab4237ad69c826a3dc54aeccbd3233422de3a41ecb9a982f4c78e47734487c"
|
| 51 |
-
},
|
| 52 |
-
"neuron_shap_summary.csv": {
|
| 53 |
-
"rows": 106,
|
| 54 |
-
"sha256": "19ab79da509e25b0d4c75cacbfd309319dc816831c93a17f9a50eb5a24985ff0"
|
| 55 |
-
},
|
| 56 |
-
"robustness_summary.csv": {
|
| 57 |
-
"rows": 115,
|
| 58 |
-
"sha256": "935381b401d26402c18bb4d32020169e63f8d081ba69fb7bbc594a4adebd6ca6"
|
| 59 |
-
},
|
| 60 |
-
"scalability_summary.csv": {
|
| 61 |
-
"rows": 115,
|
| 62 |
-
"sha256": "99921519a3af02ab660e8138c2089dd1ed781f0567fae0444349ae3bb62cf971"
|
| 63 |
-
},
|
| 64 |
-
"trial_historical_trajectories.csv": {
|
| 65 |
-
"rows": 4725,
|
| 66 |
-
"sha256": "605373599d4bd46c1379ab99b791bd82060544843be8eb880a9f9bcb523d1cda"
|
| 67 |
-
},
|
| 68 |
-
"trial_shapley_retrain_summary.csv": {
|
| 69 |
-
"rows": 99,
|
| 70 |
-
"sha256": "d2e38d7aff1cea5735d4766cb8a7612e7cc63fb1acbeb5e7b46be0dcf4ef87ad"
|
| 71 |
-
},
|
| 72 |
-
"trial_shapley_summary.csv": {
|
| 73 |
-
"rows": 81,
|
| 74 |
-
"sha256": "bba3435afa6a0e2755d30199e995f53bfa33df8b7200b066ea9b575d6125133b"
|
| 75 |
-
}
|
| 76 |
-
}
|
| 77 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
validate_data.py
CHANGED
|
@@ -9,8 +9,6 @@ against ``paper/results`` in the main benchmark repository.
|
|
| 9 |
from __future__ import annotations
|
| 10 |
|
| 11 |
import argparse
|
| 12 |
-
import hashlib
|
| 13 |
-
import json
|
| 14 |
from pathlib import Path
|
| 15 |
from typing import Iterable
|
| 16 |
|
|
@@ -150,14 +148,6 @@ class ValidationError(RuntimeError):
|
|
| 150 |
"""Raised when Space data violates its manuscript-facing contract."""
|
| 151 |
|
| 152 |
|
| 153 |
-
def _sha256(path: Path) -> str:
|
| 154 |
-
digest = hashlib.sha256()
|
| 155 |
-
with path.open("rb") as handle:
|
| 156 |
-
for chunk in iter(lambda: handle.read(1024 * 1024), b""):
|
| 157 |
-
digest.update(chunk)
|
| 158 |
-
return digest.hexdigest()
|
| 159 |
-
|
| 160 |
-
|
| 161 |
def _active_mask(frame: pd.DataFrame) -> pd.Series:
|
| 162 |
if "status" in frame.columns:
|
| 163 |
return frame["status"].fillna("").eq("present")
|
|
@@ -274,57 +264,6 @@ def validate_local(data_dir: Path) -> dict[str, pd.DataFrame]:
|
|
| 274 |
continue
|
| 275 |
frames[name] = frame
|
| 276 |
|
| 277 |
-
manifest_path = data_dir / "release_manifest.json"
|
| 278 |
-
if not manifest_path.exists():
|
| 279 |
-
errors.append(f"missing release manifest: {manifest_path}")
|
| 280 |
-
else:
|
| 281 |
-
try:
|
| 282 |
-
manifest = json.loads(manifest_path.read_text(encoding="utf-8"))
|
| 283 |
-
except (json.JSONDecodeError, OSError) as exc:
|
| 284 |
-
errors.append(f"invalid release manifest: {exc}")
|
| 285 |
-
manifest = {}
|
| 286 |
-
if not isinstance(manifest, dict):
|
| 287 |
-
errors.append("invalid release manifest: top-level value must be an object")
|
| 288 |
-
manifest = {}
|
| 289 |
-
raw_manifest_spaces = manifest.get("latent_coordinate_spaces", [])
|
| 290 |
-
if not isinstance(raw_manifest_spaces, list):
|
| 291 |
-
errors.append("release manifest: latent_coordinate_spaces must be a list")
|
| 292 |
-
raw_manifest_spaces = []
|
| 293 |
-
elif not all(isinstance(value, str) for value in raw_manifest_spaces):
|
| 294 |
-
errors.append("release manifest: coordinate-space values must be strings")
|
| 295 |
-
raw_manifest_spaces = []
|
| 296 |
-
manifest_spaces = set(raw_manifest_spaces)
|
| 297 |
-
_require(
|
| 298 |
-
manifest_spaces == {LATENT_COORDINATE_SPACE},
|
| 299 |
-
f"release manifest: coordinate spaces {sorted(manifest_spaces)}",
|
| 300 |
-
errors,
|
| 301 |
-
)
|
| 302 |
-
manifest_tables = manifest.get("tables", {})
|
| 303 |
-
if not isinstance(manifest_tables, dict):
|
| 304 |
-
errors.append("release manifest: tables must be an object")
|
| 305 |
-
manifest_tables = {}
|
| 306 |
-
for name in REQUIRED_COLUMNS:
|
| 307 |
-
entry = manifest_tables.get(name)
|
| 308 |
-
if not isinstance(entry, dict):
|
| 309 |
-
errors.append(f"release manifest: missing table entry {name}")
|
| 310 |
-
continue
|
| 311 |
-
path = data_dir / name
|
| 312 |
-
if not path.exists():
|
| 313 |
-
continue
|
| 314 |
-
expected_hash = entry.get("sha256")
|
| 315 |
-
actual_hash = _sha256(path)
|
| 316 |
-
_require(
|
| 317 |
-
expected_hash == actual_hash,
|
| 318 |
-
f"release manifest: SHA-256 mismatch for {name}",
|
| 319 |
-
errors,
|
| 320 |
-
)
|
| 321 |
-
if name in frames:
|
| 322 |
-
_require(
|
| 323 |
-
entry.get("rows") == len(frames[name]),
|
| 324 |
-
f"release manifest: row-count mismatch for {name}",
|
| 325 |
-
errors,
|
| 326 |
-
)
|
| 327 |
-
|
| 328 |
for name, (n_rows, n_active) in EXPECTED_COVERAGE.items():
|
| 329 |
if name not in frames:
|
| 330 |
continue
|
|
|
|
| 9 |
from __future__ import annotations
|
| 10 |
|
| 11 |
import argparse
|
|
|
|
|
|
|
| 12 |
from pathlib import Path
|
| 13 |
from typing import Iterable
|
| 14 |
|
|
|
|
| 148 |
"""Raised when Space data violates its manuscript-facing contract."""
|
| 149 |
|
| 150 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 151 |
def _active_mask(frame: pd.DataFrame) -> pd.Series:
|
| 152 |
if "status" in frame.columns:
|
| 153 |
return frame["status"].fillna("").eq("present")
|
|
|
|
| 264 |
continue
|
| 265 |
frames[name] = frame
|
| 266 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 267 |
for name, (n_rows, n_active) in EXPECTED_COVERAGE.items():
|
| 268 |
if name not in frames:
|
| 269 |
continue
|