htpolynet 2.8.0__tar.gz → 2.10.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 (356) hide show
  1. {htpolynet-2.8.0 → htpolynet-2.10.0}/CHANGELOG.md +132 -0
  2. {htpolynet-2.8.0 → htpolynet-2.10.0}/PKG-INFO +1 -1
  3. {htpolynet-2.8.0 → htpolynet-2.10.0}/ROADMAP.md +44 -0
  4. {htpolynet-2.8.0 → htpolynet-2.10.0}/docker/Dockerfile +8 -1
  5. htpolynet-2.10.0/docs/source/_static/htpolynet-favicon.ico +0 -0
  6. htpolynet-2.10.0/docs/source/_static/htpolynet-landing.jpg +0 -0
  7. htpolynet-2.10.0/docs/source/_static/htpolynet-logo-dark.png +0 -0
  8. htpolynet-2.10.0/docs/source/_static/htpolynet-logo-light.png +0 -0
  9. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/conf.py +13 -0
  10. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/6-cyanate-ester/reactions.rst +15 -0
  11. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/index.rst +5 -0
  12. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/install.rst +33 -6
  13. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/user-guide/configs/configs-for-run.rst +27 -0
  14. {htpolynet-2.8.0 → htpolynet-2.10.0}/pyproject.toml +1 -1
  15. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/core/bondtemplate.py +28 -6
  16. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/core/molecule.py +1 -1
  17. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/core/paramcache.py +35 -2
  18. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/core/runtime.py +114 -6
  19. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/core/topocoord.py +71 -5
  20. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/core/topology.py +61 -0
  21. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/cure/curecontroller.py +65 -7
  22. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/cure/expandreactions.py +115 -1
  23. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/external/ambertools.py +23 -1
  24. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/repair/cyanate_cap.py +19 -22
  25. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/repair/topology_surgery.py +73 -7
  26. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/resources/example_depot/6-cyanate-ester.yaml +4 -1
  27. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/schema/base.yaml +12 -0
  28. {htpolynet-2.8.0 → htpolynet-2.10.0}/tests/unit/test_completion_bias.py +33 -0
  29. {htpolynet-2.8.0 → htpolynet-2.10.0}/tests/unit/test_conda_sync.py +10 -0
  30. htpolynet-2.10.0/tests/unit/test_cure_site_functionality.py +154 -0
  31. htpolynet-2.10.0/tests/unit/test_mol2_bond_fallback.py +58 -0
  32. htpolynet-2.10.0/tests/unit/test_molecule_charge_report.py +68 -0
  33. {htpolynet-2.8.0 → htpolynet-2.10.0}/tests/unit/test_paramcache.py +4 -2
  34. htpolynet-2.10.0/tests/unit/test_repair_charge_neutrality.py +87 -0
  35. htpolynet-2.10.0/tests/unit/test_sibling_templates.py +181 -0
  36. htpolynet-2.10.0/tests/unit/test_user_frcmod.py +149 -0
  37. {htpolynet-2.8.0 → htpolynet-2.10.0}/.claude/settings.json +0 -0
  38. {htpolynet-2.8.0 → htpolynet-2.10.0}/.claude/skills/htpolynet/SKILL.md +0 -0
  39. {htpolynet-2.8.0 → htpolynet-2.10.0}/.envrc +0 -0
  40. {htpolynet-2.8.0 → htpolynet-2.10.0}/.github/workflows/conda-forge-sync.yml +0 -0
  41. {htpolynet-2.8.0 → htpolynet-2.10.0}/.github/workflows/docker.yml +0 -0
  42. {htpolynet-2.8.0 → htpolynet-2.10.0}/.github/workflows/docs.yml +0 -0
  43. {htpolynet-2.8.0 → htpolynet-2.10.0}/.github/workflows/release.yaml +0 -0
  44. {htpolynet-2.8.0 → htpolynet-2.10.0}/.github/workflows/test.yml +0 -0
  45. {htpolynet-2.8.0 → htpolynet-2.10.0}/.gitignore +0 -0
  46. {htpolynet-2.8.0 → htpolynet-2.10.0}/.readthedocs.yaml +0 -0
  47. {htpolynet-2.8.0 → htpolynet-2.10.0}/CITATION.cff +0 -0
  48. {htpolynet-2.8.0 → htpolynet-2.10.0}/CLAUDE.md +0 -0
  49. {htpolynet-2.8.0 → htpolynet-2.10.0}/LICENSE +0 -0
  50. {htpolynet-2.8.0 → htpolynet-2.10.0}/MANIFEST.in +0 -0
  51. {htpolynet-2.8.0 → htpolynet-2.10.0}/README.md +0 -0
  52. {htpolynet-2.8.0 → htpolynet-2.10.0}/docker/compose.yml +0 -0
  53. {htpolynet-2.8.0 → htpolynet-2.10.0}/docker/docker-entrypoint.sh +0 -0
  54. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/Makefile +0 -0
  55. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/README.rst +0 -0
  56. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/make.bat +0 -0
  57. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/requirements.txt +0 -0
  58. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/_static/.gitkeep +0 -0
  59. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/changelog.rst +0 -0
  60. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/0-liquid-styrene/configuration.rst +0 -0
  61. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/0-liquid-styrene/index.rst +0 -0
  62. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/0-liquid-styrene/introduction.rst +0 -0
  63. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/0-liquid-styrene/monomer.rst +0 -0
  64. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/0-liquid-styrene/postsim.rst +0 -0
  65. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/0-liquid-styrene/results.rst +0 -0
  66. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/0-liquid-styrene/run.rst +0 -0
  67. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/1-polystyrene/configuration.rst +0 -0
  68. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/1-polystyrene/index.rst +0 -0
  69. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/1-polystyrene/introduction.rst +0 -0
  70. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/1-polystyrene/monomer.rst +0 -0
  71. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/1-polystyrene/pics/STY.png +0 -0
  72. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/1-polystyrene/pics/STYCC.png +0 -0
  73. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/1-polystyrene/pics/buildtraces.png +0 -0
  74. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/1-polystyrene/pics/cure_info.png +0 -0
  75. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/1-polystyrene/pics/densification-density.png +0 -0
  76. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/1-polystyrene/pics/final-box.png +0 -0
  77. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/1-polystyrene/pics/reaction_network.png +0 -0
  78. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/1-polystyrene/pics/sty-coloring.tcl +0 -0
  79. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/1-polystyrene/pics/sty-cured.png +0 -0
  80. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/1-polystyrene/pics/sty-detail.png +0 -0
  81. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/1-polystyrene/pics/sty-liq.png +0 -0
  82. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/1-polystyrene/pics/styrene-polymerization.png +0 -0
  83. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/1-polystyrene/postsim.rst +0 -0
  84. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/1-polystyrene/reactions.rst +0 -0
  85. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/1-polystyrene/results.rst +0 -0
  86. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/1-polystyrene/run.rst +0 -0
  87. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/configuration.rst +0 -0
  88. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/index.rst +0 -0
  89. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/introduction.rst +0 -0
  90. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/BPA.png +0 -0
  91. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/GMA.png +0 -0
  92. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/HIE.png +0 -0
  93. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/buildtraces.png +0 -0
  94. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/cure_info.png +0 -0
  95. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/densification-density.png +0 -0
  96. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/four_dimers.eps +0 -0
  97. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/four_dimers.fig +0 -0
  98. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/four_dimers.png +0 -0
  99. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/gma-sty-coloring.tcl +0 -0
  100. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/gma-sty-cured.png +0 -0
  101. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/gma-sty-detail.png +0 -0
  102. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/gma-sty-liq.png +0 -0
  103. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/p1-traces.png +0 -0
  104. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/reaction_network.png +0 -0
  105. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/vesys.eps +0 -0
  106. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/vesys.fig +0 -0
  107. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/vesys.png +0 -0
  108. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/postsim.rst +0 -0
  109. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/reactions.rst +0 -0
  110. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/results.rst +0 -0
  111. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/run.rst +0 -0
  112. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/configuration.rst +0 -0
  113. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/index.rst +0 -0
  114. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/introduction.rst +0 -0
  115. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/monomers.rst +0 -0
  116. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/DGE-epoxy.png +0 -0
  117. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/DGE-labelled.png +0 -0
  118. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/PAC-2d.png +0 -0
  119. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/PAC-labelled.png +0 -0
  120. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/buildtraces.png +0 -0
  121. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/cure_info.png +0 -0
  122. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/densification-density.png +0 -0
  123. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/dge-pac-coloring.tcl +0 -0
  124. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/dge-pac-cured.png +0 -0
  125. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/dge-pac-detail.png +0 -0
  126. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/dge-pac-liq.png +0 -0
  127. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/dgesys.eps +0 -0
  128. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/dgesys.fig +0 -0
  129. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/dgesys.png +0 -0
  130. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/equil-rho_v_ns.png +0 -0
  131. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/postsim-typical.png +0 -0
  132. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/prod-e.png +0 -0
  133. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/prod-equil-rho_v_ns.png +0 -0
  134. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/prod-rho_v_ns.png +0 -0
  135. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/prod-tg.png +0 -0
  136. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/r1.png +0 -0
  137. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/r2.png +0 -0
  138. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/r3.png +0 -0
  139. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/reaction_network.png +0 -0
  140. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/rho_v_ns.png +0 -0
  141. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/short-e.png +0 -0
  142. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/short-tg.png +0 -0
  143. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/postsim.rst +0 -0
  144. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/reactions.rst +0 -0
  145. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/results.rst +0 -0
  146. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/run.rst +0 -0
  147. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/configuration.rst +0 -0
  148. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/index.rst +0 -0
  149. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/introduction.rst +0 -0
  150. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/monomers.rst +0 -0
  151. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/buildtraces.png +0 -0
  152. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/cure_info.png +0 -0
  153. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/densification-density.png +0 -0
  154. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/dfa-fde-coloring.tcl +0 -0
  155. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/dfa-fde-cured.png +0 -0
  156. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/dfa-fde-detail.png +0 -0
  157. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/dfa-fde-liq.png +0 -0
  158. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/reaction_network.png +0 -0
  159. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/postsim.rst +0 -0
  160. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/reactions.rst +0 -0
  161. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/results.rst +0 -0
  162. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/run.rst +0 -0
  163. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/5-htpb-ipdi/configuration.rst +0 -0
  164. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/5-htpb-ipdi/index.rst +0 -0
  165. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/5-htpb-ipdi/introduction.rst +0 -0
  166. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/5-htpb-ipdi/monomers.rst +0 -0
  167. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/5-htpb-ipdi/pics/buildtraces.png +0 -0
  168. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/5-htpb-ipdi/pics/cure_info.png +0 -0
  169. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/5-htpb-ipdi/pics/densification-density.png +0 -0
  170. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/5-htpb-ipdi/pics/htpb-coloring.tcl +0 -0
  171. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/5-htpb-ipdi/pics/htpb-ipdi-cured.png +0 -0
  172. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/5-htpb-ipdi/pics/htpb-ipdi-detail.png +0 -0
  173. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/5-htpb-ipdi/pics/htpb-ipdi-liq.png +0 -0
  174. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/5-htpb-ipdi/pics/reaction_network.png +0 -0
  175. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/5-htpb-ipdi/postsim.rst +0 -0
  176. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/5-htpb-ipdi/reactions.rst +0 -0
  177. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/5-htpb-ipdi/results.rst +0 -0
  178. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/5-htpb-ipdi/run.rst +0 -0
  179. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/6-cyanate-ester/configuration.rst +0 -0
  180. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/6-cyanate-ester/index.rst +0 -0
  181. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/6-cyanate-ester/introduction.rst +0 -0
  182. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/6-cyanate-ester/monomers.rst +0 -0
  183. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/6-cyanate-ester/pics/badcy-coloring.tcl +0 -0
  184. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/6-cyanate-ester/pics/badcy-cured.png +0 -0
  185. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/6-cyanate-ester/pics/badcy-detail.png +0 -0
  186. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/6-cyanate-ester/pics/badcy-liq.png +0 -0
  187. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/6-cyanate-ester/pics/buildtraces.png +0 -0
  188. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/6-cyanate-ester/pics/cure_info.png +0 -0
  189. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/6-cyanate-ester/pics/densification-density.png +0 -0
  190. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/6-cyanate-ester/pics/reaction_network.png +0 -0
  191. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/6-cyanate-ester/postsim.rst +0 -0
  192. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/6-cyanate-ester/results.rst +0 -0
  193. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/6-cyanate-ester/run.rst +0 -0
  194. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/example-tutorials/index.rst +0 -0
  195. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/htpolynetpackage.rst +0 -0
  196. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/references/index.rst +0 -0
  197. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/references/mol2-reference.pdf +0 -0
  198. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/references.bib +0 -0
  199. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/user-guide/CURE.odg +0 -0
  200. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/user-guide/bond_filter.odg +0 -0
  201. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/user-guide/building-a-system.rst +0 -0
  202. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/user-guide/configs/configs-for-analyze.rst +0 -0
  203. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/user-guide/configs/configs-for-postsim.rst +0 -0
  204. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/user-guide/configuration-files.rst +0 -0
  205. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/user-guide/container-usage.rst +0 -0
  206. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/user-guide/flow1.odg +0 -0
  207. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/user-guide/flow1yaml.odg +0 -0
  208. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/user-guide/hydrogenated.eps +0 -0
  209. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/user-guide/hydrogenated.fig +0 -0
  210. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/user-guide/index.rst +0 -0
  211. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/user-guide/molecular-structure-inputs.rst +0 -0
  212. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/user-guide/periodic-networks.rst +0 -0
  213. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/user-guide/pics/STY.png +0 -0
  214. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/user-guide/pics/STYCC.png +0 -0
  215. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/user-guide/pics/TypicalUsageFlow.png +0 -0
  216. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/user-guide/pics/bond_filter.png +0 -0
  217. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/user-guide/pics/chemdoodle-2dsketcher-emb.png +0 -0
  218. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/user-guide/pics/chemdoodle-2dsketcher-styrene.png +0 -0
  219. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/user-guide/pics/hydrogenated.png +0 -0
  220. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/user-guide/pics/ring_pierce/ring_pierce_cases.png +0 -0
  221. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/user-guide/pics/ring_pierce/ring_pierce_linkcell.png +0 -0
  222. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/user-guide/postcure-repair.rst +0 -0
  223. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/user-guide/program-flow.rst +0 -0
  224. {htpolynet-2.8.0 → htpolynet-2.10.0}/docs/source/user-guide/usage.rst +0 -0
  225. {htpolynet-2.8.0 → htpolynet-2.10.0}/scripts/check-conda-sync.py +0 -0
  226. {htpolynet-2.8.0 → htpolynet-2.10.0}/scripts/release.sh +0 -0
  227. {htpolynet-2.8.0 → htpolynet-2.10.0}/scripts/render-detail.sh +0 -0
  228. {htpolynet-2.8.0 → htpolynet-2.10.0}/scripts/render-detail.tcl +0 -0
  229. {htpolynet-2.8.0 → htpolynet-2.10.0}/scripts/render-snapshot.sh +0 -0
  230. {htpolynet-2.8.0 → htpolynet-2.10.0}/scripts/run_all_examples.sh +0 -0
  231. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/__init__.py +0 -0
  232. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/analysis/__init__.py +0 -0
  233. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/analysis/analyze.py +0 -0
  234. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/analysis/plot.py +0 -0
  235. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/analysis/postsim.py +0 -0
  236. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/analysis/utils.py +0 -0
  237. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/cli.py +0 -0
  238. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/core/__init__.py +0 -0
  239. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/core/configuration.py +0 -0
  240. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/core/coordinates.py +0 -0
  241. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/core/projectfilesystem.py +0 -0
  242. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/cure/__init__.py +0 -0
  243. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/cure/chain.py +0 -0
  244. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/cure/reaction.py +0 -0
  245. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/external/__init__.py +0 -0
  246. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/external/command.py +0 -0
  247. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/external/gromacs.py +0 -0
  248. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/external/slurm.py +0 -0
  249. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/external/smiles_input.py +0 -0
  250. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/external/software.py +0 -0
  251. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/geometry/__init__.py +0 -0
  252. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/geometry/bondlist.py +0 -0
  253. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/geometry/lattice.py +0 -0
  254. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/geometry/linkcell.py +0 -0
  255. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/geometry/matrix4.py +0 -0
  256. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/geometry/ring.py +0 -0
  257. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/io/__init__.py +0 -0
  258. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/io/gro.py +0 -0
  259. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/io/mol2.py +0 -0
  260. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/io/pdb.py +0 -0
  261. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/repair/__init__.py +0 -0
  262. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/resources/README.md +0 -0
  263. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/resources/__init__.py +0 -0
  264. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/resources/claude/SKILL.md +0 -0
  265. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/resources/example_depot/0-liquid-styrene.yaml +0 -0
  266. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/resources/example_depot/1-polystyrene.yaml +0 -0
  267. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/resources/example_depot/2-bisgma-styrene-thermoset.yaml +0 -0
  268. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/resources/example_depot/3-pacm-dgeba-epoxy-thermoset.yaml +0 -0
  269. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/resources/example_depot/4-dfda-fde-epoxy-thermoset.yaml +0 -0
  270. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/resources/example_depot/5-htpb-ipdi.yaml +0 -0
  271. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/resources/mdp/README.md +0 -0
  272. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/resources/mdp/drag-min.mdp +0 -0
  273. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/resources/mdp/drag-npt.mdp +0 -0
  274. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/resources/mdp/drag-nvt.mdp +0 -0
  275. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/resources/mdp/min.mdp +0 -0
  276. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/resources/mdp/npt.mdp +0 -0
  277. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/resources/mdp/nvt.mdp +0 -0
  278. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/resources/mdp/relax-min.mdp +0 -0
  279. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/resources/mdp/relax-npt.mdp +0 -0
  280. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/resources/mdp/relax-nvt.mdp +0 -0
  281. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/resources/mdp/single-molecule-min.mdp +0 -0
  282. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/resources/mdp/single-molecule-nvt.mdp +0 -0
  283. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/resources/molecules/inputs/DFA.pdb +0 -0
  284. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/resources/molecules/inputs/DGE.mol2 +0 -0
  285. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/resources/molecules/inputs/EMB.mol2 +0 -0
  286. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/resources/molecules/inputs/FDE.pdb +0 -0
  287. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/resources/molecules/inputs/GMA.mol2 +0 -0
  288. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/resources/molecules/inputs/PAC.mol2 +0 -0
  289. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/resources/molecules/inputs/STY.mol2 +0 -0
  290. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/resources/molecules/make-monomers.sh +0 -0
  291. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/resources/molecules/pics/DFA.png +0 -0
  292. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/resources/molecules/pics/DGE.png +0 -0
  293. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/resources/molecules/pics/EMB.png +0 -0
  294. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/resources/molecules/pics/FDE.png +0 -0
  295. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/resources/molecules/pics/GMA.png +0 -0
  296. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/resources/molecules/pics/PAC.png +0 -0
  297. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/resources/molecules/pics/STY.png +0 -0
  298. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/resources/molecules/sample-inputs/DFA.pdb +0 -0
  299. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/resources/molecules/sample-inputs/DGE.mol2 +0 -0
  300. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/resources/molecules/sample-inputs/EMB.mol2 +0 -0
  301. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/resources/molecules/sample-inputs/FDE.pdb +0 -0
  302. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/resources/molecules/sample-inputs/GMA.mol2 +0 -0
  303. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/resources/molecules/sample-inputs/PAC.mol2 +0 -0
  304. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/resources/molecules/sample-inputs/STY.mol2 +0 -0
  305. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/resources/tcl/readbonds.tcl +0 -0
  306. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/resources/tcl/readgrx.tcl +0 -0
  307. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/resources/tcl/render.tcl +0 -0
  308. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/utils/__init__.py +0 -0
  309. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/utils/banner.py +0 -0
  310. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/utils/checkpoint.py +0 -0
  311. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/utils/convergence.py +0 -0
  312. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/utils/dataframetools.py +0 -0
  313. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/utils/inputcheck.py +0 -0
  314. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/utils/logsetup.py +0 -0
  315. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/utils/profiling.py +0 -0
  316. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/utils/stringthings.py +0 -0
  317. {htpolynet-2.8.0 → htpolynet-2.10.0}/src/htpolynet/utils/vmd_viz.py +0 -0
  318. {htpolynet-2.8.0 → htpolynet-2.10.0}/tests/__init__.py +0 -0
  319. {htpolynet-2.8.0 → htpolynet-2.10.0}/tests/conftest.py +0 -0
  320. {htpolynet-2.8.0 → htpolynet-2.10.0}/tests/unit/__init__.py +0 -0
  321. {htpolynet-2.8.0 → htpolynet-2.10.0}/tests/unit/fixtures/config1.gro +0 -0
  322. {htpolynet-2.8.0 → htpolynet-2.10.0}/tests/unit/fixtures/config1.top +0 -0
  323. {htpolynet-2.8.0 → htpolynet-2.10.0}/tests/unit/fixtures/config2.gro +0 -0
  324. {htpolynet-2.8.0 → htpolynet-2.10.0}/tests/unit/fixtures/config2.top +0 -0
  325. {htpolynet-2.8.0 → htpolynet-2.10.0}/tests/unit/fixtures/items31.edr +0 -0
  326. {htpolynet-2.8.0 → htpolynet-2.10.0}/tests/unit/fixtures/items43.edr +0 -0
  327. {htpolynet-2.8.0 → htpolynet-2.10.0}/tests/unit/fixtures/items45.edr +0 -0
  328. {htpolynet-2.8.0 → htpolynet-2.10.0}/tests/unit/fixtures/short.mdp +0 -0
  329. {htpolynet-2.8.0 → htpolynet-2.10.0}/tests/unit/test_bondtemplate.py +0 -0
  330. {htpolynet-2.8.0 → htpolynet-2.10.0}/tests/unit/test_cap_placement.py +0 -0
  331. {htpolynet-2.8.0 → htpolynet-2.10.0}/tests/unit/test_chain.py +0 -0
  332. {htpolynet-2.8.0 → htpolynet-2.10.0}/tests/unit/test_configuration.py +0 -0
  333. {htpolynet-2.8.0 → htpolynet-2.10.0}/tests/unit/test_convergence.py +0 -0
  334. {htpolynet-2.8.0 → htpolynet-2.10.0}/tests/unit/test_dataframetools.py +0 -0
  335. {htpolynet-2.8.0 → htpolynet-2.10.0}/tests/unit/test_density_gate.py +0 -0
  336. {htpolynet-2.8.0 → htpolynet-2.10.0}/tests/unit/test_gpu_usability.py +0 -0
  337. {htpolynet-2.8.0 → htpolynet-2.10.0}/tests/unit/test_gromacs_get_energy_menu.py +0 -0
  338. {htpolynet-2.8.0 → htpolynet-2.10.0}/tests/unit/test_gromacs_gmx_energy_trace.py +0 -0
  339. {htpolynet-2.8.0 → htpolynet-2.10.0}/tests/unit/test_inputcheck.py +0 -0
  340. {htpolynet-2.8.0 → htpolynet-2.10.0}/tests/unit/test_linkcell_pierce.py +0 -0
  341. {htpolynet-2.8.0 → htpolynet-2.10.0}/tests/unit/test_moleculetype_name.py +0 -0
  342. {htpolynet-2.8.0 → htpolynet-2.10.0}/tests/unit/test_paramcache_ambertools.py +0 -0
  343. {htpolynet-2.8.0 → htpolynet-2.10.0}/tests/unit/test_parameterize_react.py +0 -0
  344. {htpolynet-2.8.0 → htpolynet-2.10.0}/tests/unit/test_plot_smoke.py +0 -0
  345. {htpolynet-2.8.0 → htpolynet-2.10.0}/tests/unit/test_projectfilesystem.py +0 -0
  346. {htpolynet-2.8.0 → htpolynet-2.10.0}/tests/unit/test_relax_instrumentation.py +0 -0
  347. {htpolynet-2.8.0 → htpolynet-2.10.0}/tests/unit/test_repair_conversion.py +0 -0
  348. {htpolynet-2.8.0 → htpolynet-2.10.0}/tests/unit/test_resources.py +0 -0
  349. {htpolynet-2.8.0 → htpolynet-2.10.0}/tests/unit/test_ring.py +0 -0
  350. {htpolynet-2.8.0 → htpolynet-2.10.0}/tests/unit/test_ring_pierce_figs.py +0 -0
  351. {htpolynet-2.8.0 → htpolynet-2.10.0}/tests/unit/test_setup_claude.py +0 -0
  352. {htpolynet-2.8.0 → htpolynet-2.10.0}/tests/unit/test_slurm_script.py +0 -0
  353. {htpolynet-2.8.0 → htpolynet-2.10.0}/tests/unit/test_smiles_input.py +0 -0
  354. {htpolynet-2.8.0 → htpolynet-2.10.0}/tests/unit/test_software_provenance.py +0 -0
  355. {htpolynet-2.8.0 → htpolynet-2.10.0}/tests/unit/test_topology/test.top +0 -0
  356. {htpolynet-2.8.0 → htpolynet-2.10.0}/tests/unit/test_topology.py +0 -0
