Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
6372140
test(live): a child's closed result must stay off the family page
GeiserX Nov 11, 2026
76354c4
fix(live): tag the closed results for the family page, and close a ch…
GeiserX Nov 11, 2026
1bf0623
fix(live): keep a child's closed result off the family page
GeiserX Nov 11, 2026
0d715a0
fix(live): keep a family row closed until every closed result it name…
GeiserX Nov 11, 2026
40c4110
fix(live): close position-only family rows with a gene-only result, a…
GeiserX Nov 11, 2026
d7477df
Merge remote-tracking branch 'origin/main' into pgp/map-veil-family
GeiserX Nov 11, 2026
996de9d
fix(live): close a child's side-by-side rows and the grandparents of …
GeiserX Nov 11, 2026
0bb4906
fix(live): open a child's drawing only by its own button while the pa…
GeiserX Nov 11, 2026
097f6c1
test(live): check that each demo person page draws the genome map
GeiserX Nov 11, 2026
2e3e9d8
feat(live): replace the findings karyogram with a genome map
GeiserX Nov 11, 2026
39749a0
ci(docs): build og so the demo site carries the map documents
GeiserX Nov 11, 2026
77c4d0c
docs(live): describe Figure 1, the genome map
GeiserX Nov 11, 2026
f292237
fix(live): close every place of a child on the family page while any …
GeiserX Nov 11, 2026
c31290e
fix(live): keep a phone's person page short with the genome map
GeiserX Nov 11, 2026
3e82797
Merge remote-tracking branch 'origin/main' into pgp/map-1e1
GeiserX Nov 11, 2026
1ff5652
test(live): check a closed family page only once the child's results …
GeiserX Nov 11, 2026
4409a96
fix(live): keep an overlapping closed result off the map and answer t…
GeiserX Nov 11, 2026
c3c5abc
fix(live): read malformed veil.spans as unreadable and test each box,…
GeiserX Nov 11, 2026
aade7a9
Merge remote-tracking branch 'origin/main' into pgp/map-veil-family
GeiserX Nov 11, 2026
b170ad7
fix(live): keep a shown finding on the map when a closed result lies …
GeiserX Nov 11, 2026
ae3716f
fix(live): count every closed result on the map chip and stop drawing…
GeiserX Nov 12, 2026
a6e3f15
fix(live): open the map chip's closed results in the page's order, on…
GeiserX Nov 12, 2026
e530654
ci(guard): give the unit-test shards 15 minutes so the browser tests …
GeiserX Nov 12, 2026
6785463
Merge commit 'e5306541a8c1cf81bcc1efa6975a78901e152736' into pgp/map-…
GeiserX Nov 12, 2026
0b68104
Merge commit '67854635e4bb27a41a490b5d9f511c9430556f31' into pgp/map-1e1
GeiserX Nov 12, 2026
1a23510
fix(live): close every gene of a closed deletion and list the fixed-p…
GeiserX Nov 12, 2026
9ef5059
fix(live): make a child's page the same whichever result is closed
GeiserX Nov 12, 2026
283ee24
docs(live): say how a child's page keeps which result is closed to it…
GeiserX Nov 12, 2026
bd9fde0
fix(live): close the known mobile element insertions card whole as well
GeiserX Nov 12, 2026
c76188c
Merge remote-tracking branch 'origin/main' into pgp/map-veil-infer
GeiserX Nov 12, 2026
a80d92c
fix(live): close the ClinVar card's deep intronic lines all together
GeiserX Nov 12, 2026
1edf2e9
fix(live): close a child's fixed panels, guessed ids and history entr…
GeiserX Nov 12, 2026
6314a5c
test(live): open a closed result by its handle and read the map chip'…
GeiserX Nov 12, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ Each release's notes. From 1.0.0 on, a major or minor release has hand-written n
## Unreleased

