def calculateCyclicSymmetryNumber(molecule): """ Get the symmetry number correction for cyclic regions of a molecule. For complicated fused rings the smallest set of smallest rings is used. """ from rdkit.Chem.rdmolops import SanitizeMol from rdkit.Chem.rdchem import Mol symmetryNumber = 1 rings = molecule.getSmallestSetOfSmallestRings() # Get symmetry number for each ring in structure for ring0 in rings: # Make another copy structure structure = molecule.copy(True) ring = [structure.atoms[molecule.atoms.index(atom)] for atom in ring0] # Remove bonds of ring from structure for i, atom1 in enumerate(ring): for atom2 in ring[i + 1 :]: if structure.hasBond(atom1, atom2): structure.removeBond(atom1.edges[atom2]) structures = structure.split() groups = [] for struct in structures: for atom in ring: if struct.hasAtom(atom): struct.removeAtom(atom) groups.append(struct.split()) # Find equivalent functional groups on ring equivalentGroups = [] equivalentGroupCount = [] for group in groups: found = False for i, eqGroup in enumerate(equivalentGroups): if not found and len(group) == len(eqGroup): for g, eg in zip(group, eqGroup): if not g.isIsomorphic(eg): # The groups do not match break else: # The groups match found = True if found: # We've found a matching group, so increment its count equivalentGroupCount[i] += 1 break else: # No matching group found, so add it as a new group equivalentGroups.append(group) equivalentGroupCount.append(1) # Find equivalent bonds on ring equivalentBonds = [] for i, atom1 in enumerate(ring0): for atom2 in ring0[i + 1 :]: if molecule.hasBond(atom1, atom2): bond = molecule.getBond(atom1, atom2) found = False for eqBond in equivalentBonds: if not found: if bond.equivalent(eqBond[0]): eqBond.append(group) found = True if not found: equivalentBonds.append([bond]) # Find maximum number of equivalent groups and bonds minEquivalentGroups = min(equivalentGroupCount) maxEquivalentGroups = max(equivalentGroupCount) minEquivalentBonds = None maxEquivalentBonds = 0 for bonds in equivalentBonds: N = len(bonds) if minEquivalentBonds is None or N < minEquivalentBonds: minEquivalentBonds = N if N > maxEquivalentBonds: maxEquivalentBonds = N if maxEquivalentGroups == maxEquivalentBonds == len(ring): symmetryNumber *= len(ring) * 2 else: symmetryNumber *= min(minEquivalentGroups, minEquivalentBonds) return symmetryNumber
def calculateCyclicSymmetryNumber(molecule): """ Get the symmetry number correction for cyclic regions of a molecule. For complicated fused rings the smallest set of smallest rings is used. """ from rdkit.Chem.rdmolops import SanitizeMol from rdkit.Chem.rdchem import Mol mcopy = molecule.toRDKitMol(removeHs=True, returnMapping=False) SanitizeMol(mcopy) symmetryNumber = 1 # Get symmetry number for each ring in structure rings = molecule.getSmallestSetOfSmallestRings() for ring0 in rings: # Make copy of structure structure = molecule.copy(True) ring = [structure.atoms[molecule.atoms.index(atom)] for atom in ring0] # Figure out which atoms and bonds are aromatic and reassign appropriately: for i, atom1 in enumerate(ring0): for atom2 in ring0[i + 1:]: if molecule.hasBond(atom1, atom2): if mcopy.GetBondBetweenAtoms(i, i + 1) is not None: if str( mcopy.GetBondBetweenAtoms( i, i + 1).GetBondType()) == 'AROMATIC': bond = molecule.getBond(atom1, atom2) bond.applyAction( ['CHANGE_BOND', atom1, 'B', atom2]) atom1.atomType = atom2.atomType = rmgpy.molecule.atomTypes[ 'Cb'] else: pass # Remove bonds of ring from structure for i, atom1 in enumerate(ring): for atom2 in ring[i + 1:]: if structure.hasBond(atom1, atom2): structure.removeBond(atom1.edges[atom2]) structures = structure.split() groups = [] for struct in structures: for atom in ring: if struct.hasAtom(atom): struct.removeAtom(atom) groups.append(struct.split()) # Find equivalent functional groups on ring equivalentGroups = [] equivalentGroupCount = [] for group in groups: found = False for i, eqGroup in enumerate(equivalentGroups): if not found and len(group) == len(eqGroup): for g, eg in zip(group, eqGroup): if not g.isIsomorphic(eg): # The groups do not match break else: # The groups match found = True if found: # We've found a matching group, so increment its count equivalentGroupCount[i] += 1 break else: # No matching group found, so add it as a new group equivalentGroups.append(group) equivalentGroupCount.append(1) # Find equivalent bonds on ring equivalentBonds = [] for i, atom1 in enumerate(ring0): for atom2 in ring0[i + 1:]: if molecule.hasBond(atom1, atom2): bond = molecule.getBond(atom1, atom2) found = False for eqBond in equivalentBonds: if not found: if bond.equivalent(eqBond[0]): eqBond.append(group) found = True if not found: equivalentBonds.append([bond]) # Find maximum number of equivalent groups and bonds minEquivalentGroups = min(equivalentGroupCount) maxEquivalentGroups = max(equivalentGroupCount) minEquivalentBonds = None maxEquivalentBonds = 0 for bonds in equivalentBonds: N = len(bonds) if minEquivalentBonds is None or N < minEquivalentBonds: minEquivalentBonds = N if N > maxEquivalentBonds: maxEquivalentBonds = N if maxEquivalentGroups == maxEquivalentBonds == len(ring): symmetryNumber *= len(ring) * 2 else: symmetryNumber *= min(minEquivalentGroups, minEquivalentBonds) #print len(ring), minEquivalentGroups, maxEquivalentGroups, minEquivalentBonds, maxEquivalentBonds, symmetryNumber return symmetryNumber
def calculateCyclicSymmetryNumber(molecule): """ Get the symmetry number correction for cyclic regions of a molecule. For complicated fused rings the smallest set of smallest rings is used. """ from rdkit.Chem.rdmolops import SanitizeMol from rdkit.Chem.rdchem import Mol mcopy = molecule.toRDKitMol(removeHs=True, returnMapping=False) SanitizeMol(mcopy) symmetryNumber = 1 # Get symmetry number for each ring in structure rings = molecule.getSmallestSetOfSmallestRings() for ring0 in rings: # Make copy of structure structure = molecule.copy(True) ring = [structure.atoms[molecule.atoms.index(atom)] for atom in ring0] # Figure out which atoms and bonds are aromatic and reassign appropriately: for i, atom1 in enumerate(ring0): for atom2 in ring0[i+1:]: if molecule.hasBond(atom1, atom2): if mcopy.GetBondBetweenAtoms(i,i+1) is not None: if str(mcopy.GetBondBetweenAtoms(i,i+1).GetBondType()) == 'AROMATIC': bond = molecule.getBond(atom1, atom2) bond.applyAction(['CHANGE_BOND', atom1, 'B', atom2]) atom1.atomType = atom2.atomType = rmgpy.molecule.atomTypes['Cb'] else: pass # Remove bonds of ring from structure for i, atom1 in enumerate(ring): for atom2 in ring[i+1:]: if structure.hasBond(atom1, atom2): structure.removeBond(atom1.edges[atom2]) structures = structure.split() groups = [] for struct in structures: for atom in ring: if struct.hasAtom(atom): struct.removeAtom(atom) groups.append(struct.split()) # Find equivalent functional groups on ring equivalentGroups = []; equivalentGroupCount = [] for group in groups: found = False for i, eqGroup in enumerate(equivalentGroups): if not found and len(group) == len(eqGroup): for g, eg in zip(group, eqGroup): if not g.isIsomorphic(eg): # The groups do not match break else: # The groups match found = True if found: # We've found a matching group, so increment its count equivalentGroupCount[i] += 1 break else: # No matching group found, so add it as a new group equivalentGroups.append(group) equivalentGroupCount.append(1) # Find equivalent bonds on ring equivalentBonds = [] for i, atom1 in enumerate(ring0): for atom2 in ring0[i+1:]: if molecule.hasBond(atom1, atom2): bond = molecule.getBond(atom1, atom2) found = False for eqBond in equivalentBonds: if not found: if bond.equivalent(eqBond[0]): eqBond.append(group) found = True if not found: equivalentBonds.append([bond]) # Find maximum number of equivalent groups and bonds minEquivalentGroups = min(equivalentGroupCount) maxEquivalentGroups = max(equivalentGroupCount) minEquivalentBonds = None maxEquivalentBonds = 0 for bonds in equivalentBonds: N = len(bonds) if minEquivalentBonds is None or N < minEquivalentBonds: minEquivalentBonds = N if N > maxEquivalentBonds: maxEquivalentBonds = N if maxEquivalentGroups == maxEquivalentBonds == len(ring): symmetryNumber *= len(ring) * 2 else: symmetryNumber *= min(minEquivalentGroups, minEquivalentBonds) #print len(ring), minEquivalentGroups, maxEquivalentGroups, minEquivalentBonds, maxEquivalentBonds, symmetryNumber return symmetryNumber
def calculateCyclicSymmetryNumber(molecule): """ Get the symmetry number correction for cyclic regions of a molecule. For complicated fused rings the smallest set of smallest rings is used. """ from rdkit.Chem.rdmolops import SanitizeMol from rdkit.Chem.rdchem import Mol symmetryNumber = 1 rings = molecule.getSmallestSetOfSmallestRings() # Get symmetry number for each ring in structure for ring0 in rings: # Make another copy structure structure = molecule.copy(True) ring = [structure.atoms[molecule.atoms.index(atom)] for atom in ring0] # Remove bonds of ring from structure for i, atom1 in enumerate(ring): for atom2 in ring[i + 1:]: if structure.hasBond(atom1, atom2): structure.removeBond(atom1.edges[atom2]) structures = structure.split() groups = [] for struct in structures: for atom in ring: if struct.hasAtom(atom): struct.removeAtom(atom) groups.append(struct.split()) # Find equivalent functional groups on ring equivalentGroups = [] equivalentGroupCount = [] for group in groups: found = False for i, eqGroup in enumerate(equivalentGroups): if not found and len(group) == len(eqGroup): for g, eg in zip(group, eqGroup): if not g.isIsomorphic(eg): # The groups do not match break else: # The groups match found = True if found: # We've found a matching group, so increment its count equivalentGroupCount[i] += 1 break else: # No matching group found, so add it as a new group equivalentGroups.append(group) equivalentGroupCount.append(1) # Find equivalent bonds on ring equivalentBonds = [] for i, atom1 in enumerate(ring0): for atom2 in ring0[i + 1:]: if molecule.hasBond(atom1, atom2): bond = molecule.getBond(atom1, atom2) found = False for eqBond in equivalentBonds: if not found: if bond.equivalent(eqBond[0]): eqBond.append(group) found = True if not found: equivalentBonds.append([bond]) # Find maximum number of equivalent groups and bonds minEquivalentGroups = min(equivalentGroupCount) maxEquivalentGroups = max(equivalentGroupCount) minEquivalentBonds = None maxEquivalentBonds = 0 for bonds in equivalentBonds: N = len(bonds) if minEquivalentBonds is None or N < minEquivalentBonds: minEquivalentBonds = N if N > maxEquivalentBonds: maxEquivalentBonds = N if maxEquivalentGroups == maxEquivalentBonds == len(ring): symmetryNumber *= len(ring) * 2 else: symmetryNumber *= min(minEquivalentGroups, minEquivalentBonds) return symmetryNumber