mdprep 0.3.0__tar.gz → 0.4.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (360) hide show
  1. {mdprep-0.3.0 → mdprep-0.4.0}/AGENTS.md +3 -2
  2. {mdprep-0.3.0 → mdprep-0.4.0}/CHANGELOG.md +148 -0
  3. mdprep-0.4.0/CONTRIBUTING.md +115 -0
  4. {mdprep-0.3.0 → mdprep-0.4.0}/PKG-INFO +41 -23
  5. {mdprep-0.3.0 → mdprep-0.4.0}/README.md +40 -22
  6. {mdprep-0.3.0 → mdprep-0.4.0}/docs/README.md +2 -0
  7. {mdprep-0.3.0 → mdprep-0.4.0}/docs/guided_manifests.md +24 -3
  8. {mdprep-0.3.0 → mdprep-0.4.0}/docs/manifest_reference.md +25 -5
  9. {mdprep-0.3.0 → mdprep-0.4.0}/docs/metals.md +86 -4
  10. {mdprep-0.3.0 → mdprep-0.4.0}/docs/molecular_dynamics.md +33 -0
  11. mdprep-0.4.0/docs/oligomers.md +169 -0
  12. mdprep-0.4.0/docs/predicted_structures.md +170 -0
  13. {mdprep-0.3.0 → mdprep-0.4.0}/docs/tleap_and_validation.md +13 -0
  14. {mdprep-0.3.0 → mdprep-0.4.0}/docs/troubleshooting.md +41 -0
  15. mdprep-0.4.0/examples/17_syrb2_bound_water_mcpb.yaml +216 -0
  16. mdprep-0.4.0/examples/18_syrb2_dimer_shared_mcpb.yaml +345 -0
  17. {mdprep-0.3.0 → mdprep-0.4.0}/examples/README.md +23 -5
  18. {mdprep-0.3.0 → mdprep-0.4.0}/examples/colab_smoke_test.ipynb +1 -1
  19. mdprep-0.4.0/examples/mdprep_colab.ipynb +1080 -0
  20. mdprep-0.4.0/examples/mdprep_colab_run.ipynb +30 -0
  21. {mdprep-0.3.0 → mdprep-0.4.0}/examples/mdprep_interactive_colab.ipynb +2 -2
  22. {mdprep-0.3.0 → mdprep-0.4.0}/pyproject.toml +2 -1
  23. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/__init__.py +1 -1
  24. mdprep-0.4.0/src/mdprep/analysis/__init__.py +6 -0
  25. mdprep-0.4.0/src/mdprep/analysis/charges.py +209 -0
  26. mdprep-0.4.0/src/mdprep/analysis/dcd.py +112 -0
  27. mdprep-0.4.0/src/mdprep/analysis/equilibration.py +90 -0
  28. mdprep-0.4.0/src/mdprep/analysis/metal_site.py +78 -0
  29. mdprep-0.4.0/src/mdprep/analysis/prmtop.py +236 -0
  30. mdprep-0.4.0/src/mdprep/analysis/trajectory.py +365 -0
  31. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/cli.py +222 -8
  32. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/config/decisions.py +832 -135
  33. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/config/models.py +230 -0
  34. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/leap/builder.py +21 -2
  35. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/leap/report.py +15 -0
  36. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/leap/residues.py +28 -0
  37. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/ligands/workflow.py +106 -9
  38. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/md/roe_brooks.py +139 -6
  39. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/metals/coordination.py +11 -4
  40. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/metals/mcpb.py +519 -14
  41. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/metals/report.py +25 -0
  42. mdprep-0.4.0/src/mdprep/metals/through_metal.py +135 -0
  43. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/metals/workflow.py +31 -11
  44. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/protonation/histidine_xtb.py +18 -1
  45. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/refinement/selection.py +14 -0
  46. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/reports/structure_report.py +5 -0
  47. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/structure/classify.py +30 -1
  48. mdprep-0.4.0/src/mdprep/structure/closest_xray.py +301 -0
  49. mdprep-0.4.0/src/mdprep/structure/coordination.py +70 -0
  50. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/structure/inspect.py +8 -0
  51. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/structure/normalize.py +37 -2
  52. mdprep-0.4.0/src/mdprep/structure/oligomer.py +713 -0
  53. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/structure/pdb.py +17 -0
  54. mdprep-0.4.0/src/mdprep/structure/waters.py +868 -0
  55. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/structure/writer.py +47 -2
  56. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/validation/topology.py +2 -2
  57. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/workflows/doctor.py +55 -0
  58. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/workflows/runtime.py +124 -5
  59. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/workflows/wizard.py +30 -2
  60. mdprep-0.4.0/tests/test_analysis.py +435 -0
  61. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_besd_halogenase_case.py +65 -1
  62. mdprep-0.4.0/tests/test_closest_xray.py +256 -0
  63. mdprep-0.4.0/tests/test_colab_official_notebook.py +164 -0
  64. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_colab_smoke_notebook.py +1 -1
  65. mdprep-0.4.0/tests/test_crystal_ions.py +215 -0
  66. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_doctor.py +21 -0
  67. mdprep-0.4.0/tests/test_external_dcd_openmm.py +42 -0
  68. mdprep-0.4.0/tests/test_external_oligomer_mcpb.py +112 -0
  69. mdprep-0.4.0/tests/test_external_water_transplant.py +61 -0
  70. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_leap_builder.py +23 -0
  71. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_manifest_decisions.py +52 -14
  72. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_manifest_wizard.py +3 -1
  73. mdprep-0.4.0/tests/test_metal_bound_water.py +223 -0
  74. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_metals.py +1 -0
  75. mdprep-0.4.0/tests/test_oligomers.py +925 -0
  76. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_packaging_metadata.py +1 -1
  77. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_pdb_writer.py +58 -0
  78. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_roe_brooks.py +26 -0
  79. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_runtime_requirements.py +118 -0
  80. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_structure_completeness.py +113 -3
  81. mdprep-0.4.0/tests/test_syrb2_bound_water_case.py +99 -0
  82. mdprep-0.4.0/tests/test_through_metal.py +100 -0
  83. mdprep-0.4.0/tests/test_water_transplant.py +382 -0
  84. mdprep-0.4.0/tests/test_web_builder_bound_water_case.py +130 -0
  85. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_web_builder_browser.py +3 -2
  86. mdprep-0.4.0/tests/test_web_builder_oligomer_case.py +165 -0
  87. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_web_builder_reference_case.py +3 -0
  88. {mdprep-0.3.0 → mdprep-0.4.0}/web/README.md +11 -0
  89. {mdprep-0.3.0 → mdprep-0.4.0}/web/app.js +92 -13
  90. {mdprep-0.3.0 → mdprep-0.4.0}/web/index.html +24 -8
  91. {mdprep-0.3.0 → mdprep-0.4.0}/web/style.css +20 -0
  92. mdprep-0.3.0/CONTRIBUTING.md +0 -58
  93. mdprep-0.3.0/examples/mdprep_colab_run.ipynb +0 -277
  94. mdprep-0.3.0/tests/test_colab_run_notebook.py +0 -125
  95. {mdprep-0.3.0 → mdprep-0.4.0}/.gitignore +0 -0
  96. {mdprep-0.3.0 → mdprep-0.4.0}/CITATION.cff +0 -0
  97. {mdprep-0.3.0 → mdprep-0.4.0}/LICENSE +0 -0
  98. {mdprep-0.3.0 → mdprep-0.4.0}/docs/developer_notes.md +0 -0
  99. {mdprep-0.3.0 → mdprep-0.4.0}/docs/installation.md +0 -0
  100. {mdprep-0.3.0 → mdprep-0.4.0}/docs/ligands.md +0 -0
  101. {mdprep-0.3.0 → mdprep-0.4.0}/docs/mcpb_xtb_benchmark.md +0 -0
  102. {mdprep-0.3.0 → mdprep-0.4.0}/docs/protonation.md +0 -0
  103. {mdprep-0.3.0 → mdprep-0.4.0}/docs/qmmesp_pyscf.md +0 -0
  104. {mdprep-0.3.0 → mdprep-0.4.0}/docs/qmmm_refinement.md +0 -0
  105. {mdprep-0.3.0 → mdprep-0.4.0}/docs/quickstart.md +0 -0
  106. {mdprep-0.3.0 → mdprep-0.4.0}/environment-dev.yml +0 -0
  107. {mdprep-0.3.0 → mdprep-0.4.0}/environment-minimal.yml +0 -0
  108. {mdprep-0.3.0 → mdprep-0.4.0}/environment.yml +0 -0
  109. {mdprep-0.3.0 → mdprep-0.4.0}/examples/00_basic_protein.yaml +0 -0
  110. {mdprep-0.3.0 → mdprep-0.4.0}/examples/01_protein_only_ff19sb.yaml +0 -0
  111. {mdprep-0.3.0 → mdprep-0.4.0}/examples/02_manual_catalytic_protonation.yaml +0 -0
  112. {mdprep-0.3.0 → mdprep-0.4.0}/examples/03_multi_ligand_am1bcc.yaml +0 -0
  113. {mdprep-0.3.0 → mdprep-0.4.0}/examples/04_qmmesp_pyscf_ligand.yaml +0 -0
  114. {mdprep-0.3.0 → mdprep-0.4.0}/examples/05_histidine_gxtb_sp.yaml +0 -0
  115. {mdprep-0.3.0 → mdprep-0.4.0}/examples/06_disulfide_manual.yaml +0 -0
  116. {mdprep-0.3.0 → mdprep-0.4.0}/examples/07_gas_resp_pyscf_ligand.yaml +0 -0
  117. {mdprep-0.3.0 → mdprep-0.4.0}/examples/08_nonbonded_zinc_1264.yaml +0 -0
  118. {mdprep-0.3.0 → mdprep-0.4.0}/examples/09_bonded_zinc_mcpb_prepare.yaml +0 -0
  119. {mdprep-0.3.0 → mdprep-0.4.0}/examples/10_qmmm_refinement_ash.yaml +0 -0
  120. {mdprep-0.3.0 → mdprep-0.4.0}/examples/11_qmmm_metal_gfn2_mcpb.yaml +0 -0
  121. {mdprep-0.3.0 → mdprep-0.4.0}/examples/12_qmmm_metal_mace_polar1_mcpb.yaml +0 -0
  122. {mdprep-0.3.0 → mdprep-0.4.0}/examples/13_qmmm_refinement_gxtb_mechanical.yaml +0 -0
  123. {mdprep-0.3.0 → mdprep-0.4.0}/examples/14_qmmm_refinement_mace_polar1_mechanical.yaml +0 -0
  124. {mdprep-0.3.0 → mdprep-0.4.0}/examples/15_roe_brooks_openmm.yaml +0 -0
  125. {mdprep-0.3.0 → mdprep-0.4.0}/examples/16_besd_halogenase_gfn2_mcpb.yaml +0 -0
  126. {mdprep-0.3.0 → mdprep-0.4.0}/examples/colab/mdprep_colab_pipeline.py +0 -0
  127. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/_selftest_data/basic_protein.yaml +0 -0
  128. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/_selftest_data/ligand_sub.mol2 +0 -0
  129. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/ambertools/__init__.py +0 -0
  130. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/ambertools/antechamber.py +0 -0
  131. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/ambertools/commands.py +0 -0
  132. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/ambertools/mol2.py +0 -0
  133. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/ambertools/parmchk2.py +0 -0
  134. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/ambertools/resp.py +0 -0
  135. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/charges/__init__.py +0 -0
  136. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/charges/esp_grid.py +0 -0
  137. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/config/__init__.py +0 -0
  138. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/config/loader.py +0 -0
  139. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/external/__init__.py +0 -0
  140. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/external/discovery.py +0 -0
  141. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/external/runner.py +0 -0
  142. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/leap/__init__.py +0 -0
  143. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/leap/forcefields.py +0 -0
  144. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/leap/ions.py +0 -0
  145. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/leap/log_parser.py +0 -0
  146. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/leap/runner.py +0 -0
  147. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/ligands/__init__.py +0 -0
  148. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/ligands/extract.py +0 -0
  149. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/ligands/hydrogenate.py +0 -0
  150. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/ligands/identity.py +0 -0
  151. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/ligands/pyscf_charges.py +0 -0
  152. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/ligands/report.py +0 -0
  153. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/md/__init__.py +0 -0
  154. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/md/imaging.py +0 -0
  155. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/metals/__init__.py +0 -0
  156. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/metals/c4.py +0 -0
  157. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/metals/gxtb_hessian.py +0 -0
  158. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/metals/hydrogenate.py +0 -0
  159. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/metals/mace_polar1_hessian.py +0 -0
  160. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/metals/mace_polar1_worker.py +0 -0
  161. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/metals/mcpb_compat.py +0 -0
  162. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/metals/nonbonded.py +0 -0
  163. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/metals/parameter_comparison.py +0 -0
  164. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/metals/pyscf_mcpb.py +0 -0
  165. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/protonation/__init__.py +0 -0
  166. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/protonation/apply.py +0 -0
  167. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/protonation/disulfide_states.py +0 -0
  168. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/protonation/histidine_geometry.py +0 -0
  169. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/protonation/histidine_qmmm.py +0 -0
  170. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/protonation/overrides.py +0 -0
  171. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/protonation/pka_rules.py +0 -0
  172. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/protonation/propka.py +0 -0
  173. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/protonation/propka_parser.py +0 -0
  174. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/protonation/report.py +0 -0
  175. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/protonation/states.py +0 -0
  176. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/protonation/temporary_hydrogenation.py +0 -0
  177. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/protonation/xtb_parser.py +0 -0
  178. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/protonation/xtb_runner.py +0 -0
  179. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/qm/__init__.py +0 -0
  180. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/qm/point_charges.py +0 -0
  181. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/qm/pyscf_esp.py +0 -0
  182. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/qm/pyscf_runner.py +0 -0
  183. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/qm/xtb_esp.py +0 -0
  184. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/refinement/__init__.py +0 -0
  185. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/refinement/ash.py +0 -0
  186. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/refinement/coordinates.py +0 -0
  187. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/refinement/mapping.py +0 -0
  188. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/refinement/openmm_minimizer.py +0 -0
  189. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/refinement/report.py +0 -0
  190. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/refinement/workflow.py +0 -0
  191. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/reports/__init__.py +0 -0
  192. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/structure/__init__.py +0 -0
  193. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/structure/completeness.py +0 -0
  194. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/structure/disulfides.py +0 -0
  195. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/structure/mmcif.py +0 -0
  196. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/structure/models.py +0 -0
  197. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/structure/pdb_fields.py +0 -0
  198. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/structure/reader.py +0 -0
  199. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/structure/rename.py +0 -0
  200. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/structure/repair.py +0 -0
  201. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/structure/selectors.py +0 -0
  202. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/validation/__init__.py +0 -0
  203. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/validation/openmm_check.py +0 -0
  204. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/validation/parmed_check.py +0 -0
  205. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/workflows/__init__.py +0 -0
  206. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/workflows/init.py +0 -0
  207. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/workflows/inspect.py +0 -0
  208. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/workflows/prepare.py +0 -0
  209. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/workflows/selftest.py +0 -0
  210. {mdprep-0.3.0 → mdprep-0.4.0}/src/mdprep/workflows/validate.py +0 -0
  211. {mdprep-0.3.0 → mdprep-0.4.0}/tests/__init__.py +0 -0
  212. {mdprep-0.3.0 → mdprep-0.4.0}/tests/besd_structure.py +0 -0
  213. {mdprep-0.3.0 → mdprep-0.4.0}/tests/browser/launch.mjs +0 -0
  214. {mdprep-0.3.0 → mdprep-0.4.0}/tests/browser/smoke.mjs +0 -0
  215. {mdprep-0.3.0 → mdprep-0.4.0}/tests/browser/student_flow.mjs +0 -0
  216. {mdprep-0.3.0 → mdprep-0.4.0}/tests/conftest.py +0 -0
  217. {mdprep-0.3.0 → mdprep-0.4.0}/tests/data/amber/README.md +0 -0
  218. {mdprep-0.3.0 → mdprep-0.4.0}/tests/data/amber/ace_ala_gly_nme.inpcrd +0 -0
  219. {mdprep-0.3.0 → mdprep-0.4.0}/tests/data/amber/ace_ala_gly_nme.prmtop +0 -0
  220. {mdprep-0.3.0 → mdprep-0.4.0}/tests/data/boltz_far_donor.cif +0 -0
  221. {mdprep-0.3.0 → mdprep-0.4.0}/tests/data/boltz_model.cif +0 -0
  222. {mdprep-0.3.0 → mdprep-0.4.0}/tests/data/boltz_smiles_ligands.cif +0 -0
  223. {mdprep-0.3.0 → mdprep-0.4.0}/tests/data/boltz_wide_names.cif +0 -0
  224. {mdprep-0.3.0 → mdprep-0.4.0}/tests/data/ligands/ligand_cof.frcmod +0 -0
  225. {mdprep-0.3.0 → mdprep-0.4.0}/tests/data/ligands/ligand_cof.good.mol2 +0 -0
  226. {mdprep-0.3.0 → mdprep-0.4.0}/tests/data/ligands/ligand_sub.atom_count_mismatch.mol2 +0 -0
  227. {mdprep-0.3.0 → mdprep-0.4.0}/tests/data/ligands/ligand_sub.bad_charge.mol2 +0 -0
  228. {mdprep-0.3.0 → mdprep-0.4.0}/tests/data/ligands/ligand_sub.frcmod +0 -0
  229. {mdprep-0.3.0 → mdprep-0.4.0}/tests/data/ligands/ligand_sub.good.mol2 +0 -0
  230. {mdprep-0.3.0 → mdprep-0.4.0}/tests/data/ligands/ligand_sub.pdb +0 -0
  231. {mdprep-0.3.0 → mdprep-0.4.0}/tests/data/ligands/ligand_sub.renamed.mol2 +0 -0
  232. {mdprep-0.3.0 → mdprep-0.4.0}/tests/data/ligands/ligand_sub.shifted_coords.mol2 +0 -0
  233. {mdprep-0.3.0 → mdprep-0.4.0}/tests/data/ligands/ligand_sub.small_residual.mol2 +0 -0
  234. {mdprep-0.3.0 → mdprep-0.4.0}/tests/data/propka_sample.pka +0 -0
  235. {mdprep-0.3.0 → mdprep-0.4.0}/tests/data/protein_altloc.pdb +0 -0
  236. {mdprep-0.3.0 → mdprep-0.4.0}/tests/data/protein_atom_record_ligand_blank_chain.pdb +0 -0
  237. {mdprep-0.3.0 → mdprep-0.4.0}/tests/data/protein_blank_chain.pdb +0 -0
  238. {mdprep-0.3.0 → mdprep-0.4.0}/tests/data/protein_cyx_disulfide.pdb +0 -0
  239. {mdprep-0.3.0 → mdprep-0.4.0}/tests/data/protein_disulfide.pdb +0 -0
  240. {mdprep-0.3.0 → mdprep-0.4.0}/tests/data/protein_histidine_ring.pdb +0 -0
  241. {mdprep-0.3.0 → mdprep-0.4.0}/tests/data/protein_histidine_ring_hydrogenated.pdb +0 -0
  242. {mdprep-0.3.0 → mdprep-0.4.0}/tests/data/protein_histidine_water_oxygen.pdb +0 -0
  243. {mdprep-0.3.0 → mdprep-0.4.0}/tests/data/protein_histidine_zinc.pdb +0 -0
  244. {mdprep-0.3.0 → mdprep-0.4.0}/tests/data/protein_insertion_code.pdb +0 -0
  245. {mdprep-0.3.0 → mdprep-0.4.0}/tests/data/protein_two_ligands.pdb +0 -0
  246. {mdprep-0.3.0 → mdprep-0.4.0}/tests/data/protein_with_hydrogenated_free_lysine.pdb +0 -0
  247. {mdprep-0.3.0 → mdprep-0.4.0}/tests/data/protein_with_hydrogens.pdb +0 -0
  248. {mdprep-0.3.0 → mdprep-0.4.0}/tests/data/protein_with_waters.pdb +0 -0
  249. {mdprep-0.3.0 → mdprep-0.4.0}/tests/data/protein_zinc_aqua.pdb +0 -0
  250. {mdprep-0.3.0 → mdprep-0.4.0}/tests/data/xtb_hid_stdout.txt +0 -0
  251. {mdprep-0.3.0 → mdprep-0.4.0}/tests/data/xtb_hie_stdout.txt +0 -0
  252. {mdprep-0.3.0 → mdprep-0.4.0}/tests/data/zinc_only.pdb +0 -0
  253. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_altloc.py +0 -0
  254. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_amber_resp.py +0 -0
  255. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_ambertools_commands.py +0 -0
  256. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_browser_planning_path.py +0 -0
  257. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_build_residues_is_defined_once.py +0 -0
  258. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_classify.py +0 -0
  259. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_cli.py +0 -0
  260. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_colab_wizard_notebook.py +0 -0
  261. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_config_examples.py +0 -0
  262. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_config_validation.py +0 -0
  263. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_coordinating_ions.py +0 -0
  264. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_disulfide_assignment.py +0 -0
  265. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_disulfide_leap_mapping.py +0 -0
  266. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_disulfides.py +0 -0
  267. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_esp_grid.py +0 -0
  268. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_external_amber_resp.py +0 -0
  269. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_external_ambertools.py +0 -0
  270. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_external_gxtb_hessian.py +0 -0
  271. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_external_mace_polar1.py +0 -0
  272. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_external_md_restraint_frame.py +0 -0
  273. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_external_md_snapshot_box.py +0 -0
  274. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_external_metals.py +0 -0
  275. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_external_propka_xtb.py +0 -0
  276. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_external_pyscf.py +0 -0
  277. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_external_structure_repair.py +0 -0
  278. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_external_tleap.py +0 -0
  279. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_external_xtb_embedding.py +0 -0
  280. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_gxtb_hessian.py +0 -0
  281. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_histidine_cluster_metal.py +0 -0
  282. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_histidine_geometry.py +0 -0
  283. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_histidine_qmmm.py +0 -0
  284. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_import.py +0 -0
  285. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_init_cli.py +0 -0
  286. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_init_ligand_placeholders.py +0 -0
  287. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_inspect_cli.py +0 -0
  288. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_ions.py +0 -0
  289. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_leap_forcefields.py +0 -0
  290. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_leap_input_pdb.py +0 -0
  291. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_leap_ligand_residue_names.py +0 -0
  292. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_leap_log_parser.py +0 -0
  293. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_ligand_extraction.py +0 -0
  294. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_ligand_hydrogenation.py +0 -0
  295. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_ligand_mol2_validation.py +0 -0
  296. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_ligand_workflow_mocked.py +0 -0
  297. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_mace_polar1_hessian.py +0 -0
  298. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_manifest_paths.py +0 -0
  299. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_manual_protonation.py +0 -0
  300. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_mcpb_compat.py +0 -0
  301. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_mcpb_parameter_comparison.py +0 -0
  302. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_mcpb_pyscf_fixed_geometry.py +0 -0
  303. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_md_config.py +0 -0
  304. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_md_imaging.py +0 -0
  305. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_metal_hydrogenation_preservation.py +0 -0
  306. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_mmcif.py +0 -0
  307. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_mol2_parser.py +0 -0
  308. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_mol2_validation.py +0 -0
  309. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_no_openbabel.py +0 -0
  310. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_pdb_large_serials.py +0 -0
  311. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_pdb_parser.py +0 -0
  312. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_pdb_roundtrip_property.py +0 -0
  313. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_pka_rules.py +0 -0
  314. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_point_charges.py +0 -0
  315. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_prediction_pdb_quirks.py +0 -0
  316. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_prepare_ligands_stage.py +0 -0
  317. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_prepare_protonation_stage.py +0 -0
  318. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_prepare_pyscf_ligands_stage.py +0 -0
  319. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_prepare_refinement_stage.py +0 -0
  320. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_prepare_structure_stage.py +0 -0
  321. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_prepare_tleap_stage.py +0 -0
  322. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_propka_parser.py +0 -0
  323. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_protonation_propka_workflow.py +0 -0
  324. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_protonation_reuse_refined.py +0 -0
  325. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_protonation_states.py +0 -0
  326. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_protonation_xtb_workflow.py +0 -0
  327. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_pyscf_esp_mocked.py +0 -0
  328. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_pyscf_runner_config.py +0 -0
  329. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_qm_region_spin_state.py +0 -0
  330. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_qmmesp_correctness.py +0 -0
  331. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_qmmesp_final_mol2_usage.py +0 -0
  332. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_qmmesp_no_environment_fit.py +0 -0
  333. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_readme_example.py +0 -0
  334. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_refinement_ash.py +0 -0
  335. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_refinement_config.py +0 -0
  336. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_refinement_coordinates.py +0 -0
  337. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_refinement_openmm.py +0 -0
  338. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_refinement_platform.py +0 -0
  339. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_refinement_report.py +0 -0
  340. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_refinement_selection.py +0 -0
  341. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_remove_hydrogens.py +0 -0
  342. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_residue_rename.py +0 -0
  343. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_roe_brooks_restraints.py +0 -0
  344. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_runtime_requirements_cover_every_option.py +0 -0
  345. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_selectors.py +0 -0
  346. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_selftest_installed.py +0 -0
  347. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_structure_normalize.py +0 -0
  348. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_structure_repair_inputs.py +0 -0
  349. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_temporary_hydrogenation_hold_back.py +0 -0
  350. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_tleap_workflow_mocked.py +0 -0
  351. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_validation_helpers.py +0 -0
  352. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_validation_topology.py +0 -0
  353. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_web_bundle_zip.py +0 -0
  354. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_xtb_command_builder.py +0 -0
  355. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_xtb_esp.py +0 -0
  356. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_xtb_parser.py +0 -0
  357. {mdprep-0.3.0 → mdprep-0.4.0}/tests/test_xtb_water_hydrogens.py +0 -0
  358. {mdprep-0.3.0 → mdprep-0.4.0}/web/.gitignore +0 -0
  359. {mdprep-0.3.0 → mdprep-0.4.0}/web/build.py +0 -0
  360. {mdprep-0.3.0 → mdprep-0.4.0}/web/zip.js +0 -0
