This package is designed to convert BioNetGen Language (BNGL) strings into visual railroad diagrams to represent biological networks and reaction mechanisms. The bngl_parser.js module preprocesses strings from BNGL code files. expanded.js returns fully expanded BNGL strings and compare_reactions.js finds differences between reactants and products in a BNGL reaction rule. Molecules_BNGL_to_Python.js is designed to take these parsed BNGL strings and translate them into formatted diagram code to be drawn by railroad diagram classes. railroad.js is a railroad-diagram renderer that reads the diagram code and generates the SVG railroad visualization. These diagrams show molecular interactions by highlighting sites, states, bonds, and changes through reactions.
- Parses BNGL files line by line to extract sections such as molecule types, species, observables, and reaction rules.
- Cleans BNGL code to ensure proper formatting by stripping comments, extra whitespace, trailing functions or parameters, and malformed lines.
- Standardizes code by merging multiline expressions and fixing malformed molecule patterns that lack parentheses.
- Sends the cleaned BNGL strings to
expanded.jsto fully expand molecule/site definitions andcompare_reactions.jsto detect and return changes across reactions. - Passes expanded BNGL strings and dictionary with reaction changes to bnglToRailroad function in
Molecules_BNGL_to_Python.jsfor conversion.
Expands shortened molecule patterns, as in observables and reaction rules, into their full forms using molSiteDict, which stores all molecules in a given BNGL file and their sites/states.
- Input: a BNGL string and a molecule-site dictionary (molSiteDict)
- Functions:
- Fills in missing sites, states, and bond arguments when only partial information is given.
- Resolves inconsistent ordering of sites within a molecule to match with original order in molecule type definition
- Properly handles and expands sites with the same name.
- Output: returns a fully "expanded" BNGL string for accurate visualization and comparison.
Example: EGFR(tmd!+,y1068~u) returns EGFR(ecd!?,tmd!+,y1068~u!-,y1173~u~p!?) given the molecule EGFR(ecd,tmd,y1068~u~p,y1173~u~p)
Detects bond and state changes between reactants and products and stores the changes in a dictionary to display a reaction rule in a single diagram.
- Input: expanded versions of reactant and product strings, the reaction arrow (either -> or <->), and molecule-site dictionary (molSiteDict)
- compareReactions Functions:
- Analyzes differences between the expanded left-hand side (reactants) and the expanded right-hand side (products) of a reaction rule.
- Tracks changes like bond addition, bond breakage, state transitions, the type of reaction (reversible or nonreversible), and their respective molecules, sites, and states.
- Tracks synthesis and degradation changes and stores in a separate dictionary (synth_deg_changesDict).
- Stores synthesized/degraded molecule's name, full code, and index.
- Handles multiple molecules with the same name separately.
- Handles reactions that use 0 in reactants or products to describe synthesis/degradation.
- Stores changes with notes like:
- "radded" / "nradded" (bond added)
- "rbroken" / "nrbroken" (bond broken)
- "change from bottom state to top state" / "change from top state to bottom state"
- Output: a changesDict that matches molecules, sites, and states to the type of change they undergo.
changesDict[siteKey] = {
molecule: rmol,
site: rsite,
reactant: rRaw,
product: pRaw,
change: change,
};- compareComplexSeparation Functions:
- Goes through expanded reactants and expanded products, and stores the order of separators (either + for molecules in separate complexes or . for molecules in the same complex)
- Analyzes differences between the orders of separators and stores each comparison in a list:
- "NoChangeComplex" / "NoChangeSeparate" (no association/dissociation)
- "NonRevChangeComplex" / "NonRevChangeSeparate" (nonreversible association/dissociation)
- "RevChangeComplex" / "RevChangeSeparate" (reversible association/dissociation)
- Output: a list with all changes that will be inserted between each molecule in a diagram.
Breaks BNGL string into components to write diagram code that includes molecules, sites, states, bonds, and changes from reactions (e.g., state transitions or binding/unbinding). Inserts diagram elements (e.g., Choice, Sequence, Terminal), applies notes for state, bond, or molecule changes, and returns a string of JavaScript code for rendering by railroad.js:
`new Terminal("EGFR", { box_color: "lightgreen" }),
new Sequence(new Terminal("ecd", { box_color: "lightblue" })),
new Sequence(new Terminal("tmd", { box_color: "lightblue" })),
new Sequence(new Choice(0,
new Terminal("y1068", { box_color: "lightblue" }),
new NonTerminal("u", { box_color: "khaki" }),
new NonTerminal("p", { box_color: "khaki" })
)),`bnglString(String): The BNGL-formatted input string representing molecules and their interactions.displayString(String, optional): Alternative display label for the diagram; defaults tonull.changesDict(Object, optional): Dictionary indicating changes such as bonds formed/broken and state transitions. Default isnull.molSiteDict(Object, optional): Dictionary containing molecule-specific site information; default is an empty object{}.arrow(String, optional): Symbol representing reversible or nonreversible reaction changes (e.g., -> or <->).complexChanges(Array, optional): Array indicating whether molecules remain in the same complex or switch (e.g., dissociation or reassociation). Default isnull.synth_deg_changes(Object, optional): Dictionary indicating changes such as synthesized or degraded molecules. Default isnull.
The generated railroad diagrams visually represent BNGL components using customizable color-coded elements:
const MoleculeColor = 'lightgreen';
const SiteColor = 'lightblue';
const StateColor = 'khaki';- Molecules: Colored rounded-boxes labeled with molecule names.
- Sites: Colored rounded-boxes representing specific binding sites within molecules.
- States: Colored boxes indicating specific states of sites (e.g., ~P, ~Y).
Reaction Changes: Indicators for molecular changes as a result of reactions, including:
const stateChangeUp = "change from bottom state to top state";
const stateChangeDown = "change from top state to bottom state";
const bondAddedNonRev = "nradded";
const bondRemovedNonRev = "nrbroken";
const bondAddedRev = "radded";
const bondRemovedRev = "rbroken";
const bindAndStateChange = "bind_and_state_change";- State changes (transition from one state to another)
- Non-reversible bonds (nradded, nrbroken)
- Reversible bonds (radded, rbroken)
- Combined state and bond changes (bind_and_state_change)
Complex Changes: Indicators for changes between molecules in the same VS separate complex
const NoChangeComplex = "NoChangeComplex";
const NoChangeSeparate = "NoChangeSeparate";
const NonRevChangeComplex = "NonRevChangeComplex";
const NonRevChangeSeparate = "NonRevChangeSeparate";
const RevChangeComplex = "RevChangeComplex";
const RevChangeSeparate = "RevChangeSeparate";- Molecules stay in their original (separate or same) complex (NoChangeComplex, NoChangeSeparate)
- Non-reversible switch between same/separate complex (NonRevChangeComplex, NonRevChangeSeparate)
- Reversible switch between same/separate complex (RevChangeComplex, RevChangeSeparate)
This module is a customized SVG-based renderer that defines layout classes to read the formatted diagram code and draw the related railroad diagram showing molecule and site structure, bond connectivity, binding/unbinding and state transitions, complex changes, and other styling components.
Diagram()
- its arguments are the components of the diagram (e.g., Diagram(Choice(), Terminal())...)
Terminal(text[, {box_color, bottom_bind, bottom_bind_color, bond_num, bond_type, wrap}])
- all the properties in the options bag are optional
box_colorspecifies the color to fill the containerbottom_bindspecifies possible bond connection (e.g, "!?" or "!+")bottom_bind_colorpasses the color of the bond connection (e.g., "gray")bond_numpasses the bond argument (e.g., "?", "+", "4")bond_typespecifies a bond change (e.g., "radded")wrapspecifies if the bond wrap around all states
NonTerminal(text[, {box_color, bottom_bind, bottom_bind_color, bond_num, bond_type, wrap}])
- the optional arguments have the same meaning as for Terminal, except it visualizes as a rectangular box rather than a rounded-rectangle
Skip() - an empty line
Start({type, label}) and End({type}) - the start/end shapes.
- shapes are supplied by default
- all properties are optional
typetakes either "simple" (the default) or"complex"for slightly different start/end shapeslabelprovides a text label before the diagram starts
EndWhiteSpace(changeType, type) - separator between molecules
- all properties are optional
changeTypespecifies a switch between molecules in the same complex or separate complexestypeargument has the same meaning as for Start and End
Sequence(...children) - arranges all arguments on the same horizontal line, one after another
Choice(index, ...children) - arranges arguments on different vertical levels to represent mutually exclusive options. The index specifies the default (middle) choice
MultipleChoice(index, type, arrow, ...children) - it's similar to Choice, but used to show state changes
indexspecifies the default middle choicetypespecifies whether the state changes from a top state to a bottom state or vice versaarrowis either -> or <-> to specify whether the transition is reversible or non-reversible
Group(child, label?) - highlights its child with a dashed outline, and optionally labels it
labelspecifies whether a molecule was synthesized or degraded- "synthesized" labels are shown in green, "degraded" in red