@@ -7,6 +7,138 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [2.10.0] - 2026-09-15
11
+
12
+ ### Added
13
+
14
+ - **A constituent can carry its own frcmod.** `frcmod: file.frcmod` on a
15
+ constituent loads that Amber parameter file into `tleap` after GAFF and
16
+ `parmchk2`, so its parameters override theirs. It is loaded for the
17
+ molecule and for every template containing it, including cure, capping,
18
+ repair and multiply-substituted templates. The file's contents are part of
19
+ the parameter cache record, so an edited frcmod re-parameterizes instead of
20
+ reusing stale numbers. A system has one table per bonded type, so setup
21
+ stops with the type's name if an overridden type also appears, with other
22
+ parameters, in a molecule built without the file.
23
+
24
+ ## [2.9.0] - 2026-09-15
25
+
26
+ ### Added
27
+
28
+ - **The build log reports molecules that carry net charge.** After cure,
29
+ after postcure repair, and when the final results are written, htpolynet
30
+ checks every covalently bonded molecule. It logs one line when all are
31
+ neutral to within 0.01 e, and a warning naming the count and the largest
32
+ charge when some are not. The system total is zero by construction, so
33
+ until now a template or repair step that moved charge from one molecule to
34
+ another left no trace. The check can't see charge misplaced *inside* a
35
+ percolated network, because the whole network is a single molecule.
36
+
37
+ ### Fixed
38
+
39
+ - **Later bonds on a triazine reset the charges of its earlier ones.**
40
+ Each cure template shows a single BPA on the ring, and splicing it in
41
+ rewrites the charges of atoms up to two bonds from the new bond, which
42
+ includes the other ring carbons. So every ring carbon that reacted before
43
+ the last one got its *unreacted* charge back. Example 6's fully reacted
44
+ rings had carbons anywhere from 0.14 to 0.31 e, where the template value is
45
+ 0.28. A cured bisphenol-A dicyanate network showed a clean 2:1 split,
46
+ +0.70 against +0.90 e. htpolynet now builds extra templates at setup for
47
+ rings that already carry one or two BPAs; example 6 gets 18 of them. Each
48
+ cure bond picks the one that matches the ring as it stands: templates
49
+ record which atoms two bonds from the bonding atom have already reacted,
50
+ and matching prefers the one that records the most. This applies to any
51
+ reactive atom whose `symmetry_equivalent_atoms` partners sit two bonds
52
+ away. None of the other shipped examples has one, and example 5's
53
+ build-stage molecules are unchanged, charge for charge.
54
+
55
+ Replaying example 6's recorded cure bonds offline puts every bonded ring
56
+ carbon at its template value: 0.275, 0.277 or 0.279 e for one, two or
57
+ three BPAs. All 13 molecules after cure are now neutral, where before
58
+ they ranged from -0.37 to +0.29 e. Cyanate-ester builds should be
59
+ rebuilt.
60
+
61
+ - **A template that matched a bond only in reverse crashed the cure** with
62
+ `mapping mismatch -- bug`. After reversing the bond to line up with the
63
+ template, the mapping check still compared it the original way round. No
64
+ shipped example had reached this path.
65
+
66
+ - **Cyanate-cap repair left molecules charged.** `triazine_to_cyanate_cap`
67
+ kept the system neutral, but not each molecule. It settled charge twice,
68
+ both times system-wide:
69
+ - once while splicing the cap template, when the sacrificial H's still
70
+ existed;
71
+ - once after deleting them, onto only the atoms those H's had been bonded
72
+ to.
73
+
74
+ Caps formed in place and caps transferred to a free BPA-OH therefore ended
75
+ with charges 0.24 e apart on the phenolic O and the cap C. In a
76
+ zero-conversion bisphenol-A dicyanate melt, every molecule came out at
77
+ either +0.21 or -0.27 e. In example 6, the 27 molecules left after repair
78
+ ranged from -3.59 to +0.62 e. Repair now brings each molecule it touched
79
+ back to neutral, and makes the correction only on the atoms it changed.
80
+ Example 6's molecules are all neutral, and its cap residues sit at
81
+ 0.05-0.09 e, near the template's 0.069, instead of splitting between 0.04
82
+ and 0.20. Builds that used `postcure_repair` should be rebuilt.
83
+
84
+ - **A false percolation warning on linear polymers.** The end-of-cure check
85
+ warned that too few residues had reacted at every site to assume the system
86
+ percolates, and it fired on chain-growth systems like example 1's
87
+ polystyrene -- "only 902 of 1000 STY (90.2%) ... below the 100.0% ... at its
88
+ gel point". For a difunctional monomer that threshold, `(1/(f-1))^f`, is
89
+ exactly 100%, and a fully reacted difunctional unit is a chain interior
90
+ rather than a crosslink junction, so neither the warning nor its premise
91
+ applied. The check now runs only when some residue has at least three
92
+ reactive sites.
93
+
94
+ - **The percolation check counted sites the cure never uses.** It summed
95
+ every reactive site a residue was built with, including bonds made while
96
+ assembling molecules and valences no cure reaction can consume. Example 2
97
+ warned that "0 of 150 HIE" had reacted at all four sites, which was
98
+ impossible: two of those sites sit on an atom only the molecule-building
99
+ reactions touch. Example 5's warning about TB was the same mistake, since
100
+ every TB site is a chain bond made before the cure. In examples 3 and 4 the
101
+ diepoxide and the diamine tied at four sites, so the reported fraction
102
+ mixed both residue types ("83 of 300 DGE"). Functionality and completion are
103
+ now counted only on atoms a cure reaction can bond, taken from the
104
+ symmetry-expanded reaction list the bond search itself uses. Example 3 now
105
+ reports "83 of 100 PAC", and example 6's check is unchanged. When no
106
+ residue has three or more cure sites, the check says crosslink percolation
107
+ was not assessed, rather than staying silent: systems that crosslink through
108
+ a multi-residue molecule, such as a dimethacrylate, are outside what a
109
+ residue-level count can see.
110
+
111
+ - **Bondless MOL2 files for symmetry-sibling molecules.** A molecule built by
112
+ copying a parent's topology (for example `GMAS-4`, from `GMA`) has its bonds
113
+ in the topology but no MOL2 bond table, so writing it as MOL2 produced a file
114
+ with no bonds and a "Cannot write any bonds to MOL2 file" warning -- twelve
115
+ times in example 2 on a fresh parameterization. Those writes are now filled
116
+ from the topology's bonds, as single bonds. In every shipped example the
117
+ affected files were diagnostic `*-prebonding.mol2` outputs that nothing reads,
118
+ so no parameterization input was ever affected.
119
+
120
+ - **The CPU container image failed to build for 2.8.0**, so
121
+ `ghcr.io/cameronabrams/htpolynet:v2.8.0` was never published (the CUDA image
122
+ was). The base image `condaforge/miniforge3:latest` moved to mamba 2.9.0,
123
+ whose `mamba clean -afy` fails on a symlink inside the CPU AmberTools
124
+ package. The install was succeeding; only the cleanup step failed. The
125
+ Dockerfile now cleans with `conda clean`.
126
+
127
+ ### Documentation
128
+
129
+ - **The installation page now recommends the container as the default way to
130
+ run htpolynet**, in a callout at the top with the two commands you need on a
131
+ desktop (Docker Compose) or on a cluster (Singularity/Apptainer), plus the
132
+ note that the default image is CPU-only and GPU users want the `:cuda` tag.
133
+ Installing htpolynet and its tools natively is still documented below it,
134
+ for development and for systems without containers.
135
+
136
+ - **The documentation has a logo and a landing-page illustration.** The
137
+ logo appears in every page's sidebar, in black-on-transparent for the light
138
+ theme and white-on-transparent for the dark one, so it never shows as a white
139
+ box in dark mode. The browser tab shows it too, as a favicon on a white disc
140
+ so it stays visible whether the tab bar is light or dark.
141
+
10
142
  ## [2.8.0] - 2026-09-12
