Repository navigation
Add proteinbox and protein_mixedbox simulation types - #59
Conversation
…Config New models for the proteinbox simulation type: - ProteinSpecies: PDB-path-based species with disulfide/protonation annotations - ProteinBoxComposition: protein + box_padding + ionization config - Pdb2gmxConfig: force field and water model config for pdb2gmx - GromacsProteinParameterSet: output paths from pdb2gmx - BuildInput extended with proteinbox type and pdb2gmx parametrization Closes: relates to #13 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Functions for the proteinbox build pipeline: - check_gmx_available: verify gmx binary is on PATH - clean_pdb: PDBFixer-based PDB standardization - run_pdb2gmx: subprocess wrapper for gmx pdb2gmx - extract_charge_from_topology: parse net charge from .top/.itp - update_topology_molecules: append water/ion entries to [ molecules ] - validate_with_grompp: dry-run topology validation Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Brief NPT equilibration with protein heavy atoms position-restrained via CustomExternalForce. Allows water/ions to relax around the fixed protein structure before GROMACS production runs. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Build pipeline: clean PDB -> pdb2gmx -> center in cubic box -> solvate (reuses existing solvate()) -> ionize (reuses ionize_solvated_system()) -> update topology -> OpenMM relax with protein restraints -> validate. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
MDP files for protein-in-waterbox equilibration and production: - em.mdp: steepest descent minimization - nvt.mdp: NVT with -DPOSRES and Protein/Non-Protein tc-grps - npt.mdp: NPT with -DPOSRES and Berendsen barostat - md.mdp: production with Parrinello-Rahman, no position restraints All use CHARMM36m-specific nonbonded settings (1.2nm cutoffs, Force-switch VdW modifier, no dispersion correction). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- 13 unit tests covering ProteinSpecies, ProteinBoxComposition, Pdb2gmxConfig, BuildInput integration, and topology parsing - Fix ProteinSpecies to default count=1/fraction=1.0 at field level (avoids parent Species validator ordering issue) - Example YAML for lysozyme with CHARMM36m force field Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Addresses 4 P2 review comments: - Add missing `from pathlib import Path` to build.py module scope - Resolve all paths to absolute in run_pdb2gmx before subprocess call (avoids cwd confusion with output_dir) - Add species/total_count/charge properties to ProteinBoxComposition and proteinbox case in BuildInput.metadata for analysis compatibility - Implement _apply_protonation_states: renames residues in PDB before pdb2gmx so protonation overrides (HIS->HIE, GLU->GLH) are applied Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add check_forcefield_available() that verifies the force field directory exists in GROMACS share, GMXLIB, or cwd before invoking pdb2gmx. Lists available force fields on failure. - Clean up mdout.mdp artifact in validate_with_grompp alongside check.tpr. - Fix bare open() file handles in relax_with_protein_restraints (use with-blocks). - Add CHARMM HIS alias translation (HIE→HSE, HID→HSD, HIP→HSP for charmm FFs). - Use re.fullmatch for protonation state key parsing (reject trailing chars). - Validate 3-character residue names for PDB column safety. - Add disulfide bond prompt generation (_build_disulfide_prompt_input) for deterministic pdb2gmx -ss interaction. - Resolve paths before working_directory context switch to avoid cwd breakage. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add FORCEFIELD_REGISTRY mapping friendly names (charmm36m, charmm36m-ljpme) to MacKerell lab download URLs and extracted directory names. - Auto-download missing force fields on first use from the registry. Stored in platformdirs user_data_dir (~/Library/Application Support/mdfactory/forcefields/). - resolve_forcefield() translates friendly names to actual directory stems so users write "charmm36m" in YAML and pdb2gmx receives the correct directory name. - Inject GMXLIB in subprocess env so gmx finds downloaded force fields. - Fix extract_charge_from_topology: skip .ff/ library includes (ions.itp, tip3p.itp) that contain atom type templates, not system charges. Was causing +159 charge for lysozyme with charmm36m instead of +8. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add [gromacs] section to settings.py with GMX_PATH and FORCEFIELD_DIR, following the same pattern as [cgenff] SILCSBIODIR. - Settings.__init__ auto-prepends FORCEFIELD_DIR to GMXLIB env var on startup, matching how SILCSBIODIR is auto-set for CGenFF. - check_gmx_available() checks configured GMX_PATH first, falls back to PATH lookup. - All gmx subprocess calls (pdb2gmx, grompp) use the configured binary and inject GMXLIB for force field resolution. - Add GROMACS setup to config wizard (sync_config.py): prompts for gmx path, forcefield dir, and offers to download CHARMM36m on setup. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- rename Pdb2gmxConfig.ignh to ignore_hydrogens - rename ProteinBoxComposition.box_padding to padding (matches LNP) - accept disulfide bonds as CYS-prefixed residue references (e.g. CYS6) to match the protonation_states residue nomenclature Addresses review comments on examples/proteinbox/lysozyme_charmm36m.yaml.
Address 7 issues flagged in review of the protein-box feature: - [P1] Resolve a relative protein pdb_path against the YAML file's directory in run_build_from_file, not the process cwd (the CLI cd's into the output dir before building), so bundled paths like ./1aki.pdb are found. - [P1] Declare pdbfixer in [tool.pixi.dependencies]; clean_pdb imports it at runtime but it was undeclared. - [P2] Run pdb2gmx with relative output filenames so the generated topology has a portable relative #include "posre.itp" instead of an absolute path. - [P2] Enforce simulation_type <-> parametrization <-> config-type consistency in BuildInput; proteinbox+cgenff and mismatched configs now fail validation with a clear message instead of late in the build. - [P2] Restrict Pdb2gmxConfig to CHARMM force fields and 3-site water (tip3p/spc/spce), matching what solvation and the mdp files support. - [P2] Let grompp validation failure fail the build instead of being swallowed as a warning. - [P2] Center the protein on its bounding-box center (not center of geometry) so every box face keeps the requested padding.
Rewrite the absolute force-field #includes that pdb2gmx writes into a relative path and copy the .ff directory next to the topology, mirroring the CGenFF strategy in generate_gromacs_topology. Both grompp (cwd) and OpenMM's GromacsTopFile (topology dir) then resolve the force field from the build directory, so it is portable to another machine. Reject CHARMM LJ-PME force-field variants (e.g. charmm36m-ljpme): the proteinbox run schedule uses cutoff/Force-switch LJ, which is incompatible with LJ-PME. Move the newly added test imports to module top level.
Multi-chain PDBs now build each subunit as its own Protein_chain_<ID> moleculetype, referenced from topol.top, rather than requiring a merge. The chains list must be declared in the YAML and is validated against the chains pdb2gmx produces; an undeclared multi-chain PDB is an error so subunits are never silently dropped. GromacsProteinParameterSet carries the per-chain include files (topol_Protein_chain_*.itp, posre*.itp), which build_proteinbox copies alongside topology.top in both the build and relaxation directories. Also fixes two review findings: - Protonation overrides match histidine tautomers as a family and raise when an override matches no residue; 4-character CHARMM acid states (GLUP/ASPP) are rejected with a clear message. - bundle_forcefield_into_topology copies each .ff directory only once instead of once per include line.
Protein charge is set from the pdb2gmx topology, and every caller treats species.charge as Optional[int] (guarding with 'is not None'). Raising NotImplementedError broke that contract and would propagate through the hasattr guard in _compute_charge_from_universe if a protein ever reached it. Returning None aligns with the contract and is skipped by the charge sums, leaving proteinbox charge results (from the topology) unchanged.
- Parse delimited protein list cells (chains 'A;B', disulfide pairs 'CYS6-CYS127' joined by ';') and dotted protonation_states columns from CSV rows; drop blank optional protein cells per row and exclude them from the strict NaN guard so heterogeneous proteins share one CSV. - Resolve relative protein pdb_path against the CSV directory at read time. - Reject merge_all combined with declared protein.chains at config validation instead of failing deep inside pdb2gmx. - Make relax_steps config-driven on ProteinBoxComposition. - Remove proteinbox build intermediates on success so the output dir holds only final artifacts, matching small-molecule builds.
Serialize prepared per-system YAML with model_dump(mode="json") so proteinbox Path fields (pdb_path) and tuple fields (disulfide_bonds) become plain str/list that yaml.safe_dump can write. Small-molecule inputs have no Path/tuple fields, so this path never surfaced before. Correct the build_proteinbox cleanup comment: only the three pdb2gmx-specific loose intermediates are removed; solvated.pdb and relaxation/ are left in place, matching how the bilayer build leaves solvated.pdb and bilayer_squeeze/. Add examples/proteinbox/proteins.csv showing the flat dotted-key / delimited-cell CSV encoding for single-chain (lysozyme) and multi-chain (insulin) systems. PDBs are referenced by RCSB id filename and fetched separately, matching the existing YAML example.
Extend compress_box with optional protein position restraints and a target-volume stop for the protein_mixedbox pipeline. When protein_indices is given, every listed atom is held with a harmonic CustomExternalForce through minimization and high-pressure compression so a pdb2gmx-prepared protein stays fixed while solvent and solutes pack around it. When target_volume is given, compression stops on box volume instead of density (the fixed_box sizing mode). Defaults preserve the existing mixedbox behavior exactly.
generate_gromacs_topology_with_protein assembles one topology for a pdb2gmx-prepared protein packed with CGenFF small molecules, water, and ions, in strict include order: bundled CHARMM force field, merged CGenFF parameters (atomtypes de-duplicated against the force field, [defaults] dropped since the FF already bundles CGenFF), protein moleculetypes and position restraints, CGenFF small-molecule moleculetypes, then the water and ion topologies pdb2gmx already includes. The [ molecules ] section keeps the protein chain entries and appends the solution molecules in coordinate order so topology and coordinates agree. Native water and ions reuse the pdb2gmx force-field moleculetypes and contribute no extra include or parameters.
…dbox extract_mass_from_topology sums the topology mass column (following protein chain includes) so the build can derive the protein displacement volume. ionize_solvated_system gains an optional solvent_volume_a3 to resolve the salt pair count on an explicit volume basis instead of the water-count proxy.
Pack water, ions, and SMILES solutes around a pdb2gmx-prepared protein under one CHARMM/CGenFF force-field family, compress with every protein atom restrained, re-image the protein whole and centered across PBC, ionize on the chosen concentration-volume basis, and relax with the protein restrained. compress_box skips its residue wrap when protein_indices is given, since a restrained protein ends up torn across the boundary; build_protein_mixedbox makes it whole from the restraint reference shape and re-centers instead.
End-to-end run of the test plan (2026-11-02)I ran every item of the test plan above for real, on the Environment notes
Blocking bugs
Passed
Minor, not blocking
Amber14SB check for issue 60
|
…charge grompp validation Findings from the end-to-end run of the protein_mixedbox test plan: - compress_box: the 1000 bar barostat sweeps past the target between checks (3.4-7.8% in about half of the builds). Overshoots up to 15% are now undone by expanding the box and molecule centers to the exact target volume (finish_compression / rescale_to_volume); a restrained protein moves as one rigid unit. - LNP core compression warns instead of failing when the nominal density is not reached (require_convergence=False), restoring the develop behavior. - protein_mixedbox writes CGenFF solutes with their ITP atom names (topology_atom_names), so grompp -maxwarn 0 no longer sees non-matching names. - validate_with_grompp(allow_net_charge=...) accepts only grompp's net-charge warning when neutralization is disabled, in a single grompp call (a failing gmx_mpi call aborts through MPI and can kill an enclosing srun step). - Reformat test_topology_utilities.py with ruff 0.9.2 (the CI version).
Progress update: fixes for the four blocking e2e bugsThis addresses the four blocking bugs in the e2e findings comment above.
Also:
Still open, not addressed here:
Commit: Progress tracked by mach6 |
Unverified Review Candidates — Pending AssessmentReview round: 1
CriticalNone. ImportantFinding 1: CSV push and discovery hash the relative
Finding 2: single-YAML builds through
Finding 3: neutral-lysine (
Finding 4: issue 13 asks for a selectable force field including
Finding 5: the LNP leniency and the stricter mixedbox default have no tests, although e2e bug 2 was exactly this regression (test-reviewer, 88)
Finding 6:
Finding 7: the count and report bookkeeping in
SuggestionsFinding 8: out-of-date docstrings (code-reviewer, 90)
Finding 9: the PR body is out of date on Finding 10: test-plan checkboxes not updated (completeness-checker, 80). These are still unticked although the progress comment reports them as passing:
Finding 11: no test of the density-compression loop (test-reviewer, 80). Finding 12: weak RMSD-restraint test (test-reviewer, 85)
Finding 13: Finding 14: Finding 15: four almost identical Finding 16: the concentration-volume-basis branch appears three times (simplifier, 88). It is in Finding 17: Finding 18: topology and force-field staging copied three times, relaxation-directory staging twice, in Finding 19: two Finding 20: the RMSD and clash verification block after compression and after relaxation is duplicated (simplifier, 80). It is in Finding 21: one-use wrapper Finding 22: verbose index bookkeeping for Strengths
Agents run: code-reviewer (split into 4 parts after 2 stalled runs), error-auditor, test-reviewer, completeness-checker, simplifier Reviewed by mach6 |
Review AssessmentFindings comment: #59 (comment) Scope basis: The maintainer-authored test plan, under "Known limitations / follow-ups (not in this PR)", explicitly narrows issue 13's "also supports Classifications
Action Plan
Assessment by mach6 |
…try points - Add prepare.load_build_input_csv as the single CSV loader for prepare-build, build and push/discovery, so relative system.protein.pdb_path cells resolve against the CSV's directory everywhere and hashes match the built folders. - Move the YAML resolver to prepare.resolve_protein_pdb_path and call it in cli._build_from_yaml before hashing, so --config (Parsl) and --dry-run find the PDB and the build directory is named after the model that is built. - Add regression tests for the shared CSV hash, the dispatched model path and the sequential build-directory hash.
Progress Update: the two round 1 merge blockers are fixedThis fixes findings 1 and 2 from the round 1 assessment. Both were cases where one entry point did not resolve a relative
Tests: three new tests in
All three fail without the fix and pass with it. Not addressed here: the deferred follow-ups and nitpicks from the assessment. That includes findings 8–10, the stale docstrings, the outdated PR-body line about Commit: Progress tracked by mach6 |
…e mdp templates, consolidate tests - protein_mixedbox reuses the identical proteinbox mdp files via a run-schedule template_dir key - build.py: shared helpers for protein prep, relaxation, topology staging, reimage/verify and finalization; drop the redundant second force-field bundle - setup/protein.py: one [ atoms ] column parser, shared residue resolution and gmx subprocess helper, drop thin settings wrappers - openmm_utils: fixed-box compression uses the density loop; shared universe/reporter helpers - models: shared CHARMM config base, Literal single-copy ProteinSpecies, drop unused charge properties and single-use wrappers - tests: shared fixtures and parametrization across proteinbox/protein_mixedbox; rename tests that -k "not build" was silently deselecting
Progress UpdateSimplification/duplication pass over the PR (no feature changes intended). PR additions vs develop drop from ~7255 to ~5920 lines (source ~4212 → ~3540, tests 2780 → 2119). Source
Small behavior changes
Tests
Still to do: the refactored build functions have no direct unit tests. Re-run one real proteinbox and one protein_mixedbox e2e build before merge. Commit: Progress tracked by mach6 |
Unverified Review Candidates — Pending AssessmentReview round: 2
Round 1 merge blockers, re-checked at this commit:
CriticalNone. ImportantFinding 1:
Finding 2: no real end-to-end rerun after the 47c2298 refactor (completeness-checker, 85)
Finding 3: the
Finding 4: the fixed-box→density conversion and the argument forwarding in
Finding 5: the LNP leniency flag is still untested (test-reviewer, 84)
Finding 6: the shared protein build helpers and the report bookkeeping are untested (test-reviewer, 82)
Finding 7:
Finding 8: the consolidated
Finding 9:
Finding 10: the RMSD-restraint test passes for a force that is identically zero, and
SuggestionsFinding 11: the PR body is out of date in several places (completeness-checker, 95)
Finding 12: test-plan checkboxes are still unticked for items the progress comments report as passing (completeness-checker, 90)
Finding 13: the example inputs need Finding 14: Finding 15: Finding 16: the Strengths
Agents run: code-reviewer ×2 (split: build/openmm/setup_utilities; models/setup/protein/topology/CLI/push/analysis), error-auditor, test-reviewer, completeness-checker, simplifier Reviewed by mach6 |
Review AssessmentFindings comment: #59 (comment) Review round: 2. Assessed by: independent-assessor. Scope basis:
Round 1 merge blockers: findings 1 and 2 are both verified fixed at 47c2298. Classifications
Action Plan
Assessment by mach6 |
…ery missing segment
Progress Update: round 2 merge blockers (findings 1 and 2)Finding 1:
|
| Build | Result |
|---|---|
proteinbox lysozyme_charmm36m.yaml |
Built in 25 s. [ molecules ]: protein, SOL 8424, NA 23, CL 31. Net charge 0. HIS15 → HSE. The protein is whole (max CA–CA 4.02 Å). EM Fmax 945. |
protein_mixedbox lysozyme_fixed_box.yaml (ethanol, CGenFF) |
Built in 47 s. Compression overshot by 1.48% and was rescaled to exactly 373.248 nm³. RMSD was 0.28 Å after compression, and the relaxation RMSD check (< 0.5 Å) also passed. build_metadata.json: ETH 214 → 0.999 M, SOL 11716 → 54.67 M, NA 32 / CL 40. EM Fmax 858. |
mixedbox water_ethanol_cgenff.yaml |
Built in 19 s. The density target was reached at step 15800, and a 0.17% overshoot was rescaled. The pre-existing atom-name mismatch on the plain mixedbox path is still there; this path has no grompp check. |
| proteinbox 1STN (finding 1, terminal tails) | SEQRES covers 1–149; the coordinates cover 6–141. Both tails (5 and 8 residues) were reported and not built, giving 136 residues. Before the fix these 13 residues would have been built as extended stubs. |
| proteinbox 1aki with residues 101–103 deleted (finding 1, internal gap) | The log reports "modeling 3 missing internal residue(s) ASP-GLY-ASN between SER100 and GLY104". The result has 129 residues, max CA–CA 3.97 Å. EM Fmax 920. |
New bug, not fixed: chains that start with MET fail in pdb2gmx
The 5DFR build (DHFR, whose first residue is MET1) fails with atom C1 not found in buiding block 1MET while combining tdb and rtp.
- Cause: the CHARMM36 Feb-2026 bundle's
ethers.n.tdbdefines aMET1terminus, a methyl-ether cap. pdb2gmx matches termini on the first three characters of the residue name, so it takesMET1as a MET-specific N-terminus. - C-terminal MET:
ethers.c.tdbhas aMET2entry, which probably breaks chains that end with MET in the same way. I have not tested that. - Origin: this goes back to the original proteinbox work and is not caused by the changes here.
- Impact: proteins whose sequence starts with Met are common, so this needs a decision: fix it in this PR, or file a follow-up issue.
Commit: b33adf3
Progress tracked by mach6
b33adf3 to
94afbfe
Compare
gregorweiss
left a comment
There was a problem hiding this comment.
awesome new feature!
Unverified Review Candidates — Pending AssessmentReview round: 3
Scope of this round. This is a composite review. The target is the whole stack (PR 59, PR 63, PR 65, PR 67) as one diff against Round 2 merge blockers on PR 59, re-checked:
No leftover legacy names in source. A grep of the final tree found no remaining reference to Index of requested categories
CriticalNone. ImportantFinding 1: A build whose grompp validation fails is left looking simulation-ready (error-auditor, 85)
Finding 2:
Finding 3: Generated mdps differ from the deleted static templates for existing mixedbox, bilayer and lnp, with no token-level guard (code-reviewer, 90; test-reviewer, 82)
Finding 4: CI deselects, by name, the only tests that run the real mixedbox and bilayer builds, real grompp, and the orchestration CLI (test-reviewer, 92; completeness-checker, 90)
Finding 5:
Finding 6: Cache and download integrity is not enforced (error-auditor, 80; code-reviewer, 80)
Finding 7: Charge and mass sums silently skip bad lines and missing includes (error-auditor, 80)
Finding 8: Close cysteine pairs are silently left reduced when
Finding 9:
Finding 10: Old-schema build directories silently drop out of discovery (error-auditor, 80)
Finding 11: The same
Finding 12: PR housekeeping before merge (completeness-checker, 90)
Finding 13: The 20-system tutorial CSV is delivered in the new schema but fails validation on every row (completeness-checker, 95)
Finding 14: The CHARMM
Finding 15: Unguarded seams in tests (test-reviewer, 80 to 85)
Legacy, compatibility and fallback code (maintainer policy: none wanted)Finding 16: Docs keep an old-key to new-key migration section (code-reviewer, 80; simplifier, 90)
Finding 17:
Finding 18: LNP core compression keeps the old non-convergence behaviour behind a flag (code-reviewer A1, 80)
Finding 19: Optional parameters and
Finding 20: Dead or write-only code retained (simplifier, 80 to 95; code-reviewer, 85)
SuggestionsFinding 21: Over-engineering (simplifier, 80 to 85)
Finding 22: Hand-rolled GROMACS section and include walkers (simplifier, 92)
Finding 23: Duplicate atom-type loop in two validators (simplifier, 90)
Finding 24: Native water and ion tables repeated (simplifier, 80 to 85; code-reviewer, 80)
Finding 25: Repeated type sets and mappings (simplifier, 80 to 95; code-reviewer, 85)
Finding 26: Duplication across the builders (code-reviewer A1, 80 to 85; simplifier, 80)
Finding 27: Test duplication and global-settings leakage (simplifier, 88; test-reviewer, 80)
Finding 28: Brittle assertions (test-reviewer, 80)
Finding 29: Version-gate loose ends (test-reviewer, 80; error-auditor, 80)
Finding 30: Docs overclaim override-key validation (completeness-checker, 85)
Finding 31: OpenMM nits (code-reviewer A1, 80)
Finding 32: Remaining silent defaults (error-auditor, 80)
Strengths
Agents run: code-reviewer ×3 (part B; part A1; part A2a), error-auditor, simplifier, test-reviewer, completeness-checker. Two further code-reviewer runs (part A, part A2b) were cancelled after stalling; their scope ( Reviewed by mach6 |
Review AssessmentFindings comment: #59 (comment) Round 3, composite review of the stack tip Classifications
Action PlanNo merge blockers; there is nothing to implement before merge. The assessors suggest these non-blocking items, cheapest first, if you want to tidy the stack before merging (none of them gates the merge):
Assessment by mach6 |
Summary
Adds two protein simulation types. Supersedes #15 (closed): this branch contains all of its commits plus the
protein_mixedboxwork, and hasdevelopmerged in. Implements #13 (proteinbox).proteinbox— protein in a water boxgmx pdb2gmx(CHARMM only), disulfides from an explicit list (-ssprompts answered deterministically), residue-name based protonation overrides, multi-chain proteins via an explicitchainsdeclaration.padding, solvation with the existingspc216tiling, Na⁺/Cl⁻ via the existingionize_solvated_system, restrained OpenMM relaxation,gromppvalidation, GROMACS run schedule (em/nvt/npt/md).[gromacs]settings (GMX_PATH,FORCEFIELD_DIR) in the config andmdfactory config init.;-separated chains/disulfides) and YAML-relativepdb_pathresolution.protein_mixedbox— protein + water / ions / SMILES solutesparametrization: charmm(CharmmConfig, currentlycharmm36m+tip3ponly).SolutionSpecies: water assmiles: O, ions, arbitrary SMILES) given bycountor molarconcentration; concentrations are resolved on theboxorprotein_excludedvolume (partial_specific_volume). Sizing byfixed_boxorcount_density.generate_gromacs_topology_with_protein) with atom-type de-duplication against the force field.build_metadata.json(resolved/final counts, achieved concentrations), surfaced inSimulation.metadataandsystem_chemistry.system_chemistry,last_frame_pdb); no protein-specific analyses yet.Notes for review
Changes to shared code (also affect existing builds)
relax_with_protein_restraints(used bybuild_proteinbox) now uses a best-fit RMSD restraint instead of absolute position restraints, and no longer wraps by residue.build_proteinboxhas no re-imaging step, so its output is now unwrapped and the protein can move as a rigid body.compress_box(used by the existingmixedboxbuild) checks the density every 25 steps (was 1000) and raisesRuntimeErrorif the target is not reached or is overshot by more than 2% (previously silent).ionize_solvated_systemgained an optionalsolvent_volume_a3.Merge of
develop: conflicts from #43 were resolved inbuild.py,models/composition.pyandmodels/input.py.build_proteinboxread the ion counts by position ([0]= Na,[1]= Cl); since #43 returns only the species actually added, a lone Cl⁻ would have been written asNA. Counts are now looked up by residue name (_ion_counts, with tests).Tests
pytest -k "not build" mdfactoryon a compute node: 2998 passed, 25 failed, 53 errors, 1 skipped. The failing/erroring test IDs are identical to the pre-merge head (0de0618), so none are caused by this branch: CGenFF parametrization tests (the local SILCSBIO license is expired) and DB push/pull tests (Column names do not match with existing tablein the local environment).Status
Draft: not yet validated end-to-end. The unit tests mock
gmx,pdb2gmx, packmol and OpenMM. The test plan is in the first comment. SMILES-solute builds are currently blocked by the expired CGenFF license (renewal in progress); water/ion-only builds are not affected.