py-chargemol 1.0.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 (306) hide show
  1. py_chargemol-1.0.0/CHANGELOG.md +39 -0
  2. py_chargemol-1.0.0/LICENSE +44 -0
  3. py_chargemol-1.0.0/LICENSE-CHARGEMOL +57 -0
  4. py_chargemol-1.0.0/PKG-INFO +531 -0
  5. py_chargemol-1.0.0/README.md +505 -0
  6. py_chargemol-1.0.0/build_tools/smoke_install.py +50 -0
  7. py_chargemol-1.0.0/pyproject.toml +174 -0
  8. py_chargemol-1.0.0/pyproject.toml.orig +164 -0
  9. py_chargemol-1.0.0/src/py_chargemol/__init__.py +71 -0
  10. py_chargemol-1.0.0/src/py_chargemol/__main__.py +206 -0
  11. py_chargemol-1.0.0/src/py_chargemol/_version.py +5 -0
  12. py_chargemol-1.0.0/src/py_chargemol/ddec6.py +377 -0
  13. py_chargemol-1.0.0/src/py_chargemol/density/__init__.py +1 -0
  14. py_chargemol-1.0.0/src/py_chargemol/density/analysis.py +382 -0
  15. py_chargemol-1.0.0/src/py_chargemol/density/bonds.py +558 -0
  16. py_chargemol-1.0.0/src/py_chargemol/density/cm5.py +343 -0
  17. py_chargemol-1.0.0/src/py_chargemol/density/core.py +157 -0
  18. py_chargemol-1.0.0/src/py_chargemol/density/data/README.md +20 -0
  19. py_chargemol-1.0.0/src/py_chargemol/density/data/SHA256SUMS.json +1899 -0
  20. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_001.zip +0 -0
  21. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_002.zip +0 -0
  22. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_003.zip +0 -0
  23. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_004.zip +0 -0
  24. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_005.zip +0 -0
  25. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_006.zip +0 -0
  26. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_007.zip +0 -0
  27. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_008.zip +0 -0
  28. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_009.zip +0 -0
  29. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_010.zip +0 -0
  30. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_011.zip +0 -0
  31. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_012.zip +0 -0
  32. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_013.zip +0 -0
  33. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_014.zip +0 -0
  34. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_015.zip +0 -0
  35. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_016.zip +0 -0
  36. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_017.zip +0 -0
  37. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_018.zip +0 -0
  38. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_019.zip +0 -0
  39. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_020.zip +0 -0
  40. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_021.zip +0 -0
  41. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_022.zip +0 -0
  42. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_023.zip +0 -0
  43. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_024.zip +0 -0
  44. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_025.zip +0 -0
  45. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_026.zip +0 -0
  46. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_027.zip +0 -0
  47. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_028.zip +0 -0
  48. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_029.zip +0 -0
  49. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_030.zip +0 -0
  50. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_031.zip +0 -0
  51. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_032.zip +0 -0
  52. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_033.zip +0 -0
  53. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_034.zip +0 -0
  54. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_035.zip +0 -0
  55. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_036.zip +0 -0
  56. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_037.zip +0 -0
  57. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_038.zip +0 -0
  58. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_039.zip +0 -0
  59. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_040.zip +0 -0
  60. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_041.zip +0 -0
  61. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_042.zip +0 -0
  62. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_043.zip +0 -0
  63. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_044.zip +0 -0
  64. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_045.zip +0 -0
  65. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_046.zip +0 -0
  66. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_047.zip +0 -0
  67. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_048.zip +0 -0
  68. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_049.zip +0 -0
  69. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_050.zip +0 -0
  70. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_051.zip +0 -0
  71. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_052.zip +0 -0
  72. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_053.zip +0 -0
  73. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_054.zip +0 -0
  74. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_055.zip +0 -0
  75. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_056.zip +0 -0
  76. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_057.zip +0 -0
  77. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_058.zip +0 -0
  78. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_059.zip +0 -0
  79. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_060.zip +0 -0
  80. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_061.zip +0 -0
  81. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_062.zip +0 -0
  82. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_063.zip +0 -0
  83. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_064.zip +0 -0
  84. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_065.zip +0 -0
  85. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_066.zip +0 -0
  86. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_067.zip +0 -0
  87. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_068.zip +0 -0
  88. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_069.zip +0 -0
  89. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_070.zip +0 -0
  90. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_071.zip +0 -0
  91. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_072.zip +0 -0
  92. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_073.zip +0 -0
  93. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_074.zip +0 -0
  94. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_075.zip +0 -0
  95. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_076.zip +0 -0
  96. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_077.zip +0 -0
  97. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_078.zip +0 -0
  98. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_079.zip +0 -0
  99. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_080.zip +0 -0
  100. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_081.zip +0 -0
  101. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_082.zip +0 -0
  102. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_083.zip +0 -0
  103. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_084.zip +0 -0
  104. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_085.zip +0 -0
  105. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_086.zip +0 -0
  106. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_087.zip +0 -0
  107. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_088.zip +0 -0
  108. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_089.zip +0 -0
  109. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_090.zip +0 -0
  110. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_091.zip +0 -0
  111. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_092.zip +0 -0
  112. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_093.zip +0 -0
  113. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_094.zip +0 -0
  114. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_095.zip +0 -0
  115. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_096.zip +0 -0
  116. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_097.zip +0 -0
  117. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_098.zip +0 -0
  118. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_099.zip +0 -0
  119. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_100.zip +0 -0
  120. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_101.zip +0 -0
  121. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_102.zip +0 -0
  122. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_103.zip +0 -0
  123. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_104.zip +0 -0
  124. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_105.zip +0 -0
  125. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_106.zip +0 -0
  126. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_107.zip +0 -0
  127. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_108.zip +0 -0
  128. py_chargemol-1.0.0/src/py_chargemol/density/data/c2_109.zip +0 -0
  129. py_chargemol-1.0.0/src/py_chargemol/density/data/core_001.zip +0 -0
  130. py_chargemol-1.0.0/src/py_chargemol/density/data/core_002.zip +0 -0
  131. py_chargemol-1.0.0/src/py_chargemol/density/data/core_003.zip +0 -0
  132. py_chargemol-1.0.0/src/py_chargemol/density/data/core_004.zip +0 -0
  133. py_chargemol-1.0.0/src/py_chargemol/density/data/core_005.zip +0 -0
  134. py_chargemol-1.0.0/src/py_chargemol/density/data/core_006.zip +0 -0
  135. py_chargemol-1.0.0/src/py_chargemol/density/data/core_007.zip +0 -0
  136. py_chargemol-1.0.0/src/py_chargemol/density/data/core_008.zip +0 -0
  137. py_chargemol-1.0.0/src/py_chargemol/density/data/core_009.zip +0 -0
  138. py_chargemol-1.0.0/src/py_chargemol/density/data/core_010.zip +0 -0
  139. py_chargemol-1.0.0/src/py_chargemol/density/data/core_011.zip +0 -0
  140. py_chargemol-1.0.0/src/py_chargemol/density/data/core_012.zip +0 -0
  141. py_chargemol-1.0.0/src/py_chargemol/density/data/core_013.zip +0 -0
  142. py_chargemol-1.0.0/src/py_chargemol/density/data/core_014.zip +0 -0
  143. py_chargemol-1.0.0/src/py_chargemol/density/data/core_015.zip +0 -0
  144. py_chargemol-1.0.0/src/py_chargemol/density/data/core_016.zip +0 -0
  145. py_chargemol-1.0.0/src/py_chargemol/density/data/core_017.zip +0 -0
  146. py_chargemol-1.0.0/src/py_chargemol/density/data/core_018.zip +0 -0
  147. py_chargemol-1.0.0/src/py_chargemol/density/data/core_019.zip +0 -0
  148. py_chargemol-1.0.0/src/py_chargemol/density/data/core_020.zip +0 -0
  149. py_chargemol-1.0.0/src/py_chargemol/density/data/core_021.zip +0 -0
  150. py_chargemol-1.0.0/src/py_chargemol/density/data/core_022.zip +0 -0
  151. py_chargemol-1.0.0/src/py_chargemol/density/data/core_023.zip +0 -0
  152. py_chargemol-1.0.0/src/py_chargemol/density/data/core_024.zip +0 -0
  153. py_chargemol-1.0.0/src/py_chargemol/density/data/core_025.zip +0 -0
  154. py_chargemol-1.0.0/src/py_chargemol/density/data/core_026.zip +0 -0
  155. py_chargemol-1.0.0/src/py_chargemol/density/data/core_027.zip +0 -0
  156. py_chargemol-1.0.0/src/py_chargemol/density/data/core_028.zip +0 -0
  157. py_chargemol-1.0.0/src/py_chargemol/density/data/core_029.zip +0 -0
  158. py_chargemol-1.0.0/src/py_chargemol/density/data/core_030.zip +0 -0
  159. py_chargemol-1.0.0/src/py_chargemol/density/data/core_031.zip +0 -0
  160. py_chargemol-1.0.0/src/py_chargemol/density/data/core_032.zip +0 -0
  161. py_chargemol-1.0.0/src/py_chargemol/density/data/core_033.zip +0 -0
  162. py_chargemol-1.0.0/src/py_chargemol/density/data/core_034.zip +0 -0
  163. py_chargemol-1.0.0/src/py_chargemol/density/data/core_035.zip +0 -0
  164. py_chargemol-1.0.0/src/py_chargemol/density/data/core_036.zip +0 -0
  165. py_chargemol-1.0.0/src/py_chargemol/density/data/core_037.zip +0 -0
  166. py_chargemol-1.0.0/src/py_chargemol/density/data/core_038.zip +0 -0
  167. py_chargemol-1.0.0/src/py_chargemol/density/data/core_039.zip +0 -0
  168. py_chargemol-1.0.0/src/py_chargemol/density/data/core_040.zip +0 -0
  169. py_chargemol-1.0.0/src/py_chargemol/density/data/core_041.zip +0 -0
  170. py_chargemol-1.0.0/src/py_chargemol/density/data/core_042.zip +0 -0
  171. py_chargemol-1.0.0/src/py_chargemol/density/data/core_043.zip +0 -0
  172. py_chargemol-1.0.0/src/py_chargemol/density/data/core_044.zip +0 -0
  173. py_chargemol-1.0.0/src/py_chargemol/density/data/core_045.zip +0 -0
  174. py_chargemol-1.0.0/src/py_chargemol/density/data/core_046.zip +0 -0
  175. py_chargemol-1.0.0/src/py_chargemol/density/data/core_047.zip +0 -0
  176. py_chargemol-1.0.0/src/py_chargemol/density/data/core_048.zip +0 -0
  177. py_chargemol-1.0.0/src/py_chargemol/density/data/core_049.zip +0 -0
  178. py_chargemol-1.0.0/src/py_chargemol/density/data/core_050.zip +0 -0
  179. py_chargemol-1.0.0/src/py_chargemol/density/data/core_051.zip +0 -0
  180. py_chargemol-1.0.0/src/py_chargemol/density/data/core_052.zip +0 -0
  181. py_chargemol-1.0.0/src/py_chargemol/density/data/core_053.zip +0 -0
  182. py_chargemol-1.0.0/src/py_chargemol/density/data/core_054.zip +0 -0
  183. py_chargemol-1.0.0/src/py_chargemol/density/data/core_055.zip +0 -0
  184. py_chargemol-1.0.0/src/py_chargemol/density/data/core_056.zip +0 -0
  185. py_chargemol-1.0.0/src/py_chargemol/density/data/core_057.zip +0 -0
  186. py_chargemol-1.0.0/src/py_chargemol/density/data/core_058.zip +0 -0
  187. py_chargemol-1.0.0/src/py_chargemol/density/data/core_059.zip +0 -0
  188. py_chargemol-1.0.0/src/py_chargemol/density/data/core_060.zip +0 -0
  189. py_chargemol-1.0.0/src/py_chargemol/density/data/core_061.zip +0 -0
  190. py_chargemol-1.0.0/src/py_chargemol/density/data/core_062.zip +0 -0
  191. py_chargemol-1.0.0/src/py_chargemol/density/data/core_063.zip +0 -0
  192. py_chargemol-1.0.0/src/py_chargemol/density/data/core_064.zip +0 -0
  193. py_chargemol-1.0.0/src/py_chargemol/density/data/core_065.zip +0 -0
  194. py_chargemol-1.0.0/src/py_chargemol/density/data/core_066.zip +0 -0
  195. py_chargemol-1.0.0/src/py_chargemol/density/data/core_067.zip +0 -0
  196. py_chargemol-1.0.0/src/py_chargemol/density/data/core_068.zip +0 -0
  197. py_chargemol-1.0.0/src/py_chargemol/density/data/core_069.zip +0 -0
  198. py_chargemol-1.0.0/src/py_chargemol/density/data/core_070.zip +0 -0
  199. py_chargemol-1.0.0/src/py_chargemol/density/data/core_071.zip +0 -0
  200. py_chargemol-1.0.0/src/py_chargemol/density/data/core_072.zip +0 -0
  201. py_chargemol-1.0.0/src/py_chargemol/density/data/core_073.zip +0 -0
  202. py_chargemol-1.0.0/src/py_chargemol/density/data/core_074.zip +0 -0
  203. py_chargemol-1.0.0/src/py_chargemol/density/data/core_075.zip +0 -0
  204. py_chargemol-1.0.0/src/py_chargemol/density/data/core_076.zip +0 -0
  205. py_chargemol-1.0.0/src/py_chargemol/density/data/core_077.zip +0 -0
  206. py_chargemol-1.0.0/src/py_chargemol/density/data/core_078.zip +0 -0
  207. py_chargemol-1.0.0/src/py_chargemol/density/data/core_079.zip +0 -0
  208. py_chargemol-1.0.0/src/py_chargemol/density/data/core_080.zip +0 -0
  209. py_chargemol-1.0.0/src/py_chargemol/density/data/core_081.zip +0 -0
  210. py_chargemol-1.0.0/src/py_chargemol/density/data/core_082.zip +0 -0
  211. py_chargemol-1.0.0/src/py_chargemol/density/data/core_083.zip +0 -0
  212. py_chargemol-1.0.0/src/py_chargemol/density/data/core_084.zip +0 -0
  213. py_chargemol-1.0.0/src/py_chargemol/density/data/core_085.zip +0 -0
  214. py_chargemol-1.0.0/src/py_chargemol/density/data/core_086.zip +0 -0
  215. py_chargemol-1.0.0/src/py_chargemol/density/data/core_087.zip +0 -0
  216. py_chargemol-1.0.0/src/py_chargemol/density/data/core_088.zip +0 -0
  217. py_chargemol-1.0.0/src/py_chargemol/density/data/core_089.zip +0 -0
  218. py_chargemol-1.0.0/src/py_chargemol/density/data/core_090.zip +0 -0
  219. py_chargemol-1.0.0/src/py_chargemol/density/data/core_091.zip +0 -0
  220. py_chargemol-1.0.0/src/py_chargemol/density/data/core_092.zip +0 -0
  221. py_chargemol-1.0.0/src/py_chargemol/density/data/core_093.zip +0 -0
  222. py_chargemol-1.0.0/src/py_chargemol/density/data/core_094.zip +0 -0
  223. py_chargemol-1.0.0/src/py_chargemol/density/data/core_095.zip +0 -0
  224. py_chargemol-1.0.0/src/py_chargemol/density/data/core_096.zip +0 -0
  225. py_chargemol-1.0.0/src/py_chargemol/density/data/core_097.zip +0 -0
  226. py_chargemol-1.0.0/src/py_chargemol/density/data/core_098.zip +0 -0
  227. py_chargemol-1.0.0/src/py_chargemol/density/data/core_099.zip +0 -0
  228. py_chargemol-1.0.0/src/py_chargemol/density/data/core_100.zip +0 -0
  229. py_chargemol-1.0.0/src/py_chargemol/density/data/core_101.zip +0 -0
  230. py_chargemol-1.0.0/src/py_chargemol/density/data/core_102.zip +0 -0
  231. py_chargemol-1.0.0/src/py_chargemol/density/data/core_103.zip +0 -0
  232. py_chargemol-1.0.0/src/py_chargemol/density/data/core_104.zip +0 -0
  233. py_chargemol-1.0.0/src/py_chargemol/density/data/core_105.zip +0 -0
  234. py_chargemol-1.0.0/src/py_chargemol/density/data/core_106.zip +0 -0
  235. py_chargemol-1.0.0/src/py_chargemol/density/data/core_107.zip +0 -0
  236. py_chargemol-1.0.0/src/py_chargemol/density/data/core_108.zip +0 -0
  237. py_chargemol-1.0.0/src/py_chargemol/density/data/core_109.zip +0 -0
  238. py_chargemol-1.0.0/src/py_chargemol/density/ddec3.py +191 -0
  239. py_chargemol-1.0.0/src/py_chargemol/density/diagnostics.py +63 -0
  240. py_chargemol-1.0.0/src/py_chargemol/density/grid.py +310 -0
  241. py_chargemol-1.0.0/src/py_chargemol/density/output.py +356 -0
  242. py_chargemol-1.0.0/src/py_chargemol/density/partition.py +316 -0
  243. py_chargemol-1.0.0/src/py_chargemol/density/readers.py +634 -0
  244. py_chargemol-1.0.0/src/py_chargemol/density/references.py +153 -0
  245. py_chargemol-1.0.0/src/py_chargemol/density/reshaping.py +90 -0
  246. py_chargemol-1.0.0/src/py_chargemol/density/spin.py +282 -0
  247. py_chargemol-1.0.0/src/py_chargemol/density/wfx.py +768 -0
  248. py_chargemol-1.0.0/src/py_chargemol/density/workflow.py +486 -0
  249. py_chargemol-1.0.0/src/py_chargemol/elements.py +97 -0
  250. py_chargemol-1.0.0/src/py_chargemol/multipoles.py +143 -0
  251. py_chargemol-1.0.0/src/py_chargemol/py.typed +0 -0
  252. py_chargemol-1.0.0/src/py_chargemol/qdr/__init__.py +23 -0
  253. py_chargemol-1.0.0/src/py_chargemol/qdr/arrays.py +159 -0
  254. py_chargemol-1.0.0/src/py_chargemol/qdr/output.py +237 -0
  255. py_chargemol-1.0.0/src/py_chargemol/qdr/run.py +211 -0
  256. py_chargemol-1.0.0/src/py_chargemol/qdr/solver.py +354 -0
  257. py_chargemol-1.0.0/src/py_chargemol/units.py +6 -0
  258. py_chargemol-1.0.0/test/conftest.py +56 -0
  259. py_chargemol-1.0.0/test/data/density_reference.json +1759 -0
  260. py_chargemol-1.0.0/test/density_examples/README.md +23 -0
  261. py_chargemol-1.0.0/test/density_examples/nacl.json +692 -0
  262. py_chargemol-1.0.0/test/density_examples/nacl_core_density.npz +0 -0
  263. py_chargemol-1.0.0/test/density_examples/nacl_density.npz +0 -0
  264. py_chargemol-1.0.0/test/density_examples/nacl_pseudodensity.npz +0 -0
  265. py_chargemol-1.0.0/test/density_examples/ozone_triplet_PW91.json +102 -0
  266. py_chargemol-1.0.0/test/density_examples/ozone_triplet_PW91.wfx +945 -0
  267. py_chargemol-1.0.0/test/test_api.py +330 -0
  268. py_chargemol-1.0.0/test/test_arrays.py +262 -0
  269. py_chargemol-1.0.0/test/test_cli.py +188 -0
  270. py_chargemol-1.0.0/test/test_ddec3_cm5.py +193 -0
  271. py_chargemol-1.0.0/test/test_ddec6.py +346 -0
  272. py_chargemol-1.0.0/test/test_density_analysis.py +369 -0
  273. py_chargemol-1.0.0/test/test_density_bonds.py +485 -0
  274. py_chargemol-1.0.0/test/test_density_core.py +119 -0
  275. py_chargemol-1.0.0/test/test_density_diagnostics.py +82 -0
  276. py_chargemol-1.0.0/test/test_density_grid.py +184 -0
  277. py_chargemol-1.0.0/test/test_density_output.py +206 -0
  278. py_chargemol-1.0.0/test/test_density_readers.py +440 -0
  279. py_chargemol-1.0.0/test/test_density_workflow.py +454 -0
  280. py_chargemol-1.0.0/test/test_elements.py +49 -0
  281. py_chargemol-1.0.0/test/test_multipoles.py +155 -0
  282. py_chargemol-1.0.0/test/test_output.py +63 -0
  283. py_chargemol-1.0.0/test/test_partition.py +143 -0
  284. py_chargemol-1.0.0/test/test_references.py +147 -0
  285. py_chargemol-1.0.0/test/test_solver.py +332 -0
  286. py_chargemol-1.0.0/test/test_wfx.py +363 -0
  287. py_chargemol-1.0.0/test/test_worked_examples.py +87 -0
  288. py_chargemol-1.0.0/test/worked_examples/ALPO5/DDEC6_net_atomic_charges.xyz +240 -0
  289. py_chargemol-1.0.0/test/worked_examples/ALPO5/QDR-DDEC6_point_charges.xyz +323 -0
  290. py_chargemol-1.0.0/test/worked_examples/ALPO5/overlap_populations_and_contact_exchanges.txt +2990 -0
  291. py_chargemol-1.0.0/test/worked_examples/BN_nanotube/DDEC6_net_atomic_charges.xyz +144 -0
  292. py_chargemol-1.0.0/test/worked_examples/BN_nanotube/QDR-DDEC6_point_charges.xyz +195 -0
  293. py_chargemol-1.0.0/test/worked_examples/BN_nanotube/overlap_populations_and_contact_exchanges.txt +1476 -0
  294. py_chargemol-1.0.0/test/worked_examples/CO2_CCSD_augccpVTZ/DDEC6_net_atomic_charges.xyz +47 -0
  295. py_chargemol-1.0.0/test/worked_examples/CO2_CCSD_augccpVTZ/QDR-DDEC6_point_charges.xyz +61 -0
  296. py_chargemol-1.0.0/test/worked_examples/CO2_CCSD_augccpVTZ/overlap_populations_and_contact_exchanges.txt +10 -0
  297. py_chargemol-1.0.0/test/worked_examples/CO_molecule/DDEC6_even_tempered_net_atomic_charges.xyz +45 -0
  298. py_chargemol-1.0.0/test/worked_examples/CO_molecule/QDR-DDEC6_point_charges.xyz +57 -0
  299. py_chargemol-1.0.0/test/worked_examples/CO_molecule/overlap_populations_and_contact_exchanges.txt +6 -0
  300. py_chargemol-1.0.0/test/worked_examples/H2_CCSD_def2QZVPPD/DDEC6_net_atomic_charges.xyz +44 -0
  301. py_chargemol-1.0.0/test/worked_examples/H2_CCSD_def2QZVPPD/QDR-DDEC6_point_charges.xyz +57 -0
  302. py_chargemol-1.0.0/test/worked_examples/H2_CCSD_def2QZVPPD/overlap_populations_and_contact_exchanges.txt +6 -0
  303. py_chargemol-1.0.0/test/worked_examples/formamide_VASP/DDEC6_net_atomic_charges.xyz +42 -0
  304. py_chargemol-1.0.0/test/worked_examples/formamide_VASP/QDR-DDEC6_point_charges.xyz +59 -0
  305. py_chargemol-1.0.0/test/worked_examples/formamide_VASP/overlap_populations_and_contact_exchanges.txt +34 -0
  306. py_chargemol-1.0.0/uv.lock +484 -0
