Paper2Agent_decoupleRpy / scripts /load_and_validate_geo.py
Annie Voigt
style: apply ruff lint --fix + ruff format across the tree
c3b49d6
Raw
History Blame Contribute Delete
4.84 kB
"""
One-off script to load all 4 GEO datasets, save as h5ad, and validate
against their manifests. Run from the project root with:
.venv/bin/python scripts/load_and_validate_geo.py
"""
import json
import os
import sys
from pathlib import Path
# Run from project root
ROOT = Path(__file__).parent.parent
sys.path.insert(0, str(ROOT))
os.environ.setdefault("RNA_OUTPUT_DIR", str(ROOT / "tmp" / "datasets"))
from src.tools.dataset_tools import dataset_validate_manifest_against_data
from src.tools.rna import decoupler_load_geo_series_matrix
DATASETS = [
{
"dataset_id": "gse71989_chen",
"url": "https://ftp.ncbi.nlm.nih.gov/geo/series/GSE71nnn/GSE71989/matrix/GSE71989_series_matrix.txt.gz",
"condition_column": "tissue_subtype",
"out_prefix": "gse71989_chen",
},
{
"dataset_id": "gse62165_jiang",
"url": "https://ftp.ncbi.nlm.nih.gov/geo/series/GSE62nnn/GSE62165/matrix/GSE62165_series_matrix.txt.gz",
"condition_column": "tissue",
"out_prefix": "gse62165_jiang",
},
{
"dataset_id": "gse16515_mayo",
"url": "https://ftp.ncbi.nlm.nih.gov/geo/series/GSE16nnn/GSE16515/matrix/GSE16515_series_matrix.txt.gz",
"condition_column": "tissue",
"out_prefix": "gse16515_mayo",
},
{
"dataset_id": "gse28735_pdac",
"url": "https://ftp.ncbi.nlm.nih.gov/geo/series/GSE28nnn/GSE28735/matrix/GSE28735_series_matrix.txt.gz",
"condition_column": "tissue",
"out_prefix": "gse28735_pdac",
},
]
def run():
results = {}
for ds in DATASETS:
did = ds["dataset_id"]
print(f"\n{'=' * 60}")
print(f"Loading {did} ...")
print(f"{'=' * 60}")
# Step 1: Load from GEO
try:
load_result = decoupler_load_geo_series_matrix(
url_or_path=ds["url"],
condition_column=ds["condition_column"],
out_prefix=ds["out_prefix"],
)
print(f" Load: {load_result.get('message', load_result)}")
adata_path = load_result.get("output_path")
print(f" Saved to: {adata_path}")
print(f" OBS columns: {load_result.get('obs_columns', [])}")
print(" Sample characteristics:")
for k, v in (load_result.get("sample_characteristics") or {}).items():
vals = v if isinstance(v, list) else list(v)[:5]
print(f" {k}: {vals}")
except Exception as e:
print(f" ERROR loading: {e}")
results[did] = {"load_error": str(e)}
continue
if not adata_path or not Path(adata_path).exists():
print(f" ERROR: h5ad not found at {adata_path}")
results[did] = {"load_error": "h5ad not written"}
continue
# Step 2: Validate against manifest
print("\n Validating against manifest ...")
try:
val_result = dataset_validate_manifest_against_data(
dataset_id=did,
adata_path=adata_path,
)
print(f" overall_valid: {val_result.get('overall_valid')}")
print(f" n_errors: {val_result.get('n_errors')}")
print(f" n_warnings: {val_result.get('n_warnings')}")
for err in val_result.get("errors", []):
print(f" ERROR: {err}")
for warn in val_result.get("warnings", []):
print(f" WARNING: {warn}")
checks = val_result.get("checks", {})
for check_name, check in checks.items():
status = check.get("status", "?")
msg = check.get("message", "")
print(f" [{status}] {check_name}: {msg[:120]}")
except Exception as e:
print(f" ERROR validating: {e}")
val_result = {"validation_error": str(e)}
results[did] = {
"load": load_result,
"validation": val_result,
}
# Summary
print(f"\n{'=' * 60}")
print("SUMMARY")
print(f"{'=' * 60}")
for did, r in results.items():
if "load_error" in r:
print(f" {did}: LOAD FAILED — {r['load_error']}")
elif "validation_error" in r.get("validation", {}):
print(f" {did}: VALIDATION FAILED — {r['validation']['validation_error']}")
else:
v = r.get("validation", {})
print(
f" {did}: valid={v.get('overall_valid')} errors={v.get('n_errors')} warnings={v.get('n_warnings')}"
)
# Save full results as JSON for inspection
out = ROOT / "tmp" / "datasets" / "validation_results.json"
with open(out, "w") as f:
json.dump(results, f, indent=2, default=str)
print(f"\nFull results written to: {out}")
if __name__ == "__main__":
run()