class TestSubstituent(TestWithTimer): COCH3 = Geometry(os.path.join(prefix, "test_files", "COCH3.xyz")) NO2 = Geometry(os.path.join(prefix, "test_files", "NO2.xyz")) benz_NO2_Cl = Geometry( os.path.join(prefix, "test_files", "benzene_1-NO2_4-Cl.xyz")) def is_COCH3(self, sub): ref = TestSubstituent.COCH3 self.assertEqual(sub.name, "COCH3") self.assertEqual(sub.comment, "CF:2,180") self.assertEqual(sub.conf_num, 2) self.assertEqual(sub.conf_angle, np.deg2rad(180)) self.assertTrue(validate(sub, ref)) return def is_NO2(self, sub): ref = TestSubstituent.NO2 self.assertEqual(sub.name, "NO2") self.assertEqual(sub.comment, "CF:2,120") self.assertEqual(sub.conf_num, 2) self.assertEqual(sub.conf_angle, np.deg2rad(120)) self.assertTrue(validate(sub, ref, thresh=1e-5)) return def test_init(self): sub = Substituent("COCH3") self.is_COCH3(sub) sub = Substituent("COCH3", targets=["C", "O", "H"]) self.is_COCH3(sub) return def test_copy(self): sub = Substituent("COCH3") sub = sub.copy() self.is_COCH3(sub) return def test_detect_sub(self): mol = TestSubstituent.benz_NO2_Cl NO2 = mol.get_fragment("N", "C", as_object=True) sub = Substituent(NO2) self.is_NO2(sub) NO2 = mol.get_fragment("N", "C", copy=True) sub = Substituent(NO2) self.is_NO2(sub) def test_align_to_bond(self): mol = TestSubstituent.benz_NO2_Cl bond = mol.bond("1", "12") sub = Substituent("NO2") sub.align_to_bond(bond) bond /= np.linalg.norm(bond) test_bond = sub.find("N")[0].coords - np.array([0.0, 0.0, 0.0]) test_bond /= np.linalg.norm(test_bond) self.assertTrue(np.linalg.norm(bond - test_bond) < 10**-8)
def test_RMSD(self): ref = Geometry(TestGeometry.benz_NO2_Cl) # RMSD of copied object should be 0 other = ref.copy() self.assertTrue(ref.RMSD(other) < rmsd_tol(ref, superTight=True)) # if they are out of order, sorting should help res = ref.RMSD(other, longsort=True) self.assertTrue(res < rmsd_tol(other, superTight=True)) # RMSD of shifted copy should be 0 other = ref.copy() other.coord_shift([1, 2, 3]) self.assertTrue(ref.RMSD(other) < rmsd_tol(ref, superTight=True)) # RMSD of rotated copy should be 0 other = ref.copy() other.rotate([1, 2, 3], 2.8) other.write("tmp") self.assertTrue(ref.RMSD(other) < rmsd_tol(ref)) # RMSD of two different structures should not be 0 other = Geometry(TestGeometry.pent) self.assertTrue(ref.RMSD(other) > 10**-2) # RMSD of similar molecule other = Geometry(TestGeometry.benzene) res = ref.RMSD(other, targets="C", ref_targets="C") self.assertTrue(res < rmsd_tol(ref)) res = ref.RMSD(other, sort=True)
def test_map_ligand(self): monodentate = TestCatalyst.monodentate tridentate = TestCatalyst.tridentate tm_simple = TestCatalyst.tm_simple.copy() tm_simple.map_ligand([monodentate, "ACN"], ["35", "36"]) self.assertTrue( self.validate(tm_simple, Geometry(prefix + "ref_files/lig_map_2.xyz"))) tm_simple = TestCatalyst.tm_simple.copy() tm_simple.map_ligand("S-tBu-BOX", ["35", "36"]) self.assertTrue( self.validate(tm_simple, Geometry(prefix + "ref_files/lig_map_3.xyz"))) org_tri = TestCatalyst.org_tri.copy() org_tri.map_ligand(tridentate, ["30", "28", "58"]) self.assertTrue( self.validate(org_tri, Geometry(prefix + "ref_files/lig_map_4.xyz"))) tm_simple = TestCatalyst.tm_simple.copy() tm_simple.map_ligand(monodentate, ["35"]) self.assertTrue( self.validate(tm_simple, Geometry(prefix + "ref_files/lig_map_1.xyz")))
def test_interpolate(self): """test interpolate.py assumes current working directory is writable b/c interpolate doesn't print structures to stdout""" ref = Geometry( os.path.join(prefix, "ref_files", "torsion_interpolation.xyz")) args = [ sys.executable, os.path.join(self.aarontools_bin, "interpolate.py"), TestCLS.t60, TestCLS.t90, "-t", "0.40", "-u", ] proc = Popen(args, stdout=PIPE, stderr=PIPE) out, err = proc.communicate() if len(err) != 0: raise RuntimeError(err) mol = Geometry("traj-0.xyz") os.remove("traj-0.xyz") rmsd = mol.RMSD(ref, align=True, sort=True) self.assertTrue(rmsd < rmsd_tol(ref, superLoose=True))
def test_vbur_MC(self): """ tests % volume buried (MC integration) uses Monte Carlo integration, so it this fails, run it again still figuring out how reliable it is """ # import cProfile # # profile = cProfile.Profile() # profile.enable() geom = Geometry(os.path.join(prefix, "ref_files", "lig_map_3.xyz")) vbur = geom.percent_buried_volume(method="MC") if not np.isclose(vbur, 86.0, atol=0.35): print("V_bur =", vbur, "expected:", 86.0) self.assertTrue(np.isclose(vbur, 86.0, atol=0.35)) # a few synthetic tests geom2 = Geometry(os.path.join(prefix, "ref_files", "vbur.xyz")) vbur = geom2.percent_buried_volume(method="MC", scale=1 / 1.1, radius=3) if not np.isclose(vbur, 100.0 / 27, atol=0.2): print("V_bur =", vbur, "expected:", 100.0 / 27) self.assertTrue(np.isclose(vbur, 100.0 / 27, atol=0.2)) geom3 = Geometry(os.path.join(prefix, "ref_files", "vbur2.xyz")) vbur = geom2.percent_buried_volume(method="MC", scale=1 / 1.1, radius=4) if not np.isclose(vbur, 100.0 / 64, atol=0.2): print("V_bur =", vbur, "expected:", 100.0 / 64) self.assertTrue(np.isclose(vbur, 100.0 / 64, atol=0.2))
def test_changeChirality(self): """test changeChirality.py""" args = [ sys.executable, os.path.join(self.aarontools_bin, "changeChirality.py"), TestCLS.change_chir_1, "--diastereomers", ] proc = Popen(args, stdout=PIPE, stderr=PIPE) out, err = proc.communicate() if len(err) != 0: raise RuntimeError(err) fr = FileReader(("out", "xyz", out.decode("utf-8")), get_all=True) for step, ref in zip(fr.all_geom, self.change_chir_ref_1): geom = None for item in step: if isinstance(item, list) and all( isinstance(a, Atom) for a in item): geom = Geometry(item) if geom is None: raise RuntimeError("an output is missing atoms") ref_geom = Geometry(ref) rmsd = ref_geom.RMSD(geom) self.assertTrue(rmsd < rmsd_tol(ref_geom))
def test_compare_connectivity(self): geom = Geometry(TestGeometry.cat) ref = Geometry(TestGeometry.cat) # no formed/broken broken, formed = geom.compare_connectivity(ref) self.assertTrue(len(broken) == 0) self.assertTrue(len(formed) == 0) # broken geom.change_distance("10", "15", dist=1, adjust=True) geom.refresh_connected() broken, formed = geom.compare_connectivity(ref) self.assertTrue(len(broken) == 1) self.assertTrue(len(formed) == 0) self.assertSetEqual(broken, set([("10", "15")])) # formed ref.change_distance("10", "15", dist=1, adjust=True) ref.refresh_connected() geom.change_distance("10", "15", dist=-1, adjust=True) geom.refresh_connected() broken, formed = geom.compare_connectivity(ref) self.assertTrue(len(broken) == 0) self.assertTrue(len(formed) == 1) self.assertSetEqual(formed, set([("10", "15")])) # broken and formed geom.change_distance("20", "29", dist=1, adjust=True) geom.refresh_connected() broken, formed = geom.compare_connectivity(ref) self.assertTrue(len(broken) == 1) self.assertTrue(len(formed) == 1) self.assertSetEqual(broken, set([("20", "29")])) self.assertSetEqual(formed, set([("10", "15")]))
def test_RMSD(self): ref = Geometry(TestGeometry.benz_NO2_Cl) # RMSD of copied object should be 0 test = ref.copy() self.assertTrue(validate(test, ref)) # RMSD of shifted copy should be 0 test = ref.copy() test.coord_shift([1, 2, 3]) self.assertTrue(validate(test, ref)) # RMSD of rotated copy should be 0 test = ref.copy() test.rotate([1, 2, 3], 2.8) self.assertTrue(validate(test, ref)) # RMSD of two different structures should not be 0 test = Geometry(TestGeometry.pentane) self.assertFalse(validate(test, ref)) # RMSD of similar molecule test = Geometry(TestGeometry.benzene) res = ref.RMSD(test, targets="C", ref_targets="C") self.assertTrue(res < rmsd_tol(ref))
def check_geometry_rmsd(self, *args): """check RMSD between energy and frequency filereader on the absolute tab if the RMSD is > 10^-5 or the number of atoms is different, put a warning in the status bar""" if self.thermo_selector.currentIndex( ) >= 0 and self.sp_selector.currentIndex() >= 0: fr = self.sp_selector.currentData() fr2 = self.thermo_selector.currentData() if len(fr.atoms) != len(fr2.atoms): self.status.showMessage( "structures are not the same: different number of atoms") return geom = Geometry(fr) geom2 = Geometry(fr2) rmsd = geom.RMSD(geom2) if not isclose(rmsd, 0, atol=10**-5): rmsd = geom.RMSD(geom2, sort=True) if not isclose(rmsd, 0, atol=10**-5): self.status.showMessage( "structures might not be the same - RMSD = %.4f" % rmsd) else: self.status.showMessage("")
def test_C1(self): mol1 = Geometry(self.chiral_ring, refresh_ranks=False) pg = PointGroup(mol1) self.assertEqual(pg.name, "C1") mol2 = Geometry(self.chiral_mol_1, refresh_ranks=False) pg = PointGroup(mol2) self.assertEqual(pg.name, "C1") mol3 = Geometry(self.chiral_mol_2, refresh_ranks=False) pg = PointGroup(mol3) self.assertEqual(pg.name, "C1") mol4 = Geometry(self.chiral_mol_3, refresh_ranks=False) pg = PointGroup(mol4) self.assertEqual(pg.name, "C1") mol5 = Geometry(self.chiral_mol_4, refresh_ranks=False) pg = PointGroup(mol5) self.assertEqual(pg.name, "C1")
class TestPathway(TestWithTimer): t60 = Geometry(prefix + "test_files/torsion-60.xyz") t90 = Geometry(prefix + "test_files/torsion-90.xyz") def test_interpolating_structure(self): #test to see if interpolated geometry is correct ref = Geometry(prefix + "ref_files/torsion_interpolation.xyz") S = Pathway([self.t60, self.t90]) geom = S.Geom_func(0.4) rmsd = geom.RMSD(ref, align=True) self.assertTrue(rmsd < rmsd_tol(ref, superLoose=True)) def test_splines_values(self): # test cubic splines function values # ought to have two splines: # g(x) = -10x^3 + 15x^2 # h(x) = 10x^3 + -15x^2 + 5 ref = [0, 0.78125, 2.5, 5, 4.21875, 2.5, 0] ref_d = [0, 5.625, 7.5, 0, -5.625, -7.5, 0] test_t = [0, 0.125, 0.25, 0.5, 0.625, 0.75, 1] tolerance = 50*finfo(float).eps ev = [0, 5, 0] m = Pathway.get_splines_mat(3) mi = inv(m) b = Pathway.get_splines_vector(ev) c = dot(mi, b) f, df = Pathway.get_E_func(c, [1, 1]) for i in range(0, len(test_t)): v = f(test_t[i]) dv = df(test_t[i]) self.assertTrue(abs(v-ref[i]) <= tolerance) self.assertTrue(abs(dv-ref_d[i]) <= tolerance)
def test_substitute(self): ref = Geometry(TestGeometry.benz_NO2_Cl) mol = Geometry(TestGeometry.benzene) mol.substitute(Substituent("NO2"), "12") mol.substitute(Substituent("Cl"), "11") self.assertTrue(validate(mol, ref))
def test_substitute(self): ref = Geometry(TestGeometry.benz_NO2_Cl) mol = Geometry(TestGeometry.benzene) mol.substitute(Substituent("NO2"), "12") mol.substitute(Substituent("Cl"), "11") rmsd = mol.RMSD(ref, align=True) self.assertTrue(rmsd < rmsd_tol(ref))
def test_equality(self): mol = Geometry(TestGeometry.benz_NO2_Cl) benz = Geometry(TestGeometry.benzene) # same object should be equal self.assertEqual(mol, mol) # copy should be equal self.assertEqual(mol, mol.copy()) # different molecules should be unequal self.assertNotEqual(mol, benz)
def test_close_ring_rmsd(self): mol = Geometry(TestGeometry.naphthalene) ref = Geometry(TestGeometry.pyrene) targets1 = mol.find(['9', '15']) targets2 = mol.find(['10', '16']) mol.ring_substitute(targets1, RingFragment('benzene')) mol.ring_substitute(targets2, RingFragment('benzene')) rmsd = mol.RMSD(ref, align=True) self.assertTrue(rmsd < rmsd_tol(ref))
def test_canonical_rank(self): pentane = Geometry(os.path.join(prefix, "test_files", "pentane.xyz")) pentane_rank = [1, 3, 4, 2, 0] test_rank = pentane.canonical_rank(heavy_only=True) self.assertSequenceEqual(test_rank, pentane_rank) mol = Geometry(os.path.join(prefix, "test_files", "6a2e5am1hex.xyz")) mol_rank = [11, 9, 8, 10, 6, 5, 4, 7, 3, 0, 2, 1] test_rank = mol.canonical_rank(heavy_only=True) self.assertSequenceEqual(test_rank, mol_rank)
def test_Td(self): mol = Geometry(self.adamantane, refresh_ranks=False) pg = PointGroup(mol) self.assertEqual(pg.name, "Td") mol = Geometry(self.methane, refresh_ranks=False) pg = PointGroup(mol) self.assertEqual(pg.name, "Td")
def test_add_sub_iter_len(self): ref = Geometry(TestGeometry.benz_OH_Cl) mol = Geometry(TestGeometry.benzene) mol.debug = True OH = ref.find(["12", "13"]) Cl = ref.find(["11"]) mol -= mol.find(["11", "12"]) mol += Cl mol += OH mol.refresh_connected() mol.refresh_ranks() self.assertTrue(validate(mol, ref, thresh="loose"))
class TestPathway(TestWithTimer): t60 = Geometry(os.path.join(prefix, "test_files", "torsion-60.xyz")) t90 = Geometry(os.path.join(prefix, "test_files", "torsion-90.xyz")) def test_interpolating_structure(self): # test to see if interpolated geometry is correct ref = Geometry( os.path.join(prefix, "ref_files", "torsion_interpolation.xyz")) pathway = Pathway(self.t60, array([self.t60.coords, self.t90.coords])) geom = pathway.geom_func(0.4) rmsd = geom.RMSD(ref, align=True, sort=False) self.assertTrue(rmsd < rmsd_tol(ref, superLoose=True))
def test_close_ring_approx(self): mol = Geometry(TestGeometry.benzene) ref1 = Geometry(TestGeometry.naphthalene) mol1 = mol.copy() mol1.ring_substitute(['7', '8'], RingFragment('benzene')) rmsd = mol1.RMSD(ref1, align=True) self.assertTrue(rmsd < rmsd_tol(ref1)) ref2 = Geometry(TestGeometry.tetrahydronaphthalene) mol2 = mol.copy() mol2.ring_substitute(['7', '8'], RingFragment('cyclohexane-chair.1')) rmsd = mol2.RMSD(ref2, align=True) self.assertTrue(rmsd < rmsd_tol(ref2))
def main(args): geom_patt = re.compile("([A-Z][a-z]*)((?:\s+-?\d+\.?\d*){3})") float_patt = re.compile("-?\d+\.?\d*") all_names = [] atoms = [] name = None for i, page in enumerate(extract_pages(args.infile)): print("parsing page {: 4d} please wait...".format(i + 1), end="\r") for element in page: last_line = None if hasattr(element, "get_text"): for line in element: text = line.get_text() match = geom_patt.search(text) if not match and last_line and atoms: name_match = geom_patt.search(name) if name_match: geom = Geometry(all_names[-1] + ".xyz") geom.atoms.extend(atoms) else: geom = Geometry(atoms) geom.name = name geom.comment = name if args.directory != "CURRENTDIR": geom.name = os.path.join( args.directory, geom.name) orig_name = geom.name i = 2 while geom.name in all_names: geom.name = "{}_{:03d}".format(orig_name, i) i += 1 if args.sort: geom.refresh_connected() geom.refresh_ranks() geom.atoms = geom.reorder()[0] geom.write() all_names.append(geom.name) atoms = [] name = None # print() # print(geom.name, len(geom.atoms)) # print(geom) if match: if not name: name = last_line element = match.group(1) coords = float_patt.findall(match.group(2)) atoms.append(Atom(element, [float(c) for c in coords])) last_line = text.strip()
def list( cls, name_regex=None, coordinating_elements=None, denticity=None, include_ext=False, ): names = [] for lib in [cls.AARON_LIBS, cls.BUILTIN]: if not os.path.exists(lib): continue for f in os.listdir(lib): name, ext = os.path.splitext(f) if not any(".%s" % x == ext for x in read_types): continue if name in names: continue name_ok = True elements_ok = True denticity_ok = True if ( name_regex is not None and re.search(name_regex, name, re.IGNORECASE) is None ): name_ok = False if coordinating_elements is not None: geom = Geometry( os.path.join(lib, name + ext), refresh_connected=False, refresh_ranks=False, ) # geom = cls(name) elements = [ geom.atoms[i].element for i in geom.other["key_atoms"] ] if not all( elements.count(x) == coordinating_elements.count(x) for x in coordinating_elements ) or not all( coordinating_elements.count(x) == elements.count(x) for x in elements ): elements_ok = False if denticity is not None: geom = cls(name) if len(geom.find("key")) != denticity: denticity_ok = False if name_ok and elements_ok and denticity_ok: if include_ext: names.append(name + ext) else: names.append(name) return names + sorted(cls.FROM_SUBSTITUENTS)
def gaussian_input_from_dict(cls, json_dict, fname=None): """write gaussian input file to fname using info in dict any keys (self.GAUSSIAN_*) should be strings instead of integers""" s = "" s += json_dict['header'] if json_dict['geometry'] is not None: atoms = [] for atom in json_dict['geometry']: atom_info = atom.split() atoms.append(Atom(element=atom_info[0], coords=[float(x) for x in atom_info[1:]])) geometry = Geometry(atoms) for atom in geometry.atoms: s += "%-2s %13.6f %13.6f %13.6f\n" % (atom.element, *atom.coords) s += json_dict['footer'] if fname is not None: with open(fname, "w") as f: f.write(s) return s
def test_flag(self): geom = Geometry(TestGeometry.benz_NO2_Cl) # freeze all test = geom.copy() test.freeze() for a in test.atoms: self.assertTrue(a.flag) # freeze some test = geom.copy() test.freeze("C") for a in test.atoms: if a.element == "C": self.assertTrue(a.flag) else: self.assertFalse(a.flag) geom.freeze() # relax all test = geom.copy() test.relax() for a in test.atoms: self.assertFalse(a.flag) # relax some test = geom.copy() test.relax("C") for a in test.atoms: if a.element == "C": self.assertFalse(a.flag) else: self.assertTrue(a.flag)
def test_change_angle(self): def diff(a, b): return abs(a - b) mol = Geometry(TestGeometry.benz_NO2_Cl) # set angle mol.change_angle("13", "12", "14", np.pi / 2, fix=1) angle = mol.angle("13", "12", "14") self.assertTrue(diff(np.rad2deg(angle), 90) < 10**-8) # change angle mol.change_angle("13", "12", "14", 30, fix=3, adjust=True, radians=False) angle = mol.angle("13", "12", "14") self.assertTrue(diff(np.rad2deg(angle), 120) < 10**-8) mol.change_angle("13", "12", "14", -30, adjust=True, radians=False) angle = mol.angle("13", "12", "14") self.assertTrue(diff(np.rad2deg(angle), 90) < 10**-8)
def test_WithinRadiusFromAtom(self): mol = Geometry(self.benzene) c1 = mol.find('C')[0] out = mol.find(WithinRadiusFromAtom(c1, 1.5)) self.assertTrue(all([atom in mol.find('1,2,6,12') for atom in out]))
def test_BondedTo(self): mol = Geometry(self.benzene) c1 = mol.find('C')[0] out = mol.find(BondedTo(c1)) self.assertTrue(all([atom in mol.find('2,6,12') for atom in out]))
def test_WithinBondsOf(self): mol = Geometry(self.benzene) h1 = mol.find('H')[0] out = mol.find(WithinBondsOf(h1, 2)) self.assertTrue(all([atom in mol.find('1,2,3') for atom in out]))
def test_interpolating_structure(self): #test to see if interpolated geometry is correct ref = Geometry(prefix + "ref_files/torsion_interpolation.xyz") S = Pathway([self.t60, self.t90]) geom = S.Geom_func(0.4) rmsd = geom.RMSD(ref, align=True) self.assertTrue(rmsd < rmsd_tol(ref, superLoose=True))
def test_write_inp(self): """write orca input file""" # like gaussian input files, this compares exact output geom = Geometry(self.small_mol) ref = """#comment line 1 #comment line 2 ! PBE0 D3BJ CPCM(dichloromethane) def2-SVP Freq Opt %cpcm smd true end %basis newGTO C "def2-TZVP" end end %freq Temp 298.15 end *xyz 0 1 C -1.97696 -2.32718 0.00126 C -2.36814 -1.29554 0.85518 C -1.67136 -0.08735 0.85440 C -0.58210 0.08919 0.00026 C -0.19077 -0.94241 -0.85309 C -0.88848 -2.15056 -0.85289 H -3.22679 -1.43483 1.52790 H -1.98002 0.72606 1.52699 H 0.66766 -0.80358 -1.52636 H -0.57992 -2.96360 -1.52585 Cl 0.29699 1.61392 -0.00037 N -2.73689 -3.64357 0.00188 O -2.07823 -4.68230 0.00289 O -3.96579 -3.59263 0.00134 * """ theory = Theory( charge=0, multiplicity=1, method="PBE0", basis=BasisSet( [Basis("def2-SVP", ["H"]), Basis("def2-TZVP", ["C"])]), empirical_dispersion=EmpiricalDispersion("D3BJ"), solvent=ImplicitSolvent("SMD", "dichloromethane"), job_type=[FrequencyJob(), OptimizationJob()], ) kw_dict = {ORCA_COMMENT: ["comment line 1", "comment line 2"]} test = FileWriter.write_inp(geom, theory=theory, outfile=False, **kw_dict) for line1, line2 in zip(test.splitlines(), ref.splitlines()): self.assertEqual(line1.strip(), line2.strip())