abmptools 2.0.0__tar.gz → 2.2.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 (359) hide show
  1. {abmptools-2.0.0/abmptools.egg-info → abmptools-2.2.0}/PKG-INFO +18 -1
  2. {abmptools-2.0.0 → abmptools-2.2.0}/README.md +5 -0
  3. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/addsolvfrag.py +10 -2
  4. abmptools-2.2.0/abmptools/amorphous/builder.py +466 -0
  5. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/amorphous/mdp_protocol.py +147 -90
  6. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/amorphous/models.py +26 -0
  7. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/amorphous/molecule_prep.py +8 -1
  8. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/amorphous/ndx_writer.py +9 -0
  9. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/amorphous/packing.py +29 -0
  10. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/amorphous/trajectory_ingest.py +71 -2
  11. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/cg/dpd/__init__.py +4 -1
  12. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/cg/dpd/__main__.py +30 -0
  13. abmptools-2.2.0/abmptools/cg/dpd/aij_assign.py +173 -0
  14. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/cg/dpd/orchestrator.py +7 -2
  15. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/cg/dpd/udf_writer.py +12 -4
  16. abmptools-2.2.0/abmptools/cg/dpd/udf_writer_udfm.py +249 -0
  17. abmptools-2.2.0/abmptools/formulation/analysis/__init__.py +155 -0
  18. abmptools-2.2.0/abmptools/formulation/analysis/aggregate_transition.py +297 -0
  19. abmptools-2.2.0/abmptools/formulation/analysis/contact_map.py +253 -0
  20. abmptools-2.2.0/abmptools/formulation/analysis/plots.py +214 -0
  21. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/formulation/builder.py +355 -0
  22. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/formulation/cli.py +56 -7
  23. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/formulation/models.py +6 -0
  24. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/formulation/ndx.py +7 -2
  25. abmptools-2.2.0/abmptools/formulation/peptide_atomistic_openff.py +245 -0
  26. abmptools-2.2.0/abmptools/formulation/small_molecule_openff.py +117 -0
  27. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/formulation/topology.py +81 -0
  28. abmptools-2.2.0/abmptools/formulation/topology_openff.py +571 -0
  29. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/fragmenter/cg_segmenter/__init__.py +10 -0
  30. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/fragmenter/cg_segmenter/__main__.py +51 -4
  31. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/fragmenter/cg_segmenter/dpdgen_exporter.py +21 -8
  32. abmptools-2.2.0/abmptools/fragmenter/cg_segmenter/fcews_export.py +316 -0
  33. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/fragmenter/cg_segmenter/notebook_ui.py +5 -4
  34. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/fragmenter/cg_segmenter/orchestrator.py +38 -0
  35. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/fragmenter/expand_to_system.py +40 -36
  36. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/gro2udf/top_exporter.py +8 -3
  37. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/gro2udf/udf_writer.py +12 -9
  38. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/hbond/__init__.py +16 -0
  39. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/hbond/analyzer.py +104 -5
  40. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/hbond/cli.py +33 -0
  41. abmptools-2.2.0/abmptools/hbond/distance_dist.py +322 -0
  42. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/molcalc.py +100 -5
  43. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/setfmo.py +2 -1
  44. abmptools-2.2.0/abmptools/trajectory/__init__.py +41 -0
  45. abmptools-2.2.0/abmptools/trajectory/__main__.py +3 -0
  46. abmptools-2.2.0/abmptools/trajectory/cli.py +151 -0
  47. abmptools-2.2.0/abmptools/trajectory/postprocess.py +322 -0
  48. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/udf_io.py +113 -19
  49. abmptools-2.2.0/abmptools/udfcharge/__init__.py +28 -0
  50. abmptools-2.2.0/abmptools/udfcharge/__main__.py +63 -0
  51. abmptools-2.2.0/abmptools/udfcharge/core.py +279 -0
  52. {abmptools-2.0.0 → abmptools-2.2.0/abmptools.egg-info}/PKG-INFO +18 -1
  53. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools.egg-info/SOURCES.txt +15 -0
  54. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools.egg-info/requires.txt +13 -0
  55. {abmptools-2.0.0 → abmptools-2.2.0}/pyproject.toml +24 -1
  56. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_builder_integration.py +11 -5
  57. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_builder_mocked.py +8 -6
  58. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_charge_method.py +15 -4
  59. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_formulation_ndx.py +23 -0
  60. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_mdp_protocol.py +27 -31
  61. abmptools-2.2.0/tests/test_trajectory_postprocess.py +287 -0
  62. abmptools-2.0.0/abmptools/amorphous/builder.py +0 -260
  63. abmptools-2.0.0/abmptools/formulation/analysis/__init__.py +0 -61
  64. abmptools-2.0.0/abmptools/formulation/analysis/aggregate_transition.py +0 -153
  65. abmptools-2.0.0/abmptools/formulation/analysis/contact_map.py +0 -115
  66. abmptools-2.0.0/abmptools/formulation/analysis/plots.py +0 -66
  67. {abmptools-2.0.0 → abmptools-2.2.0}/LICENSE +0 -0
  68. {abmptools-2.0.0 → abmptools-2.2.0}/NOTICE +0 -0
  69. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/__init__.py +0 -0
  70. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/abinit_io.py +0 -0
  71. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/ajf2config.py +0 -0
  72. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/ajfserial.py +0 -0
  73. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/amorphous/__init__.py +0 -0
  74. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/amorphous/__main__.py +0 -0
  75. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/amorphous/cli.py +0 -0
  76. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/amorphous/density.py +0 -0
  77. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/amorphous/parameterizer.py +0 -0
  78. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/amorphous/pubchem.py +0 -0
  79. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/amorphous/system_model_adapter.py +0 -0
  80. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/anlfmo.py +0 -0
  81. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/cg/__init__.py +0 -0
  82. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/cg/dpd/aij_io.py +0 -0
  83. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/cg/dpd/calc_sett_io.py +0 -0
  84. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/cg/dpd/dpm_writer.py +0 -0
  85. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/cg/dpd/models.py +0 -0
  86. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/cg/dpd/monomer_io.py +0 -0
  87. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/cg/dpd/notebook_ui.py +0 -0
  88. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/cg/membrane/__init__.py +0 -0
  89. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/cg/membrane/__main__.py +0 -0
  90. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/cg/membrane/_subprocess.py +0 -0
  91. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/cg/membrane/builder.py +0 -0
  92. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/cg/membrane/cli.py +0 -0
  93. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/cg/membrane/forcefield_check.py +0 -0
  94. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/cg/membrane/insane_runner.py +0 -0
  95. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/cg/membrane/mdp_templates.py +0 -0
  96. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/cg/membrane/models.py +0 -0
  97. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/cg/membrane/pmf.py +0 -0
  98. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/cg/membrane/pulling.py +0 -0
  99. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/cg/membrane/system_packer.py +0 -0
  100. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/cg/membrane/topology_composer.py +0 -0
  101. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/cg/membrane/umbrella.py +0 -0
  102. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/cg/peptide/__init__.py +0 -0
  103. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/cg/peptide/__main__.py +0 -0
  104. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/cg/peptide/_subprocess.py +0 -0
  105. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/cg/peptide/builder.py +0 -0
  106. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/cg/peptide/cli.py +0 -0
  107. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/cg/peptide/forcefield_check.py +0 -0
  108. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/cg/peptide/martinize_runner.py +0 -0
  109. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/cg/peptide/mdp_templates.py +0 -0
  110. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/cg/peptide/models.py +0 -0
  111. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/cg/peptide/peptide_atomistic.py +0 -0
  112. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/cg/peptide/system_packer.py +0 -0
  113. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/cg/peptide/top_writer.py +0 -0
  114. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/cg/peptide/water_box.py +0 -0
  115. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/convertcpf.py +0 -0
  116. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/core/__init__.py +0 -0
  117. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/core/system_model.py +0 -0
  118. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/cpf2ifielist.py +0 -0
  119. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/cpfmanager.py +0 -0
  120. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/crystal/__init__.py +0 -0
  121. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/crystal/__main__.py +0 -0
  122. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/crystal/_subprocess.py +0 -0
  123. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/crystal/atom_distance.py +0 -0
  124. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/crystal/builder.py +0 -0
  125. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/crystal/cif_engine_ase.py +0 -0
  126. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/crystal/cif_engine_legacy.py +0 -0
  127. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/crystal/cli.py +0 -0
  128. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/crystal/forcefield_check.py +0 -0
  129. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/crystal/job_templates.py +0 -0
  130. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/crystal/legacy/__init__.py +0 -0
  131. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/crystal/models.py +0 -0
  132. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/crystal/postproc.py +0 -0
  133. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/f90/bin/readifiepiedalib.so +0 -0
  134. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/formulation/__init__.py +0 -0
  135. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/formulation/__main__.py +0 -0
  136. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/formulation/_subprocess.py +0 -0
  137. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/formulation/analysis/hbond.py +0 -0
  138. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/formulation/analysis/sasa.py +0 -0
  139. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/formulation/analysis/secondary_structure.py +0 -0
  140. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/formulation/mdp_templates.py +0 -0
  141. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/formulation/packer.py +0 -0
  142. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/formulation/peptide_atomistic.py +0 -0
  143. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/formulation/small_molecule.py +0 -0
  144. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/formulation/umbrella_release.py +0 -0
  145. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/fragmenter/__init__.py +0 -0
  146. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/fragmenter/__main__.py +0 -0
  147. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/fragmenter/auto_split.py +0 -0
  148. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/fragmenter/cg_segmenter/cap_attach.py +0 -0
  149. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/fragmenter/cg_segmenter/chain_splitter.py +0 -0
  150. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/fragmenter/cg_segmenter/exporter.py +0 -0
  151. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/fragmenter/cg_segmenter/models.py +0 -0
  152. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/fragmenter/cg_segmenter/ring_detector.py +0 -0
  153. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/fragmenter/cut_apply.py +0 -0
  154. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/fragmenter/grouping.py +0 -0
  155. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/fragmenter/headless_io.py +0 -0
  156. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/fragmenter/models.py +0 -0
  157. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/fragmenter/notebook_ui.py +0 -0
  158. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/fragmenter/pdb_loader.py +0 -0
  159. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/fragmenter/polymer.py +0 -0
  160. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/generate_difie.py +0 -0
  161. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/generateajf.py +0 -0
  162. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/genesis/__init__.py +0 -0
  163. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/genesis/grest/__init__.py +0 -0
  164. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/genesis/grest/__main__.py +0 -0
  165. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/genesis/grest/_subprocess.py +0 -0
  166. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/genesis/grest/analysis.py +0 -0
  167. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/genesis/grest/builder.py +0 -0
  168. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/genesis/grest/cli.py +0 -0
  169. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/genesis/grest/forcefield_check.py +0 -0
  170. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/genesis/grest/grest_runner.py +0 -0
  171. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/genesis/grest/inp_writer.py +0 -0
  172. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/genesis/grest/models.py +0 -0
  173. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/genesis/grest/replica_temperatures.py +0 -0
  174. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/genesis/grest/rest_selection.py +0 -0
  175. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/genesis/grest/system_builder.py +0 -0
  176. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/genesis/mmgbsa/__init__.py +0 -0
  177. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/genesis/mmgbsa/__main__.py +0 -0
  178. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/genesis/mmgbsa/_subprocess.py +0 -0
  179. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/genesis/mmgbsa/analysis.py +0 -0
  180. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/genesis/mmgbsa/builder.py +0 -0
  181. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/genesis/mmgbsa/cli.py +0 -0
  182. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/genesis/mmgbsa/forcefield_check.py +0 -0
  183. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/genesis/mmgbsa/gbsa_runner.py +0 -0
  184. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/genesis/mmgbsa/inp_writer.py +0 -0
  185. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/genesis/mmgbsa/ligand_parameterize.py +0 -0
  186. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/genesis/mmgbsa/models.py +0 -0
  187. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/genesis/mmgbsa/pdb_splitter.py +0 -0
  188. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/genesis/mmgbsa/system_builder.py +0 -0
  189. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/geomopt/__init__.py +0 -0
  190. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/geomopt/mace_optimizer.py +0 -0
  191. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/geomopt/openff_openmm_minimizer.py +0 -0
  192. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/geomopt/pyscf_optimizer.py +0 -0
  193. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/getcharge.py +0 -0
  194. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/getifiepieda.py +0 -0
  195. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/gro2udf/__init__.py +0 -0
  196. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/gro2udf/__main__.py +0 -0
  197. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/gro2udf/cli.py +0 -0
  198. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/gro2udf/default_template.udf +0 -0
  199. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/gro2udf/default_template_cognac101.udf +0 -0
  200. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/gro2udf/exporter.py +0 -0
  201. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/gro2udf/gro_adapter.py +0 -0
  202. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/gro2udf/gro_parser.py +0 -0
  203. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/gro2udf/mdp_parser.py +0 -0
  204. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/gro2udf/top_adapter.py +0 -0
  205. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/gro2udf/top_model.py +0 -0
  206. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/gro2udf/top_parser.py +0 -0
  207. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/gro2udf/trajectory_io.py +0 -0
  208. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/hbond/__main__.py +0 -0
  209. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/hbond/bdf_reader.py +0 -0
  210. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/hbond/classifier.py +0 -0
  211. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/hbond/colorizer.py +0 -0
  212. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/hbond/func_tags.py +0 -0
  213. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/hbond/functional_groups.py +0 -0
  214. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/hbond/hbond_detector.py +0 -0
  215. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/hbond/lifetime.py +0 -0
  216. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/hbond/notebook_ui.py +0 -0
  217. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/hbond/pair_type_stats.py +0 -0
  218. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/log2config.py +0 -0
  219. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/log2cpf.py +0 -0
  220. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/logmanager.py +0 -0
  221. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/membrane/__init__.py +0 -0
  222. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/membrane/bilayer.py +0 -0
  223. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/membrane/builder.py +0 -0
  224. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/membrane/lipid_info.py +0 -0
  225. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/membrane/mdp_us_protocol.py +0 -0
  226. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/membrane/models.py +0 -0
  227. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/membrane/parameterize_amber.py +0 -0
  228. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/membrane/parameterize_charmm.py +0 -0
  229. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/membrane/pmf.py +0 -0
  230. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/membrane/pulling.py +0 -0
  231. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/membrane/topology_sanity.py +0 -0
  232. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/membrane/umbrella.py +0 -0
  233. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/mol_io.py +0 -0
  234. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/pdb2fmo.py +0 -0
  235. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/pdb_io.py +0 -0
  236. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/pdbmodify.py +0 -0
  237. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/readcif.py +0 -0
  238. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/udf2fmo.py +0 -0
  239. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/udf2gro/__init__.py +0 -0
  240. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/udf2gro/__main__.py +0 -0
  241. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/udf2gro/cli.py +0 -0
  242. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/udf2gro/exporter.py +0 -0
  243. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/udf2gro/gromacs/__init__.py +0 -0
  244. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/udf2gro/gromacs/writers/__init__.py +0 -0
  245. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/udf2gro/gromacs/writers/_validator.py +0 -0
  246. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/udf2gro/gromacs/writers/gro_writer.py +0 -0
  247. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/udf2gro/gromacs/writers/itp_writer.py +0 -0
  248. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/udf2gro/gromacs/writers/mdp_writer.py +0 -0
  249. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/udf2gro/gromacs/writers/top_writer.py +0 -0
  250. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/udf2gro/udf_adapter.py +0 -0
  251. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/udfcreate.py +0 -0
  252. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/udfcreate_v2.py +0 -0
  253. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools/udfrm_io.py +0 -0
  254. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools.egg-info/dependency_links.txt +0 -0
  255. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools.egg-info/entry_points.txt +0 -0
  256. {abmptools-2.0.0 → abmptools-2.2.0}/abmptools.egg-info/top_level.txt +0 -0
  257. {abmptools-2.0.0 → abmptools-2.2.0}/setup.cfg +0 -0
  258. {abmptools-2.0.0 → abmptools-2.2.0}/setup.py +0 -0
  259. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_abinit_io.py +0 -0
  260. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_amorphous_models.py +0 -0
  261. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_anlfmo.py +0 -0
  262. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_cg_membrane_builder_mocked.py +0 -0
  263. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_cg_membrane_cli.py +0 -0
  264. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_cg_membrane_forcefield_check.py +0 -0
  265. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_cg_membrane_insane_runner.py +0 -0
  266. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_cg_membrane_integration.py +0 -0
  267. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_cg_membrane_mdp.py +0 -0
  268. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_cg_membrane_models.py +0 -0
  269. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_cg_membrane_packer.py +0 -0
  270. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_cg_membrane_pmf.py +0 -0
  271. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_cg_membrane_pulling.py +0 -0
  272. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_cg_membrane_topology_composer.py +0 -0
  273. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_cg_membrane_umbrella.py +0 -0
  274. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_cg_peptide_atomistic.py +0 -0
  275. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_cg_peptide_builder_mocked.py +0 -0
  276. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_cg_peptide_cli.py +0 -0
  277. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_cg_peptide_forcefield_check.py +0 -0
  278. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_cg_peptide_integration.py +0 -0
  279. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_cg_peptide_martinize_runner.py +0 -0
  280. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_cg_peptide_mdp.py +0 -0
  281. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_cg_peptide_models.py +0 -0
  282. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_cg_peptide_packer.py +0 -0
  283. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_cg_peptide_subprocess.py +0 -0
  284. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_cg_peptide_topwriter.py +0 -0
  285. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_cg_peptide_water_box.py +0 -0
  286. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_cli_scripts.py +0 -0
  287. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_cpfmanager.py +0 -0
  288. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_crystal_atom_distance.py +0 -0
  289. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_crystal_builder.py +0 -0
  290. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_crystal_cif_ase.py +0 -0
  291. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_crystal_cif_legacy.py +0 -0
  292. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_crystal_cli.py +0 -0
  293. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_crystal_job_templates.py +0 -0
  294. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_crystal_models.py +0 -0
  295. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_crystal_numeric_regression.py +0 -0
  296. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_crystal_regression.py +0 -0
  297. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_density.py +0 -0
  298. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_formulation_analysis.py +0 -0
  299. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_formulation_builder.py +0 -0
  300. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_formulation_mdp.py +0 -0
  301. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_formulation_models.py +0 -0
  302. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_formulation_packer.py +0 -0
  303. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_formulation_peptide_atomistic.py +0 -0
  304. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_formulation_small_molecule.py +0 -0
  305. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_formulation_topology.py +0 -0
  306. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_formulation_umbrella_release.py +0 -0
  307. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_getifiepieda.py +0 -0
  308. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_grest_analysis_mocked.py +0 -0
  309. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_grest_builder_mocked.py +0 -0
  310. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_grest_cli.py +0 -0
  311. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_grest_inp_writer.py +0 -0
  312. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_grest_integration.py +0 -0
  313. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_grest_models.py +0 -0
  314. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_grest_replica_temperatures.py +0 -0
  315. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_grest_rest_selection.py +0 -0
  316. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_grest_system_builder.py +0 -0
  317. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_gro_adapter.py +0 -0
  318. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_gro_parser.py +0 -0
  319. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_gro_writer.py +0 -0
  320. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_interchange_adapter.py +0 -0
  321. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_logmanager.py +0 -0
  322. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_mdp_parser.py +0 -0
  323. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_mdp_writer.py +0 -0
  324. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_membrane_charmm_translate.py +0 -0
  325. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_membrane_mixed_lipid.py +0 -0
  326. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_membrane_topology_sanity.py +0 -0
  327. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_mmgbsa_analysis.py +0 -0
  328. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_mmgbsa_builder_mocked.py +0 -0
  329. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_mmgbsa_cli.py +0 -0
  330. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_mmgbsa_forcefield_check.py +0 -0
  331. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_mmgbsa_inp_writer.py +0 -0
  332. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_mmgbsa_integration.py +0 -0
  333. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_mmgbsa_models.py +0 -0
  334. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_mmgbsa_pdb_splitter.py +0 -0
  335. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_mmgbsa_system_builder.py +0 -0
  336. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_mol_io.py +0 -0
  337. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_molcalc.py +0 -0
  338. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_ndx_writer.py +0 -0
  339. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_parameterizer.py +0 -0
  340. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_pdb_io.py +0 -0
  341. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_pubchem.py +0 -0
  342. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_pyscf_optimizer.py +0 -0
  343. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_pyscf_parsers.py +0 -0
  344. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_read_ifie_hf_fallback.py +0 -0
  345. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_readcif.py +0 -0
  346. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_regression.py +0 -0
  347. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_setfmo.py +0 -0
  348. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_system_model.py +0 -0
  349. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_system_model_extensions.py +0 -0
  350. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_top_exporter_frames_override.py +0 -0
  351. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_top_model.py +0 -0
  352. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_top_parser.py +0 -0
  353. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_top_writer.py +0 -0
  354. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_trajectory_ingest.py +0 -0
  355. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_udf_io.py +0 -0
  356. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_udfcreate.py +0 -0
  357. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_udfcreate_v2.py +0 -0
  358. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_udfcreate_v2_byte_equivalence.py +0 -0
  359. {abmptools-2.0.0 → abmptools-2.2.0}/tests/test_udfrm_io.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: abmptools
