Example #1
0
 def decode(self, matrix):
     frags, smiles = [], []
     for m, adj in enumerate(matrix):
         # print('decode: ', m)
         emol = Chem.RWMol()
         esub = Chem.RWMol()
         try:
             for atom, curr, prev, bond, frag in adj:
                 atom, curr, prev, bond, frag = int(atom), int(curr), int(
                     prev), int(bond), int(frag)
                 if atom == self.tk2ix['EOS']: continue
                 if atom == self.tk2ix['GO']: continue
                 if atom != self.tk2ix['*']:
                     a = Chem.Atom(self.ix2nr[atom])
                     a.SetFormalCharge(self.ix2ch[atom])
                     emol.AddAtom(a)
                     if frag != 0: esub.AddAtom(a)
                 if bond != 0:
                     b = Chem.BondType(bond)
                     emol.AddBond(curr, prev, b)
                     if frag != 0: esub.AddBond(curr, prev, b)
             Chem.SanitizeMol(emol)
             Chem.SanitizeMol(esub)
         except Exception as e:
             print(adj)
             # raise e
         frags.append(Chem.MolToSmiles(esub))
         smiles.append(Chem.MolToSmiles(emol))
     return frags, smiles
Example #2
0
  def assertBondStereoRoundTrips(self, fname):
    path = os.path.join(RDConfig.RDCodeDir, 'Chem', 'test_data', fname)
    mol = Chem.MolFromMolFile(path)
    refSmiles = mol.GetProp("_Name")
    self.assertTrue(len(refSmiles) > 0)
    self.assertEqual(Chem.MolToSmiles(mol, isomericSmiles=True), refSmiles)

    # now test Chem.DetectBondStereoChemistry more directly by constructing the molecule from scratch
    oldconf = mol.GetConformer(0)
    newconf = Chem.Conformer(mol.GetNumAtoms())
    newmol = Chem.RWMol()

    for atm in mol.GetAtoms():
        ratm = Chem.Atom(atm.GetAtomicNum())
        ratm.SetFormalCharge(atm.GetFormalCharge())
        newmol.AddAtom(ratm)

        atomidx = atm.GetIdx()
        pos = oldconf.GetAtomPosition(atomidx)
        newconf.SetAtomPosition(atomidx, pos)

    for bnd in mol.GetBonds():
        newmol.AddBond(bnd.GetBeginAtomIdx(), bnd.GetEndAtomIdx(), Chem.BondType(bnd.GetBondType()))
    newmol.AddConformer(newconf)

    Chem.SanitizeMol(newmol)
    Chem.DetectBondStereoChemistry(newmol, newmol.GetConformer())

    # these aren't necessary for this specific test case, but are for
    # a more general conversion routine, so would like to see them
    # tested eventually
    # Chem.AssignAtomChiralTagsFromStructure(newmol)
    # Chem.AssignStereochemistry(newmol)

    self.assertEqual(Chem.MolToSmiles(newmol, isomericSmiles=True), refSmiles)
