Download experiments/32_gentext_prep.py from Pathstudy/fourmodal-pathology-bind: direct link, hf CLI and curl.
- Browser
- Download file 3.69 kB
-
https://huggingface.co/Pathstudy/fourmodal-pathology-bind/resolve/main/experiments/32_gentext_prep.py
- Command line
-
hf download hf://Pathstudy/fourmodal-pathology-bind/experiments/32_gentext_prep.py
-
curl -L -o 32_gentext_prep.py https://huggingface.co/Pathstudy/fourmodal-pathology-bind/resolve/main/experiments/32_gentext_prep.py
3.69 kB
| """Synthetic captions (27_azure_caption.py, GPT, 3-shot PathGen style) -> per-set meta for 08_extract_text.py. | |
| VALIDATION ONLY: these texts are never used to train any head. | |
| Output cache/orion_gentext_meta.csv (row i = ORION tile_id i of load_all_tiles(); `caption` column) | |
| """ | |
| import json | |
| import os | |
| import pandas as pd | |
| from common import CACHE, load_all_tiles | |
| C = pd.DataFrame([json.loads(l) for l in open(os.path.join(CACHE, "gen_text", "captions.jsonl"))]) | |
| C = C[(C.set == "orion") & C.caption.notna() & (C.caption.str.len() > 0)].drop_duplicates("path", keep="last") | |
| cap = dict(zip(C.path.map(os.path.basename), C.caption)) | |
| df = load_all_tiles() | |
| df["caption"] = df.image_path.map(lambda p: cap.get(os.path.basename(p))) | |
| print(f"ORION tiles {len(df)}, with synthetic caption {df.caption.notna().sum()}") | |
| assert df.caption.notna().all(), "missing captions -> rerun 27_azure_caption.py (resumable)" | |
| df[["tile_id", "image_path", "caption"]].to_csv(os.path.join(CACHE, "orion_gentext_meta.csv"), index=False) | |
| # TCGA calibration set (27_ --sets tcga_calib): synthetic captions of patches that also have REAL text | |
| A = pd.DataFrame([json.loads(l) for l in open(os.path.join(CACHE, "gen_text", "captions.jsonl"))]) | |
| A = A[(A.set == "tcga_calib") & A.caption.notna()].drop_duplicates("path", keep="last") | |
| if len(A): | |
| I = pd.read_csv(os.path.join(CACHE, "allimg_meta.csv")) | |
| shots = [s["key"][:12] for s in json.load(open(os.path.join(CACHE, "gen_text", "prompt.json")))["shots"]] | |
| A["img_idx"] = A.path.map(dict(zip(I.image_path, I.index))) | |
| A = A[A.img_idx.notna() & ~A.img_idx.map(lambda i: I.patient[int(i)] in shots)] # drop few-shot patients | |
| A["img_idx"] = A.img_idx.astype(int) | |
| A[["img_idx", "path", "caption"]].reset_index(drop=True).to_csv(os.path.join(CACHE, "tcga_calib_meta.csv"), index_label="idx") | |
| print(f"TCGA calibration captions: {len(A)} (few-shot patients excluded: {shots})") | |
| # external test sets (27_ --sets dlpfc idc): row i = row i of cache/external/<set>_meta.csv | |
| for st in ("dlpfc", "idc"): | |
| X = pd.DataFrame([json.loads(l) for l in open(os.path.join(CACHE, "gen_text", "captions.jsonl"))]) | |
| X = X[(X.set == st) & X.caption.notna() & (X.caption.str.len() > 0)].drop_duplicates("key", keep="last") | |
| if not len(X): | |
| continue | |
| n = len(pd.read_csv(os.path.join(CACHE, "external", f"{st}_meta.csv"))) | |
| cap = dict(zip(X.path.str.split(":").str[2].astype(int), X.caption)) | |
| out = pd.DataFrame({"row": range(n), "caption": [cap.get(i) for i in range(n)]}) | |
| print(f"{st}: {n} spots, with synthetic caption {out.caption.notna().sum()}") | |
| assert out.caption.notna().all(), "missing captions -> rerun 27_azure_caption.py --sets dlpfc idc (resumable)" | |
| out.to_csv(os.path.join(CACHE, f"{st}_gentext_meta.csv"), index=False) | |
| # TCGA images without real text after junk removal (40_clean_text.py; 27_ --sets tcga_notext). A caption made for | |
| # the same image under another set (tcga_calib) is reused. Row i of the output = row i of notext_meta.csv. | |
| N = pd.read_csv(os.path.join(CACHE, "notext_meta.csv")) | |
| X = pd.DataFrame([json.loads(l) for l in open(os.path.join(CACHE, "gen_text", "captions.jsonl"))]) | |
| X = X[X.caption.notna() & (X.caption.str.len() > 0)].drop_duplicates("path", keep="last") | |
| cap = dict(zip(X.path.map(os.path.abspath), X.caption)) | |
| N["caption"] = N.image_path.map(lambda p: cap.get(os.path.abspath(p))) | |
| print(f"TCGA no-text images {len(N)}, with synthetic caption {N.caption.notna().sum()}") | |
| assert N.caption.notna().all(), "missing captions -> rerun 27_azure_caption.py --sets tcga_notext" | |
| N[["img_idx", "image_path", "patient", "caption"]].to_csv(os.path.join(CACHE, "tcga_notext_meta.csv"), index=False) | |