Example #1
0
    def add_image(self, complex):
        complex.thumbnail = tempfile.NamedTemporaryFile(
            delete=False, suffix='.png', dir=self.temp_dir.name).name
        complex.image = tempfile.NamedTemporaryFile(
            delete=False, suffix='.png', dir=self.temp_dir.name).name

        mol = complex.rdmol
        Chem.AssignStereochemistryFrom3D(mol)
        Chem.rdCoordGen.AddCoords(mol)
        mol = Draw.rdMolDraw2D.PrepareMolForDrawing(mol)

        drawer = Draw.rdMolDraw2D.MolDraw2DSVG(256, 192)
        drawer.drawOptions().additionalAtomLabelPadding = 0.3
        drawer.DrawMolecule(mol)
        drawer.FinishDrawing()
        svg = drawer.GetDrawingText()
        svg = svg.replace('stroke-linecap:butt', 'stroke-linecap:round')

        svg2png(bytestring=svg,
                write_to=complex.thumbnail,
                output_width=256,
                output_height=192)
        svg2png(bytestring=svg,
                write_to=complex.image,
                output_width=1024,
                output_height=768)
Example #2
0
    def file_to_rdkit_mol(file_path: Path) -> Chem.Mol:
        """
        Args:
            file_path:
                Path of the file used to generate the rdkit molecule.
        return:
            RDKit molecule object generated from its file (or None if incorrect file type is provided).
        """

        # Read the file
        if file_path.suffix == ".pdb":
            mol = Chem.MolFromPDBFile(file_path.as_posix(),
                                      removeHs=False,
                                      sanitize=False)
        elif file_path.suffix == ".mol2":
            mol = Chem.MolFromMol2File(file_path.as_posix(),
                                       removeHs=False,
                                       sanitize=False)
        elif file_path.suffix == ".mol" or file_path.suffix == ".sdf":
            mol = Chem.MolFromMolFile(file_path.as_posix(),
                                      removeHs=False,
                                      sanitize=False,
                                      strictParsing=True)
        else:
            raise FileTypeError(
                f"The file type {file_path.suffix} is not supported.")
        # run some sanitation
        Chem.SanitizeMol(
            mol,
            (Chem.SANITIZE_ALL ^ Chem.SANITIZE_SETAROMATICITY
             ^ Chem.SANITIZE_ADJUSTHS),
        )
        Chem.SetAromaticity(mol, Chem.AromaticityModel.AROMATICITY_MDL)
        Chem.AssignStereochemistryFrom3D(mol)

        # set the name of the input file
        mol.SetProp("_Name", file_path.stem)

        return mol
Example #3
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
Example #4
0
    def cap_unit(self, unit, n_neighbors=3):
        indices = sorted(unit.atoms.indices)
        capped = Chem.rdchem.RWMol()
        n_indices = len(indices)
        if not n_indices:
            return capped
        neighbor_ints = rdutils.get_neighbor_ints(self.rdmol, indices,
                                                  n_neighbors)
        new_conf = Chem.rdchem.Conformer(n_indices + len(neighbor_ints))
        conf = self.rdmol.GetConformer(0)
        only_on_atoms = []

        # add unit atoms
        indices = list(map(int, indices))
        for ix in indices:
            at = self.rdmol.GetAtomWithIdx(ix)
            new = capped.AddAtom(at)
            new_conf.SetAtomPosition(new, list(conf.GetAtomPosition(ix)))

        # add neighbor atoms with AltLoc "+"

        for ix in neighbor_ints:
            at = self.rdmol.GetAtomWithIdx(ix)

            new = capped.AddAtom(at)
            at = capped.GetAtomWithIdx(new)
            old_info = at.GetPDBResidueInfo()
            info = rdutils.copy_pdbinfo(old_info)
            # info.SetAltLoc("+")
            at.SetMonomerInfo(info)
            at.SetNoImplicit(False)
            new_conf.SetAtomPosition(new, list(conf.GetAtomPosition(ix)))
            only_on_atoms.append(new)

        # add bonds
        all_ints = indices + neighbor_ints
        # things RDKit complains about: np.uint,  np.uint32, np.uintp, np.uintc
        # capped_ints = np.arange(len(all_ints), dtype=np.uintc)
        capped_ints = list(map(int, range(len(all_ints))))  # omg
        for i, j in itertools.combinations(capped_ints, 2):
            bond = self.rdmol.GetBondBetweenAtoms(all_ints[i], all_ints[j])
            if bond is not None:
                capped.AddBond(i, j, bond.GetBondType())

        capped.AddConformer(new_conf)
        # add Hs
        Chem.SanitizeMol(
            capped,
            (Chem.SANITIZE_ALL ^ Chem.SANITIZE_SETAROMATICITY
             ^ Chem.SANITIZE_ADJUSTHS ^ Chem.SANITIZE_CLEANUPCHIRALITY
             ^ Chem.SANITIZE_KEKULIZE),
        )
        hcapped = Chem.AddHs(capped,
                             explicitOnly=False,
                             addCoords=True,
                             onlyOnAtoms=only_on_atoms)
        # info_template = hcapped.GetAtomWithIdx(0).GetPDBResidueInfo()
        # for i in range(capped_ints[-1], hcapped.GetNumAtoms()):
        #     at = hcapped.GetAtomWithIdx(i)
        #     new_info = rdutils.copy_pdbinfo(info_template)
        #     new_info.SetName("H")
        #     new_info.SetAltLoc("-")
        #     at.SetMonomerInfo(new_info)

        # Chem.AssignStereochemistry(hcapped)
        # Chem.SanitizeMol(hcapped)
        # Chem.SanitizeMol(hcapped,
        #     (
        #         Chem.SANITIZE_ALL
        #         ^ Chem.SANITIZE_SETAROMATICITY
        #         ^ Chem.SANITIZE_ADJUSTHS
        #         ^ Chem.SANITIZE_CLEANUPCHIRALITY
        #         ^ Chem.SANITIZE_KEKULIZE
        #     ),)

        Chem.AssignStereochemistryFrom3D(hcapped, 0)
        return hcapped
Example #5
0
def assign_stereochemistry(rdmol):
    if rdmol.GetNumConformers():
        Chem.AssignStereochemistryFrom3D(rdmol)
    else:
        Chem.AssignStereochemistry(rdmol, cleanIt=True)