2026-07-04 — v23 primer design + Tm + in-silico PCR
Work unit 4: the Primer panel lets you enter a forward and a reverse primer, instantly see Tm / GC% / hairpin risk / self-dimer scores computed with the SantaLucia 1998 nearest-neighbor parameters, search the loaded sequence for binding sites (mismatch-tolerant, strict 3′ end), and predict PCR amplicons — all in-browser, nothing uploaded. This closes the Sanger-review → primer-design → PCR-validation loop without a context switch to another tool.
What changed
-
Nearest-neighbor Tm library (
src/primers/tm.ts). Implements the SantaLucia 1998 unified parameter set (all 16 dinucleotide ΔH°/ΔS° values, terminal initiation penalties, R × ln(cT/4) entropy correction, and a Marmur–Schildkraut salt correction: Tm += 16.6 × log₁₀([Na⁺])). Default conditions: 250 nM primer, 50 mM NaCl. Also exportscomputeGC(IUPAC-aware),computeHairpinTm(stem-loop scan, ≥ 3 bp stem / ≥ 3 bp loop),computeSelfDimerScore(max contiguous complement run in anti-parallel alignment), andcomputePrimerFlags(length, GC%, Tm, hairpin, self-dimer, 3′ homopolymer, 3′ G/C clamp). -
Binding-site search (
src/primers/binding.ts).findPrimerBindingSitesslides the primer (and its reverse-complement for reverse-strand search) across the template, counting mismatches with a full IUPAC compatibility table. The lastTHREE_END_STRICT = 3bases of the primer must match perfectly (any 3′ mismatch immediately rejects the site). Returns 1-based coordinates to match the VCF / lab convention used by the rest of the app. -
In-silico PCR engine (
src/primers/pcr.ts).predictAmpliconspairs every forward site with every reverse site, emitting a linear amplicon when the reverse site is downstream of the forward site, or a circular wrap-around amplicon whencircular = trueand the primer positions cross the origin. Results are sorted by ascending size then ascending total mismatches.ampliconToFastaserialises the top amplicon to standard FASTA (80-char line wrap, header includes both primer names, size, coordinates, and[circular wrap]tag when applicable). -
Shared types (
src/types/primer.ts). DefinesPrimerEntry,PrimerBindingSite,PredictedAmplicon, andPrimerPairResult— the data contracts that flow between the math layer, the search engine, and the DOM component. -
Primer panel UI (
src/components/PrimerPanel.ts). Two primer input rows (name + sequence), each with a live stat card (Tm, GC%, hairpin Tm, self-dimer score, length, quality flags) that updates on every keystroke without a Run click. "Run in-silico PCR" fires the binding search and amplicon prediction. Results are split into a "Binding Sites" table (primer name, strand, 1-based start/end, mismatch count) and a "Predicted Amplicons" table (rank, size, coordinates, total mismatches). "Export FASTA" downloads the top amplicon with a complete FASTA header. All computation happens in the parent (TraceViewer) — the panel dispatches arun-pcrcustom event and receives rendered results back viarenderPrimerResults. -
TraceViewer wiring (
src/components/TraceViewer.ts). ImportsPrimerPanel,findPrimerBindingSites, andpredictAmplicons. Therun-pcrevent handler extracts the current display-trace sequence (strand-corrected + edited), runs binding search on both strands, predicts amplicons, and callsrenderPrimerResults. The panel is cleared bysyncContigPanel(which fires on every workspace change) so stale results never persist across trace loads. -
Full light + dark theme (
src/style.css).--color-primer-*design tokens (14 light, 14 dark), covering panel background, border, title, forward/reverse pill labels, stat text, quality-flag chips (amber warning, green OK), table header, and table border. The primer panel uses a purple accent distinct from the reference panel (sky-blue) and the contig panel (deep-blue).
Spec grounding
Tests
| File | Count | What is asserted |
|---|---|---|
tests/core/primers.test.ts |
53 |
computeGC: exact values for ACGT / poly-A / poly-G / 20-mer /
IUPAC S / empty / case-insensitive.computeTm: numeric + not-NaN; ordering (longer > shorter,
high GC > high AT); range check for a known 18-mer; salt effect.computeHairpinTm: null for short sequence; non-null for
self-complementary 15-mer; no crash for random 20-mer.computeSelfDimerScore: 0 for all-A vs all-T RC;
≥ 2 for ACGT palindrome; ≥ 3 for ATATAT; ≥ 3 for 3′ self-complement tail.computePrimerFlags: no flags for ideal primer; each flag
trigger tested individually (short, low/high GC, low Tm, hairpin,
self-dimer, 3′ homopolymer, 3′ no-clamp).findPrimerBindingSites: exact 1-based forward site position;
forward-strand exact match; reverse-strand RC match; zero-tolerance
rejection; 1-mismatch tolerance; 3′ mismatch rejection; primer longer than
template.predictAmplicons: one amplicon with exact size and sequence;
mismatch passthrough; zero amplicons when rev upstream of fwd; ascending-
size sort; circular wrap-around; no circular when disabled; maxSize filter;
empty forward/reverse arrays.ampliconToFasta: header contains both names, size, and
coordinates; sequence present; trailing newline; circular-wrap tag;
80-char line wrap.
|
tests/e2e/primer.e2e.test.ts |
8 |
Panel visible after trace load; live Tm/GC stats appear on input;
Run button disabled/enabled correctly; binding sites section appears
after Run; status reports site and amplicon counts; FASTA download
header starts with >amplicon [ (when amplicons found);
primer name reflected in UI; results cleared after new trace load.
|
Design decisions
- No new npm dependencies. The entire Tm calculator, binding search, and PCR engine are pure TypeScript — no bioinformatics library needed. The SantaLucia 1998 parameter table is embedded as a 16-entry constant (≈ 50 lines).
- 3′ strict-end rule. The last three bases of every primer must match perfectly — any 3′ mismatch immediately rejects the site. This mimics the biological reality that DNA polymerase extension requires a matched 3′ terminus, and prevents spurious partial matches from polluting the results.
- Live stats without clicking Run. Tm / GC% / hairpin / self-dimer update on every keystroke using the same pure-TS functions as the test suite. This makes the panel feel interactive rather than batch-oriented.
- Amplicon results not encoded in permalink. A predicted amplicon sequence (up to 5 000 bp) would far exceed the 1 800-character URL-hash guardrail. Users re-run PCR from the panel after re-loading the trace — the primer sequences themselves are short enough to encode in a future permalink extension.
- Privacy preserved. All primer sequences, binding searches, and amplicon predictions happen locally. The hint text in the panel reads "all in-browser, nothing uploaded" — matching the privacy language used across the reference-alignment and contig-assembly panels.