SpringSaLaD: user documentation, and a tutorial translated from the standalone guide - #2073
Merged
Merged
Conversation
All three coordinate setters in the SpringSaLaD site table guarded on c.getX() != res. Only the X one was correct, so an edit to Y or Z was silently discarded whenever the new value happened to equal that site's X -- no error, no change, the old value still in the cell. That is not a rare corner. SpringSaLaD molecules are routinely laid out along an axis with x = 0, so "set this site's z to 0" never worked, which is one of the first things anyone building a linear molecule wants to do. Demonstrated on a site with X=0 before fixing: z=7 took, z=0 was ignored, z=5 took. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019HAnpFxkzf9LmxBayDSANf
…ell editor Some columns are neither text nor checkbox: they hold a model OBJECT and their editor is a combo box of the values legal there. The SpringSaLaD site table's Location column is the clearest case -- it declares Structure.class and its model does `if (aValue instanceof Structure)` and otherwise returns, so a String changed nothing and reported nothing. The editor already holds the legal values, so the string a caller would read off the screen can be turned back into the object the model wants. Columns whose editor is not a combo box keep the String, which is what those models expect -- including the Expression-typed coordinate and radius columns right next door, which parse text. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019HAnpFxkzf9LmxBayDSANf
…ring() selectList matches on the rendered text, but the /tree dump printed String.valueOf(model.getElementAt(i)). Where a renderer shows something else, the dump named items that could not then be selected -- the SpringSaLaD Add Link dialog is exactly that: its lists render a site's name while toString() gives "name~state", so "Anchor~Anchor" appeared in the dump and list <path> "Anchor~Anchor" silently selected nothing. Same defect the table row text had before, and the same fix. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019HAnpFxkzf9LmxBayDSANf
setName additions only, plus one rename. Nothing looked any of these up by name, so nothing changes at runtime; they are identifiers for anything that has to address the SpringSaLaD editors from outside. AddLinkButton, DeleteLinkButton, AddStructuralSiteButton, DeleteStructuralSiteButton - MolecularStructuresPanel FirstSiteList, SecondSiteList - AddLinkPanel AnchorAllButton, AnchorOnlyButton, AnchorStructureCheckBox_<structure> - MolecularTypePropertiesPanel The anchor checkboxes are built one per structure, so naming them by the structure they stand for is the only thing that stays true when structures are renamed or reordered. The rename is ModelProcessSpecsPanel's table: "ScrollPaneTable" -> "ReactionSpecsTable". It was one of eight tables sharing that name, which made it unaddressable - quickstart.sh already works around it by matching on the column headers instead, and says so in a comment. Files under vcell-client are CRLF; the additions preserve that. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019HAnpFxkzf9LmxBayDSANf
The SpringSaLaD trajectory viewer is driven by one. Its frame slider is the time axis of a finished run, and "look at the last frame" is the single most useful thing a script can say about a result - a trajectory at t=0 is the initial condition, which is the one moment that tells you nothing. A drag cannot be synthesised usefully, because the knob's pixel position is a function of the slider's own geometry, so the value is set on the model, which fires the same ChangeEvent a drag would. Takes an integer, or min/max, or -1 meaning the maximum - the same "-1 is the end" convention readcell already uses for the last row of a results table. Values outside the range are clamped rather than refused: a caller asking for frame 10000 of a 201-frame run means the end. Not recorded by UiRecorder, which does not observe sliders at all - a human dragging one is not captured either, so nothing is lost that was there. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019HAnpFxkzf9LmxBayDSANf
SpringSaLaDUsersGuideAndTutorial.pdf is not an outdated VCell tutorial. It describes a DIFFERENT PROGRAM - a standalone pair of jars with its own "Langevin Dynamics System Setup" GUI, which tells the reader to install Java 8 and double-click a jar - and VCell has since absorbed that capability as the SpringSaLaD application and the Langevin solver. So this script is a translation rather than a re-enactment, and the storyline carries the noun-by-noun mapping: site types to molecular components, "Set as 2D" to the Is 2D column, the cube with a membrane at z=0 to a 3D analytic geometry, the Simulation Manager to the Simulations tab, the 3D Viewer to the 3D Trajectory tab, and the plain-text system file to .ssld. PART 1 builds the document's toy model of receptor kinase activation - an extracellular ligand, a transmembrane receptor kinase, an intracellular substrate - entirely through tables. 0 errors, 0 warnings. The thing worth knowing, and the reason the model comes out right with nothing to correct: THE ORDER OF THE SITES DECIDES WHICH SIDE OF THE MEMBRANE THEY ARE ON. SpeciesContextSpec assigns each site a compartment by where it sits relative to the reserved Anchor site - before it is Extracellular, after it is Intracellular - lays them out along z in that order, and links them in a chain. So writing the receptor as RK(B~State0~State1,Anchor~Anchor,K~Off~On), outside/membrane/inside, is the whole of the standalone program's 3D editor section: correct compartments, correct z ordering, and two springs meeting at the anchor. Written with Anchor first, both domains land inside the cell and every one of those has to be undone by hand, which is how the first draft of this script went. PART 2 does not build the reactions, and cannot: reaction rules have no textual route (BioModelEditorReactionTableModel.isCellEditable allows the BNGL column only for a ReactionStep, and the rule editor is a single anonymous custom-painted component with zero children - issue #2068). .ssld does not rescue it either: that format is the standalone program's own save file, so writing one by hand means writing the whole system, and learning it by exporting first hits #2070. So Part 2 opens a model that already has them - aaa-aSpringSaLaD-Good, a published model kept in this repo as a test fixture, whose nine rules are one of every subtype - reads each subtype and transition condition back out, runs the Langevin solver locally with the bundled langevin_x64, and drives the 3D Trajectory viewer to its last frame. Three bugs found on the way, all filed: - #2070 exporting a reaction-less SpringSaLaD application reports "Export saved as <path>" and leaves a 0-byte file. - #2071 auto-generated _tot observables land in getStructure(0), which for an anchored molecule is a standing warning with no remedy but deletion - and rebuilding one through New > In Membrane swaps it for a different warning. - #2072 the reserved Anchor site defaults to DARK_GRAY and the viewer draws on black. Every membrane molecule has an anchor, so the script gives every site a light colour and says why. A fourth was fixed rather than filed, in f3b1dc1. Also corrects a comment in quickstart.sh that this branch made stale: the Specifications > Reaction table is no longer one of eight called "ScrollPaneTable". The check still matches on column headers, because that is what it was verified against. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019HAnpFxkzf9LmxBayDSANf
VCell has had a SpringSaLaD application, a Langevin solver, a Molecular Structures editor and a 3D trajectory viewer for some time, and no user-facing documentation for any of it. What the help tree had was four scaffolds, all four hidden behind commented-out TOC entries (issue #2060). They were not finished pages waiting for a release. Three had an EMPTY <operations> section - the part that says what to do - and SpringSaLaDTheory was 484 bytes reading "Some text here", "Another paragraph", "Yet another paragraph...". So there was nothing provisional to protect. Six pages now, all in the TOC: - SpringSaLaDTheory, rewritten from scratch: molecules as spheres joined by stiff springs, what a site carries, the five reaction subtypes, and when SpringSaLaD is and is not the right tool. - LangevinApp: creating the application, the geometry it builds for you, how to resize the box and move the membrane (two independent edits - the extent and the Intracellular expression), and every Langevin solver option against the standalone program's name for it. - SSSpeciesSpecifications: sites, anchors, links, initial conditions, and the rule that decides everything - site order relative to Anchor is what puts a site inside or outside the cell. - SSReactionsSpecifications: the five subtypes and their templates, the reversibility rules, and two things a reader will otherwise hit blind (below). - SSResults, new: the 3D Trajectory viewer, and how View Data differs between a single trajectory and multiple runs. - SSImportExport, new: the .ssld format, what does and does not survive a round trip, and why an application with no reactions cannot be exported. Two explanations worth calling out, because both are errors a reader meets before they meet the concept: "The forward rate Kf is too large." The Kf you write down is the MACROSCOPICALLY OBSERVABLE rate, and it already contains two steps in series: finding a partner, and reacting once collided. Their reciprocals add, so the observable rate can never exceed the purely diffusion-limited one. The solver does not want Kf - it wants the INTRINSIC rate, the part conditional on a collision, because collisions are something it simulates rather than assumes - and it recovers that from Kf and the diffusion limit. If Kf exceeds the limit no positive intrinsic rate exists, and the model is asking for something physically impossible rather than merely fast. Fix by raising the diffusion coefficients or radii of the participating sites, or by lowering Kf. The transition condition changes name on the way in, and two of three land on a different word for the same thing: SpringSaLaD's "None" (no condition) is VCell's "Any", and its "Free" (must be unbound) is VCell's "Unbound". VCell's own source calls the terminology "very confusing", because the enum carries three names per value. A reader who picks the label matching the document gets the wrong condition two times out of three. Images: SS_trajectory.png and SS_solver.png are new, both captured from a real local run. SS_species.png is REPLACED - the 2024 one shows a Molecular Structures panel that no longer exists, with X/Y/Z and Color as fields below the table and Links as a plain list; they are table columns now, and Links has a Length column. SS_general.png and SS_reactions.png are still accurate and are kept. Verified: DocumentCompiler runs clean over the tree - no error names any of the six pages, no unreferenced-image warning names any of the new images. The seven errors it does report are all pre-existing (four oversized images, and WarningsList / SimResultsDataRange unreferenced), none of them touched here. TOC.xml is CRLF and was patched in binary mode. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019HAnpFxkzf9LmxBayDSANf
A SpringSaLaD site's z runs from outside to inside - an extracellular site sits at a smaller z than the anchor, an intracellular one at a larger z. The geometry's Intracellular expression runs the other way, "z < number", and a reader who takes both for the same frame will try to reconcile two numbers that have nothing to do with each other. They do not: the solver is told both a site's compartment and its offset within its molecule, and places the molecule accordingly. Says so, and cites the standalone tutorial's own wording for the convention. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019HAnpFxkzf9LmxBayDSANf
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
vcell.org/webstart/SpringSaLaD/SpringSaLaDUsersGuideAndTutorial.pdfis the odd one out inthe tutorial set. Every other document there describes a VCell workflow that has drifted.
This one describes a different program — a standalone pair of jars,
SpringSalad.jarand
LangevinNoVis01.jar, with its own "Langevin Dynamics System Setup" GUI, which tellsthe reader to install Java 8 and double-click a jar.
VCell has absorbed the whole of that capability — a SpringSaLaD application on an
ordinary rule-based physiology, the Langevin solver, a Molecular Structures editor
and a 3D Trajectory viewer — and had no user-facing documentation for any of it.
What the help tree had was four scaffolds, all four hidden behind commented-out TOC
entries (#2060).
This PR writes the documentation, unhides it, and adds a verified tutorial script that
translates the standalone guide into the VCell workflow.
The documentation — six pages, all now in the TOC
They were not finished pages waiting for a release. Three had an empty
<operations>section — the part that tells a reader what to do — and
SpringSaLaDTheory.xmlwas 484bytes reading "Some text here", "Another paragraph", "Yet another paragraph...".
SpringSaLaDTheoryLangevinApp<operations>written — creating the application, the geometry it builds for you, how to resize the box and move the membrane, every Langevin solver option beside the standalone program's name for itSSSpeciesSpecifications<operations>written — sites, anchors, links, initial conditions, and the ordering rule belowSSReactionsSpecifications<operations>written — the five subtypes and their templates, and the two explanations belowSSResultsSSImportExport.ssldformat and what survives a round tripTwo explanations worth calling out
Both are errors a reader meets before they meet the concept.
"The forward rate Kf is too large." The Kf you write down is the macroscopically
observable rate, and it already contains two steps in series: finding a partner, and
reacting once collided. Their reciprocals add, so the observable rate can never exceed the
purely diffusion-limited one. The solver does not want Kf — it wants the intrinsic rate,
the part conditional on a collision, because collisions are something it simulates rather
than assumes — and it recovers that from Kf and the diffusion limit. If Kf exceeds the
limit, no positive intrinsic rate exists: the model is asking for something physically
impossible rather than merely fast. Raise the diffusion coefficients or radii of the
participating sites, or lower Kf.
The transition condition changes name on the way in, and two of three land on a
different word for the same thing: SpringSaLaD's None (no condition) is VCell's
Any, and its Free (must be unbound) is VCell's Unbound. VCell's own source calls
the terminology "very confusing", because the enum carries three names per value — the
RBM bond type, the table label, and the
.lngvname. A reader who picks the label matchingthe document gets the wrong condition two times out of three.
The tutorial —
springsalad-mapk.shPart 1 builds the document's toy model of receptor kinase activation — extracellular
ligand, transmembrane receptor kinase, intracellular substrate — entirely through tables.
0 errors, 0 warnings, asserted from the Problems tab.
The thing worth knowing, and the reason the model comes out right with nothing to correct:
the order of the sites decides which side of the membrane they are on.
SpeciesContextSpecassigns each site a compartment by where it sits relative to thereserved
Anchorsite — before it is Extracellular, after it is Intracellular — lays themout along z in that order, and links them in a chain. So writing the receptor as
RK(B~State0~State1,Anchor~Anchor,K~Off~On)— outside, membrane, inside — is the whole ofthe standalone program's 3D-editor section: correct compartments, correct z ordering, and
two springs meeting at the anchor. Written with
Anchorfirst, both domains land insidethe cell and every one of those has to be undone by hand, which is how the first draft
went.
Part 2 does not build the reactions, and cannot — reaction rules have no textual route
(#2068), and
.sslddoes not rescue it, since that format is the standalone program'sown save file. So it opens a model that already has them:
aaa-aSpringSaLaD-Good, apublished model kept in this repo as a test fixture, whose nine rules are one of every
subtype. It reads each subtype and transition condition back out, runs the Langevin
solver locally with the bundled
langevin_x64, and drives the 3D Trajectory viewerto its last frame.
Bugs found by building it
One is fixed here; three are filed.
f3b1dc16d4) — a site's Y or Z could not be set to a value equal to its X.All three coordinate setters in
MolecularTypeSpecsTableModelguarded onc.getX() != res; only the X one was right, so Y and Z edits were silently discarded —no error, no change, the old value still in the cell. SpringSaLaD molecules are routinely
laid out along an axis with x = 0, so "put this site at z = 0" never worked. Negative
control before fixing: z=7 took, z=0 was ignored, z=5 took.
<path>" and leaves a 0-byte file. Three defects stacked:
isLangevin()decidesfrom the first
ParticleJumpProcess, so a model with no reactions is classifiednon-Langevin;
LangevinLngvWriterthrows;SpringSaLaDExporter.getDocumentAsStringswallows it in a catch-all returning
null; the caller NPEs and still reports success._totobservables land ingetStructure(0), which for ananchored molecule is a standing warning with no remedy but deletion, since the
Structure column is read-only. Rebuilding one through
New > In Membraneswaps it for adifferent warning, because
addObservableseeds an empty species pattern that settingthe definition does not consume. Neither path reaches a clean model.
Anchorsite defaults toDARK_GRAY, and the trajectory viewerdraws on black. Every membrane molecule has an anchor, so this is not an unusual
configuration — it is every membrane molecule in every SpringSaLaD model. The canvas has
a
visible()floor for this, but it only catches near-black; DARK_GRAY (64,64,64) sailspast it and then loses most of that to the sphere shading.
Changes to production code
Outside the two debug-bridge files, every change is a
setNamecall plus one rename.setNameis an identifier for lookup and affects nothing at runtime.AddLinkButton,DeleteLinkButton,AddStructuralSiteButton,DeleteStructuralSiteButton,FirstSiteList,SecondSiteList,AnchorAllButton,AnchorOnlyButton, andAnchorStructureCheckBox_<structure>— the last built one perstructure, so naming it by the structure is the only thing that stays true when
structures are renamed or reordered.
ModelProcessSpecsPanel's table,ScrollPaneTable→ReactionSpecsTable.It was one of eight tables sharing that name, which made it unaddressable —
quickstart.shalready worked around it by matching on column headers, and says so in acomment that this PR corrects.
The bridge itself is behind
-Dvcell.debugBridge=trueand ships inert. It gains one verb,slider, because the trajectory viewer is driven by one and "look at the last frame" isthe single most useful thing a script can say about a result.
Files under
vcell-clientare CRLF, includingTOC.xml; every edit preserves that, andthere is no whitespace-only churn in the diff.
Verification
springsalad-mapk.shexits 0 from a clean client — Problems tab empty, every fieldread back and checked, all seven subtype/condition pairs correct, the Langevin solver run
locally, and the viewer stepped from
frame 1 / 201 t = 0.000toframe 201 / 201 t = 0.02000.DocumentCompilerruns clean over the whole help tree: no error names any of the sixpages, no unreferenced-image warning names any of the new images. It reports the same
six errors before and after this branch — four oversized images, and
WarningsList/SimResultsDataRangeunreferenced — none of them touched here.smoke,detach-window,detach-window-recorded), andquickstart.shstill reports the same verdict after thetable rename: 5 claims hold, 3 stale, with the Fast-checkbox check still finding its
table.
mvn test -pl vcell-client -Dgroups=Fast: 37 run, 0 failures, 0 errors.Images
SS_trajectory.pngandSS_solver.pngare new, both captured from a real local run.SS_species.pngis replaced — the 2024 one shows a Molecular Structures panel that nolonger exists, with X/Y/Z and Color as fields below the table and Links as a plain list;
they are table columns now, and Links has a Length column.
SS_general.pngandSS_reactions.pngare still accurate and are kept.Closes #2060.
🤖 Generated with Claude Code
https://claude.ai/code/session_019HAnpFxkzf9LmxBayDSANf