topo.csp package¶
Submodules¶
topo.csp.core module¶
Core nascent-chain MD machinery (topo.csp.core).
This module holds the per-length / per-stage molecular-dynamics building blocks for protein synthesis — the foundation that the higher-level runners build on. It is a library, not a runner: it exposes no CLI and no outer loop.
Its consumers are:
topo.csp.protocol— the O’Brien Continuous Synthesis Protocol (CSP), which callsrun_length()three times per residue (one per kinetic sub-stage), andthe Tutorial-9 cylinder runner (tutorials/09_translation_cylinder/cylinder.py), which reuses these blocks with the ribosome modelled as an analytic cylinder.
(The standalone fixed-rate elongation runner — run_elongation / the
topo-elongate CLI — and its Tutorial 7 were removed: a fixed per-residue step
count is not a physically meaningful synthesis model. Use CSP (topo-csp) for
codon-resolved kinetics.)
The central primitive is run_length(), which builds, seeds, restrains, runs
and finalizes one length-``L`` segment of nascent-chain MD:
Build the length-
LTOPO model on native residues1..L(bonds, angles, torsions, Yukawa, contacts), injecting the precomputedL x Lcontact subset instead of recomputing (buildCoarseGrainModel(precomputed_contacts=...)).Seed coordinates.
L == L0: lay residues1..L0extended along the tunnel axis (+x) from the P-anchor, one CG bond length apart.L > L0: residues1..L-1from the previous segment’s final structure; the new residueLat the optimal A-site target (one equilibrium peptide bond from residue L-1).Restrain only residue ``L`` (the current C-terminus) to a chosen anchor with a harmonic
CustomExternalForce(k = restraint_k).Minimize, draw Boltzmann velocities at
ref_t, run the requested step count under the per-stage stability guard (seeSTABILITY_POTE_LIMIT_KJ), write the per-segment outputs, and return the final NASCENT coordinates to seed the next segment.
Contacts are precomputed once on the full native PDB (precompute_contacts());
STRIDE / heavy-atom analysis are never re-run per length. The optional rigid ribosome
scenery and tunnel wall are wired up via topo.csp.ribosome. Build / setup /
finalize are reused from topo.engine.
- class topo.csp.core.NascentDCDReporter(file, reportInterval, nascent_topology, n_keep, append=False)[source]¶
Bases:
objectA DCD reporter that writes only the first
n_keepatoms each frame.Used in build step v2 so the (large, static) ribosome beads are not written to the trajectory every frame – only the nascent chain (indices
0..n_keep-1) is saved. Mirrorsopenmm.app.DCDReporterbut slices the positions and uses a fixedn_keep-atom topology, so the DCD header recordsn_keepatoms and pairs with the nascent-only PSF.- describeNextReport(simulation)[source]¶
Tell the simulation when and what this reporter needs next.
- Parameters:
simulation (openmm.app.Simulation) – The running simulation (queried for the current step).
- Returns:
{'steps', 'periodic', 'include'}– steps until the next report, no PBC, positions only.- Return type:
dict
- report(simulation, state)[source]¶
Write one frame of the first
n_keepatoms to the DCD.Lazily creates the underlying
openmm.app.DCDFileon the first call, then writes the sliced (nascent-only) positions.- Parameters:
simulation (openmm.app.Simulation) – The running simulation (supplies the integrator / step info).
state (openmm.State) – The current state (source of the positions).
- Return type:
None
- class topo.csp.core.RunParams(n_steps: int = 1000, dt_ps: float = 0.015, ref_t: float = 310.0, tau_t: float = 0.05, nstout: int = 5000, device: str = 'CPU', ppn: int = 1, constraints: object = 'AllBonds', restraint_k: float = 83680.0, nascent_ev_radii: str = 'kb', minimize: bool = True, trna_tether: bool = True, tunnel_wall: bool = True, tunnel_wall_x0_nm: float | None = None, tunnel_wall_k: float = 8368.0, scale_factor: float = 4331293.0, time_stage_1: float = 0.00034, time_stage_2: float = 0.004201, uniform_codon_time: float | None = None, ribosome_traffic: bool = False, initiation_rate: float = 0.083333, random_seed: int | None = None, max_steps_per_stage: int | None = None, min_steps_per_stage: int = 1, ejection_steps: int = 0, dissociation_steps: int = 0)[source]¶
Bases:
objectAll run parameters, set once from the CLI/INI — the single CSP + elongation parameter block.
Holds both the MD / ribosome knobs consumed by the per-length helpers (
run_length()/build_length_model(): timestep, temperature, rigid ribosome tunnel wall, C-terminus restraint, …) and the O’Brien kinetic knobs consumed by the high-leveltopo.csp.run_continuous_synthesis()(per-codon timing, stage dwell means, post-synthesis phases). This was formerly split acrossElongationParams(MD) andCSPParams(kinetics); the two were merged into this one flat class so there is a single source of truth. The low-level per-length helpers simply ignore the kinetic fields.- constraints: object = 'AllBonds'¶
- device: str = 'CPU'¶
- dissociation_steps: int = 0¶
- dt_ps: float = 0.015¶
- ejection_steps: int = 0¶
- initiation_rate: float = 0.083333¶
- max_steps_per_stage: int | None = None¶
- min_steps_per_stage: int = 1¶
- minimize: bool = True¶
- n_steps: int = 1000¶
- nascent_ev_radii: str = 'kb'¶
- nstout: int = 5000¶
- ppn: int = 1¶
- random_seed: int | None = None¶
- ref_t: float = 310.0¶
- restraint_k: float = 83680.0¶
- ribosome_traffic: bool = False¶
- scale_factor: float = 4331293.0¶
- tau_t: float = 0.05¶
- time_stage_1: float = 0.00034¶
- time_stage_2: float = 0.004201¶
- trna_tether: bool = True¶
- tunnel_wall: bool = True¶
- tunnel_wall_k: float = 8368.0¶
- tunnel_wall_x0_nm: float | None = None¶
- uniform_codon_time: float | None = None¶
- topo.csp.core._dump_topology_psf(cgModel, path: str) None[source]¶
Write a PSF for the (nascent + ribosome) system via parmed.
The model’s own
dumpTopologykeys per-atom mass/charge off its nascent-only lists, so it cannot describe the v2 system. parmed reads masses/bonds straight from the OpenMM topology + System instead (charges default to 0 in the PSF – cosmetic; the real electrostatics live in the Yukawa force).- Parameters:
cgModel (topo.core.system.system) – The built (nascent + ribosome) model providing
.topologyand.system.path (str) – Output PSF path.
- Return type:
None
- topo.csp.core._finalize_nascent(cfg, ctx, nascent_topology, n_keep: int, start_epoch: float) None[source]¶
Finalize a v2 length writing a nascent-only final structure.
Like
topo.engine.finalize_simulation()but the written_final.pdbis only the firstn_keep(nascent) atoms – the rigid ribosome is dropped. The saved checkpoint still holds the full system (needed for a correct restart).- Parameters:
cfg (topo.SimulationConfig) – The per-length config (supplies output paths and the runinfo path).
ctx (topo.engine.SimulationContext) – The active simulation context (simulation, checkpoint, runinfo paths).
nascent_topology (openmm.app.Topology) – The
n_keep-atom nascent-only topology for the written_final.pdb.n_keep (int) – Number of leading (nascent) atoms to keep in the final structure.
start_epoch (float) – Wall-clock start time (
time.time()) for the elapsed-time report.
- Return type:
None
- topo.csp.core._make_cfg(out_dir: Path, sub_pdb: str, seed_pdb: str, params: RunParams) SimulationConfig[source]¶
Build a per-length
SimulationConfigfor the engine helpers.Each length is a self-contained standalone run (its own output folder), so this mirrors a single
topo-mdruninvocation: a constant-temperature production run ofn_stepsatref_t. The contact matrices are injected at build time (not via this config), sodomain_defis left unset here.- Parameters:
out_dir (pathlib.Path) – Output directory for this length’s run.
sub_pdb (str) – Length-
Lnative CA PDB (the model’spdb_file).seed_pdb (str or None) – Seed-coordinate PDB fed via
init_position(v1);Nonein v2 where seed coordinates are set directly onbuilt.positions.params (RunParams) – Shared per-length run parameters (steps, dt, temperature, device, …).
- Returns:
The configured per-length simulation config.
- Return type:
topo.SimulationConfig
- topo.csp.core._ptc_bead_index(ribo, segid: str, resid: int, name: str) int[source]¶
Index of one named ribosome bead in a
Ribosome(or raise).
- topo.csp.core._vprint(*args, **kwargs) None[source]¶
print() only when TOPO_CSP_VERBOSE is set (see
VERBOSE).
- topo.csp.core._write_pdb(topology, positions_nm: ndarray, path: str) None[source]¶
Write a PDB from a topology and an
(N, 3)nm coordinate array.- Parameters:
topology (openmm.app.Topology) – The topology describing the atoms to write.
positions_nm (numpy.ndarray) – An
(N, 3)array of coordinates in nm.path (str) – Output PDB path.
- Return type:
None
- topo.csp.core.add_cterm_restraint(system: System, particle_index: int, anchor_nm: ndarray, k: float) Force[source]¶
Add a harmonic restraint pulling one particle toward a fixed anchor.
U = k * ((x-x0)^2 + (y-y0)^2 + (z-z0)^2)via aCustomExternalForce. Only the current C-terminus (particle_index = L-1) is restrained – to the P-anchor – so the tether hand-off between lengths is automatic (each rebuilt step restrains only its own C-terminus).kis the force constant in OpenMM units (kJ/mol/nm^2).kis a per-particle parameter (not a global) so this force can coexist with otherCustomExternalForces that also call their global constantk– e.g. the tunnel wall (topo.csp.ribosome.add_tunnel_wall()). Two forces sharing a global parameter name with different default values is an OpenMM error; per-particlekavoids the clash (this combination – position restraint + tunnel wall in v2 – is whattopo.cspuses).- Parameters:
system (openmm.System) – The System to add the restraint force to (modified in place).
particle_index (int) – Index of the restrained particle (the current C-terminus,
L-1).anchor_nm (numpy.ndarray) – The fixed anchor position
(x0, y0, z0)in nm (the P-anchor target).k (float) – Harmonic force constant in OpenMM units (kJ/mol/nm^2).
- Returns:
The added
CustomExternalForcerestraint.- Return type:
openmm.Force
- topo.csp.core.build_length_model(sub_pdb: str, R_L: ndarray, eps_L: ndarray, constraints='AllBonds', model: str = 'topo', nascent_rmin_2: ndarray | None = None)[source]¶
Build a length-
LTOPO model, injecting theL x Lcontact subset.This is the dedicated “build-once-subset” path the design anticipates (DESIGN §3.5 / PROMPT notes): it mirrors
topo.models.buildCoarseGrainModel()exactly — reusing the sametopo.core.system.systemmethods for bonds, angles, torsions, Yukawa electrostatics and per-residue mass/charge/radii — but supplies the precomputed contact matrices directly instead of recomputing them (so STRIDE / heavy-atom analysis are not re-run per length). PBC is off and the build-time large-force check is skipped (the simulated coordinates come from the seeding scheme and are minimized explicitly, so the native-structure energy is irrelevant here).- Parameters:
sub_pdb (str) – Length-
Lnative CA structure (bonded terms + per-residue properties).R_L (numpy.ndarray) – The
L x Lcontact well-position (nm) and well-depth (kJ/mol) blocks.eps_L (numpy.ndarray) – The
L x Lcontact well-position (nm) and well-depth (kJ/mol) blocks.constraints (str or None) –
'AllBonds'(rigid, default) orNone(flexible harmonic bonds) – same semantics asbuildCoarseGrainModel().nascent_rmin_2 (numpy.ndarray or None) – Per-residue collision radius Rmin/2 (nm), length
L, for the nascent chain – the structure-derived Karanicolas-Brooks values (Option A). Used as the particle excluded-volume radius (particle_rmin_2). This is deliberately not taken frommodel_parameters(whose fixed per-AA protein Rmin_2 is the rigid ribosome scenery value, not the mobile chain’s).particle_rmin_2only feedsdumpForceFieldData, soNoneis harmless (the radius is left unset).
- Returns:
The built model (
.system,.topology,.positionsready to use).- Return type:
- topo.csp.core.cold_start_positions(L0: int, p_anchor: ndarray) ndarray[source]¶
Extended cold-start layout for the first length
L0(DESIGN §2.5).Residues
1..L0are laid along the tunnel axis (+x) from the P-anchor: the C-terminus (residueL0) sits at the P-anchor and the N-terminus (residue 1) points toward the exit (+x), one CG bond length apart. A small alternating transverse zig-zag (COLD_START_ZIGZAG_NM) breaks the exact collinearity that would make the angle force singular. Returns an(L0, 3)array in nm (rowi= residuei+1).
- topo.csp.core.optimal_ptc_targets(ribo, *, aa_rmin_2_nm: float = 0.5, n_starts: int = 60) Tuple[ndarray, ndarray][source]¶
Optimal A-site / P-site C-terminus restraint target points (nm).
Returns
(a_target, p_target)– two fixed points in space (nm; NOT bonds; the CSP path restrains the C-terminus to a fixed point viaadd_cterm_restraint()) that sit exactly one peptide bond (_PTC_PEPTIDE_NM= 0.381 nm) apart and clear of the ribosome excluded volume. Seeding the new residue ata_targetwhile the previous residue rests atp_targetmakes the always-present peptide bond start at its equilibrium length, so a rigidAllBondsconstraint seeds/minimizes cleanly at 15 fs and the dt-halving stability guard is not triggered (tutorials/14 step 2).The points are found (all in OpenMM units: nm, kJ/mol, rad) by minimizing the soft O’Brien restraint energy – the A/P tRNA bonds (
_PTC_D_A_NM/_PTC_D_P_NM, harmonickb = RESTRAINT_K_KJ) and orienting angles/improper (_PTC_ANGLE_K_KJ;continuous_synthesis_v6.py) – plus the ribosomeeps*(Rmin/r)^12excluded volume (eps = RIBO_NC_EPS_KJ,Rmin_ij = (Rmin/2)_AA + (Rmin/2)_beadsum rule), subject to:the peptide bond as the only hard distance constraint (
_PTC_PEPTIDE_NM= 0.381 nm – it is topo’s AllBonds constraint length, so it must hold exactly);an exit-side inequality keeping each point at
x >= xof its tRNA R bead (between the tRNA and the +x exit port, not buried in the ribosome); andO’Brien’s two excluded-volume exclusions (new AA<->AtR:76@R, prev AA<->PtR:76@R),
over
n_startsdeterministic full-sphere starts. The tRNA bond lengths are soft (finite-k, as in O’Brien’s model), so|A-RA|/|P-RP|come out near 0.427 / 0.476 nm rather than exactly – and the solve stays feasible even on geometries where those distances cannot be met exactly together with the peptide bond.- Parameters:
ribo (Ribosome) – The parsed rigid CG ribosome (supplies the AtR/PtR 76 R/P/BR2 beads, all bead coordinates and the excluded-volume radii).
aa_rmin_2_nm (float, optional) – Nascent-bead Rmin/2 (nm) used in the seed excluded-volume term, combined with the ribosome per-bead Rmin/2 by O’Brien’s SUM rule (R = aa_rmin_2_nm + Rmin/2_ribo). Default 0.5 nm – a deliberately conservative CONSTANT, not the simulation’s per-residue value. In the simulation the nascent chain’s non-native Rmin/2 is set by the Karanicolas-Brooks rule from the native structure, so it is structure-dependent: there is no universal per-residue-type radius to look up when seeding a not-yet-placed residue. 0.5 nm exceeds every amino acid’s Rmin/2 (largest is TRP = 0.382 nm), so seeding against this larger radius places the new residue clear of the ribosome wall for every residue – the peptide bond then starts near its equilibrium length and dt-halving blow-ups are avoided. The seed EV is thus a conservative superset of the simulation EV, not identical to it.
n_starts (int, optional) – Number of deterministic multistart initial orientations (default 60).
- Returns:
a_targetandp_target, each a(3,)coordinate in nm.- Return type:
(numpy.ndarray, numpy.ndarray)
- topo.csp.core.precompute_contacts(full_pdb: str, domain_def: str | None = None, stride_output_file: str | None = None) Tuple[ndarray, ndarray, ndarray][source]¶
Run TOPO’s contact builder once on the full native PDB (DESIGN §3.5).
Returns
(R_full, eps_full, rmin_2_full)– theN_full x N_fullwell-position (nm) and well-depth (kJ/mol) matrices, plus the per-residue Karanicolas-Brooks collision radiusRmin/2(nm, shape(N_full,)) that O’Brien uses as the nascent excluded-volume radius (the structure-derivedA_ivalues). STRIDE is run at most once here (and cached bybuild_nonbonded_interaction()); each length later reuses the top-leftL x Lblock (andrmin_2_full[:L]), so neither STRIDE nor the heavy-atom analysis is ever re-run per length.
- topo.csp.core.read_anchor(pdb_file: str, segid: str, resid: int = 76, bead: str = 'R') ndarray[source]¶
Return the coordinate (nm) of one ribosome bead, e.g. a tRNA anchor.
Parses the (CG) ribosome PDB for the single atom whose segID (columns 73-76), residue number and atom name match
segid/resid/bead. Used to pick the P-anchor (segid='PtR') and A-anchor (segid='AtR') from the truncated ribosome (both keep residue 76 — the truncation retains the tRNA acceptor ends). PDB coordinates are in angstrom; the returned vector is in nm.- Raises:
ValueError – If no matching atom (or more than one) is found.
- topo.csp.core.run_length(L: int, *, full_pdb: str, R_full: ndarray, eps_full: ndarray, p_anchor: ndarray, a_anchor: ndarray, prev_final: ndarray | None, out_root: Path, params: RunParams, ribo: Ribosome | None = None, seed_override: ndarray | None = None, restrain: bool = True, out_subdir: str | None = None, n_steps_override: int | None = None, seed_point: ndarray | None = None, tether_segid: str = 'PtR', tether_prev_segid: str | None = None, nascent_rmin_2: ndarray | None = None, minimize_override: bool | None = None, label: str | None = None) ndarray[source]¶
Build, seed, (restrain,) minimize and run one length-
Lsystem.Used both for an elongation step and for the post-synthesis phase (§post- synthesis below). When
ribois given (build step v2), the rigid ribosome is appended as fixed (mass-0) scenery with the ribosome<->nascent cross-interactions (topo.csp.ribosome.append_ribosome()).Parameters that tailor the standard elongation step into the post-synthesis phase:
seed_override: use these(L, 3)nm nascent coordinates directly (no cold-start / new-residue placement) – e.g. the fully-synthesized structure for an ejection / stall run.restrain: if False, do not add the C-terminus restraint (ejection = the tether is released and the chain is free to move).out_subdir: output folder name underout_root(defaultL_<L>); e.g.ejection/stall.n_steps_override: run this many steps instead ofparams.n_steps.label: short stage tag (e.g."stage 1 peptidyl-transfer") shown in the concise per-stage summary line and, underTOPO_CSP_VERBOSE, in the verbose console banner.
Returns the final nascent
(L, 3)nm coordinate array.
- topo.csp.core.seed_positions(prev_final: ndarray, seed_point: ndarray) ndarray[source]¶
Seed length
Lfrom the previous final structure + the new residue.Residues
1..L-1keep their coordinates from stepL-1’s final structure (prev_final, shape(L-1, 3)nm). The new C-terminal residueLis placed atseed_point– the equilibrium-bond A-site target fromoptimal_ptc_targets()– so the always-present peptide bondL-1<->Lstarts at its equilibrium length and a rigidAllBondsbuild seeds/minimizes cleanly. Returns an(L, 3)array in nm.
- topo.csp.core.write_subset_structure(full_pdb: str, L: int, out_pdb: str) None[source]¶
Write a CA-only PDB of the first
Lresidues offull_pdb.This length-
Lnative structure supplies the bonded terms and per-residue mass/charge/radii for the length-Lbuild; its coordinates set the native contact distances and CG bond lengths only (the simulated coordinates come from the seeding scheme, not from here). Residues are taken in file order so particlei(0..L-1) corresponds to native residuei+1, matching theL x Lcontact subset.- Parameters:
full_pdb (str) – Full native PDB of the target protein.
L (int) – Number of N-terminal residues to keep (the current nascent length).
out_pdb (str) – Path of the CA-only length-
LPDB to write.
- Return type:
None
- Raises:
ValueError – If
full_pdbhas fewer thanLCA atoms.
topo.csp.cylinder module¶
Protein synthesis through an analytic exit tunnel (topo.csp.cylinder).
A parallel of topo.csp.protocol for the cylinder ribosome model. Instead of
explicit rigid CG ribosome beads, the ribosome is a pure boundary condition – an analytic
exit tunnel (a bore of radius r in an otherwise-infinite wall,
add_tunnel_cylinder()). There are no ribosome beads, no tRNA tether, and no A/P
translocation, so each residue is a single MD segment (not the three sub-stages of the
explicit protocol).
Timing is the same O’Brien kinetics as topo.csp.protocol: each residue’s MD
length comes from its codon mean-first-passage time (topo.csp.kinetics), mapped to
integration steps by the scale_factor / dt compression – replacing any fixed
per-residue step count. The C-terminus is held on the tunnel axis at the PTC by a harmonic
position restraint; the bore keeps the in-tunnel segment extended and lets the finished
chain leave only through the exit.
Reused wholesale from topo.csp.core: the per-length MD machinery
(build_length_model, build-once-subset contacts, coordinate seeding, minimize / run /
finalize) and RunParams. New here: the analytic tunnel force, the tunnel geometry
(CylinderParams), and the single-segment kinetic driver.
Drive it with an INI control file (see read_cylinder_config()):
topo-cylinder -f cylinder.ini
python -m topo.csp.cylinder -f cylinder.ini
Units: OpenMM defaults – length nm, time ps, energy kJ/mol, temperature K, force constants kJ/mol/nm^2. In-vivo dwell times in the kinetics are seconds.
- class topo.csp.cylinder.CylinderConfig(pdb_file: str, L0: int, L_max: int | None = None, outdir: str = 'synth_out', mrna: str | None = None, codon_time_table_path: str | None = None, domain_def: str | None = None, stride_output_file: str | None = None, params: CylinderParams | None = None, config_file: str | None = None)[source]¶
Bases:
objectParsed contents of a cylinder synthesis control file (
cylinder.ini).- L0: int¶
- L_max: int | None = None¶
- codon_time_table_path: str | None = None¶
- config_file: str | None = None¶
- domain_def: str | None = None¶
- mrna: str | None = None¶
- outdir: str = 'synth_out'¶
- params: CylinderParams = None¶
- pdb_file: str¶
- stride_output_file: str | None = None¶
- class topo.csp.cylinder.CylinderParams(n_steps: int = 1000, dt_ps: float = 0.015, ref_t: float = 310.0, tau_t: float = 0.05, nstout: int = 5000, device: str = 'CPU', ppn: int = 1, constraints: object = 'AllBonds', restraint_k: float = 83680.0, nascent_ev_radii: str = 'kb', minimize: bool = True, trna_tether: bool = True, tunnel_wall: bool = True, tunnel_wall_x0_nm: float | None = None, tunnel_wall_k: float = 8368.0, scale_factor: float = 4331293.0, time_stage_1: float = 0.00034, time_stage_2: float = 0.004201, uniform_codon_time: float | None = None, ribosome_traffic: bool = False, initiation_rate: float = 0.083333, random_seed: int | None = None, max_steps_per_stage: int | None = None, min_steps_per_stage: int = 1, ejection_steps: int = 0, dissociation_steps: int = 0, tunnel_radius_nm: float = 0.9, tunnel_length_nm: float = 10.0, tunnel_x_lo_nm: float = 0.0, tunnel_center_nm: Tuple[float, float] = (0.0, 0.0), tunnel_k: float = 8368.0, tunnel_mouth_round_nm: float = 0.2)[source]¶
Bases:
RunParamsRunParams(MD + O’Brien kinetics) + the tunnel geometry.Subclasses
topo.csp.core.RunParams, so every MD knob (timestep, temperature, restraint constant, output, …) and every kinetic field (scale_factor,time_stage_1/time_stage_2,uniform_codon_time,max_steps_per_stage, …) is inherited unchanged; only the analytic-tunnel geometry fields are new.- tunnel_center_nm: Tuple[float, float] = (0.0, 0.0)¶
- tunnel_k: float = 8368.0¶
- tunnel_length_nm: float = 10.0¶
- tunnel_mouth_round_nm: float = 0.2¶
- tunnel_radius_nm: float = 0.9¶
- tunnel_x_lo_nm: float = 0.0¶
- topo.csp.cylinder.add_tunnel_cylinder(system, nascent_indices, r_nm: float, x_lo_nm: float, x_exit_nm: float, k: float = 8368.0, y0_nm: float = 0.0, z0_nm: float = 0.0, mouth_round_nm: float = 0.2) Force[source]¶
Add the analytic exit-tunnel restraint (a hole in an infinite wall).
One
CustomExternalForceover every nascent bead penalising the penetration depth into the solid ribosomeS– everything outside the bore up to the exit face, plus the closed PTC end:S = { x < x_exit AND d > r } cup { x < x_lo }, d = |(y,z) - (y0,z0)|
The bead escapes
Svia whichever face is nearer – the bore wall (d - r, a radial inward push that keeps the in-tunnel chain extended) or the exit face (x_exit - x, a +x push so a cytosol bead can only re-enter through the bore, never off-axis). The 90 deg inner corner at the mouth(x_exit, r)is rounded by a fillet of radiusrhoso the potential is continuous (-> stable MD):U = k * max(0, pen)^2 + k * min(0, x - x_lo)^2 pen = (rounded) min( x_exit - x , d - r ) # 0 outside S; > 0 inside S
Returns the added
CustomExternalForce(already insystem).
- topo.csp.cylinder.cylinder(argv: List[str] | None = None) None[source]¶
Console entry point:
topo-cylinder -f cylinder.ini.
- topo.csp.cylinder.read_cylinder_config(config_file: str, verbose: bool = True) CylinderConfig[source]¶
Parse a cylinder synthesis control file (INI) into a
CylinderConfig.Single
[OPTIONS]section. Required:pdb_file,L0,domain_def, and – unlesscodon_timesis a positive number (uniform timing) –mrna. No ribosome PDB (the tunnel geometry comes from the params, not a structure). Recognised keys (optional ones fall back to defaults):pdb_file– full native PDB of the target protein (the nascent chain).L0/L_max– start / final nascent length (blankL_max-> full).outdir– root output directory (per-length subfoldersL_<L>/).domain_def– domain YAML for contactnscale(one-time precompute).stride_output_file– precomputed STRIDE (else STRIDE runs once if on PATH).Kinetics (same as CSP):
mrna(per-codon sequence, orfastest/slowest/medianto auto-build a synonymous-codon mRNA),codon_times(a codon table path for per-codon timing – required, no bundled default; pick one underassets/csp/codon_dwell_times/– or a positive number of seconds for a uniform codon time),scale_factor,time_stage_1,time_stage_2,random_seed,max_steps_per_stage,min_steps_per_stage.Integrator / MD:
dt,ref_t,tau_t,nstout,device,ppn,minimize(yes/no),constraints(‘None’ flexible / ‘AllBonds’ rigid),restraint_k(C-terminus position-restraint constant, kJ/mol/nm^2).Tunnel geometry:
tunnel_radius(nm),tunnel_length(nm),tunnel_x_lo(nm),tunnel_center("y0,z0"nm),tunnel_k(kJ/mol/nm^2),tunnel_mouth_round(nm).Post-synthesis (same keys as CSP):
ejection_stepsanddissociation_steps– two sequential free runs at full length (each releases the C-terminus restraint so the finished protein diffuses out the exit and folds in the cytosol; 0 = skip that phase).
Inline
#/;comments are ignored. Units: OpenMM defaults.
- topo.csp.cylinder.run_cylinder_synthesis(full_pdb: str, *, L0: int = 1, L_max: int | None = None, out_root: str = 'synth_out', mrna: str | None = None, codon_time_table_path: str | None = None, domain_def: str | None = None, stride_output_file: str | None = None, params: CylinderParams | None = None) None[source]¶
Synthesize
L = L0 .. L_maxthrough the analytic tunnel, one segment per residue.Mirrors
topo.csp.protocol.run_continuous_synthesis(), but with the cylinder confinement and a single MD segment per residue (no A/P sub-stages). Each residue’s segment length is its codon dwell time mapped to integration steps – the same O’Brien kinetics (topo.csp.kinetics) the explicit protocol uses, just not split three ways. Writes per-length trajectories underout_root/L_<L>/and a per-residuedwell_times.dattable.- Parameters:
full_pdb (str) – Full native PDB of the target protein (the nascent chain at full length).
L0 (int) – First / final nascent length (
L_max=None-> the full residue count).L_max (int) – First / final nascent length (
L_max=None-> the full residue count).out_root (str) – Root output directory; each length writes to
<out_root>/L_<L>/.mrna (str, optional) – mRNA sequence file (one codon per residue) for the codon-resolved kinetics. Required for per-codon timing (i.e. unless
params.uniform_codon_timeis set).codon_time_table_path (str) – Per-codon mean-time table (required for per-codon timing; pick one under
assets/csp/codon_dwell_times/). There is no bundled default.domain_def (str, optional) – Passed to the one-time contact precompute (nscale / STRIDE).
stride_output_file (str, optional) – Passed to the one-time contact precompute (nscale / STRIDE).
params (CylinderParams, optional) – Per-length run parameters + tunnel geometry (defaults to the dataclass defaults).
- Raises:
ValueError – If the length schedule is invalid (
1 <= L0 <= L_max <= N_fullfails), or if non-uniform kinetics are requested withoutmrna(propagated fromtopo.csp.kinetics.build_codon_time_lists()).
- topo.csp.cylinder.run_length(L: int, *, full_pdb: str, R_full: ndarray, eps_full: ndarray, prev_final: ndarray | None, out_root: Path, params: CylinderParams, cterm_seed: ndarray, x_lo: float, x_exit: float, seed_override: ndarray | None = None, restrain: bool = True, out_subdir: str | None = None, n_steps_override: int | None = None, label: str | None = None) ndarray[source]¶
Build, seed, (restrain,) minimize and run one length-
Lnascent System.The System is the nascent chain only (no ribosome beads); the analytic tunnel (
add_tunnel_cylinder()) supplies all ribosome confinement. Injects theL x Lbuild-once-subset contact block exactly as the shipped runner does.The same routine drives both an elongation step and the post-synthesis phases (ejection / dissociation); these arguments tailor it to the latter:
seed_override: use these(L, 3)nm coordinates directly (the fully synthesized structure) instead of cold-start / new-residue placement.restrain: if False, drop the C-terminus restraint (ejection/dissociation – the finished protein is released and free to diffuse out the exit).out_subdir: output folder underout_root(defaultL_<L>); e.g.ejection/dissociation.n_steps_override: run this many steps instead ofparams.n_steps(the kinetic driver passes the per-residue codon-dwell step count here).label: console-banner text.
Returns the final nascent
(L, 3)nm coordinate array (seeds length L+1).
topo.csp.kinetics module¶
O’Brien continuous-synthesis kinetics: codon timing and the 3-stage schedule.
This is the timing core of the O’Brien Continuous Synthesis Protocol
(continuous_synthesis_v6.py), ported to topo as pure, side-effect-free helpers
(no OpenMM here – just the maths). It answers one question for every residue: how
many integration steps does each of the three elongation sub-stages run for?
The pieces (all of them straight out of v6):
Per-codon translation times. The mRNA is split into codons; a codon-time table maps each codon to its mean in-vivo translation time (seconds). That gives a per-residue intrinsic mean first-passage time list (
codon_time_list()).The 3-stage split. For residue
Lthe total dwell time is partitioned into peptidyl transfer (stage 1), translocation (stage 2) and tRNA binding/waiting (stage 3 = remainder). Each stage’s dwell is drawn from an exponential distribution about its mean (sample_fpt(),stage_dwell_times()) – O’Brien’s first-passage-time sampling.Time -> steps. A dwell time in seconds is mapped to in-silico nanoseconds via
scale_factorand then to integration steps via the time step (seconds_to_steps()):steps = t_s * 1e9 / scale_factor / dt_ns.
(An optional per-codon ribosome-traffic correction exists in the code but is
off by default and deferred – not exposed in the docs or example configs; see
review/TODO.md (§B). With it off, real == intrinsic and stage 2’s mean is exactly
time_stage_2.)
Indexing convention (mirrors v6 exactly): the codon/mFPT lists are 0-indexed,
mfpt[i] = time of the i-th codon (the codon that makes residue i+1… see
stage_dwell_times() for how the 1-indexed nascent length L reads
mfpt[L] / mfpt[L-1]). The mRNA carries N+1 codons (one per residue plus a
stop), so mfpt[L] is always in range for L = 1..N.
Units: times are seconds (in-vivo) until seconds_to_steps(); the time
step is picoseconds; scale_factor is dimensionless.
- topo.csp.kinetics.build_codon_time_lists(n_codons_needed: int, *, uniform_codon_time: float | None, mrna_path: str | None, codon_time_table_path: str | None, ribosome_traffic: bool, initiation_rate: float, verbose: bool = True) Tuple[List[float], List[float], List[str] | None][source]¶
Assemble the
(intrinsic, real, codons)lists for a run.uniform_codon_timeset (uniform timing): every codon gets that mean time (no mRNA needed);real == intrinsicandcodonsisNone.uniform_codon_timeisNone(per-codon timing): read the mRNA +codon_time_table_path, build the intrinsic per-codon list; ifribosome_trafficand the external binary is available, replacerealwith its traffic-corrected output, elsereal == intrinsic. Per-codon timing requires both the (protein-specific)mrnaand an explicitcodon_time_table_path– there is no bundled default table (choose one underassets/csp/codon_dwell_times/).
n_codons_neededis the minimum list length required (L_max + 1so thatintrinsic[L_max]is valid).- Parameters:
n_codons_needed (int) – Minimum required list length (use
L_max + 1).uniform_codon_time (float or None) – If a float, uniform timing – ignore the mRNA and give every codon that mean time (seconds). If
None, per-codon timing from the mRNA + table.mrna_path (str or None) – Path to the mRNA file (required for per-codon timing).
codon_time_table_path (str or None) – Path to the codon-time table (required for per-codon timing; there is no bundled default).
ribosome_traffic (bool) – If True, attempt the external
ribosome_trafficcorrection forreal(falls back toreal == intrinsicif the binary is unavailable).initiation_rate (float) – Translation-initiation rate (1/s), passed to the traffic binary.
verbose (bool, optional) – Forwarded to
ribosome_traffic_times()for its diagnostic messages.
- Returns:
(intrinsic, real, codons)– the intrinsic and (traffic-corrected) real per-codon mFPT lists (seconds), and the codon list (orNonein the uniform-timing mode).- Return type:
tuple
- Raises:
ValueError – If per-codon timing is requested without
mrna_pathor withoutcodon_time_table_path, or if the mRNA / traffic output has fewer thann_codons_neededentries.
- topo.csp.kinetics.codon_time_list(codons: Sequence[str], codon_time_table: Dict[str, float]) List[float][source]¶
Map a codon list to a 0-indexed list of per-codon mean times (seconds).
time[i] = codon_time_table[codons[i]]– i.e. the per-codon intrinsic mean translation time (the intrinsic mean first-passage time; no ribosome-traffic correction). Raises if a codon is missing from the table, so an incomplete table is caught early rather than silently mis-timing a residue.- Parameters:
codons (sequence of str) – Codons (upper-case RNA), e.g. the output of
read_mrna().codon_time_table (dict of {str: float}) – Codon -> mean translation time (seconds), e.g. from
read_codon_time_table().
- Returns:
The intrinsic mean per-codon time (seconds) for each codon, in the same order as
codons.- Return type:
list of float
- Raises:
KeyError – If any codon in
codonsis absent fromcodon_time_table.
- topo.csp.kinetics.parse_codon_times(value: str | None) Tuple[float | None, str | None][source]¶
Resolve the
codon_timesconfig value into a timing mode.codon_timesoverloads a single INI key onto the two timing modes:a positive number of seconds (e.g.
0.05) -> uniform timing: every codon gets that mean dwell (no mRNA needed);anything else -> a path to a per-codon time table, so timing is per-codon from the mRNA;
None(key absent/blank) -> unset: neither timing mode is chosen. There is no bundled default table, so per-codon timing then requires an explicit table path (seebuild_codon_time_lists(), which raises otherwise).
A codon-time table filename must therefore not be a bare number – a value that parses as a float is always taken as a uniform time in seconds, never a filename. (Give the table a name like
trans_times.txtor./12345.txt.)- Parameters:
value (str or None) – The raw
codon_timesvalue from the INI (already stripped, orNone).- Returns:
(uniform_codon_time, table_path)– exactly one is non-Nonein the two “set” cases: a float (uniform mean codon time, seconds) withtable_pathNone, or a path withuniform_codon_timeNone. A blank/absent value returns(None, None)(neither mode chosen). Ready to fillRunParams.uniform_codon_timeand thecodon_time_table_pathpath.- Return type:
tuple
- Raises:
ValueError – If
valueis numeric but not a positive, finite time in seconds.
- topo.csp.kinetics.read_codon_time_table(path: str) Dict[str, float][source]¶
Read a per-codon mean-translation-time table into
{codon: seconds}.Format (the codon-time table file, e.g. the Fluitt E. coli
trans_times.txt): one codon per line,CODON<whitespace>TIME– the codon is RNA (UnotT), the time is the mean in-vivo translation time in seconds (e.g.UUU 0.068164). Blank lines and#comments are ignored. Codons are upper-cased andTis normalised toUso a DNA-style table still works.- Parameters:
path (str) – Path to the codon-time table file (e.g.
trans_times.txt).- Returns:
dict of {str – Mapping
codon -> mean in-vivo translation time (seconds). Keys are upper-case RNA codons (Tnormalised toU).- Return type:
float}
- Raises:
ValueError – If a non-comment line cannot be parsed as
CODON TIME, or if the file contains no codon/time rows at all.
- topo.csp.kinetics.read_mrna(path: str, stop_at_stop: bool = True) List[str][source]¶
Read an mRNA sequence file and split it into a list of 3-nt codons.
The file is raw nucleotides (
A/U/G/C;Tnormalised toU), optionally wrapped across several lines (whitespace is stripped and concatenated). The sequence length must be a multiple of 3. Ifstop_at_stopthe list is truncated at (and including) the first stop codon – matching v6, which expectslen(codons) == n_residues + 1(one codon per residue plus the terminator).- Parameters:
path (str) – Path to the mRNA sequence file (raw nucleotides, blank/
#lines ignored).stop_at_stop (bool, optional) – If True (default), truncate the codon list at and including the first stop codon (
UAA/UAG/UGA). If False, return every codon in the file.
- Returns:
Codons in 5’->3’ order, each a 3-character upper-case RNA string.
- Return type:
list of str
- Raises:
ValueError – If the concatenated sequence length is not a multiple of 3.
- topo.csp.kinetics.ribosome_traffic_times(mrna_path: str, codon_time_table_path: str, initiation_rate: float, binary: str = 'ribosome_traffic', verbose: bool = True) List[float] | None[source]¶
Return per-codon real mFPTs from O’Brien’s
ribosome_trafficbinary.The binary models upstream-queue (traffic) effects: given the mRNA, the intrinsic per-codon times and the initiation rate it prints one traffic-corrected mean first-passage time per codon. We capture that into a list. If the binary is not on ``PATH`` (or fails to run) this returns ``None`` (the caller then falls back to
real == intrinsic– no traffic), so the port stays runnable without the compiled helper. This mirrors v6’sribosome_traffic <mrna> <codon_time_table_path> <initiation_rate>call.- Parameters:
mrna_path (str) – Path to the mRNA sequence file (passed through to the binary).
codon_time_table_path (str) – Path to the codon-time table (passed through to the binary).
initiation_rate (float) – Translation-initiation rate (1/s) – sets how densely ribosomes load.
binary (str, optional) – Name (or path) of the external executable to call (default
"ribosome_traffic"); resolved onPATHviashutil.which().verbose (bool, optional) – If True (default), print a message when the binary is missing/fails or produces no numeric output.
- Returns:
One traffic-corrected mean first-passage time (seconds) per codon, or
Noneif the binary is unavailable, errors out, or yields no numbers (signalling the caller to usereal == intrinsic).- Return type:
list of float or None
- topo.csp.kinetics.sample_fpt(mean_s: float, rng: Random) float[source]¶
Draw one first-passage time (seconds) from an exponential of mean
mean_s.This is v6’s
sample_fpt_dist(random.expovariate(1/mean)). A single rate-limiting molecular event has an exponentially distributed waiting time, so each sub-stage dwell is sampled this way. A non-positive mean would be ill-defined, so it is floored to1e-12s first.- Parameters:
mean_s (float) – Mean of the exponential distribution (seconds); floored to
1e-12if non-positive.rng (random.Random) – Random generator to draw from (seed it for reproducible schedules).
- Returns:
A single exponentially distributed dwell time (seconds).
- Return type:
float
- topo.csp.kinetics.seconds_to_steps(t_s: float, scale_factor: float, dt_ps: float) int[source]¶
Map an in-vivo dwell time (s) to a number of integration steps.
O’Brien’s two-step conversion:
t_sim_ns = t_s * 1e9 / scale_factor(thescale_factorcompresses real time into the in-silico timescale), thensteps = t_sim_ns / dt_nswithdt_ns = dt_ps * 1e-3. Truncated to an int (like v6’sint(...)). A largerscale_factortherefore yields fewer steps (a faster run) for the same physical dwell time.- Parameters:
t_s (float) – In-vivo dwell time to convert (seconds).
scale_factor (float) – In-vivo-seconds -> in-silico-nanoseconds compression factor (dimensionless).
dt_ps (float) – Integration timestep (picoseconds).
- Returns:
Number of integration steps (truncated toward zero); may be 0 for very short dwell times before any min/max clamp is applied.
- Return type:
int
- topo.csp.kinetics.stage_dwell_times(L: int, intrinsic: Sequence[float], real: Sequence[float], time_stage_1: float, time_stage_2: float, rng: Random) Tuple[float, float, float][source]¶
Sample the three sub-stage dwell times (seconds) for nascent length
L.Reproduces the stage-time logic of
continuous_synthesis_v6.py(lines 69-86).Lis the 1-indexed nascent chain length;intrinsic/realare 0-indexed per-codon mFPT lists (see module docstring). The three means are:stage 1 (peptidyl transfer):
time_stage_1– a fixed mean.stage 2 (translocation):
time_stage_2plus the ribosome-traffic correctionreal[L-1] - intrinsic[L-1]if that is positive (else justtime_stage_2– v6’s guard against a negative correction from sampling noise).stage 3 (tRNA binding / waiting): the remainder
intrinsic[L] - time_stage_1 - time_stage_2– floored to a tiny positive value if a fast codon makes it non-positive.
Each mean is then passed through
sample_fpt()(exponential sampling).- Parameters:
L (int) – 1-indexed nascent-chain length being synthesized.
intrinsic (sequence of float) – 0-indexed per-codon intrinsic mFPTs (seconds);
intrinsic[L](the next codon) sets the stage-3 total. Must have length >=L + 1.real (sequence of float) – 0-indexed per-codon mFPTs with the ribosome-traffic correction (equals
intrinsicwhen traffic is off). Used only viareal[L-1].time_stage_1 (float) – Fixed mean peptidyl-transfer dwell (seconds).
time_stage_2 (float) – Fixed mean translocation dwell (seconds), before any traffic correction.
rng (random.Random) – Random generator for the exponential sampling.
- Returns:
The three sampled dwell times
(t1, t2, t3)in seconds, for the peptidyl-transfer, translocation and tRNA-binding sub-stages respectively.- Return type:
tuple of (float, float, float)
- topo.csp.kinetics.stage_steps(L: int, intrinsic: Sequence[float], real: Sequence[float], *, time_stage_1: float, time_stage_2: float, scale_factor: float, dt_ps: float, rng: Random, max_steps_per_stage: int | None = None, min_steps_per_stage: int = 1) Tuple[Tuple[int, int, int], Tuple[float, float, float]][source]¶
Full per-residue schedule: sampled dwell times and clamped step counts.
Combines
stage_dwell_times()+seconds_to_steps()and applies the test clamps.max_steps_per_stagecaps each stage (the tutorial uses a small cap so a residue runs ~2000 steps total instead of the production ~10^5-10^6);min_steps_per_stagefloors it so every stage does at least a little MD.Nonecap = uncapped (production). The clamp limits MD steps only, never the sampled dwell times in seconds (which are returned unclamped for logging).- Parameters:
L (int) – 1-indexed nascent-chain length being synthesized.
intrinsic (sequence of float) – 0-indexed per-codon mFPT lists (intrinsic and traffic-corrected); see
stage_dwell_times().real (sequence of float) – 0-indexed per-codon mFPT lists (intrinsic and traffic-corrected); see
stage_dwell_times().time_stage_1 (float) – Fixed mean peptidyl-transfer / translocation dwell times (seconds).
time_stage_2 (float) – Fixed mean peptidyl-transfer / translocation dwell times (seconds).
scale_factor (float) – In-vivo-seconds -> in-silico-nanoseconds compression factor.
dt_ps (float) – Integration timestep (picoseconds).
rng (random.Random) – Random generator for the exponential dwell-time sampling.
max_steps_per_stage (int or None, optional) – Upper clamp on each stage’s step count (
None= uncapped / production).min_steps_per_stage (int, optional) – Lower clamp on each stage’s step count (default 1).
- Returns:
((s1, s2, s3), (t1, t2, t3))– the clamped integer step counts and the (unclamped) sampled dwell times in seconds they were derived from.- Return type:
tuple
- topo.csp.kinetics.uniform_codon_time_list(n: int, uniform_codon_time: float) List[float][source]¶
A constant mean-first-passage-time list of length
n(uniform timing).Every codon gets the same mean translation time
uniform_codon_time(seconds); used for uniform timing (codon_timesset to a number).- Parameters:
n (int) – Length of the list to build (number of codons needed).
uniform_codon_time (float) – The single mean translation time (seconds) assigned to every codon.
- Returns:
A list of
nidentical values, all equal touniform_codon_time.- Return type:
list of float
- Raises:
ValueError – If
uniform_codon_time <= 0.
topo.csp.movie module¶
Stitch nascent-chain synthesis trajectories into one VMD-playable movie.
A synthesis run writes a separate trajectory per growth step, and each step has
a different number of beads (length L has L CA atoms), so a single VMD
molecule (which needs a constant atom count) cannot just concatenate them. This
module pads every frame up to the final length – parking the not-yet-synthesized
beads at a far sentinel coordinate – and writes the segments back-to-back into one
fixed-width movie plus a ready-to-run movie.tcl that hides the parked beads, so
the chain appears to grow N->C.
It handles two output layouts with a shared stitching core
(stitch_segments()):
CSP (per-stage) –
<out>/L_<L>/stage_<1,2,3>/from the Continuous Synthesis Protocol (topo.csp.protocol), plusejection//dissociation/. Usestitch_movie()/find_stage_segments(). The movie plays the chain growing stage by stage (new residue at the A-site, settle, translocate to P).Flat (per-length) –
<out>/L_<L>/traj.dcdfrom a fixed-rate per-length loop (e.g. the Tutorial-9 cylinder runner), plusejection//dissociation/. Usestitch_length_movie()/find_lengths().
The main() CLI (topo-csp-movie) auto-detects the layout (per-stage if any
L_<L>/stage_<s>/ folders exist, else per-length).
Usage:
topo-csp-movie -o synth_out --ribosome ribosome_trunc.pdb
python -m topo.csp.movie -o synth_out
vmd -e synth_out/movie.tcl
- topo.csp.movie._is_csp_layout(out_root: str) bool[source]¶
Return True if
out_roothas the CSP per-stage layout.- Parameters:
out_root (str) – Output root to inspect.
- Returns:
True if any
<out_root>/L_<L>/stage_<s>/folder exists (CSP), else False (treat as the flat per-length layout).- Return type:
bool
- topo.csp.movie._pick_traj(phase_dir: str, outname: str = 'traj') str | None[source]¶
Pick the trajectory file to read for one stage/phase, or
Noneif absent.Prefer
<outname>.dcdwhen it actually holds frames, but a coarsenstout(relative to the steps run per stage) can leave a stage’s DCD empty (0 bytes) – every frame interval landed past the end of the short run. In that case fall back to<outname>_final.pdb, the last-frame snapshot the runner always writes, so the stage still contributes its (single) final conformation instead of being silently dropped. Without this, a coarse-output CSP run yields a movie that skips most lengths.- Parameters:
phase_dir (str) – Directory of a single stage or post-synthesis phase (e.g.
<out_root>/L_<L>/stage_<s>or<out_root>/ejection).outname (str, optional) – Per-stage output basename used by the runner (default
"traj"); the candidate files are<outname>.dcdand<outname>_final.pdb.
- Returns:
Path to
<outname>.dcdif it exists and is non-empty, else<outname>_final.pdbif present, else the empty<outname>.dcdif it exists, elseNonewhen no trajectory file is found.- Return type:
str or None
- topo.csp.movie._write_tcl(path: str, psf_name: str, dcd_name: str, park: str, ribosome_name: str | None = None) None[source]¶
Write a VMD script that loads the movie and grows the chain N->C.
- Parameters:
path (str) – Destination path for the generated
.tclscript.psf_name (str) – Basename of the movie topology file the script should load.
dcd_name (str) – Basename of the movie trajectory file the script should load.
park ({'sentinel', 'cterm'}) – Parking scheme used when stitching;
sentineladds a per-frame selection that hides the far-parked future beads,ctermshows all beads (no hiding needed).ribosome_name (str, optional) – Basename of a static ribosome PDB to load as a separate scenery molecule;
Noneto omit the ribosome block.
- Return type:
None
- topo.csp.movie.find_lengths(out_root: str, outname: str = 'traj') List[Tuple[int, str, str]][source]¶
Return
[(L, psf, dcd), ...]for each<out_root>/L_<L>/length.Scans
<out_root>forL_<L>/length folders, sorted byL; only lengths with both a.psfand a.dcdare kept. This is the flat per-length layout (one trajectory per length, e.g. the Tutorial-9 cylinder runner), in contrast to the CSP per-stage layout (find_stage_segments()).- Parameters:
out_root (str) – The run’s output root (contains the
L_<L>/folders).outname (str) – Per-length output basename used by the runner (default
traj); the files looked for are<outname>.psfand<outname>.dcd.
- Returns:
One
(L, psf, dcd)per length found, sorted by ascendingL;psfanddcdare the paths to that length’s topology and trajectory.- Return type:
list of tuple of (int, str, str)
- topo.csp.movie.find_post(out_root: str, outname: str = 'traj') List[Tuple[str, str, str]][source]¶
Return
[(name, psf, dcd), ...]for present post-synthesis phases (flat).Looks for
<out_root>/ejection/and<out_root>/dissociation/(in that order) – the optional post-synthesis runs written after the chain reaches its final length in the flat per-length layout. Only phases with both a.psfand a.dcdare returned.- Parameters:
out_root (str) – The run’s output root (may contain the
ejection/and/ordissociation/folders).outname (str) – Per-length output basename used by the runner (default
traj); the files looked for are<outname>.psfand<outname>.dcd.
- Returns:
One
(name, psf, dcd)per present post-synthesis phase, inPOST_PHASES_FLATorder.- Return type:
list of tuple of (str, str, str)
- topo.csp.movie.find_stage_segments(out_root: str, outname: str = 'traj') List[Tuple[str, int, str, str]][source]¶
Return ordered
[(label, n_atoms, psf, traj), ...]for a CSP run.Walks
<out_root>/L_<L>/stage_<1,2,3>/in increasingLthen stage order (only stages with a.psfand a readable trajectory are kept), then appends anyejection//dissociation/phase.n_atomsisLfor a stage of lengthL(the nascent-only output) and the post-phase psf’s atom count for the post phases. The trajectory is the stage’s.dcdwhen it has frames, else its_final.pdbsnapshot (see_pick_traj()).- Parameters:
out_root (str) – CSP run output root, containing the
L_<L>/length folders and anyejection//dissociation/post-synthesis phases.outname (str, optional) – Per-stage output basename used by the runner (default
"traj"); the per-stage psf is<outname>.psfand the trajectory is chosen by_pick_traj().
- Returns:
Segments in synthesis order, each
(label, n_atoms, psf, traj):labelis"L=<L> s<s>"for a stage or the phase name for a post phase;n_atomsis the nascent bead count (Lfor a stage, the psf’s atom count for a post phase);psfandtrajare the topology and trajectory paths. Stages or phases lacking a.psfor a readable trajectory are skipped.- Return type:
list of tuple of (str, int, str, str)
- topo.csp.movie.main(argv: List[str] | None = None) None[source]¶
Command-line entry point for
topo-csp-movie/python -m topo.csp.movie.Parses arguments and stitches the synthesis trajectories under
--out-rootinto one VMD-playable movie, auto-detecting the layout: the per-stage CSP layout (stitch_movie()) if anyL_<L>/stage_<s>/folders are present, otherwise the flat per-length layout (stitch_length_movie()). The parser exposes-o/--out-root(required),--prefix,--park(sentinel/cterm),--outnameand--ribosome. With no arguments it prints help and exits0.- Parameters:
argv (list of str or None, optional) – Argument vector to parse. If
None(default), arguments are taken fromsys.argv.- Return type:
None
- topo.csp.movie.stitch_length_movie(out_root: str, out_prefix: str = 'movie', park: str = 'sentinel', outname: str = 'traj', ribosome_pdb: str | None = None, verbose: bool = True) Tuple[str, str, str][source]¶
Discover the flat per-length segments and stitch them into a movie.
The flat-layout counterpart of
stitch_movie(): enumerates<out_root>/L_<L>/per-length trajectories (find_lengths()), appends anyejection//dissociation/phase (find_post()), and hands them to the sharedstitch_segments()core. Used by the Tutorial-9 cylinder runner.- Parameters:
out_root (str) – The run’s output root (contains the
L_<L>/folders).out_prefix (str) – Basename for the movie files (default
movie).park ({'sentinel', 'cterm'}) – Where to put not-yet-synthesized beads in each frame (passed through to the stitching core).
outname (str) – Per-length output basename used by the runner (default
traj).ribosome_pdb (str, optional) – Optional CG ribosome PDB to load as static scenery in the generated
.tcl(defaultNone).verbose (bool) – When true, let the stitching core report progress.
- Returns:
The
(psf_path, dcd_path, tcl_path)of the written movie files.- Return type:
tuple of (str, str, str)
- Raises:
SystemExit – If no per-length trajectories are found under
out_root.
- topo.csp.movie.stitch_movie(out_root: str, out_prefix: str = 'movie', park: str = 'sentinel', outname: str = 'traj', ribosome_pdb: str | None = None, verbose: bool = True) Tuple[str, str, str][source]¶
Discover the CSP per-stage segments and stitch them into a movie.
Thin CSP-aware wrapper around
stitch_segments()(the shared core). Callsfind_stage_segments()to enumerate the per-stage and post-synthesis segments, then hands them to the shared padding/stitching core, which writes<out_prefix>.psf/<out_prefix>.dcd/<out_prefix>.tcl.- Parameters:
out_root (str) – CSP run output root (contains the
L_<L>/stage_<s>/folders).out_prefix (str, optional) – Basename for the stitched movie files (default
"movie").park (str, optional) – Where to put not-yet-synthesized beads in each frame (default
"sentinel"); passed through to the stitching core.outname (str, optional) – Per-stage output basename used by the runner (default
"traj").ribosome_pdb (str or None, optional) – Optional coarse-grained ribosome PDB to load as static scenery in the generated
<out_prefix>.tcl(defaultNone).verbose (bool, optional) – If
True(default), print the number of discovered segments and let the stitching core report progress.
- Returns:
Paths to the written
psf,dcdandtclmovie files, as returned bystitch_segments().- Return type:
tuple of (str, str, str)
- Raises:
SystemExit – If no per-stage trajectories are found under
out_root.
- topo.csp.movie.stitch_segments(out_root: str, segments: List[Tuple[str, int, str, str]], out_prefix: str = 'movie', park: str = 'sentinel', ribosome_pdb: str | None = None, verbose: bool = True) Tuple[str, str, str][source]¶
Pad and concatenate an ordered list of trajectory
segmentsinto a movie.The reusable core shared by the per-stage CSP movie (
stitch_movie()) and the per-length flat movie (stitch_length_movie()).segmentsis an ordered list of(label, n_atoms, psf, dcd)– each a standalone trajectory withn_atomsbeads; every frame is padded up to the widest segment (N= maxn_atoms) by parking the extra (not-yet-synthesized) beads, and the segments are written back-to-back in the given order. Also writes a ready-to-run<out_prefix>.tcl.- Parameters:
out_root (str) – Directory the stitched movie files are written into.
segments (list of tuple of (str, int, str, str)) – Ordered playback segments, each
(label, n_atoms, psf, dcd): a human label, the segment’s bead count, and its topology and trajectory paths.out_prefix (str) – Basename for the movie files (default
movie).park ({'sentinel', 'cterm'}) – Where to put not-yet-synthesized beads in each frame.
sentinel(far away, hidden by the VMD script – cleanest) orcterm(stacked on the C-terminus – no VMD selection needed, but leaves a small bead cluster at the growing tip).ribosome_pdb (str, optional) – Path to a static CG ribosome PDB to copy next to the movie and load as fixed scenery in the generated
.tcl;Noneto skip.verbose (bool) – When true, print progress messages while stitching.
- Returns:
The
(psf_path, dcd_path, tcl_path)of the written movie files.- Return type:
tuple of (str, str, str)
- Raises:
ValueError – If
parkis not'sentinel'or'cterm'.SystemExit – If
segmentsis empty.
topo.csp.protocol module¶
Continuous Synthesis Protocol (O’Brien), ported to topo (topo.csp).
This is the full O’Brien continuous-synthesis protocol – the per-codon, 3-stage
elongation cycle of continuous_synthesis_v6.py – expressed in topo style. It is
the kinetic upgrade of topo.csp.core: that driver grows the chain
one residue per step at a fixed n_steps (collapsing the elongation cycle into a
single MD segment); this driver times every residue from its codon and splits it
into three sub-stages, exactly as O’Brien do.
What is reused vs. new:
Reused wholesale from
topo.csp.core: the per-length MD machinery –run_length()(build-once-subset contacts, coordinate seeding, rigid-ribosome scenery, tunnel wall, minimize/run/finalize),read_anchor(),precompute_contacts(), andRunParamsfor all the MD/ribosome knobs. Nothing about the force field or the OpenMM plumbing is re-implemented here.New (this module): the O’Brien kinetics (
topo.csp.kinetics) and the outer loop that callsrun_length()three times per residue, switching the C-terminus restraint target A->P to reproduce translocation.
The 3-stage mapping onto run_length() (L = nascent length):
stage |
biology |
restraint target / seed |
|---|---|---|
1 |
peptidyl transfer / A-site delivery |
A-anchor; new residue placed |
2 |
translocation begins |
A-anchor; continue stage 1 |
3 |
translocation to P-site / wait |
P-anchor; continue stage 2 |
Stage 3’s final structure seeds the next residue’s stage 1. The cold-start segment
(L == L0) is laid down the tunnel from the P-anchor (no A-site delivery yet).
Because CSP needs the restraint target to switch A<->P, it drives the position
restraint path (trna_tether is forced off); the supplied ribosome is always
rigid scenery and the tunnel wall + excluded volume + electrostatics are on.
Drive it with an INI control file (see read_csp_config()):
topo-csp -f csp.ini
python -m topo.csp -f csp.ini
Units: OpenMM defaults – length nm, time ps, energy kJ/mol, temperature K, force constants kJ/mol/nm^2. In-vivo dwell times in the kinetics are seconds.
- class topo.csp.protocol.CSPConfig(pdb_file: str, ribosome: str, L0: int = 1, L_max: int | None = None, outdir: str = 'synth_out', mrna: str | None = None, codon_time_table_path: str | None = None, domain_def: str | None = None, stride_output_file: str | None = None, params: ~topo.csp.core.RunParams = <factory>, config_file: str | None = None)[source]¶
Bases:
objectParsed contents of a CSP control file (
csp.ini).Bundles the run inputs (structures, the
L0..L_maxschedule, output directory, one-time-precompute options) with the kinetic + MDRunParams. Produced byread_csp_config()and consumed bycsp()/ passed straight torun_continuous_synthesis().- Variables:
pdb_file (str) – Full native PDB of the target protein (the nascent chain at full length).
ribosome (str) – Truncated CG ribosome PDB (P-/A-anchors; always rigid scenery).
L0 (int) – Starting nascent-chain length (default
1).L_max (int or None) – Final length (
None-> the full residue count).outdir (str) – Root output directory (default
"synth_out").codon_time_table_path (mrna,) – mRNA sequence file and per-codon time table (required for per-codon timing, i.e. unless
params.uniform_codon_timeis set).domain_def (str) – Domain-definition file (contact-nscale scaling); required via the INI.
stride_output_file (str or None) – Precomputed STRIDE file for the one-time contact build (optional).
params (RunParams) – The kinetic + MD/ribosome run parameters.
config_file (str or None) – Path of the INI file this config was parsed from (provenance).
- L0: int = 1¶
- L_max: int | None = None¶
- codon_time_table_path: str | None = None¶
- config_file: str | None = None¶
- domain_def: str | None = None¶
- mrna: str | None = None¶
- outdir: str = 'synth_out'¶
- pdb_file: str¶
- ribosome: str¶
- stride_output_file: str | None = None¶
- topo.csp.protocol.csp(argv: List[str] | None = None) None[source]¶
Console entry point:
topo-csp -f csp.ini.The O’Brien continuous synthesis protocol (per-codon, 3-stage elongation), driven by an INI control file (see
read_csp_config()).-o/--deviceoverride the output directory / compute device for sweeps.- Parameters:
argv (list of str or None, optional) – Command-line arguments to parse (default
None-> usesys.argv). A bare invocation (no args) prints help and exits.- Returns:
Runs the synthesis for its side effects (see
run_continuous_synthesis()).- Return type:
None
- topo.csp.protocol.read_csp_config(config_file: str, verbose: bool = True) CSPConfig[source]¶
Parse a CSP control file (INI
[OPTIONS]) into aCSPConfig.The structure / MD / ribosome keys configure the shared
topo.csp.core.RunParamsmachinery; the O’Brien kinetic keys are added on top. Required:pdb_file,ribosome,domain_def(the protein’s domain/contact-nscale definition).L0(default1) andL_max(default = full residue count) are optional. Per-codon timing additionally requiresmrna(codon_timesis optional).Kinetic keys¶
mrna– mRNA sequence file (raw nucleotides, wrapped ok); one codon per residue + 1 stop. Required for per-codon timing (it is protein-specific). May also be the keywordfastest/slowest/medianto auto-build a synonymous-codon mRNA (each residue’s fastest/slowest/median-dwell-time codon per thecodon_timestable, written next to the PDB); a real filename must not befastest/slowest/median.codon_times– the codon-timing key. Either a path to a per-codon mean-time table (CODON seconds; per-codon timing) or a positive number of seconds (uniform codon time for every codon, nomrnaneeded). Required for per-codon timing – there is no bundled default (pick a table underassets/csp/codon_dwell_times/). A table filename must not be a bare number. Seetopo.csp.kinetics.parse_codon_times().scale_factor– in-vivo seconds -> in-silico ns compressor.time_stage_1/time_stage_2– mean peptidyl-transfer / translocation dwell (s); stage 3 = codon total minus these.random_seed– seed for the FPT sampler (reproducible schedules).max_steps_per_stage– cap each stage’s step count (the tutorial uses a small value for a ~2000-steps/residue test; blank = uncapped production).min_steps_per_stage– floor each stage’s step count (default 1).ejection_steps/dissociation_steps– post-synthesis free runs (0 = skip).
MD / ribosome keys:
dt,ref_t,tau_t,nstout,device,ppn,constraints(defaultAllBonds),restraint_k,minimize,tunnel_wall. (The supplied ribosome is always rigid scenery – there is norigid_ribosomekey – and output is always nascent-only, so there is nonascent_only_outputkey either. The wall planetunnel_wall_x0and stiffnesstunnel_wall_kare not keys – the plane is auto-derived from the ribosome structure at run time and the stiffness is a fixed model constant.)- param config_file:
Path to the INI control file (must contain an
[OPTIONS]section).- type config_file:
str
- param verbose:
If True (default), echo the parsed configuration to stdout.
- type verbose:
bool, optional
- returns:
The parsed configuration (inputs, schedule and a populated
RunParams), ready to pass torun_continuous_synthesis().- rtype:
CSPConfig
- raises FileNotFoundError:
If
config_filecannot be read.- raises ValueError:
If the
[OPTIONS]section is missing, a required key (pdb_file,ribosome,domain_def) is absent/blank, or per-codon timing is requested withoutmrna.
- topo.csp.protocol.run_continuous_synthesis(full_pdb: str, ribosome_pdb: str, *, L0: int = 1, L_max: int | None = None, out_root: str = 'synth_out', mrna: str | None = None, codon_time_table_path: str | None = None, domain_def: str | None = None, stride_output_file: str | None = None, params: RunParams | None = None) None[source]¶
Run the full O’Brien continuous synthesis
L = L0 .. L_max.- Parameters:
full_pdb (str) – Full native PDB of the target protein (the nascent chain at full length).
ribosome_pdb (str) – Truncated CG ribosome PDB – source of the P-/A-anchors and the rigid (mass-0) scenery (always loaded; providing it is the signal to use it).
L0 (int, optional) – First nascent length to synthesize (default
1– start from a single residue).L_max (int or None, optional) – Final nascent length (default
None-> the full residue count of the protein).out_root (str) – Root output directory; each residue writes
L_<L>/stage_<1,2,3>/.mrna (str, optional) – mRNA sequence file (one codon per residue) – the codon-resolved kinetics. Required for per-codon timing; not needed for uniform timing (
params.uniform_codon_timeset).codon_time_table_path (str) – Per-codon mean-time table (required for per-codon timing; pick one under
assets/csp/codon_dwell_times/). There is no bundled default.domain_def (str) – Domain-definition file (
domain.yaml) defining the protein’s native-contact nscales – per-domain and per-interface Gō well-depth scaling factors (the structure-based analog of O’Brien’snscal). Required via the INI.stride_output_file (str, optional) – Precomputed STRIDE file for the contact build (skips re-running STRIDE).
params (RunParams, optional) – Run parameters (defaults to the dataclass defaults).
- Returns:
Side-effecting: writes per-residue/-stage trajectories under
out_root/L_<L>/stage_<1,2,3>/, a per-residuedwell_times.dattable, and (if requested)ejection/anddissociation/phases.- Return type:
None
- Raises:
ValueError – If the length schedule is invalid (
1 <= L0 <= L_max <= N_fullfails), or if non-uniform kinetics are requested withoutmrna/codon_time_table_path(propagated fromtopo.csp.kinetics.build_codon_time_lists()).
topo.csp.ribosome module¶
Rigid ribosome scenery + cross-interactions for elongation build step v2.
Build step v1 (topo.csp.core) simulates the nascent chain
only and uses the truncated ribosome merely as two fixed anchor coordinates.
Build step v2 adds the truncated ribosome to the System as rigid (mass-0)
scenery and wires the two ribosome <-> nascent-chain interactions, following
the RNC design (see topo/csp/README.md and docs/usage/continuous_synthesis.md):
Append the ribosome beads at indices
L..N-1with mass = 0 (frozen; not integrated), coordinates as-is. The P-/A-anchors are now real beads.Contact force (the nascent
L×Lnative/non-native table): give the ribosome beads a dummy in-rangeid = 0addParticleentry (never read) and restrict the force to the interaction group{nascent}×{nascent}– so the table staysL×Land ribosome beads are never evaluated by it.Ribosome-NC excluded volume: a separate
CustomNonbondedForcereproducing O’Brien’s NC<->ribosome interaction – the 12-10-6 formε[13(R/r)¹² − 18(R/r)¹⁰ + 4(R/r)⁶](ε = 0.000132 kcal/mol) with the sum combination ruleR_ij = Rmin/2_i + Rmin/2_j(O’Brien’s convention; nascent Rmin/2 = per-residue K-B (Option A) or per-AAOBRIEN_SC_RMIN_2_NM, ribosome Rmin/2 frommodel_parametersviaload_ribosome), cutoff 2.0 nm / switch 1.8 nm, interaction group{nascent}×{ribosome}. (Earlier topo used a pureε(σ/r)¹²+ average rule that was ~1000× too soft – seetutorials/15_claude_fix/TOPO_OBrien_NCribosome_nonbonded_compare.md.)Electrostatics: extend the existing Yukawa force with the ribosome charges (rRNA phosphates −1e, charged residues ±1e) and restrict it to
{nascent}×{nascent}+{nascent}×{ribosome}(the rigid ribosome’s intra-interactions are constant and never computed – DESIGN §2.2).
The ribosome is held rigid, so no intra-ribosome forces are ever computed.
Because the nascent chain uses flexible bonds (no constraints) and the ribosome
has none, no distance constraint ever involves a mass-0 particle, so the
mass-0 freezing needs no special constraint handling.
- class topo.csp.ribosome.Ribosome(coords_nm: ndarray, Rmin_2_nm: List[float], charges: List[float], names: List[str], resnames: List[str], resids: List[int], segids: List[str])[source]¶
Bases:
objectParsed rigid CG ribosome: per-bead coordinates (nm) and force parameters.
- Rmin_2_nm: List[float]¶
- charges: List[float]¶
- coords_nm: ndarray¶
- property n: int¶
Number of ribosome beads.
- Returns:
The bead count, taken as the length of
Rmin_2_nm.- Return type:
int
- names: List[str]¶
- resids: List[int]¶
- resnames: List[str]¶
- segids: List[str]¶
- topo.csp.ribosome._append_topology(topology, ribo: Ribosome) None[source]¶
Append the ribosome beads to an OpenMM topology (one chain per segID).
Beads are grouped into one chain per segment id and one residue per
(segID, resid)pair, then each bead is added as a carbon atom under its residue. Mutatestopologyin place.- Parameters:
topology (openmm.app.Topology) – The topology to extend with the ribosome chains, residues, and atoms.
ribo (Ribosome) – The parsed ribosome supplying segment ids, residue ids/names, and atom names for each bead.
- Return type:
None
- topo.csp.ribosome._bead_type(name: str, resname: str) str[source]¶
Parameter-lookup key for a CG bead.
Protein Cα beads (atom name
CA) look up by residue name; RNA beads look up by atom name with trailing digits stripped (P,R,BR1/BR2→BR).- Parameters:
name (str) – The PDB atom name of the bead (e.g.
"CA","P","BR1").resname (str) – The PDB residue name of the bead (used for protein Cα beads).
- Returns:
The key into
model_parametersfor this bead:resnamefor Cα beads, otherwisenamewith trailing digits stripped.- Return type:
str
- topo.csp.ribosome.add_trna_tether(nascent_model, cterm_index: int, prev_index, ribo: Ribosome, L_nascent: int, segid: str = 'PtR', resid: int = 76) None[source]¶
Tether a nascent residue to a tRNA, the full O’Brien orienting way.
Reproduces the aminoacyl-/peptidyl-tRNA linkage of
continuous_synthesis_v6.py(A_site_tRNA_binding/translocation_AtR) for the resting geometry of the given site (segid:"AtR"A-site /"PtR"P-site). For the restrained residue N (=cterm_index):bond
N -- tRNA:R(length/k from_TRNA_SITE_GEOM/TRNA_TETHER_BOND_K);orienting angles
N -- R -- PandN -- R -- PU2(harmonic,TRNA_TETHER_ANGLE_K) – fix the residue’s bearing in the tRNA frame;improper
N -- R -- P -- PU2(periodic-harmonic on |θ−θ0|,TRNA_TETHER_IMPROPER_K) – fixes the out-of-plane sense;backbone orienting angle
prev -- N -- R(double-Gaussian backbone form) – aims the chain down the tunnel toward the exit.
Together (vs. the single bond + 1 angle of the old version) these reproduce O’Brien’s full orientation control: the chain extrudes N-first down the tunnel rather than balling up at the PTC. The peptide bond
N-1<->Nis left in place (topo keeps the always-bonded chain – a deliberate deviation, DIFFERENCES.md).prev_indexis the CA(N-1) particle index, or None (skips the backbone angle).P(O’Brien R-1) andPU2(O’Brien R+2) are resolved by topo bead name ("P"/"BR2"); a site missing either bead skips that angle/improper.- Parameters:
nascent_model (object) – The built nascent model whose
.systemreceives the tether forces and whose.gaussianAngleForcereceives the backbone orienting angle.cterm_index (int) – System index of the restrained nascent CA(N) bead.
prev_index (int or None) – System index of CA(N-1), or None (skips the backbone angle).
ribo (Ribosome) – The parsed ribosome (supplies the tRNA R/P/BR2 beads).
L_nascent (int) – Number of nascent particles preceding the ribosome beads (index offset).
segid (str, optional) – tRNA segment id:
"AtR"(A-site) or"PtR"(P-site, default).resid (int, optional) – tRNA acceptor residue id. Default is
76.
- Return type:
None
- Raises:
ValueError – If
segidis not a known tRNA site, or itsRbead is not found.
- topo.csp.ribosome.add_tunnel_wall(system, nascent_indices, x0_nm: float, k: float = 8368.0) Force[source]¶
Add O’Brien’s one-sided planar tunnel wall on the nascent chain.
U = k * min(x - x0, 0)^2per nascent bead – penalizesx < x0only, so the chain is kept atx >= x0and can only extrude forward (+x).x0_nmis the plane position (nm; the C-terminal-AA addition plane / PTC) andkis the force constant in OpenMM units (kJ/mol/nm^2).- Parameters:
system (openmm.System) – The system to which the planar-wall force is added.
nascent_indices (iterable of int) – System indices of the nascent-chain beads subjected to the wall.
x0_nm (float) – Plane position (nm); beads are penalized only for
x < x0. Always supplied by the CSP runner from the PTC-optimized A/P targets (structure-dependent); there is no default.k (float, optional) – Force constant (kJ/mol/nm^2) of the one-sided restraint. Default is
TUNNEL_WALL_K.
- Returns:
The created
CustomExternalForce(already added tosystem).- Return type:
openmm.Force
- topo.csp.ribosome.anchor_coord(ribo: Ribosome, segid: str, resid: int = 76, bead: str = 'R') ndarray[source]¶
Coordinate (nm) of a named ribosome bead from a loaded
Ribosome.The
Ribosome-object analog oftopo.csp.core.read_anchor()(which parses a PDB): used to pick the P-/A-anchors (segid='PtR'/'AtR', resid 76,Rbead) directly from the loadedRibosomearrays. Raises if the bead is absent or non-unique.
- topo.csp.ribosome.append_ribosome(nascent_model, ribo: Ribosome, nascent_rmin_2: ndarray | None = None) Tuple[List[int], List[int]][source]¶
Append the rigid ribosome to a built nascent model (system + topology).
Mutates
nascent_modelin place (its.systemand.topology): appends mass-0 (fixed) ribosome particles; extends the contact and Yukawa forces with ribosome entries and restricts their interaction groups; adds the O’Brien-consistent ribosome-NC excluded-volume force (the 12-10-6 formU = eps[13(R/r)¹² - 18(R/r)¹⁰ + 4(R/r)⁶]with the sum combination ruleR = rm_i + rm_j, acting on {nascent}×{ribosome} only); and extends the topology with one ribosome chain per segID.Must be called after
topo.csp.core.build_length_model()(the nascent forces must already exist).- Parameters:
nascent_model – The built nascent model whose
.systemand.topologyare mutated.ribo (Ribosome) – The parsed rigid ribosome (coords, per-bead Rmin/2, charges, topology).
nascent_rmin_2 (np.ndarray, optional) – Per-nascent-bead Rmin/2 (nm) for the NC-ribosome excluded volume. When given (length must equal the nascent atom count), these are O’Brien’s structure-derived per-residue Karanicolas-Brooks collision radii (“Option A”). When
None, falls back to per-AA sidechain radiiOBRIEN_SC_RMIN_2_NM(“Option B”).
- Returns:
(nascent_indices, ribosome_indices)
- Return type:
Tuple[List[int], List[int]]
- topo.csp.ribosome.bead_system_index(ribo: Ribosome, L_nascent: int, segid: str, resid: int, bead: str = 'R') int | None[source]¶
System index of a named ribosome bead (e.g. the P-site tRNA R anchor).
Ribosome beads are appended after the
L_nascentnascent particles in load order, so the system index isL_nascent + (position in the Ribosome arrays). Returns None if no such bead exists (e.g. a pyrimidine has noBR2).
- topo.csp.ribosome.load_ribosome(pdb_file: str, model: str = 'topo') Ribosome[source]¶
Parse a (truncated) CG ribosome PDB into a
Ribosome.Reads each ATOM/HETATM record, derives its bead type (
_bead_type()), and looks up its collision radius Rmin/2 and charge frommodel_parameters[model]– the fixed per-type scenery table: RNA beads (P/R/BR) by O’Brien’s per-type Rmin/2, protein Cα beads by O’Brien’s per-AA sidechain Rmin/2 (his ribosomeS<aa>values; the one structure-based Go protein L24 is treated the same per-AA way – his per-residue B-type values are not reproduced). Coordinates are converted from angstrom to nm. This reproduces O’Brien’s ribosome excluded volume from topo’s own CG PDB – no .cor/.psf/.prm needed. The mobile nascent chain uses its own per-residue K-B Rmin/2 (Option A), never this table (see model_parameters).- Parameters:
pdb_file (str) – Path to the (truncated) coarse-grained ribosome PDB file.
model (str, optional) – Key selecting the parameter set in
model_parametersused for radii and charge lookups. Default is"topo".
- Returns:
The parsed ribosome with per-bead coordinates (nm), radii, charges, atom names, residue names, residue ids, and segment ids.
- Return type:
- Raises:
ValueError – If a parsed bead type is missing from
model_parameters[model], or if no ATOM/HETATM records are found in the file.
Module contents¶
topo.csp – the O’Brien Continuous Synthesis Protocol, ported to topo.
The per-codon, three-stage protein synthesis protocol of
continuous_synthesis_v6.py (Yang Jiang, Dan Nissley, Ed O’Brien), expressed in
topo style. It is the kinetic upgrade of topo.csp.core: it times
every residue from its codon and splits each into peptidyl-transfer / translocation /
tRNA-binding sub-stages, reusing the translation module’s per-length MD machinery.
CLI:
topo-csp -f csp.ini
python -m topo.csp -f csp.ini
See topo.csp.protocol (explicit-ribosome runner + INI), topo.csp.cylinder
(the analytic-tunnel cylinder runner – a parallel model that reuses the same kinetics),
and topo.csp.kinetics (timing core).