htpolynet 2.9.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.
- {htpolynet-2.9.0 → htpolynet-2.10.0}/CHANGELOG.md +14 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/PKG-INFO +1 -1
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/user-guide/configs/configs-for-run.rst +27 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/pyproject.toml +1 -1
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/core/paramcache.py +35 -2
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/core/runtime.py +67 -4
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/core/topology.py +43 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/external/ambertools.py +23 -1
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/schema/base.yaml +12 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/tests/unit/test_paramcache.py +4 -2
- htpolynet-2.10.0/tests/unit/test_user_frcmod.py +149 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/.claude/settings.json +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/.claude/skills/htpolynet/SKILL.md +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/.envrc +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/.github/workflows/conda-forge-sync.yml +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/.github/workflows/docker.yml +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/.github/workflows/docs.yml +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/.github/workflows/release.yaml +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/.github/workflows/test.yml +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/.gitignore +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/.readthedocs.yaml +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/CITATION.cff +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/CLAUDE.md +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/LICENSE +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/MANIFEST.in +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/README.md +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/ROADMAP.md +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docker/Dockerfile +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docker/compose.yml +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docker/docker-entrypoint.sh +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/Makefile +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/README.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/make.bat +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/requirements.txt +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/_static/.gitkeep +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/_static/htpolynet-favicon.ico +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/_static/htpolynet-landing.jpg +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/_static/htpolynet-logo-dark.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/_static/htpolynet-logo-light.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/changelog.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/conf.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/0-liquid-styrene/configuration.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/0-liquid-styrene/index.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/0-liquid-styrene/introduction.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/0-liquid-styrene/monomer.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/0-liquid-styrene/postsim.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/0-liquid-styrene/results.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/0-liquid-styrene/run.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/1-polystyrene/configuration.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/1-polystyrene/index.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/1-polystyrene/introduction.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/1-polystyrene/monomer.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/1-polystyrene/pics/STY.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/1-polystyrene/pics/STYCC.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/1-polystyrene/pics/buildtraces.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/1-polystyrene/pics/cure_info.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/1-polystyrene/pics/densification-density.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/1-polystyrene/pics/final-box.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/1-polystyrene/pics/reaction_network.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/1-polystyrene/pics/sty-coloring.tcl +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/1-polystyrene/pics/sty-cured.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/1-polystyrene/pics/sty-detail.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/1-polystyrene/pics/sty-liq.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/1-polystyrene/pics/styrene-polymerization.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/1-polystyrene/postsim.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/1-polystyrene/reactions.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/1-polystyrene/results.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/1-polystyrene/run.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/configuration.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/index.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/introduction.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/BPA.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/GMA.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/HIE.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/buildtraces.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/cure_info.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/densification-density.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/four_dimers.eps +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/four_dimers.fig +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/four_dimers.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/gma-sty-coloring.tcl +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/gma-sty-cured.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/gma-sty-detail.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/gma-sty-liq.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/p1-traces.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/reaction_network.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/vesys.eps +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/vesys.fig +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/vesys.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/postsim.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/reactions.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/results.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/run.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/configuration.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/index.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/introduction.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/monomers.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/DGE-epoxy.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/DGE-labelled.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/PAC-2d.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/PAC-labelled.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/buildtraces.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/cure_info.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/densification-density.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/dge-pac-coloring.tcl +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/dge-pac-cured.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/dge-pac-detail.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/dge-pac-liq.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/dgesys.eps +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/dgesys.fig +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/dgesys.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/equil-rho_v_ns.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/postsim-typical.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/prod-e.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/prod-equil-rho_v_ns.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/prod-rho_v_ns.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/prod-tg.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/r1.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/r2.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/r3.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/reaction_network.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/rho_v_ns.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/short-e.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/short-tg.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/postsim.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/reactions.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/results.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/run.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/configuration.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/index.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/introduction.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/monomers.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/buildtraces.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/cure_info.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/densification-density.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/dfa-fde-coloring.tcl +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/dfa-fde-cured.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/dfa-fde-detail.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/dfa-fde-liq.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/reaction_network.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/postsim.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/reactions.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/results.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/run.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/5-htpb-ipdi/configuration.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/5-htpb-ipdi/index.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/5-htpb-ipdi/introduction.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/5-htpb-ipdi/monomers.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/5-htpb-ipdi/pics/buildtraces.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/5-htpb-ipdi/pics/cure_info.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/5-htpb-ipdi/pics/densification-density.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/5-htpb-ipdi/pics/htpb-coloring.tcl +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/5-htpb-ipdi/pics/htpb-ipdi-cured.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/5-htpb-ipdi/pics/htpb-ipdi-detail.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/5-htpb-ipdi/pics/htpb-ipdi-liq.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/5-htpb-ipdi/pics/reaction_network.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/5-htpb-ipdi/postsim.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/5-htpb-ipdi/reactions.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/5-htpb-ipdi/results.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/5-htpb-ipdi/run.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/6-cyanate-ester/configuration.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/6-cyanate-ester/index.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/6-cyanate-ester/introduction.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/6-cyanate-ester/monomers.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/6-cyanate-ester/pics/badcy-coloring.tcl +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/6-cyanate-ester/pics/badcy-cured.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/6-cyanate-ester/pics/badcy-detail.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/6-cyanate-ester/pics/badcy-liq.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/6-cyanate-ester/pics/buildtraces.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/6-cyanate-ester/pics/cure_info.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/6-cyanate-ester/pics/densification-density.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/6-cyanate-ester/pics/reaction_network.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/6-cyanate-ester/postsim.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/6-cyanate-ester/reactions.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/6-cyanate-ester/results.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/6-cyanate-ester/run.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/index.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/htpolynetpackage.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/index.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/install.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/references/index.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/references/mol2-reference.pdf +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/references.bib +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/user-guide/CURE.odg +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/user-guide/bond_filter.odg +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/user-guide/building-a-system.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/user-guide/configs/configs-for-analyze.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/user-guide/configs/configs-for-postsim.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/user-guide/configuration-files.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/user-guide/container-usage.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/user-guide/flow1.odg +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/user-guide/flow1yaml.odg +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/user-guide/hydrogenated.eps +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/user-guide/hydrogenated.fig +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/user-guide/index.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/user-guide/molecular-structure-inputs.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/user-guide/periodic-networks.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/user-guide/pics/STY.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/user-guide/pics/STYCC.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/user-guide/pics/TypicalUsageFlow.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/user-guide/pics/bond_filter.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/user-guide/pics/chemdoodle-2dsketcher-emb.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/user-guide/pics/chemdoodle-2dsketcher-styrene.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/user-guide/pics/hydrogenated.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/user-guide/pics/ring_pierce/ring_pierce_cases.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/user-guide/pics/ring_pierce/ring_pierce_linkcell.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/user-guide/postcure-repair.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/user-guide/program-flow.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/user-guide/usage.rst +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/scripts/check-conda-sync.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/scripts/release.sh +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/scripts/render-detail.sh +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/scripts/render-detail.tcl +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/scripts/render-snapshot.sh +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/scripts/run_all_examples.sh +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/__init__.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/analysis/__init__.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/analysis/analyze.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/analysis/plot.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/analysis/postsim.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/analysis/utils.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/cli.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/core/__init__.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/core/bondtemplate.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/core/configuration.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/core/coordinates.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/core/molecule.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/core/projectfilesystem.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/core/topocoord.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/cure/__init__.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/cure/chain.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/cure/curecontroller.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/cure/expandreactions.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/cure/reaction.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/external/__init__.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/external/command.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/external/gromacs.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/external/slurm.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/external/smiles_input.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/external/software.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/geometry/__init__.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/geometry/bondlist.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/geometry/lattice.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/geometry/linkcell.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/geometry/matrix4.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/geometry/ring.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/io/__init__.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/io/gro.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/io/mol2.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/io/pdb.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/repair/__init__.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/repair/cyanate_cap.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/repair/topology_surgery.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/resources/README.md +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/resources/__init__.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/resources/claude/SKILL.md +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/resources/example_depot/0-liquid-styrene.yaml +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/resources/example_depot/1-polystyrene.yaml +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/resources/example_depot/2-bisgma-styrene-thermoset.yaml +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/resources/example_depot/3-pacm-dgeba-epoxy-thermoset.yaml +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/resources/example_depot/4-dfda-fde-epoxy-thermoset.yaml +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/resources/example_depot/5-htpb-ipdi.yaml +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/resources/example_depot/6-cyanate-ester.yaml +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/resources/mdp/README.md +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/resources/mdp/drag-min.mdp +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/resources/mdp/drag-npt.mdp +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/resources/mdp/drag-nvt.mdp +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/resources/mdp/min.mdp +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/resources/mdp/npt.mdp +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/resources/mdp/nvt.mdp +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/resources/mdp/relax-min.mdp +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/resources/mdp/relax-npt.mdp +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/resources/mdp/relax-nvt.mdp +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/resources/mdp/single-molecule-min.mdp +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/resources/mdp/single-molecule-nvt.mdp +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/resources/molecules/inputs/DFA.pdb +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/resources/molecules/inputs/DGE.mol2 +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/resources/molecules/inputs/EMB.mol2 +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/resources/molecules/inputs/FDE.pdb +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/resources/molecules/inputs/GMA.mol2 +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/resources/molecules/inputs/PAC.mol2 +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/resources/molecules/inputs/STY.mol2 +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/resources/molecules/make-monomers.sh +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/resources/molecules/pics/DFA.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/resources/molecules/pics/DGE.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/resources/molecules/pics/EMB.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/resources/molecules/pics/FDE.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/resources/molecules/pics/GMA.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/resources/molecules/pics/PAC.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/resources/molecules/pics/STY.png +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/resources/molecules/sample-inputs/DFA.pdb +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/resources/molecules/sample-inputs/DGE.mol2 +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/resources/molecules/sample-inputs/EMB.mol2 +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/resources/molecules/sample-inputs/FDE.pdb +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/resources/molecules/sample-inputs/GMA.mol2 +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/resources/molecules/sample-inputs/PAC.mol2 +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/resources/molecules/sample-inputs/STY.mol2 +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/resources/tcl/readbonds.tcl +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/resources/tcl/readgrx.tcl +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/resources/tcl/render.tcl +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/utils/__init__.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/utils/banner.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/utils/checkpoint.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/utils/convergence.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/utils/dataframetools.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/utils/inputcheck.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/utils/logsetup.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/utils/profiling.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/utils/stringthings.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/src/htpolynet/utils/vmd_viz.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/tests/__init__.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/tests/conftest.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/tests/unit/__init__.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/tests/unit/fixtures/config1.gro +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/tests/unit/fixtures/config1.top +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/tests/unit/fixtures/config2.gro +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/tests/unit/fixtures/config2.top +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/tests/unit/fixtures/items31.edr +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/tests/unit/fixtures/items43.edr +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/tests/unit/fixtures/items45.edr +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/tests/unit/fixtures/short.mdp +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/tests/unit/test_bondtemplate.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/tests/unit/test_cap_placement.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/tests/unit/test_chain.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/tests/unit/test_completion_bias.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/tests/unit/test_conda_sync.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/tests/unit/test_configuration.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/tests/unit/test_convergence.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/tests/unit/test_cure_site_functionality.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/tests/unit/test_dataframetools.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/tests/unit/test_density_gate.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/tests/unit/test_gpu_usability.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/tests/unit/test_gromacs_get_energy_menu.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/tests/unit/test_gromacs_gmx_energy_trace.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/tests/unit/test_inputcheck.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/tests/unit/test_linkcell_pierce.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/tests/unit/test_mol2_bond_fallback.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/tests/unit/test_molecule_charge_report.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/tests/unit/test_moleculetype_name.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/tests/unit/test_paramcache_ambertools.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/tests/unit/test_parameterize_react.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/tests/unit/test_plot_smoke.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/tests/unit/test_projectfilesystem.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/tests/unit/test_relax_instrumentation.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/tests/unit/test_repair_charge_neutrality.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/tests/unit/test_repair_conversion.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/tests/unit/test_resources.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/tests/unit/test_ring.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/tests/unit/test_ring_pierce_figs.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/tests/unit/test_setup_claude.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/tests/unit/test_sibling_templates.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/tests/unit/test_slurm_script.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/tests/unit/test_smiles_input.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/tests/unit/test_software_provenance.py +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/tests/unit/test_topology/test.top +0 -0
- {htpolynet-2.9.0 → htpolynet-2.10.0}/tests/unit/test_topology.py +0 -0
|
@@ -7,6 +7,20 @@ 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
|
+
|
|
10
24
|
## [2.9.0] - 2026-09-15
|
|
11
25
|
|
|
12
26
|
### Added
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: htpolynet
|
|
3
|
-
Version: 2.
|
|
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/
|
|
@@ -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.
|
|
@@ -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
|
-
|
|
53
|
-
|
|
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
|
|
@@ -20,7 +20,7 @@ from ..core import projectfilesystem as pfs
|
|
|
20
20
|
from ..core.configuration import Configuration
|
|
21
21
|
from ..core.molecule import Molecule, MoleculeDict
|
|
22
22
|
from ..core.topocoord import TopoCoord
|
|
23
|
-
from ..core.topology import select_topology_type_option
|
|
23
|
+
from ..core.topology import conflicting_types, select_topology_type_option
|
|
24
24
|
from ..cure.chain import ChainManager
|
|
25
25
|
from ..cure.curecontroller import CureController, CureState
|
|
26
26
|
from ..cure.expandreactions import bondchain_expand_reactions, generate_stereo_reactions, generate_symmetry_reactions, sibling_expand_reactions
|
|
@@ -150,6 +150,7 @@ class Runtime:
|
|
|
150
150
|
self.restart=restart
|
|
151
151
|
if restart:
|
|
152
152
|
logger.info(f'Restarting in {pfs.proj()}')
|
|
153
|
+
self.frcmods=self._read_frcmods()
|
|
153
154
|
self.molecules:MoleculeDict={}
|
|
154
155
|
# molecules reused from a library entry that carries no provenance
|
|
155
156
|
# record, collected for a stage-end summary; see generate_molecules
|
|
@@ -194,6 +195,66 @@ class Runtime:
|
|
|
194
195
|
if k not in current:
|
|
195
196
|
current[k]=v
|
|
196
197
|
|
|
198
|
+
def _read_frcmods(self):
|
|
199
|
+
"""Reads the user frcmod file each constituent names, if any.
|
|
200
|
+
|
|
201
|
+
Returns:
|
|
202
|
+
dict: {constituent name: frcmod text}
|
|
203
|
+
|
|
204
|
+
Raises:
|
|
205
|
+
FileNotFoundError: if a named frcmod file does not exist
|
|
206
|
+
"""
|
|
207
|
+
frcmods={}
|
|
208
|
+
for name,rec in (self.cfg.constituents or {}).items():
|
|
209
|
+
fn=(rec or {}).get('frcmod')
|
|
210
|
+
if not fn: continue
|
|
211
|
+
path=os.path.join(pfs.root(),fn)
|
|
212
|
+
if not os.path.isfile(path):
|
|
213
|
+
raise FileNotFoundError(f'frcmod {fn!r} for constituent {name} not found (looked for {path})')
|
|
214
|
+
with open(path) as f:
|
|
215
|
+
frcmods[name]=f.read()
|
|
216
|
+
logger.info(f'{name}: user frcmod {fn} will be loaded for {name} and every template containing it')
|
|
217
|
+
return frcmods
|
|
218
|
+
|
|
219
|
+
def _ambertools_for(self,M:Molecule):
|
|
220
|
+
"""Returns the AmberTools directives for parameterizing M.
|
|
221
|
+
|
|
222
|
+
These are the configuration's, plus the user frcmod files of every
|
|
223
|
+
constituent residue M contains, so that a template built around a
|
|
224
|
+
monomer carries the same override as the monomer.
|
|
225
|
+
|
|
226
|
+
Args:
|
|
227
|
+
M (Molecule): molecule about to be parameterized, or checked against the cache
|
|
228
|
+
|
|
229
|
+
Returns:
|
|
230
|
+
dict: ambertools directives
|
|
231
|
+
"""
|
|
232
|
+
amb=dict(self.cfg.ambertools or {})
|
|
233
|
+
residues=set(getattr(M,'sequence',None) or [M.name])
|
|
234
|
+
frc=[(n,t) for n,t in sorted(getattr(self,'frcmods',{}).items()) if n in residues]
|
|
235
|
+
if frc:
|
|
236
|
+
amb['frcmod']=frc
|
|
237
|
+
return amb
|
|
238
|
+
|
|
239
|
+
def _check_frcmod_type_conflicts(self):
|
|
240
|
+
"""Refuses a set of molecules that a user frcmod leaves with conflicting bonded types.
|
|
241
|
+
|
|
242
|
+
Raises:
|
|
243
|
+
RuntimeError: if a type is parameterized differently in molecules built with and
|
|
244
|
+
without (or with different) user frcmod files
|
|
245
|
+
"""
|
|
246
|
+
if not getattr(self,'frcmods',None): return
|
|
247
|
+
tops={n:(M.TopoCoord.Topology,paramcache.frcmod_digest(self._ambertools_for(M).get('frcmod')))
|
|
248
|
+
for n,M in self.molecules.items() if M.TopoCoord.Topology.D.get('atoms') is not None}
|
|
249
|
+
conflicts=conflicting_types(tops)
|
|
250
|
+
if not conflicts: return
|
|
251
|
+
for typename,key,a,b in conflicts[:10]:
|
|
252
|
+
logger.error(f'{typename} {"-".join(key[:-1])} (func {key[-1]}) differs between {a} and {b}')
|
|
253
|
+
raise RuntimeError(f'{len(conflicts)} bonded type(s) are parameterized differently in molecules built with and '
|
|
254
|
+
f'without a user frcmod. A system has one table per type, so the override cannot apply to '
|
|
255
|
+
f'some molecules and not others. Give the overridden atoms their own atom type, or apply '
|
|
256
|
+
f'the frcmod to every constituent that contains the type.')
|
|
257
|
+
|
|
197
258
|
def _build_molecules_and_reactions(self):
|
|
198
259
|
"""Builds Molecule and Reaction objects from the parsed configuration.
|
|
199
260
|
|
|
@@ -331,6 +392,8 @@ class Runtime:
|
|
|
331
392
|
self.molecules[mname]=M
|
|
332
393
|
logger.debug(f'Generated {mname}')
|
|
333
394
|
|
|
395
|
+
self._check_frcmod_type_conflicts()
|
|
396
|
+
|
|
334
397
|
for M in self.molecules:
|
|
335
398
|
self.molecules[M].is_reactant=is_reactant(M,self.reactions,stage=reaction_stage.cure)
|
|
336
399
|
|
|
@@ -781,7 +844,7 @@ class Runtime:
|
|
|
781
844
|
list: descriptions of the differing directives; empty if the cached
|
|
782
845
|
parameterization agrees with this run or carries no record
|
|
783
846
|
"""
|
|
784
|
-
requested = paramcache.build_key(self.
|
|
847
|
+
requested = paramcache.build_key(self._ambertools_for(M))
|
|
785
848
|
# Discard any record left in the project directory by an earlier run so
|
|
786
849
|
# that what we check is the record belonging to the library entry that
|
|
787
850
|
# previously_parameterized() just found.
|
|
@@ -829,7 +892,7 @@ class Runtime:
|
|
|
829
892
|
generatable=(not M.generator) or (all([m in self.molecules for m in M.generator.reactants.values()]))
|
|
830
893
|
if generatable:
|
|
831
894
|
logger.debug(f'Generating {mname}')
|
|
832
|
-
M.generate(available_molecules=self.molecules,gaff=self.cfg.gaff,ambertools=self.
|
|
895
|
+
M.generate(available_molecules=self.molecules,gaff=self.cfg.gaff,ambertools=self._ambertools_for(M))
|
|
833
896
|
self._checkin_parameterization(mname, force_checkin)
|
|
834
897
|
M.origin='newly parameterized'
|
|
835
898
|
else:
|
|
@@ -899,7 +962,7 @@ class Runtime:
|
|
|
899
962
|
# assert it matches what falls out of the merged dataframe).
|
|
900
963
|
M.set_sequence_from_moldict(self.molecules)
|
|
901
964
|
M.generate(available_molecules=self.molecules,
|
|
902
|
-
gaff=self.cfg.gaff, ambertools=self.
|
|
965
|
+
gaff=self.cfg.gaff, ambertools=self._ambertools_for(M))
|
|
903
966
|
self._checkin_parameterization(mname, True)
|
|
904
967
|
M.origin='newly parameterized (stale cache refreshed)'
|
|
905
968
|
else:
|
|
@@ -137,6 +137,49 @@ _GromacsTopologyDirectiveDefaults_ = {
|
|
|
137
137
|
'defaults': [1, 2, 'yes', 0.5, 0.83333333]
|
|
138
138
|
}
|
|
139
139
|
|
|
140
|
+
def conflicting_types(topologies, typenames=('bondtypes', 'angletypes', 'dihedraltypes')):
|
|
141
|
+
"""Finds bonded types that two groups of topologies parameterize differently.
|
|
142
|
+
|
|
143
|
+
A merged topology keeps one table per type, shared by every molecule in
|
|
144
|
+
it, so a type with different parameters in two molecules cannot be
|
|
145
|
+
honored for both: drop_duplicates keeps both sets, and GROMACS applies
|
|
146
|
+
them together. A user frcmod loaded for some molecules and not others is
|
|
147
|
+
the usual way to create one.
|
|
148
|
+
|
|
149
|
+
Args:
|
|
150
|
+
topologies (dict): {name: (Topology, group)}; types are compared only between topologies
|
|
151
|
+
whose groups differ, e.g. a digest of the frcmod files each was built with
|
|
152
|
+
typenames (tuple): type sections to compare
|
|
153
|
+
|
|
154
|
+
Returns:
|
|
155
|
+
list: (typename, type key, name of one topology, name of another) tuples, one per conflicting
|
|
156
|
+
type; the key is the atom types followed by the function number
|
|
157
|
+
"""
|
|
158
|
+
seen = {}
|
|
159
|
+
conflicts = []
|
|
160
|
+
for name, (T, group) in topologies.items():
|
|
161
|
+
for typename in typenames:
|
|
162
|
+
df = T.D.get(typename)
|
|
163
|
+
if df is None or df.empty:
|
|
164
|
+
continue
|
|
165
|
+
hashables = _GromacsTopologyHashables_[typename]
|
|
166
|
+
params = [c for c in df.columns if c not in hashables]
|
|
167
|
+
rows = {}
|
|
168
|
+
for r in df.itertuples(index=False):
|
|
169
|
+
r = r._asdict()
|
|
170
|
+
t = tuple(r[h] for h in hashables)
|
|
171
|
+
# a proper and an improper can share atom types; they are different types
|
|
172
|
+
key = (*min(t, t[::-1]), int(r['func']) if 'func' in r else 0)
|
|
173
|
+
rows.setdefault(key, []).append(tuple(round(float(r[p]), 4) if isinstance(r[p], (int, float)) else r[p]
|
|
174
|
+
for p in params))
|
|
175
|
+
for key, values in rows.items():
|
|
176
|
+
values = tuple(sorted(values))
|
|
177
|
+
first = seen.setdefault((typename, key), (name, group, values))
|
|
178
|
+
if first[1] != group and first[2] != values:
|
|
179
|
+
conflicts.append((typename, key, first[0], name))
|
|
180
|
+
return conflicts
|
|
181
|
+
|
|
182
|
+
|
|
140
183
|
def select_topology_type_option(options, typename='dihedraltypes', rule='stiffest'):
|
|
141
184
|
"""Selects from a list of topological interaction options of type typename using the provided rule.
|
|
142
185
|
|
|
@@ -28,6 +28,15 @@ invocations below and the provenance record written beside their output; see
|
|
|
28
28
|
"""
|
|
29
29
|
|
|
30
30
|
|
|
31
|
+
def leapsafe(name):
|
|
32
|
+
"""Returns a tleap-safe file stem for name.
|
|
33
|
+
|
|
34
|
+
tleap reads a bare filename containing 'e' after a digit as a number, so
|
|
35
|
+
names are hashed, as GAFFParameterize does for its own files.
|
|
36
|
+
"""
|
|
37
|
+
return 'u' + hashlib.shake_128(name.encode('utf-8')).hexdigest(8).replace('e', 'x')
|
|
38
|
+
|
|
39
|
+
|
|
31
40
|
def GAFFParameterize(inputPrefix, outputPrefix, input_structure_format='mol2', ambertools=None):
|
|
32
41
|
"""Manages execution of antechamber, parmchk2, and tleap to generate GAFF parameters,
|
|
33
42
|
then converts the result to Gromacs gro/top files via parmed.
|
|
@@ -36,7 +45,9 @@ def GAFFParameterize(inputPrefix, outputPrefix, input_structure_format='mol2', a
|
|
|
36
45
|
inputPrefix (str): basename of input structure file
|
|
37
46
|
outputPrefix (str): basename of output files
|
|
38
47
|
input_structure_format (str): format of input structure file, defaults to 'mol2'; 'pdb' is other option
|
|
39
|
-
ambertools (dict | None): ambertools configuration directives, defaults to None
|
|
48
|
+
ambertools (dict | None): ambertools configuration directives, defaults to None; an
|
|
49
|
+
``frcmod`` entry, a list of (label, text) tuples, names user frcmod files that
|
|
50
|
+
tleap loads after parmchk2's, so their parameters take precedence
|
|
40
51
|
|
|
41
52
|
Raises:
|
|
42
53
|
parmed.exceptions.GromacsError: if parmed fails to convert tleap output
|
|
@@ -65,6 +76,13 @@ def GAFFParameterize(inputPrefix, outputPrefix, input_structure_format='mol2', a
|
|
|
65
76
|
f' -at {atomtype} -i {new_structin} -o {mol2out} -pf Y -nc {netcharge} -eq 1 -pl 10', quiet=False)
|
|
66
77
|
logger.debug(f'AmberTools> Antechamber generated {mol2out}')
|
|
67
78
|
run(f'parmchk2 -i {mol2out} -o {frcmodout} -f mol2 -s {atomtype}', quiet=False)
|
|
79
|
+
user_frcmods = []
|
|
80
|
+
for label, text in ambertools.get('frcmod') or []:
|
|
81
|
+
fn = f'{leapsafe(label)}-user.frcmod'
|
|
82
|
+
with open(fn, 'w') as f:
|
|
83
|
+
f.write(text)
|
|
84
|
+
user_frcmods.append(fn)
|
|
85
|
+
logger.info(f'AmberTools> loading user frcmod for {label} into {outputPrefix}')
|
|
68
86
|
|
|
69
87
|
# Antechamber ignores SUBSTRUCTURE records, so patch the antechamber output
|
|
70
88
|
# mol2 with the original resName/resNum before passing it to tleap.
|
|
@@ -92,6 +110,8 @@ def GAFFParameterize(inputPrefix, outputPrefix, input_structure_format='mol2', a
|
|
|
92
110
|
# fires, and we abort even though tleap would have completed once
|
|
93
111
|
# the frcmod was loaded.
|
|
94
112
|
f'loadamberparams {leapprefix}.frcmod',
|
|
113
|
+
# user files last, so they override both GAFF and parmchk2's guesses
|
|
114
|
+
*[f'loadamberparams {fn}' for fn in user_frcmods],
|
|
95
115
|
f'mymol = loadmol2 {leapprefix}.mol2',
|
|
96
116
|
'check mymol',
|
|
97
117
|
f'saveamberparm mymol {leapprefix}-tleap.top {leapprefix}-tleap.crd',
|
|
@@ -102,6 +122,8 @@ def GAFFParameterize(inputPrefix, outputPrefix, input_structure_format='mol2', a
|
|
|
102
122
|
run(f'tleap -f {inputPrefix}-tleap.in', override=('Error!', 'Unspecified tleap error'))
|
|
103
123
|
|
|
104
124
|
os.remove(f'{leapprefix}.frcmod')
|
|
125
|
+
for fn in user_frcmods:
|
|
126
|
+
os.remove(fn)
|
|
105
127
|
shutil.move(f'{leapprefix}.mol2', mol2out)
|
|
106
128
|
shutil.move(f'{leapprefix}-tleap.top', f'{outputPrefix}-tleap.top')
|
|
107
129
|
shutil.move(f'{leapprefix}-tleap.crd', f'{outputPrefix}-tleap.crd')
|
|
@@ -192,6 +192,18 @@ attributes:
|
|
|
192
192
|
- name: symmetry_equivalent_atoms
|
|
193
193
|
type: list
|
|
194
194
|
text: Sets of symmetry-equivalent atom names, if any.
|
|
195
|
+
- name: frcmod
|
|
196
|
+
type: str
|
|
197
|
+
required: false
|
|
198
|
+
text: >
|
|
199
|
+
Path, relative to the configuration file, to an Amber frcmod file of
|
|
200
|
+
parameter overrides for this molecule. tleap loads it after GAFF and
|
|
201
|
+
parmchk2, so its entries win. It is loaded for this molecule and for
|
|
202
|
+
every template containing it, and it is part of each parameterization's
|
|
203
|
+
cache record, so editing the file re-parameterizes them. A system
|
|
204
|
+
keeps one table per bonded type, so an overridden type must not also
|
|
205
|
+
occur, unoverridden, in a molecule without this residue; setup stops if
|
|
206
|
+
it does.
|
|
195
207
|
- name: conformers
|
|
196
208
|
type: dict
|
|
197
209
|
required: false
|
|
@@ -63,8 +63,10 @@ def _library_entry(library, name, **ambertools):
|
|
|
63
63
|
|
|
64
64
|
def _runtime(**ambertools):
|
|
65
65
|
"""A stand-in for Runtime carrying only what the check reads off it."""
|
|
66
|
-
|
|
67
|
-
|
|
66
|
+
r = SimpleNamespace(cfg=SimpleNamespace(ambertools=ambertools),
|
|
67
|
+
unverified_parameterizations=[], frcmods={})
|
|
68
|
+
r._ambertools_for = lambda M: Runtime._ambertools_for(r, M)
|
|
69
|
+
return r
|
|
68
70
|
|
|
69
71
|
|
|
70
72
|
def _mismatch(name='TAZ', **ambertools):
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
"""
|
|
2
|
+
|
|
3
|
+
.. module:: test_user_frcmod
|
|
4
|
+
:synopsis: a constituent's frcmod reaches its own parameterization, every template containing it,
|
|
5
|
+
and the parameter-cache record, and nothing else
|
|
6
|
+
|
|
7
|
+
.. moduleauthor: Cameron F. Abrams, <cfa22@drexel.edu>
|
|
8
|
+
|
|
9
|
+
"""
|
|
10
|
+
import os
|
|
11
|
+
import shutil
|
|
12
|
+
from types import SimpleNamespace
|
|
13
|
+
|
|
14
|
+
import pandas as pd
|
|
15
|
+
import pytest
|
|
16
|
+
|
|
17
|
+
import htpolynet.core.projectfilesystem as pfs
|
|
18
|
+
from htpolynet.core import paramcache
|
|
19
|
+
from htpolynet.core.molecule import Molecule
|
|
20
|
+
from htpolynet.core.runtime import Runtime
|
|
21
|
+
from htpolynet.core.topology import Topology, conflicting_types
|
|
22
|
+
|
|
23
|
+
FRC = ('BAF', 'MASS\n\nDIHE\nca-ca-c3-ca 1 0.3190 180.0 -2.0\n\n')
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class TestCacheRecord:
|
|
27
|
+
def test_no_frcmod_leaves_the_record_as_it_was(self):
|
|
28
|
+
assert paramcache.FRCMOD_FIELD not in paramcache.build_key({'charge_method': 'bcc'})
|
|
29
|
+
|
|
30
|
+
def test_frcmod_is_recorded_by_content(self):
|
|
31
|
+
a = paramcache.build_key({'frcmod': [FRC]})
|
|
32
|
+
b = paramcache.build_key({'frcmod': [(FRC[0], FRC[1] + 'x')]})
|
|
33
|
+
assert a[paramcache.FRCMOD_FIELD] != b[paramcache.FRCMOD_FIELD]
|
|
34
|
+
assert a == paramcache.build_key({'frcmod': [FRC]})
|
|
35
|
+
|
|
36
|
+
def test_plain_cache_entry_is_a_miss_when_a_frcmod_is_requested(self):
|
|
37
|
+
diffs = paramcache.describe_mismatch(paramcache.build_key({}), paramcache.build_key({'frcmod': [FRC]}))
|
|
38
|
+
assert any('frcmod' in d for d in diffs)
|
|
39
|
+
|
|
40
|
+
def test_overridden_cache_entry_is_a_miss_when_none_is_requested(self):
|
|
41
|
+
assert paramcache.describe_mismatch(paramcache.build_key({'frcmod': [FRC]}), paramcache.build_key({}))
|
|
42
|
+
|
|
43
|
+
def test_edited_frcmod_is_a_miss(self):
|
|
44
|
+
assert paramcache.describe_mismatch(paramcache.build_key({'frcmod': [FRC]}),
|
|
45
|
+
paramcache.build_key({'frcmod': [(FRC[0], FRC[1] + '\n')]}))
|
|
46
|
+
|
|
47
|
+
def test_record_from_before_frcmods_matches_a_run_without_one(self):
|
|
48
|
+
stored = {'charge_method': 'bcc', 'net_charge': 0, 'atom_type': 'gaff'}
|
|
49
|
+
assert paramcache.describe_mismatch(stored, paramcache.build_key({})) == []
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class TestWhichMoleculesGetIt:
|
|
53
|
+
def runtime(self):
|
|
54
|
+
r = SimpleNamespace(cfg=SimpleNamespace(ambertools={'atom_type': 'gaff2'}), frcmods={'BAF': FRC[1]})
|
|
55
|
+
return r
|
|
56
|
+
|
|
57
|
+
def test_the_monomer(self):
|
|
58
|
+
amb = Runtime._ambertools_for(self.runtime(), SimpleNamespace(name='BAF', sequence=['BAF']))
|
|
59
|
+
assert amb['frcmod'] == [FRC]
|
|
60
|
+
assert amb['atom_type'] == 'gaff2'
|
|
61
|
+
|
|
62
|
+
def test_every_template_containing_it(self):
|
|
63
|
+
M = SimpleNamespace(name='BAF~O1-C1~BAF~O1-C2~TAZ', sequence=['BAF', 'BAF', 'TAZ'])
|
|
64
|
+
assert Runtime._ambertools_for(self.runtime(), M)['frcmod'] == [FRC]
|
|
65
|
+
|
|
66
|
+
def test_not_a_molecule_without_it(self):
|
|
67
|
+
assert 'frcmod' not in Runtime._ambertools_for(self.runtime(), SimpleNamespace(name='TAZ', sequence=['TAZ']))
|
|
68
|
+
|
|
69
|
+
def test_configuration_directives_are_not_mutated(self):
|
|
70
|
+
r = self.runtime()
|
|
71
|
+
Runtime._ambertools_for(r, SimpleNamespace(name='BAF', sequence=['BAF']))
|
|
72
|
+
assert 'frcmod' not in r.cfg.ambertools
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
class TestReadFrcmods:
|
|
76
|
+
def runtime(self, constituents):
|
|
77
|
+
return SimpleNamespace(cfg=SimpleNamespace(constituents=constituents))
|
|
78
|
+
|
|
79
|
+
def test_reads_relative_to_the_configuration(self, tmp_path):
|
|
80
|
+
(tmp_path / 'baf.frcmod').write_text(FRC[1])
|
|
81
|
+
pfs.pfs_setup(root=str(tmp_path), mock=True)
|
|
82
|
+
got = Runtime._read_frcmods(self.runtime({'BAF': {'frcmod': 'baf.frcmod'}, 'TAZ': {'count': 1}}))
|
|
83
|
+
assert got == {'BAF': FRC[1]}
|
|
84
|
+
|
|
85
|
+
def test_a_missing_file_stops_setup(self, tmp_path):
|
|
86
|
+
pfs.pfs_setup(root=str(tmp_path), mock=True)
|
|
87
|
+
with pytest.raises(FileNotFoundError, match='BAF'):
|
|
88
|
+
Runtime._read_frcmods(self.runtime({'BAF': {'frcmod': 'nope.frcmod'}}))
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def dihedraltypes(rows):
|
|
92
|
+
T = Topology()
|
|
93
|
+
T.D['dihedraltypes'] = pd.DataFrame(rows, columns=['i', 'j', 'k', 'l', 'func', 'phase', 'kd', 'pn'])
|
|
94
|
+
return T
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
class TestConflictingTypes:
|
|
98
|
+
plain = [('ca', 'c3', 'ca', 'ca', 9, 0.0, 0.0, 2)]
|
|
99
|
+
fitted = [('ca', 'c3', 'ca', 'ca', 9, 180.0, 1.335, 2), ('ca', 'c3', 'ca', 'ca', 9, 180.0, 0.959, 4)]
|
|
100
|
+
|
|
101
|
+
def test_overridden_type_also_present_without_the_override(self):
|
|
102
|
+
c = conflicting_types({'BAF': (dihedraltypes(self.fitted), 'd1'), 'BPA': (dihedraltypes(self.plain), None)})
|
|
103
|
+
assert c == [('dihedraltypes', ('ca', 'c3', 'ca', 'ca', 9), 'BAF', 'BPA')]
|
|
104
|
+
|
|
105
|
+
def test_an_improper_with_the_same_atom_types_is_a_different_type(self):
|
|
106
|
+
improper = [('ca', 'c3', 'ca', 'ca', 4, 180.0, 0.263, 2)]
|
|
107
|
+
both = self.fitted + improper
|
|
108
|
+
assert conflicting_types({'BAF': (dihedraltypes(both), 'd1'), 'X': (dihedraltypes(improper), None)}) == []
|
|
109
|
+
|
|
110
|
+
def test_reversed_type_names_are_the_same_type(self):
|
|
111
|
+
rev = [('ca', 'ca', 'c3', 'ca', 9, 0.0, 0.0, 2)]
|
|
112
|
+
assert conflicting_types({'BAF': (dihedraltypes(self.fitted), 'd1'), 'BPA': (dihedraltypes(rev), None)})
|
|
113
|
+
|
|
114
|
+
def test_same_group_differences_are_not_this_check(self):
|
|
115
|
+
# discrepancies among plain GAFF molecules are resolve_type_discrepancies' business
|
|
116
|
+
assert conflicting_types({'A': (dihedraltypes(self.fitted), None), 'B': (dihedraltypes(self.plain), None)}) == []
|
|
117
|
+
|
|
118
|
+
def test_agreeing_parameters_are_fine(self):
|
|
119
|
+
assert conflicting_types({'BAF': (dihedraltypes(self.plain), 'd1'), 'TAZ': (dihedraltypes(self.plain), None)}) == []
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
_MISSING = [t for t in ('antechamber', 'parmchk2', 'tleap', 'gmx') if shutil.which(t) is None]
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
@pytest.mark.skipif(bool(_MISSING), reason=f'external tools not on PATH: {", ".join(_MISSING)}')
|
|
126
|
+
class TestTleapLoadsIt:
|
|
127
|
+
def parameterize(self, root, ambertools):
|
|
128
|
+
orig = os.getcwd()
|
|
129
|
+
pfs.pfs_setup(root=str(root), projdir='proj', mock=False)
|
|
130
|
+
try:
|
|
131
|
+
M = Molecule.New('STY', None)
|
|
132
|
+
M.set_sequence_from_moldict({'STY': M})
|
|
133
|
+
M.generate(ambertools=ambertools, gaff={'minimize_molecules': False})
|
|
134
|
+
return Topology.read_top('STY.top').D['dihedraltypes'], paramcache.read_key('STY')
|
|
135
|
+
finally:
|
|
136
|
+
os.chdir(orig)
|
|
137
|
+
|
|
138
|
+
def test_the_override_replaces_the_gaff_torsion(self, tmp_path_factory):
|
|
139
|
+
plain, plain_key = self.parameterize(tmp_path_factory.mktemp('plain'), {'charge_method': 'gas'})
|
|
140
|
+
t = plain.iloc[0]
|
|
141
|
+
names = '-'.join(str(x).ljust(2) for x in (t.i, t.j, t.k, t.l))
|
|
142
|
+
frcmod = f'override\nDIHE\n{names} 1 7.7700 180.0 3.0\n\n'
|
|
143
|
+
over, over_key = self.parameterize(tmp_path_factory.mktemp('over'),
|
|
144
|
+
{'charge_method': 'gas', 'frcmod': [('STY', frcmod)]})
|
|
145
|
+
rows = over[(over.i == t.i) & (over.j == t.j) & (over.k == t.k) & (over.l == t.l)]
|
|
146
|
+
assert list(rows.kd.round(3)) == [round(7.77 * 4.184, 3)]
|
|
147
|
+
assert list(rows.pn) == [3]
|
|
148
|
+
assert paramcache.FRCMOD_FIELD not in plain_key
|
|
149
|
+
assert over_key[paramcache.FRCMOD_FIELD] == paramcache.frcmod_digest([('STY', frcmod)])
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/0-liquid-styrene/index.rst
RENAMED
|
File without changes
|
{htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/0-liquid-styrene/introduction.rst
RENAMED
|
File without changes
|
{htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/0-liquid-styrene/monomer.rst
RENAMED
|
File without changes
|
{htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/0-liquid-styrene/postsim.rst
RENAMED
|
File without changes
|
{htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/0-liquid-styrene/results.rst
RENAMED
|
File without changes
|
|
File without changes
|
{htpolynet-2.9.0 → htpolynet-2.10.0}/docs/source/example-tutorials/1-polystyrene/configuration.rst
RENAMED
|
File without changes
|