3
- Version: 2.0.0
3
+ Version: 2.2.0
4
4
  Summary: Pre/post-processing and analysis toolkit for ABINIT-MP Fragment Molecular Orbital calculations
5
5
  Author-email: Koji Okuwaki <koujioku81@gmail.com>
6
6
  License-Expression: Apache-2.0
@@ -59,6 +59,18 @@ Provides-Extra: formulation-analysis
59
59
  Requires-Dist: MDAnalysis<3.0,>=2.6; extra == "formulation-analysis"
60
60
  Requires-Dist: networkx>=3.0; extra == "formulation-analysis"
61
61
  Requires-Dist: matplotlib>=3.5; extra == "formulation-analysis"
62
+ Provides-Extra: formulation-openff
63
+ Requires-Dist: openff-toolkit>=0.14.0; extra == "formulation-openff"
64
+ Requires-Dist: openff-interchange>=0.3.0; extra == "formulation-openff"
65
+ Requires-Dist: openff-amber-ff-ports>=0.0.3; extra == "formulation-openff"
66
+ Requires-Dist: openff-nagl>=0.3; extra == "formulation-openff"
67
+ Requires-Dist: openff-nagl-models>=0.1; extra == "formulation-openff"
68
+ Requires-Dist: openmm>=8.0; extra == "formulation-openff"
69
+ Requires-Dist: pdbfixer>=1.9; extra == "formulation-openff"
70
+ Requires-Dist: rdkit-pypi>=2022.09; extra == "formulation-openff"
71
+ Requires-Dist: matplotlib>=3.5; extra == "formulation-openff"
72
+ Requires-Dist: PeptideBuilder>=1.1; extra == "formulation-openff"
73
+ Requires-Dist: biopython>=1.79; extra == "formulation-openff"
62
74
  Provides-Extra: geomopt
