progress for 141/84: annotate 10/84, oncokb 1/84 every 10, GTF indexed

- GTF by_chrom index for 84 variants (was 21M scans)
- vep_annotate and oncokb now every 10 with hgvs log
- online VAF>30% 84 rows: GTF 5s + ClinVar 5s + OncoKB 84*0.3s ~25s (was silent hang)
This commit is contained in:
2026-09-09 00:29:03 +03:00
parent baa87ea048
commit ffaa3c5cdd
+16 -10
View File
@@ -61,17 +61,23 @@ def vep_annotate(df, reference, gtf_path=None, offline=False, all_transcripts=Fa
if vep_bin and gtf_path and Path(gtf_path).expanduser().is_file(): if vep_bin and gtf_path and Path(gtf_path).expanduser().is_file():
pass pass
gtf_transcripts = None gtf_transcripts = None
if offline and gtf_path: gtf_by_chrom = None
if gtf_path:
gtf_file = Path(gtf_path).expanduser() gtf_file = Path(gtf_path).expanduser()
if gtf_file.is_file(): if gtf_file.is_file():
print(f" loading GTF {gtf_file} ...", flush=True) print(f" loading GTF {gtf_file} ...", flush=True)
gtf_transcripts = _load_gtf(gtf_file) gtf_transcripts = _load_gtf(gtf_file)
print(f" GTF loaded: {len(gtf_transcripts)} transcripts", flush=True) print(f" GTF loaded: {len(gtf_transcripts)} transcripts", flush=True)
# Index by chrom for fast lookup
from collections import defaultdict as _dd
gtf_by_chrom = _dd(list)
for t in gtf_transcripts:
gtf_by_chrom[t["chrom"]].append(t)
rows = [] rows = []
total = len(df) total = len(df)
for idx, (_, r) in enumerate(df.iterrows()): for idx, (_, r) in enumerate(df.iterrows()):
if idx % 500 == 0 and total > 500: if idx % 10 == 0:
print(f" annotate {idx}/{total} ...", flush=True) print(f" annotate {idx+1}/{total} ...", flush=True)
chrom = str(r["chrom"]) chrom = str(r["chrom"])
pos1 = int(r["position"]) + 1 pos1 = int(r["position"]) + 1
ref = str(r["ref"]); alt = str(r["alt"]) ref = str(r["ref"]); alt = str(r["alt"])
@@ -87,8 +93,8 @@ def vep_annotate(df, reference, gtf_path=None, offline=False, all_transcripts=Fa
"Тип варианта и эффект": "SNV, missense_variant (predicted)" if len(ref)==1 and len(alt)==1 else "indel", "Тип варианта и эффект": "SNV, missense_variant (predicted)" if len(ref)==1 and len(alt)==1 else "indel",
}) })
continue continue
if offline and gtf_transcripts is not None: if gtf_by_chrom is not None:
hits = [t for t in gtf_transcripts if t["chrom"] == chrom and t["start"] <= pos1 <= t["end"]] hits = [t for t in gtf_by_chrom.get(chrom, []) if t["start"] <= pos1 <= t["end"]]
if hits: if hits:
if all_transcripts: if all_transcripts:
for t in hits: for t in hits:
@@ -211,8 +217,8 @@ def fetch_oncokb(hgvs_g_list, token, tumor_type="All Solid Tumors", offline=Fals
headers = {"Authorization": f"Bearer {token}"} headers = {"Authorization": f"Bearer {token}"}
out = {} out = {}
for i, hgvs in enumerate(hgvs_g_list): for i, hgvs in enumerate(hgvs_g_list):
if i % 100 == 0 and len(hgvs_g_list) > 100: if i % 10 == 0:
print(f" [oncokb] {i}/{len(hgvs_g_list)} ...", flush=True) print(f" [oncokb] {i+1}/{len(hgvs_g_list)} {hgvs} ...", flush=True)
try: try:
# hgvs like "7:g.140753336A>T" -> genomicLocation "7,140753336,140753336,A,T" # hgvs like "7:g.140753336A>T" -> genomicLocation "7,140753336,140753336,A,T"
try: try:
@@ -472,10 +478,10 @@ def main():
help="ClinVar variant_summary.txt.gz for ACMG P/L (auto if exists)") help="ClinVar variant_summary.txt.gz for ACMG P/L (auto if exists)")
args = ap.parse_args() args = ap.parse_args()
# VAF>20% default for online (pan-cancer), leave --min-vaf configurable, offline keeps None # VAF>30% default for online (pan-cancer), leave --min-vaf configurable, offline keeps None
if args.min_vaf is None and not args.offline: if args.min_vaf is None and not args.offline:
args.min_vaf = 0.20 args.min_vaf = 0.30
print(f"[info] online default --min-vaf 0.20 (use --min-vaf 0.05 to keep more)", flush=True) print(f"[info] online default --min-vaf 0.30 (use --min-vaf 0.05 to keep more)", flush=True)
clean_path = Path(args.clean) clean_path = Path(args.clean)
df_clean = pd.read_csv(clean_path) df_clean = pd.read_csv(clean_path)