@@ -65,8 +65,9 @@ Explicitly unsupported for v0.2:
65
65
  - covalent ligands
66
66
  - ORCA backend
67
67
  - Multiwfn dependency
68
- - multiple independent bonded MCPB sites
69
- - multi-chain MCPB protein inputs
68
+ - multiple independent bonded MCPB sites (copies of one site in an oligomer
69
+ share a single fit through `parameters_from`; see `docs/oligomers.md`)
70
+ - bonded MCPB sites bound by more than one protein chain
70
71
 
71
72
  ## Required Checks
72
73
 
@@ -1,5 +1,153 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.4.0 - 2026-10-20
4
+
5
+ ### Added
6
+
7
+ - Dimers, trimers and tetramers. Every protein chain can be prepared in one
8
+ system, and when the chains are copies of one protein the builder asks
9
+ whether every copy should get the same parameters. If so it asks about the
10
+ first copy only and gives each answer to the matching residue of the others,
11
+ matched by sequence and by position rather than by residue number, which
12
+ copies often do not share (2FCT numbers its two alpha-ketoglutarates 897 and
13
+ 898). A ligand is parameterised once; a bonded metal site is fitted once with
14
+ MCPB.py, and each copy's residues take the fit's templates and its metal the
15
+ fit's bonds. A copy whose site differs -- 6NIE's chains B and C bind
16
+ alpha-ketoglutarate through the other carboxylate oxygen -- is reported and
17
+ asked about on its own. See `docs/oligomers.md`.
18
+ - `parameters_from` on ligands and metal sites: a block built with another
19
+ block's parameters, checked by `config-check` to repeat its settings and, for
20
+ a bonded site, to list its residues in the reference's order.
21
+ - `examples/18_syrb2_dimer_shared_mcpb.yaml`: both copies of SyrB2, one fit.
22
+ - `mdprep.analysis.charges.metal_sites`: each metal site's charge on its own,
23
+ which the official notebook now shows one table per site.
24
+ - The web builder lists which chains are copies of one protein, shows the
25
+ chain and copy questions with each chain in its own colour, and names
26
+ residues with their chain.
27
+ - Refusals the answers already make certain are given at the question that
28
+ causes them, in the web builder and in `mdprep init --interactive`: a second
29
+ bonded metal site needing a fit of its own, or a cofactor whose charges were
30
+ to come from a site made nonbonded. Every `DecisionError` names the question
31
+ to go back to (`decision_id`), and the page goes there.
32
+
33
+ - The official Colab notebook, `examples/mdprep_colab.ipynb`: takes a bundle
34
+ from the web builder (or runs the SyrB2 example), prepares and equilibrates
35
+ the system, and shows every step -- the structure after each stage, the
36
+ protonation states, the charge on every atom in tables and in 3D, the metal
37
+ site's MCPB force constants, how temperature, density and volume
38
+ equilibrated, the structure after each Roe-Brooks step, and the trajectory
39
+ with its RMSD, RMSF and metal-site distances. The web builder links to it.
40
+ - `mdprep closest-xray`: the X-ray structures closest to a predicted model,
41
+ from the RCSB sequence search, with resolution, waters and bound ligands;
42
+ those holding the model's metal come first.
43
+ - `mdprep transplant-waters`: a reference structure's crystal waters on a
44
+ predicted model. PyMOL pairs the residues (by sequence, or by structure for a
45
+ distant homologue); each model chain takes its best reference chain; a water
46
+ bound to a metal moves with it onto the model's metal; clashing and bulk
47
+ waters are dropped; a reference of another fold is refused. Every decision
48
+ is in a JSON report.
49
+ - `mdprep.analysis`: reads a prmtop, inpcrd and OpenMM DCD with numpy alone,
50
+ and provides charge tables, the metal site's force constants, imaged and
51
+ superposed trajectories, RMSD, RMSF and distances, and the equilibration and
52
+ production logs.
53
+ - `equilibration.csv` in every Roe-Brooks run: every stage on one time axis,
54
+ with temperature, density, box volume and energies every 0.5 ps.
55
+ - `docs/predicted_structures.md`: from a Boltz or AlphaFold3 prediction to a
56
+ model with its crystal waters, with the worked SyrB2 example.
57
+ - `examples/17_syrb2_bound_water_mcpb.yaml` and the vendored 2FCT deposition.
58
+ - When a structure with a metal has no waters at all, the metal question says
59
+ so and points to `mdprep transplant-waters`.
60
+
61
+ - Waters bound to a bonded metal site, as the resting iron of an
62
+ alpha-ketoglutarate enzyme carries (SyrB2, PDB 2FCT). The decision engine
63
+ proposes the water as a donor; mdprep writes the TIP3P template MCPB.py
64
+ requires, supplies the H-O-H angle rigid TIP3P lacks, and counts the water as
65
+ neutral in the QM/MM refinement.
66
+ - `structure.keep_crystal_ions` and its question: free monatomic ions resolved
67
+ in the crystal (Cl-, Na+, Br-, ...) are kept or removed as a group, and
68
+ listed in the structure report either way.
69
+
70
+ ### Changed
71
+
72
+ - **Free crystal ions are kept by default.** A free monatomic ion in the input
73
+ used to count as an unknown heterogen, so a manifest with
74
+ `structure.remove_unknown_heterogens: true` dropped it. It is now governed by
75
+ `structure.keep_crystal_ions`, which defaults to `true`, so the same manifest
76
+ builds with the ion in place: 2FCT's free chloride, for one. Add
77
+ `keep_crystal_ions: false` to keep the old result. Every ion kept or removed
78
+ is listed in `reports/structure_report.md`.
79
+ - Two bonded metal sites are refused by `mdprep config-check`, where 0.3.0
80
+ refused them only once a run had started.
81
+
82
+ ### Fixed
83
+
84
+ - CUDA did not start on Colab's T4 GPUs (OpenCL did):
85
+ - conda-forge installed a CUDA runtime newer than the GPU driver, whose
86
+ kernels the driver refused (`CUDA_ERROR_UNSUPPORTED_PTX_VERSION`);
87
+ - the setup the notebook and the web builder run now caps `cuda-version`
88
+ at the driver's version, and rerunning section C repairs an existing
89
+ environment;
90
+ - `mdprep doctor` starts a CUDA system to check;
91
+ - a CUDA failure in the MD says what to do, and `auto` says which
92
+ platform it passed over.
93
+ - The official notebook drew the final structure (E3) from tleap's PDB, which
94
+ has no elements, so the viewer read hydrogens such as HG21 as mercury and
95
+ bonded them to everything near. It is now drawn from the topology, as E8
96
+ and H are. Each protein molecule is now its own chain in every view, so no
97
+ cartoon runs from one copy of a dimer into the next or across a missing
98
+ loop. A chloride on the iron, one atom with no bond to draw, now shows as a
99
+ sphere.
100
+ - Keeping one chain of a predicted oligomer kept every ligand chain too, so the
101
+ other copy's iron and cofactor floated in the box. A chain holding only
102
+ heterogens now goes with the protein chain it sits against.
103
+ - The spin of the QM region was asked of any structure with two metals, even
104
+ when neither turned out bonded; it is now asked once a bonded site is
105
+ confirmed, whichever site that is.
106
+ - `DecisionPlan.applicable` counted an answer whose own question was no longer
107
+ reachable -- a shell confirmed before the site was switched to nonbonded.
108
+ - The ligand coordinate check after tleap could not tell two copies of one
109
+ cofactor apart, since tleap renumbers residues; it now takes the copy nearest
110
+ the ligand it checks.
111
+ - The web builder and the wizard told a student to add a SMILES to a ligand
112
+ without hydrogens after asking for it and being given it.
113
+ - `mdprep init --interactive` re-asked a rejected answer without saying why.
114
+
115
+ - A residue name mdprep assigned (a predicted iron called `LIG1` read as `FE`)
116
+ lost that record when the structure was written and read back, and `FE` read
117
+ cold is the CCD code for Fe(III): the planner then proposed +3 for an Fe(II)
118
+ site. mdprep's PDB writer records assigned names in a remark its reader
119
+ honours.
120
+ - The model-charge proposal ignored an oxidation state accepted as proposed,
121
+ so a student added the terms up by hand.
122
+ - The old Colab run notebook ran the MD twice: `mdprep prepare` already runs it
123
+ when the manifest enables it. It now points to the official notebook, which
124
+ stops `prepare` before the MD.
125
+ - A free crystal chloride was offered as a ligand and then refused as a
126
+ reserved residue name, telling the user to rename it. tleap builds it from
127
+ its ion library like any counterion; it is no longer a ligand candidate, and
128
+ a histidine xTB cluster that contains one counts its charge.
129
+ - A topology with a water and a halide on the same metal went to NaN in
130
+ heating: their 1-4 pair through the metal had a Coulomb attraction and no
131
+ repulsion. Those 1-4 terms are now switched off in the prmtop and listed in
132
+ the tleap report.
133
+ - tleap bonded the two ends of an unresolved loop into one peptide bond, 6.08 A
134
+ long in 2FCT. A TER is now written wherever C(i)-N(i+1) exceeds 2 A.
135
+ - The crystal-water and unknown-heterogen questions disappeared whenever any
136
+ water coordinated any metal -- in 6NIE, three waters on a surface iron of
137
+ chain B hid the question for all 847. Both are asked now, and the
138
+ crystal-water question names the bound waters that are kept regardless.
139
+ - A water bound to a metal was dropped with the other crystal waters when
140
+ those were removed: for a bonded site that left an MCPB bond to a residue
141
+ that no longer existed, and for a nonbonded one it stripped the ion's first
142
+ shell, though the question had said it would stay. The question and
143
+ normalisation now share one definition of a bound water
144
+ (`mdprep.structure.coordination`).
145
+ - Declining a ligand while keeping unknown heterogens, dropping crystal waters
146
+ with a bonded site, or choosing OPC with a water bound to a bonded metal now
147
+ fail in the builder with what to change, instead of later in Colab.
148
+ - The QM-region spin proposal ignored defaults the user had accepted without
149
+ typing them, so a bonded iron with the default model got no proposal.
150
+
3
151
  ## 0.3.0 - 2026-10-19
