def test_ring(): """Test the Ring object from the ring module.""" num_slots = 10 # num_filled = 2 num_geoms = 3 num_atoms = 24 # t_size = 7 # num_muts = 3 # num_swaps = 1 pmem_dist = 2 parser = Xyz(os.path.join(TEST_DIR, "caffeine.xyz")) parser.charge = 0 parser.multip = 1 ring = Ring(num_geoms, num_atoms, num_slots, pmem_dist, 0, 0.5, 0.5, parser) # check that ring has its attributes assert ring.parser.charge == 0 assert ring.parser.multip == 1 assert ring.num_slots == 10 assert ring.num_filled == 0 assert ring.num_geoms == 3 assert ring.num_atoms == 24 assert ring.pmem_dist == 2 assert ring.fit_form == 0 assert ring.coef_energy == 0.5 assert ring.coef_rmsd == 0.5 assert ring.pmems.shape == (10,) assert all([ring.pmems[i] is None for i in range(10)]) # check that the zmatrix is the same as the # zmatrix that comes out of the openbabel gui czmat = CAFFEINE_ZMATRIX.split('\n') ring_czmat = ring.zmatrix.split('\n') assert len(czmat) == len(ring_czmat) for i, val in enumerate(czmat): assert val == ring_czmat[i]
def test_calc_rmsd(): """Test the calc_rmsd function from the rsmd module.""" # test the A1 and A3 hydrogen molecules mol1 = Xyz(os.path.join(TEST_DIR, "H2-1A.xyz")) mol3 = Xyz(os.path.join(TEST_DIR, "H2-3A.xyz")) assert calc_rmsd(mol1.coords, mol3.coords) == 1.0 # test translated/rotated hydrogen mol1tr = Xyz(os.path.join(TEST_DIR, "H2-1A-transrot.xyz")) assert calc_rmsd(mol1.coords, mol1tr.coords) == 0.0 # test same molecule twice assert calc_rmsd(mol1.coords, mol1.coords) == 0.0
def test_ring_getitem(): """Test the Ring.__getitem__ method.""" parser = Xyz(os.path.join(TEST_DIR, "1,3-butadiene.xyz")) parser.charge = 0 parser.multip = 1 ring = Ring(3, 10, 15, 2, 0, 0.5, 0.5, parser) ring.fill(5, 0) for i in range(5): assert ring[i].birthday == 0 assert ring[5] is None with assert_raises(KeyError): ring[1000] ring['one']
def test_run_tournament(): """Test run_tournament function from tournament module.""" # ring init: # num_geoms, num_atoms, num_slots, pmem_dist, fit_form, # coef_energy, coef_rmsd, parser mol = Xyz(os.path.join(TEST_DIR, "1,3-butadiene.xyz")) mol.charge = 0 mol.multip = 1 ring = Ring(3, 10, 20, 2, 0, 0.5, 0.5, mol) ring.fill(3, 0) # tournament call: # t_size, num_muts, num_swaps, ring, current_mev # check that an empty ring error is raised when trying to # run a tournament size that is too big assert_raises(RingEmptyError, run_tournament, 7, 0, 0, ring, 0) run_tournament(2, 0, 0, ring, 0)
def test_ring_setitem(): """Test the Ring.__setitem__ method.""" parser = Xyz(os.path.join(TEST_DIR, "1,3-butadiene.xyz")) parser.charge = 0 parser.multip = 1 ring = Ring(3, 10, 15, 2, 0, 0.5, 0.5, parser) with assert_raises(KeyError): ring[1000] = Pmem(1000, 3, 10, 1) ring['two'] = Pmem(2, 3, 10, 1) ring[1] = 'string' with assert_raises(AssertionError): ring[4] = Pmem(3, 3, 10, 1) ring[3] = Pmem(4, 2, 10, 1) ring[2] = Pmem(2, 3, 9, 1) ring.fill(1, 0) assert ring.num_filled == 1 ring[0] = None assert ring.num_filled == 0
def test_ring_fill(): """Test the Ring.fill method.""" parser = Xyz(os.path.join(TEST_DIR, "1,3-butadiene.xyz")) parser.charge = 0 parser.multip = 1 ring = Ring(3, 10, 15, 2, 0, 0.5, 0.5, parser) # try to put more pmems in than there are slots assert_raises(RingOverflowError, ring.fill, 200, 0) assert ring.num_filled == 0 ring.fill(1, 0) assert ring.num_filled == 1 # same test twice except getitem syntax can be used assert ring.pmems[0].birthday == 0 assert ring[0].birthday == 0 ring.fill(5, 1) assert ring.num_filled == 6 assert ring[1].birthday == 1 # test adding without contiguous segment present ring[9] = Pmem(9, 3, 10, 2) ring.fill(5, 3) assert ring.num_filled == 12 assert ring[11] is not None assert ring[12] is None assert ring[8].birthday == 3
def run_output(ring): """Run the output module. Parameters ---------- ring : object The final ring data structure after evolution. """ # find average fitness # find best pmem and its ring index total_fit = 0 best_pmem = 0 best_fit = 0 for pmem in ring.pmems: if pmem is not None: fitg = pmem.fitness total_fit += fitg if fitg > best_fit: best_pmem = pmem.ring_loc best_fit = fitg average_fit = total_fit / ring.num_filled # generate and get output directory output_dir = get_output_dir() # write a stats file with open(os.path.join(output_dir, "stats-file.txt"), "w") as fout: fout.write(f"num conformers: {ring.num_geoms}\n") fout.write(f"average fitness: {average_fit}\n") fout.write(f"best fitness: {best_fit}\n") fout.write( f"final percent filled: {100*ring.num_filled/ring.num_slots}%\n") # generate the output file for the best pmem for geom in range(ring.num_geoms): xyz_coords = zmatrix_to_xyz( update_zmatrix(ring.zmatrix, ring[best_pmem].dihedrals[geom])) xyz = Xyz() xyz.coords = xyz_coords xyz.num_atoms = ring.num_atoms xyz.comments = f"conformer {geom}" xyz.write_xyz(os.path.join(output_dir, f"conf{geom}.xyz"))
def test_ring_update(): """Test the Ring.update method.""" # parent_index, child, current_mev parser = Xyz(os.path.join(TEST_DIR, "1,3-butadiene.xyz")) parser.charge = 0 parser.multip = 1 ring = Ring(3, 10, 15, 2, 0, 0.5, 0.5, parser) # ring is empty, try adding random pmems # testing backflow ring.update(0, [[1, 2, 3, 4, 5, 6, 7], [1, 2, 3, 4, 2, 1, 1], [7, 6, 5, 4, 3, 2, 1]], 0) # possible places the update took place slots = [0, 1, 2, 13, 14] not_slots = [3, 4, 5, 6, 7, 8, 9, 10, 11, 12] assert sum(ring[i] is not None for i in slots) == 1 assert all(ring[i] is None for i in not_slots) ring[0] = None ring[1] = None ring[2] = None ring[13] = None ring[14] = None # test case where pmem_dist is zero ring.pmem_dist = 0 ring.update(0, [[1, 2, 3, 4, 5, 6, 7], [1, 2, 3, 4, 2, 1, 1], [7, 6, 5, 4, 3, 2, 1]], 0) assert ring[0] is not None assert sum(ring[i] is not None for i in range(ring.num_slots)) == 1 # test overflow ring[0] = None ring.pmem_dist = 4 ring.update(13, [[1, 2, 3, 4, 5, 6, 7], [1, 2, 3, 4, 2, 1, 1], [7, 6, 5, 4, 3, 2, 1]], 0) slots = [13, 14, 0, 1, 2, 9, 10, 11, 12] assert (sum(ring[i] is not None for i in slots)) == 1 not_slots = [3, 4, 5, 6, 7, 8] assert all(ring[i] is None for i in not_slots) # test no overflow or backflow (now, pmem dist is 4) for slot in slots: ring[slot] = None ring.update(7, [[1, 2, 3, 4, 5, 6, 7], [1, 2, 3, 4, 2, 1, 1], [7, 6, 5, 4, 3, 2, 1]], 0) slots = [7, 8, 9, 10, 11, 3, 4, 5, 6] assert (sum(ring[i] is not None for i in slots)) == 1 not_slots = [0, 1, 2, 12, 13, 14] assert all(ring[i] is None for i in not_slots) for slot in slots: ring[slot] = None # now check that slot is not updated if child has worse fitness ring.pmem_dist = 0 # fitness = 230.09933808553276 ring[0] = Pmem(0, 3, 10, 0, [[239, 278, 5, 248, 40, 67, 299], [36, 123, 295, 111, 322, 267, 170], [61, 130, 26, 139, 290, 238, 331]]) ring.set_fitness(0) # fitness = 77.4576053229711 ring.update(0, [[132, 272, 40, 226, 44, 154, 339], [182, 119, 106, 157, 194, 244, 168], [95, 81, 202, 261, 197, 166, 161]], 1) assert ring[0].dihedrals == [[239, 278, 5, 248, 40, 67, 299], [36, 123, 295, 111, 322, 267, 170], [61, 130, 26, 139, 290, 238, 331]] assert ring.num_filled == 1 assert ring[0].birthday == 0