diff --git a/annotate_clean.py b/annotate_clean.py index 1d4722c..61a3550 100644 --- a/annotate_clean.py +++ b/annotate_clean.py @@ -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(): pass gtf_transcripts = None - if offline and gtf_path: + gtf_by_chrom = None + if gtf_path: gtf_file = Path(gtf_path).expanduser() if gtf_file.is_file(): print(f" loading GTF {gtf_file} ...", flush=True) gtf_transcripts = _load_gtf(gtf_file) 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 = [] total = len(df) for idx, (_, r) in enumerate(df.iterrows()): - if idx % 500 == 0 and total > 500: - print(f" annotate {idx}/{total} ...", flush=True) + if idx % 10 == 0: + print(f" annotate {idx+1}/{total} ...", flush=True) chrom = str(r["chrom"]) pos1 = int(r["position"]) + 1 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", }) continue - if offline and gtf_transcripts is not None: - hits = [t for t in gtf_transcripts if t["chrom"] == chrom and t["start"] <= pos1 <= t["end"]] + if gtf_by_chrom is not None: + hits = [t for t in gtf_by_chrom.get(chrom, []) if t["start"] <= pos1 <= t["end"]] if hits: if all_transcripts: 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}"} out = {} for i, hgvs in enumerate(hgvs_g_list): - if i % 100 == 0 and len(hgvs_g_list) > 100: - print(f" [oncokb] {i}/{len(hgvs_g_list)} ...", flush=True) + if i % 10 == 0: + print(f" [oncokb] {i+1}/{len(hgvs_g_list)} {hgvs} ...", flush=True) try: # hgvs like "7:g.140753336A>T" -> genomicLocation "7,140753336,140753336,A,T" try: @@ -472,10 +478,10 @@ def main(): help="ClinVar variant_summary.txt.gz for ACMG P/L (auto if exists)") 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: - args.min_vaf = 0.20 - print(f"[info] online default --min-vaf 0.20 (use --min-vaf 0.05 to keep more)", flush=True) + args.min_vaf = 0.30 + print(f"[info] online default --min-vaf 0.30 (use --min-vaf 0.05 to keep more)", flush=True) clean_path = Path(args.clean) df_clean = pd.read_csv(clean_path)