docs: a technical introduction to the platform, as a LaTeX article

docs/blog/rarelens.tex builds a 10-page write-up covering the Nextflow DSL2
pipeline, the three execution backends behind one API call, the Argo and
ArgoCD track, Terraform, the external systems integrated, the ranking, the
benchmark and the model.

It is deliberately as much an account of what was wrong as of what works: the
components that scored evidence nobody had looked up, the missense AUROC that
fell from 0.872 to 0.500 once allele frequency was removed, the ontology walk
that silently dropped 399 terms, and the propagation change that measured
slightly worse than what it replaced and was kept anyway with the numbers
published.

Figures come from one headless-browser script. Screenshots are of the running
application; the six diagrams are hand-written HTML styled from the same
palette, rendered by the same script. Keeping both in one place is what stops
the article drifting from the system, and every number in a diagram has to be
changed deliberately.
This commit is contained in:
Kemal Yaylali
2026-09-12 13:10:47 +01:00
parent c25fb53666
commit 1e46fff2ff
25 changed files with 729 additions and 0 deletions
+30
View File
@@ -0,0 +1,30 @@
<!doctype html><meta charset="utf-8"><link rel="stylesheet" href="_base.css">
<div id="frame">
<h1>Evidence that was never looked up must abstain</h1>
<p class="sub">The rank is a weighted mean of four auditable components. Which ones may score is decided per job, from what the annotation run actually produced.</p>
<div class="row">
<div class="box plum" style="flex:1"><div class="t">phenotype &mdash; 0.35</div><div class="d">Share of the patient's HPO terms annotated to the gene, each weighted by its information content.</div><div class="k">always scores</div></div>
<div class="box" style="flex:1"><div class="t">rarity &mdash; 0.25</div><div class="d">Allele frequency in gnomAD, as a step function a reviewer can read.</div><div class="k">only if the run looked up frequencies</div></div>
<div class="box" style="flex:1"><div class="t">consequence &mdash; 0.20</div><div class="d">Predicted impact severity: HIGH, MODERATE, LOW, MODIFIER.</div><div class="k">always scores</div></div>
<div class="box" style="flex:1"><div class="t">model &mdash; 0.20</div><div class="d">LightGBM P(pathogenic) from variant effect.</div><div class="k">only with CADD or AlphaMissense</div></div>
</div>
<div style="height:20px"></div>
<div class="row">
<div class="band" style="flex:1">
<div class="lbl">Before &mdash; the bug</div>
<div class="box" style="border-color:var(--plum)"><div class="t" style="color:var(--plum)">rarity_score(None) &#8594; 1.00</div><div class="d">"No frequency in this run" was read as "absent from gnomAD, therefore maximally rare", and every variant collected a free 0.25. The model, meanwhile, scored 0.887 on features it had never seen. Two of four components were fiction, and the score looked fully informed.</div></div>
</div>
<div style="width:16px"></div>
<div class="band" style="flex:1">
<div class="lbl">After &mdash; abstention and renormalisation</div>
<div class="box" style="border-color:var(--green)"><div class="t" style="color:var(--green)">component &#8594; null, weights renormalised</div><div class="d">The job records <span class="k" style="font-family:var(--mono)">has_frequencies</span> and <span class="k" style="font-family:var(--mono)">has_effect_scores</span>. Absent components drop out and the remaining weights renormalise over 0.55, so the score stays on a 0&ndash;1 scale and still means the same thing. The UI prints "not looked up", never a bar.</div></div>
</div>
</div>
<div style="height:18px"></div>
<table style="width:100%; border-collapse:collapse; font-size:12.5px; border:1px solid var(--line)">
<tr style="background:var(--paper)"><th style="text-align:left;padding:7px 10px;border-bottom:1px solid var(--line)">Published Loeys&ndash;Dietz case, run without a VEP cache</th><th style="padding:7px 10px;border-bottom:1px solid var(--line)">score</th><th style="padding:7px 10px;border-bottom:1px solid var(--line)">phenotype (0.64)</th><th style="padding:7px 10px;border-bottom:1px solid var(--line)">rarity</th><th style="padding:7px 10px;border-bottom:1px solid var(--line)">consequence (0.36)</th><th style="padding:7px 10px;border-bottom:1px solid var(--line)">model</th></tr>
<tr><td style="padding:7px 10px;border-bottom:1px solid var(--line)"><em>TGFBR2</em> 3:30672252 G&gt;T missense &mdash; the published diagnosis</td><td style="padding:7px 10px;text-align:center;border-bottom:1px solid var(--line)"><strong style="color:var(--plum)">0.855</strong></td><td style="padding:7px 10px;text-align:center;border-bottom:1px solid var(--line)">1.00 <span style="color:var(--soft)">(30/30)</span></td><td style="padding:7px 10px;text-align:center;color:var(--soft);font-style:italic;border-bottom:1px solid var(--line)">not looked up</td><td style="padding:7px 10px;text-align:center;border-bottom:1px solid var(--line)">0.60</td><td style="padding:7px 10px;text-align:center;color:var(--soft);font-style:italic;border-bottom:1px solid var(--line)">not looked up</td></tr>
<tr><td style="padding:7px 10px"><em>OSBPL10</em> 3:31748090 missense &mdash; incidental</td><td style="padding:7px 10px;text-align:center">0.218</td><td style="padding:7px 10px;text-align:center">0.00</td><td style="padding:7px 10px;text-align:center;color:var(--soft);font-style:italic">not looked up</td><td style="padding:7px 10px;text-align:center">0.60</td><td style="padding:7px 10px;text-align:center;color:var(--soft);font-style:italic">not looked up</td></tr>
</table>
<p class="note">Both are rare missense variants, identical on every piece of evidence this run holds except one. The phenotype is what separates a published diagnosis from an incidental variant in a lipid-transport gene &mdash; which is the argument for phenotype-driven triage, in one table.</p>
</div>