5fe93cbef0d7692552e37e62bbf394cc7d222a28 max Thu Jul 16 00:32:55 2026 -0700 ClinVar Mapped track: map ClinVar coding variants through paralog alignments #Preview2 week - bugs introduced now will need a build patch to fix Adds the clinvarMapped composite (hg38) with two subtracks: - clinvarMappedParalog: every protein-changing ClinVar variant projected onto the equivalent (aligned) residue of each of its gene's paralogs - clinvarMappedParalogAln: the pairwise protein alignments used to do the mapping, as bigPsl, so the evidence for each projection can be inspected Pipeline: paralog pairs from Ensembl BioMart, one representative transcript per gene from MANE Select, pairwise global protein alignment (BLOSUM62) for pairs at >=20% identity, variants projected residue-to-residue and mapped back to the paralog's genomic codon. Colors and filters mirror the ClinVar track; the map track is filterable by source gene, classification, review stars, residue conservation and percent identity. refs #37883 diff --git src/hg/makeDb/doc/hg38/clinvarMapped.txt src/hg/makeDb/doc/hg38/clinvarMapped.txt new file mode 100644 index 00000000000..f37a28a21a4 --- /dev/null +++ src/hg/makeDb/doc/hg38/clinvarMapped.txt @@ -0,0 +1,89 @@ +# 2026-07-13 Claude (max): ClinVar variants mapped to related loci (clinvarMapped) + +# The clinvarMapped track container maps protein-changing ClinVar variants onto +# related loci by sequence homology. The first (and so far only) method is +# paralog mapping: every variant is projected onto the equivalent (aligned) +# residue of each of its gene's paralogs, with the pairwise protein alignments +# provided as evidence. Two bigBed outputs: +# clinvarMappedParalog projected variants (bigBed 12+) +# clinvarMappedParalogAln bigPsl alignments (with query CDS sequence) +# (Future methods, e.g. mapping through PFAM domains, will add sibling subtracks.) +# +# Inputs, all already on hg38: +# /gbdb/hg38/bbi/clinvar/clinvarMain.bb ClinVar short variants +# /gbdb/hg38/mane/mane.bb MANE Select + Plus Clinical +# /gbdb/hg38/hg38.2bit genome +# Ensembl BioMart release 116 within-species paralog pairs +# +# All scripts are in kent/src/hg/makeDb/scripts/clinvarMapped . Python steps +# run in the micromamba "claude" env (needs parasail, biopython, py2bit). +# Scripts named clinvarMapped* are reusable infrastructure; clinvarMappedParalog* +# are specific to the paralog mapping method. + +dir=/hive/data/genomes/hg38/bed/clinvarMapped +scr=~/kent/src/hg/makeDb/scripts/clinvarMapped +mkdir -p $dir && cd $dir + +# 1. Paralog pairs from Ensembl BioMart, one chromosome per request (a single +# genome-wide request never closes its socket and always times out). +$scr/clinvarMappedParalogPairs.sh $dir +# -> paralogPairs.tsv (3,552,265 pairs; geneId geneSym paralogId paralogSym percIdQ percIdT) + +# 2. MANE Select transcript set: one representative transcript+protein per gene, +# translated straight from the genome so protein and coordinate mapping agree. +$scr/clinvarMappedMane.sh $dir +# -> maneSelect.gp, maneSelect.faa, maneMeta.tsv (19,293 protein-coding genes) + +# 3. Coverage stats (genes with/without a paralog, percent-id distribution). +$scr/clinvarMappedParalogStats.sh $dir +# -> paralogStats.log (15,278 of 19,293 genes have a MANE-mappable paralog) + +# 4. Restrict to unordered pairs whose proteins share >=20% identity, and make a +# per-gene protein FASTA keyed by Ensembl gene id. +awk -F'\t' 'BEGIN{OFS="\t"} + { q=$5+0; t=$6+0; m=(q>t?q:t); if(m<20) next; + a=$1; b=$3; + if(abest[k]){seen[k]=sa"\t"sb; best[k]=m; pid[k]=p1"\t"p2} } + END{ for(k in seen) print k, seen[k], pid[k], best[k] }' \ + paralogPairs.mane.tsv | sort -k1,1 -k2,2 > pairs.ge20.tsv +# -> pairs.ge20.tsv (94,471 pairs) + +awk -F'\t' '{print $1"\t"$2}' maneMeta.tsv > .enst2ensg +awk 'BEGIN{while((getline l < ".enst2ensg")>0){split(l,a,"\t"); m[a[1]]=a[2]}} + /^>/{ id=substr($1,2); g=m[id]; if(g=="") {skip=1; next} skip=0; print ">"g; next } + !skip{print}' maneSelect.faa > geneProt.faa && rm -f .enst2ensg + +# 5. Pairwise global protein alignment (BLOSUM62) of every >=20% pair; output is +# ungapped aligned blocks in protein coordinates (fast, ~3 s with parasail). +python $scr/clinvarMappedParalogAlign.py geneProt.faa pairs.ge20.tsv -o alnBlocks.tsv -j 48 +# -> alnBlocks.tsv (94,471 alignments) + +# 6. Assign every protein-changing ClinVar variant to its MANE codon. --selftest +# verifies the genomic<->codon math; the result matches ClinVar's own protein +# HGVS for 99.9% of missense variants. +python $scr/clinvarMappedCodons.py /gbdb/hg38/bbi/clinvar/clinvarMain.bb \ + maneSelect.gp geneProt.faa maneMeta.tsv -o clinvarCodons.tsv --selftest +# -> clinvarCodons.tsv (2,623,549 variant-codon rows from 2,648,470 coding variants) + +# 7. Project each variant across its paralog alignments -> variant bigBed. Colors +# match the ClinVar track (clinVarToBed). +python $scr/clinvarMappedParalogProject.py $dir -o clinvarMappedParalog.bed -j 48 +export LC_ALL=C +sort -S8G --parallel=16 -k1,1 -k2,2n clinvarMappedParalog.bed -o clinvarMappedParalog.sorted.bed +bedToBigBed -tab -type=bed12+14 -as=$scr/clinvarMappedParalog.as \ + clinvarMappedParalog.sorted.bed /hive/data/genomes/hg38/chrom.sizes clinvarMappedParalog.bb +# -> clinvarMappedParalog.bb (16,750,740 features) + +# 8. Turn the same alignments into PSL (both orientations) -> bigPsl evidence +# track. --faOut writes a per-gene CDS FASTA (keyed by gene symbol = the PSL +# qName) built from the same coordinates, so the embedded query sequence lets +# the browser shade base matches/mismatches in the alignment. +python $scr/clinvarMappedParalogAlnPsl.py $dir /hive/data/genomes/hg38/chrom.sizes \ + -o clinvarMappedParalogAln.psl --faOut geneCds.fa --twoBit /gbdb/hg38/hg38.2bit +pslToBigPsl clinvarMappedParalogAln.psl -fa=geneCds.fa stdout \ + | sort -S4G --parallel=16 -k1,1 -k2,2n > clinvarMappedParalogAln.bigPslInput +bedToBigBed -as=$HOME/kent/src/hg/lib/bigPsl.as -type=bed12+13 -tab \ + clinvarMappedParalogAln.bigPslInput /hive/data/genomes/hg38/chrom.sizes clinvarMappedParalogAln.bb +# -> clinvarMappedParalogAln.bb (188,942 alignment features, with query sequence)