11
143
 
12
144
  ### Added
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: htpolynet
3
- Version: 2.8.0
3
+ Version: 2.10.0
4
4
  Summary: Automated MD System Builder for Amorphous Network Polymers
5
5
  Project-URL: Source, https://github.com/cameronabrams/htpolynet
6
6
  Project-URL: Documentation, https://htpolynet.readthedocs.io/
@@ -199,6 +199,20 @@ Coverage as of the last measurement: **38.8%** overall.
199
199
 
200
200
  ## Cure and repair
201
201
 
202
+ - **Cure still settles template overcharge system-wide.**
203
+ `map_from_templates` ends each batch of bonds with one `adjust_charges`
204
+ over every mapped atom in the system. When the templates are consistent
205
+ with each other this does nothing: since the second-shell templates, all 13
206
+ of example 6's molecules after cure are neutral (before them, the
207
+ range was -0.37 to +0.29 e). But any template that does not describe
208
+ its instance exactly (a mapped atom whose context the template lacks, or
209
+ charges from a different conformer) leaks charge between molecules without
210
+ a trace. A per-molecule settle, like
211
+ `topology_surgery.neutralize_touched_fragments` in repair, would contain
212
+ it. Two cases the second-shell rule leaves out: reacted atoms *directly*
213
+ bonded to the bonding atom (it leaves those to the C=C chain machinery), and
214
+ atoms that aren't declared symmetry-equivalent.
215
+
202
216
  - **`cap_min_clearance` has never been calibrated against a working metric.**
