PIVOT / scripts /download_data.py
pranamanam's picture
Upload 176 files
6fa9282 verified
Raw
History Blame Contribute Delete
1.8 kB
"""Download a versioned scPerturb count matrix and verify its source checksum."""
from pathlib import Path
import argparse, hashlib, os
import requests
FILES = {
"norman": ("NormanWeissman2019_filtered.h5ad", "c870e6967d91c017d9da827bab183cd6"),
"replogle_k562": (
"ReplogleWeissman2022_K562_essential.h5ad",
"d8cba17576d1a8afc0f7d71b79cad0f7",
),
}
def md5(path):
h = hashlib.md5()
with open(path, "rb") as f:
for block in iter(lambda: f.read(8 * 1024**2), b""):
h.update(block)
return h.hexdigest()
def download(dataset, output):
name, digest = FILES[dataset]
out = Path(output)
out.mkdir(parents=True, exist_ok=True)
dest = out / name
if dest.exists():
if md5(dest) != digest:
raise ValueError(f"Checksum mismatch: {dest}")
return dest
part = dest.with_suffix(".h5ad.partial")
offset = part.stat().st_size if part.exists() else 0
url = f"https://zenodo.org/records/10044268/files/{name}?download=1"
with requests.get(
url,
stream=True,
headers={"Range": f"bytes={offset}-"} if offset else {},
timeout=(30, 120),
) as response:
response.raise_for_status()
append = offset > 0 and response.status_code == 206
with open(part, "ab" if append else "wb") as f:
for chunk in response.iter_content(8 * 1024**2):
f.write(chunk)
if md5(part) != digest:
raise ValueError(f"Source checksum mismatch: {part}")
os.replace(part, dest)
return dest
if __name__ == "__main__":
p = argparse.ArgumentParser()
p.add_argument("dataset", choices=FILES)
p.add_argument("--output", default="data/raw")
a = p.parse_args()
print(download(a.dataset, a.output))