def testSubgraphIsomorphism(self): # Simple test comparing C-C to C-C-C (no hydrogens) mol = Molecule() c1 = Atom(getElement(6)) c2 = c1.copy() mol.addAtom(c1) mol.addAtom(c2) mol.addBond(Bond(c1, c2)) mol2 = Molecule() c1 = c1.copy() c2 = c1.copy() c3 = c1.copy() mol2.addAtom(c1) mol2.addAtom(c2) mol2.addAtom(c3) mol2.addBond(Bond(c1, c2)) mol2.addBond(Bond(c2, c3)) self.assertTrue(self.vf3.isSubgraphIsomorphic(mol2, mol, None)) self.assertFalse(self.vf3.isSubgraphIsomorphic(mol, mol2, None)) # Ring membership is a semantic property of molecules, # so straight chains are not considered sub graphs of rings hexane = Molecule().fromSMILES("C1CCCCC1") self.assertFalse(self.vf3.isSubgraphIsomorphic(hexane, mol, None)) self.assertFalse(self.vf3.isSubgraphIsomorphic(hexane, mol2, None)) # Benzene and hexane, while technically sharing the same shape, # differ in semantic information. benzene = Molecule().fromSMILES("C1=CC=CC=C1") self.assertFalse(self.vf3.isSubgraphIsomorphic(hexane, benzene, None)) # Test sub graph isomorphism on rings hexaneMinusH = hexane.copy(True) hexaneMinusH.removeVertex(hexaneMinusH.vertices[6]) self.assertTrue(self.vf3.isSubgraphIsomorphic(hexane, hexaneMinusH, None)) self.assertFalse(self.vf3.isSubgraphIsomorphic(hexaneMinusH, hexane, None)) benzeneMinusH = benzene.copy(True) benzeneMinusH.removeVertex(benzeneMinusH.vertices[6]) self.assertTrue(self.vf3.isSubgraphIsomorphic(benzene, benzeneMinusH, None)) self.assertFalse(self.vf3.isSubgraphIsomorphic(benzeneMinusH, hexane, None))
def testGraphIsomorphism(self): self.assertTrue(self.vf3.isIsomorphic(self.mol, self.mol2, None)) examples = ["CC(C)=O", "C1=CC=CC=C1O[H]", "[S](=O)(=O)([O-])[O-]", "C1=CC=C2C(=C1)C=CC=C2"] for smiles in examples: mol = Molecule().fromSMILES(smiles) self.assertTrue(self.vf3.isIsomorphic(mol, mol.copy(True), None)) self.assertTrue(self.vf3.isSubgraphIsomorphic(mol, mol.copy(True), None)) for smiles2 in examples: if smiles is not smiles2: self.assertFalse(self.vf3.isIsomorphic(mol, Molecule().fromSMILES(smiles2), None)) self.assertFalse(self.vf3.isSubgraphIsomorphic(mol, Molecule().fromSMILES(smiles2), None))
def testInitialMapping(self): mol1 = Molecule().fromSMILES("CCC") mol2 = mol1.copy(True) mol1.sortVertices() mol2.sortVertices() initMap = {mol1.vertices[0]: mol2.vertices[0], mol1.vertices[2]: mol2.vertices[2]} self.assertTrue(self.vf3.isIsomorphic(mol1, mol2, initMap))
def testNumberOfMappings(self): examples = {"CC": 72, "CCC": 144, "CC[O]": 12, "C1=CC=CC=C1": 6, "C1(CCCC1)O[H]": 32, "C1=CC=C2C(=C1)C=CC=C2": 1} for smiles in examples.keys(): mol = Molecule().fromSMILES(smiles) self.assertEquals(len(self.vf3.findIsomorphism(mol, mol.copy(True), None)), examples[smiles])
class TestVF2(unittest.TestCase): """ Contains unit tests of the methods for computing symmetry numbers for a given Molecule object. """ def setUp(self): self.vf2 = VF2() self.mol = Molecule().fromSMILES("CC(=O)C[CH2]") self.mol2 = self.mol.copy(deep=True) def test_import_graph(self): """Test that we can add graphs to the object and that they are sorted""" self.mol.sortVertices() ordered_original_connectivity_order = [ getVertexConnectivityValue(atom) for atom in self.mol.atoms ] self.vf2.graphA = self.mol self.vf2.graphB = self.mol2 final_connectivity_order = [ getVertexConnectivityValue(atom) for atom in self.vf2.graphA.atoms ] final_connectivity_order2 = [ getVertexConnectivityValue(atom) for atom in self.vf2.graphB.atoms ] testing.assert_array_equal(final_connectivity_order, final_connectivity_order2) testing.assert_array_equal(final_connectivity_order, ordered_original_connectivity_order) def test_feasible(self): """ Test that feasibility returns correct values on highly functional molecule `feasible` method isn't perfect in assigning values but it should do a good job on highly functional values """ self.vf2.graphA = self.mol self.vf2.graphB = self.mol2 for atom1 in self.vf2.graphA.atoms: for atom2 in self.vf2.graphB.atoms: # same connectivity values should result in `feasible` being true if getVertexConnectivityValue( atom1) == getVertexConnectivityValue(atom2): self.assertTrue(self.vf2.feasible(atom1, atom2)) else: # different connectivity values should return false self.assertFalse(self.vf2.feasible(atom1, atom2))
class TestVF2(unittest.TestCase): """ Contains unit tests of the methods for computing symmetry numbers for a given Molecule object. """ def setUp(self): self.vf2 = VF2() self.mol = Molecule().fromSMILES("CC(=O)C[CH2]") self.mol2 = self.mol.copy(deep=True) def test_import_graph(self): """Test that we can add graphs to the object and that they are sorted""" self.mol.sortVertices() ordered_original_connectivity_order = [getVertexConnectivityValue(atom) for atom in self.mol.atoms] self.vf2.graphA = self.mol self.vf2.graphB = self.mol2 final_connectivity_order = [getVertexConnectivityValue(atom) for atom in self.vf2.graphA.atoms] final_connectivity_order2 = [getVertexConnectivityValue(atom) for atom in self.vf2.graphB.atoms] testing.assert_array_equal(final_connectivity_order,final_connectivity_order2) testing.assert_array_equal(final_connectivity_order,ordered_original_connectivity_order) def test_feasible(self): """ Test that feasibility returns correct values on highly functional molecule `feasible` method isn't perfect in assigning values but it should do a good job on highly functional values """ self.vf2.graphA = self.mol self.vf2.graphB = self.mol2 for atom1 in self.vf2.graphA.atoms: for atom2 in self.vf2.graphB.atoms: # same connectivity values should result in `feasible` being true if getVertexConnectivityValue(atom1) == getVertexConnectivityValue(atom2): self.assertTrue(self.vf2.feasible(atom1, atom2)) else: # different connectivity values should return false self.assertFalse(self.vf2.feasible(atom1, atom2)) def test_clear_mapping(self): """Test that vertex mapping is cleared after isomorphism.""" self.vf2.isIsomorphic(self.mol, self.mol2, None) for atom in self.mol.atoms: self.assertIsNone(atom.mapping) self.assertFalse(atom.terminal)
def testSaturateAromaticRadical(self): """ Test that the Molecule.saturate() method works properly for an indenyl radical containing Benzene bonds """ indenyl = Molecule().fromAdjacencyList(""" multiplicity 2 1 C u0 p0 c0 {2,B} {3,S} {4,B} 2 C u0 p0 c0 {1,B} {5,B} {6,S} 3 C u0 p0 c0 {1,S} {7,D} {11,S} 4 C u0 p0 c0 {1,B} {8,B} {12,S} 5 C u0 p0 c0 {2,B} {9,B} {15,S} 6 C u1 p0 c0 {2,S} {7,S} {16,S} 7 C u0 p0 c0 {3,D} {6,S} {10,S} 8 C u0 p0 c0 {4,B} {9,B} {13,S} 9 C u0 p0 c0 {5,B} {8,B} {14,S} 10 H u0 p0 c0 {7,S} 11 H u0 p0 c0 {3,S} 12 H u0 p0 c0 {4,S} 13 H u0 p0 c0 {8,S} 14 H u0 p0 c0 {9,S} 15 H u0 p0 c0 {5,S} 16 H u0 p0 c0 {6,S} """) indene = Molecule().fromAdjacencyList(""" 1 C u0 p0 c0 {2,B} {3,S} {4,B} 2 C u0 p0 c0 {1,B} {5,B} {6,S} 3 C u0 p0 c0 {1,S} {7,D} {11,S} 4 C u0 p0 c0 {1,B} {8,B} {12,S} 5 C u0 p0 c0 {2,B} {9,B} {15,S} 6 C u0 p0 c0 {2,S} {7,S} {16,S} {17,S} 7 C u0 p0 c0 {3,D} {6,S} {10,S} 8 C u0 p0 c0 {4,B} {9,B} {13,S} 9 C u0 p0 c0 {5,B} {8,B} {14,S} 10 H u0 p0 c0 {7,S} 11 H u0 p0 c0 {3,S} 12 H u0 p0 c0 {4,S} 13 H u0 p0 c0 {8,S} 14 H u0 p0 c0 {9,S} 15 H u0 p0 c0 {5,S} 16 H u0 p0 c0 {6,S} 17 H u0 p0 c0 {6,S} """) saturated_molecule = indenyl.copy(deep=True) saturated_molecule.saturate() self.assertTrue(saturated_molecule.isIsomorphic(indene))