4
152
 
5
153
  ### Added
@@ -0,0 +1,115 @@
1
+ # Contributing
2
+
3
+ ## Setup
4
+
5
+ ```bash
6
+ mamba env create -f environment.yml
7
+ conda activate mdprep
8
+ pip install -e .
9
+ mdprep selftest --quick
10
+ ```
11
+
12
+ For packaging and lint tooling, use `environment-dev.yml` or install the
13
+ `dev` extra in a suitable environment.
14
+
15
+ ## Tests
16
+
17
+ Default tests must not require AmberTools, xTB, PropKa, PySCF, ParmEd, or
18
+ OpenMM:
19
+
20
+ ```bash
21
+ pytest -q
22
+ python -m mdprep.cli config-check examples/*.yaml
23
+ python -m mdprep.cli selftest --quick
24
+ ```
25
+
26
+ External tests must skip cleanly when optional tools are unavailable:
27
+
28
+ ```bash
29
+ pytest -q -m "external"
30
+ pytest -q -m "external or ambertools or tleap or propka or xtb or pyscf or qmmesp"
31
+ ```
32
+
33
+ ## Chemistry Rules
34
+
35
+ - The legacy molecule-conversion toolkit identified by the dedicated ban test
36
+ is intentionally prohibited.
37
+ - Do not add molecule-conversion fallbacks.
38
+ - User overrides always win.
39
+ - Do not silently guess catalytic chemistry, ligand charge, protonation, or
40
+ metal-center behavior.
41
+ - Every chemical decision and every residue rename must be reported.
42
+ - Unsupported chemistry must fail with a clear error.
43
+ - External commands must go through `mdprep.external.runner`.
44
+
45
+ ## QMMESP Rules
46
+
47
+ - MM point charges polarize only the selected target ligand QM density.
48
+ - The RESP/ESP fit is performed only on target ligand atoms.
49
+ - Environment point charges must not be fitted.
50
+ - Environment point charges must not be written to ligand mol2 files.
51
+ - The final Amber system must use final PySCF-fitted mol2 charges, not
52
+ provisional charges.
53
+
54
+ ## Adding Features
55
+
56
+ New user-facing features need docs, tests, examples when practical, and clear
57
+ failure behavior for unsupported chemistry. Keep changes local to the relevant
58
+ workflow stage and avoid broad rewrites unless there is a tested reason.
59
+
60
+ ## Releasing
61
+
62
+ Publishing is automatic and tokenless. `.github/workflows/release.yml` fires
63
+ on a `v*` tag and uploads to PyPI through Trusted Publishing, so no API token
64
+ exists to leak or rotate. PyPI is configured to trust this repository, this
65
+ workflow file by name, and the `pypi` environment; renaming either breaks
66
+ publishing until the publisher at
67
+ <https://pypi.org/manage/project/mdprep/settings/publishing/> is updated.
68
+
69
+ To cut a release:
70
+
71
+ 1. Bump the version in `pyproject.toml` and `src/mdprep/__init__.py`, and in
72
+ the README's first line. `tests/test_packaging_metadata.py` fails if the
73
+ first two disagree.
74
+ 2. Retitle the changelog's `## Unreleased` section to `## <version> - <date>`.
75
+ The workflow refuses a tag with no such heading.
76
+ 3. Update the `mdprep[md,qm]==` pin in `examples/*.ipynb` and the assertion in
77
+ `tests/test_colab_smoke_notebook.py`. The web builder installs from git
78
+ master and needs no bump.
79
+ 4. Execute the official notebook end to end (below) and fix whatever it
80
+ finds: it is what students run, and nothing else exercises it whole.
81
+ 5. Merge, then `git tag -a vX.Y.Z` and push the tag.
82
+
83
+ The workflow then refuses a tag that does not match the version in the tree,
84
+ builds, checks that the sdist carries the project and nothing that was lying
85
+ in the working tree, installs the wheel and runs `mdprep selftest --quick`
86
+ from it, publishes to PyPI, and attaches the same two files to the GitHub
87
+ release -- creating one from the changelog section if you have not written
88
+ one by hand.
89
+
90
+ Use semantic versioning against the *manifest*, not just the API: a change
91
+ that makes an existing manifest stop validating is breaking, whatever it did
92
+ to the Python surface.
93
+
94
+ ### Executing the official notebook outside Colab
95
+
96
+ `examples/mdprep_colab.ipynb` runs anywhere with a Linux GPU. Its uploads and
97
+ installs are redirected by environment variables, so a Python with mdprep,
98
+ `pymol-open-source-whl`, `py3Dmol`, `pandas`, `matplotlib` and `nbclient`
99
+ can execute it against a micromamba runtime built once:
100
+
101
+ ```bash
102
+ MDPREP_COLAB_PREFIX=/scratch/colab \
103
+ MDPREP_SKIP_KERNEL_INSTALL=1 \
104
+ MDPREP_SPEC=$PWD \
105
+ MDPREP_TEST_UPLOAD_MODEL=/path/to/predicted_model.cif \
106
+ MDPREP_TEST_UPLOAD_BUNDLE=/path/to/mdprep-bundle.zip \
107
+ python -c "import nbformat; from nbclient import NotebookClient; \
108
+ nb = nbformat.read('examples/mdprep_colab.ipynb', 4); \
109
+ NotebookClient(nb, timeout=5400).execute(); nbformat.write(nb, 'executed.ipynb')"
110
+ ```
111
+
112
+ `MDPREP_COLAB_PREFIX` stands in for `/content` (micromamba goes in its `bin/`,
113
+ the environment in `mamba-root/`), and `MDPREP_TEST_EXAMPLE_DIR=examples`
114
+ makes the SyrB2 example read the manifest from the checkout instead of GitHub.
115
+
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: mdprep
3
- Version: 0.3.0
3
+ Version: 0.4.0
4
4
  Summary: Reproducible Amber preparation for proteins, ligands, metal centers, and OpenMM MD.
