示例#1
0
文件: symmetry.py 项目: alongd/RMG-Py
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
示例#2
0
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
示例#3
0
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
示例#4
0
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