@@ -0,0 +1,39 @@
1
+ # Changelog
2
+
3
+ ## 1.0.0
4
+
5
+ First release. py-chargemol implements the density analyses of Chargemol 3.5
6
+ (September 26, 2017) and T. A. Manz's April 9, 2025 QDR program in Python and
7
+ NumPy. No Chargemol installation, Fortran compiler, or external atomic-density
8
+ directory is needed.
9
+
10
+ - Compute DDEC6 and DDEC3 net atomic charges from electron densities, with
11
+ core-density reconstruction, atomic multipoles, collinear and noncollinear
12
+ spin moments, bond orders, overlap populations, and Hirshfeld and CM5
13
+ charges.
14
+ - Read VASP, Gaussian cube, XSF, and WFX inputs, or `DensityGrid` arrays in
15
+ memory, with supported `job_control.txt` settings. Analyze them with
16
+ `read_density` and `compute_ddec6` or the `py-chargemol analyze` command.
17
+ - Bundle the reference-ion and core-density data for elements 1–109 with their
18
+ original attribution and SHA-256 provenance hashes.
19
+ - Compute quadrupole-dipole resorbed (QDR) point charges directly from a density
20
+ analysis (`compute_qdr_from_density`), from existing Chargemol output
21
+ (`calculate_qdr`), or from DDEC6 arrays (`compute_qdr_from_arrays`), without
22
+ writing files. `QDRResult` includes residual atomic multipoles, solver
23
+ diagnostics, and, for nonperiodic systems, total molecular multipole moments.
24
+ - Read Chargemol net atomic charges and overlap populations, including the
25
+ September 2017 layouts and atom and pair counts that overflow their
26
+ fixed-width fields.
27
+ - Write density-analysis, bond-order, and QDR output files with
28
+ `write_density_results`, `run_qdr`, or the `py-chargemol qdr` command, which
29
+ also writes a computation log.
30
+ - Reject malformed, ambiguous, or nonfinite inputs with explicit errors,
31
+ including inconsistent electron counts and invalid QDR arrays.
32
+ - Reproduce the six QDR worked examples within rounding at the last printed
33
+ digit, with regression tests included in the source distribution.
34
+ - Support Python 3.14 or newer, with NumPy as the only runtime dependency.
35
+
36
+ The public API is the names exported from `py_chargemol` and the `py-chargemol`
37
+ command; later releases follow semantic versioning for them. The package
38
+ retains the original QDR and Chargemol licenses, and publications must cite the
39
+ original methods.
@@ -0,0 +1,44 @@
1
+ py-chargemol
2
+
3
+ Copyright (c) 2025 by Thomas A. Manz. Rights reserved.
4
+ Python port copyright (c) 2026 Louie Slocombe.
5
+
6
+ The density-analysis implementation and bundled atomic reference data also
7
+ retain Chargemol 3.5's terms, reproduced separately in LICENSE-CHARGEMOL.
8
+
9
+ py-chargemol is a Python reimplementation of the QDR program (version April 9,
10
+ 2025) by Thomas A. Manz, which computes quadrupole-dipole resorbed (QDR) atomic
11
+ charges. As a derived work of that program, it is distributed under exactly the
12
+ same terms as the QDR program, reproduced below from section 5 of the original
13
+ April 9, 2025 QDR user guide.
14
+
15
+ Software license:
16
+
17
+ This software is distributed under the license described below. You are not
18
+ licensed to use or modify this software unless you agree to all of the licensing
19
+ terms below:
20
+
21
+ 1. Derived Works and Integrity of The Author's Source Code: Derived works must be
22
+ distributed under exactly the same terms as this license. The source code is
23
+ restricted from being distributed in modified form; however, this license
24
+ allows the distribution of "patch files" with the source code for the purpose
25
+ of modifying the program at build time.
26
+
27
+ 2. Free Redistribution: The license does not restrict any party from selling or
28
+ giving away the software as a component of an aggregate software distribution
29
+ containing programs from several different sources. The license does not
30
+ require a royalty or other fee for such a sale. This license does not restrict
31
+ other software that may be distributed along with the licensed software.
32
+
33
+ 3. Source Code: The program includes source code, and allows distribution in
34
+ source code as well as compiled form. (Deliberately obfuscated source code and
35
+ intermediate forms such as the output of a preprocessor or translator are not
36
+ allowed.)
37
+
38
+ 4. Distribution of License: The rights attached to the program apply to all to
39
+ whom the program is redistributed without the need for execution of an
40
+ additional license by those parties.
41
+
42
+ 5. Scientific publications that use computational results of the program are
43
+ required to properly cite the original research papers describing the methods
44
+ used in the program, according to best scientific practice.
@@ -0,0 +1,57 @@
1
+ Chargemol version 3.5, September 26, 2017
2
+
3
+ Copyright (c) 2014, 2015, 2016, 2017 by Thomas A. Manz and Nidia Gabaldon Limas.
4
+ Rights reserved.
5
+
6
+ The following terms are reproduced from section A4 of
7
+ instructions_09_26_2017.pdf distributed with Chargemol. They apply to the
8
+ Chargemol-derived Python implementations and bundled atomic reference data.
9
+
10
+ This software is distributed under the license described below, which is compliant with the Open Source Initiative
11
+ found at http://www.opensource.org/docs/osd. You are not licensed to use or modify this software unless you
12
+ agree to all of the licensing terms below:
13
+ 1. Derived Works and Integrity of The Author’s Source Code: Derived works must be distributed under exactly the
14
+ same terms as this license. The source code is restricted from being distributed in modified form; however,
15
+ this license allows the distribution of “patch files” with the source code for the purpose of modifying the
16
+ program at build time.
17
+ 2. Free Redistribution: The license does not restrict any party from selling or giving away the software as a
18
+ component of an aggregate software distribution containing programs from several different sources. The
19
+ license does not require a royalty or other fee for such a sale. This license does not restrict other software that
20
+ may be distributed along with the licensed software.
21
+ 3. Source Code: The program includes source code, and allows distribution in source code as well as compiled
22
+ form. (Deliberately obfuscated source code and intermediate forms such as the output of a preprocessor or
23
+ translator are not allowed.)
24
+ 4. Distribution of License: The rights attached to the program apply to all to whom the program is redistributed
25
+ without the need for execution of an additional license by those parties.
26
+ 5. Scientific publications that use computational results of the program are required to properly cite the original
27
+ research papers describing the methods used in the program, according to best scientific practice.
28
+ Note: For the current software version, this would include citation of the following papers:
29
+ (a) for the calculation of DDEC6 atomic charges, please cite: (1) T. A. Manz and N. Gabaldon
30
+ Limas, “Introducing DDEC6 atomic population analysis: part 1. Charge partitioning theory
31
+ and methodology,” RSC Adv., 6 (2016) 47771-47801. (2) N. Gabaldon Limas and T. A. Manz, “Introducing
32
+ DDEC6 atomic population analysis: part 2. Computed results for a wide range of periodic and
33
+ nonperiodic materials,” RSC Adv., 6 (2016) 45727-45747. If desired, you can also cite references listed
34
+ below for the DDEC3 and earlier methods.
35
+ (b) for the calculation of DDEC3 atomic charges, please cite: (i) T. A. Manz and D. S. Sholl, “Improved
36
+ Atoms-in-Molecule Charge Partitioning Functional for Simultaneously Reproducing the Electrostatic
37
+ Potential and Chemical States in Periodic and Non-Periodic Materials,” J. Chem. Theory Comput. 8 (2012)
38
+ 2844-2867. (ii) T. A. Manz and D. S. Sholl, “Chemically Meaningful Atomic Charges that Reproduce the
39
+ Electrostatic Potential in Periodic and Nonperiodic Materials,” J. Chem. Theory Comput. 6 (2010) 2455-
40
+ 2468.
41
+ (c) for the calculation of RMSE and RRMSE, please cite: (i) T. A. Manz and D. S. Sholl, “Improved Atoms-
42
+ in-Molecule Charge Partitioning Functional for Simultaneously Reproducing the Electrostatic Potential
43
+ and Chemical States in Periodic and Non-Periodic Materials,” J. Chem. Theory Comput. 8 (2012) 2844-
44
+ 2867. (ii) T. Watanabe, T. A. Manz, and D. S. Sholl, “Accurate Treatment of Electrostatics during
45
+ Molecular Adsorption in Nanoporous Crystals without Assigning Point Charges to Framework Atoms,” J.
46
+ Phys. Chem. C, 115 (2011) 4824 – 4836.
47
+ (d) for the calculation of atomic spin moments, please cite: T. A. Manz and D. S. Sholl, “Methods for
48
+ Computing Accurate Atomic Spin Moments for Collinear and Noncollinear Magnetism in Periodic and
49
+ Nonperiodic Materials,” J. Chem. Theory Comput. 7 (2011) 4146-4164.
50
+ (e) for the calculation of bond orders, please cite: T. A. Manz, “Introducing DDEC6 atomic population
51
+ analysis: part 3. Comprehensive method to compute bond orders,” RSC Adv., 7 (2017) 45552-45581.
52
+ 6. In addition to the scientific papers described in # 5 above, please cite this software program as
53
+ following: T. A. Manz and N. Gabaldon Limas, Chargemol program for performing DDEC analysis,
54
+ Version 3.5, 2017, ddec.sourceforge.net.
55
+ 7. This license makes no discrimination against persons or groups or fields of endeavor. The rights attached
56
+ to this program do not depend on the program’s being part of a particular software distribution. No
57
+ provision of this license is predicated on any particular style of interface.
@@ -0,0 +1,531 @@
1
+ Metadata-Version: 2.4
2
+ Name: py-chargemol
3
+ Version: 1.0.0
4
+ Summary: DDEC6, DDEC3, and QDR atomic charges from electron densities in Python.
5
+ Keywords: chargemol,computational chemistry,DDEC6,force fields,point charges,QDR
6
+ Author: Thomas A. Manz, Nidia Gabaldon Limas, Louie Slocombe
7
+ Author-email: Louie Slocombe <louies@hotmail.co.uk>
8
+ License-Expression: LicenseRef-QDR AND LicenseRef-Chargemol
9
+ License-File: LICENSE
10
+ License-File: LICENSE-CHARGEMOL
11
+ Classifier: Development Status :: 5 - Production/Stable
12
+ Classifier: Intended Audience :: Science/Research
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Programming Language :: Python :: 3 :: Only
15
+ Classifier: Programming Language :: Python :: 3.14
16
+ Classifier: Programming Language :: Python :: 3.15
17
+ Classifier: Topic :: Scientific/Engineering :: Chemistry
18
+ Classifier: Typing :: Typed
19
+ Requires-Dist: numpy>=2.3.3
20
+ Requires-Python: >=3.14
21
+ Project-URL: Homepage, https://github.com/LouieSlocombe/py-chargemol
22
+ Project-URL: Issues, https://github.com/LouieSlocombe/py-chargemol/issues
23
+ Project-URL: Repository, https://github.com/LouieSlocombe/py-chargemol
24
+ Project-URL: Changelog, https://github.com/LouieSlocombe/py-chargemol/blob/main/CHANGELOG.md
25
+ Description-Content-Type: text/markdown
26
+
27
+ # py-chargemol
28
+
29
+ py-chargemol computes DDEC6 and DDEC3 atomic charges, atomic multipoles, spin
30
+ moments, bond orders, Hirshfeld and CM5 charges, and quadrupole-dipole resorbed
31
+ (QDR) point charges directly from electron densities. The numerical algorithms
32
+ are implemented in Python and NumPy, based on Chargemol 3.5 (September 26, 2017)
33
+ and T. A. Manz's April 9, 2025 QDR program.
34
+
35
+ **No Chargemol executable, Fortran compiler, external atomic-density directory,
36
+ or network access is needed.** The reference atomic densities are bundled in
37
+ the Python package for elements 1–109, including neutral ions, charged ions,
38
+ and core electrons. Existing Chargemol result files and in-memory DDEC6 arrays
39
+ remain supported.
40
+
41
+ QDR charges are meant for atom-centred point-charge models in classical force
42
+ fields. They fold part of each atom's DDEC6 quadrupole and dipole into the point
43
+ charges of its bonded neighbours, weighted by the bond overlap populations, so a
44
+ model truncated at monopole order reproduces more of the electrostatic potential
45
+ around the material. To interpret charge transfer or the chemical states of
46
+ atoms, use the DDEC6 net atomic charges, which are not resorbed.
47
+
48
+ ## Installation
49
+
50
+ Python 3.14 or newer is required. NumPy 2.3.3 or newer is the only runtime
51
+ dependency and is installed automatically by pip.
52
+
53
+ Install the latest release from PyPI:
54
+
55
+ ```bash
56
+ python -m pip install py-chargemol
57
+ py-chargemol --version
58
+ ```
59
+
60
+ To install from a checkout instead, run this from the repository root:
61
+
62
+ ```bash
63
+ python -m pip install .
64
+ ```
65
+
66
+ See [Development](#development) for an editable install and developer tools, and the
67
+ [changelog](https://github.com/LouieSlocombe/py-chargemol/blob/main/CHANGELOG.md)
68
+ for release notes. Conda and uv are optional development tools.
69
+
70
+ You still need an electron density or wavefunction from an electronic-structure
71
+ calculation. Atomic coordinates alone do not determine a DDEC analysis:
72
+
73
+ ```text
74
+ Electron-density calculation → py-chargemol DDEC6 analysis → QDR charges
75
+ ```
76
+
77
+ ## Usage
78
+
79
+ Choose an entry point for the data you already have:
80
+
81
+ | Starting point | Python API | Command line |
82
+ | --- | --- | --- |
83
+ | Electron density or wavefunction | [`read_density` → `compute_ddec6`](#compute-directly-from-an-electron-density) | `py-chargemol analyze` |
84
+ | Existing Chargemol output files | [`calculate_qdr`](#python) | `py-chargemol qdr` |
85
+ | DDEC6 arrays in memory | [`compute_qdr_from_arrays`](#compute-directly-from-arrays) | — |
86
+
87
+ ### Compute directly from an electron density
88
+
89
+ For a VASP calculation:
90
+
91
+ ```python
92
+ from py_chargemol import compute_ddec6, read_density, write_density_results
93
+
94
+ grid = read_density("path/to/vasp/calculation")
95
+ ddec = compute_ddec6(grid)
96
+ qdr = ddec.compute_qdr()
97
+
98
+ print(ddec.charges)
99
+ print(ddec.analysis.atomic_dipoles)
100
+ print(ddec.bonds.bond_orders)
101
+ print(qdr.charges)
102
+
103
+ # Optional: write DDEC, bond, radial-moment and QDR output files.
104
+ write_density_results(ddec, "results", qdr=True)
105
+ ```
106
+
107
+ `DDECResult` also exposes Hirshfeld/CM5 charges, radial moments, spherical
108
+ atomic densities, and total molecular multipoles. For magnetic inputs,
109
+ `result.spin.populations` contains atomic spin moments; noncollinear inputs
110
+ also provide integrated spin-gradient diagnostics in `result.spin_gradients`.
111
+ Isolated-atom WFX inputs provide analytic explicit-electron radial moments
112
+ for powers −1 through 4 in `result.wavefunction_radial_moments` when supported
113
+ by the original diagnostic.
114
+ The bond result records the remaining population residual after density
115
+ correction, which is also printed in the bond-order output.
116
+
117
+ The command-line equivalent is:
118
+
119
+ ```bash
120
+ py-chargemol analyze path/to/vasp/calculation --output-dir results
121
+ ```
122
+
123
+ `--method ddec3` selects the older charge-partitioning method; QDR requires
124
+ DDEC6. `--no-qdr` writes the density analysis without resorption. See
125
+ `py-chargemol analyze --help` for charge, periodicity, and core-electron options.
126
+ The command also honors `charge type` and `print atomic densities` in
127
+ `job_control.txt`; explicit command-line options take precedence.
128
+ Use `--atomic-densities` to export spherical atomic densities and radial integrals,
129
+ or `write_density_results(ddec, "results", atomic_densities=True)` in Python.
130
+ `--no-bonds` (or `<compute bos> .false. </compute bos>` in the job controls)
131
+ skips bond orders, radial moments, atomic-density exports, and QDR. The Python
132
+ equivalent is `compute_ddec6(grid, compute_bos=False)`.
133
+
134
+ Supported density sources:
135
+
136
+ | Source | Inputs |
137
+ | --- | --- |
138
+ | VASP 4/5 | `AECCAR2`, `CHGCAR` or `CHG`, and `POTCAR`; `AECCAR0` when available. Explicit core counts can replace POTCAR when the geometry names the elements. |
139
+ | Gaussian WFX | Wavefunction with primitive coefficients, occupations, and optional effective-core-density functions. Tight Gaussian contributions are integrated analytically. |
140
+ | Gaussian cube | Total electron density, or valence density with explicit core counts; optional separate total and spin-density files. |
141
+ | XSF | Scalar valence density, spin-up/spin-down grids, or noncollinear spin components, with explicit core counts. |
142
+ | Python arrays | A `DensityGrid` containing atomic numbers, positions, density, origin, voxel vectors, and periodicity, all in atomic units. |
143
+
144
+ `read_density` discovers conventional filenames and reads supported settings
145
+ from `job_control.txt`. Explicit function arguments override those settings.
146
+ Its atomic-densities-directory setting is unnecessary because the reference
147
+ data are bundled. The individual `read_cube`, `read_vasp`, `read_wfx`, and
148
+ `read_xsf` functions are also public.
149
+
150
+ Cube coordinate units follow the signed voxel counts; electron density defaults
151
+ to electrons/bohr³. XSF coordinates are in ångströms, with density also defaulting
152
+ to electrons/bohr³. Reader options support explicit unit conversion, and
153
+ `read_density` honors the original `onetep` and `e_per_angs3` density-format
154
+ settings. Python `DensityGrid` arrays always use atomic units.
155
+
156
+ For example, a periodic valence-density cube for water with an oxygen
157
+ pseudopotential that replaces two core electrons is read with:
158
+
159
+ ```python
160
+ from py_chargemol import compute_qdr_from_density, read_cube
161
+
162
+ grid = read_cube(
163
+ "valence_density.cube",
164
+ density_kind="valence",
165
+ core_electrons=[2, 0, 0], # atom order: O, H, H
166
+ periodic=(True, True, True),
167
+ )
168
+ qdr = compute_qdr_from_density(grid)
169
+ ```
170
+
171
+ Core counts must match the actual pseudopotentials. For an all-electron cube,
172
+ use `read_cube("total_density.cube")`. Set periodicity explicitly when needed.
173
+ The density integral is checked against the electron count; inconsistent
174
+ charge, units, or core counts raise an error.
175
+
176
+ ### Python
177
+
178
+ Read existing Chargemol output and return the computed arrays without writing
179
+ any files:
180
+
181
+ ```python
182
+ from py_chargemol import calculate_qdr
183
+
184
+ result = calculate_qdr("path/to/chargemol/output")
185
+
186
+ print(result.charges) # QDR point charges, e, shape (n,)
187
+ print(result.atomic_dipoles) # residual dipoles, e·bohr, shape (n, 3)
188
+ print(result.atomic_quadrupoles) # residual quadrupoles, e·bohr², shape (n, 6)
189
+ print(result.cg_iterations, result.residual_norm) # solver diagnostics
190
+
191
+ if result.moments is not None:
192
+ print(result.moments.charges.dipole_magnitude)
193
+ print(result.moments.with_dipoles.dipole_magnitude)
194
+ print(result.moments.with_quadrupoles.quadrupole_tensor)
195
+ ```
196
+
197
+ `calculate_qdr(directory=".", *, charges_file=None, overlaps_file=None,
198
+ max_cg_iterations=10, tolerance=1e-12)` returns a `QDRResult`. The directory
199
+ defaults to the current directory. It discovers these input filenames:
200
+
201
+ - `DDEC6_net_atomic_charges.xyz` (or `DDEC6_even_tempered_net_atomic_charges.xyz`)
202
+ - `overlap_populations_and_contact_exchanges.txt`, `overlap_populations.txt`, or
203
+ the September 2017 `overlap_populations.xyz`
204
+
205
+ Pass `charges_file` and `overlaps_file` to choose other input files. A
206
+ nonperiodic single atom needs no overlap file and returns its original charge
207
+ and atomic multipoles.
208
+
209
+ For nonperiodic systems, `result.moments` contains the total molecular moments
210
+ about the centre of mass at three levels: `charges` (point charges alone),
211
+ `with_dipoles` (including residual atomic dipoles), and `with_quadrupoles`
212
+ (including residual atomic quadrupoles too). Each provides a `dipole`,
213
+ `dipole_magnitude`, `quadrupole`, `quadrupole_tensor`, and
214
+ `quadrupole_eigenvalues`. For periodic systems, `result.moments` is `None`.
215
+
216
+ #### Compute directly from arrays
217
+
218
+ `compute_qdr_from_arrays` accepts Python lists or NumPy arrays, so an in-memory
219
+ workflow needs no intermediate files or electron-cloud parameters. This
220
+ synthetic two-atom example is runnable as written:
221
+
222
+ ```python
223
+ from py_chargemol import compute_qdr_from_arrays
224
+
225
+ result = compute_qdr_from_arrays(
226
+ atomic_numbers=[1, 1],
227
+ positions=[[0.0, 0.0, 0.0], [1.4, 0.0, 0.0]],
228
+ net_charges=[0.1, -0.1],
229
+ atomic_dipoles=[[0.02, 0.0, 0.0], [0.02, 0.0, 0.0]],
230
+ atomic_quadrupoles=[[0.0] * 6, [0.0] * 6],
231
+ atom1=[0, 1],
232
+ atom2=[1, 0],
233
+ populations=[0.5, 0.5],
234
+ )
235
+
236
+ print(result.charges)
237
+ print(result.atomic_dipoles)
238
+ ```
239
+
240
+ The inputs describe `n` atoms and `m` directed overlap pairs:
241
+
242
+ | Argument | Shape | Meaning and units |
243
+ | --- | --- | --- |
244
+ | `atomic_numbers` | `(n,)` | Atomic numbers |
245
+ | `positions` | `(n, 3)` | Cartesian coordinates in bohr |
246
+ | `net_charges` | `(n,)` | DDEC6 net atomic charges in e |
247
+ | `atomic_dipoles` | `(n, 3)` | DDEC6 atomic dipoles in e·bohr |
248
+ | `atomic_quadrupoles` | `(n, 6)` | Traceless DDEC6 quadrupoles in e·bohr², ordered `xx, xy, xz, yy, yz, zz` |
249
+ | `atom1`, `atom2` | `(m,)` | Zero-based atom indices |
250
+ | `populations` | `(m,)` | Bond overlap populations in e |
251
+ | `translations` | `(m, 3)` | Integer lattice translations of the second atom; defaults to zero |
252
+ | `lattice_vectors` | `(3, 3)` | Cell vectors as rows, in bohr; defaults to zero for a nonperiodic system |
253
+
254
+ Each bond must appear in both directions with the same population, as in the
255
+ example. For a periodic pair `(i, j)` with translation `t`, also supply `(j, i)`
256
+ with translation `-t`. A zero cell-vector row marks a nonperiodic direction.
257
+ All arguments are keyword-only; `max_cg_iterations=10` and `tolerance=1e-12`
258
+ control the solver. The returned `QDRResult` has the same arrays, diagnostics,
259
+ and moments as `calculate_qdr`.
260
+
261
+ This array API performs QDR resorption using supplied DDEC6 results. Use
262
+ `compute_ddec6` to generate those results from an electron density. The synthetic
263
+ values above illustrate the API, not a physical DDEC6 analysis.
264
+
265
+ #### Work with parsed analysis objects
266
+
267
+ The readers, `DDEC6Analysis`, `OverlapPairs`, and pure `compute_qdr_charges`
268
+ function are also available from the package root:
269
+
270
+ ```python
271
+ from py_chargemol import (
272
+ DDEC6Analysis,
273
+ OverlapPairs,
274
+ compute_qdr_charges,
275
+ read_ddec6_net_atomic_charges,
276
+ read_overlap_populations,
277
+ )
278
+
279
+ analysis: DDEC6Analysis = read_ddec6_net_atomic_charges("DDEC6_net_atomic_charges.xyz")
280
+ pairs: OverlapPairs = read_overlap_populations(
281
+ "overlap_populations_and_contact_exchanges.txt"
282
+ )
283
+ result = compute_qdr_charges(analysis, pairs)
284
+ ```
285
+
286
+ The readers convert Chargemol coordinates to bohr and pair indices to zero-based
287
+ indices. `compute_qdr_charges` returns the same `QDRResult`, including molecular
288
+ moments for nonperiodic systems, without writing files.
289
+
290
+ #### Write the legacy output file
291
+
292
+ Use `run_qdr` when you want to compute and write
293
+ `QDR-DDEC6_point_charges.xyz`:
294
+
295
+ ```python
296
+ from py_chargemol import run_qdr
297
+
298
+ result = run_qdr("path/to/chargemol/output")
299
+ ```
300
+
301
+ Progress goes to the `py_chargemol.qdr.run` Python logger. Configure Python
302
+ logging to capture it; the command-line interface creates the logfile
303
+ automatically.
304
+
305
+ ### Chargemol input compatibility
306
+
307
+ The September 2017 `overlap_populations.xyz` file has the same leading columns
308
+ as the newer text files and is read directly. A development Chargemol release
309
+ is not required. The Python density workflow supplies the analysis and overlaps
310
+ directly to QDR without intermediate files.
311
+
312
+ ### Command line
313
+
314
+ Run `py-chargemol qdr` in the directory that holds the Chargemol output, or pass
315
+ the directory:
316
+
317
+ ```bash
318
+ py-chargemol qdr path/to/chargemol/output
319
+ ```
320
+
321
+ Like the Fortran program, the command writes two files to that directory:
322
+
323
+ - `QDR-DDEC6_point_charges.xyz`: the QDR point charges as an XYZ file Jmol can
324
+ read, followed by the residual atomic dipoles and quadrupoles, the electron
325
+ cloud parameters, and, for molecules, the total dipole and quadrupole moments.
326
+ - `QDR_charges_computation_logfile.txt`: a log of the run.
327
+
328
+ `--charges`, `--overlaps`, `--output`, and `--log` choose other files. See
329
+ `py-chargemol qdr --help`.
330
+
331
+ ## Compatibility with the original programs
332
+
333
+ The density engine implements the analyses enabled in the September 2017
334
+ Chargemol program. Output files retain the scientific quantities and familiar
335
+ table layouts, while status messages and filenames use the Python interface.
336
+ Invalid densities, failed partition convergence, and negative valence
337
+ populations raise explicit errors. Quadrupole eigenvalues are computed from
338
+ the complete tensor, including analytic WFX corrections.
339
+
340
+ Grid validation is not identical to the original executable: the Python API
341
+ permits coarse grids for controlled numerical experiments and does not apply
342
+ all of Chargemol's negative-density rejection thresholds. Electron-count and
343
+ partition checks do not establish grid convergence; physical calculations
344
+ still require a sufficiently resolved input density. Periodic, effective-core,
345
+ and ghost-centre WFX paths have analytic and conservation tests, but were not
346
+ compared against supplied full reference calculations for those cases.
347
+
348
+ The QDR regression tests compare every worked example with the Fortran program,
349
+ allowing one unit in the last printed digit for rounding and checking tiny
350
+ solver residuals against an absolute tolerance of `1e-10`. Some implementation
351
+ details differ:
352
+
353
+ - Each atom's conjugate gradient solve ran on its own OpenMP thread. Here they
354
+ all run at once on NumPy arrays. Integers are 64-bit throughout, so the
355
+ separate `int8` builds for very large cells are not needed.
356
+ - The 3×3 quadrupole eigenvalues come from `numpy.linalg.eigvalsh`, not a closed
357
+ form.
358
+ - Malformed input raises an error that names the file and line, where the
359
+ Fortran could read garbage or stop silently. This includes a number too wide
360
+ for its field, which Fortran prints as asterisks joined to the column before
361
+ it, shifting the columns after it.
362
+ - The Fortran program skips 14 lines between the atomic coordinates and the
363
+ multipole table. The September 2017 Chargemol release writes 13, so here the
364
+ table is found by its title line instead, and that release's
365
+ `DDEC6_even_tempered_net_atomic_charges.xyz` can be read too.
366
+ - Chargemol writes the atom and pair counts in five-character fields, which
367
+ print as `*****` from 100,000 on. The Fortran program stops on these; here
368
+ the count is taken from the number of rows in the table instead.
369
+ - The output's version line names the py-chargemol version. The log file holds
370
+ the same information in a different layout, and the XYZ output always uses
371
+ LF line endings.
372
+
373
+ ## Reference fixtures
374
+
375
+ `test/worked_examples/` holds the Chargemol inputs and reference QDR charge
376
+ outputs from the six worked examples distributed with T. A. Manz's April 9,
377
+ 2025 QDR program. These files are preserved unmodified. The regression tests
378
+ run every example and compare the output with the Fortran program's reference
379
+ output line by line.
380
+
381
+ The density engine has separate offline regression fixtures for the original
382
+ VASP NaCl and spin-polarized Gaussian ozone calculations, plus numerical
383
+ reference cases for the reference-ion, reshaping, and spin routines.
384
+ During development it was also checked against
385
+ the supplied CP2K water and four Gaussian ozone examples, including charged
386
+ and spin-polarized wavefunctions. Ordinary tests use only packaged fixtures;
387
+ they do not run Chargemol or require a compiler.
388
+
389
+ The 1,897 reference-ion and core-density text files used at the default radial
390
+ resolution are stored byte-for-byte in compressed, per-element package
391
+ archives. A SHA-256 manifest records their provenance. The installed wheel
392
+ includes these resources.
393
+
394
+ ## Citation
395
+
396
+ Publications using these analyses must cite the original methods, as the
397
+ licenses require. For DDEC, bond-order, and spin calculations, cite the methods
398
+ listed in
399
+ [LICENSE-CHARGEMOL](https://github.com/LouieSlocombe/py-chargemol/blob/main/LICENSE-CHARGEMOL),
400
+ including the DDEC6 papers by T. A. Manz and N. Gabaldon Limas and the
401
+ Chargemol 3.5 program. For QDR charges, cite:
402
+
403
+ - A. C. Escobosa and T. A. Manz, "How well do various QM-derived net atomic
404
+ charges reproduce the electrostatic potential surrounding a material across
405
+ multiple geometric conformations?", RSC Advances, Vol. 15 (2025) 23223-23265,
406
+ [doi:10.1039/D4RA07900K](https://doi.org/10.1039/D4RA07900K).
407
+ - T. A. Manz, InteractionModels program, 2025 version, ddec.sourceforge.net.
408
+
409
+ The output file keeps the Fortran program's citation text, which predates the
410
+ paper's publication.
411
+
412
+ ## Development
413
+
414
+ Clone the repository and enter its directory:
415
+
416
+ ```bash
417
+ git clone https://github.com/LouieSlocombe/py-chargemol.git
418
+ cd py-chargemol
419
+ ```
420
+
421
+ With [uv](https://docs.astral.sh/uv/) 0.12 or newer, install the package in
422
+ editable mode and its development tools:
423
+
424
+ ```bash
425
+ uv sync
426
+ ```
427
+
428
+ Alternatively, create or update the `py-chargemol-dev` conda environment, which also
429
+ installs the package in editable mode with its development tools (see
430
+ [`build_tools/`](https://github.com/LouieSlocombe/py-chargemol/blob/main/build_tools/README.md)):
431
+
432
+ ```bash
433
+ bash build_tools/conda_install.sh
434
+ conda activate py-chargemol-dev
435
+ ```
436
+
437
+ Install the Git hooks once. They then run Ruff, lockfile, workflow security,
438
+ and file hygiene checks before each commit. The hooks skip the reference
439
+ fixture data in `test/worked_examples/` and the original WFX regression input
440
+ to preserve those files.
441
+
442
+ ```bash
443
+ uv run prek install
444
+ ```
445
+
446
+ Run the complete local checks:
447
+
448
+ ```bash
449
+ uv run prek run --all-files
450
+ uv run mypy
451
+ uv run pytest --cov
452
+ uv build
453
+ ```
454
+
455
+ `--cov` measures coverage and fails below 100%, as CI does. Leave it off to run a
456
+ subset of the tests. Ruff can apply safe lint and formatting changes with:
457
+
458
+ ```bash
459
+ uv run ruff check --fix .
460
+ uv run ruff format .
461
+ ```
462
+
463
+ In the conda environment, run the same tools without `uv run`.
464
+
465
+ ### Dependencies
466
+
467
+ `pyproject.toml` declares the oldest versions the package supports and
468
+ `uv.lock` pins the exact versions used in development and CI. CI also tests
469
+ against the oldest allowed versions, so keep lower bounds honest. Update the
470
+ conda environment files in `build_tools/` alongside `pyproject.toml`.
471
+
472
+ Dependabot refreshes `uv.lock`, the pre-commit hooks, and the GitHub Actions
473
+ once a month, grouping each into a single pull request.
474
+
475
+ ### Continuous integration
476
+
477
+ Every push to `main` and every pull request runs the hooks and mypy, tests on
478
+ Linux, macOS, and Windows with Python 3.14 and 3.15, tests the
479
+ free-threaded 3.14t build and the oldest allowed dependencies, and builds and
480
+ smoke tests the sdist and wheel. Require the **All checks passed** job in
481
+ branch protection rather than each matrix entry.
482
+
483
+ `release.yml` can publish to PyPI with trusted publishing when a GitHub release
484
+ is published. Follow the
485
+ [release guide](https://github.com/LouieSlocombe/py-chargemol/blob/main/RELEASE.md)
486
+ for preparation and publishing steps. Check that the license allows the
487
+ distribution first.
488
+
489
+ ## Project layout
490
+
491
+ ```text
492
+ .
493
+ ├── .github/ # CI, PyPI release, and Dependabot
494
+ ├── build_tools/ # conda environments and install script
495
+ ├── src/py_chargemol/
496
+ │ ├── ddec6.py # readers for Chargemol's DDEC6 output
497
+ │ ├── elements.py # element symbols and atomic weights
498
+ │ ├── multipoles.py # total molecular multipole moments
499
+ │ ├── units.py # unit conversions
500
+ │ ├── __main__.py # the py-chargemol command
501
+ │ ├── density/ # independent density-to-DDEC calculations
502
+ │ │ ├── readers.py # cube, VASP and XSF density input
503
+ │ │ ├── wfx.py # wavefunctions and analytic Gaussian integrals
504
+ │ │ ├── partition.py # DDEC6 partitioning and radial constraints
505
+ │ │ ├── ddec3.py # DDEC3 partitioning
506
+ │ │ ├── cm5.py # Hirshfeld-to-CM5 charge correction
507
+ │ │ ├── bonds.py # overlaps, contact exchanges and bond orders
508
+ │ │ ├── spin.py # collinear and noncollinear spin partitioning
509
+ │ │ └── data/ # bundled reference-ion and core densities
510
+ │ └── qdr/
511
+ │ ├── arrays.py # direct computation from Python and NumPy arrays
512
+ │ ├── solver.py # the QDR resorption passes
513
+ │ ├── output.py # QDR-DDEC6_point_charges.xyz writer
514
+ │ └── run.py # calculate_qdr and the legacy run_qdr writer
515
+ ├── test/ # unit and worked-example regression tests
516
+ │ └── worked_examples/ # unmodified reference inputs and QDR outputs
517
+ ├── CHANGELOG.md # release notes
518
+ ├── RELEASE.md # release preparation and publishing
519
+ ├── pyproject.toml # project metadata and tool configuration
520
+ └── uv.lock # pinned development dependencies
521
+ ```
522
+
523
+ ## License
524
+
525
+ The QDR implementation retains the original terms, which
526
+ [LICENSE](https://github.com/LouieSlocombe/py-chargemol/blob/main/LICENSE)
527
+ reproduces. The density-analysis implementation and reference data retain
528
+ Chargemol's terms in
529
+ [LICENSE-CHARGEMOL](https://github.com/LouieSlocombe/py-chargemol/blob/main/LICENSE-CHARGEMOL).
530
+ Both require
531
+ attribution and citation of the original methods in published results.