Skip to content

How it works

Nothing on this page is needed to use prot-struct-viz. It is here for anyone extending the package, or wondering why the output file is shaped the way it is.

The pipeline

  1. The structure is fetched from RCSB (or read from a local file) and its deposited residues are enumerated in author numbering, each classified as polymer, glycan, ligand, ion, or water.
  2. The CSV is parsed strictly, and its residue set is checked against the structure's addressable residues. The result goes into the report file.
  3. A MolViewSpec state plus a JSON annotation table are zipped with the coordinates into an MVSX archive, embedded base64 in the HTML, and loaded by Mol* in the browser.

Annotation tables, not baked-in colors

An annotation table is a MolViewSpec concept: a table of rows, each selecting some residues and carrying a value — a color, a tooltip. The Mol* state references the table rather than naming every atom, and Mol* resolves the rows at load time.

The consequence is worth knowing even as a user: everything the file sets is the initial state, not a frozen picture. The Components panel stays usable, so a reader of your figure can restyle what is there or turn a component off.

There is one real limit, and it follows from where the colors hang. color_from_uri is a child of each representation node, so Mol* resolves the annotation rows into the representations the file created and nowhere else. A representation you add yourself from the Components panel is a new node with no annotation attached: it arrives in Mol*'s own element coloring and cannot be recolored from the CSV through the UI. This is a property of MolViewSpec rather than a setting — the format has no structure-level or global color node, only per-representation ones.

Tooltips and labels are unaffected, because they attach higher up: tooltip_from_uri is on the structure node, and the persistent labels are primitives on the structure. So a representation you add still shows the CSV tooltips on mouseover; only the color is missing.

The Reset view button reloads the state from the archive still embedded in the page, which restores the coloring and the starting camera.

Being primitives rather than components is also why the page carries its own Labels checkbox: the labels are not an entry in the Components panel that a reader would find and switch off. The checkbox hides the representation Mol* builds for each primitives group, so one click covers every label and every symmetry copy of it.

What the components are called

Mol* names each entry in the Components panel after the annotation field and value it selects on, which is why they read as MVS Annotation Component (base_rep: surface) rather than something friendlier. The fields are ours:

  • base_rep — the base representation for a group of residues: from default_representation or chain_representation, or ball-and-stick for a heteroatom the CSV names.
  • extra_rep — the additive layer from the CSV's representation column.
  • het_layer — a default heteroatom group (ligand, glycan, ion, water) holding residues the CSV does not name.

Mol* composes that label itself, and MolViewSpec has no field for overriding it.

Every view is built up front

A spec's views are one MolViewSpec state with several structure nodes, not several snapshots. All of them are built when the page loads and the selector only changes which is visible, which is what keeps the camera still while a reader switches. The cost is that geometry scales with the number of views — three views of a large surface is three surfaces — so first paint and memory grow with the list.

They are separate structure nodes rather than separate components because Mol* collects tooltip_from_uri per structure node: one shared node would merge every view's tooltips into a single mouseover.

The snapshot stepper is hidden

Mol* mounts a snapshot stepper in the top-left of the viewport whenever at least one snapshot is registered, and the MolViewSpec loader registers one even for a single-state file. Since views here are not snapshots, it always reads [1/1] with a timestamp, over a play button that cycles a list of one. Mol* offers no configuration option to suppress it, so the generated page hides it with a stylesheet rule.

Why only the asymmetric unit is embedded

assembly does not expand symmetry copies into the file. The deposited coordinates go in alongside an assembly id, and Mol* generates the copies in the browser. A 60-mer capsid therefore costs the same bytes as its asymmetric unit.

This is also why validation is independent of assembly: symmetry copies introduce no new residue numbers, so the addressable residue set is the deposited one either way.

Structures are not cached

A PDB ID is fetched on every run. Only the coordinate text is used, and it ends up embedded in the output, so a cache would save one HTTP request at the price of a stale-file failure mode. If you are re-rendering the same entry repeatedly, download it once and pass the path as structure instead.

Why a large export is sharper

Mol*'s screenshot is a fresh offscreen render, not a scaled-up copy of the viewport, and it turns on quality settings the live view cannot afford: 16 jittered samples of anti-aliasing against the viewport's 4, and, where ambient occlusion is on, 128 occlusion samples against 32. That is why it takes seconds and freezes the view.

There is no ray tracing to turn on. Mol* rasterizes, and its depth cues are screen-space effects. The nearest thing is the optional Global Illumination pass (keyboard G), which is off by default; a screenshot taken with it on runs it for more iterations than the live view does.

What the file does and does not carry

All the data is inline: coordinates, colors, tooltips, labels, and the state that ties them together. There is no server side and no data fetch at view time.

Mol* itself is loaded from a CDN, at a version pinned by the package. So viewing needs an internet connection, but not a backend — which is what makes GitHub Pages, or any static host, enough.