63
75
  Requires-Dist: pyscf; extra == "geomopt"
64
76
  Requires-Dist: ase; extra == "geomopt"
@@ -109,6 +121,7 @@ A Python toolkit for pre-processing, post-processing, and analysis of Fragment M
109
121
 
110
122
  - **udf2gro**: Convert OCTA UDF files to GROMACS format (`.gro`, `.top`, `.mdp`, `.itp`)
111
123
  - **gro2udf**: Convert GROMACS files to OCTA UDF format (supports `--from-top` mode)
124
+ - **udfcharge**: Transfer per-atom partial charges from a single-molecule UDF to every same-named molecule in a bulk UDF
112
125
 
113
126
  ### Geometry Optimization (`geomopt`)
114
127
 
@@ -300,6 +313,9 @@ python -m abmptools.udf2gro.cli -i system.udf -o output
300
313
  # Convert GROMACS to UDF
301
314
  python -m abmptools.gro2udf.cli -i system.gro -t system.top -o output.udf
302
315
 
316
+ # Transfer charges from a single-molecule UDF to all same-named molecules in a bulk UDF
317
+ python -m abmptools.udfcharge --template mol.udf --bulk bulk.udf --out bulk_charged.udf
318
+
303
319
  # Build an amorphous mixture from SMILES (50 ketoprofen molecules, density 0.8 g/cm^3)