5
5
  Project-URL: Homepage, https://github.com/miqueleg/mdprep
6
6
  Project-URL: Issues, https://github.com/miqueleg/mdprep/issues
@@ -52,7 +52,7 @@ Description-Content-Type: text/markdown
52
52
 
53
53
  # mdprep
54
54
 
55
- `mdprep` 0.3.0 prepares reproducible Amber molecular-dynamics systems from a
55
+ `mdprep` 0.4.0 prepares reproducible Amber molecular-dynamics systems from a
56
56
  PDB structure and a validated YAML manifest. It supports standard proteins,
57
57
  independent ligands and cofactors, explicit metal models, optional active-site
58
58
  QM/MM refinement, final `tleap` assembly, validation, and an optional OpenMM
@@ -72,6 +72,10 @@ recorded in the output reports.
72
72
  PySCF gas-phase RESP, or electrostatically embedded PySCF QMMESP charges.
73
73
  - Amber nonbonded metal models or bonded MCPB.py models with explicit
74
74
  coordinating atoms, charges, and multiplicities.
75
+ - Dimers, trimers, tetramers: every protein chain in one system. Copies of one
76
+ protein can share parameters -- asked about once, matched residue for
77
+ residue by sequence and position rather than number, and a bonded metal site
78
+ fitted once and reused in every copy ([docs/oligomers.md](docs/oligomers.md)).
75
79
  - MCPB Seminario Hessians from PySCF, GFN2-xTB, g-xTB, or MACE-POLAR-1;
