5ad55adbb6a5cc72a393700130584aa87fef2c89
lrnassar
  Tue Jun 30 06:15:44 2026 -0700
varFreqs: add Top 3 source AFs to mouseOvers; audit excludes SGDP and SVatalog. refs #36642

Adds a Top 3 source AFs ranking to the varFreqsAffected and varFreqsBackground
mouseOvers. Alongside the pooled allele frequency, the mouseOver now lists the
three cohorts/arms with the highest per-source AF, formatted as
"Source (AF), Source (AF), Source (AF)". Disease cohorts with phenotype splits
carry the arm label (SPARK ASD, SCHEMA case, GREGoR unaffected); population
cohorts use the bare key. Per-population sub-ancestries are deliberately
excluded so a high sub-pop AF cannot crowd out actual project-level signals.

vcfToBigBed.py adds a top_n_source_afs helper, collects per-arm AFs into
affected_arm_afs / background_arm_afs, and emits two new fields
topAffectedSources and topBackgroundSources. AS schema field count 163 -> 165.

An AF-distribution sweep across all 28 source cohorts identified SGDP and
SVatalog as encoding allele counts per genotyped individual (small N, AF
defaults near 0.5), making their per-source AF unreliable for the ranking.
Adds a skip_top_ranking column (col 9) to databases.tsv, set to 1 for SGDP
and SVatalog, and gates the per-arm AF append in vcfToBigBed.py on this
flag. Both cohorts still contribute to pooled backgroundAC/AN/AF and still
appear in backgroundSources; they are only suppressed from the Top 3.

Description pages varFreqsAffected.html and varFreqsBackground.html document
the ranking; the latter also documents the SGDP/SVatalog exclusion. Build
documentation in varFreqs.txt is updated.

diff --git src/hg/makeDb/trackDb/human/varFreqsAffected.html src/hg/makeDb/trackDb/human/varFreqsAffected.html
index e1cd9bbefab..bb67d401445 100644
--- src/hg/makeDb/trackDb/human/varFreqsAffected.html
+++ src/hg/makeDb/trackDb/human/varFreqsAffected.html
@@ -49,30 +49,45 @@
 <p>
 <b>Affected AF</b> is the pooled rate across contributing affected arms:
 <code>affectedAF = sum(AC) / sum(AN)</code>, where <b>affectedAC</b> sums the allele counts
 and <b>affectedAN</b> sums the allele numbers across each cohort/arm that provides both AC and
 AF (the per-arm AN is derived as <code>round(AC / AF)</code>). Cohorts that publish only AF
 (with no AC or AN of their own) are still pooled by assigning them an assumed allele number,
 set as a <code>default_an</code> in the build configuration; their per-arm AC is then derived
 as <code>round(AF &times; default_an)</code>. Cohorts
 that publish only AC and have no <code>default_an</code> set (currently GREGoR's per-arm
 AC_AFFECTED/UNAFFECTED/UNKNOWN) are listed in <b>affectedCohorts</b> but do not contribute
 to the pool numerator or denominator; their carriers are visible in the per-database AC
 column instead. The pooled rate is preferred over a max-across-cohorts statistic so a
 small cohort with a high local AF cannot dominate the displayed frequency.
 </p>
 
+<h3>Top affected sources by AF</h3>
+<p>
+Alongside the pooled rate, the mouseover lists the top 3 contributing
+affected arms ranked by their own per-source AF, formatted as
+<code>Source (AF)</code>. This surfaces case cohorts where the variant is
+specifically enriched, even when the pooled rate across all arms is small.
+For disease cohorts that ship a phenotype split (SPARK, SFARI WGS, SCHEMA,
+GREGoR), the displayed AF is the affected-arm AF and the label includes the
+arm (for example <code>SPARK ASD</code>, <code>SCHEMA case</code>); for
+cohorts with no split (GA4K) the label is just the cohort name and the AF
+is the whole-cohort AF. Arms that ship only AC and no AF (currently GREGoR
+per-arm) are not included in this ranking because no AF is available;
+they still appear in <b>affectedCohorts</b>.
+</p>
+
 <h3>Finding case-enriched loss-of-function variants</h3>
 <p>
 To look for protein-truncating variants that are common in affected individuals but rare
 in the background, set the Consequence filter to Stop Gained, Frameshift, Splice Donor and
 Splice Acceptor (these appear red), then add an upper limit on the
 <b>Background AF</b> filter. Each variant here carries both its affected frequency and its
 background frequency, so this isolates variants seen in cases with little or no presence in
 the population/unaffected set. Comparing visually against the
 <a href="hgTrackUi?g=varFreqsBackground">Population reference</a> track shows the same
 contrast across a whole gene.
 </p>
 
 <h2>Filters</h2>
 <ul>
   <li><b>Variant Type</b> and <b>Consequence</b>: restrict to SNV/insertion/deletion/MNV