ad8e7d43125d15461861a22ccb4d99e2b46c88c0
lrnassar
  Fri Aug 21 10:46:04 2026 -0700
Fix TP53 gnomAD PASS filtering and FLOSSIES carrier count, per code review. refs #37399 refs #38139

Two independent correctness fixes from CR #38139:

- tp53AFfrequencies.py: skip non-PASS gnomAD records (mostly AC0, i.e. observed
in nobody after QC). They were entering the present-set and wrongly counting as
present in gnomAD, blocking the absent -> PM2_Supporting rule. 68 missense
variants now correctly get PM2, changing 6 provisional classes at the 5/6 and
-2/-1 boundaries. gnomAD frequency use is PASS-only regardless.

- tp53Flossies.py: count carriers as het + hom by summing the per-population het
and hom counts, instead of allele_count - hom_count. In this FLOSSIES export
allele_count is already het + hom (not the usual het + 2*hom), so the old
formula dropped homozygous carriers (e.g. P72R showed 4031 carriers, not 8372).
No BS2 tier changes in the current export; fixes the mouseover count and a
latent tier bug for low-count variants with homozygotes.

diff --git src/hg/makeDb/scripts/tp53/tp53Flossies.py src/hg/makeDb/scripts/tp53/tp53Flossies.py
index 8498bdb2571..71ac996badf 100644
--- src/hg/makeDb/scripts/tp53/tp53Flossies.py
+++ src/hg/makeDb/scripts/tp53/tp53Flossies.py
@@ -187,31 +187,36 @@
         alt = v['alt']
         pos_hg19 = int(v['pos'])
         if assembly == 'hg19':
             chrom = "chr{}".format(v['chrom'])
             start = pos_hg19 - 1
             end = start + len(ref)
         else:
             if v['variant_id'] not in hg38_lookup:
                 skipped += 1
                 continue
             chrom, start, end = hg38_lookup[v['variant_id']]
         conseq = v.get('major_consequence') or 'unknown'
         ac = int(v.get('allele_count') or 0)
         an = int(v.get('allele_num') or 0)
         hom = int(v.get('hom_count') or 0)
-        carriers = ac - hom   # individuals: het + hom = allele_count - hom_count
+        # Carrier individuals = heterozygous + homozygous carriers. In this
+        # FLOSSIES export allele_count is already het + hom (not the usual
+        # het + 2*hom), so we sum the per-population het and hom counts directly
+        # rather than allele_count - hom_count, which would drop homozygotes.
+        carriers = (sum(int(x or 0) for x in (v.get('pop_hets') or {}).values())
+                    + sum(int(x or 0) for x in (v.get('pop_homs') or {}).values()))
         applies, pts, _ = bs2_tier(conseq, carriers)
         color = COLORS[applies]
         hgvsc = v.get('HGVSc') or ''
         hgvsp = v.get('HGVSp') or ''
         pop_acs = v.get('pop_acs') or {}
         pop_ans = v.get('pop_ans') or {}
         pop_breakdown = "; ".join(
             "{}={}/{}".format(p, pop_acs.get(p, 0), pop_ans.get(p, 0))
             for p in pop_acs
         )
         disp = "{}:{}{}>{}".format(chrom, start + 1, ref, alt)
         name = hgvsp if hgvsp else (hgvsc if hgvsc else disp)
         mo = mouseover(disp, hgvsc, hgvsp, conseq, applies, pts, carriers,
                        ac, an, pop_acs, pop_ans)
         lines.append("\t".join([