Example #3
0
def to_rdmol(plams_mol, sanitize=True):
    """
    Translate a PLAMS molecule into an RDKit molecule type
    """
    # Create rdkit molecule
    e = Chem.EditableMol(Chem.Mol())
    for atom in plams_mol.atoms:
        a = Chem.Atom(atom.atnum)
        ch = atom.properties.charge
        if isinstance(ch, int):
            a.SetFormalCharge(ch)
        e.AddAtom(a)
    for bond in plams_mol.bonds:
        a1 = plams_mol.atoms.index(bond.atom1)
        a2 = plams_mol.atoms.index(bond.atom2)
        e.AddBond(a1, a2, Chem.BondType(bond.order))
    rdmol = e.GetMol()
    if sanitize:
        Chem.SanitizeMol(rdmol)
    conf = Chem.Conformer()
    for a in range(len(plams_mol.atoms)):
        atom = plams_mol.atoms[a]
        p = Geometry.Point3D(atom._getx(), atom._gety(), atom._getz())
        conf.SetAtomPosition(a, p)
    rdmol.AddConformer(conf)
    return rdmol
 def _prevent_allene(self, mol: Chem.Mol) -> Chem.Mol:
     if not isinstance(mol, Chem.RWMol):
         mol = Chem.RWMol(mol)
     for atom in mol.GetAtoms():
         if atom.GetAtomicNum() < 14:
             n = []
             for bond in atom.GetBonds():
                 if bond.GetBondType().name in ('DOUBLE', 'TRIPLE'):
                     n.append(bond)
                 else:
                     pass
             if len(n) > 2:
                 #this is a mess!
                 log.info(f'Allene issue: {n} double bonds on {atom.GetSymbol()} atom {atom.GetIdx()}!')
                 for bond in n:
                     bond.SetBondType(Chem.BondType().SINGLE)
             elif len(n) == 2:
                 # downgrade the higher bonded one!
                 others = [a for bond in n for a in (bond.GetBeginAtom(), bond.GetEndAtom()) if a.GetIdx() != atom.GetIdx()]
                 others = sorted(others, key=lambda atom: sum([b.GetBondTypeAsDouble() for b in atom.GetBonds()]))
                 log.info(f'Allene removed between {atom.GetIdx()} and {[a.GetIdx() for a in others]}')
                 mol.GetBondBetweenAtoms(atom.GetIdx(), others[-1].GetIdx()).SetBondType(Chem.BondType.SINGLE)
             else:
                 pass
         else:
             continue
     return mol
Example #5
0
def to_rdmol(plams_mol, sanitize=True):
    """
    Translate a PLAMS molecule into an RDKit molecule type.

    :parameter plams_mol: PLAMS molecule
    :type plams_mol: plams.Molecule
    :return: an RDKit molecule
    :rtype: rdkit.Chem.Mol

    """
    if isinstance(plams_mol, Chem.Mol):
        return plams_mol
    # Create rdkit molecule
    e = Chem.EditableMol(Chem.Mol())
    for atom in plams_mol.atoms:
        a = Chem.Atom(atom.atnum)
        if 'charge' in atom.properties:
            a.SetFormalCharge(atom.properties.charge)
        if 'pdb_info' in atom.properties:
            set_PDBresidueInfo(a, atom.properties.pdb_info)
        e.AddAtom(a)
    for bond in plams_mol.bonds:
        a1 = plams_mol.atoms.index(bond.atom1)
        a2 = plams_mol.atoms.index(bond.atom2)
        e.AddBond(a1, a2, Chem.BondType(bond.order))
    rdmol = e.GetMol()
    if sanitize:
        Chem.SanitizeMol(rdmol)
    conf = Chem.Conformer()
    for a in range(len(plams_mol.atoms)):
        atom = plams_mol.atoms[a]
        p = Geometry.Point3D(atom._getx(), atom._gety(), atom._getz())
        conf.SetAtomPosition(a, p)
    rdmol.AddConformer(conf)
    return rdmol
 def getbondtype(self,bondtype):
     if bondtype.GetBondType().__str__() == 'SINGLE':
         return Chem.BondType().DOUBLE
     elif bondtype.GetBondType().__str__() == 'DOUBLE':
         return Chem.BondType().TRIPLE
     elif bondtype.GetBondType().__str__() == 'TRIPLE':
         return Chem.BondType().QUADRUPLE
     elif bondtype.GetBondType().__str__() == 'QUADRUPLE':
         return Chem.BondType().QUINTUPLE
     elif bondtype.GetBondType().__str__() == 'QUINTUPLE':
         raise ReactionQueryError('BondIncrease: Increasing bond order above quintuple bond is not supported')
     elif bondtype.GetBondType().__str__() == 'AROMATIC':
         raise ReactionQueryError('BondIncrease: Increasing bond order of aromatic bond is not supported')
     elif bondtype.GetBondType().__str__() == 'DATIVE':
         raise ReactionQueryError('BondIncrease: Increasing bond order of partial bond is not supported')
     else:
         raise ReactionQueryError("BondDecrease: Unsupported bond type:'"+bondtype.GetBondType().__str__()+"'")