- The family page now keeps a child's results to act on closed, as the child's own page does, and what it shows of a child no longer depends on which result is closed or where it lies. While a child has a result still closed, or the page cannot read the child's results, these close for that child, one box each: the painting's grandparents (every stretch drawn from its parent alone), the chromosome map image, all de novo and compound-het rows, the child's medicines and HLA cells in the side by side, and the carrier screen of a couple the child is part of. Each "Show the result" opens one result; the places come back once the last one is opened, and a reload closes them again. While the results cannot be read, each box opens only its own place. On a child's page, a copy-number dot and a card's fact that name a closed result's gene now close with it too, on a phone in the card's line as well. `results.json` adds `veil.spans`, `veil.facts` and `veil.widget`; nothing is renamed or removed. The veil is still a browser veil: `results.json` and `family.json` hold every row.
- A child's page no longer tells which result to act on is closed. A closed finding's card, its place in the page and the address carry a handle (`#f/closed-2`) instead of its id, which names the gene and variant; the address never holds a closable finding's id, closed (`#f/closed-<n>`) or opened (`#f/opened-<n>`), so no history entry keeps it, and any other `#f/<x>` on such a page, a closed result's id or nothing, lands on the first closed finding, so a guessed id tells nothing. The home page links a child's closed result to the child's report, not to the finding's own page. A closed structural variant now closes the rows and findings that name any of its genes, not only the first. The cards whose rows are the same genes for everyone (known mobile element insertions, repeat expansions, VNtyper, Lp(a), CHIP, the copy numbers, CPIC, CYP2D6, HLA, Locityper, the traits panel, the blood groups) close whole while any result is closed, behind one box, and so do their own findings (a medicine gene, a CHIP call) and the lead's words on them, the ClinVar card's lines for the known deep intronic sites, the carrier list's two-hit line and the callability card's rows, all together; a row or line closes with a result only when it names its gene as a gene symbol (never a prose word, an ontology id or a unit such as `5 MB`), and the polygenic score card is never tagged; a card's note on its closed rows no longer counts them. `results.json` gains `veil.panels`, the tag `*panel*` in `veil.lines`, `veil.rows`, `veil.findings` and `veil.lead`, a `genes` list on each structural-variant finding, and one `veil.spans` row per gene; nothing is renamed or removed.
- Step 40, the 23andMe and AncestryDNA raw-data files, now runs on the Rust `og` binary: `og consumer export`, `og consumer build-sites` and `og consumer check` replace `bin/export_consumer.py`. On a synthetic gVCF of 552 MB (32 million records) with 617,044 sites it takes about 2 s and 43 MB in a Linux container on 4 cores, where the Python took 30 s and 660 MB; the files hold the same rows. `setup.sh --consumer-sites` reads dbSNP on 4 cores without the grep pass. The zips are now the same bytes for the same day (`--date`, else `SOURCE_DATE_EPOCH`, else today). Fixes: a call of three or more alleles stops the export with the site, instead of a file the strict reader refuses; two dbSNP records of one rsID at one position have their ALT alleles joined before the strand test; a bad site row or an unreadable zip is reported with the file and line instead of a traceback; a good export removes the `.txt` files a failed one left. The musl builds of `og` use the mimalloc allocator, which keeps a long multi-threaded read at its live memory. Step 40 needs `og`: `scripts/setup.sh <genome_dir>` builds it, and `scripts/setup.sh --og` builds only it.

