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.
- docs/source/conf.py +224 -0
- molSimplify/Classes/__init__.py +6 -0
- molSimplify/Classes/atom3D.py +235 -0
- molSimplify/Classes/dft_obs.py +130 -0
- molSimplify/Classes/globalvars.py +827 -0
- molSimplify/Classes/helpers.py +161 -0
- molSimplify/Classes/ligand.py +2330 -0
- molSimplify/Classes/mGUI.py +2493 -0
- molSimplify/Classes/mWidgets.py +438 -0
- molSimplify/Classes/miniGUI.py +41 -0
- molSimplify/Classes/mol2D.py +260 -0
- molSimplify/Classes/mol3D.py +5846 -0
- molSimplify/Classes/monomer3D.py +253 -0
- molSimplify/Classes/partialcharges.py +226 -0
- molSimplify/Classes/protein3D.py +1178 -0
- molSimplify/Classes/rundiag.py +151 -0
- molSimplify/Data/ML.dat +212 -0
- molSimplify/Data/MLS_FSR_for_inter.dat +23 -0
- molSimplify/Data/MLS_FSR_for_inter2.dat +23 -0
- molSimplify/Data/MLS_angle_for_click.dat +8 -0
- molSimplify/Data/MLS_angle_for_inter.dat +23 -0
- molSimplify/Data/MLS_angle_for_inter2.dat +48 -0
- molSimplify/Data/MLS_angle_for_intra.dat +10 -0
- molSimplify/Data/MLS_angle_for_intra2.dat +6 -0
- molSimplify/Data/MLS_angle_for_oa.dat +18 -0
- molSimplify/Data/ML_FSR_for_inter.dat +112 -0
- molSimplify/Data/ML_FSR_for_inter2.dat +110 -0
- molSimplify/Data/ML_bond_for_cat.dat +8 -0
- molSimplify/Data/ML_bond_for_click.dat +8 -0
- molSimplify/Data/ML_bond_for_inter.dat +48 -0
- molSimplify/Data/ML_bond_for_inter2.dat +48 -0
- molSimplify/Data/ML_bond_for_intra.dat +10 -0
- molSimplify/Data/ML_bond_for_intra2.dat +6 -0
- molSimplify/Data/ML_bond_for_oa.dat +18 -0
- molSimplify/Data/bp1.dat +21 -0
- molSimplify/Data/li.dat +3 -0
- molSimplify/Data/no.dat +2 -0
- molSimplify/Data/oct.dat +7 -0
- molSimplify/Data/pbp.dat +8 -0
- molSimplify/Data/spy.dat +6 -0
- molSimplify/Data/sqap.dat +9 -0
- molSimplify/Data/sqp.dat +5 -0
- molSimplify/Data/tbp.dat +6 -0
- molSimplify/Data/tdhd.dat +9 -0
- molSimplify/Data/thd.dat +5 -0
- molSimplify/Data/tpl.dat +4 -0
- molSimplify/Data/tpr.dat +7 -0
- molSimplify/Informatics/HFXsensitivity/__init__.py +0 -0
- molSimplify/Informatics/HFXsensitivity/measure_HFX_sensitivity_oxo_hat_reb_rel.py +443 -0
- molSimplify/Informatics/HFXsensitivity/measure_HFX_stable.py +346 -0
- molSimplify/Informatics/MOF/Linker_rotation.py +179 -0
- molSimplify/Informatics/MOF/MOF_descriptors.py +1299 -0
- molSimplify/Informatics/MOF/MOF_descriptors_alternate_functional.py +589 -0
- molSimplify/Informatics/MOF/MOF_functionalizer.py +1648 -0
- molSimplify/Informatics/MOF/PBC_functions.py +1347 -0
- molSimplify/Informatics/MOF/__init__.py +0 -0
- molSimplify/Informatics/MOF/atomic.py +267 -0
- molSimplify/Informatics/MOF/cluster_extraction.py +388 -0
- molSimplify/Informatics/MOF/fragment_MOFs_for_pormake.py +895 -0
- molSimplify/Informatics/MOF/monofunctionalized_BDC/index_information.py +10 -0
- molSimplify/Informatics/Mol2Parser.py +46 -0
- molSimplify/Informatics/RACassemble.py +408 -0
- molSimplify/Informatics/__init__.py +0 -0
- molSimplify/Informatics/active_learning/__init__.py +0 -0
- molSimplify/Informatics/active_learning/expected_improvement.py +269 -0
- molSimplify/Informatics/autocorrelation.py +1930 -0
- molSimplify/Informatics/clean_autocorrelation.py +778 -0
- molSimplify/Informatics/coulomb_analyze.py +67 -0
- molSimplify/Informatics/decoration_manager.py +193 -0
- molSimplify/Informatics/geo_analyze.py +88 -0
- molSimplify/Informatics/geometrics.py +56 -0
- molSimplify/Informatics/graph_analyze.py +163 -0
- molSimplify/Informatics/graph_racs.py +288 -0
- molSimplify/Informatics/jupyter_vis.py +172 -0
- molSimplify/Informatics/lacRACAssemble.py +2192 -0
- molSimplify/Informatics/lacRACAssemble_bisdithiolenes.py +236 -0
- molSimplify/Informatics/misc_descriptors.py +198 -0
- molSimplify/Informatics/organic_fingerprints.py +61 -0
- molSimplify/Informatics/partialcharges.py +345 -0
- molSimplify/Informatics/protein/activesite.py +53 -0
- molSimplify/Informatics/protein/pymol_add_hs.py +33 -0
- molSimplify/Informatics/rac155_geo.py +48 -0
- molSimplify/Ligands/(1_methylbenzimidazol_2_yl)pyridine.xyz +45 -0
- molSimplify/Ligands/1-4-dimethyl-1-2-3-triazole.xyz +15 -0
- molSimplify/Ligands/12crown4.mol +62 -0
- molSimplify/Ligands/Antipyrine.mol +58 -0
- molSimplify/Ligands/BPAbipy.mol +106 -0
- molSimplify/Ligands/Hpyrrole.mol +26 -0
- molSimplify/Ligands/N-quinolinylbutyramidate.xyz +31 -0
- molSimplify/Ligands/N-quinolinylmethylmethinylacetamidate.xyz +30 -0
- molSimplify/Ligands/NMe2_-1.xyz +11 -0
- molSimplify/Ligands/PCy3.mol +111 -0
- molSimplify/Ligands/PMe3.xyz +15 -0
- molSimplify/Ligands/PPh3.mol +76 -0
- molSimplify/Ligands/Propyphenazone.mol +77 -0
- molSimplify/Ligands/acac.mol +33 -0
- molSimplify/Ligands/acacen.mol +76 -0
- molSimplify/Ligands/acetate.smi +1 -0
- molSimplify/Ligands/acetate.xyz +9 -0
- molSimplify/Ligands/aceticacidbipyridine.mol +70 -0
- molSimplify/Ligands/acetonitrile.mol +17 -0
- molSimplify/Ligands/alanine.mol +30 -0
- molSimplify/Ligands/alphabetizer.py +21 -0
- molSimplify/Ligands/amine.mol +11 -0
- molSimplify/Ligands/ammonia.mol +12 -0
- molSimplify/Ligands/arginine.mol +58 -0
- molSimplify/Ligands/asparagine.mol +38 -0
- molSimplify/Ligands/aspartic_acid.mol +35 -0
- molSimplify/Ligands/azide.mol +11 -0
- molSimplify/Ligands/benzene.mol +28 -0
- molSimplify/Ligands/benzene_pi.mol +30 -0
- molSimplify/Ligands/benzenedithiol.mol +30 -0
- molSimplify/Ligands/benzenethiol.mol +30 -0
- molSimplify/Ligands/benzylisocy.mol +38 -0
- molSimplify/Ligands/bidiazine.mol +42 -0
- molSimplify/Ligands/bidiazole.mol +38 -0
- molSimplify/Ligands/bifuran.mol +38 -0
- molSimplify/Ligands/bihydrodiazine.mol +58 -0
- molSimplify/Ligands/bihydrodiazole.mol +46 -0
- molSimplify/Ligands/bihydrooxazine.mol +54 -0
- molSimplify/Ligands/bihydrooxazole.mol +42 -0
- molSimplify/Ligands/bihydrothiazine.mol +54 -0
- molSimplify/Ligands/bihydrothiazole.mol +42 -0
- molSimplify/Ligands/biimidazole.mol +38 -0
- molSimplify/Ligands/bioxazole.mol +34 -0
- molSimplify/Ligands/bipy.mol +46 -0
- molSimplify/Ligands/bipyrazine.xyz +20 -0
- molSimplify/Ligands/bipyrimidine.mol +42 -0
- molSimplify/Ligands/bipyrrole.mol +42 -0
- molSimplify/Ligands/bisnapthyridylpyridine.mol +111 -0
- molSimplify/Ligands/bithiazole.mol +34 -0
- molSimplify/Ligands/bromide.mol +7 -0
- molSimplify/Ligands/bromide.smi +1 -0
- molSimplify/Ligands/c2.mol +9 -0
- molSimplify/Ligands/caprolactone.mol +41 -0
- molSimplify/Ligands/carbonyl.mol +8 -0
- molSimplify/Ligands/carboxyl.mol +13 -0
- molSimplify/Ligands/cat.mol +30 -0
- molSimplify/Ligands/chloride.mol +7 -0
- molSimplify/Ligands/chloride.smi +1 -0
- molSimplify/Ligands/chloropyridine.mol +27 -0
- molSimplify/Ligands/co2.mol +10 -0
- molSimplify/Ligands/corrolazine.mol +72 -0
- molSimplify/Ligands/cs.mol +8 -0
- molSimplify/Ligands/cyanate.xyz +5 -0
- molSimplify/Ligands/cyanide.mol +9 -0
- molSimplify/Ligands/cyanoaceticporphyrin.mol +114 -0
- molSimplify/Ligands/cyanopyridine.mol +29 -0
- molSimplify/Ligands/cyclam.mol +81 -0
- molSimplify/Ligands/cyclen.mol +69 -0
- molSimplify/Ligands/cyclopentadienyl.mol +26 -0
- molSimplify/Ligands/cysteine.mol +32 -0
- molSimplify/Ligands/diaminomethyl.mol +19 -0
- molSimplify/Ligands/diazine.mol +25 -0
- molSimplify/Ligands/diazole.mol +23 -0
- molSimplify/Ligands/dicyanamide.mol +15 -0
- molSimplify/Ligands/dihydrofuran.mol +27 -0
- molSimplify/Ligands/dmap.xyz +35 -0
- molSimplify/Ligands/dmf.mol +28 -0
- molSimplify/Ligands/dmi.mol +41 -0
- molSimplify/Ligands/dmpe.mol +52 -0
- molSimplify/Ligands/dpmu.mol +47 -0
- molSimplify/Ligands/dppe.mol +112 -0
- molSimplify/Ligands/edta.mol +69 -0
- molSimplify/Ligands/en.mol +28 -0
- molSimplify/Ligands/ethanethiol.mol +21 -0
- molSimplify/Ligands/ethanolamine.mol +26 -0
- molSimplify/Ligands/ethbipy.mol +70 -0
- molSimplify/Ligands/ethyl.mol +19 -0
- molSimplify/Ligands/ethylamine.mol +24 -0
- molSimplify/Ligands/ethylene.mol +16 -0
- molSimplify/Ligands/ethylesteracac.mol +57 -0
- molSimplify/Ligands/fluoride.mol +7 -0
- molSimplify/Ligands/fluoride.smi +1 -0
- molSimplify/Ligands/formaldehyde.mol +12 -0
- molSimplify/Ligands/formamidate.xyz +8 -0
- molSimplify/Ligands/formate.xyz +6 -0
- molSimplify/Ligands/furan.mol +23 -0
- molSimplify/Ligands/glutamic_acid.mol +42 -0
- molSimplify/Ligands/glutamine.mol +44 -0
- molSimplify/Ligands/glycinate.mol +23 -0
- molSimplify/Ligands/glycine.mol +24 -0
- molSimplify/Ligands/h2s.mol +10 -0
- molSimplify/Ligands/helium.mol +6 -0
- molSimplify/Ligands/histidine.mol +45 -0
- molSimplify/Ligands/hmpa.mol +62 -0
- molSimplify/Ligands/hs-.mol +9 -0
- molSimplify/Ligands/hydride.mol +7 -0
- molSimplify/Ligands/hydrocarboxyacetylide.xyz +8 -0
- molSimplify/Ligands/hydrocyanide.mol +10 -0
- molSimplify/Ligands/hydrodiazine.mol +33 -0
- molSimplify/Ligands/hydrodiazole.mol +27 -0
- molSimplify/Ligands/hydrogensulfide.mol +10 -0
- molSimplify/Ligands/hydroisocyanide.mol +11 -0
- molSimplify/Ligands/hydrooxazine.mol +31 -0
- molSimplify/Ligands/hydrooxazole.mol +25 -0
- molSimplify/Ligands/hydrothiazine.mol +31 -0
- molSimplify/Ligands/hydrothiazole.mol +25 -0
- molSimplify/Ligands/hydroxyl.mol +9 -0
- molSimplify/Ligands/imidazole.mol +23 -0
- molSimplify/Ligands/imidazolidinone.mol +29 -0
- molSimplify/Ligands/imine.mol +13 -0
- molSimplify/Ligands/iminodiacetic.mol +33 -0
- molSimplify/Ligands/iodide.mol +7 -0
- molSimplify/Ligands/iodobenzene.xyz +14 -0
- molSimplify/Ligands/isoleucine.mol +48 -0
- molSimplify/Ligands/isothiocyanate.mol +11 -0
- molSimplify/Ligands/leucine.mol +48 -0
- molSimplify/Ligands/ligands.dict +257 -0
- molSimplify/Ligands/lysine.mol +54 -0
- molSimplify/Ligands/mebenzenedithiol.mol +36 -0
- molSimplify/Ligands/mebim_py.xyz +29 -0
- molSimplify/Ligands/mebim_pz.xyz +28 -0
- molSimplify/Ligands/mebipy.mol +58 -0
- molSimplify/Ligands/mecat.mol +36 -0
- molSimplify/Ligands/methanal.mol +11 -0
- molSimplify/Ligands/methanethiol.mol +15 -0
- molSimplify/Ligands/methanol.mol +16 -0
- molSimplify/Ligands/methionine.mol +44 -0
- molSimplify/Ligands/methyl.mol +13 -0
- molSimplify/Ligands/methylacetylide.xyz +8 -0
- molSimplify/Ligands/methylamine.mol +19 -0
- molSimplify/Ligands/methylazide.xyz +9 -0
- molSimplify/Ligands/methylisocy.mol +17 -0
- molSimplify/Ligands/methylpyridine.mol +33 -0
- molSimplify/Ligands/n2.mol +8 -0
- molSimplify/Ligands/n4py.xyz +51 -0
- molSimplify/Ligands/nch.mol +10 -0
- molSimplify/Ligands/nco-.mol +11 -0
- molSimplify/Ligands/nethanolamine.mol +26 -0
- molSimplify/Ligands/nitrate.mol +14 -0
- molSimplify/Ligands/nitrite.mol +11 -0
- molSimplify/Ligands/nitro.mol +11 -0
- molSimplify/Ligands/nitrobipy.mol +54 -0
- molSimplify/Ligands/nitroso.mol +8 -0
- molSimplify/Ligands/nme3.mol +30 -0
- molSimplify/Ligands/no-.mol +10 -0
- molSimplify/Ligands/no2-.mol +11 -0
- molSimplify/Ligands/noxygen.mol +8 -0
- molSimplify/Ligands/ns-.mol +10 -0
- molSimplify/Ligands/o-pyridylbenzene.xyz +23 -0
- molSimplify/Ligands/o-pyridylphenylanion.xyz +22 -0
- molSimplify/Ligands/o2-.mol +9 -0
- molSimplify/Ligands/o2.xyz +4 -0
- molSimplify/Ligands/och2.mol +12 -0
- molSimplify/Ligands/oethanolamine.mol +26 -0
- molSimplify/Ligands/ome2.mol +22 -0
- molSimplify/Ligands/ooh.xyz +5 -0
- molSimplify/Ligands/oxalate.mol +17 -0
- molSimplify/Ligands/oxalate.smi +1 -0
- molSimplify/Ligands/oxygen.mol +7 -0
- molSimplify/Ligands/pentacyanocyclopentadienide.mol +36 -0
- molSimplify/Ligands/ph2-.mol +11 -0
- molSimplify/Ligands/ph3.mol +12 -0
- molSimplify/Ligands/phen.mol +51 -0
- molSimplify/Ligands/phenacac.mol +63 -0
- molSimplify/Ligands/phenalalanine.mol +51 -0
- molSimplify/Ligands/phendione.mol +51 -0
- molSimplify/Ligands/phenphen.mol +75 -0
- molSimplify/Ligands/phenylbenzoxazole.mol +54 -0
- molSimplify/Ligands/phenylcyc.mol +99 -0
- molSimplify/Ligands/phenylenediamine.mol +37 -0
- molSimplify/Ligands/phenylisocy.mol +32 -0
- molSimplify/Ligands/phosacidbipy.mol +66 -0
- molSimplify/Ligands/phosphine.mol +13 -0
- molSimplify/Ligands/phosphorine.mol +27 -0
- molSimplify/Ligands/phosphorustrifluoride.mol +12 -0
- molSimplify/Ligands/phthalocyanine.mol +126 -0
- molSimplify/Ligands/pme3o.mol +32 -0
- molSimplify/Ligands/porphyrin.mol +82 -0
- molSimplify/Ligands/pph3o.mol +77 -0
- molSimplify/Ligands/proline.mol +39 -0
- molSimplify/Ligands/propdiol.mol +21 -0
- molSimplify/Ligands/propylene.mol +23 -0
- molSimplify/Ligands/pyridine.mol +27 -0
- molSimplify/Ligands/pyrimidone.mol +27 -0
- molSimplify/Ligands/pyrrole.mol +24 -0
- molSimplify/Ligands/quinoxalinedithiol.mol +39 -0
- molSimplify/Ligands/s2-.mol +9 -0
- molSimplify/Ligands/salen.mol +75 -0
- molSimplify/Ligands/salphen.mol +84 -0
- molSimplify/Ligands/serine.mol +32 -0
- molSimplify/Ligands/simple_ligands.dict +14 -0
- molSimplify/Ligands/sulfacidbipy.mol +63 -0
- molSimplify/Ligands/tbucat.mol +54 -0
- molSimplify/Ligands/tbuphisocy.mol +56 -0
- molSimplify/Ligands/tbutylcyclen.mol +166 -0
- molSimplify/Ligands/tbutylisocy.mol +35 -0
- molSimplify/Ligands/tbutylthiol.mol +33 -0
- molSimplify/Ligands/tcnoet.mol +43 -0
- molSimplify/Ligands/tcnoetOH.mol +45 -0
- molSimplify/Ligands/terpy.mol +65 -0
- molSimplify/Ligands/tetrahydrofuran.mol +31 -0
- molSimplify/Ligands/thiane.mol +37 -0
- molSimplify/Ligands/thiazole.mol +21 -0
- molSimplify/Ligands/thiocyanate.mol +11 -0
- molSimplify/Ligands/thiol.mol +9 -0
- molSimplify/Ligands/thiophene.mol +23 -0
- molSimplify/Ligands/thiopyridine.mol +29 -0
- molSimplify/Ligands/threonine.mol +38 -0
- molSimplify/Ligands/tpp.mol +165 -0
- molSimplify/Ligands/tricyanomethyl.mol +19 -0
- molSimplify/Ligands/trifluoromethyl.mol +13 -0
- molSimplify/Ligands/tryptophan.mol +60 -0
- molSimplify/Ligands/tyrosine.mol +53 -0
- molSimplify/Ligands/uthiol.mol +11 -0
- molSimplify/Ligands/uthiolme2.mol +23 -0
- molSimplify/Ligands/valine.mol +42 -0
- molSimplify/Ligands/water.mol +10 -0
- molSimplify/Ligands/x.mol +6 -0
- molSimplify/Scripts/__init__.py +0 -0
- molSimplify/Scripts/addtodb.py +308 -0
- molSimplify/Scripts/cellbuilder.py +1592 -0
- molSimplify/Scripts/cellbuilder_tools.py +701 -0
- molSimplify/Scripts/chains.py +342 -0
- molSimplify/Scripts/convert_2to3.py +23 -0
- molSimplify/Scripts/dbinteract.py +631 -0
- molSimplify/Scripts/distgeom.py +617 -0
- molSimplify/Scripts/findcorrelations.py +287 -0
- molSimplify/Scripts/generator.py +267 -0
- molSimplify/Scripts/geometry.py +1224 -0
- molSimplify/Scripts/grabguivars.py +845 -0
- molSimplify/Scripts/in_b3lyp_usetc.py +141 -0
- molSimplify/Scripts/inparse.py +1673 -0
- molSimplify/Scripts/io.py +1149 -0
- molSimplify/Scripts/isomers.py +415 -0
- molSimplify/Scripts/jobgen.py +247 -0
- molSimplify/Scripts/krr_prep.py +1262 -0
- molSimplify/Scripts/molSimplify_io.py +18 -0
- molSimplify/Scripts/molden2psi4wfn.py +166 -0
- molSimplify/Scripts/namegen.py +32 -0
- molSimplify/Scripts/nn_prep.py +561 -0
- molSimplify/Scripts/oct_check_mols.py +782 -0
- molSimplify/Scripts/periodic_QE.py +97 -0
- molSimplify/Scripts/postmold.py +304 -0
- molSimplify/Scripts/postmwfn.py +709 -0
- molSimplify/Scripts/postparse.py +488 -0
- molSimplify/Scripts/postproc.py +139 -0
- molSimplify/Scripts/qcgen.py +1450 -0
- molSimplify/Scripts/rmsd.py +489 -0
- molSimplify/Scripts/rungen.py +670 -0
- molSimplify/Scripts/structgen.py +3040 -0
- molSimplify/Scripts/tf_nn_prep.py +894 -0
- molSimplify/Scripts/tsgen.py +295 -0
- molSimplify/Scripts/uq_calibration.py +69 -0
- molSimplify/__init__.py +0 -0
- molSimplify/__main__.py +197 -0
- molSimplify/icons/chemdb.png +0 -0
- molSimplify/icons/hjklogo.png +0 -0
- molSimplify/icons/icon.png +0 -0
- molSimplify/icons/logo.png +0 -0
- molSimplify/icons/logo_old.png +0 -0
- molSimplify/icons/petachem.png +0 -0
- molSimplify/icons/petachem2.png +0 -0
- molSimplify/icons/petachem_full.png +0 -0
- molSimplify/icons/pythonlogo.png +0 -0
- molSimplify/icons/sge copy.png +0 -0
- molSimplify/icons/sge.png +0 -0
- molSimplify/icons/slurm.png +0 -0
- molSimplify/icons/wft1.png +0 -0
- molSimplify/icons/wft2.png +0 -0
- molSimplify/icons/wft3.png +0 -0
- molSimplify/ml/__init__.py +0 -0
- molSimplify/ml/kernels.py +36 -0
- molSimplify/ml/layers.py +29 -0
- molSimplify/molscontrol/__init__.py +14 -0
- molSimplify/molscontrol/_version.py +521 -0
- molSimplify/molscontrol/clf_tools.py +144 -0
- molSimplify/molscontrol/data/README.md +21 -0
- molSimplify/molscontrol/data/look_and_say.dat +15 -0
- molSimplify/molscontrol/dynamic_classifier.py +514 -0
- molSimplify/molscontrol/io_tools.py +363 -0
- molSimplify/molscontrol/molscontrol.py +49 -0
- molSimplify/molscontrol/terachem/jobscript_control.sh +31 -0
- molSimplify/molscontrol/terachem/terachem_input +22 -0
- molSimplify/python_krr/X_train_TS.csv +535 -0
- molSimplify/python_krr/__init__.py +0 -0
- molSimplify/python_krr/hat2_X_mean_std.csv +3 -0
- molSimplify/python_krr/hat2_feature_names.csv +1 -0
- molSimplify/python_krr/hat2_y_mean_std.csv +2 -0
- molSimplify/python_krr/hat_X_mean_std.csv +6 -0
- molSimplify/python_krr/hat_feature_names.csv +1 -0
- molSimplify/python_krr/hat_krr_X_train.csv +5205 -0
- molSimplify/python_krr/hat_krr_dual_coef.csv +1 -0
- molSimplify/python_krr/hat_y_mean_std.csv +2 -0
- molSimplify/python_krr/sklearn_models.py +34 -0
- molSimplify/python_krr/y_train_TS.csv +535 -0
- molSimplify/python_nn/ANN.py +198 -0
- molSimplify/python_nn/__init__.py +0 -0
- molSimplify/python_nn/clf_analysis_tool.py +125 -0
- molSimplify/python_nn/dictionary_toolbox.py +49 -0
- molSimplify/python_nn/ensemble_test.py +309 -0
- molSimplify/python_nn/hs_center.csv +26 -0
- molSimplify/python_nn/hs_scale.csv +26 -0
- molSimplify/python_nn/ls_center.csv +26 -0
- molSimplify/python_nn/ls_scale.csv +26 -0
- molSimplify/python_nn/ms_hs_b1.csv +50 -0
- molSimplify/python_nn/ms_hs_b2.csv +50 -0
- molSimplify/python_nn/ms_hs_b3.csv +1 -0
- molSimplify/python_nn/ms_hs_w1.csv +50 -0
- molSimplify/python_nn/ms_hs_w2.csv +50 -0
- molSimplify/python_nn/ms_hs_w3.csv +1 -0
- molSimplify/python_nn/ms_ls_b1.csv +50 -0
- molSimplify/python_nn/ms_ls_b2.csv +50 -0
- molSimplify/python_nn/ms_ls_b3.csv +1 -0
- molSimplify/python_nn/ms_ls_w1.csv +50 -0
- molSimplify/python_nn/ms_ls_w2.csv +50 -0
- molSimplify/python_nn/ms_ls_w3.csv +1 -0
- molSimplify/python_nn/ms_slope_b1.csv +50 -0
- molSimplify/python_nn/ms_slope_b2.csv +50 -0
- molSimplify/python_nn/ms_slope_b3.csv +1 -0
- molSimplify/python_nn/ms_slope_w1.csv +50 -0
- molSimplify/python_nn/ms_slope_w2.csv +50 -0
- molSimplify/python_nn/ms_slope_w3.csv +1 -0
- molSimplify/python_nn/ms_split_b1.csv +50 -0
- molSimplify/python_nn/ms_split_b2.csv +50 -0
- molSimplify/python_nn/ms_split_b3.csv +1 -0
- molSimplify/python_nn/ms_split_w1.csv +50 -0
- molSimplify/python_nn/ms_split_w2.csv +50 -0
- molSimplify/python_nn/ms_split_w3.csv +1 -0
- molSimplify/python_nn/slope_center.csv +25 -0
- molSimplify/python_nn/slope_scale.csv +25 -0
- molSimplify/python_nn/split_center.csv +26 -0
- molSimplify/python_nn/split_scale.csv +26 -0
- molSimplify/python_nn/tf_ANN.py +762 -0
- molSimplify/python_nn/train_data.csv +1211 -0
- molSimplify/tf_nn/__init__.py +0 -0
- molSimplify/tf_nn/geo_static_clf/geo_static_clf_model.h5 +0 -0
- molSimplify/tf_nn/geo_static_clf/geo_static_clf_train_name.csv +1591 -0
- molSimplify/tf_nn/geo_static_clf/geo_static_clf_train_x.csv +2790 -0
- molSimplify/tf_nn/geo_static_clf/geo_static_clf_train_y.csv +2790 -0
- molSimplify/tf_nn/geo_static_clf/geo_static_clf_vars.csv +154 -0
- molSimplify/tf_nn/geos/hs_ii_bl_x.csv +1577 -0
- molSimplify/tf_nn/geos/hs_ii_bl_y.csv +1577 -0
- molSimplify/tf_nn/geos/hs_ii_model.h5 +0 -0
- molSimplify/tf_nn/geos/hs_ii_model.json +1 -0
- molSimplify/tf_nn/geos/hs_ii_vars.csv +154 -0
- molSimplify/tf_nn/geos/hs_iii_bl_x.csv +1659 -0
- molSimplify/tf_nn/geos/hs_iii_bl_y.csv +1659 -0
- molSimplify/tf_nn/geos/hs_iii_model.h5 +0 -0
- molSimplify/tf_nn/geos/hs_iii_model.json +1 -0
- molSimplify/tf_nn/geos/hs_iii_vars.csv +154 -0
- molSimplify/tf_nn/geos/ls_ii_bl_x.csv +1374 -0
- molSimplify/tf_nn/geos/ls_ii_bl_y.csv +1374 -0
- molSimplify/tf_nn/geos/ls_ii_model.h5 +0 -0
- molSimplify/tf_nn/geos/ls_ii_model.json +1 -0
- molSimplify/tf_nn/geos/ls_ii_vars.csv +154 -0
- molSimplify/tf_nn/geos/ls_iii_bl_x.csv +1364 -0
- molSimplify/tf_nn/geos/ls_iii_bl_y.csv +1364 -0
- molSimplify/tf_nn/geos/ls_iii_model.h5 +0 -0
- molSimplify/tf_nn/geos/ls_iii_model.json +1 -0
- molSimplify/tf_nn/geos/ls_iii_vars.csv +154 -0
- molSimplify/tf_nn/homolumo/gap_model.h5 +0 -0
- molSimplify/tf_nn/homolumo/gap_model.json +1 -0
- molSimplify/tf_nn/homolumo/gap_test_names.csv +175 -0
- molSimplify/tf_nn/homolumo/gap_test_x.csv +176 -0
- molSimplify/tf_nn/homolumo/gap_test_y.csv +176 -0
- molSimplify/tf_nn/homolumo/gap_train_names.csv +699 -0
- molSimplify/tf_nn/homolumo/gap_train_x.csv +700 -0
- molSimplify/tf_nn/homolumo/gap_train_y.csv +700 -0
- molSimplify/tf_nn/homolumo/gap_vars.csv +153 -0
- molSimplify/tf_nn/homolumo/homo_model.h5 +0 -0
- molSimplify/tf_nn/homolumo/homo_model.json +126 -0
- molSimplify/tf_nn/homolumo/homo_test_names.csv +175 -0
- molSimplify/tf_nn/homolumo/homo_test_x.csv +176 -0
- molSimplify/tf_nn/homolumo/homo_test_y.csv +176 -0
- molSimplify/tf_nn/homolumo/homo_train_names.csv +699 -0
- molSimplify/tf_nn/homolumo/homo_train_x.csv +700 -0
- molSimplify/tf_nn/homolumo/homo_train_y.csv +700 -0
- molSimplify/tf_nn/homolumo/homo_vars.csv +153 -0
- molSimplify/tf_nn/oxoandhomo/homo_empty_info.json +7 -0
- molSimplify/tf_nn/oxoandhomo/homo_empty_model.h5 +0 -0
- molSimplify/tf_nn/oxoandhomo/homo_empty_model.json +1 -0
- molSimplify/tf_nn/oxoandhomo/homo_empty_test_names.csv +143 -0
- molSimplify/tf_nn/oxoandhomo/homo_empty_test_x.csv +144 -0
- molSimplify/tf_nn/oxoandhomo/homo_empty_test_y.csv +144 -0
- molSimplify/tf_nn/oxoandhomo/homo_empty_train_names.csv +513 -0
- molSimplify/tf_nn/oxoandhomo/homo_empty_train_x.csv +514 -0
- molSimplify/tf_nn/oxoandhomo/homo_empty_train_y.csv +514 -0
- molSimplify/tf_nn/oxoandhomo/homo_empty_val_names.csv +143 -0
- molSimplify/tf_nn/oxoandhomo/homo_empty_val_x.csv +58 -0
- molSimplify/tf_nn/oxoandhomo/homo_empty_val_y.csv +58 -0
- molSimplify/tf_nn/oxoandhomo/homo_empty_vars.csv +155 -0
- molSimplify/tf_nn/oxoandhomo/oxo20_info.json +7 -0
- molSimplify/tf_nn/oxoandhomo/oxo20_model.h5 +0 -0
- molSimplify/tf_nn/oxoandhomo/oxo20_model.json +1 -0
- molSimplify/tf_nn/oxoandhomo/oxo20_test_names.csv +143 -0
- molSimplify/tf_nn/oxoandhomo/oxo20_test_x.csv +144 -0
- molSimplify/tf_nn/oxoandhomo/oxo20_test_y.csv +144 -0
- molSimplify/tf_nn/oxoandhomo/oxo20_train_names.csv +513 -0
- molSimplify/tf_nn/oxoandhomo/oxo20_train_x.csv +514 -0
- molSimplify/tf_nn/oxoandhomo/oxo20_train_y.csv +514 -0
- molSimplify/tf_nn/oxoandhomo/oxo20_val_names.csv +143 -0
- molSimplify/tf_nn/oxoandhomo/oxo20_val_x.csv +58 -0
- molSimplify/tf_nn/oxoandhomo/oxo20_val_y.csv +58 -0
- molSimplify/tf_nn/oxoandhomo/oxo20_vars.csv +154 -0
- molSimplify/tf_nn/oxocatalysis/hat_model.h5 +0 -0
- molSimplify/tf_nn/oxocatalysis/hat_model.json +1 -0
- molSimplify/tf_nn/oxocatalysis/hat_test_names.csv +419 -0
- molSimplify/tf_nn/oxocatalysis/hat_test_x.csv +420 -0
- molSimplify/tf_nn/oxocatalysis/hat_test_y.csv +420 -0
- molSimplify/tf_nn/oxocatalysis/hat_train_names.csv +1507 -0
- molSimplify/tf_nn/oxocatalysis/hat_train_x.csv +1508 -0
- molSimplify/tf_nn/oxocatalysis/hat_train_y.csv +1508 -0
- molSimplify/tf_nn/oxocatalysis/hat_val_x.csv +169 -0
- molSimplify/tf_nn/oxocatalysis/hat_val_y.csv +169 -0
- molSimplify/tf_nn/oxocatalysis/hat_vars.csv +162 -0
- molSimplify/tf_nn/oxocatalysis/oxo_model.h5 +0 -0
- molSimplify/tf_nn/oxocatalysis/oxo_model.json +1 -0
- molSimplify/tf_nn/oxocatalysis/oxo_test_names.csv +527 -0
- molSimplify/tf_nn/oxocatalysis/oxo_test_x.csv +528 -0
- molSimplify/tf_nn/oxocatalysis/oxo_test_y.csv +528 -0
- molSimplify/tf_nn/oxocatalysis/oxo_train_names.csv +1897 -0
- molSimplify/tf_nn/oxocatalysis/oxo_train_x.csv +1898 -0
- molSimplify/tf_nn/oxocatalysis/oxo_train_y.csv +1898 -0
- molSimplify/tf_nn/oxocatalysis/oxo_val_x.csv +212 -0
- molSimplify/tf_nn/oxocatalysis/oxo_val_y.csv +212 -0
- molSimplify/tf_nn/oxocatalysis/oxo_vars.csv +162 -0
- molSimplify/tf_nn/rescaling_data/gap_mean_x.csv +153 -0
- molSimplify/tf_nn/rescaling_data/gap_mean_y.csv +1 -0
- molSimplify/tf_nn/rescaling_data/gap_var_x.csv +153 -0
- molSimplify/tf_nn/rescaling_data/gap_var_y.csv +1 -0
- molSimplify/tf_nn/rescaling_data/geo_static_clf_mean_x.csv +154 -0
- molSimplify/tf_nn/rescaling_data/geo_static_clf_mean_y.csv +1 -0
- molSimplify/tf_nn/rescaling_data/geo_static_clf_var_x.csv +154 -0
- molSimplify/tf_nn/rescaling_data/geo_static_clf_var_y.csv +1 -0
- molSimplify/tf_nn/rescaling_data/hat_mean_x.csv +162 -0
- molSimplify/tf_nn/rescaling_data/hat_mean_y.csv +1 -0
- molSimplify/tf_nn/rescaling_data/hat_var_x.csv +162 -0
- molSimplify/tf_nn/rescaling_data/hat_var_y.csv +1 -0
- molSimplify/tf_nn/rescaling_data/homo_empty_mean_x.csv +155 -0
- molSimplify/tf_nn/rescaling_data/homo_empty_mean_y.csv +1 -0
- molSimplify/tf_nn/rescaling_data/homo_empty_var_x.csv +155 -0
- molSimplify/tf_nn/rescaling_data/homo_empty_var_y.csv +1 -0
- molSimplify/tf_nn/rescaling_data/homo_mean_x.csv +153 -0
- molSimplify/tf_nn/rescaling_data/homo_mean_y.csv +1 -0
- molSimplify/tf_nn/rescaling_data/homo_var_x.csv +153 -0
- molSimplify/tf_nn/rescaling_data/homo_var_y.csv +1 -0
- molSimplify/tf_nn/rescaling_data/hs_ii_mean_x.csv +154 -0
- molSimplify/tf_nn/rescaling_data/hs_ii_mean_y.csv +3 -0
- molSimplify/tf_nn/rescaling_data/hs_ii_var_x.csv +154 -0
- molSimplify/tf_nn/rescaling_data/hs_ii_var_y.csv +3 -0
- molSimplify/tf_nn/rescaling_data/hs_iii_mean_x.csv +154 -0
- molSimplify/tf_nn/rescaling_data/hs_iii_mean_y.csv +3 -0
- molSimplify/tf_nn/rescaling_data/hs_iii_var_x.csv +154 -0
- molSimplify/tf_nn/rescaling_data/hs_iii_var_y.csv +3 -0
- molSimplify/tf_nn/rescaling_data/ls_ii_mean_x.csv +154 -0
- molSimplify/tf_nn/rescaling_data/ls_ii_mean_y.csv +3 -0
- molSimplify/tf_nn/rescaling_data/ls_ii_var_x.csv +154 -0
- molSimplify/tf_nn/rescaling_data/ls_ii_var_y.csv +3 -0
- molSimplify/tf_nn/rescaling_data/ls_iii_mean_x.csv +154 -0
- molSimplify/tf_nn/rescaling_data/ls_iii_mean_y.csv +3 -0
- molSimplify/tf_nn/rescaling_data/ls_iii_var_x.csv +154 -0
- molSimplify/tf_nn/rescaling_data/ls_iii_var_y.csv +3 -0
- molSimplify/tf_nn/rescaling_data/oxo20_mean_x.csv +154 -0
- molSimplify/tf_nn/rescaling_data/oxo20_mean_y.csv +1 -0
- molSimplify/tf_nn/rescaling_data/oxo20_var_x.csv +154 -0
- molSimplify/tf_nn/rescaling_data/oxo20_var_y.csv +1 -0
- molSimplify/tf_nn/rescaling_data/oxo_mean_x.csv +162 -0
- molSimplify/tf_nn/rescaling_data/oxo_mean_y.csv +1 -0
- molSimplify/tf_nn/rescaling_data/oxo_var_x.csv +162 -0
- molSimplify/tf_nn/rescaling_data/oxo_var_y.csv +1 -0
- molSimplify/tf_nn/rescaling_data/sc_static_clf_mean_x.csv +154 -0
- molSimplify/tf_nn/rescaling_data/sc_static_clf_mean_y.csv +1 -0
- molSimplify/tf_nn/rescaling_data/sc_static_clf_var_x.csv +154 -0
- molSimplify/tf_nn/rescaling_data/sc_static_clf_var_y.csv +1 -0
- molSimplify/tf_nn/rescaling_data/split_mean_x.csv +155 -0
- molSimplify/tf_nn/rescaling_data/split_mean_y.csv +1 -0
- molSimplify/tf_nn/rescaling_data/split_var_x.csv +155 -0
- molSimplify/tf_nn/rescaling_data/split_var_y.csv +1 -0
- molSimplify/tf_nn/sc_static_clf/sc_static_clf_model.h5 +0 -0
- molSimplify/tf_nn/sc_static_clf/sc_static_clf_train_name.csv +1591 -0
- molSimplify/tf_nn/sc_static_clf/sc_static_clf_train_x.csv +1592 -0
- molSimplify/tf_nn/sc_static_clf/sc_static_clf_train_y.csv +1592 -0
- molSimplify/tf_nn/sc_static_clf/sc_static_clf_vars.csv +154 -0
- molSimplify/tf_nn/split/split_model.h5 +0 -0
- molSimplify/tf_nn/split/split_model.json +1 -0
- molSimplify/tf_nn/split/split_vars.csv +155 -0
- molSimplify/tf_nn/split/split_x.csv +1902 -0
- molSimplify/tf_nn/split/split_y.csv +1902 -0
- molSimplify/tf_nn/split/train_names.csv +1901 -0
- molSimplify/utils/__init__.py +0 -0
- molSimplify/utils/decorators.py +16 -0
- molSimplify/utils/metaclasses.py +12 -0
- molSimplify/utils/tensorflow.py +23 -0
- molSimplify/utils/timer.py +16 -0
- molSimplify-1.7.4.dist-info/LICENSE +674 -0
- molSimplify-1.7.4.dist-info/METADATA +821 -0
- molSimplify-1.7.4.dist-info/RECORD +651 -0
- molSimplify-1.7.4.dist-info/WHEEL +5 -0
- molSimplify-1.7.4.dist-info/entry_points.txt +3 -0
- molSimplify-1.7.4.dist-info/top_level.txt +4 -0
- tests/generateTests.py +122 -0
- tests/helperFuncs.py +658 -0
- tests/informatics/test_MOF_descriptors.py +128 -0
- tests/informatics/test_active_learning.py +113 -0
- tests/informatics/test_coulomb_analyze.py +24 -0
- tests/informatics/test_graph_racs.py +193 -0
- tests/ml/test_kernels.py +20 -0
- tests/ml/test_layers.py +47 -0
- tests/runtest.py +10 -0
- tests/test_Mol2D.py +128 -0
- tests/test_basic_imports.py +62 -0
- tests/test_bidentate.py +25 -0
- tests/test_cli.py +20 -0
- tests/test_distgeom.py +106 -0
- tests/test_example_1.py +29 -0
- tests/test_example_3.py +31 -0
- tests/test_example_5.py +43 -0
- tests/test_example_7.py +28 -0
- tests/test_example_8.py +15 -0
- tests/test_example_tbp.py +15 -0
- tests/test_ff_xtb.py +111 -0
- tests/test_geocheck_oct.py +26 -0
- tests/test_geocheck_one_empty.py +15 -0
- tests/test_geometry.py +44 -0
- tests/test_inparse.py +76 -0
- tests/test_io.py +84 -0
- tests/test_jobgen.py +84 -0
- tests/test_joption_pythonic.py +27 -0
- tests/test_ligand_assign.py +58 -0
- tests/test_ligand_assign_consistent.py +60 -0
- tests/test_ligand_class.py +26 -0
- tests/test_ligand_from_mol_file.py +35 -0
- tests/test_ligands.py +86 -0
- tests/test_mol3D.py +337 -0
- tests/test_molcas_caspt2.py +15 -0
- tests/test_molcas_casscf.py +15 -0
- tests/test_old_ANNs.py +68 -0
- tests/test_orca_ccsdt.py +15 -0
- tests/test_orca_dft.py +15 -0
- tests/test_qcgen.py +50 -0
- tests/test_racs.py +124 -0
- tests/test_rmsd.py +68 -0
- tests/test_structgen_functions.py +198 -0
- tests/test_tetrahedral.py +29 -0
- tests/test_tutorial_10_part_one.py +16 -0
- tests/test_tutorial_10_part_two.py +15 -0
- tests/test_tutorial_2.py +11 -0
- tests/test_tutorial_3.py +15 -0
- tests/test_tutorial_4.py +57 -0
- tests/test_tutorial_6.py +10 -0
- tests/test_tutorial_8.py +29 -0
- tests/test_tutorial_9_part_one.py +15 -0
- tests/test_tutorial_9_part_two.py +15 -0
- tests/test_tutorial_qm9_part_one.py +6 -0
- tests/testresources/refs/racs/generate_references.py +85 -0
- workflows/NandyJACSAu2022/bridge_functionalizer.py +253 -0
- workflows/NandyJACSAu2022/frag_functionalizer.py +242 -0
- workflows/NandyJACSAu2022/fragment_classes.py +586 -0
- 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()
|