htpolynet 2.3.0__tar.gz → 2.4.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (336) hide show
  1. htpolynet-2.4.0/.claude/skills/htpolynet/SKILL.md +1 -0
  2. {htpolynet-2.3.0 → htpolynet-2.4.0}/.github/workflows/docker.yml +2 -0
  3. {htpolynet-2.3.0 → htpolynet-2.4.0}/CHANGELOG.md +111 -0
  4. {htpolynet-2.3.0 → htpolynet-2.4.0}/PKG-INFO +1 -1
  5. {htpolynet-2.3.0 → htpolynet-2.4.0}/ROADMAP.md +116 -0
  6. {htpolynet-2.3.0 → htpolynet-2.4.0}/docker/Dockerfile +8 -0
  7. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/6-cyanate-ester/postsim.rst +16 -0
  8. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/user-guide/configs/configs-for-run.rst +9 -1
  9. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/user-guide/container-usage.rst +32 -0
  10. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/user-guide/usage.rst +35 -5
  11. {htpolynet-2.3.0 → htpolynet-2.4.0}/pyproject.toml +1 -1
  12. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/analysis/analyze.py +1 -1
  13. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/analysis/postsim.py +1 -1
  14. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/cli.py +41 -1
  15. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/core/projectfilesystem.py +25 -1
  16. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/core/runtime.py +19 -8
  17. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/external/software.py +27 -2
  18. htpolynet-2.4.0/src/htpolynet/resources/claude/SKILL.md +165 -0
  19. {htpolynet-2.3.0 → htpolynet-2.4.0}/tests/unit/test_paramcache.py +20 -4
  20. {htpolynet-2.3.0 → htpolynet-2.4.0}/tests/unit/test_projectfilesystem.py +51 -0
  21. htpolynet-2.4.0/tests/unit/test_setup_claude.py +64 -0
  22. htpolynet-2.4.0/tests/unit/test_software_provenance.py +116 -0
  23. htpolynet-2.3.0/.claude/skills/htpolynet/SKILL.md +0 -71
  24. {htpolynet-2.3.0 → htpolynet-2.4.0}/.claude/settings.json +0 -0
  25. {htpolynet-2.3.0 → htpolynet-2.4.0}/.envrc +0 -0
  26. {htpolynet-2.3.0 → htpolynet-2.4.0}/.github/workflows/conda-forge-sync.yml +0 -0
  27. {htpolynet-2.3.0 → htpolynet-2.4.0}/.github/workflows/release.yaml +0 -0
  28. {htpolynet-2.3.0 → htpolynet-2.4.0}/.github/workflows/test.yml +0 -0
  29. {htpolynet-2.3.0 → htpolynet-2.4.0}/.gitignore +0 -0
  30. {htpolynet-2.3.0 → htpolynet-2.4.0}/.readthedocs.yaml +0 -0
  31. {htpolynet-2.3.0 → htpolynet-2.4.0}/CITATION.cff +0 -0
  32. {htpolynet-2.3.0 → htpolynet-2.4.0}/CLAUDE.md +0 -0
  33. {htpolynet-2.3.0 → htpolynet-2.4.0}/LICENSE +0 -0
  34. {htpolynet-2.3.0 → htpolynet-2.4.0}/MANIFEST.in +0 -0
  35. {htpolynet-2.3.0 → htpolynet-2.4.0}/README.md +0 -0
  36. {htpolynet-2.3.0 → htpolynet-2.4.0}/docker/compose.yml +0 -0
  37. {htpolynet-2.3.0 → htpolynet-2.4.0}/docker/docker-entrypoint.sh +0 -0
  38. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/Makefile +0 -0
  39. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/README.rst +0 -0
  40. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/make.bat +0 -0
  41. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/requirements.txt +0 -0
  42. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/_static/.gitkeep +0 -0
  43. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/changelog.rst +0 -0
  44. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/conf.py +0 -0
  45. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/0-liquid-styrene/configuration.rst +0 -0
  46. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/0-liquid-styrene/index.rst +0 -0
  47. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/0-liquid-styrene/introduction.rst +0 -0
  48. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/0-liquid-styrene/monomer.rst +0 -0
  49. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/0-liquid-styrene/postsim.rst +0 -0
  50. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/0-liquid-styrene/results.rst +0 -0
  51. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/0-liquid-styrene/run.rst +0 -0
  52. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/1-polystyrene/configuration.rst +0 -0
  53. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/1-polystyrene/index.rst +0 -0
  54. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/1-polystyrene/introduction.rst +0 -0
  55. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/1-polystyrene/monomer.rst +0 -0
  56. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/1-polystyrene/pics/STY.png +0 -0
  57. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/1-polystyrene/pics/STYCC.png +0 -0
  58. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/1-polystyrene/pics/buildtraces.png +0 -0
  59. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/1-polystyrene/pics/cure_info.png +0 -0
  60. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/1-polystyrene/pics/densification-density.png +0 -0
  61. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/1-polystyrene/pics/final-box.png +0 -0
  62. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/1-polystyrene/pics/reaction_network.png +0 -0
  63. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/1-polystyrene/pics/sty-coloring.tcl +0 -0
  64. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/1-polystyrene/pics/sty-cured.png +0 -0
  65. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/1-polystyrene/pics/sty-detail.png +0 -0
  66. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/1-polystyrene/pics/sty-liq.png +0 -0
  67. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/1-polystyrene/pics/styrene-polymerization.png +0 -0
  68. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/1-polystyrene/postsim.rst +0 -0
  69. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/1-polystyrene/reactions.rst +0 -0
  70. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/1-polystyrene/results.rst +0 -0
  71. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/1-polystyrene/run.rst +0 -0
  72. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/configuration.rst +0 -0
  73. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/index.rst +0 -0
  74. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/introduction.rst +0 -0
  75. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/BPA.png +0 -0
  76. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/GMA.png +0 -0
  77. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/HIE.png +0 -0
  78. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/buildtraces.png +0 -0
  79. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/cure_info.png +0 -0
  80. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/densification-density.png +0 -0
  81. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/four_dimers.eps +0 -0
  82. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/four_dimers.fig +0 -0
  83. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/four_dimers.png +0 -0
  84. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/gma-sty-coloring.tcl +0 -0
  85. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/gma-sty-cured.png +0 -0
  86. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/gma-sty-detail.png +0 -0
  87. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/gma-sty-liq.png +0 -0
  88. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/p1-traces.png +0 -0
  89. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/reaction_network.png +0 -0
  90. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/vesys.eps +0 -0
  91. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/vesys.fig +0 -0
  92. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/vesys.png +0 -0
  93. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/postsim.rst +0 -0
  94. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/reactions.rst +0 -0
  95. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/results.rst +0 -0
  96. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/run.rst +0 -0
  97. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/configuration.rst +0 -0
  98. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/index.rst +0 -0
  99. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/introduction.rst +0 -0
  100. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/monomers.rst +0 -0
  101. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/DGE-epoxy.png +0 -0
  102. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/DGE-labelled.png +0 -0
  103. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/PAC-2d.png +0 -0
  104. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/PAC-labelled.png +0 -0
  105. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/buildtraces.png +0 -0
  106. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/cure_info.png +0 -0
  107. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/densification-density.png +0 -0
  108. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/dge-pac-coloring.tcl +0 -0
  109. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/dge-pac-cured.png +0 -0
  110. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/dge-pac-detail.png +0 -0
  111. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/dge-pac-liq.png +0 -0
  112. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/dgesys.eps +0 -0
  113. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/dgesys.fig +0 -0
  114. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/dgesys.png +0 -0
  115. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/equil-rho_v_ns.png +0 -0
  116. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/postsim-typical.png +0 -0
  117. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/prod-e.png +0 -0
  118. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/prod-equil-rho_v_ns.png +0 -0
  119. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/prod-rho_v_ns.png +0 -0
  120. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/prod-tg.png +0 -0
  121. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/r1.png +0 -0
  122. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/r2.png +0 -0
  123. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/r3.png +0 -0
  124. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/reaction_network.png +0 -0
  125. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/rho_v_ns.png +0 -0
  126. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/short-e.png +0 -0
  127. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/short-tg.png +0 -0
  128. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/postsim.rst +0 -0
  129. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/reactions.rst +0 -0
  130. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/results.rst +0 -0
  131. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/run.rst +0 -0
  132. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/configuration.rst +0 -0
  133. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/index.rst +0 -0
  134. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/introduction.rst +0 -0
  135. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/monomers.rst +0 -0
  136. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/buildtraces.png +0 -0
  137. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/cure_info.png +0 -0
  138. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/densification-density.png +0 -0
  139. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/dfa-fde-coloring.tcl +0 -0
  140. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/dfa-fde-cured.png +0 -0
  141. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/dfa-fde-detail.png +0 -0
  142. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/dfa-fde-liq.png +0 -0
  143. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/reaction_network.png +0 -0
  144. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/postsim.rst +0 -0
  145. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/reactions.rst +0 -0
  146. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/results.rst +0 -0
  147. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/run.rst +0 -0
  148. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/5-htpb-ipdi/configuration.rst +0 -0
  149. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/5-htpb-ipdi/index.rst +0 -0
  150. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/5-htpb-ipdi/introduction.rst +0 -0
  151. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/5-htpb-ipdi/monomers.rst +0 -0
  152. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/5-htpb-ipdi/pics/buildtraces.png +0 -0
  153. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/5-htpb-ipdi/pics/cure_info.png +0 -0
  154. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/5-htpb-ipdi/pics/densification-density.png +0 -0
  155. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/5-htpb-ipdi/pics/htpb-coloring.tcl +0 -0
  156. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/5-htpb-ipdi/pics/htpb-ipdi-cured.png +0 -0
  157. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/5-htpb-ipdi/pics/htpb-ipdi-detail.png +0 -0
  158. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/5-htpb-ipdi/pics/htpb-ipdi-liq.png +0 -0
  159. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/5-htpb-ipdi/pics/reaction_network.png +0 -0
  160. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/5-htpb-ipdi/postsim.rst +0 -0
  161. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/5-htpb-ipdi/reactions.rst +0 -0
  162. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/5-htpb-ipdi/results.rst +0 -0
  163. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/5-htpb-ipdi/run.rst +0 -0
  164. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/6-cyanate-ester/configuration.rst +0 -0
  165. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/6-cyanate-ester/index.rst +0 -0
  166. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/6-cyanate-ester/introduction.rst +0 -0
  167. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/6-cyanate-ester/monomers.rst +0 -0
  168. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/6-cyanate-ester/pics/badcy-coloring.tcl +0 -0
  169. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/6-cyanate-ester/pics/badcy-cured.png +0 -0
  170. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/6-cyanate-ester/pics/badcy-detail.png +0 -0
  171. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/6-cyanate-ester/pics/badcy-liq.png +0 -0
  172. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/6-cyanate-ester/pics/buildtraces.png +0 -0
  173. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/6-cyanate-ester/pics/cure_info.png +0 -0
  174. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/6-cyanate-ester/pics/densification-density.png +0 -0
  175. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/6-cyanate-ester/pics/reaction_network.png +0 -0
  176. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/6-cyanate-ester/reactions.rst +0 -0
  177. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/6-cyanate-ester/results.rst +0 -0
  178. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/6-cyanate-ester/run.rst +0 -0
  179. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/example-tutorials/index.rst +0 -0
  180. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/htpolynetpackage.rst +0 -0
  181. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/index.rst +0 -0
  182. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/install.rst +0 -0
  183. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/references/index.rst +0 -0
  184. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/references/mol2-reference.pdf +0 -0
  185. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/references.bib +0 -0
  186. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/release-history.rst +0 -0
  187. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/user-guide/CURE.odg +0 -0
  188. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/user-guide/bond_filter.odg +0 -0
  189. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/user-guide/building-a-system.rst +0 -0
  190. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/user-guide/configs/configs-for-analyze.rst +0 -0
  191. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/user-guide/configs/configs-for-postsim.rst +0 -0
  192. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/user-guide/configuration-files.rst +0 -0
  193. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/user-guide/flow1.odg +0 -0
  194. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/user-guide/flow1yaml.odg +0 -0
  195. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/user-guide/hydrogenated.eps +0 -0
  196. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/user-guide/hydrogenated.fig +0 -0
  197. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/user-guide/index.rst +0 -0
  198. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/user-guide/molecular-structure-inputs.rst +0 -0
  199. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/user-guide/pics/STY.png +0 -0
  200. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/user-guide/pics/STYCC.png +0 -0
  201. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/user-guide/pics/TypicalUsageFlow.png +0 -0
  202. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/user-guide/pics/bond_filter.png +0 -0
  203. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/user-guide/pics/chemdoodle-2dsketcher-emb.png +0 -0
  204. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/user-guide/pics/chemdoodle-2dsketcher-styrene.png +0 -0
  205. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/user-guide/pics/hydrogenated.png +0 -0
  206. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/user-guide/pics/ring_pierce/ring_pierce_cases.png +0 -0
  207. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/user-guide/pics/ring_pierce/ring_pierce_linkcell.png +0 -0
  208. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/user-guide/postcure-repair.rst +0 -0
  209. {htpolynet-2.3.0 → htpolynet-2.4.0}/docs/source/user-guide/program-flow.rst +0 -0
  210. {htpolynet-2.3.0 → htpolynet-2.4.0}/scripts/check-conda-sync.py +0 -0
  211. {htpolynet-2.3.0 → htpolynet-2.4.0}/scripts/release.sh +0 -0
  212. {htpolynet-2.3.0 → htpolynet-2.4.0}/scripts/render-detail.sh +0 -0
  213. {htpolynet-2.3.0 → htpolynet-2.4.0}/scripts/render-detail.tcl +0 -0
  214. {htpolynet-2.3.0 → htpolynet-2.4.0}/scripts/render-snapshot.sh +0 -0
  215. {htpolynet-2.3.0 → htpolynet-2.4.0}/scripts/run_all_examples.sh +0 -0
  216. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/__init__.py +0 -0
  217. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/analysis/__init__.py +0 -0
  218. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/analysis/plot.py +0 -0
  219. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/analysis/utils.py +0 -0
  220. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/core/__init__.py +0 -0
  221. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/core/bondtemplate.py +0 -0
  222. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/core/configuration.py +0 -0
  223. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/core/coordinates.py +0 -0
  224. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/core/molecule.py +0 -0
  225. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/core/paramcache.py +0 -0
  226. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/core/topocoord.py +0 -0
  227. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/core/topology.py +0 -0
  228. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/cure/__init__.py +0 -0
  229. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/cure/chain.py +0 -0
  230. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/cure/curecontroller.py +0 -0
  231. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/cure/expandreactions.py +0 -0
  232. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/cure/reaction.py +0 -0
  233. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/external/__init__.py +0 -0
  234. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/external/ambertools.py +0 -0
  235. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/external/command.py +0 -0
  236. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/external/gromacs.py +0 -0
  237. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/external/slurm.py +0 -0
  238. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/external/smiles_input.py +0 -0
  239. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/geometry/__init__.py +0 -0
  240. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/geometry/bondlist.py +0 -0
  241. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/geometry/lattice.py +0 -0
  242. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/geometry/linkcell.py +0 -0
  243. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/geometry/matrix4.py +0 -0
  244. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/geometry/ring.py +0 -0
  245. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/io/__init__.py +0 -0
  246. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/io/gro.py +0 -0
  247. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/io/mol2.py +0 -0
  248. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/io/pdb.py +0 -0
  249. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/repair/__init__.py +0 -0
  250. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/repair/cyanate_cap.py +0 -0
  251. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/repair/topology_surgery.py +0 -0
  252. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/resources/README.md +0 -0
  253. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/resources/__init__.py +0 -0
  254. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/resources/example_depot/0-liquid-styrene.yaml +0 -0
  255. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/resources/example_depot/1-polystyrene.yaml +0 -0
  256. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/resources/example_depot/2-bisgma-styrene-thermoset.yaml +0 -0
  257. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/resources/example_depot/3-pacm-dgeba-epoxy-thermoset.yaml +0 -0
  258. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/resources/example_depot/4-dfda-fde-epoxy-thermoset.yaml +0 -0
  259. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/resources/example_depot/5-htpb-ipdi.yaml +0 -0
  260. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/resources/example_depot/6-cyanate-ester.yaml +0 -0
  261. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/resources/mdp/README.md +0 -0
  262. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/resources/mdp/drag-min.mdp +0 -0
  263. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/resources/mdp/drag-npt.mdp +0 -0
  264. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/resources/mdp/drag-nvt.mdp +0 -0
  265. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/resources/mdp/min.mdp +0 -0
  266. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/resources/mdp/npt.mdp +0 -0
  267. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/resources/mdp/nvt.mdp +0 -0
  268. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/resources/mdp/relax-min.mdp +0 -0
  269. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/resources/mdp/relax-npt.mdp +0 -0
  270. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/resources/mdp/relax-nvt.mdp +0 -0
  271. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/resources/mdp/single-molecule-min.mdp +0 -0
  272. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/resources/mdp/single-molecule-nvt.mdp +0 -0
  273. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/resources/molecules/inputs/DFA.pdb +0 -0
  274. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/resources/molecules/inputs/DGE.mol2 +0 -0
  275. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/resources/molecules/inputs/EMB.mol2 +0 -0
  276. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/resources/molecules/inputs/FDE.pdb +0 -0
  277. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/resources/molecules/inputs/GMA.mol2 +0 -0
  278. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/resources/molecules/inputs/PAC.mol2 +0 -0
  279. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/resources/molecules/inputs/STY.mol2 +0 -0
  280. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/resources/molecules/make-monomers.sh +0 -0
  281. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/resources/molecules/pics/DFA.png +0 -0
  282. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/resources/molecules/pics/DGE.png +0 -0
  283. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/resources/molecules/pics/EMB.png +0 -0
  284. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/resources/molecules/pics/FDE.png +0 -0
  285. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/resources/molecules/pics/GMA.png +0 -0
  286. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/resources/molecules/pics/PAC.png +0 -0
  287. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/resources/molecules/pics/STY.png +0 -0
  288. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/resources/molecules/sample-inputs/DFA.pdb +0 -0
  289. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/resources/molecules/sample-inputs/DGE.mol2 +0 -0
  290. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/resources/molecules/sample-inputs/EMB.mol2 +0 -0
  291. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/resources/molecules/sample-inputs/FDE.pdb +0 -0
  292. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/resources/molecules/sample-inputs/GMA.mol2 +0 -0
  293. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/resources/molecules/sample-inputs/PAC.mol2 +0 -0
  294. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/resources/molecules/sample-inputs/STY.mol2 +0 -0
  295. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/resources/tcl/readbonds.tcl +0 -0
  296. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/resources/tcl/readgrx.tcl +0 -0
  297. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/resources/tcl/render.tcl +0 -0
  298. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/utils/__init__.py +0 -0
  299. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/utils/banner.py +0 -0
  300. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/utils/checkpoint.py +0 -0
  301. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/utils/dataframetools.py +0 -0
  302. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/utils/inputcheck.py +0 -0
  303. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/utils/logsetup.py +0 -0
  304. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/utils/profiling.py +0 -0
  305. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/utils/stringthings.py +0 -0
  306. {htpolynet-2.3.0 → htpolynet-2.4.0}/src/htpolynet/utils/vmd_viz.py +0 -0
  307. {htpolynet-2.3.0 → htpolynet-2.4.0}/tests/__init__.py +0 -0
  308. {htpolynet-2.3.0 → htpolynet-2.4.0}/tests/conftest.py +0 -0
  309. {htpolynet-2.3.0 → htpolynet-2.4.0}/tests/unit/__init__.py +0 -0
  310. {htpolynet-2.3.0 → htpolynet-2.4.0}/tests/unit/fixtures/config1.gro +0 -0
  311. {htpolynet-2.3.0 → htpolynet-2.4.0}/tests/unit/fixtures/config1.top +0 -0
  312. {htpolynet-2.3.0 → htpolynet-2.4.0}/tests/unit/fixtures/config2.gro +0 -0
  313. {htpolynet-2.3.0 → htpolynet-2.4.0}/tests/unit/fixtures/config2.top +0 -0
  314. {htpolynet-2.3.0 → htpolynet-2.4.0}/tests/unit/fixtures/items31.edr +0 -0
  315. {htpolynet-2.3.0 → htpolynet-2.4.0}/tests/unit/fixtures/items43.edr +0 -0
  316. {htpolynet-2.3.0 → htpolynet-2.4.0}/tests/unit/fixtures/items45.edr +0 -0
  317. {htpolynet-2.3.0 → htpolynet-2.4.0}/tests/unit/fixtures/short.mdp +0 -0
  318. {htpolynet-2.3.0 → htpolynet-2.4.0}/tests/unit/test_bondtemplate.py +0 -0
  319. {htpolynet-2.3.0 → htpolynet-2.4.0}/tests/unit/test_chain.py +0 -0
  320. {htpolynet-2.3.0 → htpolynet-2.4.0}/tests/unit/test_configuration.py +0 -0
  321. {htpolynet-2.3.0 → htpolynet-2.4.0}/tests/unit/test_dataframetools.py +0 -0
  322. {htpolynet-2.3.0 → htpolynet-2.4.0}/tests/unit/test_gpu_usability.py +0 -0
  323. {htpolynet-2.3.0 → htpolynet-2.4.0}/tests/unit/test_gromacs_get_energy_menu.py +0 -0
  324. {htpolynet-2.3.0 → htpolynet-2.4.0}/tests/unit/test_gromacs_gmx_energy_trace.py +0 -0
  325. {htpolynet-2.3.0 → htpolynet-2.4.0}/tests/unit/test_inputcheck.py +0 -0
  326. {htpolynet-2.3.0 → htpolynet-2.4.0}/tests/unit/test_linkcell_pierce.py +0 -0
  327. {htpolynet-2.3.0 → htpolynet-2.4.0}/tests/unit/test_paramcache_ambertools.py +0 -0
  328. {htpolynet-2.3.0 → htpolynet-2.4.0}/tests/unit/test_parameterize_react.py +0 -0
  329. {htpolynet-2.3.0 → htpolynet-2.4.0}/tests/unit/test_plot_smoke.py +0 -0
  330. {htpolynet-2.3.0 → htpolynet-2.4.0}/tests/unit/test_resources.py +0 -0
  331. {htpolynet-2.3.0 → htpolynet-2.4.0}/tests/unit/test_ring.py +0 -0
  332. {htpolynet-2.3.0 → htpolynet-2.4.0}/tests/unit/test_ring_pierce_figs.py +0 -0
  333. {htpolynet-2.3.0 → htpolynet-2.4.0}/tests/unit/test_slurm_script.py +0 -0
  334. {htpolynet-2.3.0 → htpolynet-2.4.0}/tests/unit/test_smiles_input.py +0 -0
  335. {htpolynet-2.3.0 → htpolynet-2.4.0}/tests/unit/test_topology/test.top +0 -0
  336. {htpolynet-2.3.0 → htpolynet-2.4.0}/tests/unit/test_topology.py +0 -0
