oncodsl / Read docs /PROMPT_param_help.md
govindbalki's picture
Upload folder using huggingface_hub
0fff343 verified
|
Raw
History Blame Contribute Delete
20.3 kB
# Prompt β€” Rich parameter help (click-to-open explainers with diagrams)
Upgrade the "?" help for the 8 Parameters in the Lab from a one-line tooltip into a rich, click-to-open explainer (text + examples + diagrams), aimed at a non-expert reviewer. Presentation/read-only β€” no logic changes. Reuse the calm theme (bg #FAFAF7, card #FCFBF8, ink #23303A, muted #6E7F8C, border #ECEAE4, accent #3A6B7E, highlight #BC6B2E) and the existing monospace for gene IDs.
## Interaction
- Build ONE reusable component `<ParamHelp short="..." detailed={...} />` so wording can't drift. The "?" button:
- on **hover/focus**, shows the SHORT one-liner (a small tooltip β€” keep the current text as the short summary);
- on **click**, opens a MODAL dialog with the DETAILED content (text + any diagram).
- Modal: `role="dialog"`, `aria-modal="true"`, labelled by its title; ~640px wide on desktop, full-width with padding and vertical scroll on narrow screens; close on X, Esc, and backdrop click; return focus to the "?" button on close. Calm card styling (border #ECEAE4, fill #FCFBF8, ~14px radius, generous padding). Headings in #23303A, body readable (~14px), muted captions #6E7F8C.
- Apply this ONLY to the 8 Parameters "?" icons. Leave other "?" icons elsewhere (objectives, run id/status) as the existing InfoTip β€” do not touch them.
- Diagrams are embedded as small SVG components, `width:100%; height:auto` (viewBox scales). Each diagram is used once, in its own parameter.
## Detailed content per parameter
For each: SHORT = hover text; DETAILED = modal body (use the wording below; render line breaks and bullet/example blocks cleanly).
### Generations
SHORT: "How many rounds of 'keep the best, breed, mutate' the engine runs. More rounds refine further, but take longer."
DETAILED:
- What it is: one "generation" is a single round of the engine's loop β€” score every program, keep the best, then breed and mutate them into the next batch. Generations is how many rounds it runs.
- How it works: the engine starts with random programs (mostly poor) and each round nudges the population toward better ones β€” like selective breeding.
- More vs fewer: more rounds refine the winners further, but with diminishing returns once it has converged. The harder part is usually *discovering* the right genes in the first place (driven by Population and mutation), not polishing β€” so extra generations help less once the curve flattens.
- Typical: 30–60.
- Small inline illustration: a 4-step loop "random programs β†’ score each β†’ keep the best β†’ breed & mutate β†’ (back to score)", calm style, arrows; the loop arrow labelled "Γ— Generations".
### Population
SHORT: "How many candidate programs compete in each round. A 'program' is a small pipeline built by composing the DSL operators (Select β†’ Reduce β†’ Fit) over the gene data. More programs explores more options, but is slower."
DETAILED:
- What it is: how many candidate programs compete each round. A "program" is a small pipeline built from the DSL operators β€” Select (pick genes) β†’ Reduce (average them into one score) β†’ Fit (use the score to separate the groups).
- Why it matters: a bigger population samples more genes and structures each round, so it's the main lever for *discovery* β€” finding the right genes at all. Generations then refine what was found.
- Example β€” three random programs in a population (opaque gene IDs, monospace):
- `average(g04823, g11201, g00917) β†’ score`
- `average(g15522, g02013) βˆ’ average(g08840, g00231) β†’ score`
- `average(g07788, g13002, g05340) β†’ score`
- More vs fewer: more explores more options, but each round is slower.
- Typical: 150–300.
### Genes / set
SHORT: "The most genes a single score may use. Smaller keeps programs simple and readable."
DETAILED:
- What it is: a "set" is the group of genes averaged together into a single score. Genes/set is the maximum size of that group.
- Example: `Select(g05347, g00048, g06271) β†’ average β†’ one score` (uses 3; the cap might be 8).
- Smaller vs larger: smaller keeps each score simple and readable; larger lets one score blend more genes.
- It pairs with Max sets: Genes/set is the *width* of each group; Max sets is *how many* groups.
### Max sets
SHORT: "How many separate gene-scores a program may combine (1 or 2). 2 lets it build a small 'score made of scores'."
DETAILED:
- What it is: how many *separate* gene groups a program may build and then combine (1 or 2). They use different genes β€” not the same ones reused.
- Example (2 sets):
- Set 1: `average(g05347, g00048, g06271) β†’ scoreA`
- Set 2: `average(g15522, g02013) β†’ scoreB`
- Combine: `scoreA βˆ’ scoreB β†’ final score`
- Why two: to capture a *contrast* β€” e.g. one group that's low in MSI-H and one that's high; the gap between them can separate better than either alone (like "repair activity minus immune activity"). One set can't express that; two can.
- If one group is enough, the engine can still use 1.
- Diagram (small): two short chains β€” `matrix β†’ Select β†’ Reduce β†’ scoreA` and `matrix β†’ Select β†’ Reduce β†’ scoreB` β€” both feeding a `Combine (sub)` node, then a final `score`. Verbs = accent-bordered boxes, scores = amber pills, calm style.
### Ξ» (size penalty)
SHORT: "How hard the engine is penalised for using more genes. Higher pushes it toward fewer genes (simpler answers)."
DETAILED:
- What it is: a "price per gene" that discourages bloated programs. Every program is graded on a single number:
- `fitness = separation βˆ’ Ξ» Γ— (number of genes)`
- so the engine ranks by accuracy *minus* a size tax.
- The key idea β€” Ξ» is the admission price each gene must beat: with Ξ» = 0.005, a gene is only worth keeping if it adds more than 0.005 of separation.
- Worked example: a 3-gene program scores 0.90 β†’ net 0.90 βˆ’ 0.015 = 0.885. Add a 4th gene that lifts it to 0.903 (only +0.003) β†’ net 0.883, *lower*, so it's rejected. A 4th gene that lifts it to 0.91 (+0.01) β†’ net 0.890, *higher*, so it's kept.
- Turning the knob: Ξ» = 0 β†’ genes free β†’ bloated, overfit programs. Ξ» small (0.005) β†’ trims useless genes, keeps useful ones. Ξ» large β†’ very lean programs, but may drop useful genes.
- Diagram: the accuracy-vs-genes trade-off (embed the SVG in "DIAGRAMS" below).
### Seed
SHORT: "The starting point for the engine's randomness. The same seed reproduces the exact same run; change it to see a different run."
DETAILED:
- Why randomness: the space of possible programs is astronomically large (picking even 8 genes out of 20,000 is ~10^29 combinations), so the engine can't try them all β€” it explores with randomness: random starting programs, random mutations, random breeding.
- What the seed is: computers don't make true randomness; a formula generates a sequence of numbers, each from the previous one. The seed is the *starting number* fed into that formula β€” everything random flows from it. (One common formula: `next = (1664525 Γ— current + 1013904223) mod 2Β³Β²`; with seed 42 the first value is 1,083,814,273, then mapped onto a gene position.)
- What it does: think of the seed as one fixed list of dice rolls used in order across the whole run β€” early rolls pick the starting genes, later rolls drive mutations. Same seed β†’ same list β†’ identical run. Different seed β†’ a different list β†’ a different run.
- Why vary it: because the search has luck in it, run a few seeds (42, 7, 123) and see whether the same genes keep appearing β€” that tells you a finding is real, not a fluke.
- Diagram: the seed-as-a-fixed-list-of-dice-rolls (embed the SVG below).
### Permutations
SHORT: "How many times we re-run on deliberately scrambled labels to check the result isn't luck. The real result must beat these chance runs (that's the 'permutation p')."
DETAILED:
- What it checks: whether the winning score is real signal or could have come up by luck. The engine searches so hard that some programs separate the groups well by pure coincidence, so a high score alone isn't proof.
- How it works: shuffle the MSI-H / MSS labels across patients at random β€” this breaks any real gene↔label link, creating a "no-signal world". Re-score there: any score above 0.5 is pure chance. Repeat many times (this knob = how many) to build a picture of what luck looks like.
- Reading it: permutation p = the fraction of shuffled runs that scored β‰₯ the real winner. p = 0.005 means only 0.5% of chance runs matched it β†’ very unlikely a fluke. Conventionally p < 0.05 is the "unlikely to be luck" line.
- The knob: with 200 shuffles the smallest p you can report is about 1/200 β‰ˆ 0.005; more permutations give a finer, more trustworthy p.
- Diagram: the "luck pile" vs the real result (embed the SVG below).
### Prefilter top-N
SHORT: "By default the engine searches all ~20,000 genes, so nothing is pre-excluded. Turning this on narrows to the N most promising genes first β€” faster, but it can drop a real gene that only shows signal in combination."
DETAILED:
- Default (off): the engine searches all ~20,000 genes, so nothing is pre-excluded β€” the most honest setting for a discovery demo.
- Turning it on: first narrows to the N genes most individually associated with the target (computed name-blind, on the training split only), then searches within that shortlist. Faster, because the space is ~10Γ— smaller.
- The trade-off: speed and focus vs completeness. A univariate shortlist can drop a gene that only matters *in combination* (no signal on its own), and it sets a ceiling β€” if a gene isn't in the shortlist, the engine can never find it.
- Small inline illustration (funnel): "~20,000 genes β†’ keep the N most individually associated β†’ search within N", with a muted note "off by default = no funnel".
## DIAGRAMS (embed verbatim; wrap each so it scales: width:100%, height auto)
### Seed diagram
```svg
<svg viewBox="0 0 720 200" xmlns="http://www.w3.org/2000/svg" role="img" font-family="ui-sans-serif,system-ui,sans-serif">
<title>The seed as one fixed list of dice rolls used in order across the whole run</title>
<desc>Seed 42 produces a fixed sequence of dice rolls; early rolls pick initial genes, later rolls drive a mutation. Same seed gives the same run.</desc>
<rect x="40" y="6" width="74" height="22" rx="11" fill="#3A6B7E"/>
<text x="77" y="21" text-anchor="middle" font-size="12" font-weight="700" fill="#fff">Seed 42</text>
<text x="124" y="22" font-size="12.5" fill="#6E7F8C">β†’ one fixed list of random rolls, used in order:</text>
<rect x="50" y="55" width="48" height="48" rx="9" fill="#FCFBF8" stroke="#3A6B7E" stroke-width="1.5"/>
<circle cx="62" cy="67" r="3.5" fill="#23303A"/><circle cx="74" cy="79" r="3.5" fill="#23303A"/><circle cx="86" cy="91" r="3.5" fill="#23303A"/>
<rect x="112" y="55" width="48" height="48" rx="9" fill="#FCFBF8" stroke="#3A6B7E" stroke-width="1.5"/>
<circle cx="124" cy="67" r="3.5" fill="#23303A"/><circle cx="148" cy="67" r="3.5" fill="#23303A"/><circle cx="136" cy="79" r="3.5" fill="#23303A"/><circle cx="124" cy="91" r="3.5" fill="#23303A"/><circle cx="148" cy="91" r="3.5" fill="#23303A"/>
<rect x="174" y="55" width="48" height="48" rx="9" fill="#FCFBF8" stroke="#3A6B7E" stroke-width="1.5"/>
<circle cx="186" cy="67" r="3.5" fill="#23303A"/><circle cx="210" cy="91" r="3.5" fill="#23303A"/>
<rect x="236" y="55" width="48" height="48" rx="9" fill="#FCFBF8" stroke="#3A6B7E" stroke-width="1.5"/>
<circle cx="248" cy="67" r="3.5" fill="#23303A"/><circle cx="248" cy="79" r="3.5" fill="#23303A"/><circle cx="248" cy="91" r="3.5" fill="#23303A"/><circle cx="272" cy="67" r="3.5" fill="#23303A"/><circle cx="272" cy="79" r="3.5" fill="#23303A"/><circle cx="272" cy="91" r="3.5" fill="#23303A"/>
<line x1="294" y1="52" x2="294" y2="106" stroke="#C7CDD1" stroke-width="1.5" stroke-dasharray="4 4"/>
<rect x="314" y="55" width="48" height="48" rx="9" fill="#FCFBF8" stroke="#3A6B7E" stroke-width="1.5"/>
<circle cx="338" cy="79" r="3.5" fill="#23303A"/>
<rect x="376" y="55" width="48" height="48" rx="9" fill="#FCFBF8" stroke="#3A6B7E" stroke-width="1.5"/>
<circle cx="388" cy="67" r="3.5" fill="#23303A"/><circle cx="412" cy="67" r="3.5" fill="#23303A"/><circle cx="388" cy="91" r="3.5" fill="#23303A"/><circle cx="412" cy="91" r="3.5" fill="#23303A"/>
<text x="446" y="86" font-size="22" fill="#B9B6AE">…</text>
<path d="M50,110 L50,116 L284,116 L284,110" fill="none" stroke="#9AA0A6" stroke-width="1.2"/>
<text x="167" y="132" text-anchor="middle" font-size="11.5" fill="#2C5563"><tspan font-weight="700">Generation 0</tspan> β€” pick the initial programs' genes</text>
<path d="M314,110 L314,116 L424,116 L424,110" fill="none" stroke="#9AA0A6" stroke-width="1.2"/>
<text x="369" y="132" text-anchor="middle" font-size="11.5" fill="#8A4E20"><tspan font-weight="700">Generation 5</tspan> β€” a mutation</text>
<text x="294" y="150" text-anchor="middle" font-size="10.5" fill="#6E7F8C">… many rolls later …</text>
<line x1="40" y1="166" x2="680" y2="166" stroke="#ECEAE4"/>
<text x="40" y="186" font-size="12" fill="#23303A"><tspan font-weight="700">Same seed</tspan> β†’ same list β†’ same run. <tspan fill="#6E7F8C">Change the seed β†’ a different list β†’ a different run.</tspan></text>
</svg>
```
### Ξ» trade-off diagram
```svg
<svg viewBox="0 0 720 410" xmlns="http://www.w3.org/2000/svg" role="img" font-family="ui-sans-serif,system-ui,sans-serif">
<title>How lambda picks the best program size: net fitness = separation minus a per-gene penalty</title>
<desc>Raw separation rises then plateaus; net fitness subtracts lambda times genes and peaks at an intermediate size; a larger lambda moves the peak to fewer genes.</desc>
<g stroke="#ECEAE4" stroke-width="1">
<line x1="70" y1="340" x2="660" y2="340"/><line x1="70" y1="273" x2="660" y2="273"/><line x1="70" y1="207" x2="660" y2="207"/><line x1="70" y1="140" x2="660" y2="140"/><line x1="70" y1="73" x2="660" y2="73"/>
</g>
<g font-size="10" fill="#6E7F8C" text-anchor="end">
<text x="62" y="344">0.5</text><text x="62" y="277">0.6</text><text x="62" y="211">0.7</text><text x="62" y="144">0.8</text><text x="62" y="77">0.9</text>
</g>
<line x1="70" y1="40" x2="70" y2="340" stroke="#D9D6CE" stroke-width="1.5"/>
<line x1="70" y1="340" x2="660" y2="340" stroke="#D9D6CE" stroke-width="1.5"/>
<g font-size="10" fill="#6E7F8C" text-anchor="middle">
<text x="70" y="356">0</text><text x="154" y="356">2</text><text x="238" y="356">4</text><text x="322" y="356">6</text><text x="406" y="356">8</text><text x="491" y="356">10</text><text x="575" y="356">12</text><text x="659" y="356">14</text>
</g>
<text x="365" y="378" text-anchor="middle" font-size="12" fill="#23303A">number of genes in the program</text>
<text x="20" y="190" text-anchor="middle" font-size="12" fill="#23303A" transform="rotate(-90 20,190)">separation (accuracy)</text>
<polyline fill="none" stroke="#3A6B7E" stroke-width="2.5" points="70,340 112,227 154,159 196,117 238,92 280,77 322,67 364,62 406,59 449,57 491,55 575,54 659,53"/>
<text x="500" y="44" font-size="11.5" font-weight="700" fill="#3A6B7E">raw separation</text>
<text x="500" y="59" font-size="10.5" fill="#6E7F8C">rises fast, then plateaus β€”</text>
<text x="500" y="72" font-size="10.5" fill="#6E7F8C">extra genes barely help</text>
<polyline fill="none" stroke="#BC6B2E" stroke-width="2.5" points="70,340 112,231 154,165 196,127 238,105 280,93 322,87 364,85 406,85 449,87 491,89 575,94 659,100"/>
<line x1="364" y1="85" x2="364" y2="340" stroke="#BC6B2E" stroke-width="1" stroke-dasharray="3 3" opacity="0.5"/>
<circle cx="364" cy="85" r="5" fill="#BC6B2E"/>
<text x="376" y="120" font-size="11" font-weight="700" fill="#8A4E20">peak (Ξ» = 0.005)</text>
<text x="376" y="134" font-size="10.5" fill="#8A4E20">engine keeps ~7 genes</text>
<polyline fill="none" stroke="#D79A6A" stroke-width="2.2" stroke-dasharray="6 4" points="70,340 112,247 154,199 196,177 238,172 280,177 322,187 364,202 406,219 449,237 491,255"/>
<line x1="238" y1="172" x2="238" y2="340" stroke="#D79A6A" stroke-width="1" stroke-dasharray="3 3" opacity="0.5"/>
<circle cx="238" cy="172" r="5" fill="#D79A6A"/>
<text x="250" y="200" font-size="10.5" font-weight="700" fill="#B07636">higher Ξ» = 0.03</text>
<text x="250" y="214" font-size="10.5" fill="#B07636">peak shifts left β†’ ~4 genes</text>
<g font-size="11" fill="#23303A">
<line x1="80" y1="398" x2="104" y2="398" stroke="#3A6B7E" stroke-width="2.5"/><text x="110" y="402">raw separation</text>
<line x1="240" y1="398" x2="264" y2="398" stroke="#BC6B2E" stroke-width="2.5"/><text x="270" y="402">net fitness (Ξ»=0.005)</text>
<line x1="450" y1="398" x2="474" y2="398" stroke="#D79A6A" stroke-width="2.2" stroke-dasharray="6 4"/><text x="480" y="402">net fitness (Ξ»=0.03)</text>
</g>
</svg>
```
### Permutations diagram
```svg
<svg viewBox="0 0 700 380" xmlns="http://www.w3.org/2000/svg" role="img" font-family="ui-sans-serif,system-ui,sans-serif">
<title>Permutation null: scores from 200 shuffled-label runs versus the real result</title>
<desc>A histogram of 200 shuffled-label scores clusters near 0.58, well below the real winning score of 0.89; no shuffle reaches it, giving a permutation p of about 0.005.</desc>
<line x1="70" y1="50" x2="70" y2="320" stroke="#D9D6CE" stroke-width="1.5"/>
<line x1="70" y1="320" x2="640" y2="320" stroke="#D9D6CE" stroke-width="1.5"/>
<g font-size="10" fill="#6E7F8C" text-anchor="middle">
<text x="70" y="336">0.4</text><text x="162" y="336">0.5</text><text x="253" y="336">0.6</text><text x="345" y="336">0.7</text><text x="437" y="336">0.8</text><text x="528" y="336">0.9</text><text x="620" y="336">1.0</text>
</g>
<text x="355" y="358" text-anchor="middle" font-size="12" fill="#23303A">score (separation / AUROC)</text>
<text x="20" y="185" text-anchor="middle" font-size="12" fill="#23303A" transform="rotate(-90 20,185)">number of shuffled runs</text>
<line x1="162" y1="60" x2="162" y2="320" stroke="#C7CDD1" stroke-width="1" stroke-dasharray="4 4"/>
<text x="162" y="72" text-anchor="middle" font-size="9.5" fill="#9AA0A6">0.5 = guessing</text>
<g fill="#CFE0E4">
<rect x="110.4" y="303.1" width="20" height="16.9"/><rect x="133.3" y="277.8" width="20" height="42.2"/><rect x="156.3" y="235.6" width="20" height="84.4"/><rect x="179.2" y="176.6" width="20" height="143.4"/><rect x="202.1" y="109.1" width="20" height="210.9"/><rect x="225" y="58.4" width="20" height="261.6"/><rect x="247.9" y="92.2" width="20" height="227.8"/><rect x="270.8" y="159.7" width="20" height="160.3"/><rect x="293.75" y="218.75" width="20" height="101.25"/><rect x="316.7" y="260.9" width="20" height="59.1"/><rect x="339.6" y="286.25" width="20" height="33.75"/><rect x="362.5" y="303.1" width="20" height="16.9"/>
</g>
<text x="150" y="44" font-size="11.5" font-weight="700" fill="#3A6B7E">200 shuffled-label runs (chance)</text>
<text x="150" y="100" font-size="10.5" fill="#6E7F8C">if there were no real signal,</text>
<text x="150" y="113" font-size="10.5" fill="#6E7F8C">scores land in here</text>
<text x="455" y="250" text-anchor="middle" font-size="10.5" fill="#9AA0A6">no shuffle ever</text>
<text x="455" y="263" text-anchor="middle" font-size="10.5" fill="#9AA0A6">gets this far β†’</text>
<line x1="519" y1="60" x2="519" y2="320" stroke="#BC6B2E" stroke-width="2.5"/>
<circle cx="519" cy="60" r="5" fill="#BC6B2E"/>
<text x="519" y="48" text-anchor="middle" font-size="12" font-weight="700" fill="#8A4E20">real result: 0.89</text>
<text x="519" y="300" text-anchor="middle" font-size="11" font-weight="700" fill="#8A4E20">p β‰ˆ 0.005</text>
</svg>
```
## "How these parameters relate" chart
- Keep the neat (HTML/flex, wrapping) version already built.
- Enhancement: make each parameter NAME in the chart's pills a button that opens that parameter's ParamHelp modal (same content). So the chart becomes a map into the detailed help.
## Constraints
- Presentation-only; do not change any GP logic or other tooltips.
- One reusable `ParamHelp` component + one reusable modal; diagrams are separate small components used once each.
- Accessible: "?" is a real button (keyboard-activatable); modal has role/aria, Esc + backdrop + X close, focus trap and focus return.
- Responsive: modal scrolls on small screens; diagrams scale to container width.
- These are Client Components ("use client") since they manage open/close state.