304
320
  python -m abmptools.amorphous --smiles "OC(=O)C(C)c1cccc(C(=O)c2ccccc2)c1" \
305
321
  --name ketoprofen --n_mol 50 --density 0.8 --output_dir ./ketoprofen
@@ -349,6 +365,7 @@ Use `-h` with any module for full option details.
349
365
  - **[Developer Quickstart](docs/dev_quickstart.md)** — Setup and code conventions
350
366
  - **[I/O Spec](docs/io_spec.md)** — File format specifications
351
367
  - **[gro2udf](docs/gro2udf.md)** / **[udf2gro](docs/udf2gro.md)** — GROMACS ↔ OCTA conversion
368
+ - **[udfcharge](docs/udfcharge.md)** / **[tutorial_udfcharge](docs/tutorial_udfcharge.md)** — single-molecule → bulk UDF charge transfer
352
369
  - **[geomopt](docs/geomopt.md)** / **[amorphous](docs/amorphous.md)** — Optimization and structure building
353
370
  - **[membrane](docs/membrane.md)** / **[tutorial_membrane_us](docs/tutorial_membrane_us.md)** — Peptide-bilayer umbrella-sampling PMF (AA, CHARMM36 / Lipid21)
354
371
  - **[cg_membrane](docs/cg_membrane.md)** / **[tutorial_cg_membrane_us](docs/tutorial_cg_membrane_us.md)** — Martini 3 peptide-bilayer PMF (CG, 30-100× faster than AA, KGG-POPC smoke 5 min / production 45 min)