@@ -0,0 +1 @@
1
+ ../../../src/htpolynet/resources/claude/SKILL.md
@@ -31,6 +31,8 @@ jobs:
31
31
  context: .
32
32
  file: docker/Dockerfile
33
33
  push: true
34
+ build-args: |
35
+ HTPOLYNET_COMMIT=${{ github.sha }}
34
36
  tags: |
35
37
  ghcr.io/cameronabrams/htpolynet:latest
36
38
  ghcr.io/cameronabrams/htpolynet:${{ github.sha }}
@@ -7,6 +7,117 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [2.4.0] - 2026-08-25
11
+
12
+ ### Added
13
+
14
+ - **`htpolynet setup-claude` installs the bundled Claude Code skill**, so it
15
+ reaches users who `pip install` or `conda install` htpolynet rather than
16
+ only those working inside a clone. The skill previously lived at
17
+ `.claude/skills/htpolynet/`, which the tool finds only when the working
18
+ directory is the repository -- that is contributors, and not most users.
19
+ It now ships as package data and is copied to
20
+ `~/.claude/skills/htpolynet/SKILL.md` on request; `--skills-dir
21
+ ./.claude/skills` scopes it to one project instead, and `--force`
22
+ overwrites an existing copy after an upgrade.
23
+
24
+ Nothing happens at install time: installing the package never writes to
25
+ `~/.claude/`. The repository's `.claude/skills/htpolynet/SKILL.md` is now
26
+ a symbolic link to the packaged file, so a clone and an install get the
27
+ same skill and the two cannot drift apart.
28
+
29
+ The skill itself was rewritten to stand alone. It used to be a router --
30
+ its first instruction was to read
31
+ `docs/source/user-guide/building-a-system.rst`, a path that does not exist
32
+ for an installed user -- so it now carries the procedure inline and cites
33
+ Read the Docs once as the full reference.
34
+
35
+ ### Fixed
36
+
37
+ - **The container image now reports the commit it was built from.** A
38
+ published image had no way to say what code it contained: there is no git
39
+ in the image and no `.git` beside the installed package, so
40
+ `htpolynet info` fell back to the installed version -- which is right for
41
+ pip and conda and *misleading for the container*, because the weekly
42
+ scheduled rebuild builds from `main` HEAD and reports whatever
43
+ `pyproject.toml` last said. An image built four commits past a release
44
+ claimed to be that release, and `:latest` is the default thing people
45
+ pull. A user could pull `:latest`, trust the version string, and record
46
+ the wrong version in a methods section.
47
+
48
+ The build now passes the commit as a `HTPOLYNET_COMMIT` build argument,
49
+ the image carries it in its environment, and `htpolynet info` reports it
50
+ in preference to the version fallback. A real git checkout still wins
51
+ over both, since it reflects the working tree including uncommitted
52
+ changes. The container-usage guide explains why `:latest` moves and how
53
+ to pull by digest or per-commit tag when provenance has to be stateable
54
+ later.
55
+
56
+ - The container-usage guide now distinguishes two habits that are easy to
57
+ conflate: **pulling once** gives a campaign a constant tool chain, while
58
+ **recording the digest** is what lets you state afterwards what that tool
59
+ chain was. The image pins more than the htpolynet code -- Gromacs and
60
+ AmberTools come unpinned from conda-forge at build time, so two images
61
+ built days apart can carry different versions of either while running
62
+ identical htpolynet code.
63
+
64
+ ## [2.3.1] - 2026-08-25
65
+
66
+ ### Fixed
67
+
68
+ - **`htpolynet postsim` and `htpolynet analyze` no longer die in a directory
69
+ without a `lib/`.** Both took `-lib` with a default of `'lib'`, but only
70
+ `htpolynet run` creates that tree, so the default value of a flag the user
71
+ never typed reached `UserLibrary` and tripped its existence assertion:
72
+ `AssertionError: lib is not a directory`, three seconds in. The documented
73
+ container invocation failed on it -- running `postsim` against a staged
74
+ directory holding only finished results, which is the normal shape of a
75
+ cluster workflow, where the cure ran somewhere else.
76
+
77
+ `-lib` now defaults to nothing for these two subcommands, and the
78
+ conventional `./lib` is used when it happens to be there. An explicitly
79
+ supplied `-lib` is still validated, so a typo fails loudly rather than
80
+ silently degrading to no library. The assertion message now names the flag
81
+ and the resolved path instead of echoing a bare `lib` the user never
82
+ supplied.
83
+
84
+ ### Changed
85
+
86
+ - Documented that **the density at the end of `postcure` is not an
87
+ equilibrated density**, in the `postcure` directive reference and at the
88
+ point in the example 6 tutorial where a reader would take a number off the
89
+ plot. A crosslinked network relaxes only above its glass transition, and
90
+ a postcure anneal peaking near *Tg* spends almost no time where the
91
+ network can move, so the plateau reports an under-relaxed structure
92
+ however long the plateau runs. Measured on four independent BPA builds:
93
+ the plateau gives 1.1712 +/- 0.0029 g/cm3 against 1.1983 +/- 0.0037 for
94
+ the same systems melted and slowly re-cooled -- 2.31% apart, with the
95
+ plateau 2.6-2.8% below experiment and the re-cooled value within 1%.
96
+ Nothing is computed incorrectly; the protocol simply does not equilibrate
97
+ what a reader would assume it does. The example's own anneal peak is
98
+ unchanged pending a test that raising it actually helps; see `ROADMAP.md`.
99
+
100
+ - `htpolynet info` no longer reports `HTPolyNet git commit: unknown` for an
101
+ installed copy. pip, conda and the published container have no `.git`
102
+ beside the package, so the lookup could never succeed and a build had no
103
+ way to identify its own code from inside itself -- the same question the
104
+ parameterization records answer for molecules. It now falls back to the
105
+ installed distribution version, which for a released install maps to a tag.
106
+
107
+ - The warnings about a cached parameterization with no provenance record
108
+ now say that the cached values are being **used**, not merely that they
109
+ could not be checked. The old wording ("cannot be checked against the
110
+ requested 'bcc' charge method") left the decisive fact implicit: the
111
+ build proceeds with whatever charges that entry holds. A user who
112
+ upgrades with an existing library, asks for `bcc` and measures `gas`
113
+ numbers would reasonably conclude the 2.3.0 cache guard does not work --
114
+ correct behavior is otherwise indistinguishable from the bug it replaced.
115
+ Both the per-molecule line and the stage-end block now state that the
116
+ build carries the cached charges, that they may not match the requested
117
+ method, and that this is expected for a pre-2.3 entry rather than a
118
+ failure. The same clarification is made in the user guide and the
119
+ `ambertools` directive reference.
120
+
10
121
  ## [2.3.0] - 2026-08-23
11
122
 
12
123
  ### Fixed
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: htpolynet
3
- Version: 2.3.0
3
+ Version: 2.4.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/
@@ -27,6 +27,34 @@ Rough ordering within each section is by value, not by effort.
27
27
  every week via the scheduled rebuild, so a run recorded as "built with
28
28
  the container" is not reproducible. Per-commit tags already exist;
29
29
  what's missing is documenting that users should pin one.
30
+
31
+ - **The image's Gromacs and AmberTools are unpinned, so two images with
32
+ identical htpolynet code can compute different numbers.** `docker/Dockerfile`
33
+ installs `ambertools`, `gromacs`, `parmed` and `rdkit` from conda-forge with
34
+ no version constraints, and the weekly rebuild exists precisely to pick up
35
+ whatever is newest. So the commit stamp now tells you which htpolynet
36
+ produced a build, and still does not tell you which force-field tool chain
37
+ did. Observed live: the image built 2026-08-25 carries AmberTools 26.0 and
38
+ Gromacs 2026.3, while panacea's native environment is on Gromacs
39
+ 2025.4 -- a different major version against the same htpolynet.
40
+
41
+ Unpinning is deliberate and mostly right: pinning would freeze the image on
42
+ old Gromacs and defeat the point of a weekly rebuild. The gap is that
43
+ nothing *records* what a given image resolved to, so the versions are
44
+ discoverable only by running `htpolynet info` inside it and writing the
45
+ answer down by hand. The better of two candidates is an image
46
+ **label** carrying a `conda list` export, written at build time: `docker
47
+ inspect` then answers the question without running the image, so the record
48
+ survives reaching someone who cannot run the container at all -- a reviewer,
49
+ an archive, a future reader holding only the digest. The alternative, making
50
+ `htpolynet info` machine-readable so a build can capture it, requires the
51
+ image to still be runnable, which is the weaker guarantee. This is the same
52
+ requirement as the build manifest below, one layer further down -- what
53
+ produced this build, all the way to the compilers.
54
+
55
+ Raised by the calibration study, which found the 2025.4/2026.3 split only
56
+ because it went looking after an unrelated prompt.
57
+
30
58
  - **Retire `ghcr.io/abramsgroup/htpolynet`.** Superseded by the
31
59
  `cameronabrams` package; still public and still serving a June image to
32
60
  anyone with an old link.
@@ -122,6 +150,29 @@ Coverage as of the last measurement: **38.8%** overall.
122
150
  cyanate-ester bridge series meant doing (a) and (b) by hand in a throwaway
123
151
  RDKit script, which is exactly the work a user should not have to
124
152
  reinvent.
153
+ - **Generated topologies cannot be compared byte-wise, because ParmEd
154
+ stamps them.** Every `.top` htpolynet writes opens with a ParmEd header
155
+ recording the invoking user, the host, and the date:
156
+
157
+ ; File TAZ.top was generated
158
+ ; By user: cfa (1000)
159
+ ; On host: panacea.chemeng.drexel.edu
160
+ ; At date: Fri. May 5 15:55:38 2026
161
+
162
+ So two physically identical parameterizations never hash the same, and the
163
+ obvious check -- "did these two builds produce the same parameters for the
164
+ shared monomers?" -- returns a false difference. The calibration study hit
165
+ this on its bridge series and nearly reported the series confounded on the
166
+ strength of an md5; the fix on their side was to strip comment lines before
167
+ comparing, which every user will have to reinvent. Note the header is
168
+ itself provenance, but the wrong kind: it records *when and where* rather
169
+ than *what directives*, which is what the `parm` record now covers, and it
170
+ actively prevents the comparison you would want. The `.itp` files carry no
171
+ such header and the `parm` records are JSON with sorted keys, so both
172
+ already compare cleanly. Worth either normalizing the `.top` header away or
173
+ shipping a comparison helper; this belongs with the manifest entry below,
174
+ since both are about being able to answer "is this the same build?".
175
+
125
176
  - **`-lib` is read-only, and nothing says so.** `pfs.checkout()` and
126
177
  `pfs.exists()` consult the `-lib` user library first, then the user cache,
127
178
  then the system library -- but `pfs.checkin()` writes unconditionally to the
@@ -234,6 +285,71 @@ Coverage as of the last measurement: **38.8%** overall.
234
285
 
235
286
  ## Example depot
236
287
 
288
+ - **Example 6's postcure anneal peaks too close to *T*:sub:`g` to relax the
289
+ network, and the fix is not simply "run it longer".** Measured on four
290
+ independent BPA builds: the postcure NPT plateau gives 1.1712 ± 0.0029
291
+ g/cm³ where the same systems melted and slowly re-cooled give 1.1983 ±
292
+ 0.0037 g/cm³ -- 2.31% apart, with the plateau 2.6-2.8% below experiment
293
+ and the re-cooled value within 1%. The plateau is an under-relaxed
294
+ structure.
295
+
296
+ The mechanism, and the reason the obvious fix is the wrong one: the
297
+ example anneals at a 500 K peak, and the measured *T*:sub:`g` for this
298
+ system is 487.9 K. That is 12.1 K above the glass transition, for 80 ps.
299
+ The Tg ladder that produced the relaxed value spent 15,785 ps above
300
+ *T*:sub:`g`, peaking 112 K above it -- 197x the time, in the regime where
301
+ a crosslinked network actually moves. Lengthening an anneal that sits 12 K
302
+ above *T*:sub:`g` extends a process that barely moves anything, so the
303
+ lever is the peak temperature, not the duration.
304
+
305
+ **But raising the peak is unlikely to close the gap entirely.** Two
306
+ structures of the same network were held for 5 ns at a 480 K setpoint
307
+ that thermostatted to 477.1 K -- about 11 K *below* the measured
308
+ *T*:sub:`g`, and far longer than the 80 ps the example spends near it.
309
+ Relaxation there is fast at first and then stops: about 87% of an
310
+ initial 34.8 kg/m³ density gap -- the gap measured over the first 200 ps
311
+ -- closes within 3 ns, and the remaining 4.25 kg/m³ persists at
312
+ 7.2 sigma, with a last-half trend of +0.030 kg/m³/ns, i.e. not decaying.
313
+ (State the baseline and the window whenever this number is quoted: the
314
+ same data give 83.5-87.8% across the defensible choices of each, so a
315
+ bare percentage is not a fact.) So heat and time buy most of the
316
+ relaxation quickly and then buy nothing, and a residual difference
317
+ survives that a longer anneal at this scale does not appear able to
318
+ remove. Whatever replaces the current anneal should
319
+ therefore be argued as a large improvement, not as a fix; an entry
320
+ promising equilibration would oversell what was measured.
321
+
322
+ Note what that hold also says about *T*:sub:`g` itself: **relaxation does
323
+ not switch off at the glass transition**, it slows continuously through
324
+ it. A transition 20-34 K wide by experiment means 11 K below
325
+ *T*:sub:`g` is inside the transition, not deep in the glass, so fast
326
+ early relaxation there is expected rather than anomalous. This does not
327
+ soften the argument above -- the 197x figure is unchanged and a peak well
328
+ clear of the transition is still the lever -- but it does mean *T*:sub:`g`
329
+ is a soft kinetic boundary for this material, which any protocol
330
+ expressed relative to it has to accommodate.
331
+
332
+ **Untested.** Nobody has yet built with a hotter anneal and compared it
333
+ against the melt-and-recool value, which is the experiment that would
334
+ settle it; the argument above is mechanism, not measurement. That is why
335
+ the example is documented rather than changed. Raising the peak also costs
336
+ wall-clock in a tutorial that should stay small, so the test needs to
337
+ report both whether it works and what it costs.
338
+
339
+ The general problem is worth more than the instance: **any protocol whose
340
+ relaxation depends on being above *T*:sub:`g` is fragile when *T*:sub:`g`
341
+ is unknown at configuration time**, which it always is -- you cannot know
342
+ it before building the thing. A fixed absolute peak temperature is a guess
343
+ that happens to be right or wrong per chemistry, silently. Something
344
+ expressed relative to an estimated or measured *T*:sub:`g`, or a postcure
345
+ that measures *T*:sub:`g` and then anneals accordingly, would be robust
346
+ where an absolute number is not. That is a real design change, not a
347
+ config edit.
348
+
349
+ Raised by the calibration study, which had already published the
350
+ pessimistic density before catching it -- the failure mode is reporting a
351
+ protocol artifact as a force-field result.
352
+
237
353
  - **Example 5 is still not laptop-scale.** The `68d81fb` retune cut the
238
354
  monomer pool to make HTPB/IPDI "fit in a reasonable wall time on a
239
355
  laptop", but a validation run on 16 CPU cores took **10h17m** — about
@@ -51,6 +51,14 @@ COPY . /htpolynet
51
51
  WORKDIR /htpolynet
52
52
  RUN pip install --no-cache-dir .
53
53
 
54
+ # The commit this image was built from. There is no git in the image and no
55
+ # .git beside the installed package, so without this an image cannot say what
56
+ # code it contains -- and its version string is actively misleading between
57
+ # releases, since the weekly rebuild builds from main HEAD. Declared after the
58
+ # expensive layers so that a changed sha does not invalidate the mamba cache.
59
+ ARG HTPOLYNET_COMMIT=unknown
60
+ ENV HTPOLYNET_COMMIT=${HTPOLYNET_COMMIT}
61
+
54
62
  # Pre-create HOME for the unprivileged user the entrypoint drops to. When
55
63
  # compose.yml mounts a named volume here, Docker initializes the fresh volume
56
64
  # from this directory and preserves the 0777 mode.
@@ -87,6 +87,22 @@ Run it:
87
87
  Density during annealing and equilibration
88
88
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
89
89
 
90
+ .. warning::
91
+
92
+ The density this stage settles at is **not** an equilibrated density.
93
+ This example's postcure anneal peaks at 500 K, and the measured
94
+ *T*:sub:`g` for this system is about 488 K -- so the anneal spends its
95
+ 80 ps of peak time only ~12 K above the glass transition, where a
96
+ crosslinked network barely moves. On four independent builds the
97
+ postcure plateau came out 2.31% below the same systems' density after a
98
+ melt and slow re-cool, and 2.6-2.8% below experiment, where the
99
+ re-cooled value agrees with experiment to under 1%.
100
+
101
+ The 500 K peak is fine for this tutorial's purpose, which is to show the
102
+ workflow. It is not a basis for quoting a density. Take densities from
103
+ the cooling ladder below instead.
104
+
105
+
90
106
  .. admonition:: Placeholder
91
107
  :class: caution
92
108
 
@@ -61,7 +61,7 @@ In this section we show all subdirectives for each of the five main directives i
61
61
 
62
62
  These three directives determine the parameters ``antechamber`` produces, so each parameterization records them in a ``.parm`` file checked into the library alongside its ``gro``, ``top``, ``itp``, ``tpx`` and ``grx`` files. Because the library is keyed on molecule name, that record is the only thing distinguishing a molecule parameterized one way from the same molecule parameterized another. A run whose directives disagree with the record re-parameterizes rather than reusing the cached files, and says which directives differed.
63
63
 
64
- A parameterization checked in before htpolynet 2.3 has no such record. It is still used, but the run warns that it cannot verify what produced it; rebuild it with ``--force-parameterization`` if you need to be sure. Note that re-parameterizing after a mismatch does **not** replace the library entry unless you also pass ``--force-checkin``, so a library holding a ``gas`` parameterization keeps it even after a ``bcc`` run.
64
+ A parameterization checked in before htpolynet 2.3 has no such record. It is still used **as-is**, which means the build takes whatever charges that entry holds even if they were produced with a different ``charge_method``; the run warns, per molecule and again in a block at the end of the parameterization stage, that it could not verify what produced them. This is deliberate -- it keeps an existing library working instead of re-parameterizing it wholesale -- but it does mean that asking for ``bcc`` against a pre-2.3 library can still yield ``gas`` numbers. Rebuild those entries with ``--force-parameterization`` if a build's charges need to be certain. Note that re-parameterizing after a mismatch does **not** replace the library entry unless you also pass ``--force-checkin``, so a library holding a ``gas`` parameterization keeps it even after a ``bcc`` run.
65
65
 
66
66
  * ``GAFF``
67
67
 
@@ -263,6 +263,14 @@ In this section we show all subdirectives for each of the five main directives i
263
263
 
264
264
  The ``postcure`` directive instructs ``htpolynet`` on running a series of MD simulations after cure. Its form is identical to that of ``precure``, namely with optional ``preequilibration``, ``anneal``, and ``postequilibration`` subdirectives.
265
265
 
266
+ .. warning::
267
+
268
+ **The density at the end of ``postequilibration`` is not an equilibrated density, and should not be quoted as one.** A crosslinked network only relaxes appreciably above its glass transition, and a postcure anneal whose peak sits near *T*:sub:`g` spends very little time where the network can move -- so the postcure plateau reports an under-relaxed structure no matter how long the plateau itself runs.
269
+
270
+ Measured on four independent BPA cyanate-ester builds: the postcure NPT plateau gave 1.1712 ± 0.0029 g/cm³ at 300 K, while the same systems melted and slowly re-cooled gave 1.1983 ± 0.0037 g/cm³ at 293 K -- a 2.31% difference between two extractions of the same quantity. Against experiment (1.205 by mercury dilatometry, 1.202 by flotation, same monomer), the plateau value is 2.6-2.8% low and the re-cooled value 0.3-0.6% low. A build reporting the plateau density would have read as a force-field failure when it was a protocol artifact.
271
+
272
+ If you need a density, extract it from a melt-and-slow-cool trajectory (an :doc:`htpolynet postsim <configs-for-postsim>` ladder does this) rather than from the postcure plateau. The same caution applies to any property that depends on the structure having relaxed.
273
+
266
274
  .. _reactions:
267
275
 
268
276
  * ``reactions``
@@ -99,6 +99,38 @@ The ``compose.yml`` file mounts the current directory into the container as
99
99
  ``/work`` and runs the process as your host user, so all output files are
100
100
  written with your own ownership.
101
101
 
102
+ .. admonition:: Which code is in your image?
103
+ :class: note
104
+
105
+ ``htpolynet info`` reports the exact commit the image was built from, which
106
+ is baked in at build time. This matters because ``:latest`` moves: besides
107
+ moving on every release, it is rebuilt weekly from ``main`` to pick up new
108
+ Gromacs and AmberTools builds, so an image tagged ``:latest`` is frequently
109
+ built from a commit *after* the last release and its version number alone
110
+ will not tell you that.
111
+
112
+ For anything whose provenance you need to be able to state later -- a
113
+ published result, a long campaign you want to keep consistent -- pull by
114
+ digest or by the per-commit tag rather than ``:latest``, and record what
115
+ you pulled::
116
+
117
+ $ docker pull ghcr.io/cameronabrams/htpolynet@sha256:<digest>
118
+
119
+ Every build is also pushed as ``ghcr.io/cameronabrams/htpolynet:<commit-sha>``.
120
+
121
+ Note that the image pins more than the ``htpolynet`` code. Gromacs and
122
+ AmberTools are installed unpinned from conda-forge at build time, so two
123
+ images built days apart can carry different versions of either while
124
+ running identical ``htpolynet`` code -- and a charge method or an
125
+ integrator is not something you want silently varying across a campaign.
126
+ Two distinct habits protect against this and are worth keeping apart:
127
+ **pulling once** and reusing that image gives a campaign a constant tool
128
+ chain, while **recording the digest** is what lets you say afterwards what
129
+ that tool chain was. Doing only the first leaves you consistent but unable
130
+ to state what you did; doing only the second leaves every fresh pull free
131
+ to move under you. ``htpolynet info`` prints the AmberTools and Gromacs
132
+ versions actually present, so record its output alongside the digest.
133
+
102
134
  Running example shell scripts
103
135
  """""""""""""""""""""""""""""
104
136
 
@@ -21,6 +21,7 @@ Subcommand Description
21
21
  ``analyze`` Perform ``gmx``-style analyses of trajectories generated by post-build MD simulations
22
22
  ``gen-slurm-script`` Emit a SLURM batch script that runs ``htpolynet run`` for a given config
23
23
  ``make-viz`` Regenerate VMD visualization files (``.viz.psf`` + ``.viz.tcl``) from an existing ``top`` + ``gro`` pair
24
+ ``setup-claude`` Install htpolynet's Claude Code skill so an agent can drive htpolynet
24
25
  ==================== ========================
25
26
 
26
27
  ``htpolynet <subcommand> -h`` provides subcommand-level help.
@@ -222,8 +223,9 @@ checked in under the same name.
222
223
  .. note::
223
224
 
224
225
  A parameterization checked in before htpolynet 2.3 carries no record.
225
- Those entries are still used, so an existing cache keeps working, but
226
- each one logs a warning that its provenance could not be verified, and
226
+ Those entries are still used **as-is**, so an existing cache keeps
227
+ working — but the build takes whatever charges they hold, which may not
228
+ be what your ``charge_method`` asks for. Each one logs a warning, and
227
229
  the parameterization stage ends with a block listing them all. Rebuild
228
230
  them with ``--force-parameterization`` if you need certainty about what
229
231
  a build used.
@@ -387,7 +389,9 @@ The purpose of the ``postsim`` subcommand is to control the execution of several
387
389
  -h, --help show this help message and exit
388
390
  -proj PROJ [PROJ ...]
389
391
  name of project directory
390
- -lib LIB local user library of molecular structures and parameterizations
392
+ -lib LIB local user library of molecular structures and
393
+ parameterizations (default: ./lib if it exists,
394
+ otherwise none)
391
395
  -ocfg OCFG original htpolynet config file used to generate project(s)
392
396
  -cfg CFG config file specifying the operations to perform
393
397
  --no-banner suppress the startup banner
@@ -410,7 +414,9 @@ The ``analyze`` subcommand provides a shortcut interfaces to selected ``gmx``-st
410
414
  -h, --help show this help message and exit
411
415
  -proj PROJ [PROJ ...]
412
416
  name of project directory
413
- -lib LIB local user library of molecular structures and parameterizations
417
+ -lib LIB local user library of molecular structures and
418
+ parameterizations (default: ./lib if it exists,
419
+ otherwise none)
414
420
  -ocfg OCFG original htpolynet config file used to generate project(s)
415
421
  -cfg CFG config file specifying the operations to perform
416
422
  --no-banner suppress the startup banner
@@ -506,4 +512,28 @@ The main ``.viz.tcl`` sources this file when it exists, so the macros are availa
506
512
  # composable with the rest of VMD's selection language
507
513
  mol modselect 0 top "THT and not hydrogen"
508
514
 
509
- The residue-level view is untouched — selections like ``resname TBO`` or ``resname IPD`` still work — the constituent macros are an *additive* layer.
515
+ The residue-level view is untouched — selections like ``resname TBO`` or ``resname IPD`` still work — the constituent macros are an *additive* layer.
516
+
517
+ ``htpolynet setup-claude``
518
+ !!!!!!!!!!!!!!!!!!!!!!!!!!
519
+
520
+ ``setup-claude`` installs the skill bundled with the package, which teaches Claude Code how to drive ``htpolynet``: start from the nearest example, describe monomers in their active form, check a config before spending compute, and recognize the failure modes that are known rather than mysterious.
521
+
522
+ .. code-block:: console
523
+
524
+ $ htpolynet setup-claude -h
525
+
526
+ usage: htpolynet setup-claude [-h] [--skills-dir SKILLS_DIR] [--force]
527
+
528
+ options:
529
+ -h, --help show this help message and exit
530
+ --skills-dir SKILLS_DIR
531
+ skills directory to install into (default: ~/.claude/skills);
532
+ use ./.claude/skills to scope the skill to one project
533
+ --force overwrite an existing installed skill
534
+
535
+ By default the skill goes to ``~/.claude/skills/htpolynet/SKILL.md``, where Claude Code finds it from any working directory. Pass ``--skills-dir ./.claude/skills`` to scope it to a single project instead.
536
+
537
+ Nothing is installed automatically: installing ``htpolynet`` never writes to ``~/.claude/``. Re-run ``setup-claude --force`` after upgrading to pick up the current version of the skill, which otherwise stays as it was when you first installed it.
538
+
539
+ Working inside a clone of the repository needs none of this --- ``.claude/skills/`` there is a symbolic link to the same file, so the skill is already in scope.
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "htpolynet"
7
- version = "2.3.0"
7
+ version = "2.4.0"
8
8
  authors = [
9
9
  { name="Cameron F Abrams", email="cfa22@drexel.edu" },
10
10
  ]
@@ -248,7 +248,7 @@ def analyze(args):
248
248
  software.sw_setup()
249
249
  logger.debug(f'ogromacs {ogromacs}')
250
250
  for d in args.proj:
251
- pfs.pfs_setup(root=os.getcwd(),topdirs=pfs.Dirs.analyze_topdirs,verbose=True,projdir=d,reProject=False,userlibrary=args.lib)
251
+ pfs.pfs_setup(root=os.getcwd(),topdirs=pfs.Dirs.analyze_topdirs,verbose=True,projdir=d,reProject=False,userlibrary=pfs.resolve_user_library(args.lib))
252
252
  pfs.go_to(pfs.Dirs.analyze)
253
253
  for stage in cfg.stagelist:
254
254
  stage.do(**ogromacs)
@@ -436,7 +436,7 @@ def postsim(args):
436
436
  software.sw_setup()
437
437
  logger.debug(f'ogromacs {ogromacs}')
438
438
  for d in args.proj:
439
- pfs.pfs_setup(root=os.getcwd(),topdirs=pfs.Dirs.postsim_topdirs,verbose=True,projdir=d,reProject=False,userlibrary=args.lib)
439
+ pfs.pfs_setup(root=os.getcwd(),topdirs=pfs.Dirs.postsim_topdirs,verbose=True,projdir=d,reProject=False,userlibrary=pfs.resolve_user_library(args.lib))
440
440
  pfs.go_to(pfs.Dirs.postsim)
441
441
  for stage in cfg.stagelist:
442
442
  stage.do(mdp_pfx='local',**ogromacs)
@@ -5,11 +5,15 @@ Author: Cameron F. Abrams <cfa22@drexel.edu>
5
5
 
6
6
  import logging
7
7
  import os
8
+ import shutil
8
9
  import textwrap
9
10
 
10
11
  import argparse as ap
11
12
  import yaml
12
13
 
14
+ from importlib.resources import files as pkg_files
15
+ from pathlib import Path
16
+
13
17
  from .analysis.analyze import analyze
14
18
  from .analysis.plot import plots
15
19
  from .analysis.postsim import postsim
@@ -119,6 +123,37 @@ def fetch_example(args):
119
123
  _fetch_one(depot, fullname)
120
124
 
121
125
 
126
+ def setup_claude(args: ap.Namespace):
127
+ """Handles the setup-claude subcommand.
128
+
129
+ Copies the bundled skill into the user's skills directory. This runs only
130
+ when the user asks for it; installing the package never touches
131
+ ``~/.claude/``.
132
+
133
+ Args:
134
+ args (argparse.Namespace): parsed arguments
135
+ """
136
+ # Resolve through htpolynet.resources, which is a real package; the claude/
137
+ # subdirectory carries no __init__.py, matching every other resource
138
+ # subdirectory.
139
+ source = pkg_files('htpolynet.resources').joinpath('claude', 'SKILL.md')
140
+ if not source.is_file():
141
+ raise FileNotFoundError(f'Bundled skill not found at {source}')
142
+
143
+ skill_dir = Path(args.skills_dir).expanduser() / 'htpolynet'
144
+ target = skill_dir / 'SKILL.md'
145
+
146
+ if target.exists() and not args.force:
147
+ print(f'{target} already exists; re-run with --force to overwrite it')
148
+ return
149
+
150
+ skill_dir.mkdir(parents=True, exist_ok=True)
151
+ with source.open('rb') as fh, open(target, 'wb') as out:
152
+ shutil.copyfileobj(fh, out)
153
+ print(f'Written: {target}')
154
+ print('Claude Code picks the skill up on its next session in any directory.')
155
+
156
+
122
157
  def _add_run_options(p, loglevel='debug'):
123
158
  """Adds run options (no positional config) shared by run and gen-slurm-script."""
124
159
  p.add_argument('-lib',type=str,default='lib',help='local user library of molecular structures and parameterizations')
@@ -235,7 +270,7 @@ def _add_gen_slurm_args(p):
235
270
  def _add_analysis_args(p):
236
271
  """Adds the common arguments shared by the postsim and analyze subcommands."""
237
272
  p.add_argument('-proj',type=str,default='',nargs='+',help='name of project directory')
238
- p.add_argument('-lib',type=str,default='lib',help='local user library of molecular structures and parameterizations')
273
+ p.add_argument('-lib',type=str,default=None,help='local user library of molecular structures and parameterizations (default: ./lib if it exists, otherwise none)')
239
274
  p.add_argument('-ocfg',type=str,default='',help='original htpolynet config file used to generate project(s)')
240
275
  p.add_argument('-cfg',type=str,default='',help='config file specifying the operations to perform')
241
276
  p.add_argument('--no-banner',default=False,action='store_true',help='suppress the startup banner')
@@ -257,6 +292,7 @@ def cli():
257
292
  ('analyze', analyze, "perform 'gmx <command>' style analyses specified in the config file"),
258
293
  ('gen-slurm-script', gen_slurm_script, 'generate a SLURM submission script for running htpolynet on a cluster'),
259
294
  ('make-viz', make_viz, 'regenerate VMD viz files (.viz.psf + .viz.tcl) from an existing gromacs top + gro pair'),
295
+ ('setup-claude', setup_claude, "install htpolynet's Claude Code skill so an agent can drive htpolynet"),
260
296
  ]
261
297
 
262
298
  parser = ap.ArgumentParser(description=textwrap.dedent(banner_message),formatter_class=ap.RawDescriptionHelpFormatter)
@@ -291,6 +327,10 @@ def cli():
291
327
  cp['make-viz'].add_argument('-grx', type=str, default=None, help='input htpolynet .grx (default: auto-detect <gro-stem>.grx; needed for the constituent-selection macros)')
292
328
  cp['make-viz'].add_argument('-prefix', type=str, default=None, help='output basename; the .viz.psf, .viz.tcl, and .viz.macros.tcl are written next to the input gro (default: stem of -gro)')
293
329
 
330
+ cp['setup-claude'].add_argument('--skills-dir', type=str, default='~/.claude/skills',
331
+ help='skills directory to install into (default: %(default)s); use ./.claude/skills to scope the skill to one project')
332
+ cp['setup-claude'].add_argument('--force', default=False, action='store_true', help='overwrite an existing installed skill')
333
+
294
334
  _add_analysis_args(cp['postsim'])
295
335
  _add_analysis_args(cp['analyze'])
296
336
 
@@ -208,7 +208,9 @@ class UserLibrary:
208
208
  pathname (str): path to the user library directory, defaults to '.'
209
209
  """
210
210
  self.root = Path(os.path.abspath(pathname))
211
- assert self.root.exists() and self.root.is_dir(), f'{pathname} is not a directory'
211
+ assert self.root.exists() and self.root.is_dir(), (
212
+ f'user library {pathname!r} (resolved to {self.root}) is not a directory; '
213
+ f'pass -lib <path> to point at an existing library, or create it')
212
214
 
213
215
  def exists(self, filename):
214
216
  """Checks if filename exists in the user library.
@@ -448,6 +450,28 @@ def pfs_setup(root='.', topdirs=['molecules', 'systems', 'plots'], projdir='next
448
450
  userlibrary=userlibrary, mock=mock)
449
451
 
450
452
 
453
+ def resolve_user_library(pathname, default='lib'):
454
+ """Returns the user-library path a subcommand should use, or None for none.
455
+
456
+ An explicitly supplied path is returned unchanged, so that a typo fails
457
+ loudly in UserLibrary rather than silently degrading to no library. When
458
+ nothing was supplied, the conventional ``lib/`` is used only if it is
459
+ actually there: a subcommand that merely reads finished results has no
460
+ reason to require a molecule library, and demanding one turns the default
461
+ value of a flag the user never typed into a hard error.
462
+
463
+ Args:
464
+ pathname (str or None): the value of the ``-lib`` flag, or None if unset
465
+ default (str): the conventional library directory, defaults to 'lib'
466
+
467
+ Returns:
468
+ str or None: path to use as the user library, or None for no user library
469
+ """
470
+ if pathname is not None:
471
+ return pathname
472
+ return default if os.path.isdir(default) else None
473
+
474
+
451
475
  def checkout(filename, altpath=[]):
452
476
  """Copies a file to cwd; searches user library, then user cache, then system library.
453
477