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,1592 @@
|
|
|
1
|
+
# @file cellbuilder.py
|
|
2
|
+
# Builds unit cells with adsorbed species.
|
|
3
|
+
#
|
|
4
|
+
# Written by JP Janet for HJK Group
|
|
5
|
+
#
|
|
6
|
+
# Dpt of Chemical Engineering, MIT
|
|
7
|
+
|
|
8
|
+
import os
|
|
9
|
+
import random
|
|
10
|
+
import copy
|
|
11
|
+
import numpy
|
|
12
|
+
from math import sqrt
|
|
13
|
+
|
|
14
|
+
from scipy.spatial import Delaunay
|
|
15
|
+
from molSimplify.Classes.atom3D import atom3D
|
|
16
|
+
from molSimplify.Classes.mol3D import mol3D
|
|
17
|
+
from molSimplify.Classes.globalvars import globalvars
|
|
18
|
+
from molSimplify.Scripts.cellbuilder_tools import (cell_ffopt,
|
|
19
|
+
center_of_sym,
|
|
20
|
+
check_top_layer_correct,
|
|
21
|
+
closest_torus_point,
|
|
22
|
+
distance_2d_torus,
|
|
23
|
+
evaluate_basis_coefficients,
|
|
24
|
+
find_all_surface_atoms,
|
|
25
|
+
find_extents,
|
|
26
|
+
find_extents_cv,
|
|
27
|
+
freeze_bottom_n_layers,
|
|
28
|
+
get_basis_coefficients,
|
|
29
|
+
import_from_cif,
|
|
30
|
+
mdistance,
|
|
31
|
+
normalize_vector,
|
|
32
|
+
periodic_mindist,
|
|
33
|
+
periodic_selfdist,
|
|
34
|
+
shave_surface_layer,
|
|
35
|
+
shave_under_layer,
|
|
36
|
+
threshold_basis,
|
|
37
|
+
xgcd,
|
|
38
|
+
zero_z)
|
|
39
|
+
from molSimplify.Scripts.geometry import (PointRotateAxis,
|
|
40
|
+
checkcolinear,
|
|
41
|
+
vecdiff,
|
|
42
|
+
rotate_around_axis,
|
|
43
|
+
rotation_params,
|
|
44
|
+
vecangle,
|
|
45
|
+
distance)
|
|
46
|
+
from molSimplify.Scripts.periodic_QE import (write_periodic_mol3d_to_qe)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
###############################
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def d_fix(unit_cell, cell_vector):
|
|
53
|
+
fixed_cell = mol3D()
|
|
54
|
+
fixed_cell.copymol3D(unit_cell)
|
|
55
|
+
mind = 100
|
|
56
|
+
for i, atoms in enumerate(fixed_cell.getAtoms()):
|
|
57
|
+
this_distance = mdistance(atoms.coords(), [0, 0, 0])
|
|
58
|
+
print(("min d is " + str(mind)))
|
|
59
|
+
print(("atom at " + str(atoms.coords())))
|
|
60
|
+
if this_distance < mind:
|
|
61
|
+
mind = this_distance
|
|
62
|
+
minatom = atoms
|
|
63
|
+
minind = i
|
|
64
|
+
print('this was saved')
|
|
65
|
+
print("\n\n")
|
|
66
|
+
c = cell_vector[2]
|
|
67
|
+
dx = c[0]
|
|
68
|
+
dy = c[1]
|
|
69
|
+
dz = c[2]
|
|
70
|
+
trans_vect = (dx, dy, dz)
|
|
71
|
+
new_atom = atom3D(minatom.symbol(), minatom.coords())
|
|
72
|
+
new_atom.translate(trans_vect)
|
|
73
|
+
fixed_cell.addAtom(new_atom)
|
|
74
|
+
fixed_cell.deleteatoms([minind])
|
|
75
|
+
return fixed_cell
|
|
76
|
+
#####################################################
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def cut_cell_to_index(unit_cell, cell_vector, miller_index):
|
|
80
|
+
# determine the plane:
|
|
81
|
+
cut_cell = mol3D()
|
|
82
|
+
cut_cell.copymol3D(unit_cell)
|
|
83
|
+
h, k, l = miller_index # noqa: E741
|
|
84
|
+
# print('h,k,l',str(h) + ' ' + str(k) + ' ' + str(l))
|
|
85
|
+
disc, p, q = xgcd(k, l)
|
|
86
|
+
# print('p,q',str(p) + ' ' + str(q))
|
|
87
|
+
cell_vector = numpy.array(cell_vector)
|
|
88
|
+
k1 = numpy.dot(p*(k*cell_vector[0]-h*cell_vector[1]) + q*(
|
|
89
|
+
l*cell_vector[0] - h*cell_vector[2]), l*cell_vector[1] - k*cell_vector[2])
|
|
90
|
+
k2 = numpy.dot(l*(k*cell_vector[0]-h*cell_vector[1]) - k*(
|
|
91
|
+
l*cell_vector[0] - h*cell_vector[2]), l*cell_vector[1] - k*cell_vector[2])
|
|
92
|
+
# print('k1',k1)
|
|
93
|
+
# print('k2',k2)
|
|
94
|
+
tol = 1e-3
|
|
95
|
+
if abs(k2) > tol:
|
|
96
|
+
c = -1*int(round(k1/k2))
|
|
97
|
+
p, q = p+c*l, q - c*k
|
|
98
|
+
v1 = p*numpy.array(k*cell_vector[0]-h*cell_vector[1]) + \
|
|
99
|
+
q*numpy.array(l*cell_vector[0] - h*cell_vector[2])
|
|
100
|
+
v2 = numpy.array(l*cell_vector[1]-k*cell_vector[2])
|
|
101
|
+
disc, a, b = xgcd(p*k + q*l, h)
|
|
102
|
+
v3 = numpy.array(b*cell_vector[0] + a*p *
|
|
103
|
+
cell_vector[1] + a*q*cell_vector[2])
|
|
104
|
+
|
|
105
|
+
non_zero_indices = list()
|
|
106
|
+
zero_indices = list()
|
|
107
|
+
for i in [0, 1, 2]:
|
|
108
|
+
if not (miller_index[i] == 0):
|
|
109
|
+
non_zero_indices.append(i)
|
|
110
|
+
else:
|
|
111
|
+
zero_indices.append(i)
|
|
112
|
+
|
|
113
|
+
print(('nz ind', non_zero_indices))
|
|
114
|
+
plane_normal = numpy.zeros(3)
|
|
115
|
+
if len(non_zero_indices) == 3:
|
|
116
|
+
# zint = 1/(miller_index[2]*cell_vector[2][2])
|
|
117
|
+
# yint = 1/(miller_index[1]*cell_vector[1][1])
|
|
118
|
+
# xint = 1/(miller_index[0]*cell_vector[0][0])
|
|
119
|
+
# w = [0,0,0]
|
|
120
|
+
# w[2] = zint
|
|
121
|
+
# w[1] = -w[2]/yint
|
|
122
|
+
# w[0] = -w[2]/xint
|
|
123
|
+
plane_normal = numpy.cross(v1, v2)
|
|
124
|
+
elif len(non_zero_indices) == 2:
|
|
125
|
+
# print('\n\n\n\n')
|
|
126
|
+
# print(cell_vector)
|
|
127
|
+
# print("\n\n")
|
|
128
|
+
vec1 = [0, 0, 0]
|
|
129
|
+
vec1[non_zero_indices[0]] = cell_vector[non_zero_indices[0]
|
|
130
|
+
][non_zero_indices[0]]
|
|
131
|
+
vec2 = [0, 0, 0]
|
|
132
|
+
vec2[non_zero_indices[1]] = cell_vector[non_zero_indices[1]
|
|
133
|
+
][non_zero_indices[1]]
|
|
134
|
+
vec3 = [0, 0, 0]
|
|
135
|
+
vec3[zero_indices[0]] = cell_vector[zero_indices[0]][zero_indices[0]]
|
|
136
|
+
# print('vec1',vec1)
|
|
137
|
+
# print('vec2',vec2)
|
|
138
|
+
# print('vec3',vec3)
|
|
139
|
+
plane_normal = numpy.cross(v1, v2)
|
|
140
|
+
elif len(non_zero_indices) == 1:
|
|
141
|
+
|
|
142
|
+
v1 = cell_vector[zero_indices[0]]
|
|
143
|
+
v2 = cell_vector[zero_indices[1]]
|
|
144
|
+
v3 = cell_vector[non_zero_indices[0]]
|
|
145
|
+
plane_normal = numpy.cross(v1, v2)
|
|
146
|
+
print(miller_index)
|
|
147
|
+
print(('plane normal is ', plane_normal))
|
|
148
|
+
angle = vecangle(plane_normal, [0, 0, 1])
|
|
149
|
+
u = numpy.cross(plane_normal, [0, 0, 1])
|
|
150
|
+
return v1, v2, v3, angle, u
|
|
151
|
+
|
|
152
|
+
##################################
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
def concave_hull(points, alpha):
|
|
156
|
+
# points should be tuples
|
|
157
|
+
de = Delaunay(points)
|
|
158
|
+
for i in de.simplices:
|
|
159
|
+
tmp = [] # noqa F841 WIP
|
|
160
|
+
j = [points[c] for c in i] # noqa F841 WIP
|
|
161
|
+
# print(i)
|
|
162
|
+
# print(j)
|
|
163
|
+
# print(de)
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
points = [[1, 1], [1, 0], [0, 1], [0, 0]]
|
|
167
|
+
|
|
168
|
+
###################################
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
def unit_to_super(unit_cell, cell_vector, duplication_vector):
|
|
172
|
+
# INPUT
|
|
173
|
+
# - unit_cell: mol3D class that contains the unit cell
|
|
174
|
+
# - cell_vector: list of float contains the cell vectors a,b,c
|
|
175
|
+
# - duplication_vector: list of int the number of duplications in each dim
|
|
176
|
+
# OUTPUT
|
|
177
|
+
# - super_cell: mol3D class that contains the super cell
|
|
178
|
+
super_cell = mol3D()
|
|
179
|
+
print(cell_vector)
|
|
180
|
+
acell = duplication_vector[0]
|
|
181
|
+
bcell = duplication_vector[1]
|
|
182
|
+
ccell = duplication_vector[2]
|
|
183
|
+
a = cell_vector[0]
|
|
184
|
+
b = cell_vector[1]
|
|
185
|
+
c = cell_vector[2]
|
|
186
|
+
for i in range(0, acell):
|
|
187
|
+
for j in range(0, bcell):
|
|
188
|
+
for k in range(0, ccell):
|
|
189
|
+
for atoms in unit_cell.getAtoms():
|
|
190
|
+
# print(str(i) + str(j) + str(k))
|
|
191
|
+
dx = 0 + i*a[0] + j*b[0] + k*c[0]
|
|
192
|
+
dy = 0 + i*a[1] + j*b[1] + k*c[1]
|
|
193
|
+
dz = 0 + i*a[2] + j*b[2] + k*c[2]
|
|
194
|
+
trans_vect = (dx, dy, dz)
|
|
195
|
+
new_atom = atom3D(
|
|
196
|
+
atoms.symbol(), atoms.coords(), atoms.name)
|
|
197
|
+
new_atom.translate(trans_vect)
|
|
198
|
+
super_cell.addAtom(new_atom)
|
|
199
|
+
return super_cell
|
|
200
|
+
#############################
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
def multialign_objective_function(payload, surface_coord_list, cand_list, bind_dist):
|
|
204
|
+
# INPUT
|
|
205
|
+
# - payload: mol3D, the structure to add
|
|
206
|
+
# - surface_coord_list: list of list of 3 float, coordinates of the
|
|
207
|
+
# slab target points
|
|
208
|
+
# - cand_list: list of int, indices of the attachment points in the
|
|
209
|
+
# payload
|
|
210
|
+
# - bind_dist: float, target alignment distance
|
|
211
|
+
# OUPUT
|
|
212
|
+
# - cost: float, sum of squared error, the difference between
|
|
213
|
+
# the actual distance and the target
|
|
214
|
+
cost = 0
|
|
215
|
+
# print('cand list is ' + str(cand_list))
|
|
216
|
+
# print('surface_coord_list ' + str(surface_coord_list))
|
|
217
|
+
for indices in enumerate(cand_list):
|
|
218
|
+
v1 = (surface_coord_list[indices[0]])
|
|
219
|
+
v2 = payload.getAtom(int(indices[1])).coords()
|
|
220
|
+
cost += numpy.power((mdistance(v1, v2)) - bind_dist, 2)
|
|
221
|
+
return cost
|
|
222
|
+
#############################
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
def tracked_merge(payload, super_cell):
|
|
226
|
+
# INPUT
|
|
227
|
+
# - super_cell: mol3D, the slab (and previously added adsorbates)
|
|
228
|
+
# - payload: mol3D, the structure to add
|
|
229
|
+
# OUPUT
|
|
230
|
+
# - merged_cell: mol3D, merged combintation of payload and cell
|
|
231
|
+
# - payload_index: list of int, indices of payload atoms in cell
|
|
232
|
+
# - slab_index: list of int, indices of slab atoms in the cell
|
|
233
|
+
payload_index = [i for i in range(0, payload.natoms)]
|
|
234
|
+
slab_index = [i + payload.natoms for i in range(0, super_cell.natoms)]
|
|
235
|
+
merged_cell = mol3D()
|
|
236
|
+
merged_cell.copymol3D(payload)
|
|
237
|
+
merged_cell.combine(super_cell)
|
|
238
|
+
return merged_cell, payload_index, slab_index
|
|
239
|
+
#############################
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
def force_field_relax_with_slab(super_cell, payload, cand_list, its):
|
|
243
|
+
# INPUT
|
|
244
|
+
# - super_cell: mol3D, the slab (and previously added adsorbates)
|
|
245
|
+
# - payload: mol3D, the structure to add
|
|
246
|
+
# - can_ind: list of int, indices of taget attachement points in molecule
|
|
247
|
+
# OUPUT
|
|
248
|
+
# - new_payload: mol3D, payload relaxed by force field with slab fixed
|
|
249
|
+
new_payload = mol3D()
|
|
250
|
+
new_payload.copymol3D(payload)
|
|
251
|
+
cell_copy = mol3D()
|
|
252
|
+
surface_sites_list = find_all_surface_atoms(super_cell, tol=1e-2)
|
|
253
|
+
for sites in surface_sites_list:
|
|
254
|
+
cell_copy.addAtom(super_cell.getAtom(sites))
|
|
255
|
+
merged_payload, payload_ind, slab_index = tracked_merge(
|
|
256
|
+
new_payload, cell_copy)
|
|
257
|
+
merged_payload.writexyz('modi.xyz')
|
|
258
|
+
full_fixed_atoms_list = cand_list + slab_index # freeze the slab componentsp
|
|
259
|
+
distorted_payload = mol3D()
|
|
260
|
+
distorted_payload.copymol3D(merged_payload)
|
|
261
|
+
print(('in ff, distorded coords' + str(distorted_payload.getAtom(0).coords())))
|
|
262
|
+
distorted_payload, enl = cell_ffopt(
|
|
263
|
+
'uff', merged_payload, full_fixed_atoms_list)
|
|
264
|
+
print(('after ff, distorded coords' + str(distorted_payload.getAtom(0).coords())))
|
|
265
|
+
print(full_fixed_atoms_list)
|
|
266
|
+
# distorted_payload.writexyz(str(its)+'modr.xyz')
|
|
267
|
+
distorted_payload.deleteatoms(slab_index)
|
|
268
|
+
return distorted_payload
|
|
269
|
+
#############################
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
def surface_center(super_cell):
|
|
273
|
+
# INPUT
|
|
274
|
+
# - super_cell: mol3D, the slab (and previously added adsorbates)
|
|
275
|
+
# - payload: mol3D, the structure to add
|
|
276
|
+
# - can_ind: list of int, indices of taget attachement points in molecule
|
|
277
|
+
# OUPUT
|
|
278
|
+
# - new_payload: mol3D, payload relaxed by force field with slab fixed
|
|
279
|
+
cell_copy = mol3D()
|
|
280
|
+
surface_sites_list = find_all_surface_atoms(super_cell, tol=1e-2)
|
|
281
|
+
for sites in surface_sites_list:
|
|
282
|
+
cell_copy.addAtom(super_cell.getAtom(sites))
|
|
283
|
+
centroid = cell_copy.centersym()
|
|
284
|
+
|
|
285
|
+
return centroid
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
##############################
|
|
289
|
+
def choose_nearest_neighbour(target_site, avail_sites_dict, occupied_sites_dict, super_cell, super_cell_vector, debug=False):
|
|
290
|
+
# INPUT
|
|
291
|
+
# - avail_sites_dict: dict with {index:[coords] } of {int,list of float}, free sites
|
|
292
|
+
# - occupied_sites_dict: dict with {index:[coords] } of {int,list of float}, occupied sites
|
|
293
|
+
# - target_site: list of doubles, coords that the new site should be close to
|
|
294
|
+
|
|
295
|
+
# - weight: float in [0,1], how strongly the interace-absorbate distance is weighted
|
|
296
|
+
# - method: 'linear' a linear combination of distance from centroid and neighbour
|
|
297
|
+
# distance is used
|
|
298
|
+
# 'log' a logarithmic weighting is used - strong re
|
|
299
|
+
# OUPUT
|
|
300
|
+
# - nn_site: index of nearest neighbour site, a key for avail_sites_dict
|
|
301
|
+
extents = find_extents_cv(super_cell_vector)
|
|
302
|
+
# print('extents = ' + str(extents))
|
|
303
|
+
weight = 0 # favours adjaceny to point over distance from other occupied sites
|
|
304
|
+
# get the nearest site to target
|
|
305
|
+
score = 100000 # weighted assessment, lower is better
|
|
306
|
+
avail_sites_list = list(avail_sites_dict.keys())
|
|
307
|
+
occupied_sites_list = list(occupied_sites_dict.keys())
|
|
308
|
+
if debug:
|
|
309
|
+
print('********** choosing nearest neighbour sites ********')
|
|
310
|
+
if (len(avail_sites_list) > 1): # more than 1 option, pick closest to target site
|
|
311
|
+
for indices in avail_sites_list:
|
|
312
|
+
if debug:
|
|
313
|
+
print(('checking site ' + str(indices) + ' at ' +
|
|
314
|
+
str(avail_sites_dict[indices]) + ' relative to ' + str(target_site)))
|
|
315
|
+
# NOT the torus distance - must be two cells in one unit
|
|
316
|
+
distance_to_target = distance(
|
|
317
|
+
target_site, avail_sites_dict[indices])
|
|
318
|
+
distance_to_nearest_occupied = 0
|
|
319
|
+
for neighbours in occupied_sites_list:
|
|
320
|
+
# get distance to nearest neighbour
|
|
321
|
+
distance_to_nearest_occupied = max(distance_2d_torus(
|
|
322
|
+
avail_sites_dict[indices], occupied_sites_dict[neighbours], extents), distance_to_nearest_occupied)
|
|
323
|
+
this_score = (1 - weight)*distance_to_target - \
|
|
324
|
+
weight*distance_to_nearest_occupied
|
|
325
|
+
if debug:
|
|
326
|
+
print(('this score is ' + str(this_score)))
|
|
327
|
+
if this_score < score:
|
|
328
|
+
score = this_score
|
|
329
|
+
if debug:
|
|
330
|
+
print(('New lowest score at ' + str(indices) +
|
|
331
|
+
' has score =' + str(score) + '\n'))
|
|
332
|
+
nn_site = indices
|
|
333
|
+
elif (len(avail_sites_list) == 1):
|
|
334
|
+
nn_site = avail_sites_list[0]
|
|
335
|
+
else:
|
|
336
|
+
emsg = ('error: no free site is possible')
|
|
337
|
+
print(emsg)
|
|
338
|
+
return None
|
|
339
|
+
if debug:
|
|
340
|
+
print(('**** final choice = ' +
|
|
341
|
+
str(avail_sites_dict[nn_site]) + ' at ' + str(score)))
|
|
342
|
+
return nn_site
|
|
343
|
+
#####################################
|
|
344
|
+
|
|
345
|
+
|
|
346
|
+
def choose_best_site(avail_sites_dict, occupied_sites_dict, centroid, super_cell, super_cell_vector, weight=0.5, method='linear', debug=False):
|
|
347
|
+
|
|
348
|
+
# INPUT
|
|
349
|
+
# - avail_sites_dict: dict with {index:[coords] } of {int,list of float}, free sites
|
|
350
|
+
# - occupied_sites_dict: dict with {index:[coords] } of {int,list of float}, occupied sites
|
|
351
|
+
# - weight: float in [0,1], how strongly the interace-absorbate distance is weighted
|
|
352
|
+
# - method: 'linear' a linear combination of distance from centroid and neighbour
|
|
353
|
+
# distance is used
|
|
354
|
+
# 'log' a logarithmic weighting is used - strong re
|
|
355
|
+
# OUPUT
|
|
356
|
+
# - target_site: index of target site, a key for avail_sites_dict
|
|
357
|
+
extents = find_extents_cv(super_cell_vector)
|
|
358
|
+
centroid = surface_center(super_cell)
|
|
359
|
+
score = 100000 # weighted assessment, lower is better
|
|
360
|
+
avail_sites_list = list(avail_sites_dict.keys())
|
|
361
|
+
random.shuffle(avail_sites_list)
|
|
362
|
+
occupied_sites_list = list(occupied_sites_dict.keys())
|
|
363
|
+
if debug:
|
|
364
|
+
print(('extents = ' + str(extents)))
|
|
365
|
+
print(('centroid is at ' + str(centroid)))
|
|
366
|
+
print(('ac sites dict = '+str(avail_sites_dict)))
|
|
367
|
+
print(('oc sites list = '+str(occupied_sites_list)))
|
|
368
|
+
print(('ac sites list = '+str(avail_sites_list)))
|
|
369
|
+
print(('weight = ' + str(weight)))
|
|
370
|
+
if (len(avail_sites_list) > 1): # more than 1 option, pick closest to center of plane
|
|
371
|
+
for indices in avail_sites_list:
|
|
372
|
+
# distance_to_center = distance_2d_torus(centroid,avail_sites_dict[indices],extents)
|
|
373
|
+
distance_to_center = distance(centroid, avail_sites_dict[indices])
|
|
374
|
+
|
|
375
|
+
distance_to_nearest_occupied = 1000
|
|
376
|
+
for neighbours in occupied_sites_list:
|
|
377
|
+
# get distance to nearest neighbour
|
|
378
|
+
if debug:
|
|
379
|
+
print(
|
|
380
|
+
('Neighbour:' + str(occupied_sites_dict[neighbours]) + ' point is at ' + str(avail_sites_dict[indices])))
|
|
381
|
+
distance_to_nearest_occupied = min(distance_2d_torus(
|
|
382
|
+
avail_sites_dict[indices], occupied_sites_dict[neighbours], extents), distance_to_nearest_occupied)
|
|
383
|
+
if debug:
|
|
384
|
+
print(('dist to nearest = ' + str(distance_to_nearest_occupied) +
|
|
385
|
+
' at ' + str(avail_sites_dict[indices])))
|
|
386
|
+
if (method == 'linear'):
|
|
387
|
+
this_score = (1 - weight)*distance_to_center - \
|
|
388
|
+
weight*distance_to_nearest_occupied
|
|
389
|
+
elif (method == 'log'):
|
|
390
|
+
this_score = (1 - weight)*abs(numpy.log(distance_to_center)) - \
|
|
391
|
+
weight*abs(numpy.log(distance_to_nearest_occupied))
|
|
392
|
+
if debug:
|
|
393
|
+
print(('the score here : ' + str(this_score) +
|
|
394
|
+
' oc sites ' + str(occupied_sites_dict)))
|
|
395
|
+
if this_score < score:
|
|
396
|
+
score = this_score
|
|
397
|
+
target_site = indices
|
|
398
|
+
if debug:
|
|
399
|
+
print(('target site is ' + str(indices) + ' at ' +
|
|
400
|
+
str(super_cell.getAtom(indices).coords())))
|
|
401
|
+
elif (len(avail_sites_list) == 1):
|
|
402
|
+
target_site = avail_sites_list[0]
|
|
403
|
+
else:
|
|
404
|
+
emsg = ('error: no free site is possible')
|
|
405
|
+
print(emsg)
|
|
406
|
+
return None
|
|
407
|
+
print(('choosing site ' + str(target_site) + ' at ' +
|
|
408
|
+
str(avail_sites_dict[target_site]) + ' score: ' + str(score) + ' oc sites ' + str(occupied_sites_dict) + '\n'))
|
|
409
|
+
return target_site
|
|
410
|
+
#####################################
|
|
411
|
+
|
|
412
|
+
|
|
413
|
+
def align_payload_to_multi_site(payload, surface_coord_list, cand_list, bind_dist, debug=False):
|
|
414
|
+
# INPUT
|
|
415
|
+
# - payload: mol3D class that contains the molecule to place
|
|
416
|
+
# - align_coord: list of lists of float, positions on surface
|
|
417
|
+
# - cand_mask: list of int, indices of atoms in payload that will be aligned
|
|
418
|
+
# can also contain a string, mask, list of indicies
|
|
419
|
+
# OUPUT
|
|
420
|
+
# - newpay_load: mol3D class with the atom in payload(cand_in) directly above
|
|
421
|
+
# align_coord. )Does NOT change height
|
|
422
|
+
|
|
423
|
+
# Get all atoms on the top surface - NB, this will not handle complex surfaces, split calls by atom type
|
|
424
|
+
# print('align symbol is ' + payload.getAtom(cand_ind).symbol())
|
|
425
|
+
new_payload = mol3D()
|
|
426
|
+
new_payload.copymol3D(payload)
|
|
427
|
+
payload_coord = center_of_sym(
|
|
428
|
+
[new_payload.getAtom(i).coords() for i in cand_list])
|
|
429
|
+
surface_coord = center_of_sym(surface_coord_list)
|
|
430
|
+
|
|
431
|
+
vec1 = vecdiff(surface_coord, payload.centersym())
|
|
432
|
+
vec2 = vecdiff(payload_coord, new_payload.centersym())
|
|
433
|
+
rotate_angle = vecangle(vec1, vec2)
|
|
434
|
+
theta, u = rotation_params(
|
|
435
|
+
payload_coord, new_payload.centersym(), surface_coord)
|
|
436
|
+
if debug:
|
|
437
|
+
print(('\n vec1 is ' + str(vec1)))
|
|
438
|
+
print(('vec2 is ' + str(vec2) + '\n'))
|
|
439
|
+
print(cand_list)
|
|
440
|
+
print(theta)
|
|
441
|
+
print(('angle is ' + str(rotate_angle)))
|
|
442
|
+
print(('normal is ' + str(u)))
|
|
443
|
+
new_payload = rotate_around_axis(
|
|
444
|
+
new_payload, new_payload.centersym(), u, rotate_angle)
|
|
445
|
+
cost = multialign_objective_function(
|
|
446
|
+
new_payload, surface_coord_list, cand_list, bind_dist)
|
|
447
|
+
final_payload = new_payload
|
|
448
|
+
|
|
449
|
+
# need to determine the collinearity of the points are co-plannar
|
|
450
|
+
collinear_flag = False
|
|
451
|
+
coplanar_flag = False
|
|
452
|
+
if len(cand_list) == 2:
|
|
453
|
+
collinear_flag = True
|
|
454
|
+
if len(cand_list) == 3:
|
|
455
|
+
coplanar_flag = True
|
|
456
|
+
collinear_flag = checkcolinear(new_payload.getAtom(cand_list[0]).coords(
|
|
457
|
+
), new_payload.getAtom(cand_list[1]).coords(), new_payload.getAtom(cand_list[2]).coords())
|
|
458
|
+
elif len(cand_list) == 4:
|
|
459
|
+
pass
|
|
460
|
+
# coplanar_flag = checkplanar(new_payload.getAtom(cand_list[0]),new_payload.getAtom(cand_list[1]),new_payload.getAtom(cand_list[2]),new_payload.getAtom(cand_list[3]).coords())
|
|
461
|
+
new_u = numpy.zeros(3)
|
|
462
|
+
if collinear_flag: # there is a single line defining the axis - align this with
|
|
463
|
+
line_slope = vecdiff(new_payload.getAtom(
|
|
464
|
+
cand_list[0]).coords(), new_payload.getAtom(cand_list[1]).coords())
|
|
465
|
+
print(('collinear case : line ' + str(line_slope)))
|
|
466
|
+
new_u = numpy.cross(line_slope, vecdiff(surface_coord, payload_coord))
|
|
467
|
+
print(('new u is ' + str(new_u)))
|
|
468
|
+
elif coplanar_flag:
|
|
469
|
+
dvec1 = vecdiff(new_payload.getAtom(cand_list[0]).coords(
|
|
470
|
+
), new_payload.getAtom(cand_list[1]).coords())
|
|
471
|
+
dvec2 = vecdiff(new_payload.getAtom(cand_list[0]).coords(
|
|
472
|
+
), new_payload.getAtom(cand_list[2]).coords())
|
|
473
|
+
plane_vector = numpy.cross(dvec1, dvec2)
|
|
474
|
+
print(('coplanar case : normal ' + str(plane_vector)))
|
|
475
|
+
new_u = numpy.cross(plane_vector, vecdiff(
|
|
476
|
+
surface_coord, payload_coord))
|
|
477
|
+
print(('new u is ' + str(new_u)))
|
|
478
|
+
|
|
479
|
+
if collinear_flag or coplanar_flag:
|
|
480
|
+
print('starting rotation for coplanar case')
|
|
481
|
+
for rotate_angle in range(-100, 100):
|
|
482
|
+
this_payload = mol3D()
|
|
483
|
+
this_payload.copymol3D(final_payload)
|
|
484
|
+
this_payload = rotate_around_axis(this_payload, this_payload.centersym(
|
|
485
|
+
), new_u, float(rotate_angle)/10) # fine grained check
|
|
486
|
+
this_cost = multialign_objective_function(
|
|
487
|
+
this_payload, surface_coord_list, cand_list, bind_dist)
|
|
488
|
+
if (this_cost < (cost)):
|
|
489
|
+
# print('current cost = ' + str(this_cost) + ', the max is ' + str(cost))
|
|
490
|
+
if debug:
|
|
491
|
+
print(('accepting rotate at theta = ' + str(rotate_angle)))
|
|
492
|
+
cost = this_cost
|
|
493
|
+
final_payload = this_payload
|
|
494
|
+
print('placement complete')
|
|
495
|
+
return final_payload
|
|
496
|
+
|
|
497
|
+
##################################
|
|
498
|
+
|
|
499
|
+
|
|
500
|
+
def combine_multi_aligned_payload_with_cell(super_cell, super_cell_vector, payload, cand_list, surface_coord_list, bind_dist, duplicate=False, control_angle=False, align_axis=False, align_ind=False, debug=False):
|
|
501
|
+
# This function does final lowering, rotate and merge of previously aligned molecule with surface
|
|
502
|
+
# Precede all calls to this funciton with allign_payload_to_Site to avoid strange behaviour
|
|
503
|
+
# INPUT
|
|
504
|
+
# - super_cell: mol3D class that contains the super cell
|
|
505
|
+
# - payload: mol3D class that contains that target molecule
|
|
506
|
+
# - payload_ind: int, index of atom in payload that will bind to the surface
|
|
507
|
+
# - align_coord: list of float, coordinates of the target surface site
|
|
508
|
+
# - bind_dist: float, binding distance in A
|
|
509
|
+
# - duplicate: logical, create a negative-z reflection as well?
|
|
510
|
+
# OUPUT
|
|
511
|
+
# - combined_cel: mol3D class, loaded cell
|
|
512
|
+
combined_cell = mol3D()
|
|
513
|
+
combined_cell.copymol3D(super_cell)
|
|
514
|
+
new_payload = mol3D()
|
|
515
|
+
new_payload.copymol3D(payload)
|
|
516
|
+
trial_cell = mol3D()
|
|
517
|
+
trial_cell.copymol3D(combined_cell)
|
|
518
|
+
|
|
519
|
+
######## DEBUG ONLY #####
|
|
520
|
+
backup_payload = mol3D()
|
|
521
|
+
backup_payload.copymol3D(payload)
|
|
522
|
+
if debug:
|
|
523
|
+
print(('trying to align mol: ' + str(cand_list)))
|
|
524
|
+
print(('and sites ' + str(surface_coord_list)))
|
|
525
|
+
|
|
526
|
+
##########################
|
|
527
|
+
|
|
528
|
+
extents = find_extents_cv(super_cell_vector)
|
|
529
|
+
# the generalized distance descriptors
|
|
530
|
+
payload_coord = center_of_sym(
|
|
531
|
+
[new_payload.getAtom(i).coords() for i in cand_list])
|
|
532
|
+
surface_coord = center_of_sym(surface_coord_list)
|
|
533
|
+
|
|
534
|
+
vec = vecdiff(surface_coord, payload_coord)
|
|
535
|
+
cost = multialign_objective_function(
|
|
536
|
+
new_payload, surface_coord_list, cand_list, bind_dist)
|
|
537
|
+
final_payload = new_payload
|
|
538
|
+
distances_list = []
|
|
539
|
+
for indices in enumerate(cand_list):
|
|
540
|
+
v1 = (surface_coord_list[indices[0]])
|
|
541
|
+
v2 = final_payload.getAtom(int(indices[1])).coords()
|
|
542
|
+
distances_list.append((distance(v1, v2)))
|
|
543
|
+
if debug:
|
|
544
|
+
print(('\n\n Target distance was ' + str(bind_dist) +
|
|
545
|
+
', achieved ' + str(distances_list)))
|
|
546
|
+
print(('the cm of sites: ' + str(surface_coord)))
|
|
547
|
+
print(('the cm of mol: ' + str(payload_coord)))
|
|
548
|
+
print(('cost before rotation =' + str(cost)))
|
|
549
|
+
distances_list = []
|
|
550
|
+
for indices in enumerate(cand_list):
|
|
551
|
+
v1 = (surface_coord_list[indices[0]])
|
|
552
|
+
v2 = final_payload.getAtom(int(indices[1])).coords()
|
|
553
|
+
distances_list.append((distance(v1, v2)))
|
|
554
|
+
if debug:
|
|
555
|
+
print(('\n\n Target distance was ' + str(bind_dist) +
|
|
556
|
+
', achieved ' + str(distances_list)))
|
|
557
|
+
|
|
558
|
+
print('starting align rotation')
|
|
559
|
+
for rotate_angle in range(0, 360):
|
|
560
|
+
this_payload = mol3D()
|
|
561
|
+
this_payload.copymol3D(new_payload)
|
|
562
|
+
this_payload = rotate_around_axis(
|
|
563
|
+
this_payload, this_payload.centersym(), vec, rotate_angle)
|
|
564
|
+
this_cost = multialign_objective_function(
|
|
565
|
+
this_payload, surface_coord_list, cand_list, bind_dist)
|
|
566
|
+
if (this_cost < (cost)):
|
|
567
|
+
cost = this_cost
|
|
568
|
+
final_payload = this_payload
|
|
569
|
+
if debug:
|
|
570
|
+
print(('cost after rotation =' + str(cost)))
|
|
571
|
+
distances_list = []
|
|
572
|
+
|
|
573
|
+
for indices in enumerate(cand_list):
|
|
574
|
+
v1 = (surface_coord_list[indices[0]])
|
|
575
|
+
v2 = final_payload.getAtom(int(indices[1])).coords()
|
|
576
|
+
distances_list.append((distance(v1, v2)))
|
|
577
|
+
if debug:
|
|
578
|
+
print(('\n\n Target distance was ' + str(bind_dist) +
|
|
579
|
+
', achieved ' + str(distances_list)))
|
|
580
|
+
|
|
581
|
+
# lower into positon
|
|
582
|
+
# step size:
|
|
583
|
+
factor = 0.20
|
|
584
|
+
deltaZ = factor*(distance(payload_coord, surface_coord)-bind_dist)
|
|
585
|
+
this_step_accepted = True
|
|
586
|
+
num_bad_steps = 0
|
|
587
|
+
break_flag = False
|
|
588
|
+
maxits = 250
|
|
589
|
+
its = 0
|
|
590
|
+
while (not break_flag) and (its < maxits):
|
|
591
|
+
its += 1
|
|
592
|
+
if (not this_step_accepted) and (num_bad_steps <= 4):
|
|
593
|
+
factor = 0.1*factor
|
|
594
|
+
elif (not this_step_accepted) and (num_bad_steps > 4):
|
|
595
|
+
break_flag = True
|
|
596
|
+
payload_coord = center_of_sym(
|
|
597
|
+
[final_payload.getAtom(i).coords() for i in cand_list])
|
|
598
|
+
# this will be lowered slowly, then rotate to optimize at each height
|
|
599
|
+
trans_vec = [factor*deltaZ *
|
|
600
|
+
element for element in normalize_vector(vec)]
|
|
601
|
+
this_payload = mol3D()
|
|
602
|
+
this_payload.copymol3D(final_payload)
|
|
603
|
+
this_payload.translate(trans_vec)
|
|
604
|
+
this_cost = multialign_objective_function(
|
|
605
|
+
this_payload, surface_coord_list, cand_list, bind_dist)
|
|
606
|
+
this_dist = min(periodic_mindist(this_payload, combined_cell,
|
|
607
|
+
extents), this_payload.mindist(combined_cell))
|
|
608
|
+
this_coord = center_of_sym(
|
|
609
|
+
[this_payload.getAtom(i).coords() for i in cand_list])
|
|
610
|
+
|
|
611
|
+
this_deltaZ = (distance(this_coord, surface_coord)-bind_dist)
|
|
612
|
+
if debug:
|
|
613
|
+
print(('cost = ' + str(this_cost) + '/' + str(cost) + ' i = ' + str(its) + ' dz = ' + str(deltaZ) +
|
|
614
|
+
' dist ' + str(this_dist) + ' b step = ' + str(num_bad_steps) + ' nxt dz = ' + str(this_deltaZ)))
|
|
615
|
+
if (this_cost < (cost)) and (this_dist > 0.75) and (deltaZ > 1e-4):
|
|
616
|
+
if debug:
|
|
617
|
+
print(('accepting down shift at i = ' + str(its)))
|
|
618
|
+
cost = this_cost
|
|
619
|
+
del final_payload
|
|
620
|
+
final_payload = mol3D()
|
|
621
|
+
if (this_payload.mindist(combined_cell) < 1.5):
|
|
622
|
+
if debug:
|
|
623
|
+
print(('ff on at iteration ' + str(its)))
|
|
624
|
+
distorted_payload = mol3D()
|
|
625
|
+
distorted_payload.copymol3D(this_payload)
|
|
626
|
+
print('Warning, a force-field relaxation is in progress. For large molecules (Natoms > 50), this may take a few minutes. Please be patient.')
|
|
627
|
+
distorted_payload = force_field_relax_with_slab(
|
|
628
|
+
super_cell, this_payload, cand_list, its)
|
|
629
|
+
if debug:
|
|
630
|
+
print((this_payload.getAtom(0).symbol() + ' at ' + str(this_payload.getAtom(
|
|
631
|
+
cand_list[0]).coords()) + 'target at ' + str(surface_coord_list[0])))
|
|
632
|
+
print((distorted_payload.getAtom(0).symbol() + ' at ' + str(distorted_payload.getAtom(
|
|
633
|
+
cand_list[0]).coords()) + 'target at ' + str(surface_coord_list[0])))
|
|
634
|
+
final_payload.copymol3D(distorted_payload)
|
|
635
|
+
if debug:
|
|
636
|
+
print((final_payload.getAtom(0).symbol() + ' at ' + str(final_payload.getAtom(
|
|
637
|
+
cand_list[0]).coords()) + 'target at ' + str(surface_coord_list[0])))
|
|
638
|
+
else:
|
|
639
|
+
final_payload.copymol3D(this_payload)
|
|
640
|
+
this_step_accepted = True
|
|
641
|
+
factor = min(1.25*factor, 0.8)
|
|
642
|
+
deltaZ = this_deltaZ
|
|
643
|
+
num_bad_steps = 0
|
|
644
|
+
else:
|
|
645
|
+
this_step_accepted = False
|
|
646
|
+
num_bad_steps += 1
|
|
647
|
+
if debug:
|
|
648
|
+
print(('\n\n exit after ' + str(its) + ' iterations'))
|
|
649
|
+
print(('target distance = ' + str(bind_dist) +
|
|
650
|
+
', average deviation = ' + str(sqrt(cost)/len(cand_list))))
|
|
651
|
+
distances_list = []
|
|
652
|
+
for indices in enumerate(cand_list):
|
|
653
|
+
v1 = (surface_coord_list[indices[0]])
|
|
654
|
+
v2 = final_payload.getAtom(int(indices[1])).coords()
|
|
655
|
+
distances_list.append((distance(v1, v2)))
|
|
656
|
+
if debug:
|
|
657
|
+
print((' Target distance was ' + str(bind_dist) +
|
|
658
|
+
', achieved ' + str(distances_list)))
|
|
659
|
+
min_dist = final_payload.mindist(combined_cell)
|
|
660
|
+
# now, rotate to maximize spacing, based on mask length
|
|
661
|
+
rotate_on = False
|
|
662
|
+
if len(cand_list) == 1:
|
|
663
|
+
rotate_on = True
|
|
664
|
+
elif len(cand_list) == 2:
|
|
665
|
+
vec = vecdiff(final_payload.getAtom(cand_list[0]).coords(
|
|
666
|
+
), final_payload.getAtom(cand_list[1]).coords())
|
|
667
|
+
rotate_on = True
|
|
668
|
+
|
|
669
|
+
if rotate_on:
|
|
670
|
+
trial_cell.combine(final_payload)
|
|
671
|
+
trial_cell.writexyz('before_rot.xyz')
|
|
672
|
+
print('starting strain rotation')
|
|
673
|
+
for rotate_angle in range(0, 360):
|
|
674
|
+
this_payload = mol3D()
|
|
675
|
+
this_payload.copymol3D(final_payload)
|
|
676
|
+
payload_coord = center_of_sym(
|
|
677
|
+
[this_payload.getAtom(i).coords() for i in cand_list])
|
|
678
|
+
this_payload = rotate_around_axis(
|
|
679
|
+
this_payload, payload_coord, vec, rotate_angle)
|
|
680
|
+
this_dist = min(periodic_mindist(this_payload, combined_cell, extents), periodic_selfdist(
|
|
681
|
+
this_payload, extents), this_payload.mindist(combined_cell))
|
|
682
|
+
if (this_dist > (min_dist + 1e-3)):
|
|
683
|
+
if debug:
|
|
684
|
+
print(('current dist = ' + str(this_dist) +
|
|
685
|
+
', the max is ' + str(min_dist)))
|
|
686
|
+
print(('accepting rotate at theta = ' + str(rotate_angle)))
|
|
687
|
+
min_dist = this_dist
|
|
688
|
+
final_payload = this_payload
|
|
689
|
+
|
|
690
|
+
if control_angle:
|
|
691
|
+
print('inner control angle loop')
|
|
692
|
+
if not len(cand_list) == 1:
|
|
693
|
+
print('Warning! Using control angle with more than one payload, reference will only use the FIRST payload reference ')
|
|
694
|
+
|
|
695
|
+
print(('begining controlled rotation, targeting angle ' +
|
|
696
|
+
str(control_angle) + ' to line ' + str(align_axis)))
|
|
697
|
+
print(('aligning payload index ' +
|
|
698
|
+
str(cand_list[0]) + ' and indicies ' + str(align_ind-1) + ' with slab axes '))
|
|
699
|
+
this_payload = mol3D()
|
|
700
|
+
this_payload.copymol3D(final_payload)
|
|
701
|
+
|
|
702
|
+
if debug:
|
|
703
|
+
debug_cell = mol3D()
|
|
704
|
+
debug_cell.copymol3D(combined_cell)
|
|
705
|
+
debug_cell.combine(this_payload)
|
|
706
|
+
this_payload.writexyz('aligned-payload-before-angle-control.xyz')
|
|
707
|
+
debug_cell.writexyz('cell-before-angle-control.xyz')
|
|
708
|
+
|
|
709
|
+
this_payload = axes_angle_align(
|
|
710
|
+
this_payload, cand_list[0], align_ind-1, align_axis, control_angle)
|
|
711
|
+
if debug:
|
|
712
|
+
debug_cell = mol3D()
|
|
713
|
+
debug_cell.copymol3D(combined_cell)
|
|
714
|
+
debug_cell.combine(this_payload)
|
|
715
|
+
this_payload.writexyz('aligned-payload-after-angle-control.xyz')
|
|
716
|
+
debug_cell.writexyz('cell-before-after-control.xyz')
|
|
717
|
+
final_payload = this_payload
|
|
718
|
+
|
|
719
|
+
if len(cand_list) > 1:
|
|
720
|
+
# now, distort molecule based on FF to optimize bond length
|
|
721
|
+
print('\n begining distortion ')
|
|
722
|
+
nsteps = 20
|
|
723
|
+
dfactor = float(1)/nsteps
|
|
724
|
+
trans_vec_list = list()
|
|
725
|
+
distances_list = list()
|
|
726
|
+
# fetch all of the remaining
|
|
727
|
+
for indices in enumerate(cand_list):
|
|
728
|
+
v1 = (surface_coord_list[indices[0]])
|
|
729
|
+
v2 = final_payload.getAtom(int(indices[1])).coords()
|
|
730
|
+
trans_vec_list.append(normalize_vector(vecdiff(v2, v1)))
|
|
731
|
+
distances_list.append(distance(v1, v2) - bind_dist)
|
|
732
|
+
ens = []
|
|
733
|
+
distorted_payload = mol3D()
|
|
734
|
+
distorted_payload.copymol3D(final_payload)
|
|
735
|
+
for ii in range(0, nsteps+1):
|
|
736
|
+
for indices in enumerate(cand_list):
|
|
737
|
+
this_translation = [(-1)*dfactor*distances_list[indices[0]]
|
|
738
|
+
for _ in trans_vec_list[indices[0]]]
|
|
739
|
+
distorted_payload.getAtom(
|
|
740
|
+
int(indices[1])).translate(this_translation)
|
|
741
|
+
distorted_payload, enl = cell_ffopt(
|
|
742
|
+
'mmff94', distorted_payload, cand_list)
|
|
743
|
+
ens.append(enl)
|
|
744
|
+
this_cost = multialign_objective_function(
|
|
745
|
+
distorted_payload, surface_coord_list, cand_list, bind_dist)
|
|
746
|
+
this_dist = min(periodic_mindist(distorted_payload, combined_cell,
|
|
747
|
+
extents), periodic_selfdist(distorted_payload, extents))
|
|
748
|
+
del distances_list
|
|
749
|
+
distances_list = list()
|
|
750
|
+
for indices in enumerate(cand_list):
|
|
751
|
+
v1 = (surface_coord_list[indices[0]])
|
|
752
|
+
v2 = distorted_payload.getAtom(int(indices[1])).coords()
|
|
753
|
+
distances_list.append((distance(v1, v2) - bind_dist))
|
|
754
|
+
# print(str((abs(ens[-1] - ens[0]) < 5.0)) + str((this_cost < cost)) + str((this_dist >= (min_dist - 0.1))))
|
|
755
|
+
|
|
756
|
+
if (abs(ens[-1] - ens[0]) < 5.0) and (this_cost < cost) and (this_dist >= (min_dist - 0.1)):
|
|
757
|
+
final_payload = distorted_payload
|
|
758
|
+
cost = this_cost
|
|
759
|
+
min_dist = this_dist
|
|
760
|
+
if debug:
|
|
761
|
+
print('accepting distort')
|
|
762
|
+
|
|
763
|
+
distances_list = []
|
|
764
|
+
for indices in enumerate(cand_list):
|
|
765
|
+
v1 = (surface_coord_list[indices[0]])
|
|
766
|
+
v2 = final_payload.getAtom(int(indices[1])).coords()
|
|
767
|
+
distances_list.append((distance(v1, v2)))
|
|
768
|
+
|
|
769
|
+
print(('Target distance was ' + str(bind_dist) +
|
|
770
|
+
', achieved ' + str(distances_list)))
|
|
771
|
+
|
|
772
|
+
if duplicate:
|
|
773
|
+
second_payload = mol3D()
|
|
774
|
+
second_payload.copymol3D(final_payload)
|
|
775
|
+
xyline = [second_payload.centersym(
|
|
776
|
+
)[0], second_payload.centersym()[1], 0]
|
|
777
|
+
point = [xyline[0], xyline[1], 0*(second_payload.centersym()[2])/2]
|
|
778
|
+
rotate_angle = 180
|
|
779
|
+
second_payload = rotate_around_axis(
|
|
780
|
+
second_payload, point, xyline, rotate_angle)
|
|
781
|
+
second_payload.translate([0, 0, surface_coord[2]])
|
|
782
|
+
final_payload.combine(second_payload)
|
|
783
|
+
min_intercell_d = closest_torus_point(final_payload, extents)
|
|
784
|
+
print(('minimum inter-cell adsorbate self-atom distance is ' + str(min_intercell_d)))
|
|
785
|
+
combined_cell.combine(final_payload)
|
|
786
|
+
return combined_cell
|
|
787
|
+
###################################
|
|
788
|
+
|
|
789
|
+
|
|
790
|
+
def molecule_placement_supervisor(super_cell, super_cell_vector, target_molecule, method, target_atom_type, align_dist, surface_atom_type=False, control_angle=False, align_ind=False, align_axis=False,
|
|
791
|
+
duplicate=False, number_of_placements=1, coverage=False, weighting_method='linear', weight=0.5, masklength=1, surface_atom_ind=False, debug=False):
|
|
792
|
+
# parse input
|
|
793
|
+
if ((number_of_placements != 1) or coverage) and ((method != 'alignpair') or (control_angle)):
|
|
794
|
+
if not (method == 'alignpair'):
|
|
795
|
+
print(('Multiple placement NOT supported for method ' + method))
|
|
796
|
+
if control_angle:
|
|
797
|
+
print('Cannot support multiple placements and controlled align')
|
|
798
|
+
print(' Setting single placement only')
|
|
799
|
+
number_of_placements = 1
|
|
800
|
+
coverage = False
|
|
801
|
+
if ((control_angle) and not (align_axis)) or ((align_axis) and not (control_angle)):
|
|
802
|
+
print('Cannot control angle and not provide axis or vice-versa')
|
|
803
|
+
print(('control angle is ' + str(control_angle)))
|
|
804
|
+
print(('align_axis is ' + str(align_axis)))
|
|
805
|
+
control_angle = False
|
|
806
|
+
align_axis = False
|
|
807
|
+
if control_angle and not align_ind:
|
|
808
|
+
print('align_ind not found, even though control_angle is on. Disabling controlled rotation')
|
|
809
|
+
control_angle = False
|
|
810
|
+
if (method == 'alignpair') and not (surface_atom_type or surface_atom_ind):
|
|
811
|
+
print('Must provide surface binding atom type to use alignpair')
|
|
812
|
+
print(' using centered placemented instead')
|
|
813
|
+
method = 'center'
|
|
814
|
+
print('\n')
|
|
815
|
+
print(('the method is', method))
|
|
816
|
+
max_sites = 1
|
|
817
|
+
if (method == 'alignpair'): # get all vaccancies
|
|
818
|
+
avail_sites_dict = dict()
|
|
819
|
+
occupied_sites_dict = dict()
|
|
820
|
+
if not surface_atom_ind:
|
|
821
|
+
if debug:
|
|
822
|
+
print(('surface_atom_type', surface_atom_type))
|
|
823
|
+
avail_sites_list = find_all_surface_atoms(
|
|
824
|
+
super_cell, tol=0.75, type_of_atom=surface_atom_type)
|
|
825
|
+
avail_sites_dict = dict()
|
|
826
|
+
for indices in avail_sites_list:
|
|
827
|
+
avail_sites_dict[indices] = super_cell.getAtom(
|
|
828
|
+
indices).coords()
|
|
829
|
+
occupied_sites_dict = dict()
|
|
830
|
+
# calculate max number of sites that need to be filled
|
|
831
|
+
max_sites = int(numpy.floor(
|
|
832
|
+
float(len(list(avail_sites_dict.keys())))/masklength))
|
|
833
|
+
if coverage:
|
|
834
|
+
number_of_placements = int(numpy.ceil(max_sites*coverage))
|
|
835
|
+
print(('Coverage requested = ' + str(coverage)))
|
|
836
|
+
if debug:
|
|
837
|
+
print(('masklengh is ' + str(masklength)))
|
|
838
|
+
if surface_atom_ind:
|
|
839
|
+
print(('using surface_atom_ind' + str(surface_atom_ind)))
|
|
840
|
+
for indices in surface_atom_ind:
|
|
841
|
+
avail_sites_dict[indices] = super_cell.getAtom(
|
|
842
|
+
indices).coords()
|
|
843
|
+
avail_sites_list = [i for i in surface_atom_ind]
|
|
844
|
+
if coverage:
|
|
845
|
+
print('cannot use coverage with surface_atom_ind')
|
|
846
|
+
coverage = False
|
|
847
|
+
|
|
848
|
+
######## prepare and allocate
|
|
849
|
+
loaded_cell = mol3D()
|
|
850
|
+
loaded_cell.copymol3D(super_cell)
|
|
851
|
+
debug_cell = mol3D()
|
|
852
|
+
debug_cell.copymol3D(loaded_cell)
|
|
853
|
+
# begin actual work
|
|
854
|
+
print('begining the placement loop')
|
|
855
|
+
for placements in range(0, number_of_placements):
|
|
856
|
+
sites_list = list() # list to hod all of the target sites on the surface
|
|
857
|
+
if (method == 'center'):
|
|
858
|
+
align_coord = centered_align_coord(super_cell_vector)
|
|
859
|
+
sites_list.append(align_coord)
|
|
860
|
+
elif (method == 'staggered'):
|
|
861
|
+
align_coord = staggered2_align_coord(super_cell)
|
|
862
|
+
sites_list.append(align_coord)
|
|
863
|
+
|
|
864
|
+
elif (method == 'alignpair'):
|
|
865
|
+
best_site = choose_best_site(avail_sites_dict, occupied_sites_dict, centered_align_coord(
|
|
866
|
+
super_cell_vector), super_cell, super_cell_vector, weight, weighting_method, debug=debug)
|
|
867
|
+
align_coord = super_cell.getAtom(best_site).coords()
|
|
868
|
+
occupied_sites_dict[best_site] = avail_sites_dict.pop(
|
|
869
|
+
best_site) # this transfers the site to occupied
|
|
870
|
+
sites_list.append(align_coord)
|
|
871
|
+
if masklength != 1: # this is if we need multiple sites
|
|
872
|
+
mask_target = align_coord
|
|
873
|
+
for iterates in range(1, masklength):
|
|
874
|
+
if debug:
|
|
875
|
+
print(('in loop for ' + str(iterates)))
|
|
876
|
+
nn_site = choose_nearest_neighbour(
|
|
877
|
+
mask_target, avail_sites_dict, occupied_sites_dict, super_cell, super_cell_vector, debug=False)
|
|
878
|
+
align_coord = super_cell.getAtom(nn_site).coords()
|
|
879
|
+
sites_list.append(align_coord)
|
|
880
|
+
occupied_sites_dict[nn_site] = avail_sites_dict.pop(
|
|
881
|
+
nn_site) # this transfers the site to occupied
|
|
882
|
+
mask_target = center_of_sym(sites_list)
|
|
883
|
+
align_coord = center_of_sym(sites_list)
|
|
884
|
+
if debug:
|
|
885
|
+
print(('oc sites chosen are = ' +
|
|
886
|
+
str(list(occupied_sites_dict.keys()))))
|
|
887
|
+
|
|
888
|
+
else:
|
|
889
|
+
emsg = 'unkown method of molecule placement ' + method
|
|
890
|
+
print(emsg)
|
|
891
|
+
return emsg
|
|
892
|
+
print(('Target for align is ' + str(align_coord)))
|
|
893
|
+
# actual placement
|
|
894
|
+
payload = mol3D()
|
|
895
|
+
payload.copymol3D(target_molecule)
|
|
896
|
+
payload_rad = payload.molsize()
|
|
897
|
+
|
|
898
|
+
trans_vec = vecdiff(align_coord, payload.centersym())
|
|
899
|
+
payload.translate(trans_vec)
|
|
900
|
+
extents = find_extents_cv(super_cell_vector)
|
|
901
|
+
# place far above
|
|
902
|
+
payload.translate([0, 0, extents[2]+1.15*(payload_rad + align_dist)])
|
|
903
|
+
|
|
904
|
+
###############################
|
|
905
|
+
temp_pay = mol3D()
|
|
906
|
+
temp_pay.copymol3D(payload)
|
|
907
|
+
debug_cell.combine(temp_pay)
|
|
908
|
+
|
|
909
|
+
# find matching atom in payload
|
|
910
|
+
# need to determine if the target is an element or a mask
|
|
911
|
+
globs = globalvars()
|
|
912
|
+
elements = globs.elementsbynum()
|
|
913
|
+
if target_atom_type in elements:
|
|
914
|
+
# find all matches in target
|
|
915
|
+
payload_targets = payload.findAtomsbySymbol(target_atom_type)
|
|
916
|
+
if (len(payload_targets) > 1): # more than 1 option, pick closest to center of plane
|
|
917
|
+
maxd = 1000
|
|
918
|
+
for indices in payload_targets:
|
|
919
|
+
dist = distance(payload.getAtom(indices).coords(), [
|
|
920
|
+
extents[0]/2, extents[1]/2, extents[2]])
|
|
921
|
+
if (dist < maxd):
|
|
922
|
+
cand_ind = indices
|
|
923
|
+
maxd = dist
|
|
924
|
+
elif (len(payload_targets) == 1):
|
|
925
|
+
cand_ind = payload_targets[0]
|
|
926
|
+
else:
|
|
927
|
+
emsg = ('Error: no align of type' + target_atom_type +
|
|
928
|
+
' is possible. Not found in target. Using atom 0 align')
|
|
929
|
+
cand_ind = 0
|
|
930
|
+
print(emsg)
|
|
931
|
+
|
|
932
|
+
if debug:
|
|
933
|
+
print(('cand _ind = ' + str(cand_ind)))
|
|
934
|
+
cand_list = [cand_ind]
|
|
935
|
+
# [(int(i)-1) for i in cand_ind]
|
|
936
|
+
else:
|
|
937
|
+
cand_ind = target_atom_type
|
|
938
|
+
print('loading from TAT')
|
|
939
|
+
cand_list = [(int(i)-1) for i in cand_ind]
|
|
940
|
+
if debug:
|
|
941
|
+
print(('target molecule mask on ' + str(target_atom_type)))
|
|
942
|
+
print(('candidate list is ' + str(cand_list)))
|
|
943
|
+
# rotate for optimal approach
|
|
944
|
+
payload = align_payload_to_multi_site(
|
|
945
|
+
payload, sites_list, cand_list, align_dist, debug) # align
|
|
946
|
+
if debug:
|
|
947
|
+
payload.writexyz('aligned-payload-before-angle-control.xyz')
|
|
948
|
+
|
|
949
|
+
if debug:
|
|
950
|
+
print(('payload cysm ' + str(payload.centersym())))
|
|
951
|
+
|
|
952
|
+
#######################################
|
|
953
|
+
temp_pay2 = mol3D()
|
|
954
|
+
temp_pay2.copymol3D(payload)
|
|
955
|
+
temp_pay2.translate([0, 0, -5])
|
|
956
|
+
debug_cell.combine(temp_pay2)
|
|
957
|
+
if debug:
|
|
958
|
+
debug_cell.writexyz('db2.xyz')
|
|
959
|
+
# lower payload to distance, rotate to avoid conflicr
|
|
960
|
+
loaded_cell = combine_multi_aligned_payload_with_cell(
|
|
961
|
+
loaded_cell, super_cell_vector, payload, cand_list, sites_list,
|
|
962
|
+
align_dist, duplicate, control_angle, align_axis, align_ind, debug)
|
|
963
|
+
|
|
964
|
+
########################
|
|
965
|
+
temp_pay3 = mol3D()
|
|
966
|
+
temp_pay3.copymol3D(payload)
|
|
967
|
+
debug_cell.combine(temp_pay3)
|
|
968
|
+
if debug:
|
|
969
|
+
debug_cell.writexyz('db3.xyz')
|
|
970
|
+
temp_pay3.writexyz('db3-only.xyz')
|
|
971
|
+
print(('number of atoms = ' + str(loaded_cell.natoms)))
|
|
972
|
+
# print("\n")
|
|
973
|
+
# run tests
|
|
974
|
+
overlap_flag = loaded_cell.sanitycheck(0)
|
|
975
|
+
if (number_of_placements > 1):
|
|
976
|
+
print(('preparing ' + str(number_of_placements) + ' placements '))
|
|
977
|
+
effectvie_coverage = float(number_of_placements)/float(max_sites)
|
|
978
|
+
print(('giving effectvie coverage of ' + str(effectvie_coverage) + '\n'))
|
|
979
|
+
print(('Is there overalp? ' + str(overlap_flag)))
|
|
980
|
+
|
|
981
|
+
return loaded_cell
|
|
982
|
+
|
|
983
|
+
###################################
|
|
984
|
+
|
|
985
|
+
|
|
986
|
+
def centered_align_coord(super_cell_vector):
|
|
987
|
+
extents = find_extents_cv(super_cell_vector)
|
|
988
|
+
centroid = [extents[0]/2, extents[1]/2, extents[2]]
|
|
989
|
+
print(('Centroid is at ' + str(centroid)))
|
|
990
|
+
align_coord = centroid
|
|
991
|
+
return align_coord
|
|
992
|
+
###################################
|
|
993
|
+
|
|
994
|
+
|
|
995
|
+
def staggered2_align_coord(super_cell):
|
|
996
|
+
max_dist = 1000
|
|
997
|
+
avail_sites_list = find_all_surface_atoms(
|
|
998
|
+
super_cell, tol=1e-2, type_of_atom=False)
|
|
999
|
+
close_list = list()
|
|
1000
|
+
extents = find_extents(super_cell)
|
|
1001
|
+
centroid = [extents[0]/2, extents[1]/2, extents[2]]
|
|
1002
|
+
for indices in avail_sites_list:
|
|
1003
|
+
this_dist = distance(centroid, super_cell.getAtom(indices).coords())
|
|
1004
|
+
if (this_dist < (max_dist - 1e-3)):
|
|
1005
|
+
max_dist = this_dist
|
|
1006
|
+
if (len(close_list) > 1):
|
|
1007
|
+
print('subseq')
|
|
1008
|
+
close_list[1] = close_list[0] # save old index
|
|
1009
|
+
close_list[0] = super_cell.getAtom(indices)
|
|
1010
|
+
elif (len(close_list) == 1):
|
|
1011
|
+
print('second atom found')
|
|
1012
|
+
close_list.append(super_cell.getAtom(indices))
|
|
1013
|
+
temp = close_list[0]
|
|
1014
|
+
close_list[0] = close_list[1]
|
|
1015
|
+
close_list[1] = temp
|
|
1016
|
+
elif (len(close_list) == 0):
|
|
1017
|
+
print('first atom found')
|
|
1018
|
+
close_list.append(super_cell.getAtom(indices))
|
|
1019
|
+
align_coord = [
|
|
1020
|
+
sum(x)/2 for x in zip(close_list[0].coords(), close_list[1].coords())]
|
|
1021
|
+
return align_coord # end of stagger
|
|
1022
|
+
###################################
|
|
1023
|
+
|
|
1024
|
+
|
|
1025
|
+
def axes_angle_align(payload, cand_ind, align_ind, align_target, angle):
|
|
1026
|
+
"""This function rotates a given payload molecule such that the X-Y
|
|
1027
|
+
projection of the cord joining the two atoms in cand_ind and align_ind
|
|
1028
|
+
is aligned with the vector given in align_target.
|
|
1029
|
+
|
|
1030
|
+
Parameters
|
|
1031
|
+
----------
|
|
1032
|
+
payload : mol3D
|
|
1033
|
+
mol3D class that contains that target molecule
|
|
1034
|
+
cand_ind : int
|
|
1035
|
+
index of atom in payload that is used as reference
|
|
1036
|
+
align_ind : int
|
|
1037
|
+
index of atom in payload that define the cord to align
|
|
1038
|
+
align_target : list of 3 float
|
|
1039
|
+
vector on the cell surface to align. Normally z=0
|
|
1040
|
+
angle : float
|
|
1041
|
+
rotation angle
|
|
1042
|
+
Returns
|
|
1043
|
+
-------
|
|
1044
|
+
new_payload: mol3D
|
|
1045
|
+
mol3D class, rotation of payload.
|
|
1046
|
+
"""
|
|
1047
|
+
new_payload = mol3D()
|
|
1048
|
+
new_payload.copymol3D(payload)
|
|
1049
|
+
align_chord = vecdiff(new_payload.getAtom(
|
|
1050
|
+
cand_ind).coords(), new_payload.getAtom(align_ind).coords())
|
|
1051
|
+
print(('align coord:' + str(align_chord)))
|
|
1052
|
+
align_chord[2] = 0 # project into X-Y
|
|
1053
|
+
print(('align coord, proj ' + str(align_chord)))
|
|
1054
|
+
print(('align target ' + str(align_target)))
|
|
1055
|
+
normal_vect = numpy.cross(align_chord, align_target)
|
|
1056
|
+
print(('vec angle id ' + str(vecangle(align_chord, align_target))))
|
|
1057
|
+
rotate_angle = vecangle(align_chord, align_target) + angle
|
|
1058
|
+
print(('my angle is ' + str(rotate_angle) + ' nv is ' + str(normal_vect)))
|
|
1059
|
+
# Rotates molecule about axis defined by direction vector and point on axis
|
|
1060
|
+
#
|
|
1061
|
+
# Loops over PointRotateAxis().
|
|
1062
|
+
# @param mol mol3D of molecule to be rotated
|
|
1063
|
+
# @param Rp Reference point along axis
|
|
1064
|
+
# @param u Direction vector of axis
|
|
1065
|
+
# @param theta Angle of rotation in DEGREES
|
|
1066
|
+
# @return mol3D of rotated molecule
|
|
1067
|
+
|
|
1068
|
+
new_payload = rotate_around_axis(new_payload, new_payload.getAtom(
|
|
1069
|
+
cand_ind).coords(), normal_vect, rotate_angle)
|
|
1070
|
+
return new_payload
|
|
1071
|
+
##########################################
|
|
1072
|
+
|
|
1073
|
+
|
|
1074
|
+
def slab_module_supervisor(args, rootdir):
|
|
1075
|
+
print('******** cell builder on ********')
|
|
1076
|
+
###################################
|
|
1077
|
+
###################################
|
|
1078
|
+
############# INPUT ###############
|
|
1079
|
+
######### Default values #########
|
|
1080
|
+
# Invocation
|
|
1081
|
+
slab_gen = False
|
|
1082
|
+
place_on_slab = False
|
|
1083
|
+
# Required Input: slab generation
|
|
1084
|
+
unit_cell = False
|
|
1085
|
+
cell_vector = False
|
|
1086
|
+
# OR
|
|
1087
|
+
cif_path = False
|
|
1088
|
+
duplication_vector = False
|
|
1089
|
+
# OR
|
|
1090
|
+
slab_size = False
|
|
1091
|
+
# optional_input
|
|
1092
|
+
miller_index = False
|
|
1093
|
+
# Required Input: placement
|
|
1094
|
+
# target_molecule = False
|
|
1095
|
+
align_distance_method = False
|
|
1096
|
+
# options are "physisorption","chemisorption","custom"
|
|
1097
|
+
align_dist = False # use in conjunction with "custom" above
|
|
1098
|
+
# Optionial Input: placement
|
|
1099
|
+
align_method = 'center'
|
|
1100
|
+
# other options: 'center','staggered', 'alignpair'
|
|
1101
|
+
# for alignpair only:
|
|
1102
|
+
surface_atom_type = False
|
|
1103
|
+
object_align = False
|
|
1104
|
+
num_surface_atoms = 1
|
|
1105
|
+
num_placements = 1
|
|
1106
|
+
coverage = False
|
|
1107
|
+
# multi_placement_centering = 0.95
|
|
1108
|
+
# for surface rotation:
|
|
1109
|
+
control_angle = False
|
|
1110
|
+
angle_control_partner = False
|
|
1111
|
+
angle_surface_axis = False
|
|
1112
|
+
|
|
1113
|
+
# duplication
|
|
1114
|
+
duplicate = False
|
|
1115
|
+
|
|
1116
|
+
# debug
|
|
1117
|
+
debug = False
|
|
1118
|
+
|
|
1119
|
+
# passivate
|
|
1120
|
+
passivate = False
|
|
1121
|
+
|
|
1122
|
+
# freeze layers
|
|
1123
|
+
freeze = False
|
|
1124
|
+
|
|
1125
|
+
# expose a certain atom type
|
|
1126
|
+
expose_type = False
|
|
1127
|
+
|
|
1128
|
+
# shave extra layers
|
|
1129
|
+
shave_extra_layers = False
|
|
1130
|
+
|
|
1131
|
+
# overwrite surface_atom_ind
|
|
1132
|
+
surface_atom_ind = False
|
|
1133
|
+
|
|
1134
|
+
###### Now attempt input ####
|
|
1135
|
+
import_success = True
|
|
1136
|
+
emsg = list()
|
|
1137
|
+
# multi_placement_centering_overide = False
|
|
1138
|
+
miller_flag = False
|
|
1139
|
+
if (args.slab_gen): # 0
|
|
1140
|
+
slab_gen = True
|
|
1141
|
+
if (args.unit_cell): # 1
|
|
1142
|
+
print('importing unit cell')
|
|
1143
|
+
unit_cell = mol3D()
|
|
1144
|
+
# test if the unit cell is a .xyz file
|
|
1145
|
+
try:
|
|
1146
|
+
ext = os.path.splitext(args.unit_cell)[1]
|
|
1147
|
+
if (ext == '.xyz'):
|
|
1148
|
+
unit_cell.readfromxyz(args.unit_cell)
|
|
1149
|
+
elif (ext == '.mol'):
|
|
1150
|
+
unit_cell.OBmol = unit_cell.getOBmol(args.unit_cell)
|
|
1151
|
+
unit_cell.convert2mol3D()
|
|
1152
|
+
except FileNotFoundError:
|
|
1153
|
+
emsg.append('Unable to import unit cell at ' +
|
|
1154
|
+
str(args.unit_cell))
|
|
1155
|
+
import_success = False
|
|
1156
|
+
if (args.cell_vector): # 2
|
|
1157
|
+
cell_vector = args.cell_vector
|
|
1158
|
+
if (args.cif_path): # 3
|
|
1159
|
+
cif_path = args.cif_path
|
|
1160
|
+
if (args.duplication_vector): # 4
|
|
1161
|
+
duplication_vector = args.duplication_vector
|
|
1162
|
+
if (args.slab_size): # 5
|
|
1163
|
+
slab_size = args.slab_size
|
|
1164
|
+
if (args.miller_index): # 6
|
|
1165
|
+
miller_index = args.miller_index
|
|
1166
|
+
miller_flag = True
|
|
1167
|
+
if (args.freeze): # 7
|
|
1168
|
+
freeze = args.freeze
|
|
1169
|
+
if (args.debug): # 8
|
|
1170
|
+
debug = True
|
|
1171
|
+
if (args.expose_type): # 9
|
|
1172
|
+
expose_type = args.expose_type
|
|
1173
|
+
if (args.shave_extra_layers): # 10
|
|
1174
|
+
shave_extra_layers = args.shave_extra_layers
|
|
1175
|
+
# parse placement options
|
|
1176
|
+
if (args.place_on_slab): # 0
|
|
1177
|
+
place_on_slab = True
|
|
1178
|
+
if (args.target_molecule): # 1
|
|
1179
|
+
target_molecule = mol3D()
|
|
1180
|
+
# test if the unit cell is a .xyz file
|
|
1181
|
+
ext = os.path.splitext(args.target_molecule)[1]
|
|
1182
|
+
try:
|
|
1183
|
+
ext = os.path.splitext(args.target_molecule)[1]
|
|
1184
|
+
if (ext == '.xyz'):
|
|
1185
|
+
target_molecule.readfromxyz(args.target_molecule)
|
|
1186
|
+
elif (ext == '.mol'):
|
|
1187
|
+
target_molecule.OBmol = unit_cell.getOBmol(
|
|
1188
|
+
args.target_molecule)
|
|
1189
|
+
target_molecule.convert2mol3D()
|
|
1190
|
+
except FileNotFoundError:
|
|
1191
|
+
emsg.append('Unable to import target at ' +
|
|
1192
|
+
str(args.target_molecule))
|
|
1193
|
+
import_success = False
|
|
1194
|
+
if (args.align_distance_method): # 2
|
|
1195
|
+
align_distance_method = args.align_distance_method
|
|
1196
|
+
if (args.align_dist): # 3
|
|
1197
|
+
align_dist = args.align_dist
|
|
1198
|
+
if (args.object_align): # 4
|
|
1199
|
+
object_align = args.object_align
|
|
1200
|
+
if (args.align_method): # 5
|
|
1201
|
+
align_method = args.align_method
|
|
1202
|
+
if (args.surface_atom_type): # 6
|
|
1203
|
+
surface_atom_type = args.surface_atom_type
|
|
1204
|
+
if (args.surface_atom_ind): # 7
|
|
1205
|
+
surface_atom_ind = args.surface_atom_ind
|
|
1206
|
+
|
|
1207
|
+
if (args.num_surface_atoms): # 8
|
|
1208
|
+
num_surface_atoms = args.num_surface_atoms
|
|
1209
|
+
if (args.num_placements): # 9
|
|
1210
|
+
num_placements = args.num_placements
|
|
1211
|
+
if (args.coverage): # 10
|
|
1212
|
+
coverage = args.coverage
|
|
1213
|
+
# if (args.multi_placement_centering): # 12
|
|
1214
|
+
# multi_placement_centering = args.multi_placement_centering
|
|
1215
|
+
# multi_placement_centering_overide = True
|
|
1216
|
+
if (args.control_angle): # 13
|
|
1217
|
+
control_angle = args.control_angle
|
|
1218
|
+
if (args.angle_control_partner): # 14
|
|
1219
|
+
angle_control_partner = args.angle_control_partner
|
|
1220
|
+
if (args.angle_surface_axis): # 14
|
|
1221
|
+
angle_surface_axis = args.angle_surface_axis
|
|
1222
|
+
print(('ang_surf_axis ' + str(angle_surface_axis)))
|
|
1223
|
+
if (args.duplicate): # 15
|
|
1224
|
+
duplicate = True
|
|
1225
|
+
# check inputs
|
|
1226
|
+
if slab_gen and not (slab_size or duplication_vector):
|
|
1227
|
+
emsg = "Size of slab required (-slab_size or -duplication_vector)"
|
|
1228
|
+
print(emsg)
|
|
1229
|
+
return emsg
|
|
1230
|
+
if slab_gen and not ((unit_cell and cell_vector) or cif_path):
|
|
1231
|
+
emsg = "Unit cell info required! (-cif_path or -unit_cell and cell_vector)"
|
|
1232
|
+
print(emsg)
|
|
1233
|
+
return emsg
|
|
1234
|
+
|
|
1235
|
+
if not import_success:
|
|
1236
|
+
print(emsg)
|
|
1237
|
+
return emsg
|
|
1238
|
+
# if num_placements > 1 and not multi_placement_centering_overide:
|
|
1239
|
+
# multi_placement_centering = 1 # reccomended for multiple placments
|
|
1240
|
+
if not slab_gen and not place_on_slab:
|
|
1241
|
+
emsg.append(
|
|
1242
|
+
'Slab builder module not enabled, placement mode not enabled - no action taken ')
|
|
1243
|
+
print(emsg)
|
|
1244
|
+
return emsg
|
|
1245
|
+
if place_on_slab and not target_molecule:
|
|
1246
|
+
emsg.append('Placement requested, but no object given. Skipping')
|
|
1247
|
+
print(emsg)
|
|
1248
|
+
if place_on_slab and not align_dist and (align_distance_method != "chemisorption"):
|
|
1249
|
+
emsg.append('No placement distance given, defaulting to covalent radii')
|
|
1250
|
+
align_distance_method = "chemisorption"
|
|
1251
|
+
print(emsg)
|
|
1252
|
+
if place_on_slab and align_dist and not align_distance_method:
|
|
1253
|
+
print(("using custom align distance of " + str(align_dist)))
|
|
1254
|
+
align_distance_method = "custom"
|
|
1255
|
+
if num_placements > 1 or coverage:
|
|
1256
|
+
weight = 1
|
|
1257
|
+
else:
|
|
1258
|
+
weight = 0.90
|
|
1259
|
+
|
|
1260
|
+
# if args.target_atom_type:
|
|
1261
|
+
# if not args.target_atom_type in elements:
|
|
1262
|
+
# masklength = len(args.target_atom_type)
|
|
1263
|
+
# print("Target masking with length " + str(masklength))
|
|
1264
|
+
# else:
|
|
1265
|
+
# masklength = 1
|
|
1266
|
+
# else:
|
|
1267
|
+
# masklength = 1
|
|
1268
|
+
|
|
1269
|
+
# resolve align distance
|
|
1270
|
+
if align_distance_method == "chemisorption":
|
|
1271
|
+
globs = globalvars()
|
|
1272
|
+
if surface_atom_type in globs.elementsbynum():
|
|
1273
|
+
surf_rad = globs.amass()[surface_atom_type][2]
|
|
1274
|
+
else:
|
|
1275
|
+
surf_rad = 1.5
|
|
1276
|
+
print('unknown surface atom type, using 1.5A as distance')
|
|
1277
|
+
if object_align in globs.elementsbynum():
|
|
1278
|
+
obj_rad = globs.amass()[object_align][2]
|
|
1279
|
+
else:
|
|
1280
|
+
obj_rad = 1.0
|
|
1281
|
+
print('unknown object atom type, using 1.0A as distance')
|
|
1282
|
+
align_dist = obj_rad + surf_rad
|
|
1283
|
+
print(('Chemisorption align distance set to ' + str(align_dist)))
|
|
1284
|
+
if miller_flag:
|
|
1285
|
+
non_zero_indices = list()
|
|
1286
|
+
zero_indices = list()
|
|
1287
|
+
for i in [0, 1, 2]:
|
|
1288
|
+
if not (miller_index[i] == 0):
|
|
1289
|
+
non_zero_indices.append(i)
|
|
1290
|
+
else:
|
|
1291
|
+
zero_indices.append(i)
|
|
1292
|
+
|
|
1293
|
+
# Main calls
|
|
1294
|
+
if slab_gen:
|
|
1295
|
+
print('Generating a new slab...')
|
|
1296
|
+
print(rootdir)
|
|
1297
|
+
if not os.path.exists(rootdir + 'slab'):
|
|
1298
|
+
os.makedirs(rootdir + 'slab')
|
|
1299
|
+
|
|
1300
|
+
if cif_path:
|
|
1301
|
+
print('testing cif')
|
|
1302
|
+
# try:
|
|
1303
|
+
unit_cell, cell_vector = import_from_cif(cif_path)
|
|
1304
|
+
if debug:
|
|
1305
|
+
print('cell vector from cif is')
|
|
1306
|
+
print(cell_vector)
|
|
1307
|
+
# except:
|
|
1308
|
+
# emsg.append('unable to import cif at ' + str(cif_path))
|
|
1309
|
+
# print(emsg)
|
|
1310
|
+
# return emsg
|
|
1311
|
+
|
|
1312
|
+
# testing
|
|
1313
|
+
unit_cell.writexyz(rootdir + 'slab/before_COB.xyz')
|
|
1314
|
+
print('loaded')
|
|
1315
|
+
|
|
1316
|
+
if miller_flag:
|
|
1317
|
+
print(('miller index on ' + str(miller_index) + ' ' + str(miller_flag)))
|
|
1318
|
+
point_coefficients = [get_basis_coefficients(
|
|
1319
|
+
at.coords(), cell_vector) for at in unit_cell.getAtoms()]
|
|
1320
|
+
point_coefficients = threshold_basis(point_coefficients, 1E-6)
|
|
1321
|
+
print('coords in old UC')
|
|
1322
|
+
for j in point_coefficients:
|
|
1323
|
+
print(j)
|
|
1324
|
+
if debug:
|
|
1325
|
+
unit_cell.writexyz(rootdir + 'slab/step_0.xyz')
|
|
1326
|
+
print('\n\n')
|
|
1327
|
+
print('cell vector was ')
|
|
1328
|
+
print((cell_vector[0]))
|
|
1329
|
+
print((cell_vector[1]))
|
|
1330
|
+
print((cell_vector[2]))
|
|
1331
|
+
print('\n**********************\n')
|
|
1332
|
+
v1, v2, v3, angle, u = cut_cell_to_index(
|
|
1333
|
+
unit_cell, cell_vector, miller_index)
|
|
1334
|
+
|
|
1335
|
+
old_cv = cell_vector
|
|
1336
|
+
# change basis of cell to reflect cut, will rotate after gen
|
|
1337
|
+
cell_vector = [v1, v2, v3]
|
|
1338
|
+
new_basis = [v1, v2, v3]
|
|
1339
|
+
print('old basis:')
|
|
1340
|
+
print(old_cv)
|
|
1341
|
+
print('new basis:')
|
|
1342
|
+
print(new_basis)
|
|
1343
|
+
print('\n')
|
|
1344
|
+
point_coefficients = [get_basis_coefficients(
|
|
1345
|
+
at.coords(), new_basis) for at in unit_cell.getAtoms()]
|
|
1346
|
+
point_coefficients = threshold_basis(point_coefficients, 1E-6)
|
|
1347
|
+
print('coords in transformed UC:')
|
|
1348
|
+
print(point_coefficients)
|
|
1349
|
+
# for i in range(0,len(point_coefficients)):
|
|
1350
|
+
# for j in [0,1,2]:
|
|
1351
|
+
# if point_coefficients[i][j]<0:
|
|
1352
|
+
# point_coefficients[i][j] += 1
|
|
1353
|
+
new_coords = [evaluate_basis_coefficients(
|
|
1354
|
+
points, new_basis) for points in point_coefficients]
|
|
1355
|
+
for i, coords in enumerate(new_coords):
|
|
1356
|
+
unit_cell.getAtom(i).setcoords(coords)
|
|
1357
|
+
|
|
1358
|
+
print('coords in final UC:')
|
|
1359
|
+
print(point_coefficients)
|
|
1360
|
+
|
|
1361
|
+
# find out how many units to use
|
|
1362
|
+
max_dims = [numpy.linalg.norm(i) for i in cell_vector]
|
|
1363
|
+
print(('vector norms of actual cell vector are' + str(max_dims)))
|
|
1364
|
+
if slab_size:
|
|
1365
|
+
duplication_vector = [
|
|
1366
|
+
int(numpy.ceil(slab_size[i]/max_dims[i])) for i in [0, 1, 2]]
|
|
1367
|
+
print(('duplication vector set to ' + str(duplication_vector)))
|
|
1368
|
+
|
|
1369
|
+
# keep track of the enlarged cell vector for the slab:
|
|
1370
|
+
ext_duplication_vector = cell_vector
|
|
1371
|
+
ext_duplication_vector = [[i*duplication_vector[0] for i in ext_duplication_vector[0]],
|
|
1372
|
+
[i*duplication_vector[1]
|
|
1373
|
+
for i in ext_duplication_vector[1]],
|
|
1374
|
+
[i*duplication_vector[2] for i in ext_duplication_vector[2]]]
|
|
1375
|
+
|
|
1376
|
+
if miller_index:
|
|
1377
|
+
duplication_vector[2] += 2 # add some extra height to trim off
|
|
1378
|
+
# this is a hack to prevent bumpy bottoms
|
|
1379
|
+
# when duplicating cell vectors were
|
|
1380
|
+
# elements in the top an bottom layes
|
|
1381
|
+
# are bonded/close
|
|
1382
|
+
|
|
1383
|
+
# perfrom duplication
|
|
1384
|
+
####################################################################
|
|
1385
|
+
super_cell = unit_to_super(unit_cell, cell_vector, duplication_vector)
|
|
1386
|
+
####################################################################
|
|
1387
|
+
|
|
1388
|
+
if debug:
|
|
1389
|
+
super_cell.writexyz(rootdir + 'slab/after_enlargement.xyz')
|
|
1390
|
+
|
|
1391
|
+
if debug:
|
|
1392
|
+
print('ext_dup vector is: ')
|
|
1393
|
+
print((ext_duplication_vector[0]))
|
|
1394
|
+
print((ext_duplication_vector[1]))
|
|
1395
|
+
print((ext_duplication_vector[2]))
|
|
1396
|
+
|
|
1397
|
+
# lower the cell into the xy plane
|
|
1398
|
+
#############################################################
|
|
1399
|
+
#############################################################
|
|
1400
|
+
if miller_index:
|
|
1401
|
+
print(('rotating angle ' + str(angle) + ' around ' + str(u)))
|
|
1402
|
+
super_cell = rotate_around_axis(super_cell, [0, 0, 0], u, angle)
|
|
1403
|
+
# decoy = rotate_around_axis(decoy,[0,0,0],u,angle)##
|
|
1404
|
+
cell_vector = [PointRotateAxis(u, [0, 0, 0], list(
|
|
1405
|
+
i), numpy.pi*angle/(180)) for i in cell_vector]
|
|
1406
|
+
ext_duplication_vector = [PointRotateAxis(u, [0, 0, 0], list(
|
|
1407
|
+
i), numpy.pi*angle/(180)) for i in ext_duplication_vector]
|
|
1408
|
+
# threshold:
|
|
1409
|
+
cell_vector = threshold_basis(cell_vector, 1E-6)
|
|
1410
|
+
ext_duplication_vector = threshold_basis(
|
|
1411
|
+
ext_duplication_vector, 1E-6)
|
|
1412
|
+
#############################################################
|
|
1413
|
+
|
|
1414
|
+
if debug:
|
|
1415
|
+
print('cell vector is: ')
|
|
1416
|
+
print((cell_vector[0]))
|
|
1417
|
+
print((cell_vector[1]))
|
|
1418
|
+
print((cell_vector[2]))
|
|
1419
|
+
print('ext_dup vector is: ')
|
|
1420
|
+
print((ext_duplication_vector[0]))
|
|
1421
|
+
print((ext_duplication_vector[1]))
|
|
1422
|
+
print((ext_duplication_vector[2]))
|
|
1423
|
+
super_cell.writexyz(rootdir + 'slab/after_rotate.xyz')
|
|
1424
|
+
|
|
1425
|
+
if miller_index: # get rid of the extra padding we added:
|
|
1426
|
+
super_cell = shave_under_layer(super_cell)
|
|
1427
|
+
super_cell = shave_under_layer(super_cell)
|
|
1428
|
+
super_cell = shave_under_layer(super_cell)
|
|
1429
|
+
super_cell = shave_surface_layer(super_cell)
|
|
1430
|
+
super_cell = shave_surface_layer(super_cell)
|
|
1431
|
+
super_cell = zero_z(super_cell)
|
|
1432
|
+
if debug:
|
|
1433
|
+
super_cell.writexyz(rootdir + 'slab/after_millercut.xyz')
|
|
1434
|
+
|
|
1435
|
+
# check angle between v1 and x for aligining nicely
|
|
1436
|
+
angle = -1*vecangle(cell_vector[0], [1, 0, 0])
|
|
1437
|
+
if debug:
|
|
1438
|
+
print(('x-axis angle is ' + str(angle)))
|
|
1439
|
+
if abs(angle) > 5 and False:
|
|
1440
|
+
print(('angle is ' + str(angle)))
|
|
1441
|
+
u = [0, 0, 1]
|
|
1442
|
+
print('aligning with x-axis')
|
|
1443
|
+
print(('rotating angle ' + str(angle) + ' around ' + str(u)))
|
|
1444
|
+
super_cell = rotate_around_axis(super_cell, [0, 0, 0], u, angle)
|
|
1445
|
+
super_cell.writexyz(rootdir + 'slab/after_x_align.xyz')
|
|
1446
|
+
cell_vector = [PointRotateAxis(u, [0, 0, 0], list(
|
|
1447
|
+
i), numpy.pi*angle/(180)) for i in cell_vector]
|
|
1448
|
+
ext_duplication_vector = [PointRotateAxis(u, [0, 0, 0], list(
|
|
1449
|
+
i), numpy.pi*angle/(180)) for i in ext_duplication_vector]
|
|
1450
|
+
# threshold:
|
|
1451
|
+
cell_vector = threshold_basis(cell_vector, 1E-6)
|
|
1452
|
+
ext_duplication_vector = threshold_basis(
|
|
1453
|
+
ext_duplication_vector, 1E-6)
|
|
1454
|
+
|
|
1455
|
+
stop_flag = False
|
|
1456
|
+
if slab_size:
|
|
1457
|
+
counter = 0
|
|
1458
|
+
while not stop_flag:
|
|
1459
|
+
counter += 1
|
|
1460
|
+
zmax = 0
|
|
1461
|
+
for atoms in super_cell.getAtoms():
|
|
1462
|
+
coords = atoms.coords()
|
|
1463
|
+
if (coords[2] > zmax):
|
|
1464
|
+
zmax = coords[2]
|
|
1465
|
+
if (zmax <= 1.1*slab_size[2]):
|
|
1466
|
+
stop_flag = True
|
|
1467
|
+
else:
|
|
1468
|
+
if debug:
|
|
1469
|
+
print('cutting due to zmax')
|
|
1470
|
+
super_cell = shave_surface_layer(super_cell)
|
|
1471
|
+
if counter > 20:
|
|
1472
|
+
print('stopping after 10 cuts, zmax not obtained')
|
|
1473
|
+
stop_flag = True
|
|
1474
|
+
if debug:
|
|
1475
|
+
super_cell.writexyz(rootdir + 'slab/after_size_control.xyz')
|
|
1476
|
+
# measure and recored slab vectors
|
|
1477
|
+
super_cell_vector = copy.copy(ext_duplication_vector)
|
|
1478
|
+
|
|
1479
|
+
# check if passivation needed
|
|
1480
|
+
if passivate:
|
|
1481
|
+
pass # not implemented
|
|
1482
|
+
# check if atoms should be frozen
|
|
1483
|
+
if freeze:
|
|
1484
|
+
if isinstance(freeze, int):
|
|
1485
|
+
print('freezing')
|
|
1486
|
+
super_cell = freeze_bottom_n_layers(super_cell, freeze)
|
|
1487
|
+
else:
|
|
1488
|
+
super_cell = freeze_bottom_n_layers(super_cell, 1)
|
|
1489
|
+
|
|
1490
|
+
# check if a different surface atom should be exposed:
|
|
1491
|
+
if expose_type:
|
|
1492
|
+
super_cell = check_top_layer_correct(super_cell, expose_type)
|
|
1493
|
+
if shave_extra_layers:
|
|
1494
|
+
for i in range(0, int(shave_extra_layers)):
|
|
1495
|
+
print(('shaving ' + str(shave_extra_layers) + ' layers'))
|
|
1496
|
+
super_cell = shave_surface_layer(super_cell, TOL=1e-2)
|
|
1497
|
+
|
|
1498
|
+
# move in all negative positions
|
|
1499
|
+
# if all(super_cell_vector[0]) <= 0: ## all signs are the same:
|
|
1500
|
+
# super_cell_vector[0] = [-1*i for i in super_cell_vector[0]]
|
|
1501
|
+
point_coefficients = [get_basis_coefficients(
|
|
1502
|
+
at.coords(), super_cell_vector) for at in super_cell.getAtoms()]
|
|
1503
|
+
# print('coords in final slab:' )
|
|
1504
|
+
# print(point_coefficients)
|
|
1505
|
+
point_coefficients = threshold_basis(point_coefficients, 1E-6)
|
|
1506
|
+
# for i in range(0,len(point_coefficients)):
|
|
1507
|
+
# for j in [0,1,2]:
|
|
1508
|
+
# if point_coefficients[i][j]<0:
|
|
1509
|
+
# point_coefficients[i][j] += 1
|
|
1510
|
+
# if point_coefficients[i][j] >1:
|
|
1511
|
+
# point_coefficients[i][j] -= 1
|
|
1512
|
+
new_coords = [evaluate_basis_coefficients(
|
|
1513
|
+
points, super_cell_vector) for points in point_coefficients]
|
|
1514
|
+
|
|
1515
|
+
# for j,points in enumerate(point_coefficients):
|
|
1516
|
+
# if min(new_coords[i])<0:
|
|
1517
|
+
# try shift one cv in each direction:
|
|
1518
|
+
# potential_new_point = []
|
|
1519
|
+
|
|
1520
|
+
for i, coords in enumerate(new_coords):
|
|
1521
|
+
super_cell.getAtom(i).setcoords(coords)
|
|
1522
|
+
# point_coefficients = [get_basis_coefficients(at.coords(),super_cell_vector) for at in super_cell.getAtoms()]
|
|
1523
|
+
print('coords in final slab:')
|
|
1524
|
+
print(point_coefficients)
|
|
1525
|
+
######
|
|
1526
|
+
rest = super_cell.sanitycheck(silence=False)
|
|
1527
|
+
print(('result of collision check is ' + str(rest)))
|
|
1528
|
+
|
|
1529
|
+
#################################
|
|
1530
|
+
# write slab output
|
|
1531
|
+
super_cell.writexyz(rootdir + 'slab/super' +
|
|
1532
|
+
''.join([str(i) for i in duplication_vector])+'.xyz')
|
|
1533
|
+
print(('\n Created a supercell in ' + str(rootdir) + '\n'))
|
|
1534
|
+
|
|
1535
|
+
# let's check if the periodicity is correct
|
|
1536
|
+
super_duper_cell = unit_to_super(super_cell, cell_vector, [2, 2, 1])
|
|
1537
|
+
super_duper_cell.writexyz(rootdir + 'slab/SD.xyz')
|
|
1538
|
+
|
|
1539
|
+
# get some vapourspace
|
|
1540
|
+
final_cv = copy.deepcopy(super_cell_vector)
|
|
1541
|
+
final_cv[2][2] = float(final_cv[2][2]) + 20
|
|
1542
|
+
print('final cell vector, inc vapour space is :')
|
|
1543
|
+
print(final_cv)
|
|
1544
|
+
write_periodic_mol3d_to_qe(
|
|
1545
|
+
super_cell, final_cv, rootdir + 'slab/slab.in')
|
|
1546
|
+
elif not slab_gen: # placement only, skip slabbing!
|
|
1547
|
+
super_cell = unit_cell
|
|
1548
|
+
super_cell_vector = cell_vector
|
|
1549
|
+
|
|
1550
|
+
if place_on_slab:
|
|
1551
|
+
if slab_gen:
|
|
1552
|
+
print(
|
|
1553
|
+
'\n\n ************************ starting placement ***************** \n\n')
|
|
1554
|
+
# Whoever started this obviously has not finished this part of the implementation:
|
|
1555
|
+
# Variables needed in the next few lines, such as new_dup_vector are not assigned...
|
|
1556
|
+
raise NotImplementedError()
|
|
1557
|
+
if not slab_gen:
|
|
1558
|
+
print(
|
|
1559
|
+
'\n\n ************************ placement on existing slab ***************** \n\n')
|
|
1560
|
+
new_dup_vector = cell_vector
|
|
1561
|
+
super_cell_vector = cell_vector
|
|
1562
|
+
print('this supercell vector is:')
|
|
1563
|
+
print(super_cell_vector)
|
|
1564
|
+
|
|
1565
|
+
if control_angle:
|
|
1566
|
+
print('control angle on')
|
|
1567
|
+
print(angle_surface_axis)
|
|
1568
|
+
angle_surface_axis.append(0)
|
|
1569
|
+
print(angle_surface_axis)
|
|
1570
|
+
|
|
1571
|
+
print(('object_align ' + str(object_align)))
|
|
1572
|
+
loaded_cell = molecule_placement_supervisor(super_cell, super_cell_vector, target_molecule,
|
|
1573
|
+
align_method, object_align, align_dist, surface_atom_type,
|
|
1574
|
+
control_angle=control_angle, align_ind=angle_control_partner, align_axis=angle_surface_axis,
|
|
1575
|
+
duplicate=duplicate, number_of_placements=num_placements, coverage=coverage,
|
|
1576
|
+
weighting_method='linear', weight=weight, masklength=num_surface_atoms, surface_atom_ind=surface_atom_ind, debug=debug)
|
|
1577
|
+
if not os.path.exists(rootdir + 'loaded_slab'):
|
|
1578
|
+
os.makedirs(rootdir + 'loaded_slab')
|
|
1579
|
+
if freeze and not slab_gen: # freezing happens at gen time
|
|
1580
|
+
if isinstance(freeze, int):
|
|
1581
|
+
print('freezing')
|
|
1582
|
+
loaded_cell = freeze_bottom_n_layers(loaded_cell, freeze)
|
|
1583
|
+
else:
|
|
1584
|
+
loaded_cell = freeze_bottom_n_layers(loaded_cell, 1)
|
|
1585
|
+
|
|
1586
|
+
loaded_cell.writexyz(rootdir + 'loaded_slab/loaded.xyz')
|
|
1587
|
+
super_duper_cell = unit_to_super(
|
|
1588
|
+
loaded_cell, new_dup_vector, [2, 2, 1])
|
|
1589
|
+
|
|
1590
|
+
super_duper_cell.writexyz(rootdir + 'loaded_slab/SD.xyz')
|
|
1591
|
+
write_periodic_mol3d_to_qe(
|
|
1592
|
+
loaded_cell, new_dup_vector, rootdir + 'loaded_slab/loaded_slab.in')
|