@@ -37,6 +37,7 @@ A Python toolkit for pre-processing, post-processing, and analysis of Fragment M
37
37
 
38
38
  - **udf2gro**: Convert OCTA UDF files to GROMACS format (`.gro`, `.top`, `.mdp`, `.itp`)
39
39
  - **gro2udf**: Convert GROMACS files to OCTA UDF format (supports `--from-top` mode)
40
+ - **udfcharge**: Transfer per-atom partial charges from a single-molecule UDF to every same-named molecule in a bulk UDF
40
41
 
41
42
  ### Geometry Optimization (`geomopt`)
42
43
 
@@ -228,6 +229,9 @@ python -m abmptools.udf2gro.cli -i system.udf -o output
228
229
  # Convert GROMACS to UDF
229
230
  python -m abmptools.gro2udf.cli -i system.gro -t system.top -o output.udf
230
231
 
232
+ # Transfer charges from a single-molecule UDF to all same-named molecules in a bulk UDF
233
+ python -m abmptools.udfcharge --template mol.udf --bulk bulk.udf --out bulk_charged.udf
234
+
231
235
  # Build an amorphous mixture from SMILES (50 ketoprofen molecules, density 0.8 g/cm^3)
232
236
  python -m abmptools.amorphous --smiles "OC(=O)C(C)c1cccc(C(=O)c2ccccc2)c1" \
233
237
  --name ketoprofen --n_mol 50 --density 0.8 --output_dir ./ketoprofen
@@ -277,6 +281,7 @@ Use `-h` with any module for full option details.
277
281
  - **[Developer Quickstart](docs/dev_quickstart.md)** — Setup and code conventions
278
282
  - **[I/O Spec](docs/io_spec.md)** — File format specifications
279
283
  - **[gro2udf](docs/gro2udf.md)** / **[udf2gro](docs/udf2gro.md)** — GROMACS ↔ OCTA conversion
284
+ - **[udfcharge](docs/udfcharge.md)** / **[tutorial_udfcharge](docs/tutorial_udfcharge.md)** — single-molecule → bulk UDF charge transfer
280
285
  - **[geomopt](docs/geomopt.md)** / **[amorphous](docs/amorphous.md)** — Optimization and structure building
281
286
  - **[membrane](docs/membrane.md)** / **[tutorial_membrane_us](docs/tutorial_membrane_us.md)** — Peptide-bilayer umbrella-sampling PMF (AA, CHARMM36 / Lipid21)
282
287
  - **[cg_membrane](docs/cg_membrane.md)** / **[tutorial_cg_membrane_us](docs/tutorial_cg_membrane_us.md)** — Martini 3 peptide-bilayer PMF (CG, 30-100× faster than AA, KGG-POPC smoke 5 min / production 45 min)
@@ -156,7 +156,7 @@ def get_args():
156
156
  )
157
157
 
158
158
  parser.add_argument('-ma', '--manual',
159
- help='manual table',
159
+ help='manual fragment table (already the default; kept for compatibility)',
160
160
  action='store_true',
161
161
  )
162
162
 
@@ -217,7 +217,13 @@ def main():
217
217
  aobj.ajf_method = args.method
218
218
  aobj.ajf_basis_set = args.basisset
219
219
  aobj.abinit_ver = args.ajfversion
220
- aobj.autofrag = True
220
+ # addsolvfrag は「溶質を手動フラグメント分割した上で、スナップショット
221
+ # ごとの溶媒フラグメントをテーブルに追加する」ためのツール。よって
222
+ # 出力 AJF は常に AutoFrag='OFF' とし、溶質テンプレートの &FRAGMENT に
223
+ # 溶媒フラグメントを連結したテーブルを書き出す必要がある。
224
+ # autofrag=True にすると abinit_io 側で AutoFrag='ON' かつ &FRAGMENT が
225
+ # 空になり、本ツールの目的を満たさないため False を既定とする。
226
+ aobj.autofrag = False
221
227
  aobj.piedaflag = args.nopieda
222
228
  aobj.cpfflag = args.nocpf
223
229
  aobj.cpfver = args.cpfver
@@ -241,6 +247,8 @@ def main():
241
247
  aobj.mllimit = args.mllimit
242
248
 
243
249
 
250
+ # -ma/--manual は後方互換のため残置。autofrag は既定で False(手動分割)
251
+ # のため、本フラグは明示的に手動分割を指定するだけで挙動は変わらない。
244
252
  if args.manual:
245
253
  aobj.autofrag = False
246
254
 
