all transcripts via Ensembl REST (expand per variant, pan-cancer)
- vep_annotate now iterates all transcript_consequences - timeout 15s, graceful fallback to single placeholder row
This commit is contained in:
+30
-21
@@ -66,39 +66,36 @@ def vep_annotate(df, reference, gtf_path=None):
|
|||||||
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"])
|
||||||
hgvs_g = f"{chrom}:g.{pos1}{ref}>{alt}"
|
hgvs_g = f"{chrom}:g.{pos1}{ref}>{alt}"
|
||||||
gene = "intergenic"
|
|
||||||
hgvs_c = f"c.{pos1}{ref}>{alt}"
|
|
||||||
hgvs_p = f"p.(?)"
|
|
||||||
effect = "SNV, missense_variant (predicted)" if len(ref)==1 and len(alt)==1 else "indel"
|
|
||||||
is_synthetic = chrom.startswith("chr") and chrom[3:].isdigit() and int(chrom[3:]) <= 3 and pos1 < 6000
|
is_synthetic = chrom.startswith("chr") and chrom[3:].isdigit() and int(chrom[3:]) <= 3 and pos1 < 6000
|
||||||
if is_synthetic:
|
if is_synthetic:
|
||||||
gene = f"SYNTH_{chrom}"
|
rows.append({
|
||||||
else:
|
"_orig_idx": r.name,
|
||||||
# Try Ensembl REST for real hg38 variants (one transcript, best)
|
"Ген": f"SYNTH_{chrom}",
|
||||||
|
"HGVS_c": f"c.{pos1}{ref}>{alt}",
|
||||||
|
"HGVS_p": "p.(?)",
|
||||||
|
"HGVS": f"c.{pos1}{ref}>{alt} p.(?) ({hgvs_g})",
|
||||||
|
"Тип варианта и эффект": "SNV, missense_variant (predicted)" if len(ref)==1 and len(alt)==1 else "indel",
|
||||||
|
})
|
||||||
|
continue
|
||||||
|
# Real hg38 - try Ensembl REST, expand all transcripts
|
||||||
try:
|
try:
|
||||||
# Ensembl REST: GET /vep/homo_sapiens/hgvs/{hgvs_g}
|
|
||||||
# Use chr without prefix for Ensembl: 7:g.140453136A>T
|
|
||||||
hgvs_ens = f"{chrom.replace('chr','')}:g.{pos1}{ref}>{alt}"
|
hgvs_ens = f"{chrom.replace('chr','')}:g.{pos1}{ref}>{alt}"
|
||||||
url = f"https://rest.ensembl.org/vep/homo_sapiens/hgvs/{hgvs_ens}?content-type=application/json"
|
url = f"https://rest.ensembl.org/vep/homo_sapiens/hgvs/{hgvs_ens}?content-type=application/json"
|
||||||
resp = requests.get(url, headers={"Content-Type": "application/json"}, timeout=5)
|
resp = requests.get(url, headers={"Content-Type": "application/json", "Accept": "application/json"}, timeout=15)
|
||||||
if resp.status_code == 200:
|
if resp.status_code == 200:
|
||||||
j = resp.json()
|
j = resp.json()
|
||||||
if j and isinstance(j, list) and j[0].get("transcript_consequences"):
|
tcs = j[0].get("transcript_consequences", []) if j and isinstance(j, list) and j[0] else []
|
||||||
tc = j[0]["transcript_consequences"][0]
|
if tcs:
|
||||||
gene = tc.get("gene_symbol") or gene
|
for tc in tcs:
|
||||||
hgvs_c = tc.get("hgvsc") or hgvs_c
|
gene = tc.get("gene_symbol") or "intergenic"
|
||||||
hgvs_p = tc.get("hgvsp") or hgvs_p
|
hgvs_c = tc.get("hgvsc") or f"c.{pos1}{ref}>{alt}"
|
||||||
|
hgvs_p = tc.get("hgvsp") or "p.(?)"
|
||||||
cons = tc.get("consequence_terms", [])
|
cons = tc.get("consequence_terms", [])
|
||||||
effect = ", ".join(cons) if cons else effect
|
effect = ", ".join(cons) if cons else ("SNV, missense_variant (predicted)" if len(ref)==1 and len(alt)==1 else "indel")
|
||||||
# Extract c. part from hgvsc like ENST00000288602.11:c.1799T>A -> c.1799T>A
|
|
||||||
if ":" in hgvs_c:
|
if ":" in hgvs_c:
|
||||||
hgvs_c = hgvs_c.split(":")[-1]
|
hgvs_c = hgvs_c.split(":")[-1]
|
||||||
if ":" in hgvs_p:
|
if ":" in hgvs_p:
|
||||||
hgvs_p = hgvs_p.split(":")[-1]
|
hgvs_p = hgvs_p.split(":")[-1]
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
# For all-transcripts mode, we currently emit one row per variant (best transcript).
|
|
||||||
# With VEP cache, this would expand to N rows per variant.
|
|
||||||
rows.append({
|
rows.append({
|
||||||
"_orig_idx": r.name,
|
"_orig_idx": r.name,
|
||||||
"Ген": gene,
|
"Ген": gene,
|
||||||
@@ -107,6 +104,18 @@ def vep_annotate(df, reference, gtf_path=None):
|
|||||||
"HGVS": f"{hgvs_c} {hgvs_p} ({hgvs_g})",
|
"HGVS": f"{hgvs_c} {hgvs_p} ({hgvs_g})",
|
||||||
"Тип варианта и эффект": effect,
|
"Тип варианта и эффект": effect,
|
||||||
})
|
})
|
||||||
|
continue
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
# Fallback single row
|
||||||
|
rows.append({
|
||||||
|
"_orig_idx": r.name,
|
||||||
|
"Ген": "intergenic",
|
||||||
|
"HGVS_c": f"c.{pos1}{ref}>{alt}",
|
||||||
|
"HGVS_p": "p.(?)",
|
||||||
|
"HGVS": f"c.{pos1}{ref}>{alt} p.(?) ({hgvs_g})",
|
||||||
|
"Тип варианта и эффект": "SNV, missense_variant (predicted)" if len(ref)==1 and len(alt)==1 else "indel",
|
||||||
|
})
|
||||||
return pd.DataFrame(rows)
|
return pd.DataFrame(rows)
|
||||||
|
|
||||||
def fetch_oncokb(hgvs_g_list, token, tumor_type="All Solid Tumors"):
|
def fetch_oncokb(hgvs_g_list, token, tumor_type="All Solid Tumors"):
|
||||||
|
|||||||
Reference in New Issue
Block a user