fix ClinVar header #AlleleID + GRCh38 filter (was UnboundLocalError)

- header lstrip # for #AlleleID, init ci_*=None, filter Assembly!=GRCh38
- loaded 3960956 GRCh38 variants (was 0)
- offline now correctly maps P/LP vs VUS
This commit is contained in:
2026-09-08 23:07:30 +03:00
parent c20f61240f
commit 1f28f60bc0
+9 -8
View File
@@ -389,27 +389,32 @@ def _load_clinvar(clinvar_path):
opener = gzip.open if str(clinvar_path).endswith(".gz") else open opener = gzip.open if str(clinvar_path).endswith(".gz") else open
with opener(clinvar_path, "rt") as fh: with opener(clinvar_path, "rt") as fh:
header = None header = None
ci_chr = ci_start = ci_ref = ci_alt = ci_sig = ci_asm = None
for line in fh: for line in fh:
if line.startswith("#"): if line.startswith("#"):
continue if header is None and line.lstrip("#").startswith("AlleleID"):
line = line.lstrip("#")
else:
continue
if header is None: if header is None:
header = line.rstrip("\n").split("\t") header = line.rstrip("\n").split("\t")
# Find column indices
try: try:
ci_chr = header.index("Chromosome") ci_chr = header.index("Chromosome")
ci_start = header.index("Start") ci_start = header.index("Start")
ci_ref = header.index("ReferenceAllele") ci_ref = header.index("ReferenceAllele")
ci_alt = header.index("AlternateAllele") ci_alt = header.index("AlternateAllele")
ci_sig = header.index("ClinicalSignificance") ci_sig = header.index("ClinicalSignificance")
ci_asm = header.index("Assembly") if "Assembly" in header else None
except ValueError: except ValueError:
# Fallback for older format: try different names header = None
continue continue
continue continue
parts = line.rstrip("\n").split("\t") parts = line.rstrip("\n").split("\t")
if len(parts) <= max(ci_chr, ci_start, ci_ref, ci_alt, ci_sig): if len(parts) <= max(ci_chr, ci_start, ci_ref, ci_alt, ci_sig):
continue continue
if ci_asm is not None and parts[ci_asm] != "GRCh38":
continue
chrom = parts[ci_chr] chrom = parts[ci_chr]
# ClinVar Chromosome is 1,2.. not chr1
chrom_norm = f"chr{chrom}" if not chrom.startswith("chr") else chrom chrom_norm = f"chr{chrom}" if not chrom.startswith("chr") else chrom
try: try:
pos = int(parts[ci_start]) pos = int(parts[ci_start])
@@ -417,9 +422,6 @@ def _load_clinvar(clinvar_path):
continue continue
ref = parts[ci_ref]; alt = parts[ci_alt] ref = parts[ci_ref]; alt = parts[ci_alt]
sig = parts[ci_sig] sig = parts[ci_sig]
# Normalize significance to ACMG
# ClinVar: Pathogenic, Likely pathogenic, Uncertain significance, Likely benign, Benign, etc.
# Map to our 5-tier
sig_lower = sig.lower() sig_lower = sig.lower()
if "pathogenic" in sig_lower and "likely" not in sig_lower: if "pathogenic" in sig_lower and "likely" not in sig_lower:
acmg = "Pathogenic" acmg = "Pathogenic"
@@ -432,7 +434,6 @@ def _load_clinvar(clinvar_path):
else: else:
acmg = "Uncertain significance" acmg = "Uncertain significance"
key = (chrom_norm, pos, ref, alt) key = (chrom_norm, pos, ref, alt)
# Also add without chr prefix for matching
key2 = (chrom, pos, ref, alt) key2 = (chrom, pos, ref, alt)
m[key] = acmg m[key] = acmg
m[key2] = acmg m[key2] = acmg