76
80
  PySCF supplies the embedded large-model ESP/RESP calculation.
77
81
  - Optional ASH/OpenMM active-site QM/MM refinement before final
@@ -80,6 +84,11 @@ recorded in the output reports.
80
84
  topology, coordinate, charge, and optional OpenMM energy validation.
81
85
  - Optional Roe–Brooks OpenMM minimization, heating, density equilibration, and
82
86
  manifest-sized production MD with GPU-first/CPU-fallback execution.
87
+ - Predicted models: the closest X-ray structure from the RCSB, and its crystal
88
+ waters transplanted onto the model with PyMOL -- a water on the metal moves
89
+ with it.
90
+ - An official Colab notebook that prepares, equilibrates, and shows every step:
91
+ charges, metal-site parameters, the equilibration, the trajectory.
83
92
 
84
93
  ## Installation
85
94
 
@@ -191,22 +200,27 @@ Relative paths are resolved from the manifest directory. Unknown heterogens
191
200
  are not deleted or guessed: configure them under `ligands` or `metals`, or
192
201
  explicitly request their removal.
193
202
 
194
- For a guided 3D workflow, upload
195
- [`examples/mdprep_interactive_colab.ipynb`](examples/mdprep_interactive_colab.ipynb)
196
- to Google Colab. It accepts an RCSB PDB ID or uploaded PDB, requires review of
197
- all structural and chemistry decisions, creates a validated manifest, and can
198
- either download a portable input bundle or run mdprep in Colab. BesD PDB 7JSD
199
- is the default structural example; charges, spin states, and metal chemistry
200
- remain explicit user decisions. For bonded MCPB preparation, a dedicated cell
201
- installs the pinned official g-xTB Linux build and accepts it only after
202
- checksum verification and a successful `--gxtb --hess` smoke calculation. The
203
- guided metal workflow supports one explicitly bonded, single-chain MCPB site
204
- and can select either that g-xTB Hessian or PySCF B3LYP/6-31G*; every
205
- coordination bond remains explicitly selected. The notebook derives the MCPB
206
- small/large-model charge and multiplicity and the complete QM-region
207
- multiplicity from the reviewed component electronic states, displays the
208
- calculation, and refuses ambiguous multi-open-shell spin coupling rather than
209
- guessing it. All multi-selection fields use comma-separated values.
203
+ For a guided workflow, use the [web input builder](https://miqueleg.github.io/mdprep/):
204
+ it shows the structure in 3D, asks only the questions your structure needs, and
205
+ writes a validated manifest and a bundle. Then open the
206
+ [official Colab notebook](https://colab.research.google.com/github/miqueleg/mdprep/blob/master/examples/mdprep_colab.ipynb)
207
+ ([`examples/mdprep_colab.ipynb`](examples/mdprep_colab.ipynb)), upload the
208
+ bundle, and it installs what the manifest needs, prepares the system,
209
+ equilibrates it, and lets you investigate every step: the structure at each
210
+ stage, the protonation states, the charge on every atom, the metal site's
211
+ force constants, how the box equilibrated, and the MD trajectory.
212
+
213
+ No crystal structure of your protein? Predict the complex with its cofactors
214
+ (Boltz or AlphaFold3 in ColabFold), then let mdprep find the closest X-ray
215
+ structure and bring its crystal waters across -- including a water bound to
216
+ the metal, which a prediction never has:
217
+
218
+ ```bash
219
+ mdprep closest-xray model.cif
220
+ mdprep transplant-waters model.cif --reference 2FCT
221
+ ```
222
+
223
+ See [Predicted structures](docs/predicted_structures.md).
210
224
 
211
225
  ## Common workflows
212
226
 
@@ -254,7 +268,9 @@ specified in steps in the manifest.
254
268
  | Metal centers and MCPB.py | [Metal centers](docs/metals.md) | `examples/08_nonbonded_zinc_1264.yaml`, `09_bonded_zinc_mcpb_prepare.yaml` |
255
269
  | Active-site QM/MM refinement | [QM/MM refinement](docs/qmmm_refinement.md) | `examples/10_qmmm_refinement_ash.yaml` |
256
270
  | Roe–Brooks OpenMM MD | [Molecular dynamics](docs/molecular_dynamics.md) | `examples/15_roe_brooks_openmm.yaml` |
257
- | Running a manifest in Colab | [Colab example notes](examples/README.md) | `examples/mdprep_colab_run.ipynb` |
271
+ | Predicted models: closest X-ray, crystal waters | [Predicted structures](docs/predicted_structures.md) | `mdprep closest-xray`, `mdprep transplant-waters` |
272
+ | A water bound to a metal | [Metal centers](docs/metals.md#waters-bound-in-a-metal-site) | `examples/17_syrb2_bound_water_mcpb.yaml` |
273
+ | Preparing, running and investigating in Colab | [Colab example notes](examples/README.md) | `examples/mdprep_colab.ipynb` |
258
274
  | Guided Colab builder (legacy) | [Colab example notes](examples/README.md) | `examples/mdprep_interactive_colab.ipynb` |
259
275
  | Complete Fe(III) workflow | [7E07 tutorial](examples/tutorials/7E07_bonded_fe3/README.md) | `examples/tutorials/7E07_bonded_fe3/system.yaml` |
260
276
 
@@ -278,10 +294,12 @@ charge model, protonation, force field, QM method, or metal model.
278
294
 
279
295
  ## Current limitations
280
296
 
281
- Version 0.3.0 does not support noncanonical amino acids inside peptide chains,
282
- covalent ligands, mmCIF input, automatic loop modeling, ORCA, Multiwfn,
283
- multiple independent bonded MCPB sites, or multi-chain MCPB protein inputs.
284
- Unsupported chemistry fails explicitly.
297
+ mdprep does not support noncanonical amino acids inside peptide chains,
298
+ covalent ligands, automatic loop modeling (a missing loop is left as two
299
+ termini), a metal-bound hydroxide, ORCA, Multiwfn, more than one independently
300
+ fitted bonded MCPB site (copies of one site in an oligomer share a single
301
+ fit), or a bonded MCPB site bound by two chains. Unsupported chemistry fails
302
+ explicitly.
285
303
 
286
304
  ## Development and release checks
287
305
 
@@ -1,6 +1,6 @@
1
1
  # mdprep
2
2
 
3
- `mdprep` 0.3.0 prepares reproducible Amber molecular-dynamics systems from a
3
+ `mdprep` 0.4.0 prepares reproducible Amber molecular-dynamics systems from a
4
4
  PDB structure and a validated YAML manifest. It supports standard proteins,
5
5
  independent ligands and cofactors, explicit metal models, optional active-site
6
6
  QM/MM refinement, final `tleap` assembly, validation, and an optional OpenMM
@@ -20,6 +20,10 @@ recorded in the output reports.
20
20
  PySCF gas-phase RESP, or electrostatically embedded PySCF QMMESP charges.
21
21
  - Amber nonbonded metal models or bonded MCPB.py models with explicit
22
22
  coordinating atoms, charges, and multiplicities.
23
+ - Dimers, trimers, tetramers: every protein chain in one system. Copies of one
24
+ protein can share parameters -- asked about once, matched residue for
25
+ residue by sequence and position rather than number, and a bonded metal site
26
+ fitted once and reused in every copy ([docs/oligomers.md](docs/oligomers.md)).
23
27
  - MCPB Seminario Hessians from PySCF, GFN2-xTB, g-xTB, or MACE-POLAR-1;
24
28
  PySCF supplies the embedded large-model ESP/RESP calculation.
25
29
  - Optional ASH/OpenMM active-site QM/MM refinement before final
@@ -28,6 +32,11 @@ recorded in the output reports.
28
32
  topology, coordinate, charge, and optional OpenMM energy validation.
29
33
  - Optional Roe–Brooks OpenMM minimization, heating, density equilibration, and
30
34
  manifest-sized production MD with GPU-first/CPU-fallback execution.
35
+ - Predicted models: the closest X-ray structure from the RCSB, and its crystal
36
+ waters transplanted onto the model with PyMOL -- a water on the metal moves
37
+ with it.
38
+ - An official Colab notebook that prepares, equilibrates, and shows every step:
39
+ charges, metal-site parameters, the equilibration, the trajectory.
31
40
 
32
41
  ## Installation
33
42
 
@@ -139,22 +148,27 @@ Relative paths are resolved from the manifest directory. Unknown heterogens
139
148
  are not deleted or guessed: configure them under `ligands` or `metals`, or
140
149
  explicitly request their removal.
141
150
 
142
- For a guided 3D workflow, upload
143
- [`examples/mdprep_interactive_colab.ipynb`](examples/mdprep_interactive_colab.ipynb)
144
- to Google Colab. It accepts an RCSB PDB ID or uploaded PDB, requires review of
145
- all structural and chemistry decisions, creates a validated manifest, and can
146
- either download a portable input bundle or run mdprep in Colab. BesD PDB 7JSD
147
- is the default structural example; charges, spin states, and metal chemistry
148
- remain explicit user decisions. For bonded MCPB preparation, a dedicated cell
149
- installs the pinned official g-xTB Linux build and accepts it only after
150
- checksum verification and a successful `--gxtb --hess` smoke calculation. The
151
- guided metal workflow supports one explicitly bonded, single-chain MCPB site
152
- and can select either that g-xTB Hessian or PySCF B3LYP/6-31G*; every
153
- coordination bond remains explicitly selected. The notebook derives the MCPB
154
- small/large-model charge and multiplicity and the complete QM-region
155
- multiplicity from the reviewed component electronic states, displays the
156
- calculation, and refuses ambiguous multi-open-shell spin coupling rather than
157
- guessing it. All multi-selection fields use comma-separated values.
151
+ For a guided workflow, use the [web input builder](https://miqueleg.github.io/mdprep/):
152
+ it shows the structure in 3D, asks only the questions your structure needs, and
153
+ writes a validated manifest and a bundle. Then open the
154
+ [official Colab notebook](https://colab.research.google.com/github/miqueleg/mdprep/blob/master/examples/mdprep_colab.ipynb)
155
+ ([`examples/mdprep_colab.ipynb`](examples/mdprep_colab.ipynb)), upload the
156
+ bundle, and it installs what the manifest needs, prepares the system,
157
+ equilibrates it, and lets you investigate every step: the structure at each
158
+ stage, the protonation states, the charge on every atom, the metal site's
159
+ force constants, how the box equilibrated, and the MD trajectory.
160
+
161
+ No crystal structure of your protein? Predict the complex with its cofactors
162
+ (Boltz or AlphaFold3 in ColabFold), then let mdprep find the closest X-ray
163
+ structure and bring its crystal waters across -- including a water bound to
164
+ the metal, which a prediction never has:
165
+
166
+ ```bash
167
+ mdprep closest-xray model.cif
168
+ mdprep transplant-waters model.cif --reference 2FCT
169
+ ```
170
+
171
+ See [Predicted structures](docs/predicted_structures.md).
158
172
 
159
173
  ## Common workflows
160
174
 
@@ -202,7 +216,9 @@ specified in steps in the manifest.
202
216
  | Metal centers and MCPB.py | [Metal centers](docs/metals.md) | `examples/08_nonbonded_zinc_1264.yaml`, `09_bonded_zinc_mcpb_prepare.yaml` |
203
217
  | Active-site QM/MM refinement | [QM/MM refinement](docs/qmmm_refinement.md) | `examples/10_qmmm_refinement_ash.yaml` |
204
218
  | Roe–Brooks OpenMM MD | [Molecular dynamics](docs/molecular_dynamics.md) | `examples/15_roe_brooks_openmm.yaml` |
205
- | Running a manifest in Colab | [Colab example notes](examples/README.md) | `examples/mdprep_colab_run.ipynb` |
219
+ | Predicted models: closest X-ray, crystal waters | [Predicted structures](docs/predicted_structures.md) | `mdprep closest-xray`, `mdprep transplant-waters` |
220
+ | A water bound to a metal | [Metal centers](docs/metals.md#waters-bound-in-a-metal-site) | `examples/17_syrb2_bound_water_mcpb.yaml` |
221
+ | Preparing, running and investigating in Colab | [Colab example notes](examples/README.md) | `examples/mdprep_colab.ipynb` |
206
222
  | Guided Colab builder (legacy) | [Colab example notes](examples/README.md) | `examples/mdprep_interactive_colab.ipynb` |
207
223
  | Complete Fe(III) workflow | [7E07 tutorial](examples/tutorials/7E07_bonded_fe3/README.md) | `examples/tutorials/7E07_bonded_fe3/system.yaml` |
208
224
 
@@ -226,10 +242,12 @@ charge model, protonation, force field, QM method, or metal model.
226
242
 
227
243
  ## Current limitations
228
244
 
229
- Version 0.3.0 does not support noncanonical amino acids inside peptide chains,
230
- covalent ligands, mmCIF input, automatic loop modeling, ORCA, Multiwfn,
231
- multiple independent bonded MCPB sites, or multi-chain MCPB protein inputs.
232
- Unsupported chemistry fails explicitly.
245
+ mdprep does not support noncanonical amino acids inside peptide chains,
246
+ covalent ligands, automatic loop modeling (a missing loop is left as two
247
+ termini), a metal-bound hydroxide, ORCA, Multiwfn, more than one independently
248
+ fitted bonded MCPB site (copies of one site in an oligomer share a single
249
+ fit), or a bonded MCPB site bound by two chains. Unsupported chemistry fails
250
+ explicitly.
233
251
 
234
252
  ## Development and release checks
235
253
 
@@ -8,6 +8,8 @@
8
8
  - [Protonation](protonation.md)
9
9
  - [Ligands](ligands.md)
10
10
  - [Metal centers](metals.md)
11
+ - [Dimers, trimers and tetramers](oligomers.md)
12
+ - [Predicted structures](predicted_structures.md)
11
13
  - [MCPB Hessian-method benchmark](mcpb_xtb_benchmark.md)
12
14
  - [7E07 Fe(III) bonded-site tutorial](../examples/tutorials/7E07_bonded_fe3/README.md)
13
15
  - [QMMESP charges with PySCF](qmmesp_pyscf.md)
@@ -107,7 +107,16 @@ Each decision carries a stable `id`, the `question`, its `kind`
107
107
  (`choice`, `integer`, `number`, `text`, `boolean`), the allowed `choices`, the
108
108
  `default` (`null` when there is none), `requires_user_input`, the `evidence`
109
109
  from the structure, and a `when` list naming the earlier answers that make it
110
- relevant.
110
+ relevant. A decision is asked when every condition in `when` holds and, if its
111
+ `when_any` list is not empty, at least one condition there does too; an answer
112
+ counts only while its own question is still asked.
113
+
114
+ In a structure with several copies of one protein, a copy's questions carry
115
+ `copy_of`: the id of the same question about the counterpart residue in the
116
+ first copy. They are skipped when the copies share parameters
117
+ (`structure.same_parametrization`), and `build_manifest` gives them that
118
+ question's answer. A front end needs to do nothing about this beyond
119
+ honouring `when_any`; see [oligomers.md](oligomers.md).
111
120
 
112
121
  ### Driving a 3D viewer
113
122
 
@@ -115,8 +124,11 @@ Each decision also says what a viewer should put on screen while it is being
115
124
  answered:
116
125
 
117
126
  - `focus` is `none` (no structural aspect, such as a project name),
118
- `targets` (emphasise and frame the residues below), or `structure` (show the
119
- whole system, as for the force field or the solvent box).
127
+ `targets` (emphasise and frame the residues below), `structure` (show the
128
+ whole system, as for the force field or the solvent box), or `chains` (the
129
+ whole system with each chain in its own colour and the residues below
130
+ emphasised in every copy, as for which chains to keep and whether copies
131
+ match).
120
132
  - `targets` lists the residues to highlight, each with `chain`, `resname`,
121
133
  `resid`, `icode`, and `element`/`atom_name` where they apply. **`targets[0]`
122
134
  is the subject of the decision** -- the ligand being charged, the ion being
@@ -150,3 +162,12 @@ manifest = build_manifest(plan, answers) # raises if a blocking answer is missi
150
162
  `build_manifest` returns a plain dictionary, and raises `DecisionError` rather
151
163
  than defaulting anything a user was supposed to decide. That guarantee is what
152
164
  makes it safe to put a graphical front end in front of mdprep at all.
165
+
166
+ A `DecisionError` carries `decision_id`, the question whose answer would
167
+ resolve it, when there is one; the web builder takes the user back to it.
168
+ Some refusals are certain before the last question -- a second bonded metal
169
+ site that would need an MCPB fit of its own, or a cofactor whose charges were
170
+ to come from a site that is no longer bonded. `answer_conflicts(plan,
171
+ answers)` returns that refusal as soon as the answers given make it certain,
172
+ so a front end can say so at the question that caused it, as the web builder
173
+ and `mdprep init --interactive` do.
@@ -30,11 +30,18 @@ relative executable path when needed.
30
30
 
31
31
  ## structure
32
32
 
33
- - `keep_chains`: chains to build; empty keeps all. Naming one chain is required
34
- for a bonded MCPB metal site, whose inputs are single-chain, and is how a
35
- crystal structure containing several copies of a complex is reduced to one.
36
- Chains holding only heterogens or water are kept regardless.
37
- - `keep_crystal_waters`: keep waters in the input PDB.
33
+ - `keep_chains`: chains to build; empty keeps all, which is how a dimer,
34
+ trimer or tetramer is prepared whole. Naming chains is how a crystal
35
+ structure holding several copies of a complex is reduced to one. A chain
36
+ holding only heterogens -- a prediction's ligand, say -- is listed with the
37
+ protein chain it belongs to; see [oligomers.md](oligomers.md).
38
+ - `keep_crystal_waters`: keep waters in the input PDB. A water bound to a
39
+ metal the build keeps -- bonded or nonbonded, within 2.6 A -- stays with it
40
+ regardless, and a bonded site with QM/MM refinement requires `true`.
41
+ - `keep_crystal_ions`: keep free monatomic ions (Cl-, Na+, Br-, ...) resolved
42
+ in the input. Default `true`. tleap builds them from its ion library; a
43
+ halide bound to a bonded metal site is kept regardless. Every ion kept or
44
+ removed is listed in `reports/structure_report.md`.
38
45
  - `altloc_policy`: `highest_occupancy`, `first`, or `fail`.
39
46
  - `remove_unknown_heterogens`: remove unconfigured heterogens instead of
40
47
  failing.
@@ -109,6 +116,10 @@ Each ligand has:
109
116
  - optional `user_frcmod`
110
117
  - preservation controls for names and coordinates
111
118
  - optional `qmmesp` block for PySCF charge workflows
119
+ - optional `parameters_from`: the id of a ligand with the same residue name
120
+ whose parameters this one is built with -- the same cofactor in another copy
121
+ of the protein, parameterised once. Every other setting must repeat that
122
+ ligand's. See [oligomers.md](oligomers.md).
112
123
 
113
124
  ## qmmesp
114
125
 
@@ -142,6 +153,15 @@ Each site has:
142
153
  - `multiplicity`: optional for ordinary metal parameterization, but mandatory
143
154
  when the ion's site is selected for QM/MM refinement.
144
155
 
156
+ - `parameters_from`: optional; the id of the site in another copy of the
157
+ protein whose parameters this site reuses. A bonded copy is not fitted: it
158
+ takes the reference's MCPB.py templates and bond parameters residue by
159
+ residue, so it lists its ions, coordinating ions, bonds and additional
160
+ residues in the reference's order, each the counterpart of the one in the
161
+ same place. Every other setting repeats the reference's. Only one bonded site
162
+ per preparation may be fitted, that is, have no `parameters_from`. See
163
+ [oligomers.md](oligomers.md).
164
+
145
165
  For `model: nonbonded`, `nonbonded.parameter_set` is mandatory and must be
146
166
  `12_6`, `cm`, `hfe`, `iod`, or `12_6_4`. Availability is checked against the
147
167
  active AmberTools data for the configured TIP3P or OPC water model.