Example #7
0
 def convertSMILES(self, atoms, bonds):
     """Convert atoms and bonds information to SMILES."""
     m = Chem.RWMol(Chem.MolFromSmiles(''))
     d = {}
     for name, number in zip(self.atomnames[atoms], atoms):
         d[number] = m.AddAtom(Chem.Atom(name))
     for atom1, atom2, level in bonds:
         m.AddBond(d[atom1], d[atom2], Chem.BondType(level))
     name = Chem.MolToSmiles(m)
     return name
Example #8
0
def to_rdmol(plams_mol, sanitize=True, properties=True):
    """
    Translate a PLAMS molecule into an RDKit molecule type.
    PLAMS |Molecule|, |Atom| or |Bond| properties are pickled if they are neither booleans, floats,
    integers, floats nor strings, the resulting property names are appended with '_pickled'.

    :parameter plams_mol: A PLAMS molecule
    :parameter bool sanitize: Kekulize, check valencies, set aromaticity, conjugation and hybridization
    :parameter bool properties: If all |Molecule|, |Atom| and |Bond| properties should be converted from PLAMS to RDKit format.
    :type plams_mol: |Molecule|
    :return: an RDKit molecule
    :rtype: rdkit.Chem.Mol
    """
    if isinstance(plams_mol, Chem.Mol):
        return plams_mol
    # Create rdkit molecule
    e = Chem.EditableMol(Chem.Mol())
    for atom in plams_mol.atoms:
        a = Chem.Atom(atom.atnum)
        if 'charge' in atom.properties:
            a.SetFormalCharge(atom.properties.charge)
        if properties:
            if 'pdb_info' in atom.properties:
                set_PDBresidueInfo(a, atom.properties.pdb_info)
            for prop in atom.properties:
                if prop != 'charge' or prop != 'pdb_info':
                    prop_to_rdmol(atom, a, prop)
        e.AddAtom(a)
    for bond in plams_mol.bonds:
        a1 = plams_mol.atoms.index(bond.atom1)
        a2 = plams_mol.atoms.index(bond.atom2)
        e.AddBond(a1, a2, Chem.BondType(bond.order))
    rdmol = e.GetMol()
    if properties:
        for pl_bond, rd_bond in zip(plams_mol.bonds, rdmol.GetBonds()):
            for prop in pl_bond.properties:
                prop_to_rdmol(pl_bond, rd_bond, prop)
        for prop in plams_mol.properties:
            prop_to_rdmol(plams_mol, rdmol, prop)
    if sanitize:
        Chem.SanitizeMol(rdmol)
    conf = Chem.Conformer()
    for a in range(len(plams_mol.atoms)):
        atom = plams_mol.atoms[a]
        p = Geometry.Point3D(atom._getx(), atom._gety(), atom._getz())
        conf.SetAtomPosition(a, p)
    rdmol.AddConformer(conf)
    return rdmol