- Steps 21, 32 and 9b (and the CYRIUS, PYPGX and STRANGER_RFC1 modules) now run the CYP2D6 depth check and the RFC1 motif count with `og`, and `bin/cyp2d6_depth_check.py` and `bin/rfc1_motif.py` are gone. A run that reaches these steps needs the binary: run `./scripts/setup.sh --og` once after setup and after each pull; without it the step stops with `og is not built`. The output files, their names and formats do not change; in CI, every e2e case that runs these steps in bash checks `og` against the deleted Python, byte for byte.
Expand Down
13 changes: 11 additions & 2 deletions assets/live/finding.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,18 @@
var tags = (r.veil && r.veil.findings) || {};
function tagOf(x) { var t = tags[x.id]; return t && t !== x.id ? t : null; }
// Opening this finding opens it and the result it names, nothing else: another result keeps its own veil.
// A finding of a fixed-panel card (tag PANEL, bin/live_results.py FIXED_PANELS) names no result: it stays closed
// while any result to act on is, whichever, as on the person page.
var PANEL = '*panel*';
var opened = {};
if (draw.open) { opened[f.id] = true; if (tagOf(f)) { opened[tagOf(f)] = true; } }
function shut(x) { return child && (x.level === 'act' ? !opened[x.id] : !!tagOf(x) && !opened[tagOf(x)]); }
if (draw.open) { opened[f.id] = true; if (tagOf(f) && tagOf(f) !== PANEL) { opened[tagOf(f)] = true; } }
function actShut() { return (r.findings || []).some(function (x) { return x.level === 'act' && !opened[x.id]; }); }
function shut(x) {
if (!child) { return false; }
if (x.level === 'act') { return !opened[x.id]; }
var t = tagOf(x);
return t === PANEL ? !opened[x.id] && actShut() : !!t && !opened[t];
}
// Closed: no title, gene or variant anywhere on the page (its title, crumb, cover, rail) until opened.
var closed = shut(f);
var title = !closed ? f.title : f.level === 'act' ? 'A result to act on' : 'A finding about a result to act on';
Expand Down
3 changes: 2 additions & 1 deletion assets/live/home.js
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,8 @@
});
items.sort(function (a, b) { return order[a.f.level] - order[b.f.level]; });
items.slice(0, 6).forEach(function (x) {
var a = el('a', { href: x.r.url + 'finding/' + encodeURIComponent(x.f.id) + '/' });
// A child's closed result links to the run's page, never to its own page: its id names its gene and variant.
var a = el('a', { href: x.r.url + (closedRuns[x.r.name] && x.f.level === 'act' ? '' : 'finding/' + encodeURIComponent(x.f.id) + '/') });
var who = el('span', { 'class': 'who' });
var pc = el('span', { 'class': 'pc' }, x.r.name);
if (colourOf[x.r.name]) { pc.style.setProperty('--pcol', colourOf[x.r.name]); }
Expand Down
5 changes: 3 additions & 2 deletions assets/live/map.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,8 @@
// --- the figure ---------------------------------------------------------------------------------------
// create({url, veil(id, gated) -> 'open'|'closed'|'opened', now(id) -> shown at this moment, open(id),
// close(id), known(id) -> a finding of the page's results, closed() -> the ids of the results to act on the
// page keeps closed at this moment, stepDone(step) -> ended at this moment, fallback() -> rows}): one figure
// page keeps closed at this moment, stepDone(step) -> ended at this moment, href(id) -> the address of a finding
// the page opened (never its id on a child's page), fallback() -> rows}): one figure
// per page. The page calls refresh(key) on each of its redraws; a new key
// fetches the document again and keeps the camera.
function create(opts) {
Expand Down Expand Up @@ -910,7 +911,7 @@
inSection = inSection.filter(function (id) { return stateOf(id) !== 'closed' && opts.title && opts.title(id); });
inSection.forEach(function (id) {
var c = el('div', { 'class': 'gm-chip opened', 'data-opened': 'section' });
add(c, add(el('span', {}, 'Opened in its section: '), el('a', { href: '#f/' + id }, opts.title(id))));
add(c, add(el('span', {}, 'Opened in its section: '), el('a', { href: '#f/' + (opts.href ? opts.href(id) : id) }, opts.title(id))));
add(c, button('Close it again', function () { confirming = null; opts.close(id); keyTo(); }));
add(chips, c);
});
Expand Down
Loading
Loading