molSimplify 1.7.4__py3-none-any.whl

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 (651) hide show
  1. docs/source/conf.py +224 -0
  2. molSimplify/Classes/__init__.py +6 -0
  3. molSimplify/Classes/atom3D.py +235 -0
  4. molSimplify/Classes/dft_obs.py +130 -0
  5. molSimplify/Classes/globalvars.py +827 -0
  6. molSimplify/Classes/helpers.py +161 -0
  7. molSimplify/Classes/ligand.py +2330 -0
  8. molSimplify/Classes/mGUI.py +2493 -0
  9. molSimplify/Classes/mWidgets.py +438 -0
  10. molSimplify/Classes/miniGUI.py +41 -0
  11. molSimplify/Classes/mol2D.py +260 -0
  12. molSimplify/Classes/mol3D.py +5846 -0
  13. molSimplify/Classes/monomer3D.py +253 -0
  14. molSimplify/Classes/partialcharges.py +226 -0
  15. molSimplify/Classes/protein3D.py +1178 -0
  16. molSimplify/Classes/rundiag.py +151 -0
  17. molSimplify/Data/ML.dat +212 -0
  18. molSimplify/Data/MLS_FSR_for_inter.dat +23 -0
  19. molSimplify/Data/MLS_FSR_for_inter2.dat +23 -0
  20. molSimplify/Data/MLS_angle_for_click.dat +8 -0
  21. molSimplify/Data/MLS_angle_for_inter.dat +23 -0
  22. molSimplify/Data/MLS_angle_for_inter2.dat +48 -0
  23. molSimplify/Data/MLS_angle_for_intra.dat +10 -0
  24. molSimplify/Data/MLS_angle_for_intra2.dat +6 -0
  25. molSimplify/Data/MLS_angle_for_oa.dat +18 -0
  26. molSimplify/Data/ML_FSR_for_inter.dat +112 -0
  27. molSimplify/Data/ML_FSR_for_inter2.dat +110 -0
  28. molSimplify/Data/ML_bond_for_cat.dat +8 -0
  29. molSimplify/Data/ML_bond_for_click.dat +8 -0
  30. molSimplify/Data/ML_bond_for_inter.dat +48 -0
  31. molSimplify/Data/ML_bond_for_inter2.dat +48 -0
  32. molSimplify/Data/ML_bond_for_intra.dat +10 -0
  33. molSimplify/Data/ML_bond_for_intra2.dat +6 -0
  34. molSimplify/Data/ML_bond_for_oa.dat +18 -0
  35. molSimplify/Data/bp1.dat +21 -0
  36. molSimplify/Data/li.dat +3 -0
  37. molSimplify/Data/no.dat +2 -0
  38. molSimplify/Data/oct.dat +7 -0
  39. molSimplify/Data/pbp.dat +8 -0
  40. molSimplify/Data/spy.dat +6 -0
  41. molSimplify/Data/sqap.dat +9 -0
  42. molSimplify/Data/sqp.dat +5 -0
  43. molSimplify/Data/tbp.dat +6 -0
  44. molSimplify/Data/tdhd.dat +9 -0
  45. molSimplify/Data/thd.dat +5 -0
  46. molSimplify/Data/tpl.dat +4 -0
  47. molSimplify/Data/tpr.dat +7 -0
  48. molSimplify/Informatics/HFXsensitivity/__init__.py +0 -0
  49. molSimplify/Informatics/HFXsensitivity/measure_HFX_sensitivity_oxo_hat_reb_rel.py +443 -0
  50. molSimplify/Informatics/HFXsensitivity/measure_HFX_stable.py +346 -0
  51. molSimplify/Informatics/MOF/Linker_rotation.py +179 -0
  52. molSimplify/Informatics/MOF/MOF_descriptors.py +1299 -0
  53. molSimplify/Informatics/MOF/MOF_descriptors_alternate_functional.py +589 -0
  54. molSimplify/Informatics/MOF/MOF_functionalizer.py +1648 -0
  55. molSimplify/Informatics/MOF/PBC_functions.py +1347 -0
  56. molSimplify/Informatics/MOF/__init__.py +0 -0
  57. molSimplify/Informatics/MOF/atomic.py +267 -0
  58. molSimplify/Informatics/MOF/cluster_extraction.py +388 -0
  59. molSimplify/Informatics/MOF/fragment_MOFs_for_pormake.py +895 -0
  60. molSimplify/Informatics/MOF/monofunctionalized_BDC/index_information.py +10 -0
  61. molSimplify/Informatics/Mol2Parser.py +46 -0
  62. molSimplify/Informatics/RACassemble.py +408 -0
  63. molSimplify/Informatics/__init__.py +0 -0
  64. molSimplify/Informatics/active_learning/__init__.py +0 -0
  65. molSimplify/Informatics/active_learning/expected_improvement.py +269 -0
  66. molSimplify/Informatics/autocorrelation.py +1930 -0
  67. molSimplify/Informatics/clean_autocorrelation.py +778 -0
  68. molSimplify/Informatics/coulomb_analyze.py +67 -0
  69. molSimplify/Informatics/decoration_manager.py +193 -0
  70. molSimplify/Informatics/geo_analyze.py +88 -0
  71. molSimplify/Informatics/geometrics.py +56 -0
  72. molSimplify/Informatics/graph_analyze.py +163 -0
  73. molSimplify/Informatics/graph_racs.py +288 -0
  74. molSimplify/Informatics/jupyter_vis.py +172 -0
  75. molSimplify/Informatics/lacRACAssemble.py +2192 -0
  76. molSimplify/Informatics/lacRACAssemble_bisdithiolenes.py +236 -0
  77. molSimplify/Informatics/misc_descriptors.py +198 -0
  78. molSimplify/Informatics/organic_fingerprints.py +61 -0
  79. molSimplify/Informatics/partialcharges.py +345 -0
  80. molSimplify/Informatics/protein/activesite.py +53 -0
  81. molSimplify/Informatics/protein/pymol_add_hs.py +33 -0
  82. molSimplify/Informatics/rac155_geo.py +48 -0
  83. molSimplify/Ligands/(1_methylbenzimidazol_2_yl)pyridine.xyz +45 -0
  84. molSimplify/Ligands/1-4-dimethyl-1-2-3-triazole.xyz +15 -0
  85. molSimplify/Ligands/12crown4.mol +62 -0
  86. molSimplify/Ligands/Antipyrine.mol +58 -0
  87. molSimplify/Ligands/BPAbipy.mol +106 -0
  88. molSimplify/Ligands/Hpyrrole.mol +26 -0
  89. molSimplify/Ligands/N-quinolinylbutyramidate.xyz +31 -0
  90. molSimplify/Ligands/N-quinolinylmethylmethinylacetamidate.xyz +30 -0
  91. molSimplify/Ligands/NMe2_-1.xyz +11 -0
  92. molSimplify/Ligands/PCy3.mol +111 -0
  93. molSimplify/Ligands/PMe3.xyz +15 -0
  94. molSimplify/Ligands/PPh3.mol +76 -0
  95. molSimplify/Ligands/Propyphenazone.mol +77 -0
  96. molSimplify/Ligands/acac.mol +33 -0
  97. molSimplify/Ligands/acacen.mol +76 -0
  98. molSimplify/Ligands/acetate.smi +1 -0
  99. molSimplify/Ligands/acetate.xyz +9 -0
  100. molSimplify/Ligands/aceticacidbipyridine.mol +70 -0
  101. molSimplify/Ligands/acetonitrile.mol +17 -0
  102. molSimplify/Ligands/alanine.mol +30 -0
  103. molSimplify/Ligands/alphabetizer.py +21 -0
  104. molSimplify/Ligands/amine.mol +11 -0
  105. molSimplify/Ligands/ammonia.mol +12 -0
  106. molSimplify/Ligands/arginine.mol +58 -0
  107. molSimplify/Ligands/asparagine.mol +38 -0
  108. molSimplify/Ligands/aspartic_acid.mol +35 -0
  109. molSimplify/Ligands/azide.mol +11 -0
  110. molSimplify/Ligands/benzene.mol +28 -0
  111. molSimplify/Ligands/benzene_pi.mol +30 -0
  112. molSimplify/Ligands/benzenedithiol.mol +30 -0
  113. molSimplify/Ligands/benzenethiol.mol +30 -0
  114. molSimplify/Ligands/benzylisocy.mol +38 -0
  115. molSimplify/Ligands/bidiazine.mol +42 -0
  116. molSimplify/Ligands/bidiazole.mol +38 -0
  117. molSimplify/Ligands/bifuran.mol +38 -0
  118. molSimplify/Ligands/bihydrodiazine.mol +58 -0
  119. molSimplify/Ligands/bihydrodiazole.mol +46 -0
  120. molSimplify/Ligands/bihydrooxazine.mol +54 -0
  121. molSimplify/Ligands/bihydrooxazole.mol +42 -0
  122. molSimplify/Ligands/bihydrothiazine.mol +54 -0
  123. molSimplify/Ligands/bihydrothiazole.mol +42 -0
  124. molSimplify/Ligands/biimidazole.mol +38 -0
  125. molSimplify/Ligands/bioxazole.mol +34 -0
  126. molSimplify/Ligands/bipy.mol +46 -0
  127. molSimplify/Ligands/bipyrazine.xyz +20 -0
  128. molSimplify/Ligands/bipyrimidine.mol +42 -0
  129. molSimplify/Ligands/bipyrrole.mol +42 -0
  130. molSimplify/Ligands/bisnapthyridylpyridine.mol +111 -0
  131. molSimplify/Ligands/bithiazole.mol +34 -0
  132. molSimplify/Ligands/bromide.mol +7 -0
  133. molSimplify/Ligands/bromide.smi +1 -0
  134. molSimplify/Ligands/c2.mol +9 -0
  135. molSimplify/Ligands/caprolactone.mol +41 -0
  136. molSimplify/Ligands/carbonyl.mol +8 -0
  137. molSimplify/Ligands/carboxyl.mol +13 -0
  138. molSimplify/Ligands/cat.mol +30 -0
  139. molSimplify/Ligands/chloride.mol +7 -0
  140. molSimplify/Ligands/chloride.smi +1 -0
  141. molSimplify/Ligands/chloropyridine.mol +27 -0
  142. molSimplify/Ligands/co2.mol +10 -0
  143. molSimplify/Ligands/corrolazine.mol +72 -0
  144. molSimplify/Ligands/cs.mol +8 -0
  145. molSimplify/Ligands/cyanate.xyz +5 -0
  146. molSimplify/Ligands/cyanide.mol +9 -0
  147. molSimplify/Ligands/cyanoaceticporphyrin.mol +114 -0
  148. molSimplify/Ligands/cyanopyridine.mol +29 -0
  149. molSimplify/Ligands/cyclam.mol +81 -0
  150. molSimplify/Ligands/cyclen.mol +69 -0
  151. molSimplify/Ligands/cyclopentadienyl.mol +26 -0
  152. molSimplify/Ligands/cysteine.mol +32 -0
  153. molSimplify/Ligands/diaminomethyl.mol +19 -0
  154. molSimplify/Ligands/diazine.mol +25 -0
  155. molSimplify/Ligands/diazole.mol +23 -0
  156. molSimplify/Ligands/dicyanamide.mol +15 -0
  157. molSimplify/Ligands/dihydrofuran.mol +27 -0
  158. molSimplify/Ligands/dmap.xyz +35 -0
  159. molSimplify/Ligands/dmf.mol +28 -0
  160. molSimplify/Ligands/dmi.mol +41 -0
  161. molSimplify/Ligands/dmpe.mol +52 -0
  162. molSimplify/Ligands/dpmu.mol +47 -0
  163. molSimplify/Ligands/dppe.mol +112 -0
  164. molSimplify/Ligands/edta.mol +69 -0
  165. molSimplify/Ligands/en.mol +28 -0
  166. molSimplify/Ligands/ethanethiol.mol +21 -0
  167. molSimplify/Ligands/ethanolamine.mol +26 -0
  168. molSimplify/Ligands/ethbipy.mol +70 -0
  169. molSimplify/Ligands/ethyl.mol +19 -0
  170. molSimplify/Ligands/ethylamine.mol +24 -0
  171. molSimplify/Ligands/ethylene.mol +16 -0
  172. molSimplify/Ligands/ethylesteracac.mol +57 -0
  173. molSimplify/Ligands/fluoride.mol +7 -0
  174. molSimplify/Ligands/fluoride.smi +1 -0
  175. molSimplify/Ligands/formaldehyde.mol +12 -0
  176. molSimplify/Ligands/formamidate.xyz +8 -0
  177. molSimplify/Ligands/formate.xyz +6 -0
  178. molSimplify/Ligands/furan.mol +23 -0
  179. molSimplify/Ligands/glutamic_acid.mol +42 -0
  180. molSimplify/Ligands/glutamine.mol +44 -0
  181. molSimplify/Ligands/glycinate.mol +23 -0
  182. molSimplify/Ligands/glycine.mol +24 -0
  183. molSimplify/Ligands/h2s.mol +10 -0
  184. molSimplify/Ligands/helium.mol +6 -0
  185. molSimplify/Ligands/histidine.mol +45 -0
  186. molSimplify/Ligands/hmpa.mol +62 -0
  187. molSimplify/Ligands/hs-.mol +9 -0
  188. molSimplify/Ligands/hydride.mol +7 -0
  189. molSimplify/Ligands/hydrocarboxyacetylide.xyz +8 -0
  190. molSimplify/Ligands/hydrocyanide.mol +10 -0
  191. molSimplify/Ligands/hydrodiazine.mol +33 -0
  192. molSimplify/Ligands/hydrodiazole.mol +27 -0
  193. molSimplify/Ligands/hydrogensulfide.mol +10 -0
  194. molSimplify/Ligands/hydroisocyanide.mol +11 -0
  195. molSimplify/Ligands/hydrooxazine.mol +31 -0
  196. molSimplify/Ligands/hydrooxazole.mol +25 -0
  197. molSimplify/Ligands/hydrothiazine.mol +31 -0
  198. molSimplify/Ligands/hydrothiazole.mol +25 -0
  199. molSimplify/Ligands/hydroxyl.mol +9 -0
  200. molSimplify/Ligands/imidazole.mol +23 -0
  201. molSimplify/Ligands/imidazolidinone.mol +29 -0
  202. molSimplify/Ligands/imine.mol +13 -0
  203. molSimplify/Ligands/iminodiacetic.mol +33 -0
  204. molSimplify/Ligands/iodide.mol +7 -0
  205. molSimplify/Ligands/iodobenzene.xyz +14 -0
  206. molSimplify/Ligands/isoleucine.mol +48 -0
  207. molSimplify/Ligands/isothiocyanate.mol +11 -0
  208. molSimplify/Ligands/leucine.mol +48 -0
  209. molSimplify/Ligands/ligands.dict +257 -0
  210. molSimplify/Ligands/lysine.mol +54 -0
  211. molSimplify/Ligands/mebenzenedithiol.mol +36 -0
  212. molSimplify/Ligands/mebim_py.xyz +29 -0
  213. molSimplify/Ligands/mebim_pz.xyz +28 -0
  214. molSimplify/Ligands/mebipy.mol +58 -0
  215. molSimplify/Ligands/mecat.mol +36 -0
  216. molSimplify/Ligands/methanal.mol +11 -0
  217. molSimplify/Ligands/methanethiol.mol +15 -0
  218. molSimplify/Ligands/methanol.mol +16 -0
  219. molSimplify/Ligands/methionine.mol +44 -0
  220. molSimplify/Ligands/methyl.mol +13 -0
  221. molSimplify/Ligands/methylacetylide.xyz +8 -0
  222. molSimplify/Ligands/methylamine.mol +19 -0
  223. molSimplify/Ligands/methylazide.xyz +9 -0
  224. molSimplify/Ligands/methylisocy.mol +17 -0
  225. molSimplify/Ligands/methylpyridine.mol +33 -0
  226. molSimplify/Ligands/n2.mol +8 -0
  227. molSimplify/Ligands/n4py.xyz +51 -0
  228. molSimplify/Ligands/nch.mol +10 -0
  229. molSimplify/Ligands/nco-.mol +11 -0
  230. molSimplify/Ligands/nethanolamine.mol +26 -0
  231. molSimplify/Ligands/nitrate.mol +14 -0
  232. molSimplify/Ligands/nitrite.mol +11 -0
  233. molSimplify/Ligands/nitro.mol +11 -0
  234. molSimplify/Ligands/nitrobipy.mol +54 -0
  235. molSimplify/Ligands/nitroso.mol +8 -0
  236. molSimplify/Ligands/nme3.mol +30 -0
  237. molSimplify/Ligands/no-.mol +10 -0
  238. molSimplify/Ligands/no2-.mol +11 -0
  239. molSimplify/Ligands/noxygen.mol +8 -0
  240. molSimplify/Ligands/ns-.mol +10 -0
  241. molSimplify/Ligands/o-pyridylbenzene.xyz +23 -0
  242. molSimplify/Ligands/o-pyridylphenylanion.xyz +22 -0
  243. molSimplify/Ligands/o2-.mol +9 -0
  244. molSimplify/Ligands/o2.xyz +4 -0
  245. molSimplify/Ligands/och2.mol +12 -0
  246. molSimplify/Ligands/oethanolamine.mol +26 -0
  247. molSimplify/Ligands/ome2.mol +22 -0
  248. molSimplify/Ligands/ooh.xyz +5 -0
  249. molSimplify/Ligands/oxalate.mol +17 -0
  250. molSimplify/Ligands/oxalate.smi +1 -0
  251. molSimplify/Ligands/oxygen.mol +7 -0
  252. molSimplify/Ligands/pentacyanocyclopentadienide.mol +36 -0
  253. molSimplify/Ligands/ph2-.mol +11 -0
  254. molSimplify/Ligands/ph3.mol +12 -0
  255. molSimplify/Ligands/phen.mol +51 -0
  256. molSimplify/Ligands/phenacac.mol +63 -0
  257. molSimplify/Ligands/phenalalanine.mol +51 -0
  258. molSimplify/Ligands/phendione.mol +51 -0
  259. molSimplify/Ligands/phenphen.mol +75 -0
  260. molSimplify/Ligands/phenylbenzoxazole.mol +54 -0
  261. molSimplify/Ligands/phenylcyc.mol +99 -0
  262. molSimplify/Ligands/phenylenediamine.mol +37 -0
  263. molSimplify/Ligands/phenylisocy.mol +32 -0
  264. molSimplify/Ligands/phosacidbipy.mol +66 -0
  265. molSimplify/Ligands/phosphine.mol +13 -0
  266. molSimplify/Ligands/phosphorine.mol +27 -0
  267. molSimplify/Ligands/phosphorustrifluoride.mol +12 -0
  268. molSimplify/Ligands/phthalocyanine.mol +126 -0
  269. molSimplify/Ligands/pme3o.mol +32 -0
  270. molSimplify/Ligands/porphyrin.mol +82 -0
  271. molSimplify/Ligands/pph3o.mol +77 -0
  272. molSimplify/Ligands/proline.mol +39 -0
  273. molSimplify/Ligands/propdiol.mol +21 -0
  274. molSimplify/Ligands/propylene.mol +23 -0
  275. molSimplify/Ligands/pyridine.mol +27 -0
  276. molSimplify/Ligands/pyrimidone.mol +27 -0
  277. molSimplify/Ligands/pyrrole.mol +24 -0
  278. molSimplify/Ligands/quinoxalinedithiol.mol +39 -0
  279. molSimplify/Ligands/s2-.mol +9 -0
  280. molSimplify/Ligands/salen.mol +75 -0
  281. molSimplify/Ligands/salphen.mol +84 -0
  282. molSimplify/Ligands/serine.mol +32 -0
  283. molSimplify/Ligands/simple_ligands.dict +14 -0
  284. molSimplify/Ligands/sulfacidbipy.mol +63 -0
  285. molSimplify/Ligands/tbucat.mol +54 -0
  286. molSimplify/Ligands/tbuphisocy.mol +56 -0
  287. molSimplify/Ligands/tbutylcyclen.mol +166 -0
  288. molSimplify/Ligands/tbutylisocy.mol +35 -0
  289. molSimplify/Ligands/tbutylthiol.mol +33 -0
  290. molSimplify/Ligands/tcnoet.mol +43 -0
  291. molSimplify/Ligands/tcnoetOH.mol +45 -0
  292. molSimplify/Ligands/terpy.mol +65 -0
  293. molSimplify/Ligands/tetrahydrofuran.mol +31 -0
  294. molSimplify/Ligands/thiane.mol +37 -0
  295. molSimplify/Ligands/thiazole.mol +21 -0
  296. molSimplify/Ligands/thiocyanate.mol +11 -0
  297. molSimplify/Ligands/thiol.mol +9 -0
  298. molSimplify/Ligands/thiophene.mol +23 -0
  299. molSimplify/Ligands/thiopyridine.mol +29 -0
  300. molSimplify/Ligands/threonine.mol +38 -0
  301. molSimplify/Ligands/tpp.mol +165 -0
  302. molSimplify/Ligands/tricyanomethyl.mol +19 -0
  303. molSimplify/Ligands/trifluoromethyl.mol +13 -0
  304. molSimplify/Ligands/tryptophan.mol +60 -0
  305. molSimplify/Ligands/tyrosine.mol +53 -0
  306. molSimplify/Ligands/uthiol.mol +11 -0
  307. molSimplify/Ligands/uthiolme2.mol +23 -0
  308. molSimplify/Ligands/valine.mol +42 -0
  309. molSimplify/Ligands/water.mol +10 -0
  310. molSimplify/Ligands/x.mol +6 -0
  311. molSimplify/Scripts/__init__.py +0 -0
  312. molSimplify/Scripts/addtodb.py +308 -0
  313. molSimplify/Scripts/cellbuilder.py +1592 -0
  314. molSimplify/Scripts/cellbuilder_tools.py +701 -0
  315. molSimplify/Scripts/chains.py +342 -0
  316. molSimplify/Scripts/convert_2to3.py +23 -0
  317. molSimplify/Scripts/dbinteract.py +631 -0
  318. molSimplify/Scripts/distgeom.py +617 -0
  319. molSimplify/Scripts/findcorrelations.py +287 -0
  320. molSimplify/Scripts/generator.py +267 -0
  321. molSimplify/Scripts/geometry.py +1224 -0
  322. molSimplify/Scripts/grabguivars.py +845 -0
  323. molSimplify/Scripts/in_b3lyp_usetc.py +141 -0
  324. molSimplify/Scripts/inparse.py +1673 -0
  325. molSimplify/Scripts/io.py +1149 -0
  326. molSimplify/Scripts/isomers.py +415 -0
  327. molSimplify/Scripts/jobgen.py +247 -0
  328. molSimplify/Scripts/krr_prep.py +1262 -0
  329. molSimplify/Scripts/molSimplify_io.py +18 -0
  330. molSimplify/Scripts/molden2psi4wfn.py +166 -0
  331. molSimplify/Scripts/namegen.py +32 -0
  332. molSimplify/Scripts/nn_prep.py +561 -0
  333. molSimplify/Scripts/oct_check_mols.py +782 -0
  334. molSimplify/Scripts/periodic_QE.py +97 -0
  335. molSimplify/Scripts/postmold.py +304 -0
  336. molSimplify/Scripts/postmwfn.py +709 -0
  337. molSimplify/Scripts/postparse.py +488 -0
  338. molSimplify/Scripts/postproc.py +139 -0
  339. molSimplify/Scripts/qcgen.py +1450 -0
  340. molSimplify/Scripts/rmsd.py +489 -0
  341. molSimplify/Scripts/rungen.py +670 -0
  342. molSimplify/Scripts/structgen.py +3040 -0
  343. molSimplify/Scripts/tf_nn_prep.py +894 -0
  344. molSimplify/Scripts/tsgen.py +295 -0
  345. molSimplify/Scripts/uq_calibration.py +69 -0
  346. molSimplify/__init__.py +0 -0
  347. molSimplify/__main__.py +197 -0
  348. molSimplify/icons/chemdb.png +0 -0
  349. molSimplify/icons/hjklogo.png +0 -0
  350. molSimplify/icons/icon.png +0 -0
  351. molSimplify/icons/logo.png +0 -0
  352. molSimplify/icons/logo_old.png +0 -0
  353. molSimplify/icons/petachem.png +0 -0
  354. molSimplify/icons/petachem2.png +0 -0
  355. molSimplify/icons/petachem_full.png +0 -0
  356. molSimplify/icons/pythonlogo.png +0 -0
  357. molSimplify/icons/sge copy.png +0 -0
  358. molSimplify/icons/sge.png +0 -0
  359. molSimplify/icons/slurm.png +0 -0
  360. molSimplify/icons/wft1.png +0 -0
  361. molSimplify/icons/wft2.png +0 -0
  362. molSimplify/icons/wft3.png +0 -0
  363. molSimplify/ml/__init__.py +0 -0
  364. molSimplify/ml/kernels.py +36 -0
  365. molSimplify/ml/layers.py +29 -0
  366. molSimplify/molscontrol/__init__.py +14 -0
  367. molSimplify/molscontrol/_version.py +521 -0
  368. molSimplify/molscontrol/clf_tools.py +144 -0
  369. molSimplify/molscontrol/data/README.md +21 -0
  370. molSimplify/molscontrol/data/look_and_say.dat +15 -0
  371. molSimplify/molscontrol/dynamic_classifier.py +514 -0
  372. molSimplify/molscontrol/io_tools.py +363 -0
  373. molSimplify/molscontrol/molscontrol.py +49 -0
  374. molSimplify/molscontrol/terachem/jobscript_control.sh +31 -0
  375. molSimplify/molscontrol/terachem/terachem_input +22 -0
  376. molSimplify/python_krr/X_train_TS.csv +535 -0
  377. molSimplify/python_krr/__init__.py +0 -0
  378. molSimplify/python_krr/hat2_X_mean_std.csv +3 -0
  379. molSimplify/python_krr/hat2_feature_names.csv +1 -0
  380. molSimplify/python_krr/hat2_y_mean_std.csv +2 -0
  381. molSimplify/python_krr/hat_X_mean_std.csv +6 -0
  382. molSimplify/python_krr/hat_feature_names.csv +1 -0
  383. molSimplify/python_krr/hat_krr_X_train.csv +5205 -0
  384. molSimplify/python_krr/hat_krr_dual_coef.csv +1 -0
  385. molSimplify/python_krr/hat_y_mean_std.csv +2 -0
  386. molSimplify/python_krr/sklearn_models.py +34 -0
  387. molSimplify/python_krr/y_train_TS.csv +535 -0
  388. molSimplify/python_nn/ANN.py +198 -0
  389. molSimplify/python_nn/__init__.py +0 -0
  390. molSimplify/python_nn/clf_analysis_tool.py +125 -0
  391. molSimplify/python_nn/dictionary_toolbox.py +49 -0
  392. molSimplify/python_nn/ensemble_test.py +309 -0
  393. molSimplify/python_nn/hs_center.csv +26 -0
  394. molSimplify/python_nn/hs_scale.csv +26 -0
  395. molSimplify/python_nn/ls_center.csv +26 -0
  396. molSimplify/python_nn/ls_scale.csv +26 -0
  397. molSimplify/python_nn/ms_hs_b1.csv +50 -0
  398. molSimplify/python_nn/ms_hs_b2.csv +50 -0
  399. molSimplify/python_nn/ms_hs_b3.csv +1 -0
  400. molSimplify/python_nn/ms_hs_w1.csv +50 -0
  401. molSimplify/python_nn/ms_hs_w2.csv +50 -0
  402. molSimplify/python_nn/ms_hs_w3.csv +1 -0
  403. molSimplify/python_nn/ms_ls_b1.csv +50 -0
  404. molSimplify/python_nn/ms_ls_b2.csv +50 -0
  405. molSimplify/python_nn/ms_ls_b3.csv +1 -0
  406. molSimplify/python_nn/ms_ls_w1.csv +50 -0
  407. molSimplify/python_nn/ms_ls_w2.csv +50 -0
  408. molSimplify/python_nn/ms_ls_w3.csv +1 -0
  409. molSimplify/python_nn/ms_slope_b1.csv +50 -0
  410. molSimplify/python_nn/ms_slope_b2.csv +50 -0
  411. molSimplify/python_nn/ms_slope_b3.csv +1 -0
  412. molSimplify/python_nn/ms_slope_w1.csv +50 -0
  413. molSimplify/python_nn/ms_slope_w2.csv +50 -0
  414. molSimplify/python_nn/ms_slope_w3.csv +1 -0
  415. molSimplify/python_nn/ms_split_b1.csv +50 -0
  416. molSimplify/python_nn/ms_split_b2.csv +50 -0
  417. molSimplify/python_nn/ms_split_b3.csv +1 -0
  418. molSimplify/python_nn/ms_split_w1.csv +50 -0
  419. molSimplify/python_nn/ms_split_w2.csv +50 -0
  420. molSimplify/python_nn/ms_split_w3.csv +1 -0
  421. molSimplify/python_nn/slope_center.csv +25 -0
  422. molSimplify/python_nn/slope_scale.csv +25 -0
  423. molSimplify/python_nn/split_center.csv +26 -0
  424. molSimplify/python_nn/split_scale.csv +26 -0
  425. molSimplify/python_nn/tf_ANN.py +762 -0
  426. molSimplify/python_nn/train_data.csv +1211 -0
  427. molSimplify/tf_nn/__init__.py +0 -0
  428. molSimplify/tf_nn/geo_static_clf/geo_static_clf_model.h5 +0 -0
  429. molSimplify/tf_nn/geo_static_clf/geo_static_clf_train_name.csv +1591 -0
  430. molSimplify/tf_nn/geo_static_clf/geo_static_clf_train_x.csv +2790 -0
  431. molSimplify/tf_nn/geo_static_clf/geo_static_clf_train_y.csv +2790 -0
  432. molSimplify/tf_nn/geo_static_clf/geo_static_clf_vars.csv +154 -0
  433. molSimplify/tf_nn/geos/hs_ii_bl_x.csv +1577 -0
  434. molSimplify/tf_nn/geos/hs_ii_bl_y.csv +1577 -0
  435. molSimplify/tf_nn/geos/hs_ii_model.h5 +0 -0
  436. molSimplify/tf_nn/geos/hs_ii_model.json +1 -0
  437. molSimplify/tf_nn/geos/hs_ii_vars.csv +154 -0
  438. molSimplify/tf_nn/geos/hs_iii_bl_x.csv +1659 -0
  439. molSimplify/tf_nn/geos/hs_iii_bl_y.csv +1659 -0
  440. molSimplify/tf_nn/geos/hs_iii_model.h5 +0 -0
  441. molSimplify/tf_nn/geos/hs_iii_model.json +1 -0
  442. molSimplify/tf_nn/geos/hs_iii_vars.csv +154 -0
  443. molSimplify/tf_nn/geos/ls_ii_bl_x.csv +1374 -0
  444. molSimplify/tf_nn/geos/ls_ii_bl_y.csv +1374 -0
  445. molSimplify/tf_nn/geos/ls_ii_model.h5 +0 -0
  446. molSimplify/tf_nn/geos/ls_ii_model.json +1 -0
  447. molSimplify/tf_nn/geos/ls_ii_vars.csv +154 -0
  448. molSimplify/tf_nn/geos/ls_iii_bl_x.csv +1364 -0
  449. molSimplify/tf_nn/geos/ls_iii_bl_y.csv +1364 -0
  450. molSimplify/tf_nn/geos/ls_iii_model.h5 +0 -0
  451. molSimplify/tf_nn/geos/ls_iii_model.json +1 -0
  452. molSimplify/tf_nn/geos/ls_iii_vars.csv +154 -0
  453. molSimplify/tf_nn/homolumo/gap_model.h5 +0 -0
  454. molSimplify/tf_nn/homolumo/gap_model.json +1 -0
  455. molSimplify/tf_nn/homolumo/gap_test_names.csv +175 -0
  456. molSimplify/tf_nn/homolumo/gap_test_x.csv +176 -0
  457. molSimplify/tf_nn/homolumo/gap_test_y.csv +176 -0
  458. molSimplify/tf_nn/homolumo/gap_train_names.csv +699 -0
  459. molSimplify/tf_nn/homolumo/gap_train_x.csv +700 -0
  460. molSimplify/tf_nn/homolumo/gap_train_y.csv +700 -0
  461. molSimplify/tf_nn/homolumo/gap_vars.csv +153 -0
  462. molSimplify/tf_nn/homolumo/homo_model.h5 +0 -0
  463. molSimplify/tf_nn/homolumo/homo_model.json +126 -0
  464. molSimplify/tf_nn/homolumo/homo_test_names.csv +175 -0
  465. molSimplify/tf_nn/homolumo/homo_test_x.csv +176 -0
  466. molSimplify/tf_nn/homolumo/homo_test_y.csv +176 -0
  467. molSimplify/tf_nn/homolumo/homo_train_names.csv +699 -0
  468. molSimplify/tf_nn/homolumo/homo_train_x.csv +700 -0
  469. molSimplify/tf_nn/homolumo/homo_train_y.csv +700 -0
  470. molSimplify/tf_nn/homolumo/homo_vars.csv +153 -0
  471. molSimplify/tf_nn/oxoandhomo/homo_empty_info.json +7 -0
  472. molSimplify/tf_nn/oxoandhomo/homo_empty_model.h5 +0 -0
  473. molSimplify/tf_nn/oxoandhomo/homo_empty_model.json +1 -0
  474. molSimplify/tf_nn/oxoandhomo/homo_empty_test_names.csv +143 -0
  475. molSimplify/tf_nn/oxoandhomo/homo_empty_test_x.csv +144 -0
  476. molSimplify/tf_nn/oxoandhomo/homo_empty_test_y.csv +144 -0
  477. molSimplify/tf_nn/oxoandhomo/homo_empty_train_names.csv +513 -0
  478. molSimplify/tf_nn/oxoandhomo/homo_empty_train_x.csv +514 -0
  479. molSimplify/tf_nn/oxoandhomo/homo_empty_train_y.csv +514 -0
  480. molSimplify/tf_nn/oxoandhomo/homo_empty_val_names.csv +143 -0
  481. molSimplify/tf_nn/oxoandhomo/homo_empty_val_x.csv +58 -0
  482. molSimplify/tf_nn/oxoandhomo/homo_empty_val_y.csv +58 -0
  483. molSimplify/tf_nn/oxoandhomo/homo_empty_vars.csv +155 -0
  484. molSimplify/tf_nn/oxoandhomo/oxo20_info.json +7 -0
  485. molSimplify/tf_nn/oxoandhomo/oxo20_model.h5 +0 -0
  486. molSimplify/tf_nn/oxoandhomo/oxo20_model.json +1 -0
  487. molSimplify/tf_nn/oxoandhomo/oxo20_test_names.csv +143 -0
  488. molSimplify/tf_nn/oxoandhomo/oxo20_test_x.csv +144 -0
  489. molSimplify/tf_nn/oxoandhomo/oxo20_test_y.csv +144 -0
  490. molSimplify/tf_nn/oxoandhomo/oxo20_train_names.csv +513 -0
  491. molSimplify/tf_nn/oxoandhomo/oxo20_train_x.csv +514 -0
  492. molSimplify/tf_nn/oxoandhomo/oxo20_train_y.csv +514 -0
  493. molSimplify/tf_nn/oxoandhomo/oxo20_val_names.csv +143 -0
  494. molSimplify/tf_nn/oxoandhomo/oxo20_val_x.csv +58 -0
  495. molSimplify/tf_nn/oxoandhomo/oxo20_val_y.csv +58 -0
  496. molSimplify/tf_nn/oxoandhomo/oxo20_vars.csv +154 -0
  497. molSimplify/tf_nn/oxocatalysis/hat_model.h5 +0 -0
  498. molSimplify/tf_nn/oxocatalysis/hat_model.json +1 -0
  499. molSimplify/tf_nn/oxocatalysis/hat_test_names.csv +419 -0
  500. molSimplify/tf_nn/oxocatalysis/hat_test_x.csv +420 -0
  501. molSimplify/tf_nn/oxocatalysis/hat_test_y.csv +420 -0
  502. molSimplify/tf_nn/oxocatalysis/hat_train_names.csv +1507 -0
  503. molSimplify/tf_nn/oxocatalysis/hat_train_x.csv +1508 -0
  504. molSimplify/tf_nn/oxocatalysis/hat_train_y.csv +1508 -0
  505. molSimplify/tf_nn/oxocatalysis/hat_val_x.csv +169 -0
  506. molSimplify/tf_nn/oxocatalysis/hat_val_y.csv +169 -0
  507. molSimplify/tf_nn/oxocatalysis/hat_vars.csv +162 -0
  508. molSimplify/tf_nn/oxocatalysis/oxo_model.h5 +0 -0
  509. molSimplify/tf_nn/oxocatalysis/oxo_model.json +1 -0
  510. molSimplify/tf_nn/oxocatalysis/oxo_test_names.csv +527 -0
  511. molSimplify/tf_nn/oxocatalysis/oxo_test_x.csv +528 -0
  512. molSimplify/tf_nn/oxocatalysis/oxo_test_y.csv +528 -0
  513. molSimplify/tf_nn/oxocatalysis/oxo_train_names.csv +1897 -0
  514. molSimplify/tf_nn/oxocatalysis/oxo_train_x.csv +1898 -0
  515. molSimplify/tf_nn/oxocatalysis/oxo_train_y.csv +1898 -0
  516. molSimplify/tf_nn/oxocatalysis/oxo_val_x.csv +212 -0
  517. molSimplify/tf_nn/oxocatalysis/oxo_val_y.csv +212 -0
  518. molSimplify/tf_nn/oxocatalysis/oxo_vars.csv +162 -0
  519. molSimplify/tf_nn/rescaling_data/gap_mean_x.csv +153 -0
  520. molSimplify/tf_nn/rescaling_data/gap_mean_y.csv +1 -0
  521. molSimplify/tf_nn/rescaling_data/gap_var_x.csv +153 -0
  522. molSimplify/tf_nn/rescaling_data/gap_var_y.csv +1 -0
  523. molSimplify/tf_nn/rescaling_data/geo_static_clf_mean_x.csv +154 -0
  524. molSimplify/tf_nn/rescaling_data/geo_static_clf_mean_y.csv +1 -0
  525. molSimplify/tf_nn/rescaling_data/geo_static_clf_var_x.csv +154 -0
  526. molSimplify/tf_nn/rescaling_data/geo_static_clf_var_y.csv +1 -0
  527. molSimplify/tf_nn/rescaling_data/hat_mean_x.csv +162 -0
  528. molSimplify/tf_nn/rescaling_data/hat_mean_y.csv +1 -0
  529. molSimplify/tf_nn/rescaling_data/hat_var_x.csv +162 -0
  530. molSimplify/tf_nn/rescaling_data/hat_var_y.csv +1 -0
  531. molSimplify/tf_nn/rescaling_data/homo_empty_mean_x.csv +155 -0
  532. molSimplify/tf_nn/rescaling_data/homo_empty_mean_y.csv +1 -0
  533. molSimplify/tf_nn/rescaling_data/homo_empty_var_x.csv +155 -0
  534. molSimplify/tf_nn/rescaling_data/homo_empty_var_y.csv +1 -0
  535. molSimplify/tf_nn/rescaling_data/homo_mean_x.csv +153 -0
  536. molSimplify/tf_nn/rescaling_data/homo_mean_y.csv +1 -0
  537. molSimplify/tf_nn/rescaling_data/homo_var_x.csv +153 -0
  538. molSimplify/tf_nn/rescaling_data/homo_var_y.csv +1 -0
  539. molSimplify/tf_nn/rescaling_data/hs_ii_mean_x.csv +154 -0
  540. molSimplify/tf_nn/rescaling_data/hs_ii_mean_y.csv +3 -0
  541. molSimplify/tf_nn/rescaling_data/hs_ii_var_x.csv +154 -0
  542. molSimplify/tf_nn/rescaling_data/hs_ii_var_y.csv +3 -0
  543. molSimplify/tf_nn/rescaling_data/hs_iii_mean_x.csv +154 -0
  544. molSimplify/tf_nn/rescaling_data/hs_iii_mean_y.csv +3 -0
  545. molSimplify/tf_nn/rescaling_data/hs_iii_var_x.csv +154 -0
  546. molSimplify/tf_nn/rescaling_data/hs_iii_var_y.csv +3 -0
  547. molSimplify/tf_nn/rescaling_data/ls_ii_mean_x.csv +154 -0
  548. molSimplify/tf_nn/rescaling_data/ls_ii_mean_y.csv +3 -0
  549. molSimplify/tf_nn/rescaling_data/ls_ii_var_x.csv +154 -0
  550. molSimplify/tf_nn/rescaling_data/ls_ii_var_y.csv +3 -0
  551. molSimplify/tf_nn/rescaling_data/ls_iii_mean_x.csv +154 -0
  552. molSimplify/tf_nn/rescaling_data/ls_iii_mean_y.csv +3 -0
  553. molSimplify/tf_nn/rescaling_data/ls_iii_var_x.csv +154 -0
  554. molSimplify/tf_nn/rescaling_data/ls_iii_var_y.csv +3 -0
  555. molSimplify/tf_nn/rescaling_data/oxo20_mean_x.csv +154 -0
  556. molSimplify/tf_nn/rescaling_data/oxo20_mean_y.csv +1 -0
  557. molSimplify/tf_nn/rescaling_data/oxo20_var_x.csv +154 -0
  558. molSimplify/tf_nn/rescaling_data/oxo20_var_y.csv +1 -0
  559. molSimplify/tf_nn/rescaling_data/oxo_mean_x.csv +162 -0
  560. molSimplify/tf_nn/rescaling_data/oxo_mean_y.csv +1 -0
  561. molSimplify/tf_nn/rescaling_data/oxo_var_x.csv +162 -0
  562. molSimplify/tf_nn/rescaling_data/oxo_var_y.csv +1 -0
  563. molSimplify/tf_nn/rescaling_data/sc_static_clf_mean_x.csv +154 -0
  564. molSimplify/tf_nn/rescaling_data/sc_static_clf_mean_y.csv +1 -0
  565. molSimplify/tf_nn/rescaling_data/sc_static_clf_var_x.csv +154 -0
  566. molSimplify/tf_nn/rescaling_data/sc_static_clf_var_y.csv +1 -0
  567. molSimplify/tf_nn/rescaling_data/split_mean_x.csv +155 -0
  568. molSimplify/tf_nn/rescaling_data/split_mean_y.csv +1 -0
  569. molSimplify/tf_nn/rescaling_data/split_var_x.csv +155 -0
  570. molSimplify/tf_nn/rescaling_data/split_var_y.csv +1 -0
  571. molSimplify/tf_nn/sc_static_clf/sc_static_clf_model.h5 +0 -0
  572. molSimplify/tf_nn/sc_static_clf/sc_static_clf_train_name.csv +1591 -0
  573. molSimplify/tf_nn/sc_static_clf/sc_static_clf_train_x.csv +1592 -0
  574. molSimplify/tf_nn/sc_static_clf/sc_static_clf_train_y.csv +1592 -0
  575. molSimplify/tf_nn/sc_static_clf/sc_static_clf_vars.csv +154 -0
  576. molSimplify/tf_nn/split/split_model.h5 +0 -0
  577. molSimplify/tf_nn/split/split_model.json +1 -0
  578. molSimplify/tf_nn/split/split_vars.csv +155 -0
  579. molSimplify/tf_nn/split/split_x.csv +1902 -0
  580. molSimplify/tf_nn/split/split_y.csv +1902 -0
  581. molSimplify/tf_nn/split/train_names.csv +1901 -0
  582. molSimplify/utils/__init__.py +0 -0
  583. molSimplify/utils/decorators.py +16 -0
  584. molSimplify/utils/metaclasses.py +12 -0
  585. molSimplify/utils/tensorflow.py +23 -0
  586. molSimplify/utils/timer.py +16 -0
  587. molSimplify-1.7.4.dist-info/LICENSE +674 -0
  588. molSimplify-1.7.4.dist-info/METADATA +821 -0
  589. molSimplify-1.7.4.dist-info/RECORD +651 -0
  590. molSimplify-1.7.4.dist-info/WHEEL +5 -0
  591. molSimplify-1.7.4.dist-info/entry_points.txt +3 -0
  592. molSimplify-1.7.4.dist-info/top_level.txt +4 -0
  593. tests/generateTests.py +122 -0
  594. tests/helperFuncs.py +658 -0
  595. tests/informatics/test_MOF_descriptors.py +128 -0
  596. tests/informatics/test_active_learning.py +113 -0
  597. tests/informatics/test_coulomb_analyze.py +24 -0
  598. tests/informatics/test_graph_racs.py +193 -0
  599. tests/ml/test_kernels.py +20 -0
  600. tests/ml/test_layers.py +47 -0
  601. tests/runtest.py +10 -0
  602. tests/test_Mol2D.py +128 -0
  603. tests/test_basic_imports.py +62 -0
  604. tests/test_bidentate.py +25 -0
  605. tests/test_cli.py +20 -0
  606. tests/test_distgeom.py +106 -0
  607. tests/test_example_1.py +29 -0
  608. tests/test_example_3.py +31 -0
  609. tests/test_example_5.py +43 -0
  610. tests/test_example_7.py +28 -0
  611. tests/test_example_8.py +15 -0
  612. tests/test_example_tbp.py +15 -0
  613. tests/test_ff_xtb.py +111 -0
  614. tests/test_geocheck_oct.py +26 -0
  615. tests/test_geocheck_one_empty.py +15 -0
  616. tests/test_geometry.py +44 -0
  617. tests/test_inparse.py +76 -0
  618. tests/test_io.py +84 -0
  619. tests/test_jobgen.py +84 -0
  620. tests/test_joption_pythonic.py +27 -0
  621. tests/test_ligand_assign.py +58 -0
  622. tests/test_ligand_assign_consistent.py +60 -0
  623. tests/test_ligand_class.py +26 -0
  624. tests/test_ligand_from_mol_file.py +35 -0
  625. tests/test_ligands.py +86 -0
  626. tests/test_mol3D.py +337 -0
  627. tests/test_molcas_caspt2.py +15 -0
  628. tests/test_molcas_casscf.py +15 -0
  629. tests/test_old_ANNs.py +68 -0
  630. tests/test_orca_ccsdt.py +15 -0
  631. tests/test_orca_dft.py +15 -0
  632. tests/test_qcgen.py +50 -0
  633. tests/test_racs.py +124 -0
  634. tests/test_rmsd.py +68 -0
  635. tests/test_structgen_functions.py +198 -0
  636. tests/test_tetrahedral.py +29 -0
  637. tests/test_tutorial_10_part_one.py +16 -0
  638. tests/test_tutorial_10_part_two.py +15 -0
  639. tests/test_tutorial_2.py +11 -0
  640. tests/test_tutorial_3.py +15 -0
  641. tests/test_tutorial_4.py +57 -0
  642. tests/test_tutorial_6.py +10 -0
  643. tests/test_tutorial_8.py +29 -0
  644. tests/test_tutorial_9_part_one.py +15 -0
  645. tests/test_tutorial_9_part_two.py +15 -0
  646. tests/test_tutorial_qm9_part_one.py +6 -0
  647. tests/testresources/refs/racs/generate_references.py +85 -0
  648. workflows/NandyJACSAu2022/bridge_functionalizer.py +253 -0
  649. workflows/NandyJACSAu2022/frag_functionalizer.py +242 -0
  650. workflows/NandyJACSAu2022/fragment_classes.py +586 -0
  651. workflows/NandyJACSAu2022/macrocycle_synthesis.py +179 -0