Example #9
0
File: rdkit.py Project: BvB93/PLAMS
def to_rdmol(plams_mol, sanitize=True, properties=True, assignChirality=False):
    """
    Translate a PLAMS molecule into an RDKit molecule type.
    PLAMS |Molecule|, |Atom| or |Bond| properties are pickled if they are neither booleans, floats,
    integers, floats nor strings, the resulting property names are appended with '_pickled'.

    :parameter plams_mol: A PLAMS molecule
    :parameter bool sanitize: Kekulize, check valencies, set aromaticity, conjugation and hybridization
    :parameter bool properties: If all |Molecule|, |Atom| and |Bond| properties should be converted from PLAMS to RDKit format.
    :parameter bool assignChirality: Assign R/S and cis/trans information, insofar as this was not yet present in the PLAMS molecule.
    :type plams_mol: |Molecule|
    :return: an RDKit molecule
    :rtype: rdkit.Chem.Mol
    """
    if isinstance(plams_mol, Chem.Mol):
        return plams_mol
    # Create rdkit molecule
    e = Chem.EditableMol(Chem.Mol())

    # Add atoms and assign properties to the RDKit atom if *properties* = True
    for pl_atom in plams_mol.atoms:
        rd_atom = Chem.Atom(pl_atom.atnum)
        if 'charge' in pl_atom.properties:
            rd_atom.SetFormalCharge(pl_atom.properties.charge)
        if properties:
            if 'pdb_info' in pl_atom.properties:
                set_PDBresidueInfo(rd_atom, pl_atom.properties.pdb_info)
            for prop in pl_atom.properties:
                if prop not in ('charge', 'pdb_info', 'stereo'):
                    prop_to_rdmol(pl_atom, rd_atom, prop)

        # Check for R/S information
        if pl_atom.properties.stereo:
            stereo = pl_atom.properties.stereo.lower()
            if stereo == 'counter-clockwise':
                rd_atom.SetChiralTag(
                    Chem.rdchem.ChiralType.CHI_TETRAHEDRAL_CCW)
            elif stereo == 'clockwise':
                rd_atom.SetChiralTag(Chem.rdchem.ChiralType.CHI_TETRAHEDRAL_CW)
        e.AddAtom(rd_atom)

    # Mapping of PLAMS bond orders to RDKit bond types:
    def plams_to_rd_bonds(bo):
        if bo > 1.4 and bo < 1.6:
            return 12  # bond type for aromatic bond
        else:
            return int(bo)

    # Add bonds to the RDKit molecule
    for bond in plams_mol.bonds:
        a1 = plams_mol.atoms.index(bond.atom1)
        a2 = plams_mol.atoms.index(bond.atom2)
        e.AddBond(a1, a2, Chem.BondType(plams_to_rd_bonds(bond.order)))
    rdmol = e.GetMol()

    # Check for cis/trans information
    for pl_bond, rd_bond in zip(plams_mol.bonds, rdmol.GetBonds()):
        if pl_bond.properties.stereo:
            stereo = pl_bond.properties.stereo.lower()
            if stereo == 'e' or stereo == 'trans':
                rd_bond.SetStereo(Chem.rdchem.BondStereo.STEREOE)
            elif stereo == 'z' or stereo == 'cis':
                rd_bond.SetStereo(Chem.rdchem.BondStereo.STEREOZ)
            elif stereo == 'up':
                rd_bond.SetBondDir(Chem.rdchem.BondDir.ENDUPRIGHT)
            elif stereo == 'down':
                rd_bond.SetBondDir(Chem.rdchem.BondDir.ENDDOWNRIGHT)

    # Assign properties to RDKit molecule and bonds if *properties* = True
    if properties:
        for prop in plams_mol.properties:
            prop_to_rdmol(plams_mol, rdmol, prop)
        for pl_bond, rd_bond in zip(plams_mol.bonds, rdmol.GetBonds()):
            for prop in pl_bond.properties:
                if prop != 'stereo':
                    prop_to_rdmol(pl_bond, rd_bond, prop)

    if sanitize:
        Chem.SanitizeMol(rdmol)
    conf = Chem.Conformer()
    for i, atom in enumerate(plams_mol.atoms):
        xyz = Geometry.Point3D(atom._getx(), atom._gety(), atom._getz())
        conf.SetAtomPosition(i, xyz)
    rdmol.AddConformer(conf)
    # REB: Assign all stereochemistry, if it wasn't already there
    if assignChirality:
        Chem.rdmolops.AssignAtomChiralTagsFromStructure(
            rdmol, confId=conf.GetId(), replaceExistingTags=False)
        try:
            Chem.AssignStereochemistryFrom3D(rdmol,
                                             confId=conf.GetId(),
                                             replaceExistingTags=False)
        except AttributeError:
            pass
    return rdmol