Spaces:
Running
Running
Commit History
17 days ago
-
Point the tech report links at bioRxiv (#2) Running
- Point the tech report links at bioRxiv (b752244fd4abe270cc58e49568ff54c1b97eee3f)0135ce6
-
Species tree: drop viruses + retitle (25 species, 571,789 sequences)
Removes SARS-CoV-2 and HIV-1 from the §7 dendrogram since viruses are not part of the tree of life. Retitles the section to "How Carbon groups species from DNA", reframes the lede as a representation-geometry question (not a phylogenetic claim), and updates the takeaway to use kingdom-correct terminology ("animals cluster with animals" rather than "vertebrates cluster with vertebrates"). §6 UMAP is intentionally left intact. Recomputes Ward + UPGMA linkages and dendrogram layouts on the trimmed 25-leaf distance matrix; removes the viruses kingdom from the build script, the demo legend, and the tree-tip color table. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>a54539b
-
Suggesting wording change. (#1)
- Suggesting wording change. (e4a9c8f3b3da120450e20dfd80282b443ead8876) Co-authored-by: Margaret Mitchell <meg@users.noreply.huggingface.co>4833b78
-
bp-level: rewrite snippets for fns revision (single checkpoint, batched score_sequence)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>a36d457 -
Site map: line-art SVG icons + unified arrows in place of 01–04 numbers
Replace the mono "01/02/03/04" labels in the "What's inside" band with small line-art SVG glyphs that match the rest of the page's editorial visual language (1.2-stroke round, no fills, no frames — same DNA as the skeletal molecule formulas and the cd-helix diagram in §1–§2): • Intro — open book / primer • DNA Lab — short double helix with 6 base-pair rungs • Carbon Recipe — labelled flask with bubbles • Sandbox — terminal with prompt + cursor Each icon is monochrome (var(--ink) at rest, var(--green) on hover) via currentColor. The down/right arrows are now the same SVG; the first card rotates its glyph 90deg so the Intro card points down while the other three point right, giving every card identical arrow weight and geometry. Hover state preserved: arrow slides in its direction, label + icon + arrow shift to green together. Co-authored-by: Cursor <cursoragent@cursor.com>6a0d3d3
-
Intro: split hero rail/figure + new site-map band
- .tab-lede--split: sticky left rail (title + lede + figure caption) with the Pareto SVG promoted to a sibling figure on the right, so the message stays in view while the chart reads as adjacent evidence. - Pareto chart: tighter viewBox cropped to visible content, L-shape axis lines replace the full frame, 275× speedup shaft split around a centred on-axis label, italic units subtitle dropped. - Replace .intro-guide-list with .intro-sitemap: full-width banded nav of four numbered cards (Intro / DNA Lab / Carbon Recipe / Sandbox) feeding the existing #primer/#dna-lab/#recipe/#sandbox routing. Co-authored-by: Cursor <cursoragent@cursor.com>c30d8ed -
Merge branch 'main' of hf.co:spaces/HuggingFaceBio/carbon-demo
Co-authored-by: Cursor <cursoragent@cursor.com> # Conflicts: # demo.html187590e -
Footer: editorial site footer with collab credit + partner logos
Adds a multi-row site footer in demo.html (collab block with 4 partner stamps, three-column identity/resources/sections strip, legal hairline) backed by a full rewrite of assets/styles/footer.css. Drops partner artwork under img/partners/ (Hugging Face, Zhongguancun Academy, TIGEM, Federico II) plus their raw sources for traceability. Also bundles a few small fixes uncovered while wiring the footer: - demo.html banner: point Tech report to the paperswithcode landing - sandbox.js: clear the .empty placeholder when incrementalRender takes over straight from idle, so generated lines stop rendering inline - section-vep.css: allow horizontal scroll on .vep-window so the 60bp mono stack survives narrow viewports without breaking row alignment - intro/species/controls/recipe/banner CSS: footer-adjacent polish Co-authored-by: Cursor <cursoragent@cursor.com>5dfaccc -
Pareto chart: rebuild as inline SVG, add Dataset link to banner
Replaces /img/pareto.png with a self-contained SVG built from pareto/pareto_data.csv. Geometry mirrors the matplotlib reference (log-scale throughput, linear win-rate %, family badges, 275× speedup arrow, "better/faster" indicator) but the chrome is pulled back to fit the editorial blog tone: hairline frame + tick lines, JetBrains Mono tabular tick labels, mono-uppercase indicator eyebrows, and plain text data labels with a paint-order halo instead of pill boxes. Carbon points scale up + use a heavier label per the source script's HIGHLIGHT_LOGO_SCALE. Also adds a "Dataset" link (HuggingFaceBio/carbon-pretraining-corpus) to the banner resources row, between Models and Tech report so the two HF-hub resources sit together. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>0659e8b -
Intro polish: pareto chart in release rail + rewritten DNA Lab / Recipe ledes
- Release hero: move pareto throughput-vs-win-rate figure inside the green left rail so it visually belongs to the announcement; add hairline border and 640px max-width. - DNA Lab tab-lede: lead with what the model is + invite to explore, drop the "no curriculum" framing, soften the supervision claim (acknowledges species/biotype tags). - Recipe tab-lede: promote the curated data mixture to a third pillar alongside the 6-mer tokenizer and FNS loss. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>d835cbf -
Header: point Models link to Carbon collection
Re-applies the change from ea40f6c, which was silently dropped during the rebase onto d001974 because the surrounding banner-links structure had shifted. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>616acfe -
Demo polish + scripted reel tour
§1-§7 section titles rewritten (Autocomplete for the DNA, Recognizing gene structure, Predicting mutation effects, Species specific generation, From DNA to proteins, Mapping out genomes, Reconstructing the tree of life) with matching lede rewrites; §3 status pill moves to the top-right of the DNA box and forest-bar viewBox tightens to rowH=46 so each row fits a single reel frame; social banner reflects the 393,216 bp context. app.py adds a DEV=1 mode that re-reads templates per request (so edits to demo.html / social-banner.html show up without restarting uvicorn) and exposes /reel for the scripted tour. social_reel.html drives the tour: banner stage now adopts the iframe size (no letterbox, no crop), ken-burns zoom is gone, scene-to-scene transitions are a vertical slide on .stage-frame, and the logo / thumb contact sheets are hidden in the embedded banner so only the hero shows. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>7ae5802 -
demo.html: hash router so /social-banner is shareable from the HF Space parent URL
The HF Space wrapper pins the iframe src to the Space root and won't let you path into /social-banner from huggingface.co/spaces/... — the parent treats the slug as a subpath and 404s. The hash, on the other hand, is forwarded into the iframe verbatim, which is the standard trick Gradio/Streamlit apps use to surface deep links. Tiny inline script as the first child of <head> sniffs known share hashes (#banner, #social-banner, #share, #press) and replaces the location with /social-banner before any other asset hydrates, with documentElement.visibility hidden as a safety net so slow CPUs don't flash the demo first. Existing in-page anchors (#tokenizer, #vep, …) are unaffected — they're matched against a small allowlist. Shareable as e.g. https://huggingface.co/spaces/<org>/<space>#banner in the private Space context. Co-authored-by: Cursor <cursoragent@cursor.com>005af91 -
Social banner: HTML-rendered OG share thumbnail (1200x630, static)
- Compose the OG share image directly in HTML/CSS using the same .carbon-banner stage as the live header — copying the rendered tile into img/thumb.png keeps the share image perfectly in sync with the product, no manual export needed. - Mark the OG tile's header with data-static so banner.js draws a single frame on it; the live demo header still animates as before. - Refactor banner.js to support multiple .carbon-banner instances and honor data-static to skip the RAF loop / observers cleanly. - Nudge the OG-only helix slightly right (translateX -18px vs -56px on wider Twitter/LinkedIn ratios) so the 1200x630 ratio keeps a clean strip of paper between the wordmark and the strand. - Drop the now-unused img/logo.png and point all SEO/OG/Twitter/JSON-LD tags in demo.html at img/thumb.png with its actual 2392x1258 export dimensions. Co-authored-by: Cursor <cursoragent@cursor.com>6ea760c -
Social banner: logo + OG contact-sheet, widened helix, refreshed SVG kit
- Bring back the 44×44 brand mark in the social-banner identity strip so the editorial card reads consistently with demo.html's hero. - Add a "logo · brand marks" contact-sheet (logo.svg, logo-square.svg, logo-square-white-background.svg, logo-rectangle.svg) below the banner stage so the page doubles as a screenshot-ready brand kit. Each tile is a 1:1 export canvas with a copy-path button. - Add a "seo · share thumbnail" tile showing the current og:image (/img/logo.png at native 1153×634) so the SEO surface lives next to the brand assets and is easy to spot when it's time to swap in a real social card screenshot. - Drop the 1px stage hairline so screenshots come out clean of chrome, and ellipsize the meta filenames when they don't fit the tile width. - Widen the helix track in the social stage (36→44%, cap 520→600) and pull the canvas further left so the strand doesn't hug the right edge of the social card on LinkedIn / HF formats. - Refresh the SVG kit: drop the pl…5645f7d -
Demo polish: SEO/AI-agent discoverability + new hexagonal logo + §1 helix per-letter fade + sandbox empty-state
- Discoverability surface: robots.txt, sitemap.xml, llms.txt, JSON-LD/OG/Twitter metadata in demo.html; app.py templates demo + social-banner with {{SITE_URL}} resolved per-request from X-Forwarded-*; Dockerfile COPYs the new files. - New hexagonal Carbon mark (img/logo.svg) plus black square/rectangle lockups used by the social-banner contact sheet. - social-banner: noindex, doubles as a brand contact sheet under the stage with native-size square and rectangle lockups for one-shot screenshots. - §1 intro helix: per-letter depth-aware fade — front-strand letter at each crossing stays readable while its back-strand sibling recedes, instead of both going equally ghosted. - Sandbox empty-state: centered, white-on-white, lighter contrast so the placeholder reads as a hint rather than a block. - New §X efficiency section script wired into demo.html. Co-authored-by: Cursor <cursoragent@cursor.com>1d5de93 -
§3 VEP: replace variant set with audited 8-pick spread
Old set: 6 variants, two disagreed with ClinVar at the 4 kb scoring window, one was effectively invisible, one had a contested clinical classification (TP53 Pro72Arg). Replaced with 8 picks (6 Pathogenic + 1 Risk + 1 Benign), all checked against Carbon-3B at the demo's window length: HBB, BRCA2, TP53 c.712T>A, F9, LDLR splice donor, VHL stop, LRRK2 G2019S, VHL 3' UTR benign. The two VHL rows are paired by design as the narrative payoff (same gene, opposite verdicts: −323 nats vs ≈0). Regenerated data/variants.json end to end via fetch_variants.py + precompute_vep against the live /score endpoint; rewrote GENE_INFO / VARIANT_DESC for the new genes; updated the VEP takeaway to point at the VHL pair instead of the retired sign-disagreement framing. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>41739ad -
Intro §6: add Applications section to the bio primer
Closes out the Intro tab with three application cards covering precision breeding, synthetic biology / biomanufacturing, and biomedical use cases (variant triage and personalized therapy design). Card stack on the right matches the primer's two-col rhythm without introducing new CSS. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>21329c2 -
Recipe §3: extend BP section to cover scoring as a second endpoint
The same marginalization that powers FNS at training time also factors the scoring endpoint, where you read P(actual base | context) directly off the per-position marginals instead of forcing a token. Renamed the section "BP-level inference" (id bpinference) to reflect both endpoints, rewrote the lede, split the visual's last station into step 3a (generate) and step 3b (score), and added a "score" tab to the code snippet showing score_sequence() via the -remote checkpoints.b9445bd -
Demo polish: colorblind-safe §6 strand; §5 completion-fold; §1 helix occlusion; §7 score chip; logo SVG; §8 evals refresh
- §6 UMAP: strand palette switched from green/red to Okabe-Ito blue/vermillion so the +/- coloring survives deuteranopia and protanopia (the previous pair collapsed to two near-identical grays under both common CVD types). - §5 Folding: new completion-fold pipeline (75% CDS prompt → 25% predicted → fold the C-term tail with ESMFold); mrna-info row reads the prompt/predict ratio for completion-fold genes, falls back to the original genomic→mRNA→ORF chain for legacy fixtures. genes.json gains the fold_setup / fold_example fields and a sections[] tag to scope the showcase set per panel. - §1 Intro: helix occlusion now splits each strand at depth-zero PEAKS rather than centerline crossings, so the "behind" arcs alternate between upper and lower lobes and rungs occlude correctly under the front strand. Edge-touching arcs render solid (no ghosted 5'/3' label ties). - §7 Tree: agreement-score chip redesigned as a typographic stat block — percentage in Carbon green + raw …f5d37e0 -
Recipe §3: add bp-level generation section + custom_generate snippet
Slots between §2 FNS and §4 Data: same 6-mer→base marginalisation, applied at inference. Static SVG/HTML diagram of the per-step pipeline, takeaway on when to pick 6-mer vs bp-level, and a code-snippet block showing the HuggingFaceBio/carbon-generate custom_generate method. Lede chips and downstream section numbers updated accordingly. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>d3b6881 -
§4 Species: anchor prompt to 2nd exon, drop zebrafish
- fetch_species.py: also capture per-species exon coords from Ensembl, translated into 0-based offsets in the trimmed seq - species.js: new getPromptWindow() — anchors prefixEnd 35 bp into the 2nd exon (like §1's gene completion); slides prefixStart back by the user-selected prefixLen; falls back to flat slice when exon 2 isn't visible. Always render the prompt (no more "click run all" placeholder). Per-row "{N} bp prompt" note. - species.json: regenerated with exon data; zebrafish dropped (~450 My drift made the row look like noise next to mammals + bird) - demo.html §4 lede/takeaway: reflect new framing and dropped species2c5ccd8 -
Demo polish: header specs, primer rewrite, hide endpoint URL, tab rename
- Banner: 393,216 bp context (was 49,152); footer model badge removed - Intro tab: rewrite primer §0/§1/§3/§4 paragraphs; clarify 1T tokens (6T bp) - DNA Lab intro: use "Carbon-3B" to differentiate from upcoming releases - Hide endpoint URL in frontend (sandbox header + code snippets); /config no longer returns it; backend still uses real ENDPOINT_URL via env/default - Code snippets: rename tabs to "API" / "transformers", generic https://<your-endpoint>/v1/ placeholder, escape angle brackets - Sandbox: fold "Connected to {model}" into the Input card header - Rename tabs demo->dna-lab and model->recipe (URLs now #dna-lab, #recipe)3cf1b0c -
§6 UMAP: highlight curated gene sets (HOX, mitochondrial) + per-mode descriptions
Adds a second toolbar row of "highlight" pills next to the existing colour-by controls. Each pill recolors the WebGL scatter via a 2-class palette (dimmed grey ghost + vivid foreground), so the highlight is a view of the existing points, not new geometry on top. Identity matching is coord-snap via the spatial grid already built for hover, since the bin is species-bucketed and the CSV's row_idx doesn't line up with the bin's row order. Adds a per-mode descriptive paragraph above the chart explaining what each axis or gene set actually is (biotypes, GC content, HOX, mt-DNA), and moves the navigation hint to a right-aligned slot in the stat row. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>468dae5 -
Demo polish: Intro visuals, §3 + §6 charts readability, code-snippet UI
Intro tab (§1–§5) - §1 Atoms: bold green base letters, two-line label (mono A/C/G/T over full name). - §2 Helix: redesign à la 3D banner — letters sit *between* the two strands (helix–base–base–helix), rungs interrupted around them, faded at crossings instead of culled so there are no bald gaps; thinner strands, 5'/3' tags symmetric on both ends, tighter top spacing, more breathing room at the bottom of the card. New base-pair legend: A=T / G≡C in big green type with H-bond meta + caption. - §3 + §4 Gene strip: horizontally centred; track-labels now have a "LEGEND" prefix and §4 gets a duplicated legend. - §5 Translate / fold / 3D viewer: codon-AA grid + caption centred, fold-arrow margins trimmed, 3Dmol viewer 340 → 280 px, three-tier protein caption (sans-serif title 19px / italic desc / mono meta with clickable PDB link). Slow editorial spin (0.4 → 0.15), wheel events on the viewer container forwarded to window scroll so the page no longer traps when the curs…5da533e
-
Intro tab + central-dogma primer + em-dash sweep
- New Intro tab as default landing: release blurb, tab-nav guide (bullet list with banner-style links), and an optional "quick primer in genetics" §1-§5 walkthrough using the existing section--two-col + .demo primitives. - Primer visuals: skeletal-formula SVGs for the four bases, static DNA helix (~10 bp/turn), gene strip (promoter / exons / introns), splice diagram with transcribe arrows, 10-column codon to amino-acid table with peptide-bond chain, and a live 3Dmol.js viewer of human hemoglobin (PDB 1A3N) bundled in assets/data/ for fast first paint. - Lazy-init the 3D viewer via MutationObserver on the panel's .active class, so visitors who deep-link to #demo / #sandbox skip the fetch. - Tabs renamed: Demo to DNA Lab, Model to Carbon Recipe (display labels only; data-tab slugs and URL hashes stay 'demo' / 'model' for backwards-compat). - Banner: add Code placeholder link to banner-links; tab buttons use min-width + nowrap so "Carbon Recipe" stays on one line. - …5ea40ce -
Tab-lede: typographic step-down on P2 + §X chip anchors
The intro paragraph below the banner had grown to two full-size lede paragraphs, which read as a wall of text. Without touching the copy, this gives the second paragraph a clear visual demotion so the eye reads it as a navigator / table of contents rather than a second lede: - P2 gets .tab-lede__note (font-size 19→14, color #2d2d2a→#5b5b56, line-height 1.5→1.6, +14px top margin). Reads as a follow-up note under the main definition. - Each "(§X)" in P2 becomes an <a class="lede-chip" href="#section-id"> pointing at the matching section. Mono + warm-green border so the references pop out as scannable jump-to markers within the prose, and clicking actually scrolls to the section. Section anchors used: §1 → #completion, §2 → #track, §3 → #vep, §4 → #species, §5 → #folding, §6 → #umap, §7 → #speciesTree. Co-authored-by: Cursor <cursoragent@cursor.com>dfacb41 -
Carry over §2 Variant rework + §1/§4 polish dropped by the -s ours merge
The previous merge (32c9c3a) used -s ours to keep the local tree intact while preserving Leandro's two upstream commits (57bce37 §2 Variant rework, 176caed banner wordmark) in the history for attribution. Most of those changes had already been adapted locally to the new modular CSS/JS split, but the actual content carry-over wasn't yet committed. This commit applies the remaining ports on top of the merge. §3 VEP (was §2 in Leandro's tree) — refonte complète - 4 kb scoring window: fetch_variants.py WINDOW 60 → 4002 (well below the 8 kb eval recipe but enough that all 3 pathogenic variants land on the correct side of zero). data/variants.json regenerated. - Two-row sequence display: original above, click-editable mutation below, with arrows on every base that differs from the original. Click cycles A → C → G → T, debounced 500 ms rescore against /score. - Per-row log-likelihood score on the right (green if more likely, red if less likely); mutation score blanks to '—' while a…1d3e72f -
Sandbox card layout, sticky-nav breadcrumb, drop §2/§3 score buttons
- Sandbox: refactor into stacked cards (sb-card with eyebrow/title/hint headers, Input → Output) plus a Connected-to strip up top, replacing the flat wall of controls. - Sticky nav: add a CARBON / huggingfacebio-carbon-3b breadcrumb on the left of the sticky strip so the "you're on the Carbon page" cue stays visible after the hero scrolls out. - §2 (VEP) and §3 (Track): drop the manual ▶ score / score all buttons. §3 tracks are precomputed (logprobs ship in data/genes.json), so the toolbar is just a gene selector now; §2 will auto-score on select. - Misc: app.py, precompute.py, controls.css, layout.css, section-tree.css, banner.js and data/genes.json picked up along the way. - Add social-banner.html. Co-authored-by: Cursor <cursoragent@cursor.com>b64beb5 -
Hero refresh + sticky tab nav + section polish
Banner / hero - Desaturate the DNA helix palette (banner.js TINT) so the canvas blends into the paper rather than punching through it. - Cursor caret trimmed from the top so it stops poking above the N's cap height while keeping its baseline aligned with the wordmark. Sticky tab nav - New strip (#tab-nav-sticky) slides in from the top once the in-banner #tab-nav scrolls out of view (IntersectionObserver in tabs.js toggling .is-tabs-stuck on <body>). - Styled as a slice of the banner: same paper backing, dotted grain + green vertical stripes, same bottom hairline. Tabs reuse the in-banner colour scheme with bumped #b8b5a6 borders, sharp corners, top liseré on the active tab, and a margin-bottom: -1px trick so the active card bleeds into the page paper underneath. - Promoted --paper / --ink / --green / --hairline / --muted to :root so the sticky nav (a sibling of .carbon-banner, not a descendant) can resolve them. Section layout - §1 tokenizer: 1-mer and 6-mer colum…1cc98cf
-
Apply section--two-col to all Demo-tab sections (§1-§7)
§5 Folding has been running on section--two-col since the rebuild and the layout works: narrative + takeaway live in a sticky 248px rail on the left, demo claims the rest. With every demo card surrounded by a much-smaller block of words, the visitor was constantly scrolling between "what is this" copy and "what to interact with" demo content. Folding it back into a single grid keeps both visible at once and turns the takeaway into a live margin note instead of a postscript. Sections converted: §1 Autocomplete (id=completion) §2 Variant effect (id=vep) §3 Structure (id=track) §4 Species (id=species) §5 Folding (id=folding) — already done §6 Embedding space (id=umap) §7 Species tree (id=speciesTree) For each: added section--two-col on <section>, wrapped section-num + section-title + lede + takeaway in a new <div class="section-narrative">, and removed the takeaway from its old position after the demo card. Recipe-t…812b476 -
Split demo.html into modular CSS/JS assets
demo.html had grown to 6477 lines with a single inline <style> (1240 lines) and a single inline <script> (4358 lines) — every change meant hunting through one giant scrollback and risked breaking unrelated sections. Extracted into /assets/: styles/ 14 files, ~1280 lines: base, header, banner, layout (incl. new section--two-col), controls, sequence, section-{folding,umap,tree,vep,species}, recipe, sandbox, footer js/shared/ helpers.js (lerp, logprobRgb, renderSeq…) + config.js (fetchConfig, loadConfig, loadGenes) js/sections/ one IIFE per demo card: completion, vep, track, species, folding, tokenizer, loss, data, architecture, sandbox, umap, tree js/ banner.js (DNA helix Canvas 2D), tabs.js (hash routing + bootstrap loadConfig) Strategy: plain <script> tags, not ES modules. Each IIFE was extracted verbatim and globals stay global — minimum behavioural risk. Migrating …39a61da -
§1: replace prefix/gen pills with three draggable handles
Two dark-grey handles bracket the prompt window (drag ▼ on top, ▲ on bottom); a third green ▼ handle on top of the gen-region sets where generation stops. Removes the prefix-length and generate-size pill rows in favor of direct manipulation on the gene track. Also drops the reference sequence block — generated bases are now underlined green (match) or red (mismatch) inline. Legend redrawn as mini-glyphs (exon shape, intron shape, full widget) with instant :hover tooltips. Takeaway prompts the user to try the green window on exons vs introns. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>e9eb9ae -
Add §7 species tree, slim down §6 UMAP, mount /experiments
§7 · Species tree (Carbon-derived phylogeny) - scripts/build_species_tree.py derives a 27-species tree from Carbon-3B mean embeddings: per-species centroid distance matrix + Ward/UPGMA linkage + precomputed dendrogram layout. Output ships as data/species_tree.json (32 KB), served by new /species_tree endpoint. - demo.html gains a §7 section rendering the dendrogram as an SVG spine on the left and aligned rows on the right, with linkage + scope toggles and an "agreement vs NCBI" headline score. - scripts/render_tree_{mockups,mockups_v2,d_plus}.py: offline PNG mockups used during the §7 design review. §6 · UMAP refinements - Drop pos_3d from data/umap.bin. v1 only renders the 2D scatter and the frontend already skipped pos_3d on parse, so the int16×3 coords were 3.3 MB of dead bandwidth per visit. New WRITE_POS_3D toggle in build_real_umap.py for an easy re-enable. Wire payload 6.24 → 3.09 MB gzipped (~−50%). - New /umap_names endpoint serving the lazy-loaded per-poi…1f90847
-
Tune gene-continuation defaults: gen=60 bp, temp=0.5, top_p=0.9
Default 300-bp rollout was past the model's reliable horizon — identity collapsed to ~25% via autoregressive drift / repetition traps. Shorter window keeps demo within the regime where the model is competent (MYC: 27% → 61%; mean logprob: -7.9 → -2.5). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>7838845
-
§5 Folding + §6 UMAP: editorial polish for prod
§5 Folding - AA block laid out as two columns (Carbon left, Reference right) mirroring the 3D viewer grid below, with chips and length tags on each label so the visitor reads "131 aa carbon vs 147 aa reference, 96 mismatches" at a glance - Reference row highlights the same positions as Carbon plus the trailing residues that Carbon dropped (length asymmetry), in the same red as §1 mismatches - mRNA-info strip simplified — the duplicate REFERENCE chip moved out, Carbon/Reference labels in the columns now disambiguate - Soft-wrap tightened from 60 to 40 chars so the two columns line up row-by-row at typical viewport widths §6 UMAP - Six-kingdom species palette (27 species) replacing the synthetic 24-species one - Biotype palette rebalanced: dominant protein_coding desaturated to sage so minority biotypes (lncRNA, snRNA, misc_RNA) read through the overplot - Continuous gc_content gradient replaces the codon-phase pill - Deterministic Fisher-Yates shuffle on the points …7ec25a8
-
Merge feature/umap-scatter into feat/folding-3d (local-only)
Combines the §6 UMAP scatter and §5 Folding work into one branch for end-to-end local testing. To be split back into two separate PRs. demo.html conflict resolution: kept §6 UMAP IIFE from umap-scatter, kept the Canvas 2D banner comment from folding-3d (perf branch already merged into main). No code changes, just a comment block. Co-authored-by: Cursor <cursoragent@cursor.com>45f472e
-
§5 Folding: in-flight indicator on viewers + stats while folding runs
Clicking ▶ fold used to leave the cached cartoons and stats visible unchanged while a fresh run was in flight — the only feedback was a small status line ("carbon generating…") at the bottom of the toolbar, which is easy to miss. Visitors couldn't tell whether the button did anything for the 10-20s the pipeline takes. Now during runFold: - both viewers dim their canvas (opacity .28) and overlay a JetBrains Mono "computing" label with a pulsing green dot; the cached cartoon stays dimly visible underneath for visual continuity rather than blanking out - the overlay label updates per phase: "generating · 1608 bp" while streaming from Carbon, "folding · esmfold" while the two ESMFold calls are in flight - the four stat slots (residues, both pLDDTs, identity) get muted to signal their values are stale - the action button reads "running…" instead of "▶ fold" Everything reverts to the live result on success or to the cached example on error, via the existing try/finally. Co-aut…28428b8 -
§5 Folding: match cartoon palette to the editorial design
3Dmol's stock "rwb" colorscheme uses primary red / pure white / primary blue, which sits visually next to the demo's muted bordeaux + beige + slate-blue palette and looks out of place. The legend bar under the viewers already advertises the demo's colours, but the cartoon ribbons themselves used the loud primary version — small visual mismatch but distracting once you notice it. Replace the colorscheme with a colorfunc that linearly interpolates pLDDT between the three legend anchors (#b00020 → #f0e8e0 → #2c5aa0), the same tokens used for ref mismatches in §1 and base colors in §2. Cartoon ribbons now visibly belong to the same palette as the rest of the page. While in the function: nudge cartoon thickness/opacity slightly to align with the "editorial diagram" feel rather than the textbook-figure default 3Dmol ships with. Co-authored-by: Cursor <cursoragent@cursor.com>39bf380 -
§5 Folding: sync the two 3Dmol viewers so drag/zoom is shared
When comparing two protein structures, the visual comparison only makes sense if both cartoons are shown at the same orientation. Two independent viewers force the visitor to rotate each one separately to re-align them, which is tedious and imprecise — exactly the friction PyMOL/ChimeraX solve with synced cameras. Use 3Dmol.js's native linkViewer() to forward camera changes from each viewer to the other (linking is one-way per call, so we call it both directions). A drag or scroll on either cartoon now propagates to the other, keeping HBB-reference and Carbon-completion in lockstep. The pre-existing per-viewer spin animation is removed: with linked cameras, two independent spins would either fight each other or visibly drift apart. The legend already advertises drag-to-rotate / scroll-to-zoom so dropping the automatic spin is a no-op for discoverability. Co-authored-by: Cursor <cursoragent@cursor.com>c1a9800 -
§5 Folding: hydrate the section from a precomputed fixture
The Carbon endpoint and the NVIDIA NIM ESMFold call together take 10-20s on a cold start, which leaves the section blank when the visitor first scrolls into it. We now ship a precomputed example (Carbon continuation + both ESMFold structures + stats) inside data/genes.json so the section renders instantly. Clicking ▶ fold still triggers a fresh live run. Notable details: - scripts/precompute.py grows a precompute_folds() step that mirrors the live pipeline: it calls the backend /generate (same left-pad-to-six, same <dna> prefix, same streaming framing as runFold()) and then hits NVIDIA NIM directly to fold both the spliced-mRNA reference and Carbon's spliced mRNA. Genes whose last exon sits past 2.5 kb (TP53, MYC) are skipped — Carbon would need to generate too many bases live. - Temperature is set to 0.9 for the fixture, not 0.7. At T<=0.7 the model collapses into low-complexity sinks on long-context generation (poly-T at T<=0.5, AATC-repeat at T=0.7) — a known autoregr…2c4851e -
§5 Folding: splice Carbon's continuation with reference exons
Without this, the Carbon side translates the raw genomic DNA — introns included — while the reference is translated from the spliced mRNA. The two are not comparable: as soon as the first intron starts, the Carbon ORF reads into intronic bases and produces noise, which silently inflated the "Carbon is diverging" signal in the demo. We now treat Carbon's output as if it were the same genomic locus as the reference (it is — Carbon is autoregressively continuing that locus), so we apply the same exon coordinates to assemble a mature mRNA from Carbon's bases. The first ~30 aa stay strictly identical (exon 1 is in the prompt) and the rest reflects what Carbon actually produced for exon 2/3, which is what the section is trying to show. Genes whose last exon sits past ~2.5 kb of genomic DNA (TP53, MYC) would need Carbon to generate too many bases in a single shot to be usable in a live demo, so we hard-cap there: the gene info row shows an inline warning and the fold button returns early wi…c551f95 -
§5 Folding: wire the real DNA → ORF → AA → ESMFold pipeline
This is the section the §5 lede has been promising: feed Carbon a DNA prefix, let it continue, translate its continuation into a protein, fold both Carbon's protein and the reference protein, and put the two cartoons side by side so you can eyeball whether Carbon's completion produced something biologically plausible. Pipeline (per click ▶ fold): reference gene.seq → splice out introns (using gene.exons annotation) → longest ORF in the mature mRNA → AA_ref carbon gene.seq[0..prefix] as prompt → /generate (temp=0.7) → DNA continuation → longest ORF across all 3 frames → AA_carbon both → POST /fold in parallel → 3Dmol cartoons coloured by pLDDT stats: residues (carbon/ref), pLDDT means, 1D identity Asymmetry is deliberate: the reference gets the exon prior (a piece of biology Carbon has never seen) so we have a "true" protein to compare against, while Carbon only sees raw bases and has to find an ORF itself. That's the whole point — if Carbon's na…5509817 -
§5 Folding: HTML + CSS scaffolding with 3Dmol side-by-side viewers
Replaces the "coming soon" stub with a real section that wires up the /fold backend to a pair of 3Dmol cartoon viewers. Layout mirrors §1's two-track convention (carbon completion on the left, reference on the right) so the comparison feels native to the rest of the demo. Frontend: - Pulls 3Dmol 2.5.1 from jsDelivr (defer) — small enough to inline-cache, no bundler needed. Pinned version for reproducibility. - New CSS classes (.fold-grid, .fold-viewer, .fold-viewer-label, .fold-legend, .fold-legend-bar). Two-column at >=720px, stacked below. - Cartoon coloured by B-factor via 3Dmol's rwb gradient — ESMFold writes pLDDT into the B-factor column so per-residue confidence shading is free. Legend shows the same red→white→blue map. - Hand-rolled pill UI for gene selection (HBB / INS / LYZ), reusing the existing .pill and .pills classes. - Stat row (residues, pLDDT mean carbon, pLDDT mean ref, 1D identity) reuses .stat-row / .stat-pair, so the typography matches §1-§4. - Viewers…286aae5 -
Banner: bump helix glyph gap to compensate for rounded line caps
13.5 → 16.5 viewBox units (and the perspective-floor goes 7 → 8.5). At the canvas's stroke width, lineCap:round adds ~0.7px of stroke on each side of the rung tip, eating visibly into the gap around each ATCG glyph and making the ladder feel cramped vs the SVG version that used butt caps. Same gap math, just scaled up to recover that breathing room. Co-authored-by: Cursor <cursoragent@cursor.com>3665c0b -
§6: WebGL UMAP scatter, 500K points on a fake fixture
Replaces the "coming soon" stub for §6 with an interactive scatter that loads 500K points and lets you toggle the coloring axis (species, biotype, strand, codon phase) on the same vertex stream. Frontend (demo.html, ~290 LOC): - Vanilla WebGL (no library) — gl.POINTS + 1D palette texture, fragment shader does smoothstep AA on gl_PointCoord so dots stay clean at any zoom. Pan/zoom-around-cursor + hover picking via a 128² spatial grid. - Toggle coloring rebinds the category attribute on a different uint8 buffer and swaps the palette texture — no re-upload of the 500K vertices. Switch is instant on GPU. - Render-on-demand (no rAF loop); IntersectionObserver defers the /umap fetch until the section approaches the viewport so first paint isn't taxed. Backend (app.py): - GZipMiddleware (minimum_size=1024, compresslevel=6) — gzip(1)'s default level: ~3% worse ratio than 9, ~5x cheaper CPU. Cuts /umap from 4 MB to ~2.1 MB on the wire. - GET /umap → b…f039f0b -
Banner: switch DNA helix from SVG to Canvas 2D + assorted perf cleanups
The SVG helix mutated ~960 path nodes per frame and pinned the main thread at ~25% CPU non-stop. Canvas 2D draws the whole scene to a bitmap each frame with no DOM mutations — typically 10-50× cheaper for this kind of animation. Math and colors are unchanged, output is pixel-equivalent. Bundled in the same pass: - Pause animation off-screen (IntersectionObserver) and on hidden tab - 30 fps cap (visually indistinguishable from 60 at this rotation speed) - Pre-allocated sample/segment buffers, DPR-aware sizing - prefers-reduced-motion → single static frame - segmentCount 96 → 192 for cleaner ribbon antialiasing - Google Fonts: @import → <link preconnect> + stylesheet (parallel load) - Drop background-attachment: fixed (caused viewport-wide scroll repaints) - will-change: transform on header so its gradient pattern doesn't force whole-viewport repaints - Memoize /config + /genes on the *promise* (not the value) so concurrent callers share one network roundtrip Co-authored-by: Cursor…1641614
-
Apply banner's paper-texture pattern to body + header
Lift the radial-gradient + green-edge linear-gradient that lives on the banner up to the body and the sticky header, so the same subtle paper-dot texture runs through the entire page. background-attachment is fixed so the pattern stays viewport-anchored — body and header share the same dot phase, no visual seam where the header ends. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>c97daf1 -
Banner: drop aspect-ratio, let SVG drive height intrinsically
Switch from CSS aspect-ratio on .carbon-banner + height:100% on the inner SVG (which can fail to fill on some browser/parent combinations) to width:100% + height:auto on the SVG. The SVG's viewBox aspect ratio now drives the banner box's height directly, so the banner always fills the full body width (1016px content inside the 1080px .banner-wrap). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>6334f9b -
Crop banner viewBox so header/footer rules align with body edges
The original viewBox (0 0 2048 620) included ~40 units of empty padding on the left/right and ~50 units top/bottom, which made the banner content look small inside the body-width container. Crop to (40 50 1970 540) so the horizontal rules at x=40 and x=2010 sit at the banner's left/right edges — same edges as the blog text below. Nothing inside the SVG was repositioned; only the viewBox and matching aspect-ratio changed. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>83deead