In [ ]:
from rmgpy.molecule import Molecule
from rmgpy.molecule.group import Group
import pdb
from IPython.display import display
In [ ]:
m = Molecule(SMILES='C12C3C4C1C5C4C6C5C2C36')
m.getSmallestSetOfSmallestRings()
In [ ]:
for i in range(10000):
out = m.getSmallestSetOfSmallestRings()
sizes = [len(ring) for ring in out]
if sum(sizes) != 25:
raise Exception('Test Failed')
In [ ]:
In [ ]:
n = Molecule(SMILES='C12CCC1C3CC2CC3')
display(n)
n.getSmallestSetOfSmallestRings()
In [ ]:
n.getRelevantCycles()
In [ ]:
o = Molecule(SMILES='C1C2C3C4CC(C5C4C4CCC5CC4)C3C(C2)C1')
display(o)
o.getSmallestSetOfSmallestRings()
In [ ]:
o.getRelevantCycles()
In [ ]:
a = Group().fromAdjacencyList("""
1 *1 C u0 p0 c0 {2,S} {4,S} {6,S}
2 *2 C u0 p0 c0 {1,S} {3,S} {7,S}
3 *3 C u0 p0 c0 {2,S} {4,S} {8,S}
4 *4 C u0 p0 c0 {1,S} {3,S} {5,S}
5 *5 C u0 p0 c0 {4,S} {6,S} {8,S}
6 *6 C u0 p0 c0 {1,S} {5,S} {7,S}
7 *7 C u0 p0 c0 {2,S} {6,S} {8,S}
8 *8 C u0 p0 c0 {3,S} {5,S} {7,S}
""")
display(a)
In [ ]:
a.getSmallestSetOfSmallestRings()
In [ ]:
a.getSSSR()
In [ ]:
b = Group().fromAdjacencyList("""
1 *1 C u0 p0 c0 {2,S} {5,S}
2 *2 C u0 p0 c0 {1,S} {3,S}
3 *3 C u0 p0 c0 {2,S} {4,S}
4 *4 C u0 p0 c0 {3,S} {5,S}
5 *5 C u0 p0 c0 {1,S} {4,S}
""")
display(b)
In [ ]:
b.getSmallestCycle(b.vertices[0])
In [ ]:
b.getSSSR()
In [ ]:
def getSmallestCycle(self, rootVertex):
# Initialize queue
queue = [(neighbor, rootVertex) for neighbor in rootVertex.edges.iterkeys()]
# Initialize paths dictionary
paths = {}
for neighbor, source in queue:
paths[neighbor] = set([neighbor, source])
# Begin loop
while queue and len(paths) < len(self.vertices):
frontVertex, source = queue.pop(0)
for neighbor in frontVertex.edges.iterkeys():
if neighbor is not source:
if neighbor not in paths:
paths[neighbor] = paths[frontVertex].copy()
paths[neighbor].add(neighbor)
queue.append((neighbor, frontVertex))
elif len(paths[frontVertex] & paths[neighbor]) == 1:
return frozenset(paths[frontVertex] | paths[neighbor])
return None
In [ ]:
In [ ]:
In [ ]:
def getSSSR(self):
# Make a copy of the graph so we don't modify the original
graph = self.copy(deep=True)
vertices = graph.vertices[:]
cycleList = []
counter = 0
while len(graph.vertices) > 0:
graph.updateConnectivityValues()
minDegree = min([vertex.connectivity1 for vertex in graph.vertices])
if minDegree == 0:
# Remove unconnected vertices
done = False
while not done:
verticesToRemove = []
for vertex in graph.vertices:
if vertex.connectivity1 == 0: verticesToRemove.append(vertex)
done = len(verticesToRemove) == 0
# Remove identified vertices from graph
for vertex in verticesToRemove:
graph.removeVertex(vertex)
if minDegree == 1:
# Remove all terminal vertices
done = False
while not done:
verticesToRemove = []
for vertex in graph.vertices:
if vertex.connectivity1 == 1: verticesToRemove.append(vertex)
done = len(verticesToRemove) == 0
# Remove identified vertices from graph
for vertex in verticesToRemove:
graph.removeVertex(vertex)
elif minDegree == 2:
# Identify all N2 vertices
N2 = [vertex for vertex in graph.vertices if vertex.connectivity1 == 2]
for vertex in N2:
# Get all cycles involving the root vertex
cycles = graph.getAllCycles(vertex)
if len(cycles) > 0:
# Keep the smallest of the cycles found
cycle = cycles[0]
for c in cycles[1:]:
if len(c) < len(cycle):
cycle = c
cycleList.append(cycle)
# Remove all N2 vertices
for vertex in N2:
graph.removeVertex(vertex)
elif minDegree == 3:
# Get any N3 vertex
for vertex in graph.vertices:
if vertex.connectivity1 == 3:
N3 = vertex
break
# Get all cycles involving the root vertex
cycles = graph.getAllCycles(N3)
if len(cycles) > 0:
# Keep the smallest of the cycles found
cycle = cycles[0]
for c in cycles[1:]:
if len(c) < len(cycle):
cycle = c
cycleList.append(cycle)
# Remove one of the bonds from the cycle
for vertex, edge in N3.edges.iteritems():
if vertex in cycle:
graph.removeEdge(edge)
break
counter += 1
if counter == 100:
pdb.set_trace()
# Remove duplicate cycles
cycleSet = set([frozenset(cycle) for cycle in cycleList])
# Convert back to lists
cycleList = [list(cycle) for cycle in cycleSet]
# Map atoms in cycles back to atoms in original graph
for i in range(len(cycleList)):
cycleList[i] = [self.vertices[vertices.index(v)] for v in cycleList[i]]
return cycleList
In [ ]: