| """ |
| 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 |
|
|
| |
| 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}") |
|
|
| |
| 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 |
|
|
| |
| 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, |
| } |
|
|
| |
| 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')}" |
| ) |
|
|
| |
| 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() |
|
|