203
217
  The 0.150 nm default was chosen in 2.6.0 against a clearance that was pinned
204
218
  at 0.136 nm by a bug, so it fired on 100 % of caps for a reason that had
@@ -905,6 +919,36 @@ Coverage as of the last measurement: **38.8%** overall.
905
919
  docs describe only the GAFF-scoped form. base.yaml declares both, marking the
906
920
  top-level spelling deprecated; pick one before the schema goes live.
907
921
 
922
+ - **A parameterized molecule built from a symmetry-sibling reactant would
923
+ hand antechamber an incomplete bond table.** Found while fixing the
924
+ bondless-MOL2 writes reported by the 2026-09-13 example sweep. Symmetry
925
+ siblings are loaded from the parent's top+gro and carry no `mol2_bonds`.
926
+ When topologies merge (`Topology.merge` via `_myconcat(... 'mol2_bonds')`),
927
+ a reactant without that table contributes nothing to the product's, so the
928
+ product's `{name}.mol2`, which `Molecule.parameterize` gives to antechamber
929
+ for atom typing, would silently lack that reactant's internal bonds.
930
+ `TopoCoord.write_mol2` now falls back to topology bonds only when the table
931
+ is absent entirely, which does not cover this partial case. Not exercised by
932
+ any shipped example: the fresh-cache 2026-09-13 sweep had zero bondless
933
+ writes outside diagnostic `-prebonding` files, and every sibling product
934
+ copied its parent's topology rather than being parameterized. The fix, if
935
+ a case ever appears, is for `merge` to synthesize `mol2_bonds` from `bonds`
936
+ for any operand that lacks the table, rather than concatenating a partial
937
+ table. Bond orders would then need the same single-bond assumption.
938
+
939
+ - **Two gaps left after the percolation check moved to cure sites
940
+ (2026-09-15).** First, a system that crosslinks through a *multi-residue*
941
+ molecule -- example 2's GMA (two methacrylate HIE units), example 5's
942
+ three-armed THT -- is reported as "not assessed". A real assessment needs a
943
+ molecule-level count: sum cure sites per molecule and ask how many molecules
944
+ reacted at all of them. Second, `CureController._completion_bias_counts`
945
+ still ranks candidates by `residue_reaction_counts` over *all* atoms, so a
946
+ bond made while building a molecule (HIE's C4) counts as progress toward
947
+ completion. That only matters with `completion_bias` on, which no shipped
948
+ example uses. It was left alone because fixing it changes which bonds a
949
+ biased cure forms, not just a diagnostic; `cure_site_mask` is the tool when
950
+ that is wanted.
951
+
908
952
  ## Simulation defaults
909
953
 
910
954
  - **The halogen constraint failure is fixed but not explained.** v2.7.0
@@ -60,12 +60,19 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
60
60
  ARG GROMACS_BUILD=
61
61
  ARG CONDA_OVERRIDE_CUDA=
62
62
 
63
+ # Clean with conda, not mamba. mamba 2.9.0 (miniforge3 26.7.2-0, the image
64
+ # :latest moved to on 2026-09-09) fails `mamba clean -afy` with "cannot get
65
+ # file size: No such file or directory" on the CPU AmberTools 26.0 package:
66
+ # its bin/amber.conda is a symlink that dangles inside the package cache, and
67
+ # mamba stats everything named *.conda. The install itself succeeds; only the
68
+ # clean dies, taking the whole RUN with it. conda clean handles the same cache
69
+ # correctly. Reproduced locally in both directions before changing this.
63
70
  RUN CONDA_OVERRIDE_CUDA="${CONDA_OVERRIDE_CUDA}" mamba install -y -n base -c conda-forge \
64
71
  ambertools \
65
72
  "gromacs${GROMACS_BUILD:+=*=${GROMACS_BUILD}*}" \
66
73
  parmed \
67
74
  rdkit \
68
- && mamba clean -afy
75
+ && conda clean -afy
69
76
 
70
77
  # Install HTPolyNet
71
78
  COPY . /htpolynet
@@ -58,6 +58,19 @@ language = 'en'
58
58
  #
59
59
  html_theme = 'furo'
60
60
 
61
+ # The logo is line art, so it ships as two transparent variants rather than one
62
+ # opaque image: black ink for the light theme, white ink for the dark one. An
63
+ # opaque logo would show as a white square in furo's dark mode.
64
+ html_theme_options = {
65
+ 'light_logo': 'htpolynet-logo-light.png',
66
+ 'dark_logo': 'htpolynet-logo-dark.png',
67
+ }
68
+
69
+ # The favicon, unlike the sidebar logo, keeps an opaque white disc: a browser's
70
+ # tab bar may be light or dark, and transparent line art would vanish on one of
71
+ # them. 16, 32 and 48 px in one .ico.
72
+ html_favicon = '_static/htpolynet-favicon.ico'
73
+
61
74
  # Add any paths that contain custom static files (such as style sheets) here,
62
75
  # relative to this directory. They are copied after the builtin static files,
63
76
  # so a file named "default.css" will overwrite the builtin "default.css".
@@ -43,6 +43,21 @@ setup time, each as a separately parameterized linked-product
43
43
  template. The cure machinery treats them as six distinct reactions in
44
44
  the iterative bond search, but the user only had to write one.
45
45
 
46
+ Six templates are not enough to give the ring the right charges,
47
+ though. Each describes a triazine with one BPA attached, so it shows
48
+ the other two ring carbons unreacted, and a template splice rewrites
49
+ the charges of every atom within two bonds of the new bond, which
50
+ includes those carbons. Without more context, the second and third
51
+ bonds on a ring would reset the carbons that reacted before them to
52
+ their unreacted charge. So htpolynet also builds, at setup time, one
53
+ template for each bonding carbon, BPA oxygen, and set of ring carbons
54
+ already bonded: 18 more, with names like
55
+ ``BPA~O1-C3~BPA~O1-C2~BPA~O1-C1~TAZ``. At each bond, the cure picks
56
+ the one that matches the ring as it stands. Nothing in the
57
+ configuration asks for these. htpolynet generates them for any
58
+ reactive atom whose ``symmetry_equivalent_atoms`` partners sit two
59
+ bonds away, as a triazine's ring carbons do.
60
+
46
61
  What the cure stage produces, then, is an A2+B3 step-growth ether
47
62
  network: every formed bond is the same chemistry (an aryl O to a
48
63
  triazine ring C, replacing one H on each side with a new C-O bond),
@@ -41,6 +41,11 @@ htpolynet
41
41
  :target: https://doi.org/10.5281/zenodo.22070252
42
42
  :alt: DOI
43
43
 
44
+ .. image:: _static/htpolynet-landing.jpg
45
+ :alt: A rusty robot in a straw hat sits on a driftwood log on a tropical beach, humming as it knots a net of ball-and-stick molecules strung between posts. A hand-painted sign beside it reads "HTPOLYNET: Stranded today. Better polymers tomorrow."
46
+ :align: center
47
+ :width: 100%
48
+
44
49
  htpolynet is a command-line tool for building atomic configurations of amorphous network polymers suitable for molecular dynamics (MD) simulations.
45
50
  It uses the General Amber Force Field and produces output that can be simulated
46
51
  using Gromacs.
@@ -2,12 +2,39 @@
2
2
  Installation and Prerequisites
3
3
  ##############################
4
4
 
5
- A pre-built container image is available that bundles all required
6
- software (Gromacs, AmberTools, OpenBabel, RDKit, and ``htpolynet``). If
7
- you have Docker or Singularity/Apptainer available, this is the easiest
8
- way to get started — see :ref:`container_usage` for instructions. The
9
- remainder of this page describes how to install ``htpolynet`` and its
10
- prerequisites directly on your system.
5
+ .. admonition:: Recommended: run htpolynet from the container
6
+ :class: tip
7
+
8
+ The easiest way to use ``htpolynet`` is the pre-built container image,
9
+ ``ghcr.io/cameronabrams/htpolynet``. It bundles everything ``htpolynet``
10
+ needs --- Gromacs, AmberTools, OpenBabel, RDKit, and ``htpolynet`` itself
11
+ --- so there is nothing else to install and no versions to line up.
12
+
13
+ **On a desktop** (Docker), fetch the Compose file once, then run
14
+ ``htpolynet`` through it:
15
+
16
+ .. code-block:: console
17
+
18
+ $ curl -O https://raw.githubusercontent.com/cameronabrams/htpolynet/main/docker/compose.yml
19
+ $ docker compose run --rm htpolynet run config.yaml
20
+
21
+ **On a cluster** (Singularity/Apptainer), pull the image once, then run it
22
+ with your working directory bound in:
23
+
24
+ .. code-block:: console
25
+
26
+ $ singularity pull htpolynet.sif docker://ghcr.io/cameronabrams/htpolynet:latest
27
+ $ singularity run --bind $(pwd):/work --pwd /work htpolynet.sif run config.yaml
28
+
29
+ The default image runs Gromacs on CPUs only. To use an NVIDIA GPU, use
30
+ the ``:cuda`` tag instead.
31
+
32
+ See :ref:`container_usage` for the details: persistent caches, GPU setup,
33
+ and pinning a release.
34
+
35
+ The rest of this page covers installing ``htpolynet`` and its prerequisites
36
+ directly on your system, which you'll want for development or wherever
37
+ containers aren't available.
11
38
 
12
39
  Software Prerequisites
13
40
  ----------------------
@@ -98,8 +98,35 @@ In this section we show all subdirectives for each of the five main directives i
98
98
  ``smiles`` string (optional) SMILES for in-config monomer generation; htpolynet runs ``obabel`` (or RDKit) to materialize ``lib/molecules/inputs/<NAME>.mol2`` before parameterization
99
99
  ``rename_atoms`` dict (optional) ``{1-based-mol2-index: atom-name}`` map applied after obabel writes the mol2 (obabel path; pairs with ``smiles``)
100
100
  ``reactive_atoms`` dict (optional) ``{smiles-atom-map-label: atom-name}`` map (RDKit path; pairs with a ``smiles`` that uses ``[*:N]`` atom-mapping tokens). ``rdkit`` is a required runtime dependency and is pulled in by any normal ``htpolynet`` install
101
+ ``frcmod`` string (optional) path, relative to the configuration file, to an Amber ``frcmod`` of parameter overrides for this molecule; see below
101
102
  ===================================== ================= =====================
102
103
 
104
+ ``frcmod`` corrects GAFF for one monomer without touching the others, for
105
+ example a torsion refit against quantum-chemical scans. ``tleap`` loads
106
+ the file after GAFF and ``parmchk2``, so its entries win. It is loaded
107
+ for the molecule itself and for every template that contains it: cure
108
+ products, capping and repair templates, and the multiply-substituted
109
+ templates htpolynet derives. The file's contents are part of each of
110
+ those parameterizations' cache records, so editing it re-parameterizes
111
+ them on the next run rather than reusing the old numbers.
112
+
113
+ .. code-block:: yaml
114
+
115
+ constituents:
116
+ BAF:
117
+ smiles: "FC(F)(F)C(c1ccc([OH:1])cc1)(c1ccc([OH:2])cc1)C(F)(F)F"
118
+ reactive_atoms: {1: O1, 2: O2}
119
+ frcmod: baf-torsion.frcmod
120
+
121
+ One restriction follows from how GROMACS topologies work. A system holds
122
+ one parameter table per bonded *type* (four atom types, for a dihedral),
123
+ shared by every molecule in it. So an override cannot apply to a type in
124
+ one molecule and leave the same type alone in another: if a molecule
125
+ built without the frcmod also contains the overridden type, with
126
+ different parameters, setup stops and names it. Either load the same
127
+ frcmod for every constituent that contains the type, or give the atoms
128
+ you want to treat differently their own atom type.
129
+
103
130
  In the example below, we are requesting a system of 100 styrene molecules. The key ``STY`` signals to ``htpolynet`` that it should look for either ``STY.mol2`` or ``STY.pdb`` in ``./lib/molecules/inputs`` **or** it should look for ``STY.gro``, ``STY.itp``, ``STY.top``, and ``STY.grx`` in ``./lib/molecules/parameterized``. The latter is the case if either ``htpolynet run`` or ``htpolynet parameterized`` has already been run with ``STY.mol2`` or ``STY.pdb``. If neither set of files is found but the constituent carries a ``smiles`` key, ``htpolynet`` generates the input ``mol2`` itself. Multiple records in ``constituents`` should all have the "key":"record" syntax and be separated by commas.
104
131
 
105
132
  Any entry in ``constituents`` for which the ``count`` is 0 or missing is treated as an intermediate for which stereocenters or symmetry-equivalent atoms are specified.
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "htpolynet"
7
- version = "2.8.0"
7
+ version = "2.10.0"
8
8
  authors = [
9
9
  { name="Cameron F Abrams", email="cfa22@drexel.edu" },
10
10
  ]
@@ -15,7 +15,7 @@ logger = logging.getLogger(__name__)
15
15
 
16
16
 
17
17
  class BondTemplate:
18
- def __init__(self, names, resnames, intraresidue, order, bystander_resnames, bystander_atomnames, oneaway_resnames, oneaway_atomnames):
18
+ def __init__(self, names, resnames, intraresidue, order, bystander_resnames, bystander_atomnames, oneaway_resnames, oneaway_atomnames, siblings=None):
19
19
  """Creates a BondTemplate object.
20
20
 
21
21
  Args:
@@ -27,6 +27,10 @@ class BondTemplate:
27
27
  bystander_atomnames (list of two list-like containers of strs): lists of names of atoms in bystander residues (parallel to bystander_resnames)
28
28
  oneaway_resnames (list-like container of strs): names of one-away residues (residues bound one bond away from the new interresidue bond; only relevant for C=C free-radical polymerization)
29
29
  oneaway_atomnames (list-like container of strs): names of atoms in one-away residues
30
+ siblings (list of two lists of (str, str) tuples): for each atom in names, the
31
+ (atomName, partner resName) of every other atom in its residue, within two
32
+ intraresidue bonds, that is already bonded to another residue; defaults to
33
+ none on either side. See TopoCoord.get_siblings.
30
34
  """
31
35
  self.names = names
32
36
  self.resnames = resnames
@@ -36,6 +40,7 @@ class BondTemplate:
36
40
  self.oneaway_resnames = oneaway_resnames
37
41
  self.oneaway_atomnames = oneaway_atomnames
38
42
  self.order = order
43
+ self.siblings = [sorted(tuple(t) for t in x) for x in siblings] if siblings else [[], []]
39
44
 
40
45
  def reverse(self):
41
46
  """Reverses the order of all parallel lists in a BondTemplate object."""
@@ -45,9 +50,10 @@ class BondTemplate:
45
50
  self.bystander_atomnames = self.bystander_atomnames[::-1]
46
51
  self.oneaway_resnames = self.oneaway_resnames[::-1]
47
52
  self.oneaway_atomnames = self.oneaway_atomnames[::-1]
53
+ self.siblings = self.siblings[::-1]
48
54
 
49
55
  def __str__(self):
50
- return f'BondTemplate {self.names} resnames {self.resnames} intraresidue? {self.intraresidue} order {self.order} bystander-resnames {self.bystander_resnames} bystander-atomnames {self.bystander_atomnames} oneaway-resnames {self.oneaway_resnames} oneaway-atomnames {self.oneaway_atomnames}'
56
+ return f'BondTemplate {self.names} resnames {self.resnames} intraresidue? {self.intraresidue} order {self.order} bystander-resnames {self.bystander_resnames} bystander-atomnames {self.bystander_atomnames} oneaway-resnames {self.oneaway_resnames} oneaway-atomnames {self.oneaway_atomnames} siblings {self.siblings}'
51
57
 
52
58
  def __eq__(self,other):
53
59
  check = self.names == other.names
@@ -57,6 +63,7 @@ class BondTemplate:
57
63
  check = check and self.bystander_atomnames == other.bystander_atomnames
58
64
  check = check and self.oneaway_resnames == other.oneaway_resnames
59
65
  check = check and self.oneaway_atomnames == other.oneaway_atomnames
66
+ check = check and self.siblings == other.siblings
60
67
  return check
61
68
 
62
69
  def is_reverse_of(self,other):
@@ -73,13 +80,15 @@ class BondTemplate:
73
80
  return self == rb
74
81
 
75
82
  def bystander_count(self):
76
- """Total number of bystander (resname, atomname) pairs across both sides.
83
+ """Total number of bystander (resname, atomname) pairs and siblings across both sides.
77
84
 
78
- Used by find_template's best-match selection: more bystanders = more
85
+ Used by find_template's best-match selection: more context = more
79
86
  specific template, which should win when multiple templates can match
80
- an instance under subset semantics.
87
+ an instance under subset semantics. Siblings count here so that a
88
+ triazine template with two ring carbons already bonded beats the one
89
+ with one, which beats the bare one.
81
90
  """
82
- return sum(len(s) for s in self.bystander_resnames)
91
+ return sum(len(s) for s in self.bystander_resnames) + sum(len(s) for s in self.siblings)
83
92
 
84
93
  def matches(self, other):
85
94
  """Return True if `self` (a parameterization-stage template) is a
@@ -111,6 +120,13 @@ class BondTemplate:
111
120
  force the cure reactant to mirror every inter-residue partner
112
121
  the instance carries, which forecloses the small-fragment idiom.
113
122
 
123
+ Subset semantics on siblings, for the same reason. A sibling is
124
+ another atom of a bonding residue, close enough to the bonding atom
125
+ that the template overwrites its charge, that is already bonded to
126
+ another residue. A template declaring a sibling describes that atom
127
+ as reacted, so it must not be used where the atom has not; a template
128
+ declaring none has always been used regardless, and still is.
129
+
114
130
  Args:
115
131
  other (BondTemplate): the instance bond to test for compatibility
116
132
 
@@ -133,6 +149,12 @@ class BondTemplate:
133
149
  remaining.remove(tp)
134
150
  else:
135
151
  return False
152
+ remaining = list(other.siblings[side])
153
+ for sib in self.siblings[side]:
154
+ if sib in remaining:
155
+ remaining.remove(sib)
156
+ else:
157
+ return False
136
158
  return True
137
159
 
138
160
  def matches_reverse_of(self, other):
@@ -506,7 +506,7 @@ class Molecule:
506
506
  # logger.debug(f'{self.name} oneaways {oneaway_resids} {oneaway_resnames} {oneaway_atomidx} {oneaway_atomnames}')
507
507
  self.reaction_bonds.append(ReactionBond(atom_idx, in_product_resids, order, bystander_resids, bystander_atomidx, oneaway_resids, oneaway_atomidx))
508
508
  intraresidue = in_product_resids[0] == in_product_resids[1]
509
- self.bond_templates.append(BondTemplate(atom_names, in_product_resnames, intraresidue, order, bystander_resnames, bystander_atomnames, oneaway_resnames, oneaway_atomnames))
509
+ self.bond_templates.append(BondTemplate(atom_names, in_product_resnames, intraresidue, order, bystander_resnames, bystander_atomnames, oneaway_resnames, oneaway_atomnames, siblings=TC.get_siblings(atom_idx)))
510
510
 
511
511
  def idx_mappers(self, otherTC: TopoCoord, other_bond, bystanders, oneaways, uniq_atom_idx: set):
512
512
  """Computes the mapping dictionary from molecule template index to instance index in the other TopoCoord.
@@ -17,6 +17,7 @@ libraries keep working rather than silently re-parameterizing wholesale.
17
17
 
18
18
  Author: Cameron F. Abrams <cfa22@drexel.edu>
19
19
  """
20
+ import hashlib
20
21
  import json
21
22
  import logging
22
23
  import os
@@ -33,6 +34,30 @@ _KEY_FIELDS = (
33
34
  )
34
35
  """Fields that determine the parameters, with human-readable labels."""
35
36
 
37
+ FRCMOD_FIELD = 'frcmod'
38
+ """Record field holding a digest of the user frcmod files loaded after parmchk2's.
39
+
40
+ Written only when a molecule has any, so records of molecules without one are
41
+ unchanged; its absence means "none" when compared.
42
+ """
43
+
44
+
45
+ def frcmod_digest(frcmods):
46
+ """Returns a digest identifying a list of user frcmod files by content.
47
+
48
+ Args:
49
+ frcmods (list): (label, text) tuples, in load order
50
+
51
+ Returns:
52
+ str or None: hex digest, or None if the list is empty
53
+ """
54
+ if not frcmods:
55
+ return None
56
+ h = hashlib.sha256()
57
+ for label, text in frcmods:
58
+ h.update(label.encode('utf-8') + b'\0' + text.encode('utf-8') + b'\0')
59
+ return h.hexdigest()[:16]
60
+
36
61
 
37
62
  def build_key(ambertools=None):
38
63
  """Returns the provenance record describing a parameterization run under
@@ -49,8 +74,12 @@ def build_key(ambertools=None):
49
74
  """
50
75
  from ..external.ambertools import AMBERTOOLS_DEFAULTS
51
76
  ambertools = ambertools or {}
52
- return {field: ambertools.get(field, AMBERTOOLS_DEFAULTS[field])
53
- for field, _ in _KEY_FIELDS}
77
+ key = {field: ambertools.get(field, AMBERTOOLS_DEFAULTS[field])
78
+ for field, _ in _KEY_FIELDS}
79
+ digest = frcmod_digest(ambertools.get(FRCMOD_FIELD))
80
+ if digest:
81
+ key[FRCMOD_FIELD] = digest
82
+ return key
54
83
 
55
84
 
56
85
  def key_filename(prefix):
@@ -129,4 +158,8 @@ def describe_mismatch(stored, requested):
129
158
  continue
130
159
  if stored[field] != requested.get(field):
131
160
  diffs.append(f'{label} {stored[field]!r} cached, {requested.get(field)!r} requested')
161
+ # unlike the fields above, an absent frcmod digest is a statement: none was loaded
162
+ if stored.get(FRCMOD_FIELD) != requested.get(FRCMOD_FIELD):
163
+ diffs.append(f'user frcmod {stored.get(FRCMOD_FIELD) or "none"} cached, '
164
+ f'{requested.get(FRCMOD_FIELD) or "none"} requested')
132
165
  return diffs