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,2493 @@
1
+ # @file mGUI.py
2
+ # Contains main GUI class and routines.
3
+ #
4
+ # Written by Tim Ioannidis for HJK Group
5
+ #
6
+ # Modified by JP Janet
7
+ #
8
+ # Dpt of Chemical Engineering, MIT
9
+
10
+ from PyQt5.QtCore import Qt, QSize
11
+ from PyQt5.QtWidgets import (QWidget, QGridLayout, QStackedLayout, QAction,
12
+ QFileDialog, QMessageBox, QPushButton,
13
+ QDesktopWidget)
14
+ from PyQt5.QtGui import QPalette, QFont, QIcon
15
+ from molSimplify.Classes.mWidgets import (mQMainWindow, mQPixmap, mQLabel,
16
+ mQLineEdit, mQLineEditL, mQTextEdit,
17
+ mQCheckBox, mQComboBox, mQSpinBox,
18
+ mQPushButton, mQSlider, mQDialogWarn,
19
+ mSvgWidget, relresize, center)
20
+ from molSimplify.Classes.globalvars import globalvars, mybash
21
+ from molSimplify.Scripts.generator import startgen
22
+ from molSimplify.Scripts.grabguivars import (grabguivars, grabguivarsqch,
23
+ grabguivarstc, grabguivarsgam,
24
+ grabguivarsjob, grabguivarsP,
25
+ grabdbguivars, loadfrominputfile,
26
+ loadfrominputtc, loadfrominputgam,
27
+ loadfrominputqch, writeinputc,
28
+ loadfrominputjob)
29
+ from molSimplify.Scripts.io import (readdict, getgeoms, getcores, getmcores,
30
+ getbcores, getlicores, getslicores,
31
+ getligs, getbinds, getligroups,
32
+ lig_load, copy_to_custom_path)
33
+ from molSimplify.Scripts.addtodb import (addtoldb, addtocdb, addtobdb,
34
+ removefromDB)
35
+ import sys
36
+ import os
37
+ import shutil
38
+ import unicodedata
39
+ import glob
40
+ import tempfile
41
+ import re
42
+ from importlib_resources import files as resource_files
43
+ import xml.etree.ElementTree as ET
44
+
45
+ try:
46
+ from openbabel import openbabel # version 3 style import
47
+ except ImportError:
48
+ import openbabel # fallback to version 2
49
+
50
+ # Main GUI class
51
+
52
+
53
+ class mGUI():
54
+ getgeoms()
55
+
56
+ def __init__(self, app):
57
+ # build gui
58
+ self.app = app
59
+ self.initGUI(app)
60
+ cwd = os.getcwd()
61
+ globs = globalvars() # global variables
62
+ globs.rundir = os.path.join(cwd, 'Runs')
63
+ if not os.path.exists(globs.rundir):
64
+ print((globs.rundir))
65
+ os.makedirs(globs.rundir)
66
+ # builds the gui
67
+
68
+ def initGUI(self, app):
69
+ '''
70
+ ######################
71
+ ### build main GUI ###
72
+ ######################
73
+ '''
74
+ # ## check for configuration file ###
75
+ cwd = os.getcwd()
76
+ globs = globalvars() # global variables
77
+ globs.rundir = os.path.join(cwd, 'Runs')
78
+ if not os.path.exists(globs.rundir):
79
+ os.makedirs(globs.rundir)
80
+ # overX = True if 'localhost' in os.environ['DISPLAY'].lower() else False # detect running over X
81
+ # configfile = False if not glob.glob(homedir+'/.molSimplify') else True
82
+ # if not configfile:
83
+ # self.wwindow = mQMainWindow()
84
+ # self.wwindow.resize(0.5,0.5)
85
+ # QMessageBox.information(self.wwindow, 'Setup', 'It looks like the '
86
+ # 'configuration file "~/.molSimplify" does '
87
+ # 'not exist!Please follow the next steps to '
88
+ # 'configure the file.')
89
+ # QMessageBox.information(self.wwindow, 'Installation directory',
90
+ # "Please select the top installation "
91
+ # "directory for the program.")
92
+ # instdir = QFileDialog.getExistingDirectory(self.wwindow, "Select Directory")
93
+ # f = open(homedir+'/.molSimplify','w')
94
+ # if len(instdir) > 1:
95
+ # f.write("INSTALLDIR="+instdir+'\n')
96
+ # ## end set-up configuration file ###
97
+ # main window widget
98
+ self.wmwindow = mQMainWindow()
99
+ self.wmwindow.show()
100
+ self.wmain = QWidget()
101
+ self.wmwindow.setWindowTitle("molSimplify")
102
+ self.wmwindow.setMinimumSize(1000, 700)
103
+ # set background color
104
+ p = QPalette()
105
+ p.setColor(QPalette.Background, Qt.white)
106
+ self.wmwindow.setPalette(p)
107
+ # ## main grid layout ###
108
+ self.grid = QGridLayout()
109
+ # ## stacked layouts ###
110
+ self.sgrid = QStackedLayout()
111
+ self.sgrid.setStackingMode(1)
112
+ self.sgrid.addWidget(self.wmain)
113
+ # set manually size of rows/columns
114
+ self.grid.setRowMinimumHeight(0, 15)
115
+ self.grid.setRowMinimumHeight(2, 90)
116
+ self.grid.setRowMinimumHeight(3, 15)
117
+ self.grid.setRowMinimumHeight(4, 50)
118
+ ####################################
119
+ # ## create menubar and callbacks ###
120
+ menubar = self.wmwindow.menuBar()
121
+ menu0 = menubar.addMenu('&File')
122
+ menu1 = menubar.addMenu('&Load')
123
+ menu2 = menubar.addMenu('&Help')
124
+ exitAction = QAction('&Exit', self.wmwindow)
125
+ exitAction.setShortcut('Ctrl+Q')
126
+ exitAction.setStatusTip('Exit application')
127
+ exitAction.triggered.connect(self.qexit)
128
+ menu0.addAction(exitAction)
129
+ saveAction = QAction('&Save As..', self.wmwindow)
130
+ saveAction.setShortcut('Ctrl+S')
131
+ saveAction.setStatusTip('Save current input settings')
132
+ saveAction.triggered.connect(self.qsaveinput)
133
+ menu0.addAction(saveAction)
134
+ loadAction = QAction('&Load', self.wmwindow)
135
+ loadAction.setShortcut('Ctrl+O')
136
+ loadAction.setStatusTip('Load input file')
137
+ loadAction.triggered.connect(self.qloadinput)
138
+ menu1.addAction(loadAction)
139
+ helpAction = QAction('&About', self.wmwindow)
140
+ helpAction.setShortcut('Ctrl+H')
141
+ helpAction.setStatusTip('Show program information')
142
+ helpAction.triggered.connect(self.qshowhelp)
143
+ menu2.addAction(helpAction)
144
+ # ## place title top ###
145
+ f = resource_files("molSimplify").joinpath("icons/logo.png")
146
+ clogo = mQPixmap(f)
147
+ self.grid.addWidget(clogo, 2, 8, 1, 10)
148
+ self.txtdev = mQLabel('Developed by Kulik group @ MIT', '', 'c', 16)
149
+ self.grid.addWidget(self.txtdev, 19, 8, 2, 10)
150
+ # ##################################################
151
+ # ##################################################
152
+ # ######### STRUCTURE GENERATION INPUTS ############
153
+ # ##################################################
154
+ # ##################################################
155
+ # ## title ###
156
+ self.txtgpar = mQLabel('Structure specification', '', 'c', 20)
157
+ self.grid.addWidget(self.txtgpar, 4, 0, 2, 14)
158
+ # ## core structure specification ###
159
+ ctip = 'Core of structure'
160
+ self.rtcore = mQLabel('Core:', ctip, 'C', 12)
161
+ f = QFont("Helvetica", 14, 75)
162
+ self.rtcore.setFont(f)
163
+ self.grid.addWidget(self.rtcore, 7, 2, 1, 1)
164
+ cores = list(sorted(getmcores()))
165
+ self.etcore = mQLineEditL('', ctip, 'l', 12, cores)
166
+ self.grid.addWidget(self.etcore, 7, 3, 1, 3)
167
+ # ## Connection atoms for core ###
168
+ ctip = 'Specify connection atoms for core if using SMILES or custom cores (default: 1)'
169
+ self.rtccat = mQLabel('Core connections:', ctip, 'C', 12)
170
+ self.rtccat.setWordWrap(True)
171
+ self.grid.addWidget(self.rtccat, 7, 6, 1, 2)
172
+ self.etccat = mQLineEdit('', ctip, 'l', 12)
173
+ self.grid.addWidget(self.etccat, 7, 8, 1, 2)
174
+ # ## replace option ###
175
+ ctip = 'Replace ligand at specified connection point'
176
+ self.replig = mQCheckBox('replace', ctip, 12)
177
+ self.grid.addWidget(self.replig, 7, 10, 1, 4)
178
+ # coordination
179
+ ctip = 'Number of ligands connected to the metal.'
180
+ self.rcoord = mQLabel('Coordination:', ctip, 'Cr', 12)
181
+ self.grid.addWidget(self.rcoord, 8, 2, 1, 2)
182
+ coords, geomnames, geomshorts, geomgroups = getgeoms()
183
+ qcav = sorted(list(set(coords)))
184
+ self.dcoord = mQComboBox(qcav, ctip, 12)
185
+ self.dcoord.setCurrentIndex(5)
186
+ self.dcoord.currentIndexChanged.connect(self.matchgeomcoord)
187
+ self.grid.addWidget(self.dcoord, 8, 4, 1, 1)
188
+ # geometry of coordination
189
+ self.dcoordg = mQComboBox('', '', 12)
190
+ self.dcoordg.setCurrentIndex(0)
191
+ self.matchgeomcoord()
192
+ self.grid.addWidget(self.dcoordg, 8, 5, 1, 2)
193
+ # add new coordination
194
+ ctip = 'Add geometry'
195
+ self.butaddg = mQPushButton('Add\ngeometry', ctip, 12)
196
+ self.butaddg.clicked.connect(self.addgeom)
197
+ self.grid.addWidget(self.butaddg, 8, 7, 1, 2)
198
+ # add new coordination
199
+ ctip = 'View geometry with atom labels'
200
+ self.butvg = mQPushButton('View\ngeometry', ctip, 12)
201
+ self.butvg.clicked.connect(self.viewgeom)
202
+ self.grid.addWidget(self.butvg, 8, 9, 1, 2)
203
+ # ############################################
204
+ # ################# LIGANDS ##################
205
+ # ## ligands tables ###
206
+ ctip0 = 'Ligand(s) to be used'
207
+ self.rtligh = mQLabel('Ligand', ctip0, 'c', 12) # ligand header
208
+ f = QFont("Helvetica", 12, 75)
209
+ self.rtligh.setFont(f)
210
+ ctip1 = 'Occurrence of corresponding ligand(s)'
211
+ self.rtligocch = mQLabel(
212
+ 'Frequency', ctip1, 'c', 12) # occurrence header
213
+ ctip2 = 'Connection atom(s) of ligands (default: 1).'
214
+ # connection atom header
215
+ self.rtsmicath = mQLabel('Connections', ctip2, 'c', 12)
216
+ # keep Hs header
217
+ ctip3 = 'Do not remove hydrogens while connecting ligand to core. default True'
218
+ self.keepHh = mQLabel('keep\nHs', ctip3, 'c', 12) # occurrence header
219
+ ctip4 = 'Custom bond length for M-L in Angstrom'
220
+ # custom metal ligand bond length header
221
+ self.MLbondsh = mQLabel('M-L\nbond', ctip4, 'c', 12)
222
+ ctip5 = 'Custom angles for connection points (polar theta, azimuthal phi) in degrees separated with /. e.g 10/20'
223
+ # custom angles for distortion header
224
+ self.canglesh = mQLabel('Angle', ctip5, 'c', 12)
225
+ ctip6 = 'Name of ligand'
226
+ # name of ligand header
227
+ self.nameligh = mQLabel('Name', ctip6, 'c', 12)
228
+ ctip7 = 'Force ligand order and disable smart reordering'
229
+ self.ligfloc = mQCheckBox('Force location', ctip7, 12)
230
+ ctip8 = 'Ligand smart alignment. Aligns first the bulky ligands.'
231
+ self.ligfalign = mQCheckBox('Smart alignment', ctip8, 12)
232
+ self.ligfalign.setChecked(True)
233
+ # add to layout
234
+ self.grid.setColumnMinimumWidth(0, 150)
235
+ self.grid.addWidget(self.rtligh, 9, 0, 1, 2)
236
+ self.grid.addWidget(self.rtligocch, 9, 2, 1, 2)
237
+ self.grid.addWidget(self.rtsmicath, 9, 4, 1, 2)
238
+ self.grid.addWidget(self.keepHh, 9, 6, 1, 1)
239
+ self.grid.addWidget(self.MLbondsh, 9, 7, 1, 2)
240
+ self.grid.addWidget(self.canglesh, 9, 9, 1, 1)
241
+ self.grid.addWidget(self.nameligh, 9, 10, 1, 1)
242
+ self.grid.addWidget(self.ligfalign, 13, 15, 1, 2)
243
+ self.grid.addWidget(self.ligfloc, 13, 17, 1, 2)
244
+ # ligands #
245
+ licores = list(sorted(getlicores()))
246
+ self.lig = []
247
+ self.ligocc = []
248
+ self.ligconn = []
249
+ self.ligH = []
250
+ self.ligML = []
251
+ self.ligan = []
252
+ self.lignam = []
253
+ self.ligadd = []
254
+ for ii in range(0, 8):
255
+ # ligands #
256
+ self.lig.append(mQLineEditL('', ctip0, 'l', 12, licores))
257
+ self.grid.addWidget(self.lig[ii], 10+ii, 0, 1, 2) # add to layout
258
+ # occurrences #
259
+ self.ligocc.append(mQSpinBox(ctip1))
260
+ self.grid.addWidget(self.ligocc[ii], 10+ii, 2, 1, 2)
261
+ # connections #
262
+ self.ligconn.append(mQLineEdit('', ctip2, 'l', 12))
263
+ self.grid.addWidget(self.ligconn[ii], 10+ii, 4, 1, 2)
264
+ # keep Hydrogens #
265
+ self.ligH.append(mQComboBox(['yes', 'no'], ctip3, 12))
266
+ self.grid.addWidget(self.ligH[ii], 10+ii, 6, 1, 1)
267
+ # ML bond lengths #
268
+ self.ligML.append(mQLineEdit('', ctip4, 'l', 12))
269
+ self.grid.addWidget(self.ligML[ii], 10+ii, 7, 1, 2)
270
+ # custom angles #
271
+ self.ligan.append(mQLineEdit('', ctip5, 'l', 12))
272
+ self.grid.addWidget(self.ligan[ii], 10+ii, 9, 1, 1)
273
+ # ligand names #
274
+ self.lignam.append(mQLineEdit('', ctip6, 'l', 12))
275
+ self.grid.addWidget(self.lignam[ii], 10+ii, 10, 1, 1)
276
+ # ligand buttons #
277
+ if ii < 7:
278
+ ctip = 'Add new ligand.'
279
+ self.ligadd.append(mQPushButton('+', ctip, 12))
280
+ self.grid.addWidget(self.ligadd[ii], 10+ii, 13, 1, 1)
281
+ self.ligadd[ii].setDisabled(True)
282
+ self.ligadd[ii].hide()
283
+ if ii > 0:
284
+ self.lig[ii].setDisabled(True) # disable
285
+ self.ligocc[ii].setDisabled(True)
286
+ self.ligconn[ii].setDisabled(True)
287
+ self.ligH[ii].setDisabled(True)
288
+ self.ligML[ii].setDisabled(True)
289
+ self.ligan[ii].setDisabled(True)
290
+ self.lignam[ii].setDisabled(True)
291
+ self.ligadd[0].setDisabled(False)
292
+ self.ligadd[0].show()
293
+ # callbacks
294
+ self.ligadd[0].clicked.connect(self.addlig0) # callback
295
+ self.ligadd[1].clicked.connect(self.addlig1) # callback
296
+ self.ligadd[2].clicked.connect(self.addlig2) # callback
297
+ self.ligadd[3].clicked.connect(self.addlig3) # callback
298
+ self.ligadd[4].clicked.connect(self.addlig4) # callback
299
+ self.ligadd[5].clicked.connect(self.addlig5) # callback
300
+ self.ligadd[6].clicked.connect(self.addlig6) # callback
301
+ #############################################
302
+ # List molecules #
303
+ ctip = 'Generate 2D ligand representation.'
304
+ self.butList = mQPushButton('List molecules', ctip, 12)
305
+ self.butList.clicked.connect(self.listmols)
306
+ self.grid.addWidget(self.butList, 18, 3, 1, 2)
307
+ # Draw ligand button #
308
+ ctip = 'Generate 2D ligand representation.'
309
+ self.butDrl = mQPushButton('Draw ligands', ctip, 12)
310
+ self.butDrl.clicked.connect(self.drawligs_svg)
311
+ self.grid.addWidget(self.butDrl, 18, 1, 1, 2)
312
+ # Local database button #
313
+ ctip = 'Add core/ligand/binding species to local database.'
314
+ self.butADB = mQPushButton('Add to local DB', ctip, 12)
315
+ self.butADB.clicked.connect(self.enableDB)
316
+ self.grid.addWidget(self.butADB, 18, 5, 1, 3)
317
+ # #################################################
318
+ # #################################################
319
+ # ########## GENERAL PARAMETERS INPUTS ############
320
+ # #################################################
321
+ # #################################################
322
+ self.txtgp = mQLabel('General parameters', '', 'c', 20)
323
+ self.grid.addWidget(self.txtgp, 4, 13, 2, 8)
324
+ # random generation
325
+ ctip = 'Enable random generation.'
326
+ self.randomchk = mQCheckBox('Random generation', ctip, 12)
327
+ self.randomchk.stateChanged.connect(self.enablerandom)
328
+ self.grid.addWidget(self.randomchk, 7, 15, 1, 2)
329
+ # charge calculation
330
+ ctip = 'Calculate charge based on ox state and ligands'
331
+ self.chch = mQCheckBox('Calculate\ncharge', ctip, 12)
332
+ self.chch.setDisabled(True)
333
+ self.grid.addWidget(self.chch, 7, 17, 1, 1)
334
+ # keep Hs
335
+ ctip = 'Keep hydrogens for random generation.'
336
+ self.randkHs = mQCheckBox('Keep\nHs', ctip, 12)
337
+ self.grid.addWidget(self.randkHs, 7, 18, 1, 1)
338
+ self.randkHs.setDisabled(True)
339
+ # number of random generated structures
340
+ ctip = 'Number of structures to be randomly generated.'
341
+ self.rtrgen = mQLabel('Structures:', ctip, 'Cr', 12)
342
+ self.etrgen = mQLineEdit('', ctip, 'l', 12)
343
+ self.grid.addWidget(self.rtrgen, 8, 15, 1, 1)
344
+ self.grid.addWidget(self.etrgen, 8, 16, 1, 1)
345
+ self.rtrgen.setDisabled(True)
346
+ self.etrgen.setDisabled(True)
347
+ # number of different ligands to use
348
+ ctip = 'For random generation: total number of different ligands including specified ones.'
349
+ self.rtlignum = mQLabel('Different\nligands:', ctip, 'Cr', 12)
350
+ qcav = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10']
351
+ self.etlignum = mQComboBox(qcav, ctip, 12)
352
+ self.grid.addWidget(self.rtlignum, 8, 17, 1, 1)
353
+ self.grid.addWidget(self.etlignum, 8, 18, 1, 1)
354
+ self.rtlignum.setDisabled(True)
355
+ self.etlignum.setDisabled(True)
356
+ # group of different ligands
357
+ ctip = 'For random generation: select random ligands from group.'
358
+ self.rtliggrp = mQLabel('Ligand\ngroup:', ctip, 'Cr', 12)
359
+ cwd = os.getcwd()
360
+ globs = globalvars()
361
+ globs.rundir = os.path.join(cwd, 'Runs')
362
+ if globs.custom_path:
363
+ f = globs.custom_path + "/Ligands/ligands.dict"
364
+ else:
365
+ f = str(resource_files("molSimplify").joinpath("Ligands/ligands.dict"))
366
+ qcav0 = getligroups(readdict(f))
367
+ qcav = [_f for _f in qcav0.split(' ') if _f]
368
+ self.etliggrp = mQComboBox(qcav, ctip, 12)
369
+ self.grid.addWidget(self.rtliggrp, 9, 15, 1, 1)
370
+ self.grid.addWidget(self.etliggrp, 9, 16, 1, 1)
371
+ self.rtliggrp.setDisabled(True)
372
+ self.etliggrp.setDisabled(True)
373
+ # ligand category
374
+ ctip = 'For random generation: select random ligands from category.\nOptions are all'
375
+ ctip += '"build" for building complexes, "functionalize" for functionalizing'
376
+ self.rtligctg = mQLabel('Ligand\ncategory:', ctip, 'Cr', 12)
377
+ qcav = ['all', 'build', 'functionalize']
378
+ self.etligctg = mQComboBox(qcav, ctip, 12)
379
+ self.grid.addWidget(self.rtligctg, 9, 17, 1, 1)
380
+ self.grid.addWidget(self.etligctg, 9, 18, 1, 1)
381
+ self.rtligctg.setDisabled(True)
382
+ self.etligctg.setDisabled(True)
383
+ # oxidation state
384
+ ctip = 'Metal Oxidation state'
385
+ self.roxstate = mQLabel('Ox State:', ctip, 'Cr', 12)
386
+ qcav = ['0', 'I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII']
387
+ self.doxs = mQComboBox(qcav, ctip, 12)
388
+ self.doxs.setCurrentIndex(0)
389
+ self.grid.addWidget(self.roxstate, 10, 15, 1, 1)
390
+ self.grid.addWidget(self.doxs, 10, 16, 1, 1)
391
+ # spin state
392
+ ctip = 'System spin multiplicity'
393
+ self.rspstate = mQLabel('Spin:', ctip, 'Cr', 12)
394
+ qcav = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10']
395
+ self.dspin = mQComboBox(qcav, ctip, 12)
396
+ self.dspin.setCurrentIndex(0)
397
+ self.grid.addWidget(self.rspstate, 10, 17, 1, 1)
398
+ self.grid.addWidget(self.dspin, 10, 18, 1, 1)
399
+ # force field optimization
400
+ ctip = 'Perform Force Field optimization'
401
+ self.chkFF = mQCheckBox('FF optimize', ctip, 12)
402
+ self.chkFF.stateChanged.connect(self.enableffinput)
403
+ self.grid.addWidget(self.chkFF, 11, 15, 1, 1)
404
+ # generate all
405
+ ctip = 'Generate structure with and without optimization.'
406
+ self.chkgenall = mQCheckBox('Generate\nall', ctip, 12)
407
+ self.chkgenall.stateChanged.connect(self.disableffinput)
408
+ self.grid.addWidget(self.chkgenall, 12, 15, 1, 1)
409
+ # perform optimization
410
+ ctip = 'Select Force Field'
411
+ qcav = ['MMFF94', 'UFF', 'gchemical', 'GAFF']
412
+ self.dff = mQComboBox(qcav, ctip, 12)
413
+ self.dff.setCurrentIndex(0)
414
+ self.dff.setDisabled(True)
415
+ self.grid.addWidget(self.dff, 11, 16, 1, 1)
416
+ # optimize before or after
417
+ ctip = 'Optimize before or after building the structure'
418
+ qcav = ['Before', 'After', 'Before & After']
419
+ self.dffba = mQComboBox(qcav, ctip, 12)
420
+ self.dffba.setDisabled(True)
421
+ self.dffba.setCurrentIndex(2)
422
+ self.grid.addWidget(self.dffba, 11, 17, 1, 2)
423
+ # create distortion slider
424
+ ctip = 'Percent random distortion from default coordination geometry.'
425
+ self.distper = mQLabel('Distort:0%', ctip, 'Cr', 12)
426
+ self.sdist = mQSlider(ctip)
427
+ self.sdist.valueChanged.connect(self.sliderChanged)
428
+ self.grid.addWidget(self.distper, 12, 17, 1, 1)
429
+ self.grid.addWidget(self.sdist, 12, 18, 1, 1)
430
+ # jobs dir #
431
+ ctip = 'Top directory for job folders.'
432
+ self.rtrdir = mQLabel('Jobs dir:', ctip, 'Cr', 12)
433
+ self.grid.addWidget(self.rtrdir, 14, 15, 1, 1)
434
+ self.etrdir = mQLineEdit(globs.rundir, ctip, 'l', 12)
435
+ self.grid.addWidget(self.etrdir, 14, 16, 1, 2)
436
+ # button for browsing rundir
437
+ ctip = 'Browse running directory.'
438
+ self.butpbrdir = mQPushButton('Browse..', ctip, 12)
439
+ self.butpbrdir.clicked.connect(self.dirload)
440
+ self.grid.addWidget(self.butpbrdir, 14, 18, 1, 1)
441
+ # suffix
442
+ ctip = 'Suffix for job directories.'
443
+ self.rtsuff = mQLabel('Suffix:', ctip, 'Cr', 12)
444
+ self.etsuff = mQLineEdit('', ctip, 'l', 12)
445
+ self.grid.addWidget(self.rtsuff, 15, 15, 1, 1)
446
+ self.grid.addWidget(self.etsuff, 15, 16, 1, 2)
447
+ # structure generation
448
+ ctip = 'Generate structures'
449
+ self.butGen = mQPushButton('Generate', ctip, 18)
450
+ self.butGen.clicked.connect(self.runGUI)
451
+ self.grid.addWidget(self.butGen, 17, 15, 2, 2)
452
+ # post-processing setup
453
+ ctip = 'Setup post-processing'
454
+ self.butPost = mQPushButton('Post-process', ctip, 16)
455
+ self.butPost.clicked.connect(self.setupp)
456
+ self.grid.addWidget(self.butPost, 17, 17, 2, 2)
457
+ # Search DB button #
458
+ ctip = 'Search for ligands in chemical databases.'
459
+ self.searchDB = mQPushButton('Search DB', ctip, 16)
460
+ self.searchDB.clicked.connect(self.searchDBW)
461
+ self.grid.addWidget(self.searchDB, 17, 20, 2, 2)
462
+ # ##################################################
463
+ # ##################################################
464
+ # ########## ADDITIONAL MOLECULE INPUTS ############
465
+ # ##################################################
466
+ # ##################################################
467
+ # generate edit texts for additional molecule
468
+ self.txtamol = mQLabel('Additional molecule', '', 'c', 20)
469
+ self.txtamol.setDisabled(True)
470
+ self.grid.addWidget(self.txtamol, 4, 19, 2, 5)
471
+ # additional molecule
472
+ ctip = 'Place additional molecule'
473
+ self.chkM = mQCheckBox('Extra molecule', ctip, 12)
474
+ self.chkM.stateChanged.connect(self.enableemol)
475
+ self.grid.addWidget(self.chkM, 7, 20, 1, 3)
476
+ # name of binding species
477
+ ctip = 'Binding species'
478
+ self.rtbind = mQLabel('Molecule:', ctip, 'Cr', 12)
479
+ bicores = list(sorted(getbcores()))
480
+ self.etbind = mQLineEditL('', ctip, 'l', 12, bicores)
481
+ self.rtbind.setDisabled(True)
482
+ self.etbind.setDisabled(True)
483
+ self.grid.addWidget(self.rtbind, 8, 20, 1, 1)
484
+ self.grid.addWidget(self.etbind, 8, 21, 1, 2)
485
+ # name of binding molecule from SMILES
486
+ ctip = 'Name of binding molecule using SMILES'
487
+ self.rtbsmi = mQLabel('Name:', ctip, 'Cr', 12)
488
+ self.etbsmi = mQLineEdit('', ctip, 'l', 12)
489
+ self.rtbsmi.setDisabled(True)
490
+ self.etbsmi.setDisabled(True)
491
+ self.grid.addWidget(self.rtbsmi, 9, 20, 1, 1)
492
+ self.grid.addWidget(self.etbsmi, 9, 21, 1, 2)
493
+ # separate in xyz file
494
+ ctip = 'Separate molecules in xyz or input file with ------'
495
+ self.chsep = mQCheckBox('separate', ctip, 12)
496
+ self.chsep.setDisabled(True)
497
+ self.grid.addWidget(self.chsep, 9, 23, 1, 2)
498
+ # number of binding conformations to generate
499
+ ctip = 'Number of different conformations to be generated'
500
+ self.rtnbind = mQLabel('Conformations:', ctip, 'Cr', 12)
501
+ self.etnbind = mQLineEdit('', ctip, 'l', 12)
502
+ self.rtnbind.setDisabled(True)
503
+ self.etnbind.setDisabled(True)
504
+ self.grid.addWidget(self.rtnbind, 10, 20, 1, 1)
505
+ self.grid.addWidget(self.etnbind, 10, 21, 1, 1)
506
+ # charge of binding species
507
+ ctip = 'Charge of binding species'
508
+ self.rtchbind = mQLabel('Charge:', ctip, 'Cr', 12)
509
+ self.etchbind = mQLineEdit('', ctip, 'l', 12)
510
+ self.rtchbind.setDisabled(True)
511
+ self.etchbind.setDisabled(True)
512
+ self.grid.addWidget(self.rtchbind, 10, 22, 1, 1)
513
+ self.grid.addWidget(self.etchbind, 10, 23, 1, 1)
514
+ # min/max distance
515
+ ctip = 'Specify placing minimum/maximum distance (in A)'
516
+ self.rtplace = mQLabel('Distance:', ctip, 'Cr', 12)
517
+ ctip = 'Minimum distance between the two molecules. 0 corresponds the marginally non-overlapping configuration'
518
+ self.etplacemin = mQLineEdit('', ctip, 'l', 12)
519
+ ctip = 'Maximum distance between the two molecules. 0 corresponds the marginally non-overlapping configuration'
520
+ self.etplacemax = mQLineEdit('', ctip, 'l', 12)
521
+ self.rtplace.setDisabled(True)
522
+ self.etplacemin.setDisabled(True)
523
+ self.etplacemax.setDisabled(True)
524
+ self.grid.addWidget(self.rtplace, 11, 20, 1, 1)
525
+ self.grid.addWidget(self.etplacemin, 11, 21, 1, 1)
526
+ self.grid.addWidget(self.etplacemax, 11, 22, 1, 1)
527
+ # mask for atom/center of mass reference
528
+ ctip = ('Reference atoms in extra molecules to be used for placement '
529
+ '(e.g. 1,2 or 1-6 or COM or Fe) Default COM (center mass)')
530
+ # self.rtmaskbind = mQLabel('Reference:',ctip,'r',14)
531
+ self.etmaskbind = mQLineEdit('COM', ctip, 'l', 12)
532
+ # self.rtmaskbind.setDisabled(True)
533
+ self.etmaskbind.setDisabled(True)
534
+ # self.grid.addWidget(self.rtmaskbind,11,23,1,1)
535
+ self.grid.addWidget(self.etmaskbind, 11, 23, 1, 1)
536
+ # angle/orientation
537
+ ctip = 'Specify placement type or angle. Angle overwrites placement.'
538
+ self.rtplacea = mQLabel('Angle:', ctip, 'Cr', 12)
539
+ ctip = 'Azimouthal angle phi from 0 to 180'
540
+ self.etplacephi = mQLineEdit('', ctip, 'l', 12)
541
+ ctip = 'Polar angle theta from 0 to 360'
542
+ self.etplacetheta = mQLineEdit('', ctip, 'l', 12)
543
+ self.rtplacea.setDisabled(True)
544
+ self.etplacephi.setDisabled(True)
545
+ self.etplacetheta.setDisabled(True)
546
+ self.grid.addWidget(self.rtplacea, 12, 20, 1, 1)
547
+ self.grid.addWidget(self.etplacephi, 12, 21, 1, 1)
548
+ self.grid.addWidget(self.etplacetheta, 12, 22, 1, 1)
549
+ # placement of extr molecule
550
+ ctip = 'Orientation for placing additional molecule'
551
+ qcav = ['', 'axial', 'equatorial']
552
+ self.dmolp = mQComboBox(qcav, ctip, 12)
553
+ self.dmolp.setDisabled(True)
554
+ self.dmolp.currentIndexChanged.connect(self.checkaxial)
555
+ self.grid.addWidget(self.dmolp, 12, 23, 1, 1)
556
+ # input file generation
557
+ ctip = 'Generate input files'
558
+ self.chkI = mQCheckBox('Input files', ctip, 12)
559
+ self.chkI.stateChanged.connect(self.enableqeinput)
560
+ self.grid.addWidget(self.chkI, 13, 20, 1, 2)
561
+ # jobscript generation
562
+ ctip = 'Generate jobscripts'
563
+ self.chkJ = mQCheckBox('Jobscripts', ctip, 12)
564
+ self.chkJ.stateChanged.connect(self.enablejinput)
565
+ self.grid.addWidget(self.chkJ, 13, 22, 1, 2)
566
+ # input for QC calculation
567
+ ctip = 'Enter input for Quantum Chemistry calculations'
568
+ self.butQc = mQPushButton('Enter QC input', ctip, 12)
569
+ self.butQc.setDisabled(True)
570
+ self.butQc.clicked.connect(self.qcinput)
571
+ ctip = 'Select QC code'
572
+ qcav = ['TeraChem', 'GAMESS', 'QChem']
573
+ self.qcode = mQComboBox(qcav, ctip, 12)
574
+ self.qcode.setDisabled(True)
575
+ self.grid.addWidget(self.butQc, 14, 20, 1, 2)
576
+ self.grid.addWidget(self.qcode, 15, 20, 1, 2)
577
+ # input for jobscripts
578
+ ctip = 'Enter input for jobscript files'
579
+ self.butJob = mQPushButton('Enter job input', ctip, 12)
580
+ self.butJob.setDisabled(True)
581
+ self.butJob.clicked.connect(self.jobenable)
582
+ ctip = 'Select job scheduler'
583
+ qcav = ['SGE', 'SLURM']
584
+ self.scheduler = mQComboBox(qcav, ctip, 12)
585
+ self.scheduler.setDisabled(True)
586
+ self.grid.addWidget(self.butJob, 14, 22, 1, 2)
587
+ self.grid.addWidget(self.scheduler, 15, 22, 1, 2)
588
+ # quit button
589
+ ctip = 'Quit program'
590
+ self.butQ = mQPushButton('Quit', ctip, 14)
591
+ self.butQ.clicked.connect(self.qexit)
592
+ self.grid.addWidget(self.butQ, 17, 23, 1, 1)
593
+ # ###############################################
594
+ # ###############################################
595
+ # ###############################################
596
+ # #########################
597
+ # ## information window ###
598
+ # #########################
599
+ self.iWind = QWidget()
600
+ self.iWind.setWindowTitle('Running')
601
+ self.iWtxt = mQTextEdit('Program started..', 'l', 14)
602
+ self.iWtxt.setParent(self.iWind)
603
+ self.sgrid.addWidget(self.iWind)
604
+ # ######################################
605
+ # ## create terachem-qc input window ###
606
+ # ######################################
607
+ self.qctWindow = QWidget() # TC QC window
608
+ self.qctgrid = QGridLayout()
609
+ self.qctWindow.setWindowTitle('Terachem Input')
610
+ self.sgrid.addWidget(self.qctWindow) # add to stacked grid
611
+ self.qctWindow.setPalette(p) # set background color
612
+ self.qctWindow.setLayout(self.qctgrid) # set layout
613
+
614
+ f = resource_files("molSimplify").joinpath("icons/petachem.png")
615
+ c0 = mQPixmap(f)
616
+ self.qctgrid.addWidget(c0, 0, 2, 1, 1)
617
+ # top text
618
+ self.txtqc = mQLabel(' TeraChem Input', '', 'C', 18)
619
+ self.qctgrid.addWidget(self.txtqc, 0, 3, 1, 2)
620
+ # text for specifying charge
621
+ ctip = 'Charge of the system, default: 0'
622
+ self.rtqctch = mQLabel('Charge:', ctip, 'r', 14)
623
+ self.etqctch = mQLineEdit('0', ctip, 'l', 14)
624
+ self.qctgrid.addWidget(self.rtqctch, 1, 1, 1, 1)
625
+ self.qctgrid.addWidget(self.etqctch, 1, 2, 1, 1)
626
+ # text for specifying spin state
627
+ ctip = 'Spin multiplicity of the system, default: 1'
628
+ self.rtqctspin = mQLabel('Spin:', ctip, 'r', 14)
629
+ self.etqctspin = mQLineEdit('1', ctip, 'l', 14)
630
+ self.qctgrid.addWidget(self.rtqctspin, 1, 3, 1, 1)
631
+ self.qctgrid.addWidget(self.etqctspin, 1, 4, 1, 1)
632
+ # drop menu for selecting type of calculation
633
+ qcav = ['energy', 'minimize', 'gradient', 'ts']
634
+ ctip = 'Specify calculation type, default: minimize'
635
+ self.rtqctcalc = mQLabel('Calculation:', ctip, 'r', 14)
636
+ self.qctcalc = mQComboBox(qcav, ctip, 14)
637
+ self.qctgrid.addWidget(self.rtqctcalc, 2, 1, 1, 1)
638
+ self.qctgrid.addWidget(self.qctcalc, 2, 2, 1, 1)
639
+ # text for specifying electronic structure method
640
+ ctip = 'Select electronic structure method, default: ub3lyp'
641
+ self.rtqctmethod = mQLabel('Method:', ctip, 'r', 14)
642
+ self.etqctmethod = mQLineEdit('ub3lyp', ctip, 'l', 14)
643
+ self.qctgrid.addWidget(self.rtqctmethod, 2, 3, 1, 1)
644
+ self.qctgrid.addWidget(self.etqctmethod, 2, 4, 1, 1)
645
+ # text for specifying basis set
646
+ ctip = 'Select basis set, default: lacvp_s'
647
+ self.rtqctbasis = mQLabel('Basis:', ctip, 'r', 14)
648
+ self.etqctbasis = mQLineEdit('lacvps_ecp', ctip, 'l', 14)
649
+ self.qctgrid.addWidget(self.rtqctbasis, 3, 1, 1, 1)
650
+ self.qctgrid.addWidget(self.etqctbasis, 3, 2, 1, 1)
651
+ # drop menu for selecting dispersion
652
+ qcav = ['yes', 'no', 'd2', 'd3']
653
+ ctip = 'Select dispersion correction'
654
+ self.rtcdisp = mQLabel('Dispersion:', ctip, 'r', 14)
655
+ self.qctsel = mQComboBox(qcav, ctip, 14)
656
+ self.qctgrid.addWidget(self.rtcdisp, 3, 3, 1, 1)
657
+ self.qctgrid.addWidget(self.qctsel, 3, 4, 1, 1)
658
+ self.qctsel.setCurrentIndex(1)
659
+ # editor for additional input
660
+ ctip = 'Specify additional input here'
661
+ self.rtqctadd = mQLabel('Additional input:', ctip, 'Cr', 14)
662
+ self.qceditor = mQTextEdit('', 'l', 14)
663
+ self.qctgrid.addWidget(self.rtqctadd, 4, 2, 1, 1)
664
+ self.qctgrid.addWidget(self.qceditor, 4, 3, 1, 2)
665
+ # button for addition
666
+ ctip = 'make default'
667
+ self.butqctlf = mQPushButton('Make default', ctip, 14)
668
+ self.butqctlf.clicked.connect(self.qctdef)
669
+ self.qctgrid.addWidget(self.butqctlf, 5, 1, 2, 1)
670
+ # button for addition
671
+ ctip = 'Submit input for Quantum Chemistry'
672
+ self.butqctSub = mQPushButton('Submit', ctip, 14)
673
+ self.butqctSub.clicked.connect(self.qretmain)
674
+ self.qctgrid.addWidget(self.butqctSub, 5, 2, 2, 1)
675
+ # button for return
676
+ ctip = 'Return to main menu'
677
+ self.butqctRet = mQPushButton('Return', ctip, 14)
678
+ self.butqctRet.clicked.connect(self.qretmain)
679
+ self.qctgrid.addWidget(self.butqctRet, 5, 4, 2, 1)
680
+ # load defaults if existing
681
+ if glob.glob(str(globs.custom_path)+'/Data/.tcdefinput.inp'):
682
+ loadfrominputtc(self, str(globs.custom_path) +
683
+ '/Data/.tcdefinput.inp')
684
+ # ####################################
685
+ # ## create gamess-qc input window ###
686
+ # ######################################
687
+ self.qcgWindow = QWidget() # TC QC window
688
+ self.qcggrid = QGridLayout()
689
+ self.qcgWindow.setWindowTitle('GAMESS Input')
690
+ self.sgrid.addWidget(self.qcgWindow) # add to stacked grid
691
+ self.qcgWindow.setPalette(p) # set background color
692
+ self.qcgWindow.setLayout(self.qcggrid) # set layout
693
+ # top text
694
+ self.txtqcg = mQLabel('GAMESS Input', '', 'c', 18)
695
+ self.qcggrid.addWidget(self.txtqcg, 0, 0, 1, 4)
696
+ # text for specifying charge
697
+ ctip = 'Charge of the system, default: 0'
698
+ self.rtqcgch = mQLabel('Charge:', ctip, 'r', 14)
699
+ self.etqcgch = mQLineEdit('0', ctip, 'l', 14)
700
+ self.qcggrid.addWidget(self.rtqcgch, 1, 0, 1, 1)
701
+ self.qcggrid.addWidget(self.etqcgch, 1, 1, 1, 1)
702
+ # text for specifying spin state
703
+ ctip = 'Spin multiplicity of the system, default: 1'
704
+ self.rtqcgspin = mQLabel('Spin:', ctip, 'r', 14)
705
+ self.etqcgspin = mQLineEdit('1', ctip, 'l', 14)
706
+ self.qcggrid.addWidget(self.rtqcgspin, 1, 2, 1, 1)
707
+ self.qcggrid.addWidget(self.etqcgspin, 1, 3, 1, 1)
708
+ # drop menu for selecting type of calculation
709
+ qcav = ['energy', 'minimize', 'ts']
710
+ ctip = 'Specify calculation type, default: minimize'
711
+ self.rtqcgcalc = mQLabel('Calculation:', ctip, 'r', 14)
712
+ self.qcgcalc = mQComboBox(qcav, ctip, 14)
713
+ self.qcggrid.addWidget(self.rtqcgcalc, 2, 0, 1, 1)
714
+ self.qcggrid.addWidget(self.qcgcalc, 2, 1, 1, 1)
715
+ # text for specifying electronic structure method
716
+ ctip = 'Select electronic structure method, default: ub3lyp'
717
+ self.rtqcgmethod = mQLabel('Method:', ctip, 'r', 14)
718
+ self.etqcgmethod = mQLineEdit('ub3lyp', ctip, 'l', 14)
719
+ self.qcggrid.addWidget(self.rtqcgmethod, 2, 2, 1, 1)
720
+ self.qcggrid.addWidget(self.etqcgmethod, 2, 3, 1, 1)
721
+ # text for specifying basis set
722
+ ctip = 'Select GBASIS input, default: 6'
723
+ self.rtqcgbasis = mQLabel('GBASIS:', ctip, 'r', 14)
724
+ self.etqcgbasis = mQLineEdit('6', ctip, 'l', 14)
725
+ self.qcggrid.addWidget(self.rtqcgbasis, 3, 0, 1, 1)
726
+ self.qcggrid.addWidget(self.etqcgbasis, 3, 1, 1, 1)
727
+ # text for specifying basis set
728
+ ctip = 'Select NGAUSS input, default: N31'
729
+ self.rtqcngauss = mQLabel('NGAUSS:', ctip, 'r', 14)
730
+ self.etqcngauss = mQLineEdit('N31', ctip, 'l', 14)
731
+ self.qcggrid.addWidget(self.rtqcngauss, 3, 2, 1, 1)
732
+ self.qcggrid.addWidget(self.etqcngauss, 3, 3, 1, 1)
733
+ # text for specifying polarization functions
734
+ ctip = 'Select NPFUNC input, default: 0'
735
+ self.rtqcnpfunc = mQLabel('NPFUNC:', ctip, 'r', 14)
736
+ self.etqcnpfunc = mQLineEdit('', ctip, 'l', 14)
737
+ self.qcggrid.addWidget(self.rtqcnpfunc, 4, 0, 1, 1)
738
+ self.qcggrid.addWidget(self.etqcnpfunc, 4, 1, 1, 1)
739
+ # text for specifying polarization functions
740
+ ctip = 'Select NDFUNC input, default: 0'
741
+ self.rtqcndfunc = mQLabel('NDFUNC:', ctip, 'r', 14)
742
+ self.etqcndfunc = mQLineEdit('', ctip, 'l', 14)
743
+ self.qcggrid.addWidget(self.rtqcndfunc, 4, 2, 1, 1)
744
+ self.qcggrid.addWidget(self.etqcndfunc, 4, 3, 1, 1)
745
+ # editor for additional input
746
+ ctip = 'Specify additional input for block SYS here'
747
+ self.rtqcgadd1 = mQLabel('SYS input:', ctip, 'Cr', 14)
748
+ self.qcgedsys = mQTextEdit('', 'l', 12)
749
+ self.qcggrid.addWidget(self.rtqcgadd1, 5, 0, 1, 1)
750
+ self.qcggrid.addWidget(self.qcgedsys, 5, 1, 1, 1)
751
+ # editor for additional input
752
+ ctip = 'Specify additional input for block CTRL here'
753
+ self.rtqcgadd1 = mQLabel('CTRL input:', ctip, 'Cr', 14)
754
+ self.qcgedctrl = mQTextEdit('', 'l', 12)
755
+ self.qcggrid.addWidget(self.rtqcgadd1, 5, 2, 1, 1)
756
+ self.qcggrid.addWidget(self.qcgedctrl, 5, 3, 1, 1)
757
+ # editor for additional input
758
+ ctip = 'Specify additional input for block SCF here'
759
+ self.rtqcgadd3 = mQLabel('SCF input:', ctip, 'Cr', 14)
760
+ self.qcgedscf = mQTextEdit('', 'l', 12)
761
+ self.qcggrid.addWidget(self.rtqcgadd3, 6, 0, 1, 1)
762
+ self.qcggrid.addWidget(self.qcgedscf, 6, 1, 1, 1)
763
+ # editor for additional input
764
+ ctip = 'Specify additional input for block STAT here'
765
+ self.rtqcgadd4 = mQLabel('STAT input:', ctip, 'Cr', 14)
766
+ self.qcgedstat = mQTextEdit('', 'l', 12)
767
+ self.qcggrid.addWidget(self.rtqcgadd4, 6, 2, 1, 1)
768
+ self.qcggrid.addWidget(self.qcgedstat, 6, 3, 1, 1)
769
+ # button for addition
770
+ ctip = 'make default'
771
+ self.butqcglf = mQPushButton('Make default', ctip, 14)
772
+ self.butqcglf.clicked.connect(self.qcgdef)
773
+ self.qcggrid.addWidget(self.butqcglf, 7, 0, 1, 1)
774
+ # button for addition
775
+ ctip = 'Submit input for Quantum Chemistry'
776
+ self.butqcgSub = mQPushButton('Submit', ctip, 14)
777
+ self.butqcgSub.clicked.connect(self.qretmain)
778
+ self.qcggrid.addWidget(self.butqcgSub, 7, 1, 1, 2)
779
+ # button for return
780
+ ctip = 'Return to main menu'
781
+ self.butqcgRet = mQPushButton('Return', ctip, 14)
782
+ self.butqcgRet.clicked.connect(self.qretmain)
783
+ self.qcggrid.addWidget(self.butqcgRet, 7, 3, 1, 1)
784
+ self.qcggrid.setRowMinimumHeight(7, 30)
785
+ # load defaults if existing
786
+ if glob.glob(str(globs.custom_path)+'/Data/.gamdefinput.inp'):
787
+ loadfrominputgam(self, str(globs.custom_path))
788
+ # ######################################
789
+ # ### create Qchem-qc input window #####
790
+ # ######################################
791
+ self.qcQWindow = QWidget() # TC QC window
792
+ self.qcQgrid = QGridLayout()
793
+ self.qcQWindow.setWindowTitle('QChem Input')
794
+ self.sgrid.addWidget(self.qcQWindow) # add to stacked grid
795
+ self.qcQWindow.setPalette(p) # set background color
796
+ self.qcQWindow.setLayout(self.qcQgrid) # set layout
797
+ # top text
798
+ self.txtQqc = mQLabel('QChem Input', '', 'c', 18)
799
+ self.qcQgrid.addWidget(self.txtQqc, 0, 0, 1, 5)
800
+ # text for specifying charge
801
+ ctip = 'Charge of the system, default: 0'
802
+ self.rtqcQch = mQLabel('Charge:', ctip, 'r', 14)
803
+ self.etqcQch = mQLineEdit('0', ctip, 'l', 14)
804
+ self.qcQgrid.addWidget(self.rtqcQch, 1, 0, 1, 1)
805
+ self.qcQgrid.addWidget(self.etqcQch, 1, 1, 1, 1)
806
+ # text for specifying spin state
807
+ ctip = 'Spin multiplicity of the system, default: 1'
808
+ self.rtqcQspin = mQLabel('Spin:', ctip, 'r', 14)
809
+ self.etqcQspin = mQLineEdit('1', ctip, 'l', 14)
810
+ self.qcQgrid.addWidget(self.rtqcQspin, 1, 2, 1, 1)
811
+ self.qcQgrid.addWidget(self.etqcQspin, 1, 3, 1, 1)
812
+ # additional molecule
813
+ ctip = 'Unrestricted calculation?'
814
+ self.chQun = mQCheckBox('Unrestricted', ctip, 14)
815
+ self.chQun.setChecked(True)
816
+ self.qcQgrid.addWidget(self.chQun, 1, 4, 1, 1)
817
+ # drop menu for selecting type of calculation
818
+ qcav = ['energy', 'minimize', 'ts']
819
+ ctip = 'Specify calculation type, default: minimize'
820
+ self.rtqcQcalc = mQLabel('Calculation:', ctip, 'r', 14)
821
+ self.qcQcalc = mQComboBox(qcav, ctip, 14)
822
+ self.qcQgrid.addWidget(self.rtqcQcalc, 2, 0, 1, 1)
823
+ self.qcQgrid.addWidget(self.qcQcalc, 2, 1, 1, 1)
824
+ # text for specifying basis set
825
+ ctip = 'Select basis set, default: lanl2dz'
826
+ self.rtqcQbasis = mQLabel('Basis:', ctip, 'r', 14)
827
+ self.etqcQbasis = mQLineEdit('lanl2dz', ctip, 'l', 14)
828
+ self.qcQgrid.addWidget(self.rtqcQbasis, 2, 2, 1, 1)
829
+ self.qcQgrid.addWidget(self.etqcQbasis, 2, 3, 1, 1)
830
+ # text for specifying exchange
831
+ ctip = 'Select exchange, default: b3lyp'
832
+ self.rtqcQex = mQLabel('Exchange:', ctip, 'r', 14)
833
+ self.etqcQex = mQLineEdit('b3lyp', ctip, 'l', 14)
834
+ self.qcQgrid.addWidget(self.rtqcQex, 3, 0, 1, 1)
835
+ self.qcQgrid.addWidget(self.etqcQex, 3, 1, 1, 1)
836
+ # text for specifying electronic structure method
837
+ ctip = 'Select correlation, default: none'
838
+ self.rtqcQcor = mQLabel('Correlation:', ctip, 'r', 14)
839
+ self.etqcQcor = mQLineEdit('none', ctip, 'l', 14)
840
+ self.qcQgrid.addWidget(self.rtqcQcor, 3, 2, 1, 1)
841
+ self.qcQgrid.addWidget(self.etqcQcor, 3, 3, 1, 1)
842
+ # editor for additional input
843
+ ctip = 'Specify additional input here'
844
+ self.rtqcQadd = mQLabel('Additional input:', ctip, 'Cr', 14)
845
+ self.qcQeditor = mQTextEdit('', 'l', 12)
846
+ self.qcQgrid.addWidget(self.rtqcQadd, 4, 1, 1, 1)
847
+ self.qcQgrid.addWidget(self.qcQeditor, 4, 2, 1, 2)
848
+ # button for addition
849
+ ctip = 'make default'
850
+ self.butqcQlf = mQPushButton('Make default', ctip, 14)
851
+ self.butqcQlf.clicked.connect(self.qcqdef)
852
+ self.qcQgrid.addWidget(self.butqcQlf, 5, 0, 1, 1)
853
+ # button for addition
854
+ ctip = 'Submit input for Quantum Chemistry'
855
+ self.butqcQSub = mQPushButton('Submit', ctip, 14)
856
+ self.butqcQSub.clicked.connect(self.qretmain)
857
+ self.qcQgrid.addWidget(self.butqcQSub, 5, 2, 1, 2)
858
+ # button for return
859
+ ctip = 'Return to main menu'
860
+ self.butqcQRet = mQPushButton('Return', ctip, 14)
861
+ self.butqcQRet.clicked.connect(self.qretmain)
862
+ self.qcQgrid.addWidget(self.butqcQRet, 5, 4, 1, 1)
863
+ # load defaults if existing
864
+ if glob.glob(str(globs.custom_path)+'/Data/.qchdefinput.inp'):
865
+ loadfrominputqch(self, str(globs.custom_path) +
866
+ '/Data/.qchdefinput.inp')
867
+ # ####################################
868
+ # ## create jobscript input window ###
869
+ # ####################################
870
+ self.jWindow = QWidget() # jobscript window
871
+ self.jgrid = QGridLayout()
872
+ self.jWindow.setWindowTitle('Jobscript parameters')
873
+ self.sgrid.addWidget(self.jWindow) # add to stacked grid
874
+ self.jWindow.setPalette(p) # set background color
875
+ self.jWindow.setLayout(self.jgrid) # set layout
876
+ f1 = resource_files("molSimplify").joinpath("icons/sge.png")
877
+ f2 = resource_files("molSimplify").joinpath("icons/slurm.png")
878
+ c1 = mQPixmap(f1)
879
+ c2 = mQPixmap(f2)
880
+ self.jgrid.addWidget(c1, 1, 2, 1, 1)
881
+ self.jgrid.addWidget(c2, 1, 4, 1, 1)
882
+ # top text
883
+ self.txtj = mQLabel('Jobscript Input', '', 'r', 18)
884
+ self.jgrid.addWidget(self.txtj, 0, 2, 1, 2)
885
+ # text for main job identifier
886
+ ctip = 'Job main identifier, e.g. feII'
887
+ self.rtjname = mQLabel('Job name:', ctip, 'r', 14)
888
+ self.etjname = mQLineEdit('myjob', ctip, 'l', 14)
889
+ self.jgrid.addWidget(self.rtjname, 2, 1, 1, 1)
890
+ self.jgrid.addWidget(self.etjname, 2, 2, 1, 1)
891
+ # text for specifying spin state
892
+ ctip = 'Queue to use, e.g. gpus'
893
+ self.rtjqueue = mQLabel('Queue:', ctip, 'r', 14)
894
+ self.etjqueue = mQLineEdit('', ctip, 'l', 14)
895
+ self.jgrid.addWidget(self.rtjqueue, 2, 3, 1, 1)
896
+ self.jgrid.addWidget(self.etjqueue, 2, 4, 1, 1)
897
+ # text for specifying wall time
898
+ ctip = 'Wall time request, e.g. 48'
899
+ self.rtjwallt = mQLabel('Wall time:', ctip, 'r', 14)
900
+ self.etjwallt = mQLineEdit('48h', ctip, 'l', 14)
901
+ self.jgrid.addWidget(self.rtjwallt, 3, 1, 1, 1)
902
+ self.jgrid.addWidget(self.etjwallt, 3, 2, 1, 1)
903
+ # text for specifying memory
904
+ ctip = 'Memory request, e.g. 10G'
905
+ self.rtjmem = mQLabel('Memory:', ctip, 'r', 14)
906
+ self.etjmem = mQLineEdit('10G', ctip, 'l', 14)
907
+ self.jgrid.addWidget(self.rtjmem, 3, 3, 1, 1)
908
+ self.jgrid.addWidget(self.etjmem, 3, 4, 1, 1)
909
+ # text for specifying charge
910
+ ctip = 'Number of CPUs requested, default: 0'
911
+ self.rtjcpus = mQLabel('CPUs:', ctip, 'r', 14)
912
+ self.etjcpus = mQLineEdit('', ctip, 'l', 14)
913
+ self.jgrid.addWidget(self.rtjcpus, 4, 1, 1, 1)
914
+ self.jgrid.addWidget(self.etjcpus, 4, 2, 1, 1)
915
+ # text for specifying spin state
916
+ ctip = 'Number of GPUs requested, default: 0'
917
+ self.rtjgpus = mQLabel('GPUs:', ctip, 'r', 14)
918
+ self.etjgpus = mQLineEdit('', ctip, 'l', 14)
919
+ self.jgrid.addWidget(self.rtjgpus, 4, 3, 1, 1)
920
+ self.jgrid.addWidget(self.etjgpus, 4, 4, 1, 1)
921
+ # text for modules to be loaded
922
+ ctip = 'Modules to be loaded, e.g. terachem, openmpi'
923
+ self.rtjmod = mQLabel('Modules:', ctip, 'r', 14)
924
+ self.etjmod = mQLineEdit('', ctip, 'l', 14)
925
+ self.jgrid.addWidget(self.rtjmod, 5, 1, 1, 1)
926
+ self.jgrid.addWidget(self.etjmod, 5, 2, 1, 1)
927
+ # editor for additional input
928
+ ctip = 'Specify additional input for initial options, e.g. -j y'
929
+ self.rtjadd1 = mQLabel('Options:', ctip, 'r', 14)
930
+ self.etjopt = mQTextEdit('', 'l', 12)
931
+ self.jgrid.addWidget(self.rtjadd1, 6, 1, 1, 1)
932
+ self.jgrid.addWidget(self.etjopt, 6, 2, 1, 1)
933
+ # editor for additional input
934
+ ctip = 'Specify additional commands, e.g. mkdir $WORKDIR/test'
935
+ self.rtjadd2 = mQLabel('Commands:', ctip, 'Cr', 14)
936
+ self.jcomm = mQTextEdit('', 'l', 12)
937
+ self.jgrid.addWidget(self.rtjadd2, 6, 3, 1, 1)
938
+ self.jgrid.addWidget(self.jcomm, 6, 4, 1, 1)
939
+ # button for addition
940
+ ctip = 'make default'
941
+ self.butqcJlf = mQPushButton('Make default', ctip, 14)
942
+ self.butqcJlf.clicked.connect(self.jobdef)
943
+ self.jgrid.addWidget(self.butqcJlf, 7, 1, 1, 1)
944
+ # button for addition
945
+ ctip = 'Submit input for Quantum Chemistry'
946
+ self.butqcgSub = mQPushButton('Submit', ctip, 14)
947
+ self.butqcgSub.clicked.connect(self.qretmain)
948
+ self.jgrid.addWidget(self.butqcgSub, 7, 2, 1, 2)
949
+ # button for return
950
+ ctip = 'Return to main menu'
951
+ self.butqcgRet = mQPushButton('Return', ctip, 14)
952
+ self.butqcgRet.clicked.connect(self.qretmain)
953
+ self.jgrid.addWidget(self.butqcgRet, 7, 4, 1, 1)
954
+ # load defaults if existing
955
+ if glob.glob(str(globs.custom_path)+'/Data/.jobdefinput.inp'):
956
+ loadfrominputjob(self, str(globs.custom_path)+'/Data/.jobdefinput.inp')
957
+ # #########################################
958
+ # ## create local DB interaction window ###
959
+ # #########################################
960
+ self.DBWindow = QWidget() # DB Window
961
+ self.DBlgrid = QGridLayout()
962
+ self.sgrid.addWidget(self.DBWindow)
963
+ self.DBWindow.setPalette(p)
964
+ self.DBWindow.setLayout(self.DBlgrid)
965
+ self.DBWindow.setWindowTitle('Insert/remove to/from Database')
966
+ # top text
967
+ self.txtdb = mQLabel('Database Update', '', 'c', 18)
968
+ self.DBlgrid.addWidget(self.txtdb, 0, 0, 1, 4)
969
+ # drop menu for selecting type
970
+ ctip = 'Select what type of molecule you want to add/remove to/from the database'
971
+ self.rtDBsel = mQLabel('Select type:', '', 'r', 14)
972
+ qcav = ['core', 'ligand', 'binding']
973
+ self.DBsel = mQComboBox(qcav, ctip, 14)
974
+ self.DBsel.setCurrentIndex(1)
975
+ self.DBlgrid.addWidget(self.rtDBsel, 1, 1, 1, 1)
976
+ self.DBlgrid.addWidget(self.DBsel, 1, 2, 1, 1)
977
+ # text for selecting type
978
+ ctip = 'Type SMILES string for molecule'
979
+ self.rtDBsmi = mQLabel('SMILES or file:', '', 'r', 14)
980
+ self.etDBsmi = mQLineEdit('', ctip, 'l', 14)
981
+ self.DBlgrid.addWidget(self.rtDBsmi, 2, 1, 1, 1)
982
+ self.DBlgrid.addWidget(self.etDBsmi, 2, 2, 1, 1)
983
+ # text for specifying name
984
+ ctip = 'Type name for molecule'
985
+ self.rtDBname = mQLabel('Name:', '', 'r', 14)
986
+ self.etDBname = mQLineEdit('', ctip, 'l', 14)
987
+ self.DBlgrid.addWidget(self.rtDBname, 3, 1, 1, 1)
988
+ self.DBlgrid.addWidget(self.etDBname, 3, 2, 1, 1)
989
+ # text for specifying category
990
+ ctip = 'Type groups for ligand'
991
+ self.rtDBgrps = mQLabel('Groups:', '', 'r', 14)
992
+ self.etDBgrps = mQLineEdit('', ctip, 'l', 14)
993
+ self.DBlgrid.addWidget(self.rtDBgrps, 4, 1, 1, 1)
994
+ self.DBlgrid.addWidget(self.etDBgrps, 4, 2, 1, 1)
995
+ # text for specifying groups
996
+ ctip = 'Type category for ligand. It can be used for building complexes("build")\n'
997
+ ctip += 'functionalizing existing cores("functionalize") or both.'
998
+ self.rtDBctg = mQLabel('Category:', '', 'r', 14)
999
+ self.etDBctg = mQComboBox(['all', 'build', 'functionalize'], ctip, 14)
1000
+ self.DBlgrid.addWidget(self.rtDBctg, 5, 1, 1, 1)
1001
+ self.DBlgrid.addWidget(self.etDBctg, 5, 2, 1, 1)
1002
+ # checkboxes for FF optimization
1003
+ ctip = 'Force-field optimize in isolation'
1004
+ self.lFFb = mQCheckBox('FF before', ctip, 14)
1005
+ self.DBlgrid.addWidget(self.lFFb, 6, 1, 1, 1)
1006
+ self.lFFb.setChecked(True)
1007
+ # checkboxes for FF optimization
1008
+ ctip = 'Force-field optimize in molecule'
1009
+ self.lFFa = mQCheckBox('FF after', ctip, 14)
1010
+ self.DBlgrid.addWidget(self.lFFa, 6, 2, 1, 1)
1011
+ self.lFFa.setChecked(True)
1012
+ # drop menu for denticity
1013
+ ctip = 'Type denticity for SMILES molecule'
1014
+ self.rtDBsmident = mQLabel('Denticity:', '', 'r', 14)
1015
+ qcav = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10']
1016
+ self.DBdent = mQComboBox(qcav, ctip, 14)
1017
+ self.DBdent.setCurrentIndex(0)
1018
+ self.DBlgrid.addWidget(self.rtDBsmident, 7, 1, 1, 1)
1019
+ self.DBlgrid.addWidget(self.DBdent, 7, 2, 1, 1)
1020
+ self.DBsel.currentIndexChanged.connect(
1021
+ self.dbchange) # error if not here
1022
+ # text for typing input connection atoms
1023
+ ctip = 'Type indices for connection atoms, default: 1'
1024
+ self.rtDBsmicat = mQLabel('Catoms:', ctip, 'r', 14)
1025
+ self.etDBsmicat = mQLineEdit('', ctip, 'l', 14)
1026
+ self.DBlgrid.addWidget(self.rtDBsmicat, 8, 1, 1, 1)
1027
+ self.DBlgrid.addWidget(self.etDBsmicat, 8, 2, 1, 1)
1028
+ # button for addition
1029
+ ctip = 'Load molecule from file'
1030
+ self.butDBAlf = mQPushButton('Load file..', ctip, 14)
1031
+ self.butDBAlf.clicked.connect(self.qDBload)
1032
+ self.DBlgrid.addWidget(self.butDBAlf, 9, 0, 1, 1)
1033
+ # button for addition
1034
+ ctip = 'Add new molecule to database'
1035
+ self.butDBAub = mQPushButton('Add', ctip, 14)
1036
+ self.butDBAub.clicked.connect(self.qaddDB)
1037
+ self.DBlgrid.addWidget(self.butDBAub, 9, 1, 1, 1)
1038
+ # button for removal
1039
+ ctip = 'Remove molecule from database'
1040
+ self.butDBDub = mQPushButton('Remove', ctip, 14)
1041
+ self.butDBDub.clicked.connect(self.qdelDB)
1042
+ self.DBlgrid.addWidget(self.butDBDub, 9, 2, 1, 1)
1043
+ # button for return
1044
+ ctip = 'Return to main menu'
1045
+ self.butDBRet = mQPushButton('Return', ctip, 14)
1046
+ self.butDBRet.clicked.connect(self.qretmain)
1047
+ self.DBlgrid.addWidget(self.butDBRet, 9, 3, 1, 1)
1048
+ # ############################################
1049
+ # ## create chemical DB interaction window ###
1050
+ # ############################################
1051
+ self.cDBWindow = QWidget() # DB Window
1052
+ self.cDBgrid = QGridLayout()
1053
+ self.sgrid.addWidget(self.cDBWindow)
1054
+ self.cDBWindow.setPalette(p)
1055
+ self.cDBWindow.setLayout(self.cDBgrid)
1056
+ self.cDBWindow.setWindowTitle('Chemical Database Search')
1057
+ ctip = 'Specify screening options or similarity search.'
1058
+ # top text
1059
+ self.txtcdb = mQLabel('Database Search', ctip, 'c', 18)
1060
+ self.cDBgrid.addWidget(self.txtcdb, 0, 0, 1, 9)
1061
+ # text for reference
1062
+ self.rtcDBref = mQLabel('Similarity search', '', 'c', 18)
1063
+ self.cDBgrid.addWidget(self.rtcDBref, 1, 0, 1, 3)
1064
+ # text for selecting type
1065
+ ctip = 'Type SMILES string or molecule name for reference molecule in similarity search'
1066
+ self.rtcDBsmi = mQLabel('SMILES:', ctip, 'r', 14)
1067
+ self.etcDBsmi = mQLineEdit('', ctip, 'l', 14)
1068
+ self.cDBgrid.addWidget(self.rtcDBsmi, 2, 0, 1, 1)
1069
+ self.cDBgrid.addWidget(self.etcDBsmi, 2, 1, 1, 2)
1070
+ # button for loading from file
1071
+ ctip = 'Load reference molecule from file'
1072
+ self.rtcDBAlf = mQLabel('From file:', ctip, 'r', 14)
1073
+ self.butcDBAlf = mQPushButton('Load..', ctip, 14)
1074
+ self.butcDBAlf.clicked.connect(self.qcDBload)
1075
+ self.cDBgrid.addWidget(self.rtcDBAlf, 3, 0, 1, 1)
1076
+ self.cDBgrid.addWidget(self.butcDBAlf, 3, 1, 1, 2)
1077
+ # connection atoms for smarts/smiles
1078
+ ctip = 'Specify the connection atoms in SMARTS/SMILES. Default: 1'
1079
+ self.rtcDBcatoms = mQLabel('Conn atoms:', ctip, 'r', 14)
1080
+ self.etcDBcatoms = mQLineEdit('1', ctip, 'l', 14)
1081
+ self.cDBgrid.addWidget(self.rtcDBcatoms, 4, 0, 1, 1)
1082
+ self.cDBgrid.addWidget(self.etcDBcatoms, 4, 1, 1, 1)
1083
+ # how many molecules to return
1084
+ ctip = 'Specify the number of results you want.'
1085
+ self.rtcDBres = mQLabel('Results:', ctip, 'r', 14)
1086
+ self.etcDBnres = mQLineEdit('', ctip, 'l', 14)
1087
+ self.cDBgrid.addWidget(self.rtcDBres, 5, 0, 1, 1)
1088
+ self.cDBgrid.addWidget(self.etcDBnres, 5, 1, 1, 1)
1089
+ # text for output file
1090
+ ctip = 'Please type in output file'
1091
+ self.rtcDBsoutf = mQLabel('Output file:', ctip, 'r', 14)
1092
+ self.etcDBoutf = mQLineEdit('simres', ctip, 'l', 14)
1093
+ self.cDBgrid.addWidget(self.rtcDBsoutf, 6, 0, 1, 1)
1094
+ self.cDBgrid.addWidget(self.etcDBoutf, 6, 1, 1, 1)
1095
+ # drop menu for output file
1096
+ qcav = ['.smi'] # ,'.mol','.sdf']
1097
+ self.cDBdent = mQComboBox(qcav, ctip, 14)
1098
+ self.cDBgrid.addWidget(self.cDBdent, 6, 2, 1, 1)
1099
+ # text for screening options
1100
+ self.rtcDBsc = mQLabel('Screening options', ctip, 'c', 18)
1101
+ self.cDBgrid.addWidget(self.rtcDBsc, 1, 6, 1, 4)
1102
+ # text for selecting database
1103
+ self.rtcDBsel = mQLabel('Select database:', ctip, 'c', 14)
1104
+ self.cDBgrid.addWidget(self.rtcDBsel, 2, 5, 1, 2)
1105
+ # get existing databases
1106
+ ctip = 'Select the database you want to use. Please note that fastsearch indexes DBs allow for much faster screening.'
1107
+ dbdir = globs.chemdbdir
1108
+ dbs0 = glob.glob(dbdir+"/*.sdf")
1109
+ dbs1 = [d.rsplit('/', 1)[-1] for d in dbs0]
1110
+ dbs = [d.split('.', 1)[0] for d in dbs1]
1111
+ self.cDBsel = mQComboBox(dbs, ctip, 14)
1112
+ self.cDBgrid.addWidget(self.cDBsel, 2, 7, 1, 2)
1113
+ # text for SMARTS pattern
1114
+ ctip = 'Type SMARTS pattern for matching'
1115
+ self.rtcDBsmarts = mQLabel('SMARTS:', ctip, 'r', 14)
1116
+ self.etcDBsmarts = mQLineEdit('', ctip, 'l', 14)
1117
+ self.cDBgrid.addWidget(self.rtcDBsmarts, 3, 5, 1, 2)
1118
+ self.cDBgrid.addWidget(self.etcDBsmarts, 3, 7, 1, 2)
1119
+ ctip = 'Select molecular fingerprint'
1120
+ # text for selecting fingerprint
1121
+ self.rtcDBsf = mQLabel('Select Fingerprint:', ctip, 'r', 14)
1122
+ self.cDBgrid.addWidget(self.rtcDBsf, 4, 5, 1, 2)
1123
+ # select fingerprint
1124
+ opts = ['FP2', 'FP3', 'FP4', 'MACCS']
1125
+ self.cDBsf = mQComboBox(opts, ctip, 14)
1126
+ self.cDBgrid.addWidget(self.cDBsf, 4, 7, 1, 2)
1127
+ # get options for screening
1128
+ ctip = 'Specify minimum and maximum values for filters.'
1129
+ self.rtcDBmin = mQLabel('min', ctip, 'c', 14)
1130
+ self.rtcDBmax = mQLabel('max', ctip, 'c', 14)
1131
+ self.cDBgrid.addWidget(self.rtcDBmin, 6, 7, 1, 1)
1132
+ self.cDBgrid.addWidget(self.rtcDBmax, 6, 8, 1, 1)
1133
+ ctip = 'Total number of atoms.'
1134
+ self.rtcDBat0 = mQLabel('atoms:', ctip, 'r', 14)
1135
+ self.cDBgrid.addWidget(self.rtcDBat0, 7, 5, 1, 2)
1136
+ ctip = 'Minimum number of atoms.'
1137
+ self.etcDBsatoms0 = mQLineEdit('', ctip, 'l', 14)
1138
+ self.cDBgrid.addWidget(self.etcDBsatoms0, 7, 7, 1, 1)
1139
+ ctip = 'Maximum number of atoms.'
1140
+ self.etcDBsatoms1 = mQLineEdit('', ctip, 'l', 14)
1141
+ self.cDBgrid.addWidget(self.etcDBsatoms1, 7, 8, 1, 1)
1142
+ ctip = 'Total number of bonds.'
1143
+ self.rtcDBb0 = mQLabel('bonds:', ctip, 'r', 14)
1144
+ self.cDBgrid.addWidget(self.rtcDBb0, 8, 5, 1, 2)
1145
+ ctip = 'Minimum number of total bonds.'
1146
+ self.etcDBsbonds0 = mQLineEdit('', ctip, 'l', 14)
1147
+ self.cDBgrid.addWidget(self.etcDBsbonds0, 8, 7, 1, 1)
1148
+ ctip = 'Maximum number of total bonds.'
1149
+ self.etcDBsbonds1 = mQLineEdit('', ctip, 'l', 14)
1150
+ self.cDBgrid.addWidget(self.etcDBsbonds1, 8, 8, 1, 1)
1151
+ ctip = 'Total number of aromatic.'
1152
+ self.rtcDBba0 = mQLabel('aromatic bonds:', ctip, 'r', 14)
1153
+ self.cDBgrid.addWidget(self.rtcDBba0, 9, 5, 1, 2)
1154
+ ctip = 'Minimum number of aromatic bonds.'
1155
+ self.etcDBsabonds0 = mQLineEdit('', ctip, 'l', 14)
1156
+ self.cDBgrid.addWidget(self.etcDBsabonds0, 9, 7, 1, 1)
1157
+ ctip = 'Maximum number of aromatic bonds.'
1158
+ self.etcDBsabonds1 = mQLineEdit('', ctip, 'l', 14)
1159
+ self.cDBgrid.addWidget(self.etcDBsabonds1, 9, 8, 1, 1)
1160
+ ctip = 'Total number of single bonds.'
1161
+ self.rtcDBs0 = mQLabel('single bonds:', ctip, 'r', 14)
1162
+ self.cDBgrid.addWidget(self.rtcDBs0, 10, 5, 1, 2)
1163
+ ctip = 'Minimum number of single bonds.'
1164
+ self.etcDBsbondss0 = mQLineEdit('', ctip, 'l', 14)
1165
+ self.cDBgrid.addWidget(self.etcDBsbondss0, 10, 7, 1, 1)
1166
+ ctip = 'Maximum number of single bonds.'
1167
+ self.etcDBsbondss1 = mQLineEdit('', ctip, 'l', 14)
1168
+ self.cDBgrid.addWidget(self.etcDBsbondss1, 10, 8, 1, 1)
1169
+ ctip = 'Molecular weight.'
1170
+ self.rtcDBbtmw0 = mQLabel('MW:', ctip, '', 14)
1171
+ self.cDBgrid.addWidget(self.rtcDBbtmw0, 11, 5, 1, 2)
1172
+ ctip = 'Minimum molecular weight.'
1173
+ self.etcDBmw0 = mQLineEdit('', ctip, 'l', 14)
1174
+ self.cDBgrid.addWidget(self.etcDBmw0, 11, 7, 1, 1)
1175
+ ctip = 'Maximum molecular weight.'
1176
+ self.etcDBmw1 = mQLineEdit('', ctip, 'l', 14)
1177
+ self.cDBgrid.addWidget(self.etcDBmw1, 11, 8, 1, 1)
1178
+ # aspirin icon
1179
+ f = resource_files("molSimplify").joinpath("icons/chemdb.png")
1180
+ c = mQPixmap(f)
1181
+ relresize(c, c, 0.4)
1182
+ self.cDBgrid.addWidget(c, 7, 0, 4, 2)
1183
+ # button for addition
1184
+ ctip = 'Search database:'
1185
+ self.butcDBAub = mQPushButton('Search', ctip, 14)
1186
+ self.butcDBAub.clicked.connect(self.qaddcDB)
1187
+ self.cDBgrid.addWidget(self.butcDBAub, 11, 0, 1, 2)
1188
+ # button for addition
1189
+ ctip = 'Draw results'
1190
+ self.butcDBd0 = mQPushButton('Draw', ctip, 14)
1191
+ self.butcDBd0.clicked.connect(self.drawres)
1192
+ self.cDBgrid.addWidget(self.butcDBd0, 9, 2, 1, 1)
1193
+ # button for return
1194
+ ctip = 'Return to main menu'
1195
+ self.butcDBRet = mQPushButton('Return', ctip, 14)
1196
+ self.butcDBRet.clicked.connect(self.qretmain)
1197
+ self.cDBgrid.addWidget(self.butcDBRet, 11, 2, 1, 1)
1198
+ # ##########################
1199
+ # ## post-process window ###
1200
+ # ##########################
1201
+ self.pWindow = QWidget() # Post Window
1202
+ self.pgrid = QGridLayout()
1203
+ self.sgrid.addWidget(self.pWindow)
1204
+ self.pWindow.setPalette(p)
1205
+ self.pWindow.setLayout(self.pgrid)
1206
+ self.pWindow.setWindowTitle('Post-processing')
1207
+ self.pgrid.setRowMinimumHeight(0, 50)
1208
+ self.pgrid.setRowMinimumHeight(2, 30)
1209
+ # top text
1210
+ self.txtp = mQLabel('Post-processing setup', '', 'c', 18)
1211
+ self.pgrid.addWidget(self.txtp, 0, 0, 1, 4)
1212
+ # input for jobscripts
1213
+ ctip = 'Select top jobs directory'
1214
+ self.butpd = mQPushButton('Select directory', ctip, 16)
1215
+ self.butpd.clicked.connect(self.pdload)
1216
+ self.pgrid.addWidget(self.butpd, 1, 0, 1, 1)
1217
+ self.etpdir = mQLineEdit(globs.rundir, ctip, 'l', 16)
1218
+ self.pgrid.addWidget(self.etpdir, 1, 1, 1, 1)
1219
+ # select qc code
1220
+ ctip = 'Select QC code'
1221
+ qcav = ['TeraChem', 'GAMESS']
1222
+ self.rpcode = mQLabel('QC code:', '', 'c', 16)
1223
+ self.pgrid.addWidget(self.rpcode, 1, 2, 1, 1)
1224
+ self.pqcode = mQComboBox(qcav, ctip, 14)
1225
+ self.pgrid.addWidget(self.pqcode, 1, 3, 1, 1)
1226
+ # general summary
1227
+ ctip = 'Generate results summary'
1228
+ self.psum = mQCheckBox('Summary', ctip, 16)
1229
+ self.pgrid.addWidget(self.psum, 3, 1, 1, 1)
1230
+ # metal charges
1231
+ ctip = 'Calculate metal charge'
1232
+ self.pch = mQCheckBox('Charge', ctip, 16)
1233
+ self.pgrid.addWidget(self.pch, 3, 2, 1, 1)
1234
+ # wavefunction properties
1235
+ ctip = 'Generate average properties of the wavefunction'
1236
+ self.pwfnav = mQCheckBox('Wavefunction', ctip, 16)
1237
+ self.pgrid.addWidget(self.pwfnav, 4, 1, 1, 1)
1238
+ # cube files
1239
+ ctip = 'Generate cubefiles'
1240
+ self.pcub = mQCheckBox('Cubes', ctip, 16)
1241
+ self.pgrid.addWidget(self.pcub, 4, 2, 1, 1)
1242
+ # molecular orbital information
1243
+ ctip = 'Molecular Orbital information'
1244
+ self.porbs = mQCheckBox('MO', ctip, 16)
1245
+ self.pgrid.addWidget(self.porbs, 5, 1, 1, 1)
1246
+ # NBO analysis
1247
+ ctip = 'NBO analysis'
1248
+ self.pnbo = mQCheckBox('NBO', ctip, 16)
1249
+ self.pgrid.addWidget(self.pnbo, 5, 2, 1, 1)
1250
+ # d-orbital information
1251
+ # ctip = 'd-orbital information'
1252
+ # self.pdorbs = mCheck(self.pWindow,0.55,0.525,0.2,0.1,'d-orbitals',ctip,16)
1253
+ # delocalization indices
1254
+ ctip = 'Localization and delocalization indices'
1255
+ self.pdeloc = mQCheckBox('Deloc', ctip, 16)
1256
+ self.pgrid.addWidget(self.pdeloc, 6, 1, 1, 1)
1257
+ # button for addition
1258
+ ctip = 'Run post-processing'
1259
+ self.butpR = mQPushButton('Run', ctip, 16)
1260
+ self.pgrid.addWidget(self.butpR, 7, 1, 1, 2)
1261
+ self.butpR.clicked.connect(self.postprocGUI)
1262
+ # button for return
1263
+ ctip = 'Return to main menu'
1264
+ self.butpret = mQPushButton('Return', ctip, 16)
1265
+ self.butpret.clicked.connect(self.qretmain)
1266
+ self.pgrid.addWidget(self.butpret, 7, 3, 1, 2)
1267
+ # c1p = mPic(self.pWindow,globs.installdir+'/icons/wft1.png',0.04,0.7,0.2)
1268
+ f = resource_files("molSimplify").joinpath("icons/wft3.png")
1269
+ c3p = mQPixmap(f)
1270
+ self.pgrid.addWidget(c3p, 3, 0, 4, 1)
1271
+ # c2p = mPic(self.pWindow,globs.installdir+'/icons/wft2.png',0.04,0.035,0.2)
1272
+ # #################################
1273
+ # ## create add geometry window ###
1274
+ # #################################
1275
+ self.geWindow = QWidget() # Geometry window
1276
+ self.gegrid = QGridLayout()
1277
+ self.sgrid.addWidget(self.geWindow)
1278
+ self.geWindow.setPalette(p)
1279
+ self.geWindow.setLayout(self.gegrid)
1280
+ self.geWindow.setWindowTitle('Add new geometry')
1281
+ # top text
1282
+ self.txtg = mQLabel('New geometry', '', 'c', 18)
1283
+ self.gegrid.addWidget(self.txtg, 0, 0, 1, 4)
1284
+ # text for specifying name
1285
+ ctip = 'Type name of geometry'
1286
+ self.rtgname = mQLabel('Name:', '', 'r', 14)
1287
+ self.etgname = mQLineEdit('', ctip, 'l', 14)
1288
+ self.gegrid.addWidget(self.rtgname, 1, 0, 1, 1)
1289
+ self.gegrid.addWidget(self.etgname, 1, 1, 1, 1)
1290
+ # text for specifying short name
1291
+ ctip = 'Type short identifier of geometry (2-4 letters)'
1292
+ self.rtgshort = mQLabel('Short identifier:', '', 'r', 14)
1293
+ self.etgshort = mQLineEdit('', ctip, 'l', 14)
1294
+ self.gegrid.addWidget(self.rtgshort, 2, 0, 1, 1)
1295
+ self.gegrid.addWidget(self.etgshort, 2, 1, 1, 1)
1296
+ # xyz file
1297
+ ctip = 'Load xyz file with geometry.'
1298
+ self.rtgf = mQLabel('Filename:', '', 'r', 14)
1299
+ self.etgf = mQLineEdit('', ctip, 'l', 14)
1300
+ self.gegrid.addWidget(self.rtgf, 3, 0, 1, 1)
1301
+ self.gegrid.addWidget(self.etgf, 3, 1, 1, 1)
1302
+ # png file
1303
+ ctip = 'Load png file with chemdraw for geometry.'
1304
+ self.rtgfc = mQLabel('Chemdraw file:', '', 'r', 14)
1305
+ self.etgfc = mQLineEdit('', ctip, 'l', 14)
1306
+ self.gegrid.addWidget(self.rtgfc, 4, 0, 1, 1)
1307
+ self.gegrid.addWidget(self.etgfc, 4, 1, 1, 1)
1308
+ # load file
1309
+ self.butge = mQPushButton('Load geometry file..', ctip, 14)
1310
+ self.butge.clicked.connect(self.qgeomload)
1311
+ self.gegrid.addWidget(self.butge, 5, 0, 1, 1)
1312
+ # load file
1313
+ self.butge2 = mQPushButton('Load Chemdraw file..', ctip, 14)
1314
+ self.butge2.clicked.connect(self.qgeomload2)
1315
+ self.gegrid.addWidget(self.butge2, 5, 1, 1, 1)
1316
+ # button for addition
1317
+ ctip = 'Add new geometry to database'
1318
+ self.butgAub = mQPushButton('Add', ctip, 14)
1319
+ self.butgAub.clicked.connect(self.qaddg)
1320
+ self.gegrid.addWidget(self.butgAub, 6, 0, 1, 1)
1321
+ # button for removal
1322
+ ctip = 'Remove geometry from database'
1323
+ self.butgDub = mQPushButton('Remove', ctip, 14)
1324
+ self.butgDub.clicked.connect(self.qdelg)
1325
+ self.gegrid.addWidget(self.butgDub, 6, 1, 1, 1)
1326
+ # button for return
1327
+ ctip = 'Return to main menu'
1328
+ self.butgRet = mQPushButton('Return', ctip, 14)
1329
+ self.butgRet.clicked.connect(self.qretmain)
1330
+ self.gegrid.addWidget(self.butgRet, 7, 1, 1, 1)
1331
+ # ###############################
1332
+ # ## create ligands 2D window ###
1333
+ # ###############################
1334
+ self.lwindow = QWidget()
1335
+ self.lwindow.setPalette(p)
1336
+ self.lgrid = QGridLayout()
1337
+ self.lwindow.setLayout(self.lgrid)
1338
+ # self.sgrid.addWidget(self.lwindow)
1339
+ self.lwindow.setWindowTitle('Ligands 2D')
1340
+ self.c1p = QWidget()
1341
+ # ###################
1342
+ # ###################
1343
+ # ###################
1344
+ # ## Run main GUI ###
1345
+ # ###################
1346
+ # ###################
1347
+ # ###################
1348
+ self.wmain.setLayout(self.grid)
1349
+ self.wmwindow.setCentralWidget(self.wmain)
1350
+ self.sgrid.setCurrentWidget(self.wmain)
1351
+ self.wmain.showMaximized()
1352
+ self.wmwindow.showMaximized()
1353
+ # resize other windows
1354
+ relresize(self.iWind, self.wmwindow, 0.7)
1355
+ relresize(self.iWtxt, self.iWind, 1.0)
1356
+
1357
+ def update_ligands_binds(self):
1358
+ # this function updates the list
1359
+ # of ligand and binding species
1360
+ ctip0 = 'Ligand(s) to be used'
1361
+ self.rtligh = mQLabel('Ligand', ctip0, 'c', 12) # ligand header
1362
+ f = QFont("Helvetica", 12, 75)
1363
+ self.rtligh.setFont(f)
1364
+ # add to layout
1365
+ self.grid.addWidget(self.rtligh, 9, 0, 1, 2)
1366
+ # ligands #
1367
+ licores = list(sorted(getlicores()))
1368
+ self.lig = []
1369
+ self.ligocc = []
1370
+ self.ligconn = []
1371
+ self.ligH = []
1372
+ self.ligML = []
1373
+ self.ligan = []
1374
+ self.lignam = []
1375
+ self.ligadd = []
1376
+ for ii in range(0, 8):
1377
+ # ligands #
1378
+ self.lig.append(mQLineEditL('', ctip0, 'l', 12, licores))
1379
+ self.grid.addWidget(self.lig[ii], 10+ii, 0, 1, 2) # add to layout
1380
+ # ligand buttons #
1381
+ #############################################
1382
+
1383
+ '''
1384
+ #############################
1385
+ ### Callbacks for buttons ###
1386
+ #############################
1387
+ '''
1388
+ # ##################################
1389
+ # ##### Add new ligands input ######
1390
+ # ##################################
1391
+
1392
+ def addlig0(self):
1393
+ idx = 0
1394
+ txt0 = self.lig[idx].currentText().replace(' ', '')
1395
+ if len(txt0) == 0:
1396
+ mQDialogWarn('No ligand specified',
1397
+ 'Please specify a ligand before adding another one.')
1398
+ else:
1399
+ self.ligadd[idx].setDisabled(True)
1400
+ self.ligadd[idx].hide()
1401
+ self.ligadd[idx+1].setDisabled(False)
1402
+ self.ligadd[idx+1].show()
1403
+ self.lig[idx+1].setDisabled(False)
1404
+ self.ligocc[idx+1].setDisabled(False)
1405
+ self.ligconn[idx+1].setDisabled(False)
1406
+ self.ligH[idx+1].setDisabled(False)
1407
+ self.ligML[idx+1].setDisabled(False)
1408
+ self.ligan[idx+1].setDisabled(False)
1409
+ self.lignam[idx+1].setDisabled(False)
1410
+
1411
+ def addlig1(self):
1412
+ idx = 1
1413
+ txt0 = self.lig[idx].currentText().replace(' ', '')
1414
+ if len(txt0) == 0:
1415
+ mQDialogWarn('No ligand specified',
1416
+ 'Please specify a ligand before adding another one.')
1417
+ else:
1418
+ self.ligadd[idx].setDisabled(True)
1419
+ self.ligadd[idx].hide()
1420
+ self.ligadd[idx+1].setDisabled(False)
1421
+ self.ligadd[idx+1].show()
1422
+ self.lig[idx+1].setDisabled(False)
1423
+ self.ligocc[idx+1].setDisabled(False)
1424
+ self.ligconn[idx+1].setDisabled(False)
1425
+ self.ligH[idx+1].setDisabled(False)
1426
+ self.ligML[idx+1].setDisabled(False)
1427
+ self.ligan[idx+1].setDisabled(False)
1428
+ self.lignam[idx+1].setDisabled(False)
1429
+
1430
+ def addlig2(self):
1431
+ idx = 2
1432
+ txt0 = self.lig[idx].currentText().replace(' ', '')
1433
+ if len(txt0) == 0:
1434
+ mQDialogWarn('No ligand specified',
1435
+ 'Please specify a ligand before adding another one.')
1436
+ else:
1437
+ self.ligadd[idx].setDisabled(True)
1438
+ self.ligadd[idx].hide()
1439
+ self.ligadd[idx+1].setDisabled(False)
1440
+ self.ligadd[idx+1].show()
1441
+ self.lig[idx+1].setDisabled(False)
1442
+ self.ligocc[idx+1].setDisabled(False)
1443
+ self.ligconn[idx+1].setDisabled(False)
1444
+ self.ligH[idx+1].setDisabled(False)
1445
+ self.ligML[idx+1].setDisabled(False)
1446
+ self.ligan[idx+1].setDisabled(False)
1447
+ self.lignam[idx+1].setDisabled(False)
1448
+
1449
+ def addlig3(self):
1450
+ idx = 3
1451
+ txt0 = self.lig[idx].currentText().replace(' ', '')
1452
+ if len(txt0) == 0:
1453
+ mQDialogWarn('No ligand specified',
1454
+ 'Please specify a ligand before adding another one.')
1455
+ else:
1456
+ self.ligadd[idx].setDisabled(True)
1457
+ self.ligadd[idx].hide()
1458
+ self.ligadd[idx+1].setDisabled(False)
1459
+ self.ligadd[idx+1].show()
1460
+ self.lig[idx+1].setDisabled(False)
1461
+ self.ligocc[idx+1].setDisabled(False)
1462
+ self.ligconn[idx+1].setDisabled(False)
1463
+ self.ligH[idx+1].setDisabled(False)
1464
+ self.ligML[idx+1].setDisabled(False)
1465
+ self.ligan[idx+1].setDisabled(False)
1466
+ self.lignam[idx+1].setDisabled(False)
1467
+
1468
+ def addlig4(self):
1469
+ idx = 4
1470
+ txt0 = self.lig[idx].currentText().replace(' ', '')
1471
+ if len(txt0) == 0:
1472
+ mQDialogWarn('No ligand specified',
1473
+ 'Please specify a ligand before adding another one.')
1474
+ else:
1475
+ self.ligadd[idx].setDisabled(True)
1476
+ self.ligadd[idx].hide()
1477
+ self.ligadd[idx+1].setDisabled(False)
1478
+ self.ligadd[idx+1].show()
1479
+ self.lig[idx+1].setDisabled(False)
1480
+ self.ligocc[idx+1].setDisabled(False)
1481
+ self.ligconn[idx+1].setDisabled(False)
1482
+ self.ligH[idx+1].setDisabled(False)
1483
+ self.ligML[idx+1].setDisabled(False)
1484
+ self.ligan[idx+1].setDisabled(False)
1485
+ self.lignam[idx+1].setDisabled(False)
1486
+
1487
+ def addlig5(self):
1488
+ idx = 5
1489
+ txt0 = self.lig[idx].currentText().replace(' ', '')
1490
+ if len(txt0) == 0:
1491
+ mQDialogWarn('No ligand specified',
1492
+ 'Please specify a ligand before adding another one.')
1493
+ else:
1494
+ self.ligadd[idx].setDisabled(True)
1495
+ self.ligadd[idx].hide()
1496
+ self.ligadd[idx+1].setDisabled(False)
1497
+ self.ligadd[idx+1].show()
1498
+ self.lig[idx+1].setDisabled(False)
1499
+ self.ligocc[idx+1].setDisabled(False)
1500
+ self.ligconn[idx+1].setDisabled(False)
1501
+ self.ligH[idx+1].setDisabled(False)
1502
+ self.ligML[idx+1].setDisabled(False)
1503
+ self.ligan[idx+1].setDisabled(False)
1504
+ self.lignam[idx+1].setDisabled(False)
1505
+
1506
+ def addlig6(self):
1507
+ idx = 6
1508
+ txt0 = self.lig[idx].currentText().replace(' ', '')
1509
+ if len(txt0) == 0:
1510
+ mQDialogWarn('No ligand specified',
1511
+ 'Please specify a ligand before adding another one.')
1512
+ else:
1513
+ self.ligadd[idx].setDisabled(True)
1514
+ self.ligadd[idx].hide()
1515
+ self.ligadd[idx+1].setDisabled(False)
1516
+ self.ligadd[idx+1].show()
1517
+ self.lig[idx+1].setDisabled(False)
1518
+ self.ligocc[idx+1].setDisabled(False)
1519
+ self.ligconn[idx+1].setDisabled(False)
1520
+ self.ligH[idx+1].setDisabled(False)
1521
+ self.ligML[idx+1].setDisabled(False)
1522
+ self.ligan[idx+1].setDisabled(False)
1523
+ self.lignam[idx+1].setDisabled(False)
1524
+
1525
+ def checkaxial(self):
1526
+ if self.dmolp.currentIndex() > 0:
1527
+ self.etplacephi.setText('')
1528
+ self.etplacephi.setDisabled(True)
1529
+ self.etplacetheta.setText('')
1530
+ self.etplacetheta.setDisabled(True)
1531
+ else:
1532
+ self.etplacephi.setDisabled(False)
1533
+ self.etplacetheta.setDisabled(False)
1534
+ # #############################
1535
+ # ## Local Database window ####
1536
+ # #############################
1537
+ # load molecule from file
1538
+
1539
+ def qDBload(self):
1540
+ name = QFileDialog.getOpenFileName(
1541
+ self.DBWindow, 'Open File', '.', "Molecule files *.xyz, *.mol (*.xyz *.mol)")
1542
+ if name[0] != '':
1543
+ self.etDBsmi.setText(os.path.relpath(name[0]))
1544
+ # enable add to database interface
1545
+
1546
+ def enableDB(self):
1547
+ self.DBWindow.setWindowModality(2)
1548
+ self.DBWindow.show()
1549
+ self.sgrid.setCurrentWidget(self.DBWindow)
1550
+ # callback for addition button, adds to database
1551
+
1552
+ def qaddDB(self):
1553
+ coption = self.DBsel.currentText()
1554
+ smimol = self.etDBsmi.text()
1555
+ sminame = self.etDBname.text()
1556
+ smident = self.DBdent.currentText()
1557
+ smicat = self.etDBsmicat.text()
1558
+ smigrps = self.etDBgrps.text()
1559
+ smictg = self.etDBctg.currentText()
1560
+ globs = globalvars()
1561
+ if not globs.custom_path: # this will be false unless set
1562
+ choice = QMessageBox.question(self.cDBWindow, 'Custom path needed',
1563
+ 'In order to add to the database, you'
1564
+ ' need to select a local path for '
1565
+ 'molSimplify to store data files. '
1566
+ 'Would you like to configure it now?',
1567
+ QMessageBox.Yes, QMessageBox.No)
1568
+ if choice == QMessageBox.Yes:
1569
+ QMessageBox.information(
1570
+ self.cDBWindow, 'Custom path needed',
1571
+ "Please select a local, user-writable location.")
1572
+ new_path = QFileDialog.getExistingDirectory(
1573
+ self.cDBWindow, 'Select a writable directory.')
1574
+ if len(new_path) > 0:
1575
+ globs.add_custom_path(new_path)
1576
+ globs.custom_path = new_path
1577
+ copy_to_custom_path() # this function lives in scripts/io.py
1578
+ # instdir = globs.installdir
1579
+ if self.lFFb.getState() and self.lFFa.getState():
1580
+ ffopt = 'BA'
1581
+ elif self.lFFb.getState() and not self.lFFa.getState():
1582
+ ffopt = 'B'
1583
+ elif not self.lFFb.getState() and self.lFFa.getState():
1584
+ ffopt = 'A'
1585
+ else:
1586
+ ffopt = 'N'
1587
+ if smictg == 'all':
1588
+ smictg = 'build functionalize'
1589
+ if smimol == '' or sminame == '':
1590
+ _ = QMessageBox.warning(
1591
+ self.DBWindow, 'Error', 'Please specify molecule and name!')
1592
+ else:
1593
+ # add to database
1594
+ emsg = ''
1595
+ if 'ligand' in coption:
1596
+ emsg = addtoldb(smimol, sminame, smident,
1597
+ smicat, smigrps, smictg, ffopt)
1598
+ elif 'core' in coption:
1599
+ emsg = addtocdb(smimol, sminame, smicat)
1600
+ elif 'bind' in coption:
1601
+ emsg = addtobdb(smimol, sminame)
1602
+ if emsg:
1603
+ _ = QMessageBox.warning(self.DBWindow, 'Error', emsg)
1604
+ else:
1605
+ _ = QMessageBox.information(
1606
+ self.DBWindow, 'Add', 'Successfully added to the database!')
1607
+ self.update_ligands_binds()
1608
+ # callback for removal button, removes from db
1609
+
1610
+ def qdelDB(self):
1611
+ globs = globalvars()
1612
+ if not globs.custom_path: # this will be false unless set
1613
+ choice = QMessageBox.question(self.cDBWindow, 'Custom path needed',
1614
+ 'In order to add to the database, you'
1615
+ ' need to select a local path for '
1616
+ 'molSimplify to store data files. '
1617
+ 'Would you like to configure it now?',
1618
+ QMessageBox.Yes, QMessageBox.No)
1619
+ if choice == QMessageBox.Yes:
1620
+ QMessageBox.information(
1621
+ self.cDBWindow, 'Custom path needed',
1622
+ "Please select a local, user-writable location.")
1623
+ new_path = QFileDialog.getExistingDirectory(
1624
+ self.cDBWindow, 'Select a writable directory.')
1625
+ if len(new_path) > 0:
1626
+ globs.add_custom_path(new_path)
1627
+ copy_to_custom_path() # this function lives in scripts/io.py
1628
+
1629
+ coption = self.DBsel.currentIndex()
1630
+ sminame = self.etDBname.text()
1631
+ if sminame == '':
1632
+ _ = QMessageBox.warning(
1633
+ self.DBWindow, 'Error', 'Please specify name!')
1634
+ else:
1635
+ # remove from database
1636
+ emsg = removefromDB(sminame, int(coption))
1637
+ if emsg:
1638
+ _ = QMessageBox.warning(self.DBWindow, 'Error', emsg)
1639
+ else:
1640
+ _ = QMessageBox.information(
1641
+ self.DBWindow, 'Remove', 'Removed from the database!')
1642
+ # db type change
1643
+
1644
+ def dbchange(self):
1645
+ ci = self.DBsel.currentIndex()
1646
+ if ci == 1:
1647
+ self.rtDBsmident.setDisabled(False)
1648
+ self.DBdent.setDisabled(False)
1649
+ self.rtDBsmicat.setDisabled(False)
1650
+ self.etDBsmicat.setDisabled(False)
1651
+ self.etDBgrps.setDisabled(False)
1652
+ self.etDBgrps.setDisabled(False)
1653
+ self.lFFb.setDisabled(False)
1654
+ self.lFFa.setDisabled(False)
1655
+ elif ci == 0:
1656
+ self.rtDBsmident.setDisabled(True)
1657
+ self.DBdent.setDisabled(True)
1658
+ self.rtDBsmicat.setDisabled(False)
1659
+ self.etDBsmicat.setDisabled(False)
1660
+ self.etDBgrps.setDisabled(True)
1661
+ self.etDBgrps.setDisabled(True)
1662
+ self.lFFb.setDisabled(True)
1663
+ self.lFFa.setDisabled(True)
1664
+ else:
1665
+ self.rtDBsmident.setDisabled(True)
1666
+ self.DBdent.setDisabled(True)
1667
+ self.rtDBsmicat.setDisabled(True)
1668
+ self.etDBsmicat.setDisabled(True)
1669
+ self.etDBgrps.setDisabled(True)
1670
+ self.etDBgrps.setDisabled(True)
1671
+ self.lFFb.setDisabled(True)
1672
+ self.lFFa.setDisabled(True)
1673
+ # perform post-processing
1674
+
1675
+ def postprocGUI(self):
1676
+ rdir = self.etpdir.text()
1677
+ if rdir[-1] == '/':
1678
+ rdir = rdir[:-1]
1679
+ defaultparams = ['main.py', '-i', rdir+'/postproc.inp']
1680
+ grabguivarsP(self)
1681
+ self.pWindow.close()
1682
+ self.sgrid.setCurrentWidget(self.iWind)
1683
+ emsg = startgen(defaultparams, True, self)
1684
+ if not emsg:
1685
+ QMessageBox.information(
1686
+ self.pWindow, 'DONE', 'Your results are ready..')
1687
+ # ############################
1688
+ # ### Add geometry window ####
1689
+ # ############################
1690
+ # load molecule from file
1691
+
1692
+ def qgeomload(self):
1693
+ name = QFileDialog.getOpenFileName(
1694
+ self.DBWindow, 'Open File', '.', "Molecule files *.xyz (*.xyz)")
1695
+ if name[0] != '':
1696
+ self.etgf.setText(os.path.relpath(name[0]))
1697
+ # load png from file
1698
+
1699
+ def qgeomload2(self):
1700
+ name = QFileDialog.getOpenFileName(
1701
+ self.DBWindow, 'Open File', '.', "Geometry image files *.png (*.png)")
1702
+ if name[0] != '':
1703
+ self.etgfc.setText(os.path.relpath(name[0]))
1704
+ # enable add new geometry
1705
+
1706
+ def addgeom(self):
1707
+ self.geWindow.setWindowModality(2)
1708
+ self.geWindow.show()
1709
+ # callback for addition button, adds to database
1710
+
1711
+ def qaddg(self):
1712
+ globs = globalvars()
1713
+ if not globs.custom_path: # this will be false unless set
1714
+ choice = QMessageBox.question(self.cDBWindow, 'Custom path needed',
1715
+ 'In order to add to the database, you'
1716
+ ' need to select a local path for '
1717
+ 'molSimplify to store data files. '
1718
+ 'Would you like to configure it now?',
1719
+ QMessageBox.Yes, QMessageBox.No)
1720
+ if choice == QMessageBox.Yes:
1721
+ QMessageBox.information(
1722
+ self.cDBWindow, 'Custom path needed', "Please select a local, user-writable location.")
1723
+ new_path = QFileDialog.getExistingDirectory(
1724
+ self.cDBWindow, 'Select a writable directory.')
1725
+ if len(new_path) > 0:
1726
+ globs.add_custom_path(new_path)
1727
+ copy_to_custom_path() # this funciton lives in scripts/io.py
1728
+ gname = self.etgname.text().lower()
1729
+ gname = gname.replace(' ', '_')
1730
+ gfile = self.etgf.text()
1731
+ if gname == '' or gfile == '':
1732
+ _ = QMessageBox.warning(
1733
+ self.geWindow, 'Error', 'Please specify name and xyz file!')
1734
+ elif not glob.glob(gfile):
1735
+ _ = QMessageBox.warning(
1736
+ self.geWindow, 'Error', 'XYZ file '+gfile+' does not exist!')
1737
+ else:
1738
+ globs = globalvars()
1739
+ if globs.custom_path:
1740
+ f = globs.custom_path + "/Data/coordinations.dict"
1741
+ else:
1742
+ f = str(resource_files("molSimplify").joinpath("Data/coordinations.dict"))
1743
+ with open(f, 'r') as fl:
1744
+ s = fl.read().splitlines()
1745
+ if gname.lower() in s:
1746
+ _ = QMessageBox.warning(
1747
+ self.geWindow, 'Add', 'Coordination '+gname+' already exists.')
1748
+ return
1749
+
1750
+ gshort = self.etgshort.text()
1751
+ cfile = self.etgfc.text()
1752
+ # get geometry from xyz file
1753
+ with open(gfile, 'r') as f:
1754
+ snew = f.read().splitlines()
1755
+ dent = int(snew[0])-1
1756
+ xyzl = ''
1757
+ for ii in range(0, dent+1):
1758
+ li = [_f for _f in re.split(' |\t', snew[2+ii]) if _f]
1759
+ xyzl += li[1]+' '+li[2]+' '+li[3]+'\n'
1760
+ # write new entry in coordinations.dict
1761
+ s.append(str(dent)+': '+gname+' '+gshort)
1762
+ ssort = [_f for _f in list(sorted(s[1:])) if _f]
1763
+ globs = globalvars()
1764
+ if globs.custom_path:
1765
+ f = globs.custom_path + "/Data/coordinations.dict"
1766
+ else:
1767
+ print('Error, please set custom file path')
1768
+ QMessageBox.warning(
1769
+ self.wmain, 'Error, please set custom file path (dd to database)')
1770
+ with open(f, 'w') as fl:
1771
+ fl.write(s[0]+'\n')
1772
+ for ss in ssort:
1773
+ fl.write(ss+'\n')
1774
+ # write new backbone file
1775
+ if globs.custom_path:
1776
+ f = globs.custom_path + "/Data/"
1777
+ else:
1778
+ print('Error, please set custom file path')
1779
+ QMessageBox.warning(
1780
+ self.wmain, 'Error, please set custom file path (dd to database)')
1781
+ with open(f+gshort+'.dat', 'w') as fl:
1782
+ fl.write(xyzl)
1783
+ # write png file
1784
+ if glob.glob(cfile):
1785
+ f = str(resource_files("molSimplify").joinpath("icons/geoms/"))
1786
+ shutil.copy2(cfile, f+gshort+'.png')
1787
+ choice = QMessageBox.information(
1788
+ self.geWindow, 'Add', 'Successfully added to the database!')
1789
+ self.matchgeomcoord()
1790
+
1791
+ # callback for removal button, removes from db
1792
+ def qdelg(self):
1793
+ globs = globalvars()
1794
+ if not globs.custom_path: # this will be false unless set
1795
+ choice = QMessageBox.question(self.cDBWindow, 'Custom path needed',
1796
+ 'In order to add to the database, you'
1797
+ ' need to select a local path for '
1798
+ 'molSimplify to store data files. '
1799
+ 'Would you like to configure it now?',
1800
+ QMessageBox.Yes, QMessageBox.No)
1801
+ if choice == QMessageBox.Yes:
1802
+ QMessageBox.information(
1803
+ self.cDBWindow, 'Custom path needed', "Please select a local, user-writable location.")
1804
+ new_path = QFileDialog.getExistingDirectory(
1805
+ self.cDBWindow, 'Select a writable directory.')
1806
+ if len(new_path) > 0:
1807
+ globs.add_custom_path(new_path)
1808
+ copy_to_custom_path() # this funciton lives in scripts/io.py
1809
+
1810
+ globs = globalvars()
1811
+ gname = self.etgname.text().lower()
1812
+ gname = gname.replace(' ', '_')
1813
+ gshort = self.etgshort.text()
1814
+ if gname == '' and gshort == '':
1815
+ _ = QMessageBox.warning(
1816
+ self.geWindow, 'Error', 'Please specify geometry name!')
1817
+ else:
1818
+ if globs.custom_path:
1819
+ f = globs.custom_path + "/Data/coordinations.dict"
1820
+ else:
1821
+ f = str(resource_files("molSimplify").joinpath("Data/coordinations.dict"))
1822
+ with open(f, 'r') as fl:
1823
+ s = fl.read()
1824
+ if gname.lower() not in s and gshort.lower() not in s:
1825
+ _ = QMessageBox.warning(
1826
+ self.geWindow, 'Remove', 'Coordination '+gname+' does not exist.')
1827
+ return
1828
+ # remove entry from coordinations.dict
1829
+ snew = ''
1830
+ srem = ''
1831
+ for ss in s.splitlines():
1832
+ sl = [_f for _f in ss.split(' ') if _f]
1833
+ if gname.lower() != sl[1] and gshort.lower() != sl[2]:
1834
+ snew += ss+'\n'
1835
+ else:
1836
+ srem = [_f for _f in ss.split(' ')[-1] if _f]
1837
+ if globs.custom_path:
1838
+ f = globs.custom_path + "/Data/coordinations.dict"
1839
+ else:
1840
+ f = str(resource_files("molSimplify").joinpath("Data/coordinations.dict"))
1841
+ with open(f, 'w') as fl:
1842
+ fl.write(snew)
1843
+ # remove file
1844
+ if glob.glob(str(globs.custom_path)+'/Data/'+srem+'.dat'):
1845
+ os.remove(str(globs.custom_path)+'/Data/'+srem+'.dat')
1846
+ _ = QMessageBox.information(
1847
+ self.geWindow, 'Remove', 'Successfully removed from the database!')
1848
+ self.matchgeomcoord()
1849
+ # ############################
1850
+ # ## Chem Database window ####
1851
+ # ############################
1852
+ # load molecule from file
1853
+
1854
+ def qcDBload(self):
1855
+ name = QFileDialog.getOpenFileName(
1856
+ self.DBWindow, 'Open File', '.', "Molecule files *.xyz, *.mol *.sdf *.smi (*.xyz *.mol *.sdf *.smi)")
1857
+ if name[0] != '':
1858
+ self.etcDBsmi.setText(os.path.relpath(name[0]))
1859
+ # enable add to database interface
1860
+
1861
+ def searchDBW(self):
1862
+ globs = globalvars()
1863
+ self.cDBWindow.setWindowModality(2)
1864
+ self.cDBWindow.show()
1865
+ writef = False
1866
+ # instdir = globs.installdir
1867
+ mwfn = globs.multiwfn
1868
+ cdbdir = globs.chemdbdir
1869
+ if not os.path.isdir(globs.chemdbdir):
1870
+ choice = QMessageBox.question(self.cDBWindow, 'Database setup',
1871
+ 'It looks like the Chemical Database'
1872
+ ' directory is not configured or '
1873
+ 'does not exist. Would you like '
1874
+ 'to configure it now?',
1875
+ QMessageBox.Yes, QMessageBox.No)
1876
+ if choice == QMessageBox.Yes:
1877
+ QMessageBox.information(
1878
+ self.cDBWindow, 'Chem DB', "Please select the directory containing chemical databases.")
1879
+ cdbdir = QFileDialog.getExistingDirectory(
1880
+ self.cDBWindow, 'Select the directory containing chemical databases.')
1881
+ if len(cdbdir) > 0:
1882
+ writef = True
1883
+ if writef:
1884
+ with open(globs.homedir+'/.molSimplify', 'w') as f:
1885
+ # f.write("INSTALLDIR="+instdir+'\n')
1886
+ f.write("CHEMDBDIR="+cdbdir+'\n')
1887
+ if len(mwfn) > 1:
1888
+ f.write("MULTIWFN="+mwfn[0]+'\n')
1889
+ # get existing databases
1890
+ globsnew = globalvars()
1891
+ dbdir = globsnew.chemdbdir
1892
+ dbs0 = glob.glob(dbdir+"/*.sdf")
1893
+ dbs1 = [d.rsplit('/', 1)[-1] for d in dbs0]
1894
+ dbs = [d.split('.', 1)[0] for d in dbs1]
1895
+ for d in dbs:
1896
+ self.cDBsel.addItem(d)
1897
+ # callback for database search
1898
+
1899
+ def qaddcDB(self):
1900
+ """Collects all the info and passes it to molSimplify."""
1901
+ rdir = self.etrdir.text()
1902
+ if rdir[-1] == '/':
1903
+ rdir = rdir[:-1]
1904
+ # create running dir if not existing
1905
+ if not os.path.isdir(rdir):
1906
+ os.mkdir(rdir)
1907
+ grabdbguivars(self)
1908
+ defaultparams = ['main.py', '-i', rdir+'/dbinput.inp']
1909
+ emsg = startgen(defaultparams, True, self)
1910
+ if not emsg:
1911
+ QMessageBox.information(
1912
+ self.cDBWindow, 'DONE', 'Search is done..')
1913
+ self.sgrid.setCurrentWidget(self.cDBWindow)
1914
+ # db type change
1915
+
1916
+ def cdbchange(self):
1917
+ ci = self.DBsel.currentIndex()
1918
+ if (ci == 1):
1919
+ self.rtDBsmident.setDisabled(False)
1920
+ self.DBdent.setDisabled(False)
1921
+ self.rtDBsmicat.setDisabled(False)
1922
+ self.etDBsmicat.setDisabled(False)
1923
+ else:
1924
+ self.rtDBsmident.setDisabled(True)
1925
+ self.DBdent.setDisabled(True)
1926
+ self.rtDBsmicat.setDisabled(True)
1927
+ self.etDBsmicat.setDisabled(True)
1928
+ # ###################
1929
+ # ## Main window ####
1930
+ # ###################
1931
+ # run generation
1932
+
1933
+ def runGUI(self):
1934
+ # collects all the info and passes it to molSimplify #
1935
+ rdir = self.etrdir.text()
1936
+ if rdir[-1] == '/':
1937
+ rdir = rdir[:-1]
1938
+ # create running dir if not existing
1939
+ if not os.path.isdir(rdir):
1940
+ try:
1941
+ os.mkdir(rdir)
1942
+ except FileExistsError:
1943
+ emsg = 'Directory '+rdir+' could not be created. Check your input.\n'
1944
+ QMessageBox.critical(self.wmain, 'Problem', emsg)
1945
+ return
1946
+ # check for extra molecule
1947
+ if self.chkM.getState() and self.etbind.currentText() == '':
1948
+ emsg = ('You checked the extra molecule box but specified\n'
1949
+ 'no extra molecule. No extra molecule will be generated.\n')
1950
+ QMessageBox.warning(self.wmain, 'Warning', emsg)
1951
+ # get parameters
1952
+ grabguivars(self)
1953
+ defaultparams = ['main.py', '-i', rdir+'/geninput.inp']
1954
+ self.iWind.hide()
1955
+ self.sgrid.setCurrentWidget(self.iWind)
1956
+ self.iWind.show()
1957
+ msgBox = QMessageBox()
1958
+ if self.randomchk.getState():
1959
+ msgBox.setText(
1960
+ "Random generation initiated. This process might take some time.")
1961
+ msgBox.setIcon(1)
1962
+ msgBox.setInformativeText('Please be patient. OK?')
1963
+ msgBox.setWindowTitle('Running..')
1964
+ msgBox.exec_()
1965
+ # do the generation
1966
+ emsg = startgen(defaultparams, True, self)
1967
+ if not emsg:
1968
+ QMessageBox.information(
1969
+ self.wmain, 'Done', 'Structure generation terminated successfully!')
1970
+ else:
1971
+ QMessageBox.warning(self.wmain, 'Problem', emsg)
1972
+ # list molecules
1973
+
1974
+ def listmols(self):
1975
+ coreslist = getcores()
1976
+ liglist = getligs()
1977
+ bindlist = getbinds()
1978
+ msg = 'Available cores in the database:\n'+coreslist
1979
+ msg += '\n\nAvailable ligands in the database:\n'+liglist
1980
+ msg += '\n\nAvailable extra molecules in the database:\n'+bindlist+'\n'
1981
+ QMessageBox.information(self.wmain, 'List of molecules', msg)
1982
+ # draw ligands
1983
+
1984
+ def drawligs_svg(self):
1985
+ """Draw the ligands entered into the GUI as SVGs in a pop-up window"""
1986
+ # collects all the info and passes it to molSimplify #
1987
+ args = grabguivars(self)
1988
+ # processes ligand arguments
1989
+ if len(args['-lig']) < 1:
1990
+ mQDialogWarn('Warning', 'No ligands are specified.')
1991
+ return False
1992
+ else:
1993
+ rows = self.lgrid.rowCount()
1994
+ # Clear existing widgets in layout
1995
+ if rows > 1:
1996
+ for i in reversed(list(range(self.lgrid.count()))):
1997
+ self.lgrid.itemAt(i).widget().setParent(None)
1998
+
1999
+ args['-lig'] = args['-lig'].replace(' ', '')
2000
+ lls = args['-lig'].split(',')
2001
+ liglist = []
2002
+ # check if multiple ligands in .smi file
2003
+ for li in lls:
2004
+ if '.smi' in li:
2005
+ with open(li, 'r') as f:
2006
+ smis = [_f for _f in f.read().splitlines() if _f]
2007
+ liglist += smis
2008
+ else:
2009
+ liglist.append(li)
2010
+ # Get known ligand dictionaries
2011
+ licores = getlicores()
2012
+ simpleligs = getslicores()
2013
+ ligs = []
2014
+ for li in liglist:
2015
+ # check in simple dictionary
2016
+ if li in list(simpleligs.keys()):
2017
+ li = simpleligs[li][0]
2018
+ if isinstance(li, str):
2019
+ ll = unicodedata.normalize(
2020
+ 'NFKD', li).encode('ascii', 'ignore')
2021
+ else:
2022
+ ll = li
2023
+ # load ligands as molecules
2024
+ lig, emsg = lig_load(ll, licores)
2025
+ if emsg:
2026
+ mQDialogWarn('Error', emsg)
2027
+ else:
2028
+ ligs.append(lig.OBMol)
2029
+ if len(ligs) == 0:
2030
+ return
2031
+ else:
2032
+ for i, pmol in enumerate(ligs):
2033
+ # use openbabel to convert to labeled SVG
2034
+ obConversion = openbabel.OBConversion()
2035
+ obConversion.SetOutFormat("svg")
2036
+ obConversion.AddOption("i", obConversion.OUTOPTIONS, "")
2037
+ # return the svg with atom labels as a string
2038
+ svgstr = obConversion.WriteString(pmol)
2039
+ # unpacked nested svg as in pybel._repr_svg_
2040
+ namespace = "http://www.w3.org/2000/svg"
2041
+ ET.register_namespace("", namespace)
2042
+ tree = ET.fromstring(svgstr)
2043
+ svg = tree.find(
2044
+ "{{{ns}}}g/{{{ns}}}svg".format(ns=namespace))
2045
+ newsvg = ET.tostring(svg).decode("utf-8")
2046
+ # write unpacked svg to temp file
2047
+ filedes, filename = tempfile.mkstemp()
2048
+ with open(filename, "w") as svg_file:
2049
+ svg_file.write(newsvg)
2050
+ # Read the temp file into an SvgWidget
2051
+ self.svgwidget = mSvgWidget(filename)
2052
+ # Add the svg to the window
2053
+ self.lgrid.addWidget(self.svgwidget, 0, i)
2054
+ # Cleanup temp files
2055
+ os.close(filedes)
2056
+ os.remove(filename)
2057
+ # Build close button
2058
+ self.lwindow.setWindowTitle('Ligands 2D')
2059
+ self.lwclose = QPushButton('Close')
2060
+ self.lwclose.clicked.connect(self.qcloseligs)
2061
+ # Add close button to window
2062
+ self.lgrid.addWidget(self.lwclose, 1, 0)
2063
+ self.lwindow.show()
2064
+
2065
+ def viewgeom(self):
2066
+ # get geometry
2067
+ geom = self.dcoordg.currentText()
2068
+ gfname = str(resource_files("molSimplify").joinpath(f"icons/geoms/{geom}.png"))
2069
+ if glob.glob(gfname):
2070
+ rows = self.lgrid.rowCount()
2071
+ # Clear existing widgets in layout
2072
+ if rows > 1:
2073
+ for i in reversed(list(range(self.lgrid.count()))):
2074
+ self.lgrid.itemAt(i).widget().setParent(None)
2075
+ self.c1p = mQPixmap(gfname)
2076
+ self.lgrid.addWidget(self.c1p, 0, 0)
2077
+ # button for closing window
2078
+ ctip = 'Close current window'
2079
+ self.lwclose = mQPushButton('Close', ctip, 14)
2080
+ self.lwclose.clicked.connect(self.qcloseligs)
2081
+ self.lgrid.addWidget(self.lwclose, 1, 0)
2082
+ self.lwindow.setWindowTitle('Geometry:'+self.dcoordg.currentText())
2083
+ self.lwindow.show()
2084
+ center(self.lwindow)
2085
+ else:
2086
+ mQDialogWarn('Warning', 'No file '+gfname+' exists..')
2087
+ # draw results from db search
2088
+
2089
+ def drawres(self):
2090
+ # collects all the info and passes it to molSimplify #
2091
+ rdir = self.etrdir.text()
2092
+ if rdir[-1] == '/':
2093
+ rdir = rdir[:-1]
2094
+ # creat running dir if not existing
2095
+ if not os.path.isdir(rdir):
2096
+ os.mkdir(rdir)
2097
+ outf = rdir+'/'+self.etcDBoutf.text()
2098
+ outf = outf.replace(' ', '')+'.smi'
2099
+ if not glob.glob(outf):
2100
+ mQDialogWarn('Warning', 'No database results file in '+rdir)
2101
+ return False
2102
+ else:
2103
+ lls = [outf]
2104
+ liglist = []
2105
+ # check if multiple ligands in .smi file
2106
+ for li in lls:
2107
+ if '.smi' in li:
2108
+ with open(li, 'r') as f:
2109
+ smis = [_f for _f in f.read().splitlines() if _f]
2110
+ liglist += smis
2111
+ else:
2112
+ liglist.append(li)
2113
+ licores = getlicores()
2114
+ ligs = []
2115
+ for li in liglist:
2116
+ if isinstance(li, str):
2117
+ ll = unicodedata.normalize(
2118
+ 'NFKD', li).encode('ascii', 'ignore')
2119
+ else:
2120
+ ll = li
2121
+
2122
+ lig, emsg = lig_load(ll, licores)
2123
+ if not emsg:
2124
+ ligs.append(lig.OBMol)
2125
+ if len(ligs) == 0:
2126
+ return
2127
+ else:
2128
+ for i, pmol in enumerate(ligs):
2129
+ # use openbabel to convert to labeled SVG
2130
+ obConversion = openbabel.OBConversion()
2131
+ obConversion.SetOutFormat("svg")
2132
+ obConversion.AddOption("i", obConversion.OUTOPTIONS, "")
2133
+ # return the svg with atom labels as a string
2134
+ svgstr = obConversion.WriteString(pmol)
2135
+ # unpacked nested svg as in pybel._repr_svg_
2136
+ namespace = "http://www.w3.org/2000/svg"
2137
+ ET.register_namespace("", namespace)
2138
+ tree = ET.fromstring(svgstr)
2139
+ svg = tree.find(
2140
+ "{{{ns}}}g/{{{ns}}}svg".format(ns=namespace))
2141
+ newsvg = ET.tostring(svg).decode("utf-8")
2142
+ # write unpacked svg to temp file
2143
+ filedes, filename = tempfile.mkstemp()
2144
+ with open(filename, "w") as svg_file:
2145
+ svg_file.write(newsvg)
2146
+ # Read the temp file into an SvgWidget
2147
+ self.svgwidget = mSvgWidget(filename)
2148
+ # Add the svg to the window
2149
+ self.lgrid.addWidget(self.svgwidget, 0, i)
2150
+ # Cleanup temp files
2151
+ os.close(filedes)
2152
+ os.remove(filename)
2153
+ # Build close button
2154
+ self.lwindow.setWindowTitle('Ligands 2D')
2155
+ self.lwclose = QPushButton('Close')
2156
+ self.lwclose.clicked.connect(self.qcloseligs)
2157
+ # Add close button to window
2158
+ self.lgrid.addWidget(self.lwclose, 1, 0)
2159
+ self.lwindow.show()
2160
+ # enable random input
2161
+
2162
+ def enablerandom(self):
2163
+ if self.randomchk.isChecked():
2164
+ self.rtrgen.setDisabled(False)
2165
+ self.etrgen.setDisabled(False)
2166
+ self.rtlignum.setDisabled(False)
2167
+ self.etlignum.setDisabled(False)
2168
+ self.rtliggrp.setDisabled(False)
2169
+ self.etliggrp.setDisabled(False)
2170
+ self.rtligctg.setDisabled(False)
2171
+ self.etligctg.setDisabled(False)
2172
+ self.randkHs.setDisabled(False)
2173
+ if len(self.etrgen.text()) == 0:
2174
+ self.etrgen.setText('1')
2175
+ else:
2176
+ self.rtrgen.setDisabled(True)
2177
+ self.etrgen.setDisabled(True)
2178
+ self.rtlignum.setDisabled(True)
2179
+ self.etlignum.setDisabled(True)
2180
+ self.rtliggrp.setDisabled(True)
2181
+ self.etliggrp.setDisabled(True)
2182
+ self.rtligctg.setDisabled(True)
2183
+ self.etligctg.setDisabled(True)
2184
+ self.randkHs.setDisabled(True)
2185
+ # generate all enable FF input
2186
+
2187
+ def disableffinput(self):
2188
+ if self.chkgenall.isChecked():
2189
+ self.dff.setDisabled(True)
2190
+ self.dffba.setDisabled(True)
2191
+ self.chkFF.state = True
2192
+ self.chkFF.setDisabled(True)
2193
+ else:
2194
+ self.dff.setDisabled(False)
2195
+ self.dffba.setDisabled(False)
2196
+ self.chkFF.setDisabled(False)
2197
+ self.enableffinput()
2198
+ # enable FF input
2199
+
2200
+ def enableffinput(self):
2201
+ if self.chkFF.isChecked():
2202
+ self.chkFF.state = False
2203
+ self.dff.setDisabled(False)
2204
+ self.dffba.setDisabled(False)
2205
+ else:
2206
+ self.dff.setDisabled(True)
2207
+ self.dffba.setDisabled(True)
2208
+ self.chkFF.state = True
2209
+ # load file for editing
2210
+
2211
+ def qloadinput(self):
2212
+ name = QFileDialog.getOpenFileName(self.wmain, 'Open File')[0]
2213
+ if name != '':
2214
+ loadfrominputfile(self, name)
2215
+ # load directory
2216
+
2217
+ def dirload(self):
2218
+ name = QFileDialog.getExistingDirectory(self.wmain, 'Select Directory')
2219
+ if len(name) > 0 and name[0] != '':
2220
+ self.etrdir.setText(name)
2221
+ # save as input file
2222
+
2223
+ def qsaveinput(self, gui):
2224
+ name = QFileDialog.getSaveFileName(
2225
+ self.wmain, 'Save as..', '.', "Input files * (*)")[0]
2226
+ if name != '':
2227
+ varsg = grabguivars(self)
2228
+ writeinputc(varsg, name)
2229
+ # show help menu
2230
+
2231
+ def qshowhelp(self):
2232
+ globs = globalvars()
2233
+ QMessageBox.information(self.wmain, 'About', globs.about)
2234
+
2235
+ def getscreensize(self):
2236
+ screenShape = QDesktopWidget().screenGeometry()
2237
+ width = int(screenShape.width())
2238
+ height = int(screenShape.height())
2239
+ return [width, height]
2240
+ # slider changed value
2241
+
2242
+ def sliderChanged(self, val):
2243
+ self.distper.setText('Distort:'+str(val)+'%')
2244
+ # match index with coordination
2245
+
2246
+ def matchgeomcoord(self):
2247
+ # get current index
2248
+ dc = self.dcoord.currentIndex()
2249
+ coords, geomnames, geomshorts, geomgroups = getgeoms()
2250
+ qcav = geomgroups
2251
+ ctip = geomnames
2252
+ # empty the box
2253
+ for i in range(0, self.dcoordg.count()):
2254
+ self.dcoordg.removeItem(0)
2255
+ qc = qcav[dc]
2256
+ # add to box
2257
+ for i, t in enumerate(qc):
2258
+ # File f is never actually used? RM 2022/02/17
2259
+ f = str(resource_files("molSimplify").joinpath(f"icons/geoms/{t}.png")) # noqa F841
2260
+ self.dcoordg.addItem(QIcon(t), t)
2261
+ self.dcoordg.setIconSize(QSize(60, 60))
2262
+ # set default geometry
2263
+ self.dcoordg.setCurrentIndex(0)
2264
+ # get global index
2265
+ elem = [i for i, s in enumerate(
2266
+ geomshorts) if s in self.dcoordg.currentText()]
2267
+ ct = ''
2268
+ for ii in range(elem[0], elem[0]+len(geomgroups[dc])):
2269
+ ct += ctip[ii]+', '
2270
+ ct = ct[:-2]
2271
+ # set correct tooltip
2272
+ self.dcoordg.setToolTip(ct)
2273
+ # enable extra molecule input
2274
+
2275
+ def enableemol(self):
2276
+ if self.chkM.isChecked():
2277
+ self.chkM.state = False
2278
+ self.txtamol.setDisabled(False)
2279
+ self.rtbind.setDisabled(False)
2280
+ self.etbind.setDisabled(False)
2281
+ self.rtbsmi.setDisabled(False)
2282
+ self.etbsmi.setDisabled(False)
2283
+ self.rtnbind.setDisabled(False)
2284
+ self.etnbind.setDisabled(False)
2285
+ if self.etnbind.text() == '':
2286
+ self.etnbind.setText('1')
2287
+ self.rtplace.setDisabled(False)
2288
+ self.etplacemin.setDisabled(False)
2289
+ self.etplacemax.setDisabled(False)
2290
+ self.dmolp.setDisabled(False)
2291
+ self.rtchbind.setDisabled(False)
2292
+ self.etchbind.setDisabled(False)
2293
+ self.rtplacea.setDisabled(False)
2294
+ self.etplacephi.setDisabled(False)
2295
+ self.etplacetheta.setDisabled(False)
2296
+ # self.rtmaskbind.setDisabled(False)
2297
+ self.etmaskbind.setDisabled(False)
2298
+ self.chsep.setDisabled(False)
2299
+ else:
2300
+ self.txtamol.setDisabled(True)
2301
+ self.rtbind.setDisabled(True)
2302
+ self.etbind.setDisabled(True)
2303
+ self.rtbsmi.setDisabled(True)
2304
+ self.etbsmi.setDisabled(True)
2305
+ self.rtnbind.setDisabled(True)
2306
+ self.etnbind.setDisabled(True)
2307
+ self.rtplace.setDisabled(True)
2308
+ self.etplacemin.setDisabled(True)
2309
+ self.etplacemax.setDisabled(True)
2310
+ self.dmolp.setDisabled(True)
2311
+ self.chkM.state = True
2312
+ self.rtchbind.setDisabled(True)
2313
+ self.etchbind.setDisabled(True)
2314
+ self.rtplacea.setDisabled(True)
2315
+ self.etplacephi.setDisabled(True)
2316
+ self.etplacetheta.setDisabled(True)
2317
+ # self.rtmaskbind.setDisabled(True)
2318
+ self.etmaskbind.setDisabled(True)
2319
+ self.chsep.setDisabled(True)
2320
+ # ####################
2321
+ # ### QEt/g input ####
2322
+ # ####################
2323
+ # callback for QE input
2324
+
2325
+ def qcinput(self):
2326
+ if self.chch.getState():
2327
+ self.etqcgch.setDisabled(True)
2328
+ self.etqctch.setDisabled(True)
2329
+ self.etqcQch.setDisabled(True)
2330
+ if self.qcode.currentIndex() == 0: # generate terachem input
2331
+ self.qctWindow.setWindowModality(2)
2332
+ self.qctWindow.show()
2333
+ elif self.qcode.currentIndex() == 1: # generate GAMESS input
2334
+ self.qcgWindow.setWindowModality(2)
2335
+ self.qcgWindow.show()
2336
+ elif self.qcode.currentIndex() == 2: # generate Qchem input
2337
+ self.qcQWindow.setWindowModality(2)
2338
+ self.qcQWindow.show()
2339
+ # make default button callback
2340
+
2341
+ def jobdef(self):
2342
+ grabguivarsjob(self)
2343
+ QMessageBox.information(
2344
+ self.wmain, 'Done', 'The current settings are the default ones now.')
2345
+
2346
+ def qctdef(self):
2347
+ grabguivarstc(self)
2348
+ QMessageBox.information(
2349
+ self.wmain, 'Done', 'The current settings are the default ones now.')
2350
+
2351
+ def qcgdef(self):
2352
+ grabguivarsgam(self)
2353
+ QMessageBox.information(
2354
+ self.wmain, 'Done', 'The current settings are the default ones now.')
2355
+
2356
+ def qcqdef(self):
2357
+ grabguivarsqch(self)
2358
+ QMessageBox.information(
2359
+ self.wmain, 'Done', 'The current settings are the default ones now.')
2360
+
2361
+ def qcgload(self):
2362
+ name = QFileDialog.getOpenFileName(
2363
+ self.qctWindow, 'Open File', '.', "GAMESS input files")
2364
+ if name[0] != '':
2365
+ with open(name[0], 'r') as f:
2366
+ self.qcgWindow.molf = f.read()
2367
+ # enable QE input
2368
+
2369
+ def enableqeinput(self):
2370
+ if self.chkI.isChecked():
2371
+ self.chkI.state = False
2372
+ self.qcode.setDisabled(False)
2373
+ self.butQc.setDisabled(False)
2374
+ self.chch.setDisabled(False)
2375
+ else:
2376
+ self.qcode.setDisabled(True)
2377
+ self.butQc.setDisabled(True)
2378
+ self.chch.setDisabled(True)
2379
+ self.chkI.state = True
2380
+ # ########################
2381
+ # ### jobscript input ####
2382
+ # ########################
2383
+ # enable Jobscript input
2384
+
2385
+ def enablejinput(self):
2386
+ if self.chkJ.isChecked():
2387
+ self.chkJ.state = False
2388
+ self.scheduler.setDisabled(False)
2389
+ self.butJob.setDisabled(False)
2390
+ else:
2391
+ self.scheduler.setDisabled(True)
2392
+ self.butJob.setDisabled(True)
2393
+ self.chkJ.state = True
2394
+
2395
+ def jobenable(self):
2396
+ self.jWindow.setWindowModality(2)
2397
+ self.jWindow.show()
2398
+ # load file
2399
+
2400
+ def jload(self):
2401
+ name = QFileDialog.getOpenFileName(
2402
+ self.qctWindow, 'Open File', '.', "Jobscript files")
2403
+ if name[0] != '':
2404
+ with open(name[0], 'r') as f:
2405
+ self.jWindow.molf = f.read()
2406
+ # ##############################
2407
+ # ### post-processing input ####
2408
+ # ##############################
2409
+ # enable Post processing input
2410
+
2411
+ def setupp(self):
2412
+ self.pWindow.setWindowModality(2)
2413
+ self.pWindow.show()
2414
+ # check if Multiwfn exists
2415
+ globs = globalvars()
2416
+ cwd = os.getcwd()
2417
+ os.chdir(globs.homedir)
2418
+ inputtxt = '0\n0\n'
2419
+ with open('input1', 'w') as f:
2420
+ f.write(inputtxt)
2421
+ writef = False
2422
+ mwfn = globs.multiwfn
2423
+ cdbdir = globs.chemdbdir
2424
+ if not os.path.isfile(globs.multiwfn[1:-1]):
2425
+ choice = QMessageBox.question(self.pWindow, 'Multiwfn setup',
2426
+ 'It looks like the Multiwfn '
2427
+ 'executable is not configured '
2428
+ 'or does not exist. Would you '
2429
+ 'like to configure it now?',
2430
+ QMessageBox.Yes, QMessageBox.No)
2431
+ if choice == QMessageBox.Yes:
2432
+ QMessageBox.information(
2433
+ self.pWindow, 'Multiwfn', "Please select the Multiwfn executable.")
2434
+ mwfn = QFileDialog.getOpenFileName(
2435
+ self.pWindow, 'Select the Multiwfn executable.', '.')
2436
+ if len(mwfn[0]) > 1:
2437
+ writef = True
2438
+ if writef:
2439
+ with open(globs.homedir+'/.molSimplify', 'w') as f:
2440
+ # f.write("INSTALLDIR="+instdir+'\n')
2441
+ if len(cdbdir) > 0:
2442
+ f.write("CHEMDBDIR="+cdbdir+'\n')
2443
+ if len(mwfn) > 0:
2444
+ f.write("MULTIWFN="+mwfn[0]+"\n")
2445
+ newglobs = globalvars()
2446
+ com = newglobs.multiwfn
2447
+ tt = mybash(com + '< input1')
2448
+ os.remove('input1')
2449
+ if 'Multifunctional Wavefunction Analyzer' not in tt:
2450
+ self.pch.setDisabled(True)
2451
+ self.pwfnav.setDisabled(True)
2452
+ self.pcub.setDisabled(True)
2453
+ self.pdeloc.setDisabled(True)
2454
+ os.chdir(cwd)
2455
+ # load directory
2456
+
2457
+ def pdload(self):
2458
+ name = QFileDialog.getExistingDirectory(
2459
+ self.pWindow, 'Select Directory')
2460
+ if len(name) > 0 and name[0] != '':
2461
+ self.etpdir.setText(name)
2462
+ # ##############################
2463
+ # ##### general callbacks ######
2464
+ # ##############################
2465
+ # ## exit application ###
2466
+
2467
+ def qexit(self):
2468
+ choice = QMessageBox.question(self.wmain, 'Exit', 'Are you sure you want to quit?',
2469
+ QMessageBox.Yes, QMessageBox.No)
2470
+ if choice == QMessageBox.Yes:
2471
+ sys.exit()
2472
+ else:
2473
+ pass
2474
+ # hide current widget #
2475
+
2476
+ def qhide(self):
2477
+ self.hide()
2478
+ # close ligands window
2479
+
2480
+ def qcloseligs(self):
2481
+ self.lwindow.hide()
2482
+ # return to main window #
2483
+
2484
+ def qretmain(self):
2485
+ # hide all windows
2486
+ self.qctWindow.hide()
2487
+ self.qcgWindow.hide()
2488
+ self.qcQWindow.hide()
2489
+ self.pWindow.hide()
2490
+ self.jWindow.hide()
2491
+ self.DBWindow.hide()
2492
+ self.cDBWindow.hide()
2493
+ self.geWindow.hide()