@@ -0,0 +1,466 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ abmptools.amorphous.builder
4
+ -----------------------------
5
+ Orchestrator: integrates all stages of amorphous structure building.
6
+
7
+ Data flow:
8
+ SMILES/SDF → molecule_prep → density → packing → parameterizer → mdp/ndx
9
+ """
10
+ from __future__ import annotations
11
+
12
+ import json
13
+ import logging
14
+ import os
15
+ from pathlib import Path
16
+ from typing import Any, Dict, List, Optional
17
+
18
+ from ..core.system_model import AnnealProtocol
19
+ from .models import BuildConfig, ComponentSpec
20
+ from .density import estimate_box_size_nm, weight_fractions_to_counts
21
+ from .molecule_prep import (
22
+ prepare_molecule,
23
+ get_molecular_weight,
24
+ write_single_mol_pdb,
25
+ )
26
+ from .packing import run_packmol
27
+ from .parameterizer import create_interchange, export_gromacs
28
+ from .mdp_protocol import (
29
+ write_all_mdp,
30
+ write_run_script,
31
+ write_udf_export_script,
32
+ write_wrap_script,
33
+ )
34
+ from .ndx_writer import write_ndx
35
+
36
+ logger = logging.getLogger(__name__)
37
+
38
+
39
+ class AmorphousBuilder:
40
+ """Build an amorphous multi-component system for GROMACS MD.
41
+
42
+ Usage::
43
+
44
+ from abmptools.amorphous import AmorphousBuilder, BuildConfig, ComponentSpec
45
+
46
+ config = BuildConfig(
47
+ components=[
48
+ ComponentSpec(smiles="CCCCC", name="pentane", n_mol=200),
49
+ ComponentSpec(smiles="c1ccccc1", name="benzene", n_mol=50),
50
+ ],
51
+ density_g_cm3=0.8,
52
+ temperature=300,
53
+ output_dir="./output",
54
+ )
55
+ builder = AmorphousBuilder(config)
56
+ result = builder.build()
57
+ """
58
+
59
+ def __init__(self, config: BuildConfig) -> None:
60
+ self.config = config
61
+ self._molecules: List[Any] = []
62
+ self._mol_weights: List[float] = []
63
+ self._counts: List[int] = []
64
+ self._box_nm: float = 0.0
65
+ self._pdb_paths: List[str] = []
66
+
67
+ def build(self) -> Dict[str, Any]:
68
+ """Run the full build pipeline.
69
+
70
+ Returns
71
+ -------
72
+ dict
73
+ Keys: "output_dir", "gro", "top", "ndx", "mdp_files",
74
+ "run_script", "config_json", "box_nm", "counts".
75
+ """
76
+ cfg = self.config
77
+ out = Path(cfg.output_dir)
78
+ input_dir = out / "input"
79
+ build_dir = out / "build"
80
+ md_dir = out / "md"
81
+ for d in [input_dir, build_dir, md_dir]:
82
+ d.mkdir(parents=True, exist_ok=True)
83
+
84
+ # Save config for reproducibility
85
+ config_json = str(input_dir / "config.json")
86
+ cfg.to_json(config_json)
87
+
88
+ # Stage 1: Prepare molecules
89
+ logger.info("=== Stage 1: Molecule preparation ===")
90
+ self._prepare_molecules(input_dir)
91
+
92
+ # Stage 2: Determine counts and box size
93
+ logger.info("=== Stage 2: Density / box estimation ===")
94
+ self._compute_counts_and_box()
95
+
96
+ # Stage 3: Packmol packing
97
+ logger.info("=== Stage 3: Packmol packing ===")
98
+ mixture_pdb = str(build_dir / "mixture.pdb")
99
+ self._run_packing(mixture_pdb, str(build_dir))
100
+
101
+ # Stage 4: Parameterize with OpenFF
102
+ logger.info("=== Stage 4: OpenFF parameterization ===")
103
+ gro_path = str(build_dir / "system.gro")
104
+ top_path = str(build_dir / "system.top")
105
+ gromacs_files = self._parameterize(mixture_pdb, gro_path, top_path)
106
+
107
+ # Stage 5: Write NDX
108
+ logger.info("=== Stage 5: NDX index groups ===")
109
+ ndx_path = str(build_dir / "system.ndx")
110
+ self._write_ndx(ndx_path)
111
+
112
+ # Stage 5b: position_restraints for trimer cluster center (if frozen
113
+ # atoms specified). freezegrps was tried first but failed Fugaku MPI:
114
+ # LINCS/SETTLE matrix inversion failed (`determinant = -inf`) because
115
+ # hard freeze + DD + rigid water constraints are incompatible. Switch
116
+ # to harmonic position_restraints (k=10000 kJ/mol/nm² default) which
117
+ # plays nice with all constraints and keeps atoms within ~0.01 Å of
118
+ # initial position — functionally equivalent for trimer center fix.
119
+ frozen = list(getattr(self.config, "frozen_atom_indices", []) or [])
120
+ define_posres = None
121
+ if frozen:
122
+ self._add_trimer_posres_to_top(top_path, frozen)
123
+ define_posres = "POSRES_TRIMER"
124
+
125
+ # Stage 6: Write MDP files and run script
126
+ logger.info("=== Stage 6: MDP protocol ===")
127
+ protocol = self._make_protocol()
128
+ tc_grps = self._tc_grps_string()
129
+ mdp_files = write_all_mdp(protocol, str(md_dir), tc_grps=tc_grps,
130
+ define_posres=define_posres)
131
+ run_script = write_run_script(str(md_dir))
132
+ wrap_script = write_wrap_script(str(md_dir))
133
+ udf_script = write_udf_export_script(str(md_dir))
134
+
135
+ logger.info("=== Build complete: %s ===", cfg.output_dir)
136
+ return {
137
+ "output_dir": str(out.resolve()),
138
+ "gro": gromacs_files["gro"],
139
+ "top": gromacs_files["top"],
140
+ "ndx": str(Path(ndx_path).resolve()),
141
+ "mdp_files": mdp_files,
142
+ "run_script": run_script,
143
+ "wrap_script": wrap_script,
144
+ "udf_script": udf_script,
145
+ "config_json": config_json,
146
+ "box_nm": self._box_nm,
147
+ "counts": list(self._counts),
148
+ }
149
+
150
+ # ---- internal stages ----
151
+
152
+ def _prepare_molecules(self, input_dir: Path) -> None:
153
+ """Prepare OpenFF Molecules and write single-molecule PDBs."""
154
+ for i, comp in enumerate(self.config.components):
155
+ mol = prepare_molecule(
156
+ smiles=comp.smiles,
157
+ sdf_path=comp.sdf_path,
158
+ pdb_path=comp.pdb_path,
159
+ name=comp.name or f"comp_{i}",
160
+ charge_method=self.config.charge_method,
161
+ nagl_model=self.config.nagl_model,
162
+ )
163
+ mw = get_molecular_weight(mol)
164
+ comp.molecular_weight = mw
165
+ if not comp.name:
166
+ comp.name = mol.name
167
+
168
+ pdb_path = str(input_dir / f"component_{i}.pdb")
169
+ write_single_mol_pdb(mol, pdb_path)
170
+
171
+ self._molecules.append(mol)
172
+ self._mol_weights.append(mw)
173
+ self._pdb_paths.append(pdb_path)
174
+
175
+ def _compute_counts_and_box(self) -> None:
176
+ """Determine molecule counts and box size."""
177
+ cfg = self.config
178
+
179
+ # Determine counts
180
+ has_n_mol = any(c.n_mol > 0 for c in cfg.components)
181
+ has_wf = any(c.weight_fraction > 0 for c in cfg.components)
182
+
183
+ if has_n_mol:
184
+ self._counts = [c.n_mol for c in cfg.components]
185
+ elif has_wf:
186
+ wfs = [c.weight_fraction for c in cfg.components]
187
+ total = cfg.total_molecules if cfg.total_molecules > 0 else 200
188
+ self._counts = weight_fractions_to_counts(
189
+ self._mol_weights, wfs, total
190
+ )
191
+ else:
192
+ raise ValueError(
193
+ "Specify either n_mol or weight_fraction for each component."
194
+ )
195
+
196
+ # Determine box size
197
+ if cfg.box_size_nm > 0:
198
+ self._box_nm = cfg.box_size_nm
199
+ else:
200
+ self._box_nm = estimate_box_size_nm(
201
+ self._mol_weights, self._counts, cfg.density_g_cm3
202
+ )
203
+ logger.info("Box size: %.4f nm, Counts: %s", self._box_nm, self._counts)
204
+
205
+ def _run_packing(self, output_pdb: str, build_dir: str) -> str:
206
+ # Optional pre-built cluster (UDF cluster_file equivalent).
207
+ # When cfg.cluster_pdb_path is set, packmol places the cluster
208
+ # rigidly at box center first. We reduce the first component's
209
+ # count by the cluster's mol count (n_trimer derived from
210
+ # frozen_atom_indices) so total mol count stays the same.
211
+ cluster_pdb = str(getattr(self.config, 'cluster_pdb_path', '') or '')
212
+ cluster_pdb = cluster_pdb if cluster_pdb else None
213
+ adjusted_counts = list(self._counts)
214
+ if cluster_pdb and self._molecules:
215
+ atoms_per_first = int(self._molecules[0].n_atoms)
216
+ frozen = list(getattr(self.config, 'frozen_atom_indices', []) or [])
217
+ if frozen:
218
+ n_cluster_mol = max((int(a) - 1) // atoms_per_first
219
+ for a in frozen) + 1
220
+ adjusted_counts[0] = max(0, adjusted_counts[0] - n_cluster_mol)
221
+ logger.info(
222
+ "cluster_pdb=%s placed as rigid block; first-component "
223
+ "count reduced by %d → %d", cluster_pdb, n_cluster_mol,
224
+ adjusted_counts[0],
225
+ )
226
+ return run_packmol(
227
+ pdb_paths=self._pdb_paths,
228
+ counts=adjusted_counts,
229
+ box_size_nm=self._box_nm,
230
+ output_pdb=output_pdb,
231
+ build_dir=build_dir,
232
+ tolerance=self.config.packmol_tolerance,
233
+ seed=self.config.seed,
234
+ packmol_path=self.config.packmol_path,
235
+ cluster_pdb=cluster_pdb,
236
+ )
237
+
238
+ def _parameterize(self, mixture_pdb: str,
239
+ gro_path: str, top_path: str) -> Dict[str, str]:
240
+ # When the user opted into nagl / gasteiger we pre-assigned charges
241
+ # on each molecule; tell Interchange to reuse them instead of
242
+ # invoking AM1-BCC via sqm (which has no Windows build).
243
+ use_precomputed = self.config.charge_method in ("nagl", "gasteiger")
244
+ interchange = create_interchange(
245
+ molecules=self._molecules,
246
+ counts=self._counts,
247
+ box_size_nm=self._box_nm,
248
+ mixture_pdb=mixture_pdb,
249
+ forcefield_name=self.config.forcefield,
250
+ use_precomputed_charges=use_precomputed,
251
+ )
252
+ return export_gromacs(interchange, gro_path, top_path)
253
+
254
+ def _write_ndx(self, ndx_path: str) -> str:
255
+ comp_names = [c.name or f"comp_{i}"
256
+ for i, c in enumerate(self.config.components)]
257
+ atom_counts = [mol.n_atoms for mol in self._molecules]
258
+ frozen = list(getattr(self.config, "frozen_atom_indices", []) or [])
259
+ return write_ndx(comp_names, atom_counts, self._counts, ndx_path,
260
+ frozen_atom_indices=frozen)
261
+
262
+ def _add_trimer_posres_to_top(self, top_path: str,
263
+ frozen_atoms_1based: list) -> None:
264
+ """Add [ position_restraints ] for trimer cluster center to system.top.
265
+
266
+ Derives local atom indices and trimer molecule count from the global
267
+ 1-based ``frozen_atoms_1based`` and the first component's atom count.
268
+ If the first moleculetype's molecule count > trimer count, splits the
269
+ moletype: a ``<name>_TRIMER`` copy (trimer count instances, with
270
+ posres) is inserted BEFORE the original moleculetype (now with
271
+ reduced count). Otherwise, the posres block is appended to the
272
+ existing first moletype.
273
+
274
+ The posres block is wrapped in ``#ifdef POSRES_TRIMER`` so anneal /
275
+ sampling mdp can toggle via ``define = -DPOSRES_TRIMER``.
276
+
277
+ Why posres (not freezegrps): hard freeze on rigid water O atoms
278
+ breaks LINCS / SETTLE matrix inversion under MPI Domain
279
+ Decomposition (`determinant = -inf`). Harmonic posres
280
+ (k = posres_force_constant, default 10000 kJ/mol/nm²) keeps the
281
+ atoms within ~0.01 Å of initial position without any constraint
282
+ conflict — functionally equivalent for trimer cluster fix.
283
+ """
284
+ if not self._molecules:
285
+ return
286
+ atoms_per_first_mol = int(self._molecules[0].n_atoms)
287
+ # Local 1-based atom indices within the first moletype
288
+ local_atoms = sorted({(int(a) - 1) % atoms_per_first_mol + 1
289
+ for a in frozen_atoms_1based})
290
+ # Trimer mol count = max mol-index used + 1
291
+ n_trimer = max((int(a) - 1) // atoms_per_first_mol
292
+ for a in frozen_atoms_1based) + 1
293
+ fc = float(getattr(self.config, 'posres_force_constant', 10000.0))
294
+
295
+ text = Path(top_path).read_text()
296
+
297
+ # Find first [ moleculetype ] block. Block extends until next
298
+ # [ moleculetype ] OR [ system ] marker.
299
+ import re
300
+ starts = [m.start() for m in re.finditer(r'^\[ moleculetype \]',
301
+ text, flags=re.MULTILINE)]
302
+ if not starts:
303
+ return
304
+ end_match = re.search(r'^\[ (?:moleculetype|system) \]', text[starts[0] + 1:],
305
+ flags=re.MULTILINE)
306
+ if end_match is None:
307
+ block_end = len(text)
308
+ else:
309
+ block_end = starts[0] + 1 + end_match.start()
310
+ first_block = text[starts[0]:block_end]
311
+
312
+ # First non-comment line after [ moleculetype ] is "<name>\t<nrexcl>"
313
+ moltype_name = None
314
+ for line in first_block.split('\n')[1:]:
315
+ s = line.strip()
316
+ if not s or s.startswith(';'):
317
+ continue
318
+ moltype_name = s.split()[0]
319
+ break
320
+ if not moltype_name:
321
+ return
322
+
323
+ # Find first entry in [ molecules ] section
324
+ mol_section_match = re.search(r'^\[ molecules \]', text, flags=re.MULTILINE)
325
+ if mol_section_match is None:
326
+ return
327
+ mol_start = mol_section_match.end()
328
+ first_count = None
329
+ first_line_text = None
330
+ for line in text[mol_start:].split('\n'):
331
+ s = line.strip()
332
+ if not s or s.startswith(';') or s.startswith('['):
333
+ continue
334
+ parts = s.split()
335
+ if len(parts) >= 2 and parts[0] == moltype_name:
336
+ try:
337
+ first_count = int(parts[1])
338
+ first_line_text = line
339
+ break
340
+ except ValueError:
341
+ pass
342
+ if first_count is None:
343
+ return
344
+
345
+ # Build posres block
346
+ posres_lines = ['', '#ifdef POSRES_TRIMER',
347
+ '[ position_restraints ]',
348
+ '; ai funct kx ky kz']
349
+ for ai in local_atoms:
350
+ posres_lines.append(f' {ai} 1 {fc:g} {fc:g} {fc:g}')
351
+ posres_lines.append('#endif')
352
+ posres_str = '\n'.join(posres_lines) + '\n'
353
+
354
+ needs_split = (first_count > n_trimer)
355
+ if needs_split:
356
+ # Insert TRIMER copy BEFORE the original. Rename only the
357
+ # moltype declaration line (first non-comment line after the
358
+ # [ moleculetype ] marker).
359
+ trimer_block_lines = first_block.split('\n')
360
+ for i in range(1, len(trimer_block_lines)):
361
+ s = trimer_block_lines[i].strip()
362
+ if not s or s.startswith(';'):
363
+ continue
364
+ if s.split()[0] == moltype_name:
365
+ trimer_block_lines[i] = trimer_block_lines[i].replace(
366
+ moltype_name, moltype_name + '_TRIMER', 1)
367
+ break
368
+ trimer_block_text = '\n'.join(trimer_block_lines)
369
+ # GROMACS forbids 2 moltypes both having [ settles ]
370
+ # (`Only one such is allowed`). Convert TRIMER copy's settles
371
+ # to equivalent [ constraints ] (LINCS-based) so the original
372
+ # moltype keeps its faster SETTLE and TRIMER becomes
373
+ # constraint-based rigid water. For TIP3P/SPC 3-site water:
374
+ # [ settles ]
375
+ # 1 1 dOH dHH
376
+ # → [ constraints ]
377
+ # 1 2 1 dOH ; O-H1
378
+ # 1 3 1 dOH ; O-H2
379
+ # 2 3 1 dHH ; H1-H2
380
+ settles_block_pattern = re.compile(
381
+ r'(\[ settles \].*?)(?=\n\[ |\Z)', re.DOTALL,
382
+ )
383
+ settles_match = settles_block_pattern.search(trimer_block_text)
384
+ if settles_match:
385
+ settles_text = settles_match.group(1)
386
+ # Parse the first non-comment row: "i funct dOH dHH"
387
+ dOH = dHH = None
388
+ for line in settles_text.split('\n')[1:]:
389
+ s = line.strip()
390
+ if not s or s.startswith(';') or s.startswith('['):
391
+ continue
392
+ parts = s.split()
393
+ if len(parts) >= 4:
394
+ try:
395
+ dOH = float(parts[2])
396
+ dHH = float(parts[3])
397
+ break
398
+ except ValueError:
399
+ continue
400
+ if dOH is not None:
401
+ constraints_text = (
402
+ f'[ constraints ]\n'
403
+ f'; ai aj funct value (TIP3P/SPC rigid water, '
404
+ f'converted from [settles])\n'
405
+ f' 1 2 1 {dOH}\n'
406
+ f' 1 3 1 {dOH}\n'
407
+ f' 2 3 1 {dHH}\n'
408
+ )
409
+ trimer_block_text = trimer_block_text.replace(
410
+ settles_text, constraints_text, 1)
411
+ trimer_block = trimer_block_text.rstrip() + '\n' + posres_str + '\n'
412
+ text = text[:starts[0]] + trimer_block + text[starts[0]:]
413
+ # Update the [ molecules ] line
414
+ new_first_line = (
415
+ f'{moltype_name}_TRIMER\t{n_trimer}\n'
416
+ f'{moltype_name}\t{first_count - n_trimer}'
417
+ )
418
+ text = text.replace(first_line_text, new_first_line, 1)
419
+ else:
420
+ # No split — append posres at end of first moltype block
421
+ new_block = first_block.rstrip() + '\n' + posres_str + '\n'
422
+ text = text.replace(first_block, new_block, 1)
423
+
424
+ Path(top_path).write_text(text)
425
+ logger.info(
426
+ "added [ position_restraints ] (k=%g) for moltype %s (n_trimer=%d, "
427
+ "local_atoms=%s, split=%s)",
428
+ fc, moltype_name, n_trimer, local_atoms, needs_split,
429
+ )
430
+
431
+ def _make_protocol(self) -> AnnealProtocol:
432
+ cfg = self.config
433
+ return AnnealProtocol(
434
+ T_high=cfg.T_high,
435
+ T_low=cfg.temperature,
436
+ P_ref=cfg.pressure,
437
+ em_steps=cfg.em_steps,
438
+ em_tol=cfg.em_tol,
439
+ nvt_high_nsteps=cfg.nvt_high_nsteps,
440
+ npt_high_nsteps=cfg.npt_high_nsteps,
441
+ anneal_nsteps=cfg.anneal_nsteps,
442
+ npt_low_nsteps=cfg.npt_low_nsteps,
443
+ dt=cfg.dt,
444
+ tau_t=cfg.tau_t,
445
+ tau_p=cfg.tau_p,
446
+ nstxout_compressed=cfg.nstxout_compressed,
447
+ nstenergy=cfg.nstenergy,
448
+ gen_seed=cfg.seed,
449
+ )
450
+
451
+ def _tc_grps_string(self) -> str:
452
+ """Build the tc-grps string for MDP (e.g. 'API Polymer').
453
+
454
+ Names are deduplicated while preserving first-seen order so that
455
+ pure-component pairs (e.g. ``ComponentSpec(name='B_water', ...)``
456
+ × 2) emit a single group, matching the single ``ref-t`` /
457
+ ``tau-t`` value emitted by :func:`mdp_protocol._thermostat_block`.
458
+ Without dedup, grompp rejects the mdp with
459
+ ``Invalid T coupling input: 2 groups, 1 ref-t values``.
460
+ """
461
+ seen: dict[str, None] = {}
462
+ for i, c in enumerate(self.config.components):
463
+ name = c.name or f"comp_{i}"
464
+ if name not in seen:
465
+ seen[name] = None
466
+ return " ".join(seen.keys())