@@ -0,0 +1,1592 @@
1
+ # @file cellbuilder.py
2
+ # Builds unit cells with adsorbed species.
3
+ #
4
+ # Written by JP Janet for HJK Group
5
+ #
6
+ # Dpt of Chemical Engineering, MIT
7
+
8
+ import os
9
+ import random
10
+ import copy
11
+ import numpy
12
+ from math import sqrt
13
+
14
+ from scipy.spatial import Delaunay
15
+ from molSimplify.Classes.atom3D import atom3D
16
+ from molSimplify.Classes.mol3D import mol3D
17
+ from molSimplify.Classes.globalvars import globalvars
18
+ from molSimplify.Scripts.cellbuilder_tools import (cell_ffopt,
19
+ center_of_sym,
20
+ check_top_layer_correct,
21
+ closest_torus_point,
22
+ distance_2d_torus,
23
+ evaluate_basis_coefficients,
24
+ find_all_surface_atoms,
25
+ find_extents,
26
+ find_extents_cv,
27
+ freeze_bottom_n_layers,
28
+ get_basis_coefficients,
29
+ import_from_cif,
30
+ mdistance,
31
+ normalize_vector,
32
+ periodic_mindist,
33
+ periodic_selfdist,
34
+ shave_surface_layer,
35
+ shave_under_layer,
36
+ threshold_basis,
37
+ xgcd,
38
+ zero_z)
39
+ from molSimplify.Scripts.geometry import (PointRotateAxis,
40
+ checkcolinear,
41
+ vecdiff,
42
+ rotate_around_axis,
43
+ rotation_params,
44
+ vecangle,
45
+ distance)
46
+ from molSimplify.Scripts.periodic_QE import (write_periodic_mol3d_to_qe)
47
+
48
+
49
+ ###############################
50
+
51
+
52
+ def d_fix(unit_cell, cell_vector):
53
+ fixed_cell = mol3D()
54
+ fixed_cell.copymol3D(unit_cell)
55
+ mind = 100
56
+ for i, atoms in enumerate(fixed_cell.getAtoms()):
57
+ this_distance = mdistance(atoms.coords(), [0, 0, 0])
58
+ print(("min d is " + str(mind)))
59
+ print(("atom at " + str(atoms.coords())))
60
+ if this_distance < mind:
61
+ mind = this_distance
62
+ minatom = atoms
63
+ minind = i
64
+ print('this was saved')
65
+ print("\n\n")
66
+ c = cell_vector[2]
67
+ dx = c[0]
68
+ dy = c[1]
69
+ dz = c[2]
70
+ trans_vect = (dx, dy, dz)
71
+ new_atom = atom3D(minatom.symbol(), minatom.coords())
72
+ new_atom.translate(trans_vect)
73
+ fixed_cell.addAtom(new_atom)
74
+ fixed_cell.deleteatoms([minind])
75
+ return fixed_cell
76
+ #####################################################
77
+
78
+
79
+ def cut_cell_to_index(unit_cell, cell_vector, miller_index):
80
+ # determine the plane:
81
+ cut_cell = mol3D()
82
+ cut_cell.copymol3D(unit_cell)
83
+ h, k, l = miller_index # noqa: E741
84
+ # print('h,k,l',str(h) + ' ' + str(k) + ' ' + str(l))
85
+ disc, p, q = xgcd(k, l)
86
+ # print('p,q',str(p) + ' ' + str(q))
87
+ cell_vector = numpy.array(cell_vector)
88
+ k1 = numpy.dot(p*(k*cell_vector[0]-h*cell_vector[1]) + q*(
89
+ l*cell_vector[0] - h*cell_vector[2]), l*cell_vector[1] - k*cell_vector[2])
90
+ k2 = numpy.dot(l*(k*cell_vector[0]-h*cell_vector[1]) - k*(
91
+ l*cell_vector[0] - h*cell_vector[2]), l*cell_vector[1] - k*cell_vector[2])
92
+ # print('k1',k1)
93
+ # print('k2',k2)
94
+ tol = 1e-3
95
+ if abs(k2) > tol:
96
+ c = -1*int(round(k1/k2))
97
+ p, q = p+c*l, q - c*k
98
+ v1 = p*numpy.array(k*cell_vector[0]-h*cell_vector[1]) + \
99
+ q*numpy.array(l*cell_vector[0] - h*cell_vector[2])
100
+ v2 = numpy.array(l*cell_vector[1]-k*cell_vector[2])
101
+ disc, a, b = xgcd(p*k + q*l, h)
102
+ v3 = numpy.array(b*cell_vector[0] + a*p *
103
+ cell_vector[1] + a*q*cell_vector[2])
104
+
105
+ non_zero_indices = list()
106
+ zero_indices = list()
107
+ for i in [0, 1, 2]:
108
+ if not (miller_index[i] == 0):
109
+ non_zero_indices.append(i)
110
+ else:
111
+ zero_indices.append(i)
112
+
113
+ print(('nz ind', non_zero_indices))
114
+ plane_normal = numpy.zeros(3)
115
+ if len(non_zero_indices) == 3:
116
+ # zint = 1/(miller_index[2]*cell_vector[2][2])
117
+ # yint = 1/(miller_index[1]*cell_vector[1][1])
118
+ # xint = 1/(miller_index[0]*cell_vector[0][0])
119
+ # w = [0,0,0]
120
+ # w[2] = zint
121
+ # w[1] = -w[2]/yint
122
+ # w[0] = -w[2]/xint
123
+ plane_normal = numpy.cross(v1, v2)
124
+ elif len(non_zero_indices) == 2:
125
+ # print('\n\n\n\n')
126
+ # print(cell_vector)
127
+ # print("\n\n")
128
+ vec1 = [0, 0, 0]
129
+ vec1[non_zero_indices[0]] = cell_vector[non_zero_indices[0]
130
+ ][non_zero_indices[0]]
131
+ vec2 = [0, 0, 0]
132
+ vec2[non_zero_indices[1]] = cell_vector[non_zero_indices[1]
133
+ ][non_zero_indices[1]]
134
+ vec3 = [0, 0, 0]
135
+ vec3[zero_indices[0]] = cell_vector[zero_indices[0]][zero_indices[0]]
136
+ # print('vec1',vec1)
137
+ # print('vec2',vec2)
138
+ # print('vec3',vec3)
139
+ plane_normal = numpy.cross(v1, v2)
140
+ elif len(non_zero_indices) == 1:
141
+
142
+ v1 = cell_vector[zero_indices[0]]
143
+ v2 = cell_vector[zero_indices[1]]
144
+ v3 = cell_vector[non_zero_indices[0]]
145
+ plane_normal = numpy.cross(v1, v2)
146
+ print(miller_index)
147
+ print(('plane normal is ', plane_normal))
148
+ angle = vecangle(plane_normal, [0, 0, 1])
149
+ u = numpy.cross(plane_normal, [0, 0, 1])
150
+ return v1, v2, v3, angle, u
151
+
152
+ ##################################
153
+
154
+
155
+ def concave_hull(points, alpha):
156
+ # points should be tuples
157
+ de = Delaunay(points)
158
+ for i in de.simplices:
159
+ tmp = [] # noqa F841 WIP
160
+ j = [points[c] for c in i] # noqa F841 WIP
161
+ # print(i)
162
+ # print(j)
163
+ # print(de)
164
+
165
+
166
+ points = [[1, 1], [1, 0], [0, 1], [0, 0]]
167
+
168
+ ###################################
169
+
170
+
171
+ def unit_to_super(unit_cell, cell_vector, duplication_vector):
172
+ # INPUT
173
+ # - unit_cell: mol3D class that contains the unit cell
174
+ # - cell_vector: list of float contains the cell vectors a,b,c
175
+ # - duplication_vector: list of int the number of duplications in each dim
176
+ # OUTPUT
177
+ # - super_cell: mol3D class that contains the super cell
178
+ super_cell = mol3D()
179
+ print(cell_vector)
180
+ acell = duplication_vector[0]
181
+ bcell = duplication_vector[1]
182
+ ccell = duplication_vector[2]
183
+ a = cell_vector[0]
184
+ b = cell_vector[1]
185
+ c = cell_vector[2]
186
+ for i in range(0, acell):
187
+ for j in range(0, bcell):
188
+ for k in range(0, ccell):
189
+ for atoms in unit_cell.getAtoms():
190
+ # print(str(i) + str(j) + str(k))
191
+ dx = 0 + i*a[0] + j*b[0] + k*c[0]
192
+ dy = 0 + i*a[1] + j*b[1] + k*c[1]
193
+ dz = 0 + i*a[2] + j*b[2] + k*c[2]
194
+ trans_vect = (dx, dy, dz)
195
+ new_atom = atom3D(
196
+ atoms.symbol(), atoms.coords(), atoms.name)
197
+ new_atom.translate(trans_vect)
198
+ super_cell.addAtom(new_atom)
199
+ return super_cell
200
+ #############################
201
+
202
+
203
+ def multialign_objective_function(payload, surface_coord_list, cand_list, bind_dist):
204
+ # INPUT
205
+ # - payload: mol3D, the structure to add
206
+ # - surface_coord_list: list of list of 3 float, coordinates of the
207
+ # slab target points
208
+ # - cand_list: list of int, indices of the attachment points in the
209
+ # payload
210
+ # - bind_dist: float, target alignment distance
211
+ # OUPUT
212
+ # - cost: float, sum of squared error, the difference between
213
+ # the actual distance and the target
214
+ cost = 0
215
+ # print('cand list is ' + str(cand_list))
216
+ # print('surface_coord_list ' + str(surface_coord_list))
217
+ for indices in enumerate(cand_list):
218
+ v1 = (surface_coord_list[indices[0]])
219
+ v2 = payload.getAtom(int(indices[1])).coords()
220
+ cost += numpy.power((mdistance(v1, v2)) - bind_dist, 2)
221
+ return cost
222
+ #############################
223
+
224
+
225
+ def tracked_merge(payload, super_cell):
226
+ # INPUT
227
+ # - super_cell: mol3D, the slab (and previously added adsorbates)
228
+ # - payload: mol3D, the structure to add
229
+ # OUPUT
230
+ # - merged_cell: mol3D, merged combintation of payload and cell
231
+ # - payload_index: list of int, indices of payload atoms in cell
232
+ # - slab_index: list of int, indices of slab atoms in the cell
233
+ payload_index = [i for i in range(0, payload.natoms)]
234
+ slab_index = [i + payload.natoms for i in range(0, super_cell.natoms)]
235
+ merged_cell = mol3D()
236
+ merged_cell.copymol3D(payload)
237
+ merged_cell.combine(super_cell)
238
+ return merged_cell, payload_index, slab_index
239
+ #############################
240
+
241
+
242
+ def force_field_relax_with_slab(super_cell, payload, cand_list, its):
243
+ # INPUT
244
+ # - super_cell: mol3D, the slab (and previously added adsorbates)
245
+ # - payload: mol3D, the structure to add
246
+ # - can_ind: list of int, indices of taget attachement points in molecule
247
+ # OUPUT
248
+ # - new_payload: mol3D, payload relaxed by force field with slab fixed
249
+ new_payload = mol3D()
250
+ new_payload.copymol3D(payload)
251
+ cell_copy = mol3D()
252
+ surface_sites_list = find_all_surface_atoms(super_cell, tol=1e-2)
253
+ for sites in surface_sites_list:
254
+ cell_copy.addAtom(super_cell.getAtom(sites))
255
+ merged_payload, payload_ind, slab_index = tracked_merge(
256
+ new_payload, cell_copy)
257
+ merged_payload.writexyz('modi.xyz')
258
+ full_fixed_atoms_list = cand_list + slab_index # freeze the slab componentsp
259
+ distorted_payload = mol3D()
260
+ distorted_payload.copymol3D(merged_payload)
261
+ print(('in ff, distorded coords' + str(distorted_payload.getAtom(0).coords())))
262
+ distorted_payload, enl = cell_ffopt(
263
+ 'uff', merged_payload, full_fixed_atoms_list)
264
+ print(('after ff, distorded coords' + str(distorted_payload.getAtom(0).coords())))
265
+ print(full_fixed_atoms_list)
266
+ # distorted_payload.writexyz(str(its)+'modr.xyz')
267
+ distorted_payload.deleteatoms(slab_index)
268
+ return distorted_payload
269
+ #############################
270
+
271
+
272
+ def surface_center(super_cell):
273
+ # INPUT
274
+ # - super_cell: mol3D, the slab (and previously added adsorbates)
275
+ # - payload: mol3D, the structure to add
276
+ # - can_ind: list of int, indices of taget attachement points in molecule
277
+ # OUPUT
278
+ # - new_payload: mol3D, payload relaxed by force field with slab fixed
279
+ cell_copy = mol3D()
280
+ surface_sites_list = find_all_surface_atoms(super_cell, tol=1e-2)
281
+ for sites in surface_sites_list:
282
+ cell_copy.addAtom(super_cell.getAtom(sites))
283
+ centroid = cell_copy.centersym()
284
+
285
+ return centroid
286
+
287
+
288
+ ##############################
289
+ def choose_nearest_neighbour(target_site, avail_sites_dict, occupied_sites_dict, super_cell, super_cell_vector, debug=False):
290
+ # INPUT
291
+ # - avail_sites_dict: dict with {index:[coords] } of {int,list of float}, free sites
292
+ # - occupied_sites_dict: dict with {index:[coords] } of {int,list of float}, occupied sites
293
+ # - target_site: list of doubles, coords that the new site should be close to
294
+
295
+ # - weight: float in [0,1], how strongly the interace-absorbate distance is weighted
296
+ # - method: 'linear' a linear combination of distance from centroid and neighbour
297
+ # distance is used
298
+ # 'log' a logarithmic weighting is used - strong re
299
+ # OUPUT
300
+ # - nn_site: index of nearest neighbour site, a key for avail_sites_dict
301
+ extents = find_extents_cv(super_cell_vector)
302
+ # print('extents = ' + str(extents))
303
+ weight = 0 # favours adjaceny to point over distance from other occupied sites
304
+ # get the nearest site to target
305
+ score = 100000 # weighted assessment, lower is better
306
+ avail_sites_list = list(avail_sites_dict.keys())
307
+ occupied_sites_list = list(occupied_sites_dict.keys())
308
+ if debug:
309
+ print('********** choosing nearest neighbour sites ********')
310
+ if (len(avail_sites_list) > 1): # more than 1 option, pick closest to target site
311
+ for indices in avail_sites_list:
312
+ if debug:
313
+ print(('checking site ' + str(indices) + ' at ' +
314
+ str(avail_sites_dict[indices]) + ' relative to ' + str(target_site)))
315
+ # NOT the torus distance - must be two cells in one unit
316
+ distance_to_target = distance(
317
+ target_site, avail_sites_dict[indices])
318
+ distance_to_nearest_occupied = 0
319
+ for neighbours in occupied_sites_list:
320
+ # get distance to nearest neighbour
321
+ distance_to_nearest_occupied = max(distance_2d_torus(
322
+ avail_sites_dict[indices], occupied_sites_dict[neighbours], extents), distance_to_nearest_occupied)
323
+ this_score = (1 - weight)*distance_to_target - \
324
+ weight*distance_to_nearest_occupied
325
+ if debug:
326
+ print(('this score is ' + str(this_score)))
327
+ if this_score < score:
328
+ score = this_score
329
+ if debug:
330
+ print(('New lowest score at ' + str(indices) +
331
+ ' has score =' + str(score) + '\n'))
332
+ nn_site = indices
333
+ elif (len(avail_sites_list) == 1):
334
+ nn_site = avail_sites_list[0]
335
+ else:
336
+ emsg = ('error: no free site is possible')
337
+ print(emsg)
338
+ return None
339
+ if debug:
340
+ print(('**** final choice = ' +
341
+ str(avail_sites_dict[nn_site]) + ' at ' + str(score)))
342
+ return nn_site
343
+ #####################################
344
+
345
+
346
+ def choose_best_site(avail_sites_dict, occupied_sites_dict, centroid, super_cell, super_cell_vector, weight=0.5, method='linear', debug=False):
347
+
348
+ # INPUT
349
+ # - avail_sites_dict: dict with {index:[coords] } of {int,list of float}, free sites
350
+ # - occupied_sites_dict: dict with {index:[coords] } of {int,list of float}, occupied sites
351
+ # - weight: float in [0,1], how strongly the interace-absorbate distance is weighted
352
+ # - method: 'linear' a linear combination of distance from centroid and neighbour
353
+ # distance is used
354
+ # 'log' a logarithmic weighting is used - strong re
355
+ # OUPUT
356
+ # - target_site: index of target site, a key for avail_sites_dict
357
+ extents = find_extents_cv(super_cell_vector)
358
+ centroid = surface_center(super_cell)
359
+ score = 100000 # weighted assessment, lower is better
360
+ avail_sites_list = list(avail_sites_dict.keys())
361
+ random.shuffle(avail_sites_list)
362
+ occupied_sites_list = list(occupied_sites_dict.keys())
363
+ if debug:
364
+ print(('extents = ' + str(extents)))
365
+ print(('centroid is at ' + str(centroid)))
366
+ print(('ac sites dict = '+str(avail_sites_dict)))
367
+ print(('oc sites list = '+str(occupied_sites_list)))
368
+ print(('ac sites list = '+str(avail_sites_list)))
369
+ print(('weight = ' + str(weight)))
370
+ if (len(avail_sites_list) > 1): # more than 1 option, pick closest to center of plane
371
+ for indices in avail_sites_list:
372
+ # distance_to_center = distance_2d_torus(centroid,avail_sites_dict[indices],extents)
373
+ distance_to_center = distance(centroid, avail_sites_dict[indices])
374
+
375
+ distance_to_nearest_occupied = 1000
376
+ for neighbours in occupied_sites_list:
377
+ # get distance to nearest neighbour
378
+ if debug:
379
+ print(
380
+ ('Neighbour:' + str(occupied_sites_dict[neighbours]) + ' point is at ' + str(avail_sites_dict[indices])))
381
+ distance_to_nearest_occupied = min(distance_2d_torus(
382
+ avail_sites_dict[indices], occupied_sites_dict[neighbours], extents), distance_to_nearest_occupied)
383
+ if debug:
384
+ print(('dist to nearest = ' + str(distance_to_nearest_occupied) +
385
+ ' at ' + str(avail_sites_dict[indices])))
386
+ if (method == 'linear'):
387
+ this_score = (1 - weight)*distance_to_center - \
388
+ weight*distance_to_nearest_occupied
389
+ elif (method == 'log'):
390
+ this_score = (1 - weight)*abs(numpy.log(distance_to_center)) - \
391
+ weight*abs(numpy.log(distance_to_nearest_occupied))
392
+ if debug:
393
+ print(('the score here : ' + str(this_score) +
394
+ ' oc sites ' + str(occupied_sites_dict)))
395
+ if this_score < score:
396
+ score = this_score
397
+ target_site = indices
398
+ if debug:
399
+ print(('target site is ' + str(indices) + ' at ' +
400
+ str(super_cell.getAtom(indices).coords())))
401
+ elif (len(avail_sites_list) == 1):
402
+ target_site = avail_sites_list[0]
403
+ else:
404
+ emsg = ('error: no free site is possible')
405
+ print(emsg)
406
+ return None
407
+ print(('choosing site ' + str(target_site) + ' at ' +
408
+ str(avail_sites_dict[target_site]) + ' score: ' + str(score) + ' oc sites ' + str(occupied_sites_dict) + '\n'))
409
+ return target_site
410
+ #####################################
411
+
412
+
413
+ def align_payload_to_multi_site(payload, surface_coord_list, cand_list, bind_dist, debug=False):
414
+ # INPUT
415
+ # - payload: mol3D class that contains the molecule to place
416
+ # - align_coord: list of lists of float, positions on surface
417
+ # - cand_mask: list of int, indices of atoms in payload that will be aligned
418
+ # can also contain a string, mask, list of indicies
419
+ # OUPUT
420
+ # - newpay_load: mol3D class with the atom in payload(cand_in) directly above
421
+ # align_coord. )Does NOT change height
422
+
423
+ # Get all atoms on the top surface - NB, this will not handle complex surfaces, split calls by atom type
424
+ # print('align symbol is ' + payload.getAtom(cand_ind).symbol())
425
+ new_payload = mol3D()
426
+ new_payload.copymol3D(payload)
427
+ payload_coord = center_of_sym(
428
+ [new_payload.getAtom(i).coords() for i in cand_list])
429
+ surface_coord = center_of_sym(surface_coord_list)
430
+
431
+ vec1 = vecdiff(surface_coord, payload.centersym())
432
+ vec2 = vecdiff(payload_coord, new_payload.centersym())
433
+ rotate_angle = vecangle(vec1, vec2)
434
+ theta, u = rotation_params(
435
+ payload_coord, new_payload.centersym(), surface_coord)
436
+ if debug:
437
+ print(('\n vec1 is ' + str(vec1)))
438
+ print(('vec2 is ' + str(vec2) + '\n'))
439
+ print(cand_list)
440
+ print(theta)
441
+ print(('angle is ' + str(rotate_angle)))
442
+ print(('normal is ' + str(u)))
443
+ new_payload = rotate_around_axis(
444
+ new_payload, new_payload.centersym(), u, rotate_angle)
445
+ cost = multialign_objective_function(
446
+ new_payload, surface_coord_list, cand_list, bind_dist)
447
+ final_payload = new_payload
448
+
449
+ # need to determine the collinearity of the points are co-plannar
450
+ collinear_flag = False
451
+ coplanar_flag = False
452
+ if len(cand_list) == 2:
453
+ collinear_flag = True
454
+ if len(cand_list) == 3:
455
+ coplanar_flag = True
456
+ collinear_flag = checkcolinear(new_payload.getAtom(cand_list[0]).coords(
457
+ ), new_payload.getAtom(cand_list[1]).coords(), new_payload.getAtom(cand_list[2]).coords())
458
+ elif len(cand_list) == 4:
459
+ pass
460
+ # coplanar_flag = checkplanar(new_payload.getAtom(cand_list[0]),new_payload.getAtom(cand_list[1]),new_payload.getAtom(cand_list[2]),new_payload.getAtom(cand_list[3]).coords())
461
+ new_u = numpy.zeros(3)
462
+ if collinear_flag: # there is a single line defining the axis - align this with
463
+ line_slope = vecdiff(new_payload.getAtom(
464
+ cand_list[0]).coords(), new_payload.getAtom(cand_list[1]).coords())
465
+ print(('collinear case : line ' + str(line_slope)))
466
+ new_u = numpy.cross(line_slope, vecdiff(surface_coord, payload_coord))
467
+ print(('new u is ' + str(new_u)))
468
+ elif coplanar_flag:
469
+ dvec1 = vecdiff(new_payload.getAtom(cand_list[0]).coords(
470
+ ), new_payload.getAtom(cand_list[1]).coords())
471
+ dvec2 = vecdiff(new_payload.getAtom(cand_list[0]).coords(
472
+ ), new_payload.getAtom(cand_list[2]).coords())
473
+ plane_vector = numpy.cross(dvec1, dvec2)
474
+ print(('coplanar case : normal ' + str(plane_vector)))
475
+ new_u = numpy.cross(plane_vector, vecdiff(
476
+ surface_coord, payload_coord))
477
+ print(('new u is ' + str(new_u)))
478
+
479
+ if collinear_flag or coplanar_flag:
480
+ print('starting rotation for coplanar case')
481
+ for rotate_angle in range(-100, 100):
482
+ this_payload = mol3D()
483
+ this_payload.copymol3D(final_payload)
484
+ this_payload = rotate_around_axis(this_payload, this_payload.centersym(
485
+ ), new_u, float(rotate_angle)/10) # fine grained check
486
+ this_cost = multialign_objective_function(
487
+ this_payload, surface_coord_list, cand_list, bind_dist)
488
+ if (this_cost < (cost)):
489
+ # print('current cost = ' + str(this_cost) + ', the max is ' + str(cost))
490
+ if debug:
491
+ print(('accepting rotate at theta = ' + str(rotate_angle)))
492
+ cost = this_cost
493
+ final_payload = this_payload
494
+ print('placement complete')
495
+ return final_payload
496
+
497
+ ##################################
498
+
499
+
500
+ def combine_multi_aligned_payload_with_cell(super_cell, super_cell_vector, payload, cand_list, surface_coord_list, bind_dist, duplicate=False, control_angle=False, align_axis=False, align_ind=False, debug=False):
501
+ # This function does final lowering, rotate and merge of previously aligned molecule with surface
502
+ # Precede all calls to this funciton with allign_payload_to_Site to avoid strange behaviour
503
+ # INPUT
504
+ # - super_cell: mol3D class that contains the super cell
505
+ # - payload: mol3D class that contains that target molecule
506
+ # - payload_ind: int, index of atom in payload that will bind to the surface
507
+ # - align_coord: list of float, coordinates of the target surface site
508
+ # - bind_dist: float, binding distance in A
509
+ # - duplicate: logical, create a negative-z reflection as well?
510
+ # OUPUT
511
+ # - combined_cel: mol3D class, loaded cell
512
+ combined_cell = mol3D()
513
+ combined_cell.copymol3D(super_cell)
514
+ new_payload = mol3D()
515
+ new_payload.copymol3D(payload)
516
+ trial_cell = mol3D()
517
+ trial_cell.copymol3D(combined_cell)
518
+
519
+ ######## DEBUG ONLY #####
520
+ backup_payload = mol3D()
521
+ backup_payload.copymol3D(payload)
522
+ if debug:
523
+ print(('trying to align mol: ' + str(cand_list)))
524
+ print(('and sites ' + str(surface_coord_list)))
525
+
526
+ ##########################
527
+
528
+ extents = find_extents_cv(super_cell_vector)
529
+ # the generalized distance descriptors
530
+ payload_coord = center_of_sym(
531
+ [new_payload.getAtom(i).coords() for i in cand_list])
532
+ surface_coord = center_of_sym(surface_coord_list)
533
+
534
+ vec = vecdiff(surface_coord, payload_coord)
535
+ cost = multialign_objective_function(
536
+ new_payload, surface_coord_list, cand_list, bind_dist)
537
+ final_payload = new_payload
538
+ distances_list = []
539
+ for indices in enumerate(cand_list):
540
+ v1 = (surface_coord_list[indices[0]])
541
+ v2 = final_payload.getAtom(int(indices[1])).coords()
542
+ distances_list.append((distance(v1, v2)))
543
+ if debug:
544
+ print(('\n\n Target distance was ' + str(bind_dist) +
545
+ ', achieved ' + str(distances_list)))
546
+ print(('the cm of sites: ' + str(surface_coord)))
547
+ print(('the cm of mol: ' + str(payload_coord)))
548
+ print(('cost before rotation =' + str(cost)))
549
+ distances_list = []
550
+ for indices in enumerate(cand_list):
551
+ v1 = (surface_coord_list[indices[0]])
552
+ v2 = final_payload.getAtom(int(indices[1])).coords()
553
+ distances_list.append((distance(v1, v2)))
554
+ if debug:
555
+ print(('\n\n Target distance was ' + str(bind_dist) +
556
+ ', achieved ' + str(distances_list)))
557
+
558
+ print('starting align rotation')
559
+ for rotate_angle in range(0, 360):
560
+ this_payload = mol3D()
561
+ this_payload.copymol3D(new_payload)
562
+ this_payload = rotate_around_axis(
563
+ this_payload, this_payload.centersym(), vec, rotate_angle)
564
+ this_cost = multialign_objective_function(
565
+ this_payload, surface_coord_list, cand_list, bind_dist)
566
+ if (this_cost < (cost)):
567
+ cost = this_cost
568
+ final_payload = this_payload
569
+ if debug:
570
+ print(('cost after rotation =' + str(cost)))
571
+ distances_list = []
572
+
573
+ for indices in enumerate(cand_list):
574
+ v1 = (surface_coord_list[indices[0]])
575
+ v2 = final_payload.getAtom(int(indices[1])).coords()
576
+ distances_list.append((distance(v1, v2)))
577
+ if debug:
578
+ print(('\n\n Target distance was ' + str(bind_dist) +
579
+ ', achieved ' + str(distances_list)))
580
+
581
+ # lower into positon
582
+ # step size:
583
+ factor = 0.20
584
+ deltaZ = factor*(distance(payload_coord, surface_coord)-bind_dist)
585
+ this_step_accepted = True
586
+ num_bad_steps = 0
587
+ break_flag = False
588
+ maxits = 250
589
+ its = 0
590
+ while (not break_flag) and (its < maxits):
591
+ its += 1
592
+ if (not this_step_accepted) and (num_bad_steps <= 4):
593
+ factor = 0.1*factor
594
+ elif (not this_step_accepted) and (num_bad_steps > 4):
595
+ break_flag = True
596
+ payload_coord = center_of_sym(
597
+ [final_payload.getAtom(i).coords() for i in cand_list])
598
+ # this will be lowered slowly, then rotate to optimize at each height
599
+ trans_vec = [factor*deltaZ *
600
+ element for element in normalize_vector(vec)]
601
+ this_payload = mol3D()
602
+ this_payload.copymol3D(final_payload)
603
+ this_payload.translate(trans_vec)
604
+ this_cost = multialign_objective_function(
605
+ this_payload, surface_coord_list, cand_list, bind_dist)
606
+ this_dist = min(periodic_mindist(this_payload, combined_cell,
607
+ extents), this_payload.mindist(combined_cell))
608
+ this_coord = center_of_sym(
609
+ [this_payload.getAtom(i).coords() for i in cand_list])
610
+
611
+ this_deltaZ = (distance(this_coord, surface_coord)-bind_dist)
612
+ if debug:
613
+ print(('cost = ' + str(this_cost) + '/' + str(cost) + ' i = ' + str(its) + ' dz = ' + str(deltaZ) +
614
+ ' dist ' + str(this_dist) + ' b step = ' + str(num_bad_steps) + ' nxt dz = ' + str(this_deltaZ)))
615
+ if (this_cost < (cost)) and (this_dist > 0.75) and (deltaZ > 1e-4):
616
+ if debug:
617
+ print(('accepting down shift at i = ' + str(its)))
618
+ cost = this_cost
619
+ del final_payload
620
+ final_payload = mol3D()
621
+ if (this_payload.mindist(combined_cell) < 1.5):
622
+ if debug:
623
+ print(('ff on at iteration ' + str(its)))
624
+ distorted_payload = mol3D()
625
+ distorted_payload.copymol3D(this_payload)
626
+ print('Warning, a force-field relaxation is in progress. For large molecules (Natoms > 50), this may take a few minutes. Please be patient.')
627
+ distorted_payload = force_field_relax_with_slab(
628
+ super_cell, this_payload, cand_list, its)
629
+ if debug:
630
+ print((this_payload.getAtom(0).symbol() + ' at ' + str(this_payload.getAtom(
631
+ cand_list[0]).coords()) + 'target at ' + str(surface_coord_list[0])))
632
+ print((distorted_payload.getAtom(0).symbol() + ' at ' + str(distorted_payload.getAtom(
633
+ cand_list[0]).coords()) + 'target at ' + str(surface_coord_list[0])))
634
+ final_payload.copymol3D(distorted_payload)
635
+ if debug:
636
+ print((final_payload.getAtom(0).symbol() + ' at ' + str(final_payload.getAtom(
637
+ cand_list[0]).coords()) + 'target at ' + str(surface_coord_list[0])))
638
+ else:
639
+ final_payload.copymol3D(this_payload)
640
+ this_step_accepted = True
641
+ factor = min(1.25*factor, 0.8)
642
+ deltaZ = this_deltaZ
643
+ num_bad_steps = 0
644
+ else:
645
+ this_step_accepted = False
646
+ num_bad_steps += 1
647
+ if debug:
648
+ print(('\n\n exit after ' + str(its) + ' iterations'))
649
+ print(('target distance = ' + str(bind_dist) +
650
+ ', average deviation = ' + str(sqrt(cost)/len(cand_list))))
651
+ distances_list = []
652
+ for indices in enumerate(cand_list):
653
+ v1 = (surface_coord_list[indices[0]])
654
+ v2 = final_payload.getAtom(int(indices[1])).coords()
655
+ distances_list.append((distance(v1, v2)))
656
+ if debug:
657
+ print((' Target distance was ' + str(bind_dist) +
658
+ ', achieved ' + str(distances_list)))
659
+ min_dist = final_payload.mindist(combined_cell)
660
+ # now, rotate to maximize spacing, based on mask length
661
+ rotate_on = False
662
+ if len(cand_list) == 1:
663
+ rotate_on = True
664
+ elif len(cand_list) == 2:
665
+ vec = vecdiff(final_payload.getAtom(cand_list[0]).coords(
666
+ ), final_payload.getAtom(cand_list[1]).coords())
667
+ rotate_on = True
668
+
669
+ if rotate_on:
670
+ trial_cell.combine(final_payload)
671
+ trial_cell.writexyz('before_rot.xyz')
672
+ print('starting strain rotation')
673
+ for rotate_angle in range(0, 360):
674
+ this_payload = mol3D()
675
+ this_payload.copymol3D(final_payload)
676
+ payload_coord = center_of_sym(
677
+ [this_payload.getAtom(i).coords() for i in cand_list])
678
+ this_payload = rotate_around_axis(
679
+ this_payload, payload_coord, vec, rotate_angle)
680
+ this_dist = min(periodic_mindist(this_payload, combined_cell, extents), periodic_selfdist(
681
+ this_payload, extents), this_payload.mindist(combined_cell))
682
+ if (this_dist > (min_dist + 1e-3)):
683
+ if debug:
684
+ print(('current dist = ' + str(this_dist) +
685
+ ', the max is ' + str(min_dist)))
686
+ print(('accepting rotate at theta = ' + str(rotate_angle)))
687
+ min_dist = this_dist
688
+ final_payload = this_payload
689
+
690
+ if control_angle:
691
+ print('inner control angle loop')
692
+ if not len(cand_list) == 1:
693
+ print('Warning! Using control angle with more than one payload, reference will only use the FIRST payload reference ')
694
+
695
+ print(('begining controlled rotation, targeting angle ' +
696
+ str(control_angle) + ' to line ' + str(align_axis)))
697
+ print(('aligning payload index ' +
698
+ str(cand_list[0]) + ' and indicies ' + str(align_ind-1) + ' with slab axes '))
699
+ this_payload = mol3D()
700
+ this_payload.copymol3D(final_payload)
701
+
702
+ if debug:
703
+ debug_cell = mol3D()
704
+ debug_cell.copymol3D(combined_cell)
705
+ debug_cell.combine(this_payload)
706
+ this_payload.writexyz('aligned-payload-before-angle-control.xyz')
707
+ debug_cell.writexyz('cell-before-angle-control.xyz')
708
+
709
+ this_payload = axes_angle_align(
710
+ this_payload, cand_list[0], align_ind-1, align_axis, control_angle)
711
+ if debug:
712
+ debug_cell = mol3D()
713
+ debug_cell.copymol3D(combined_cell)
714
+ debug_cell.combine(this_payload)
715
+ this_payload.writexyz('aligned-payload-after-angle-control.xyz')
716
+ debug_cell.writexyz('cell-before-after-control.xyz')
717
+ final_payload = this_payload
718
+
719
+ if len(cand_list) > 1:
720
+ # now, distort molecule based on FF to optimize bond length
721
+ print('\n begining distortion ')
722
+ nsteps = 20
723
+ dfactor = float(1)/nsteps
724
+ trans_vec_list = list()
725
+ distances_list = list()
726
+ # fetch all of the remaining
727
+ for indices in enumerate(cand_list):
728
+ v1 = (surface_coord_list[indices[0]])
729
+ v2 = final_payload.getAtom(int(indices[1])).coords()
730
+ trans_vec_list.append(normalize_vector(vecdiff(v2, v1)))
731
+ distances_list.append(distance(v1, v2) - bind_dist)
732
+ ens = []
733
+ distorted_payload = mol3D()
734
+ distorted_payload.copymol3D(final_payload)
735
+ for ii in range(0, nsteps+1):
736
+ for indices in enumerate(cand_list):
737
+ this_translation = [(-1)*dfactor*distances_list[indices[0]]
738
+ for _ in trans_vec_list[indices[0]]]
739
+ distorted_payload.getAtom(
740
+ int(indices[1])).translate(this_translation)
741
+ distorted_payload, enl = cell_ffopt(
742
+ 'mmff94', distorted_payload, cand_list)
743
+ ens.append(enl)
744
+ this_cost = multialign_objective_function(
745
+ distorted_payload, surface_coord_list, cand_list, bind_dist)
746
+ this_dist = min(periodic_mindist(distorted_payload, combined_cell,
747
+ extents), periodic_selfdist(distorted_payload, extents))
748
+ del distances_list
749
+ distances_list = list()
750
+ for indices in enumerate(cand_list):
751
+ v1 = (surface_coord_list[indices[0]])
752
+ v2 = distorted_payload.getAtom(int(indices[1])).coords()
753
+ distances_list.append((distance(v1, v2) - bind_dist))
754
+ # print(str((abs(ens[-1] - ens[0]) < 5.0)) + str((this_cost < cost)) + str((this_dist >= (min_dist - 0.1))))
755
+
756
+ if (abs(ens[-1] - ens[0]) < 5.0) and (this_cost < cost) and (this_dist >= (min_dist - 0.1)):
757
+ final_payload = distorted_payload
758
+ cost = this_cost
759
+ min_dist = this_dist
760
+ if debug:
761
+ print('accepting distort')
762
+
763
+ distances_list = []
764
+ for indices in enumerate(cand_list):
765
+ v1 = (surface_coord_list[indices[0]])
766
+ v2 = final_payload.getAtom(int(indices[1])).coords()
767
+ distances_list.append((distance(v1, v2)))
768
+
769
+ print(('Target distance was ' + str(bind_dist) +
770
+ ', achieved ' + str(distances_list)))
771
+
772
+ if duplicate:
773
+ second_payload = mol3D()
774
+ second_payload.copymol3D(final_payload)
775
+ xyline = [second_payload.centersym(
776
+ )[0], second_payload.centersym()[1], 0]
777
+ point = [xyline[0], xyline[1], 0*(second_payload.centersym()[2])/2]
778
+ rotate_angle = 180
779
+ second_payload = rotate_around_axis(
780
+ second_payload, point, xyline, rotate_angle)
781
+ second_payload.translate([0, 0, surface_coord[2]])
782
+ final_payload.combine(second_payload)
783
+ min_intercell_d = closest_torus_point(final_payload, extents)
784
+ print(('minimum inter-cell adsorbate self-atom distance is ' + str(min_intercell_d)))
785
+ combined_cell.combine(final_payload)
786
+ return combined_cell
787
+ ###################################
788
+
789
+
790
+ def molecule_placement_supervisor(super_cell, super_cell_vector, target_molecule, method, target_atom_type, align_dist, surface_atom_type=False, control_angle=False, align_ind=False, align_axis=False,
791
+ duplicate=False, number_of_placements=1, coverage=False, weighting_method='linear', weight=0.5, masklength=1, surface_atom_ind=False, debug=False):
792
+ # parse input
793
+ if ((number_of_placements != 1) or coverage) and ((method != 'alignpair') or (control_angle)):
794
+ if not (method == 'alignpair'):
795
+ print(('Multiple placement NOT supported for method ' + method))
796
+ if control_angle:
797
+ print('Cannot support multiple placements and controlled align')
798
+ print(' Setting single placement only')
799
+ number_of_placements = 1
800
+ coverage = False
801
+ if ((control_angle) and not (align_axis)) or ((align_axis) and not (control_angle)):
802
+ print('Cannot control angle and not provide axis or vice-versa')
803
+ print(('control angle is ' + str(control_angle)))
804
+ print(('align_axis is ' + str(align_axis)))
805
+ control_angle = False
806
+ align_axis = False
807
+ if control_angle and not align_ind:
808
+ print('align_ind not found, even though control_angle is on. Disabling controlled rotation')
809
+ control_angle = False
810
+ if (method == 'alignpair') and not (surface_atom_type or surface_atom_ind):
811
+ print('Must provide surface binding atom type to use alignpair')
812
+ print(' using centered placemented instead')
813
+ method = 'center'
814
+ print('\n')
815
+ print(('the method is', method))
816
+ max_sites = 1
817
+ if (method == 'alignpair'): # get all vaccancies
818
+ avail_sites_dict = dict()
819
+ occupied_sites_dict = dict()
820
+ if not surface_atom_ind:
821
+ if debug:
822
+ print(('surface_atom_type', surface_atom_type))
823
+ avail_sites_list = find_all_surface_atoms(
824
+ super_cell, tol=0.75, type_of_atom=surface_atom_type)
825
+ avail_sites_dict = dict()
826
+ for indices in avail_sites_list:
827
+ avail_sites_dict[indices] = super_cell.getAtom(
828
+ indices).coords()
829
+ occupied_sites_dict = dict()
830
+ # calculate max number of sites that need to be filled
831
+ max_sites = int(numpy.floor(
832
+ float(len(list(avail_sites_dict.keys())))/masklength))
833
+ if coverage:
834
+ number_of_placements = int(numpy.ceil(max_sites*coverage))
835
+ print(('Coverage requested = ' + str(coverage)))
836
+ if debug:
837
+ print(('masklengh is ' + str(masklength)))
838
+ if surface_atom_ind:
839
+ print(('using surface_atom_ind' + str(surface_atom_ind)))
840
+ for indices in surface_atom_ind:
841
+ avail_sites_dict[indices] = super_cell.getAtom(
842
+ indices).coords()
843
+ avail_sites_list = [i for i in surface_atom_ind]
844
+ if coverage:
845
+ print('cannot use coverage with surface_atom_ind')
846
+ coverage = False
847
+
848
+ ######## prepare and allocate
849
+ loaded_cell = mol3D()
850
+ loaded_cell.copymol3D(super_cell)
851
+ debug_cell = mol3D()
852
+ debug_cell.copymol3D(loaded_cell)
853
+ # begin actual work
854
+ print('begining the placement loop')
855
+ for placements in range(0, number_of_placements):
856
+ sites_list = list() # list to hod all of the target sites on the surface
857
+ if (method == 'center'):
858
+ align_coord = centered_align_coord(super_cell_vector)
859
+ sites_list.append(align_coord)
860
+ elif (method == 'staggered'):
861
+ align_coord = staggered2_align_coord(super_cell)
862
+ sites_list.append(align_coord)
863
+
864
+ elif (method == 'alignpair'):
865
+ best_site = choose_best_site(avail_sites_dict, occupied_sites_dict, centered_align_coord(
866
+ super_cell_vector), super_cell, super_cell_vector, weight, weighting_method, debug=debug)
867
+ align_coord = super_cell.getAtom(best_site).coords()
868
+ occupied_sites_dict[best_site] = avail_sites_dict.pop(
869
+ best_site) # this transfers the site to occupied
870
+ sites_list.append(align_coord)
871
+ if masklength != 1: # this is if we need multiple sites
872
+ mask_target = align_coord
873
+ for iterates in range(1, masklength):
874
+ if debug:
875
+ print(('in loop for ' + str(iterates)))
876
+ nn_site = choose_nearest_neighbour(
877
+ mask_target, avail_sites_dict, occupied_sites_dict, super_cell, super_cell_vector, debug=False)
878
+ align_coord = super_cell.getAtom(nn_site).coords()
879
+ sites_list.append(align_coord)
880
+ occupied_sites_dict[nn_site] = avail_sites_dict.pop(
881
+ nn_site) # this transfers the site to occupied
882
+ mask_target = center_of_sym(sites_list)
883
+ align_coord = center_of_sym(sites_list)
884
+ if debug:
885
+ print(('oc sites chosen are = ' +
886
+ str(list(occupied_sites_dict.keys()))))
887
+
888
+ else:
889
+ emsg = 'unkown method of molecule placement ' + method
890
+ print(emsg)
891
+ return emsg
892
+ print(('Target for align is ' + str(align_coord)))
893
+ # actual placement
894
+ payload = mol3D()
895
+ payload.copymol3D(target_molecule)
896
+ payload_rad = payload.molsize()
897
+
898
+ trans_vec = vecdiff(align_coord, payload.centersym())
899
+ payload.translate(trans_vec)
900
+ extents = find_extents_cv(super_cell_vector)
901
+ # place far above
902
+ payload.translate([0, 0, extents[2]+1.15*(payload_rad + align_dist)])
903
+
904
+ ###############################
905
+ temp_pay = mol3D()
906
+ temp_pay.copymol3D(payload)
907
+ debug_cell.combine(temp_pay)
908
+
909
+ # find matching atom in payload
910
+ # need to determine if the target is an element or a mask
911
+ globs = globalvars()
912
+ elements = globs.elementsbynum()
913
+ if target_atom_type in elements:
914
+ # find all matches in target
915
+ payload_targets = payload.findAtomsbySymbol(target_atom_type)
916
+ if (len(payload_targets) > 1): # more than 1 option, pick closest to center of plane
917
+ maxd = 1000
918
+ for indices in payload_targets:
919
+ dist = distance(payload.getAtom(indices).coords(), [
920
+ extents[0]/2, extents[1]/2, extents[2]])
921
+ if (dist < maxd):
922
+ cand_ind = indices
923
+ maxd = dist
924
+ elif (len(payload_targets) == 1):
925
+ cand_ind = payload_targets[0]
926
+ else:
927
+ emsg = ('Error: no align of type' + target_atom_type +
928
+ ' is possible. Not found in target. Using atom 0 align')
929
+ cand_ind = 0
930
+ print(emsg)
931
+
932
+ if debug:
933
+ print(('cand _ind = ' + str(cand_ind)))
934
+ cand_list = [cand_ind]
935
+ # [(int(i)-1) for i in cand_ind]
936
+ else:
937
+ cand_ind = target_atom_type
938
+ print('loading from TAT')
939
+ cand_list = [(int(i)-1) for i in cand_ind]
940
+ if debug:
941
+ print(('target molecule mask on ' + str(target_atom_type)))
942
+ print(('candidate list is ' + str(cand_list)))
943
+ # rotate for optimal approach
944
+ payload = align_payload_to_multi_site(
945
+ payload, sites_list, cand_list, align_dist, debug) # align
946
+ if debug:
947
+ payload.writexyz('aligned-payload-before-angle-control.xyz')
948
+
949
+ if debug:
950
+ print(('payload cysm ' + str(payload.centersym())))
951
+
952
+ #######################################
953
+ temp_pay2 = mol3D()
954
+ temp_pay2.copymol3D(payload)
955
+ temp_pay2.translate([0, 0, -5])
956
+ debug_cell.combine(temp_pay2)
957
+ if debug:
958
+ debug_cell.writexyz('db2.xyz')
959
+ # lower payload to distance, rotate to avoid conflicr
960
+ loaded_cell = combine_multi_aligned_payload_with_cell(
961
+ loaded_cell, super_cell_vector, payload, cand_list, sites_list,
962
+ align_dist, duplicate, control_angle, align_axis, align_ind, debug)
963
+
964
+ ########################
965
+ temp_pay3 = mol3D()
966
+ temp_pay3.copymol3D(payload)
967
+ debug_cell.combine(temp_pay3)
968
+ if debug:
969
+ debug_cell.writexyz('db3.xyz')
970
+ temp_pay3.writexyz('db3-only.xyz')
971
+ print(('number of atoms = ' + str(loaded_cell.natoms)))
972
+ # print("\n")
973
+ # run tests
974
+ overlap_flag = loaded_cell.sanitycheck(0)
975
+ if (number_of_placements > 1):
976
+ print(('preparing ' + str(number_of_placements) + ' placements '))
977
+ effectvie_coverage = float(number_of_placements)/float(max_sites)
978
+ print(('giving effectvie coverage of ' + str(effectvie_coverage) + '\n'))
979
+ print(('Is there overalp? ' + str(overlap_flag)))
980
+
981
+ return loaded_cell
982
+
983
+ ###################################
984
+
985
+
986
+ def centered_align_coord(super_cell_vector):
987
+ extents = find_extents_cv(super_cell_vector)
988
+ centroid = [extents[0]/2, extents[1]/2, extents[2]]
989
+ print(('Centroid is at ' + str(centroid)))
990
+ align_coord = centroid
991
+ return align_coord
992
+ ###################################
993
+
994
+
995
+ def staggered2_align_coord(super_cell):
996
+ max_dist = 1000
997
+ avail_sites_list = find_all_surface_atoms(
998
+ super_cell, tol=1e-2, type_of_atom=False)
999
+ close_list = list()
1000
+ extents = find_extents(super_cell)
1001
+ centroid = [extents[0]/2, extents[1]/2, extents[2]]
1002
+ for indices in avail_sites_list:
1003
+ this_dist = distance(centroid, super_cell.getAtom(indices).coords())
1004
+ if (this_dist < (max_dist - 1e-3)):
1005
+ max_dist = this_dist
1006
+ if (len(close_list) > 1):
1007
+ print('subseq')
1008
+ close_list[1] = close_list[0] # save old index
1009
+ close_list[0] = super_cell.getAtom(indices)
1010
+ elif (len(close_list) == 1):
1011
+ print('second atom found')
1012
+ close_list.append(super_cell.getAtom(indices))
1013
+ temp = close_list[0]
1014
+ close_list[0] = close_list[1]
1015
+ close_list[1] = temp
1016
+ elif (len(close_list) == 0):
1017
+ print('first atom found')
1018
+ close_list.append(super_cell.getAtom(indices))
1019
+ align_coord = [
1020
+ sum(x)/2 for x in zip(close_list[0].coords(), close_list[1].coords())]
1021
+ return align_coord # end of stagger
1022
+ ###################################
1023
+
1024
+
1025
+ def axes_angle_align(payload, cand_ind, align_ind, align_target, angle):
1026
+ """This function rotates a given payload molecule such that the X-Y
1027
+ projection of the cord joining the two atoms in cand_ind and align_ind
1028
+ is aligned with the vector given in align_target.
1029
+
1030
+ Parameters
1031
+ ----------
1032
+ payload : mol3D
1033
+ mol3D class that contains that target molecule
1034
+ cand_ind : int
1035
+ index of atom in payload that is used as reference
1036
+ align_ind : int
1037
+ index of atom in payload that define the cord to align
1038
+ align_target : list of 3 float
1039
+ vector on the cell surface to align. Normally z=0
1040
+ angle : float
1041
+ rotation angle
1042
+ Returns
1043
+ -------
1044
+ new_payload: mol3D
1045
+ mol3D class, rotation of payload.
1046
+ """
1047
+ new_payload = mol3D()
1048
+ new_payload.copymol3D(payload)
1049
+ align_chord = vecdiff(new_payload.getAtom(
1050
+ cand_ind).coords(), new_payload.getAtom(align_ind).coords())
1051
+ print(('align coord:' + str(align_chord)))
1052
+ align_chord[2] = 0 # project into X-Y
1053
+ print(('align coord, proj ' + str(align_chord)))
1054
+ print(('align target ' + str(align_target)))
1055
+ normal_vect = numpy.cross(align_chord, align_target)
1056
+ print(('vec angle id ' + str(vecangle(align_chord, align_target))))
1057
+ rotate_angle = vecangle(align_chord, align_target) + angle
1058
+ print(('my angle is ' + str(rotate_angle) + ' nv is ' + str(normal_vect)))
1059
+ # Rotates molecule about axis defined by direction vector and point on axis
1060
+ #
1061
+ # Loops over PointRotateAxis().
1062
+ # @param mol mol3D of molecule to be rotated
1063
+ # @param Rp Reference point along axis
1064
+ # @param u Direction vector of axis
1065
+ # @param theta Angle of rotation in DEGREES
1066
+ # @return mol3D of rotated molecule
1067
+
1068
+ new_payload = rotate_around_axis(new_payload, new_payload.getAtom(
1069
+ cand_ind).coords(), normal_vect, rotate_angle)
1070
+ return new_payload
1071
+ ##########################################
1072
+
1073
+
1074
+ def slab_module_supervisor(args, rootdir):
1075
+ print('******** cell builder on ********')
1076
+ ###################################
1077
+ ###################################
1078
+ ############# INPUT ###############
1079
+ ######### Default values #########
1080
+ # Invocation
1081
+ slab_gen = False
1082
+ place_on_slab = False
1083
+ # Required Input: slab generation
1084
+ unit_cell = False
1085
+ cell_vector = False
1086
+ # OR
1087
+ cif_path = False
1088
+ duplication_vector = False
1089
+ # OR
1090
+ slab_size = False
1091
+ # optional_input
1092
+ miller_index = False
1093
+ # Required Input: placement
1094
+ # target_molecule = False
1095
+ align_distance_method = False
1096
+ # options are "physisorption","chemisorption","custom"
1097
+ align_dist = False # use in conjunction with "custom" above
1098
+ # Optionial Input: placement
1099
+ align_method = 'center'
1100
+ # other options: 'center','staggered', 'alignpair'
1101
+ # for alignpair only:
1102
+ surface_atom_type = False
1103
+ object_align = False
1104
+ num_surface_atoms = 1
1105
+ num_placements = 1
1106
+ coverage = False
1107
+ # multi_placement_centering = 0.95
1108
+ # for surface rotation:
1109
+ control_angle = False
1110
+ angle_control_partner = False
1111
+ angle_surface_axis = False
1112
+
1113
+ # duplication
1114
+ duplicate = False
1115
+
1116
+ # debug
1117
+ debug = False
1118
+
1119
+ # passivate
1120
+ passivate = False
1121
+
1122
+ # freeze layers
1123
+ freeze = False
1124
+
1125
+ # expose a certain atom type
1126
+ expose_type = False
1127
+
1128
+ # shave extra layers
1129
+ shave_extra_layers = False
1130
+
1131
+ # overwrite surface_atom_ind
1132
+ surface_atom_ind = False
1133
+
1134
+ ###### Now attempt input ####
1135
+ import_success = True
1136
+ emsg = list()
1137
+ # multi_placement_centering_overide = False
1138
+ miller_flag = False
1139
+ if (args.slab_gen): # 0
1140
+ slab_gen = True
1141
+ if (args.unit_cell): # 1
1142
+ print('importing unit cell')
1143
+ unit_cell = mol3D()
1144
+ # test if the unit cell is a .xyz file
1145
+ try:
1146
+ ext = os.path.splitext(args.unit_cell)[1]
1147
+ if (ext == '.xyz'):
1148
+ unit_cell.readfromxyz(args.unit_cell)
1149
+ elif (ext == '.mol'):
1150
+ unit_cell.OBmol = unit_cell.getOBmol(args.unit_cell)
1151
+ unit_cell.convert2mol3D()
1152
+ except FileNotFoundError:
1153
+ emsg.append('Unable to import unit cell at ' +
1154
+ str(args.unit_cell))
1155
+ import_success = False
1156
+ if (args.cell_vector): # 2
1157
+ cell_vector = args.cell_vector
1158
+ if (args.cif_path): # 3
1159
+ cif_path = args.cif_path
1160
+ if (args.duplication_vector): # 4
1161
+ duplication_vector = args.duplication_vector
1162
+ if (args.slab_size): # 5
1163
+ slab_size = args.slab_size
1164
+ if (args.miller_index): # 6
1165
+ miller_index = args.miller_index
1166
+ miller_flag = True
1167
+ if (args.freeze): # 7
1168
+ freeze = args.freeze
1169
+ if (args.debug): # 8
1170
+ debug = True
1171
+ if (args.expose_type): # 9
1172
+ expose_type = args.expose_type
1173
+ if (args.shave_extra_layers): # 10
1174
+ shave_extra_layers = args.shave_extra_layers
1175
+ # parse placement options
1176
+ if (args.place_on_slab): # 0
1177
+ place_on_slab = True
1178
+ if (args.target_molecule): # 1
1179
+ target_molecule = mol3D()
1180
+ # test if the unit cell is a .xyz file
1181
+ ext = os.path.splitext(args.target_molecule)[1]
1182
+ try:
1183
+ ext = os.path.splitext(args.target_molecule)[1]
1184
+ if (ext == '.xyz'):
1185
+ target_molecule.readfromxyz(args.target_molecule)
1186
+ elif (ext == '.mol'):
1187
+ target_molecule.OBmol = unit_cell.getOBmol(
1188
+ args.target_molecule)
1189
+ target_molecule.convert2mol3D()
1190
+ except FileNotFoundError:
1191
+ emsg.append('Unable to import target at ' +
1192
+ str(args.target_molecule))
1193
+ import_success = False
1194
+ if (args.align_distance_method): # 2
1195
+ align_distance_method = args.align_distance_method
1196
+ if (args.align_dist): # 3
1197
+ align_dist = args.align_dist
1198
+ if (args.object_align): # 4
1199
+ object_align = args.object_align
1200
+ if (args.align_method): # 5
1201
+ align_method = args.align_method
1202
+ if (args.surface_atom_type): # 6
1203
+ surface_atom_type = args.surface_atom_type
1204
+ if (args.surface_atom_ind): # 7
1205
+ surface_atom_ind = args.surface_atom_ind
1206
+
1207
+ if (args.num_surface_atoms): # 8
1208
+ num_surface_atoms = args.num_surface_atoms
1209
+ if (args.num_placements): # 9
1210
+ num_placements = args.num_placements
1211
+ if (args.coverage): # 10
1212
+ coverage = args.coverage
1213
+ # if (args.multi_placement_centering): # 12
1214
+ # multi_placement_centering = args.multi_placement_centering
1215
+ # multi_placement_centering_overide = True
1216
+ if (args.control_angle): # 13
1217
+ control_angle = args.control_angle
1218
+ if (args.angle_control_partner): # 14
1219
+ angle_control_partner = args.angle_control_partner
1220
+ if (args.angle_surface_axis): # 14
1221
+ angle_surface_axis = args.angle_surface_axis
1222
+ print(('ang_surf_axis ' + str(angle_surface_axis)))
1223
+ if (args.duplicate): # 15
1224
+ duplicate = True
1225
+ # check inputs
1226
+ if slab_gen and not (slab_size or duplication_vector):
1227
+ emsg = "Size of slab required (-slab_size or -duplication_vector)"
1228
+ print(emsg)
1229
+ return emsg
1230
+ if slab_gen and not ((unit_cell and cell_vector) or cif_path):
1231
+ emsg = "Unit cell info required! (-cif_path or -unit_cell and cell_vector)"
1232
+ print(emsg)
1233
+ return emsg
1234
+
1235
+ if not import_success:
1236
+ print(emsg)
1237
+ return emsg
1238
+ # if num_placements > 1 and not multi_placement_centering_overide:
1239
+ # multi_placement_centering = 1 # reccomended for multiple placments
1240
+ if not slab_gen and not place_on_slab:
1241
+ emsg.append(
1242
+ 'Slab builder module not enabled, placement mode not enabled - no action taken ')
1243
+ print(emsg)
1244
+ return emsg
1245
+ if place_on_slab and not target_molecule:
1246
+ emsg.append('Placement requested, but no object given. Skipping')
1247
+ print(emsg)
1248
+ if place_on_slab and not align_dist and (align_distance_method != "chemisorption"):
1249
+ emsg.append('No placement distance given, defaulting to covalent radii')
1250
+ align_distance_method = "chemisorption"
1251
+ print(emsg)
1252
+ if place_on_slab and align_dist and not align_distance_method:
1253
+ print(("using custom align distance of " + str(align_dist)))
1254
+ align_distance_method = "custom"
1255
+ if num_placements > 1 or coverage:
1256
+ weight = 1
1257
+ else:
1258
+ weight = 0.90
1259
+
1260
+ # if args.target_atom_type:
1261
+ # if not args.target_atom_type in elements:
1262
+ # masklength = len(args.target_atom_type)
1263
+ # print("Target masking with length " + str(masklength))
1264
+ # else:
1265
+ # masklength = 1
1266
+ # else:
1267
+ # masklength = 1
1268
+
1269
+ # resolve align distance
1270
+ if align_distance_method == "chemisorption":
1271
+ globs = globalvars()
1272
+ if surface_atom_type in globs.elementsbynum():
1273
+ surf_rad = globs.amass()[surface_atom_type][2]
1274
+ else:
1275
+ surf_rad = 1.5
1276
+ print('unknown surface atom type, using 1.5A as distance')
1277
+ if object_align in globs.elementsbynum():
1278
+ obj_rad = globs.amass()[object_align][2]
1279
+ else:
1280
+ obj_rad = 1.0
1281
+ print('unknown object atom type, using 1.0A as distance')
1282
+ align_dist = obj_rad + surf_rad
1283
+ print(('Chemisorption align distance set to ' + str(align_dist)))
1284
+ if miller_flag:
1285
+ non_zero_indices = list()
1286
+ zero_indices = list()
1287
+ for i in [0, 1, 2]:
1288
+ if not (miller_index[i] == 0):
1289
+ non_zero_indices.append(i)
1290
+ else:
1291
+ zero_indices.append(i)
1292
+
1293
+ # Main calls
1294
+ if slab_gen:
1295
+ print('Generating a new slab...')
1296
+ print(rootdir)
1297
+ if not os.path.exists(rootdir + 'slab'):
1298
+ os.makedirs(rootdir + 'slab')
1299
+
1300
+ if cif_path:
1301
+ print('testing cif')
1302
+ # try:
1303
+ unit_cell, cell_vector = import_from_cif(cif_path)
1304
+ if debug:
1305
+ print('cell vector from cif is')
1306
+ print(cell_vector)
1307
+ # except:
1308
+ # emsg.append('unable to import cif at ' + str(cif_path))
1309
+ # print(emsg)
1310
+ # return emsg
1311
+
1312
+ # testing
1313
+ unit_cell.writexyz(rootdir + 'slab/before_COB.xyz')
1314
+ print('loaded')
1315
+
1316
+ if miller_flag:
1317
+ print(('miller index on ' + str(miller_index) + ' ' + str(miller_flag)))
1318
+ point_coefficients = [get_basis_coefficients(
1319
+ at.coords(), cell_vector) for at in unit_cell.getAtoms()]
1320
+ point_coefficients = threshold_basis(point_coefficients, 1E-6)
1321
+ print('coords in old UC')
1322
+ for j in point_coefficients:
1323
+ print(j)
1324
+ if debug:
1325
+ unit_cell.writexyz(rootdir + 'slab/step_0.xyz')
1326
+ print('\n\n')
1327
+ print('cell vector was ')
1328
+ print((cell_vector[0]))
1329
+ print((cell_vector[1]))
1330
+ print((cell_vector[2]))
1331
+ print('\n**********************\n')
1332
+ v1, v2, v3, angle, u = cut_cell_to_index(
1333
+ unit_cell, cell_vector, miller_index)
1334
+
1335
+ old_cv = cell_vector
1336
+ # change basis of cell to reflect cut, will rotate after gen
1337
+ cell_vector = [v1, v2, v3]
1338
+ new_basis = [v1, v2, v3]
1339
+ print('old basis:')
1340
+ print(old_cv)
1341
+ print('new basis:')
1342
+ print(new_basis)
1343
+ print('\n')
1344
+ point_coefficients = [get_basis_coefficients(
1345
+ at.coords(), new_basis) for at in unit_cell.getAtoms()]
1346
+ point_coefficients = threshold_basis(point_coefficients, 1E-6)
1347
+ print('coords in transformed UC:')
1348
+ print(point_coefficients)
1349
+ # for i in range(0,len(point_coefficients)):
1350
+ # for j in [0,1,2]:
1351
+ # if point_coefficients[i][j]<0:
1352
+ # point_coefficients[i][j] += 1
1353
+ new_coords = [evaluate_basis_coefficients(
1354
+ points, new_basis) for points in point_coefficients]
1355
+ for i, coords in enumerate(new_coords):
1356
+ unit_cell.getAtom(i).setcoords(coords)
1357
+
1358
+ print('coords in final UC:')
1359
+ print(point_coefficients)
1360
+
1361
+ # find out how many units to use
1362
+ max_dims = [numpy.linalg.norm(i) for i in cell_vector]
1363
+ print(('vector norms of actual cell vector are' + str(max_dims)))
1364
+ if slab_size:
1365
+ duplication_vector = [
1366
+ int(numpy.ceil(slab_size[i]/max_dims[i])) for i in [0, 1, 2]]
1367
+ print(('duplication vector set to ' + str(duplication_vector)))
1368
+
1369
+ # keep track of the enlarged cell vector for the slab:
1370
+ ext_duplication_vector = cell_vector
1371
+ ext_duplication_vector = [[i*duplication_vector[0] for i in ext_duplication_vector[0]],
1372
+ [i*duplication_vector[1]
1373
+ for i in ext_duplication_vector[1]],
1374
+ [i*duplication_vector[2] for i in ext_duplication_vector[2]]]
1375
+
1376
+ if miller_index:
1377
+ duplication_vector[2] += 2 # add some extra height to trim off
1378
+ # this is a hack to prevent bumpy bottoms
1379
+ # when duplicating cell vectors were
1380
+ # elements in the top an bottom layes
1381
+ # are bonded/close
1382
+
1383
+ # perfrom duplication
1384
+ ####################################################################
1385
+ super_cell = unit_to_super(unit_cell, cell_vector, duplication_vector)
1386
+ ####################################################################
1387
+
1388
+ if debug:
1389
+ super_cell.writexyz(rootdir + 'slab/after_enlargement.xyz')
1390
+
1391
+ if debug:
1392
+ print('ext_dup vector is: ')
1393
+ print((ext_duplication_vector[0]))
1394
+ print((ext_duplication_vector[1]))
1395
+ print((ext_duplication_vector[2]))
1396
+
1397
+ # lower the cell into the xy plane
1398
+ #############################################################
1399
+ #############################################################
1400
+ if miller_index:
1401
+ print(('rotating angle ' + str(angle) + ' around ' + str(u)))
1402
+ super_cell = rotate_around_axis(super_cell, [0, 0, 0], u, angle)
1403
+ # decoy = rotate_around_axis(decoy,[0,0,0],u,angle)##
1404
+ cell_vector = [PointRotateAxis(u, [0, 0, 0], list(
1405
+ i), numpy.pi*angle/(180)) for i in cell_vector]
1406
+ ext_duplication_vector = [PointRotateAxis(u, [0, 0, 0], list(
1407
+ i), numpy.pi*angle/(180)) for i in ext_duplication_vector]
1408
+ # threshold:
1409
+ cell_vector = threshold_basis(cell_vector, 1E-6)
1410
+ ext_duplication_vector = threshold_basis(
1411
+ ext_duplication_vector, 1E-6)
1412
+ #############################################################
1413
+
1414
+ if debug:
1415
+ print('cell vector is: ')
1416
+ print((cell_vector[0]))
1417
+ print((cell_vector[1]))
1418
+ print((cell_vector[2]))
1419
+ print('ext_dup vector is: ')
1420
+ print((ext_duplication_vector[0]))
1421
+ print((ext_duplication_vector[1]))
1422
+ print((ext_duplication_vector[2]))
1423
+ super_cell.writexyz(rootdir + 'slab/after_rotate.xyz')
1424
+
1425
+ if miller_index: # get rid of the extra padding we added:
1426
+ super_cell = shave_under_layer(super_cell)
1427
+ super_cell = shave_under_layer(super_cell)
1428
+ super_cell = shave_under_layer(super_cell)
1429
+ super_cell = shave_surface_layer(super_cell)
1430
+ super_cell = shave_surface_layer(super_cell)
1431
+ super_cell = zero_z(super_cell)
1432
+ if debug:
1433
+ super_cell.writexyz(rootdir + 'slab/after_millercut.xyz')
1434
+
1435
+ # check angle between v1 and x for aligining nicely
1436
+ angle = -1*vecangle(cell_vector[0], [1, 0, 0])
1437
+ if debug:
1438
+ print(('x-axis angle is ' + str(angle)))
1439
+ if abs(angle) > 5 and False:
1440
+ print(('angle is ' + str(angle)))
1441
+ u = [0, 0, 1]
1442
+ print('aligning with x-axis')
1443
+ print(('rotating angle ' + str(angle) + ' around ' + str(u)))
1444
+ super_cell = rotate_around_axis(super_cell, [0, 0, 0], u, angle)
1445
+ super_cell.writexyz(rootdir + 'slab/after_x_align.xyz')
1446
+ cell_vector = [PointRotateAxis(u, [0, 0, 0], list(
1447
+ i), numpy.pi*angle/(180)) for i in cell_vector]
1448
+ ext_duplication_vector = [PointRotateAxis(u, [0, 0, 0], list(
1449
+ i), numpy.pi*angle/(180)) for i in ext_duplication_vector]
1450
+ # threshold:
1451
+ cell_vector = threshold_basis(cell_vector, 1E-6)
1452
+ ext_duplication_vector = threshold_basis(
1453
+ ext_duplication_vector, 1E-6)
1454
+
1455
+ stop_flag = False
1456
+ if slab_size:
1457
+ counter = 0
1458
+ while not stop_flag:
1459
+ counter += 1
1460
+ zmax = 0
1461
+ for atoms in super_cell.getAtoms():
1462
+ coords = atoms.coords()
1463
+ if (coords[2] > zmax):
1464
+ zmax = coords[2]
1465
+ if (zmax <= 1.1*slab_size[2]):
1466
+ stop_flag = True
1467
+ else:
1468
+ if debug:
1469
+ print('cutting due to zmax')
1470
+ super_cell = shave_surface_layer(super_cell)
1471
+ if counter > 20:
1472
+ print('stopping after 10 cuts, zmax not obtained')
1473
+ stop_flag = True
1474
+ if debug:
1475
+ super_cell.writexyz(rootdir + 'slab/after_size_control.xyz')
1476
+ # measure and recored slab vectors
1477
+ super_cell_vector = copy.copy(ext_duplication_vector)
1478
+
1479
+ # check if passivation needed
1480
+ if passivate:
1481
+ pass # not implemented
1482
+ # check if atoms should be frozen
1483
+ if freeze:
1484
+ if isinstance(freeze, int):
1485
+ print('freezing')
1486
+ super_cell = freeze_bottom_n_layers(super_cell, freeze)
1487
+ else:
1488
+ super_cell = freeze_bottom_n_layers(super_cell, 1)
1489
+
1490
+ # check if a different surface atom should be exposed:
1491
+ if expose_type:
1492
+ super_cell = check_top_layer_correct(super_cell, expose_type)
1493
+ if shave_extra_layers:
1494
+ for i in range(0, int(shave_extra_layers)):
1495
+ print(('shaving ' + str(shave_extra_layers) + ' layers'))
1496
+ super_cell = shave_surface_layer(super_cell, TOL=1e-2)
1497
+
1498
+ # move in all negative positions
1499
+ # if all(super_cell_vector[0]) <= 0: ## all signs are the same:
1500
+ # super_cell_vector[0] = [-1*i for i in super_cell_vector[0]]
1501
+ point_coefficients = [get_basis_coefficients(
1502
+ at.coords(), super_cell_vector) for at in super_cell.getAtoms()]
1503
+ # print('coords in final slab:' )
1504
+ # print(point_coefficients)
1505
+ point_coefficients = threshold_basis(point_coefficients, 1E-6)
1506
+ # for i in range(0,len(point_coefficients)):
1507
+ # for j in [0,1,2]:
1508
+ # if point_coefficients[i][j]<0:
1509
+ # point_coefficients[i][j] += 1
1510
+ # if point_coefficients[i][j] >1:
1511
+ # point_coefficients[i][j] -= 1
1512
+ new_coords = [evaluate_basis_coefficients(
1513
+ points, super_cell_vector) for points in point_coefficients]
1514
+
1515
+ # for j,points in enumerate(point_coefficients):
1516
+ # if min(new_coords[i])<0:
1517
+ # try shift one cv in each direction:
1518
+ # potential_new_point = []
1519
+
1520
+ for i, coords in enumerate(new_coords):
1521
+ super_cell.getAtom(i).setcoords(coords)
1522
+ # point_coefficients = [get_basis_coefficients(at.coords(),super_cell_vector) for at in super_cell.getAtoms()]
1523
+ print('coords in final slab:')
1524
+ print(point_coefficients)
1525
+ ######
1526
+ rest = super_cell.sanitycheck(silence=False)
1527
+ print(('result of collision check is ' + str(rest)))
1528
+
1529
+ #################################
1530
+ # write slab output
1531
+ super_cell.writexyz(rootdir + 'slab/super' +
1532
+ ''.join([str(i) for i in duplication_vector])+'.xyz')
1533
+ print(('\n Created a supercell in ' + str(rootdir) + '\n'))
1534
+
1535
+ # let's check if the periodicity is correct
1536
+ super_duper_cell = unit_to_super(super_cell, cell_vector, [2, 2, 1])
1537
+ super_duper_cell.writexyz(rootdir + 'slab/SD.xyz')
1538
+
1539
+ # get some vapourspace
1540
+ final_cv = copy.deepcopy(super_cell_vector)
1541
+ final_cv[2][2] = float(final_cv[2][2]) + 20
1542
+ print('final cell vector, inc vapour space is :')
1543
+ print(final_cv)
1544
+ write_periodic_mol3d_to_qe(
1545
+ super_cell, final_cv, rootdir + 'slab/slab.in')
1546
+ elif not slab_gen: # placement only, skip slabbing!
1547
+ super_cell = unit_cell
1548
+ super_cell_vector = cell_vector
1549
+
1550
+ if place_on_slab:
1551
+ if slab_gen:
1552
+ print(
1553
+ '\n\n ************************ starting placement ***************** \n\n')
1554
+ # Whoever started this obviously has not finished this part of the implementation:
1555
+ # Variables needed in the next few lines, such as new_dup_vector are not assigned...
1556
+ raise NotImplementedError()
1557
+ if not slab_gen:
1558
+ print(
1559
+ '\n\n ************************ placement on existing slab ***************** \n\n')
1560
+ new_dup_vector = cell_vector
1561
+ super_cell_vector = cell_vector
1562
+ print('this supercell vector is:')
1563
+ print(super_cell_vector)
1564
+
1565
+ if control_angle:
1566
+ print('control angle on')
1567
+ print(angle_surface_axis)
1568
+ angle_surface_axis.append(0)
1569
+ print(angle_surface_axis)
1570
+
1571
+ print(('object_align ' + str(object_align)))
1572
+ loaded_cell = molecule_placement_supervisor(super_cell, super_cell_vector, target_molecule,
1573
+ align_method, object_align, align_dist, surface_atom_type,
1574
+ control_angle=control_angle, align_ind=angle_control_partner, align_axis=angle_surface_axis,
1575
+ duplicate=duplicate, number_of_placements=num_placements, coverage=coverage,
1576
+ weighting_method='linear', weight=weight, masklength=num_surface_atoms, surface_atom_ind=surface_atom_ind, debug=debug)
1577
+ if not os.path.exists(rootdir + 'loaded_slab'):
1578
+ os.makedirs(rootdir + 'loaded_slab')
1579
+ if freeze and not slab_gen: # freezing happens at gen time
1580
+ if isinstance(freeze, int):
1581
+ print('freezing')
1582
+ loaded_cell = freeze_bottom_n_layers(loaded_cell, freeze)
1583
+ else:
1584
+ loaded_cell = freeze_bottom_n_layers(loaded_cell, 1)
1585
+
1586
+ loaded_cell.writexyz(rootdir + 'loaded_slab/loaded.xyz')
1587
+ super_duper_cell = unit_to_super(
1588
+ loaded_cell, new_dup_vector, [2, 2, 1])
1589
+
1590
+ super_duper_cell.writexyz(rootdir + 'loaded_slab/SD.xyz')
1591
+ write_periodic_mol3d_to_qe(
1592
+ loaded_cell, new_dup_vector, rootdir + 'loaded_slab/loaded_slab.in')