Esempio n. 1
0
def create_box_receptor(
    protein: oechem.OEGraphMol,
    box_dimensions: Tuple[float, float, float, float, float, float],
) -> oechem.OEGraphMol:
    """
    Create a box receptor for docking.
    Parameters
    ----------
    protein: oechem.OEGraphMol
        An OpenEye molecule holding a prepared protein structure.
    box_dimensions: tuple of float
        The box dimensions in the order of xmax, ymax, zmax, xmin, ymin, zmin.
    Returns
    -------
    receptor: oechem.OEGraphMol
        An OpenEye molecule holding a receptor with defined binding site via box dimensions.
    """
    from openeye import oedocking

    # create receptor
    box = oedocking.OEBox(*box_dimensions)
    receptor = oechem.OEGraphMol()
    oedocking.OEMakeReceptor(receptor, protein, box)

    return receptor
Esempio n. 2
0
def main(argv=[__name__]):
    path = "receptor_pdbs/*.pdb"  #input: pdbs from clustering
    files = glob.glob(path)
    for i in files:
        centroid_number = i[-5:-4]
        imstr = oechem.oemolistream(i)
        proteinStructure = oechem.OEGraphMol()
        oechem.OEReadMolecule(imstr, proteinStructure)
        coordinates_dictionary = oechem.OEMolBase.GetCoords(proteinStructure)
        x_coord = []
        y_coord = []
        z_coord = []
        for key in coordinates_dictionary:
            x = coordinates_dictionary[key][0]
            y = coordinates_dictionary[key][1]
            z = coordinates_dictionary[key][2]
            x_coord.append(x)
            y_coord.append(y)
            z_coord.append(z)
        x_max = max(x_coord)
        x_min = min(x_coord)
        y_max = max(y_coord)
        y_min = min(y_coord)
        z_max = max(z_coord)
        z_min = min(z_coord)
        box = oedocking.OEBox(
            x_max, y_max, z_max, x_min, y_min,
            z_min)  #Box set using max and min coordinates of entire protein
        receptor = oechem.OEGraphMol()
        oedocking.OEMakeReceptor(receptor, proteinStructure, box)
        oedocking.OEWriteReceptorFile(receptor, "receptor_oebs/receptor" +
                                      str(centroid_number) +
                                      ".oeb")  #output: receptor oebs
    return 0
Esempio n. 3
0
def create_hint_receptor(
    protein: oechem.OEGraphMol,
    hintx: Union[float, int],
    hinty: Union[float, int],
    hintz: Union[float, int],
) -> oechem.OEGraphMol:
    """
    Create a hint receptor for docking.
    Parameters
    ----------
    protein: oechem.OEGraphMol
        An OpenEye molecule holding a prepared protein structure.
    hintx: float or int
        A number defining the hint x coordinate.
    hinty: float or int
        A number defining the hint y coordinate.
    hintz: float or int
        A number defining the hint z coordinate.
    Returns
    -------
    receptor: oechem.OEGraphMol
        An OpenEye molecule holding a receptor with defined binding site via hint coordinates.
    """
    from openeye import oedocking

    # create receptor
    receptor = oechem.OEGraphMol()
    oedocking.OEMakeReceptor(receptor, protein, hintx, hinty, hintz)

    return receptor
Esempio n. 4
0
def create_bound_receptor(protein_pdb_path, ligand_file_path):
    """Create an OpenEye receptor from a PDB file and ligand file.

    Parameters
    ----------
    protein_pdb_path : str
        Path to the receptor PDB file.
    ligand_file_path : str
        Path to the ligand file (e.g. Tripos mol2).
        Can be any file format supported by openeye.
    Returns
    -------
    receptor : openeye.oedocking.OEReceptor
        The OpenEye receptor object
    """
    from openeye import oechem, oedocking

    # Load in protein
    input_mol_stream = oechem.oemolistream(protein_pdb_path)
    protein_oemol = oechem.OEGraphMol()
    oechem.OEReadMolecule(input_mol_stream, protein_oemol)

    # Load in ligand
    input_mol_stream = oechem.oemolistream(ligand_file_path)
    ligand_oemol = oechem.OEGraphMol()
    oechem.OEReadMolecule(input_mol_stream, ligand_oemol)

    receptor = oechem.OEGraphMol()
    oedocking.OEMakeReceptor(receptor, protein_oemol, ligand_oemol)

    return receptor
Esempio n. 5
0
    def _create_receptor(self):
        """Create an OpenEye receptor from a mol2 file.

        Returns
        -------
        openeye.oedocking.OEReceptor
            The OpenEye receptor object.
        """
        from openeye import oechem, oedocking

        input_stream = oechem.oemolistream(self.receptor_coordinate_file)

        original_receptor_molecule = oechem.OEGraphMol()
        oechem.OEReadMolecule(input_stream, original_receptor_molecule)

        center_of_mass = oechem.OEFloatArray(3)
        oechem.OEGetCenterOfMass(original_receptor_molecule, center_of_mass)

        receptor = oechem.OEGraphMol()
        oedocking.OEMakeReceptor(
            receptor,
            original_receptor_molecule,
            center_of_mass[0],
            center_of_mass[1],
            center_of_mass[2],
        )

        return receptor
Esempio n. 6
0
def create_receptor(protein_pdb_path, box):
    """Create an OpenEye receptor from a PDB file.

    Parameters
    ----------
    protein_pdb_path : str
        Path to the receptor PDB file.
    box : 1x6 array of float
        The minimum and maximum values of the coordinates of the box
        representing the binding site [xmin, ymin, zmin, xmax, ymax, zmax].

    Returns
    -------
    receptor : openeye.oedocking.OEReceptor
        The OpenEye receptor object.

    """
    input_mol_stream = oechem.oemolistream(protein_pdb_path)
    protein_oemol = oechem.OEGraphMol()
    oechem.OEReadMolecule(input_mol_stream, protein_oemol)

    box = oedocking.OEBox(*box)
    receptor = oechem.OEGraphMol()
    oedocking.OEMakeReceptor(receptor, protein_oemol, box)

    return receptor
Esempio n. 7
0
def prepare_receptor(complex_pdb_filename, prefix):
    # Read the receptor and identify design units
    from openeye import oespruce, oechem
    complex = read_pdb_file(complex_pdb_filename)
    print('Identifying design units...')
    design_units = list(oespruce.OEMakeDesignUnits(complex))
    for i, design_unit in enumerate(design_units):
        filename = f'DU_{i}.oedu'
        print(f'Writing design unit {i} to {filename}')
        oechem.OEWriteDesignUnit(filename, design_unit)
    if len(design_units) > 1:
        print('More than one design unit found---using first one')
        design_unit = design_units[0]

    # Prepare the receptor
    print('Preparing receptor...')
    from openeye import oedocking
    protein = oechem.OEGraphMol()
    design_unit.GetProtein(protein)
    ligand = oechem.OEGraphMol()
    design_unit.GetLigand(ligand)
    receptor = oechem.OEGraphMol()
    oedocking.OEMakeReceptor(receptor, protein, ligand)
    oedocking.OEWriteReceptorFile(receptor, f'{prefix}-receptor.oeb.gz')

    with oechem.oemolostream(f'{prefix}-protein.pdb') as ofs:
        oechem.OEWriteMolecule(ofs, protein)
    with oechem.oemolostream(f'{prefix}-ligand.mol2') as ofs:
        oechem.OEWriteMolecule(ofs, ligand)
    with oechem.oemolostream(f'{prefix}-ligand.pdb') as ofs:
        oechem.OEWriteMolecule(ofs, ligand)
    with oechem.oemolostream(f'{prefix}-ligand.sdf') as ofs:
        oechem.OEWriteMolecule(ofs, ligand)
Esempio n. 8
0
def create_box_receptor(protein,
                        xmax,
                        ymax,
                        zmax,
                        xmin,
                        ymin,
                        zmin,
                        receptor_save_path=None):
    """
    Create a box receptor for docking.

    Parameters
    ----------
    protein: oechem.OEGraphMol
        An oechem.OEGraphMol object holding a prepared protein structure.

    xmax: float or int
        Maximal number in x direction.

    ymax: float or int
        Maximal number in y direction.

    zmax: float or int
        Maximal number in z direction.

    xmin: float or int
        Minimal number in x direction.

    ymin: float or int
        Minimal number in x direction.

    zmin: float or int
        Minimal number in z direction.

    receptor_save_path: str
        File path for saving created receptor. If receptor_save_path is not provided, receptor will not be saved.

    Returns
    -------
    receptor: oechem.OEGraphMol
        An oechem.OEGraphMol object holding a receptor with defined binding site via box dimensions.
    """
    # Standard libraries
    import pathlib

    # External libraries
    from openeye import oechem, oedocking

    # create receptor
    box = oedocking.OEBox(xmax, ymax, zmax, xmin, ymin, zmin)
    receptor = oechem.OEGraphMol()
    oedocking.OEMakeReceptor(receptor, protein, box)

    # save receptor
    if receptor_save_path is not None:
        oedocking.OEWriteReceptorFile(
            receptor, str(pathlib.Path(receptor_save_path).absolute()))

    return receptor
Esempio n. 9
0
def make_docking_system(design_unit: oechem.OEDesignUnit) -> DockingSystem:
    protein = oechem.OEGraphMol()
    design_unit.GetProtein(protein)

    ligand = oechem.OEGraphMol()
    design_unit.GetLigand(ligand)

    receptor = oechem.OEGraphMol()
    oedocking.OEMakeReceptor(receptor, protein, ligand)

    system = DockingSystem(protein=protein, ligand=ligand, receptor=receptor)
    return system
Esempio n. 10
0
def create_receptor(output_name, pdb_file, bp_min, bp_max):
    check_oeb = output_name
    proteinStructure = oechem.OEGraphMol()
    ifs = oechem.oemolistream(pdb_file)
    ifs.SetFormat(oechem.OEFormat_PDB)
    oechem.OEReadMolecule(ifs, proteinStructure)

    box = oedocking.OEBox(*bp_max, *bp_min)

    receptor = oechem.OEGraphMol()
    s = oedocking.OEMakeReceptor(receptor, proteinStructure, box)
    oedocking.OEWriteReceptorFile(receptor, check_oeb)
Esempio n. 11
0
    def __init__(self, pdb_file, xmax, ymax, zmax, xmin, ymin, zmin):
        self.receptor = oechem.OEGraphMol()
        self.scorers = oedocking.OEScore(oedocking.OEScoreType_Chemgauss4)

        proteinStructure = oechem.OEGraphMol()
        ifs = oechem.oemolistream(pdb_file)
        ifs.SetFormat(oechem.OEFormat_PDB)
        oechem.OEReadMolecule(ifs, proteinStructure)

        box = oedocking.OEBox(xmax, ymax, zmax, xmin, ymin, zmin)

        receptor = oechem.OEGraphMol()
        s = oedocking.OEMakeReceptor(receptor, proteinStructure, box)
        self.scorers.Initialize(receptor)
Esempio n. 12
0
def create_hint_receptor(protein,
                         hintx,
                         hinty,
                         hintz,
                         receptor_save_path=None):
    """
    Create a hint receptor for docking.

    Parameters
    ----------
    protein: oechem.OEGraphMol
        An oechem.OEGraphMol object holding a prepared protein structure.

    hintx: float or int
        A number defining the hint x coordinate.

    hinty: float or int
        A number defining the hint y coordinate.

    hintz: float or int
        A number defining the hint z coordinate.

    receptor_save_path: str
        File path for saving created receptor. If receptor_save_path is not provided, receptor will not be saved.

    Returns
    -------
    receptor: oechem.OEGraphMol
        An oechem.OEGraphMol object holding a receptor with defined binding site via hint coordinates.
    """
    # Standard libraries
    import pathlib

    # External libraries
    from openeye import oechem, oedocking

    # create receptor
    receptor = oechem.OEGraphMol()
    oedocking.OEMakeReceptor(receptor, protein, hintx, hinty, hintz)

    # save receptor
    if receptor_save_path is not None:
        oedocking.OEWriteReceptorFile(
            receptor, str(pathlib.Path(receptor_save_path).absolute()))

    return receptor
def main(argv=[__name__]):
    if len(sys.argv) != 5:
        oechem.OEThrow.Usage(
            "MakeReceptorWithHintXYZ.py <protein> <hint x> <hint y> <hint z>")

    # @ <SNIPPET-MAKE-RECEPTOR-WITH-HINT-XYZ-1>
    protein = oechem.OEGraphMol()
    imstr = oechem.oemolistream(sys.argv[1])
    oechem.OEReadMolecule(imstr, protein)

    hintX = float(sys.argv[2])
    hintY = float(sys.argv[3])
    hintZ = float(sys.argv[4])

    receptor = oechem.OEGraphMol()
    oedocking.OEMakeReceptor(receptor, protein, hintX, hintY, hintZ)
    # @ </SNIPPET-MAKE-RECEPTOR-WITH-HINT-XYZ-1>

    oedocking.OEWriteReceptorFile(receptor, "receptor.oeb.gz")
Esempio n. 14
0
def main(argv):
    if len(argv) != 3:
        oechem.OEThrow.Usage(
            "MakeReceptorWithLigand.py <protein> <bound ligand>")

    proteinMolStream = oechem.oemolistream(argv[1])
    ligandMolStream = oechem.oemolistream(argv[2])

    # @ <SNIPPET-MAKE-RECEPTOR-WITH-LIGAND-1>
    protein = oechem.OEGraphMol()
    oechem.OEReadMolecule(proteinMolStream, protein)

    ligand = oechem.OEGraphMol()
    oechem.OEReadMolecule(ligandMolStream, ligand)

    receptor = oechem.OEGraphMol()
    oedocking.OEMakeReceptor(receptor, protein, ligand)
    # @ </SNIPPET-MAKE-RECEPTOR-WITH-LIGAND-1>

    oedocking.OEWriteReceptorFile(receptor, "receptor.oeb.gz")
Esempio n. 15
0
    def __init__(self, pdb_file, xmax, ymax, zmax, xmin, ymin, zmin):
        self.receptor = oechem.OEGraphMol()
        self.scorers = {
            'Shapegauss': oedocking.OEScore(oedocking.OEScoreType_Shapegauss),
            'Chemscore': oedocking.OEScore(oedocking.OEScoreType_Chemscore),
            'Chemgauss': oedocking.OEScore(oedocking.OEScoreType_Chemgauss),
            'Chemgauss3': oedocking.OEScore(oedocking.OEScoreType_Chemgauss3),
            'Chemgauss4': oedocking.OEScore(oedocking.OEScoreType_Chemgauss4),
        }

        proteinStructure = oechem.OEGraphMol()
        ifs = oechem.oemolistream(pdb_file)
        ifs.SetFormat(oechem.OEFormat_PDB)
        oechem.OEReadMolecule(ifs, proteinStructure)

        box = oedocking.OEBox(xmax, ymax, zmax, xmin, ymin, zmin)

        receptor = oechem.OEGraphMol()
        s = oedocking.OEMakeReceptor(receptor, proteinStructure, box)
        for _, score in self.scorers.items():
            assert (s != False)
            score.Initialize(receptor)
Esempio n. 16
0
def make_receptor( pdb):
    from openeye import oedocking, oechem
    import os.path

    file_name = str(os.path.basename(pdb))
    check_oeb = conf['cache'] + file_name.split(".")[0] + ".oeb"
    if os.path.isfile(check_oeb):
        g = oechem.OEGraphMol()
        oedocking.OEReadReceptorFile(g, check_oeb)
        return g
    else:
        proteinStructure = oechem.OEGraphMol()
        ifs = oechem.oemolistream(pdb)
        ifs.SetFormat(oechem.OEFormat_PDB)
        oechem.OEReadMolecule(ifs, proteinStructure)

        box = oedocking.OEBox(*conf['bp_max'], *conf['bp_min'])

        receptor = oechem.OEGraphMol()
        s = oedocking.OEMakeReceptor(receptor, proteinStructure, box)
        oedocking.OEWriteReceptorFile(receptor, check_oeb)
        assert (s != False)
        return receptor
Esempio n. 17
0
def create_hybrid_receptor(
    protein: oechem.OEGraphMol, ligand: oechem.OEGraphMol
) -> oechem.OEGraphMol:
    """
    Create a receptor for hybrid docking.
    Parameters
    ----------
    protein: oechem.OEGraphMol
        An OpenEye molecule holding a prepared protein structure.
    ligand: oechem.OEGraphMol
        An OpenEye molecule holding a prepared ligand structure.
    Returns
    -------
    receptor: oechem.OEGraphMol
        An OpenEye molecule holding a receptor with protein and ligand.
    """
    from openeye import oedocking

    # create receptor
    receptor = oechem.OEGraphMol()
    oedocking.OEMakeReceptor(receptor, protein, ligand)

    return receptor
Esempio n. 18
0
def create_hybrid_receptor(protein, ligand, receptor_save_path=None):
    """
    Create a receptor for hybrid docking.

    Parameters
    ----------
    protein: oechem.OEGraphMol
        An oechem.OEGraphMol object holding a prepared protein structure.

    ligand: oechem.OEGraphMol
        An oechem.OEGraphMol object holding a prepared ligand structure.

    receptor_save_path: str
        File path for saving created receptor. If receptor_save_path is not provided, receptor will not be saved.

    Returns
    -------
    receptor: oechem.OEGraphMol
        An oechem.OEGraphMol object holding a receptor with protein and ligand.
    """
    # Standard libraries
    import pathlib

    # External libraries
    from openeye import oechem, oedocking

    # create receptor
    receptor = oechem.OEGraphMol()
    oedocking.OEMakeReceptor(receptor, protein, ligand)

    # save receptor
    if receptor_save_path is not None:
        oedocking.OEWriteReceptorFile(
            receptor, str(pathlib.Path(receptor_save_path).absolute()))

    return receptor
def main(argv=[__name__]):
    if len(sys.argv) != 8:
        oechem.OEThrow.Usage("MakeReceptorFromBox.py \
                              <protein> <xmax> <ymax> <zmax> <xmin> <ymin> <zmin>"
                             )

    xmax = float(sys.argv[2])
    ymax = float(sys.argv[3])
    zmax = float(sys.argv[4])
    xmin = float(sys.argv[5])
    ymin = float(sys.argv[6])
    zmin = float(sys.argv[7])

    # @ <SNIPPET-MAKE-RECEPTOR-WITH-BOX-1>
    imstr = oechem.oemolistream(sys.argv[1])
    proteinStructure = oechem.OEGraphMol()
    oechem.OEReadMolecule(imstr, proteinStructure)

    box = oedocking.OEBox(xmax, ymax, zmax, xmin, ymin, zmin)
    receptor = oechem.OEGraphMol()
    oedocking.OEMakeReceptor(receptor, proteinStructure, box)
    # @ </SNIPPET-MAKE-RECEPTOR-WITH-BOX-1>

    oedocking.OEWriteReceptorFile(receptor, "receptor.oeb.gz")
Esempio n. 20
0
    def __init__(self,
                 env,
                 sort='dscores',
                 return_docked_pose=False,
                 num_returns=-1,
                 orig_pdb=None,
                 useHybrid=False,
                 trackHScores=True,
                 optimize=False):
        self.logger = make_message_writer(env.verbose, self.__class__.__name__)
        with self.logger("__init__") as logger:
            self.sort = sort
            if self.sort not in ['iscores', 'dscores', 'hscores', 'pscores']:
                logger.failure(
                    f"{self.sort} is not a valid sorting method. Exiting",
                    exit_all=True)
            self.return_docked_pose = return_docked_pose
            self.num_returns = num_returns
            self.env = env

            self.orig_pdb = orig_pdb
            self.start_dobj = None
            self.start_receptor = None
            self.track_hscores = trackHScores
            if not self.track_hscores and self.sort == 'hscores':
                logger.error(
                    "Track hscores is set to false but the sorting method desired is hscores. Assuming this was error, continuing  by setting track_hscores to True"
                )
                self.track_hscores = True

            self.past_receptors = []
            self.past_dockobjs = []
            self.past_coordinates = []
            self.optimize = optimize

            self.dockmethod = oedocking.OEDockMethod_Hybrid if useHybrid else oedocking.OEDockMethod_Chemgauss4
            if (not (self.sort != 'iscores'
                     and self.optimize)) and self.orig_pdb is not None:
                pdb = oechem.OEMol()
                prot = oechem.OEMol()
                lig = oechem.OEMol()
                wat = oechem.OEGraphMol()
                other = oechem.OEGraphMol()
                ifs = oechem.oemolistream(self.orig_pdb)
                oechem.OEReadMolecule(ifs, pdb)
                ifs.close()
                if not oechem.OESplitMolComplex(lig, prot, wat, other, pdb):
                    logger.failure("Could not split complex", exit_all=True)

                self.start_receptor = oechem.OEGraphMol()
                logger.log("Building initial receptor file...")
                oedocking.OEMakeReceptor(self.start_receptor, prot, lig)

                self.start_dobj = oedocking.OEDock(self.dockmethod)
                self.start_dobj.Initialize(self.start_receptor)
                assert (self.start_dobj.IsInitialized())
                logger.log("done")
            elif self.sort != 'iscores' and self.optimize:
                logger.log(
                    "Skipping building inital receptor because optmize is set and sorting method is not iscore"
                )
            else:
                logger.log(
                    "Skipping building inital receptor because orig_pdb was not provided."
                )
def PrepareReceptor(pdb,padding=4,outpath=""):
    """
    Prepares a receptor from a pdb with a crystalized ligand
    Padding controls the docking region.
    If outpath is given, PrepareReceptor will write an openeye binary (oeb) of the receptor structure. This will be faster than rebuilding the receptor every time.
    """
    print("STOP CALLING THIS FUNCTION")
    exit()
    com = oechem.OEGraphMol()
    ifs = oechem.oemolistream()
    if ifs.open(pdb):
        oechem.OEReadPDBFile(ifs, com)
        ifs.close()

    """
    Sorry, this requires some explanation. Openeye wasn't recognizing the previously docked ligand, so I tried to find other ways.
    The next blocks of code take our system and split it based on its connected components, for which its REQUIRED that our protein
      only has a single chain. It assumes that the last component is the ligand. It then creates the ligand (lig) and protein (prot)
      as separate molecules. Next, it finds the minimum and maximum 3D coordinates of the current ligand and produces a box around
      it with the specified padding. Finally it uses this box to create a 'receptor' object into which ligands can be docked.
    Only the receptor is returned.
    Openeye's docking shouldn't be this involved, but I couldn't get it to run the typical 'hybrid' docking without error.
    """
    oechem.OEDetermineConnectivity(com)
    nparts, connect = oechem.OEDetermineComponents(com)
    if(nparts != 2):
        print("ERR in dock_conf::prepareReceptor. PDB doesn't have 2 connected components")
        exit()
        ## TODO: What is a good way to catch errors?
    # Get apo
    pred = oechem.OEPartPredAtom(connect)
    pred.SelectPart(nparts)
    lig = oechem.OEGraphMol()
    oechem.OESubsetMol(lig, com, pred)
    print(lig)
    
    # Get protein
    pred = oechem.OEPartPredAtom(connect)
    pred.SelectPart(1)
    prot = oechem.OEGraphMol()
    oechem.OESubsetMol(prot, com, pred)
    
    # Get box dimensions by iterating over ligand
    x_min = y_min = z_min = float('inf')
    x_max = y_max = z_max = -float('inf')
    crd = lig.GetCoords()
    print("CRD", crd)
    for atm in crd:
        x,y,z = crd[atm]
        if x < x_min:
            x_min = x
        if y < y_min:
            y_min = y
        if z < z_min:
            z_min = z
        if x > x_max:
            x_max = x
        if y > y_max:
            y_max = y
        if z > z_max:
            z_max = z
    x_min -= padding
    y_min -= padding
    z_min -= padding
    x_max += padding
    y_max += padding
    z_max += padding
    print(x_min,y_min,z_max, y_max)
    # Now prepare the receptor
    receptor = oechem.OEGraphMol()
    box = oedocking.OEBox()
    box.Setup(x_max, y_max, z_max, x_min, y_min, z_min)
    oedocking.OEMakeReceptor(receptor, prot, box)
    
    if not outpath == "":
        oedocking.OEWriteReceptorFile(receptor,f'{outpath}/receptor.oeb')
    return receptor
Esempio n. 22
0
def dock_molecule(trajectory_frame,
                  original_ligands,
                  new_ligands,
                  title_list,
                  keep_ions=None,
                  override_replacement=False,
                  gen_xml=False,
                  location="./") -> List[mdtraj.Trajectory]:
    """
    Docks ligands or a list of ligands in place of another ligand

    Parameters
    ----------
    trajectory_frame: mdtraj.Trajectory, required
        The trajectory to dock to- water will be removed, but every other atoms will stay the same

    original_ligands: [str], required
        The original ligand to replace, must be an mdtraj selection string. If more than
        one residue or no residue is selected, program will throw an index error

    new_ligands: [[str]], required
        For each original ligand, a list of SMILES string representing the new ligand to dock.

    title_list: [[str]], required
        For each new ligand, the title the user wishes to have.

    keep_ions: [str], optional, default:None
        A list of ions to keep when removing solvent. Must be an mdtraj selection.

    override_replacement: bool, optional, default:False
        Setting to true will prevent replacing ligand with canonical molecule from PDB.

    gen_xml: bool, optional, default:False
        Setting to true runs the generate xml subroutine and saves openmm forcefield compatible XMLs in location. WARNING:
        Using this option requires antechmaber and is time-consuming

    location: str, optional, default:None
        The location to save xml files. Default is current directory
    Returns
    -------
    output: [mdtraj.Trajectory]
        A list of trajectories for all combinations of ligands
    """
    # Check inputs
    if len(original_ligands) != len(new_ligands):
        raise ValueError(
            "Original and new ligand arrays must have the same length.")
    # Produces pdb file in memory
    overall_dry_frame = trajectory_frame.remove_solvent(
        exclude=keep_ions)  # type: mdtraj.Trajectory
    complex_prot = _trajectory_to_oemol_(overall_dry_frame)

    # Bookkeeping
    ligand_stream = []
    output = []
    i = 0
    # Being processing a ligand
    for ligand in original_ligands:
        try:
            ligand_traj = overall_dry_frame.atom_slice(
                overall_dry_frame.top.select(
                    ligand))  # type: mdtraj.Trajectory
        except IndexError as e:
            print("Ligand selection was invalid")
            print("Exception: %s" % str(e), file=sys.stderr)
            traceback.print_tb(e.__traceback__, file=sys.stderr)
            sys.exit(1)
        # Find approximate location of binding pocket
        ligand_center = np.average(ligand_traj.xyz[0],
                                   axis=0) * 10  # Convert from nm to angstrom

        # Explicit value necessary for generated methods
        x = float(ligand_center[0])
        y = float(ligand_center[1])
        z = float(ligand_center[2])

        # Create receptor molecule
        receptor = oechem.OEGraphMol()
        oedocking.OEMakeReceptor(receptor, complex_prot, x, y, z)

        # Write out and open ligand in OpenEye
        lig_initial = _trajectory_to_oemol_(ligand_traj)
        lig_initial.SetTitle(ligand_traj.top.residue(0).name)

        # Validate if ligand is correct by checking against SMILES
        lig_smiles = NameToSMILES.getSMILE(ligand_traj.top.residue(0).name)
        if lig_smiles is not None:
            neutral_ph_smiles = NameToSMILES.addH(lig_smiles)
            validation_ligand = oechem.OEGraphMol()
            validation_ligand.SetTitle(ligand_traj.top.residue(0).name)
            oechem.OESmilesToMol(validation_ligand, neutral_ph_smiles)
            if (oechem.OEMolToSmiles(validation_ligand) !=
                    oechem.OEMolToSmiles(lig_initial)
                ) and not override_replacement:
                ligand_posed = _docking_internal(receptor, lig_initial,
                                                 validation_ligand)
                complex_prot = _trajectory_to_oemol_(
                    overall_dry_frame.atom_slice(
                        overall_dry_frame.top.select("not ( %s )" % ligand)))
                oechem.OEAddMols(receptor, ligand_posed)
                print(
                    "Warning: Original ligand had either incorrect stereochemistry or missing heavy atoms. Ligand from pdb database placed instead. "
                )

            else:
                ligand_posed = lig_initial
        else:
            print("ligand not found in PDB: No validation and continuing")
        # Dock new ligands
        ligand_position = []  # type: List[OEGraphMol]
        j = 0
        for new_ligand in new_ligands[i]:
            new_structure = oechem.OEGraphMol()
            oechem.OESmilesToMol(new_structure, new_ligand)
            new_structure.SetTitle("ligand replacement")
            print(title_list[i][j])
            docked_ligand = _docking_internal(receptor, ligand_posed,
                                              new_ligand)
            docked_ligand.SetTitle(title_list[i][j])
            ligand_position.append(docked_ligand)
            j = j + 1
        ligand_stream.append(ligand_position)
        overall_dry_frame.atom_slice(overall_dry_frame.top.select(
            "not ( %s )" % ligand),
                                     inplace=True)
        i = i + 1
    # Produce output trajectories for all combos of ligands
    for ligand_combo in itertools.product(*ligand_stream):
        new_frame_prot = overall_dry_frame  # type: Trajectory
        for built_ligand in ligand_combo:
            # Rename ligand
            ligand_dummy = tempfile.NamedTemporaryFile(suffix=".pdb")
            outputter_lig = oechem.oemolostream(ligand_dummy.name)
            oechem.OEWriteMolecule(outputter_lig, built_ligand)
            ligand_final_traj = mdtraj.load(ligand_dummy.name)
            ligand_dummy.close()
            for residue in ligand_final_traj.top.residues:
                residue.name = built_ligand.GetTitle()
            ligand_named = tempfile.NamedTemporaryFile(suffix=".pdb")
            ligand_final_traj.save(ligand_named.name)
            if gen_xml:
                if not os.path.isfile(location + built_ligand.GetTitle() +
                                      ".xml"):
                    generate_xml(ligand_named.name, location,
                                 oechem.OENetCharge(built_ligand),
                                 built_ligand.GetTitle())
                else:
                    print(built_ligand.GetTitle() + ".xml already exists")
            new_frame_prot = new_frame_prot.stack(ligand_final_traj)
        output.append(new_frame_prot)
    print("End")
    return output
def prepare_receptor(complex_pdb_filename,
                     output_basepath,
                     dimer=False,
                     retain_water=False):
    """
    Parameters
    ----------
    complex_pdb_filename : str
        The complex PDB file to read in
    output_basepath : str
        Base path for output
    dimer : bool, optional, default=False
        If True, generate the dimer as the biological unit
    retain_water : bool, optional, default=False
        If True, will retain waters
    """
    # Check whether this is a diamond SARS-CoV-2 Mpro structure or not
    import re
    is_diamond_structure = (re.search('-x\d+_', complex_pdb_filename)
                            is not None)

    import os
    basepath, filename = os.path.split(complex_pdb_filename)
    prefix, extension = os.path.splitext(filename)
    prefix = os.path.join(output_basepath, prefix)

    # Check if receptor already exists
    receptor_filename = f'{prefix}-receptor.oeb.gz'
    thiolate_receptor_filename = f'{prefix}-receptor-thiolate.oeb.gz'
    if os.path.exists(receptor_filename) and os.path.exists(
            thiolate_receptor_filename):
        return

    # Read in PDB file, skipping UNK atoms (left over from processing covalent ligands)
    pdbfile_lines = [
        line for line in open(complex_pdb_filename, 'r') if 'UNK' not in line
    ]

    # Check if biological symmetry header is present
    has_biological_symmetry_header = False
    for line in pdbfile_lines:
        if 'REMARK 350' in line:
            has_biological_symmetry_header = True
            break

    # Prepend REMARK 350 (biological symmetry) header lines for Mpro (from 5RGG) if not present
    if is_diamond_structure and (not has_biological_symmetry_header):
        pdbfile_lines = [
            line + '\n' for line in BIOLOGICAL_SYMMETRY_HEADER.split('\n')
        ] + pdbfile_lines

    # If monomer is specified, drop crystal symmetry lines
    if not dimer:
        pdbfile_lines = [
            line for line in pdbfile_lines if 'REMARK 350' not in line
        ]

    # Filter out waters
    if not retain_water:
        pdbfile_lines = [line for line in pdbfile_lines if 'HOH' not in line]

    # Filter out LINK records to covalent inhibitors so we can model non-covalent complex
    pdbfile_lines = [line for line in pdbfile_lines if 'LINK' not in line]

    # Reconstruct PDBFile contents
    pdbfile_contents = ''.join(pdbfile_lines)

    # Append SEQRES to all structures if they do not have it
    seqres = """\
SEQRES   1 A  306  SER GLY PHE ARG LYS MET ALA PHE PRO SER GLY LYS VAL
SEQRES   2 A  306  GLU GLY CYS MET VAL GLN VAL THR CYS GLY THR THR THR
SEQRES   3 A  306  LEU ASN GLY LEU TRP LEU ASP ASP VAL VAL TYR CYS PRO
SEQRES   4 A  306  ARG HIS VAL ILE CYS THR SER GLU ASP MET LEU ASN PRO
SEQRES   5 A  306  ASN TYR GLU ASP LEU LEU ILE ARG LYS SER ASN HIS ASN
SEQRES   6 A  306  PHE LEU VAL GLN ALA GLY ASN VAL GLN LEU ARG VAL ILE
SEQRES   7 A  306  GLY HIS SER MET GLN ASN CYS VAL LEU LYS LEU LYS VAL
SEQRES   8 A  306  ASP THR ALA ASN PRO LYS THR PRO LYS TYR LYS PHE VAL
SEQRES   9 A  306  ARG ILE GLN PRO GLY GLN THR PHE SER VAL LEU ALA CYS
SEQRES  10 A  306  TYR ASN GLY SER PRO SER GLY VAL TYR GLN CYS ALA MET
SEQRES  11 A  306  ARG PRO ASN PHE THR ILE LYS GLY SER PHE LEU ASN GLY
SEQRES  12 A  306  SER CYS GLY SER VAL GLY PHE ASN ILE ASP TYR ASP CYS
SEQRES  13 A  306  VAL SER PHE CYS TYR MET HIS HIS MET GLU LEU PRO THR
SEQRES  14 A  306  GLY VAL HIS ALA GLY THR ASP LEU GLU GLY ASN PHE TYR
SEQRES  15 A  306  GLY PRO PHE VAL ASP ARG GLN THR ALA GLN ALA ALA GLY
SEQRES  16 A  306  THR ASP THR THR ILE THR VAL ASN VAL LEU ALA TRP LEU
SEQRES  17 A  306  TYR ALA ALA VAL ILE ASN GLY ASP ARG TRP PHE LEU ASN
SEQRES  18 A  306  ARG PHE THR THR THR LEU ASN ASP PHE ASN LEU VAL ALA
SEQRES  19 A  306  MET LYS TYR ASN TYR GLU PRO LEU THR GLN ASP HIS VAL
SEQRES  20 A  306  ASP ILE LEU GLY PRO LEU SER ALA GLN THR GLY ILE ALA
SEQRES  21 A  306  VAL LEU ASP MET CYS ALA SER LEU LYS GLU LEU LEU GLN
SEQRES  22 A  306  ASN GLY MET ASN GLY ARG THR ILE LEU GLY SER ALA LEU
SEQRES  23 A  306  LEU GLU ASP GLU PHE THR PRO PHE ASP VAL VAL ARG GLN
SEQRES  24 A  306  CYS SER GLY VAL THR PHE GLN
"""
    has_seqres = 'SEQRES' in pdbfile_contents
    if not has_seqres:
        #print('Adding SEQRES')
        pdbfile_contents = seqres + pdbfile_contents

    # Read the receptor and identify design units
    from openeye import oespruce, oechem
    from tempfile import NamedTemporaryFile
    with NamedTemporaryFile(delete=False, mode='wt', suffix='.pdb') as pdbfile:
        pdbfile.write(pdbfile_contents)
        pdbfile.close()
        complex = read_pdb_file(pdbfile.name)
        # TODO: Clean up

    # Strip protons from structure to allow SpruceTK to add these back
    # See: 6wnp, 6wtj, 6wtk, 6xb2, 6xqs, 6xqt, 6xqu, 6m2n
    #print('Suppressing hydrogens')
    #print(f' Initial: {sum([1 for atom in complex.GetAtoms()])} atoms')
    for atom in complex.GetAtoms():
        if atom.GetAtomicNum() > 1:
            oechem.OESuppressHydrogens(atom)
    #print(f' Final: {sum([1 for atom in complex.GetAtoms()])} atoms')

    # Delete and rebuild C-terminal residue because Spruce causes issues with this
    # See: 6m2n 6lze
    #print('Deleting C-terminal residue O')
    pred = oechem.OEIsCTerminalAtom()
    for atom in complex.GetAtoms():
        if pred(atom):
            for nbor in atom.GetAtoms():
                if oechem.OEGetPDBAtomIndex(nbor) == oechem.OEPDBAtomName_O:
                    complex.DeleteAtom(nbor)

    #pred = oechem.OEAtomMatchResidue(["GLN:306:.*:.*:.*"])
    #for atom in complex.GetAtoms(pred):
    #    if oechem.OEGetPDBAtomIndex(atom) == oechem.OEPDBAtomName_O:
    #        print('Deleting O')
    #        complex.DeleteAtom(atom)

    #het = oespruce.OEHeterogenMetadata()
    #het.SetTitle("LIG")  # real ligand 3 letter code
    #het.SetID("CovMoonShot1234")  # in case you have corporate IDs
    #het.SetType(oespruce.OEHeterogenType_Ligand)
    #   mdata.AddHeterogenMetadata(het)

    #print('Identifying design units...')
    # Produce zero design units if we fail to protonate

    # Log warnings
    errfs = oechem.oeosstream(
    )  # create a stream that writes internally to a stream
    oechem.OEThrow.SetOutputStream(errfs)
    oechem.OEThrow.Clear()
    oechem.OEThrow.SetLevel(
        oechem.OEErrorLevel_Verbose)  # capture verbose error output

    opts = oespruce.OEMakeDesignUnitOptions()
    #print(f'ligand atoms: min {opts.GetSplitOptions().GetMinLigAtoms()}, max {opts.GetSplitOptions().GetMaxLigAtoms()}')
    opts.GetSplitOptions().SetMinLigAtoms(
        7)  # minimum fragment size (in heavy atoms)

    mdata = oespruce.OEStructureMetadata()
    opts.GetPrepOptions().SetStrictProtonationMode(True)

    # Both N- and C-termini should be zwitterionic
    # Mpro cleaves its own N- and C-termini
    # See https://www.pnas.org/content/113/46/12997
    opts.GetPrepOptions().GetBuildOptions().SetCapNTermini(False)
    opts.GetPrepOptions().GetBuildOptions().SetCapCTermini(False)
    # Don't allow truncation of termini, since force fields don't have parameters for this
    opts.GetPrepOptions().GetBuildOptions().GetCapBuilderOptions(
    ).SetAllowTruncate(False)
    # Build loops and sidechains
    opts.GetPrepOptions().GetBuildOptions().SetBuildLoops(True)
    opts.GetPrepOptions().GetBuildOptions().SetBuildSidechains(True)

    # Don't flip Gln189
    #pred = oechem.OEAtomMatchResidue(["GLN:189: :A"])
    pred = oechem.OEAtomMatchResidue(["GLN:189:.*:.*:.*"])
    protonate_opts = opts.GetPrepOptions().GetProtonateOptions()
    place_hydrogens_opts = protonate_opts.GetPlaceHydrogensOptions()
    #place_hydrogens_opts.SetBypassPredicate(pred)
    place_hydrogens_opts.SetNoFlipPredicate(pred)
    #protonate_opts = oespruce.OEProtonateDesignUnitOptions(place_hydrogens_opts)
    #opts.GetPrepOptions().SetProtonateOptions(protonate_options);

    # Make design units
    design_units = list(oespruce.OEMakeDesignUnits(complex, mdata, opts))

    # Restore error stream
    oechem.OEThrow.SetOutputStream(oechem.oeerr)

    # Capture the warnings to a string
    warnings = errfs.str().decode("utf-8")

    if len(design_units) >= 1:
        design_unit = design_units[0]
        print('')
        print('')
        print(f'{complex_pdb_filename} : SUCCESS')
        print(warnings)
    elif len(design_units) == 0:
        print('')
        print('')
        print(f'{complex_pdb_filename} : FAILURE')
        print(warnings)
        msg = f'No design units found for {complex_pdb_filename}\n'
        msg += warnings
        msg += '\n'
        raise Exception(msg)

    # Prepare the receptor
    #print('Preparing receptor...')
    from openeye import oedocking
    protein = oechem.OEGraphMol()
    design_unit.GetProtein(protein)
    ligand = oechem.OEGraphMol()
    design_unit.GetLigand(ligand)

    # Create receptor and other files
    receptor = oechem.OEGraphMol()
    oedocking.OEMakeReceptor(receptor, protein, ligand)
    oedocking.OEWriteReceptorFile(receptor, receptor_filename)

    with oechem.oemolostream(f'{prefix}-protein.pdb') as ofs:
        oechem.OEWriteMolecule(ofs, protein)
    with oechem.oemolostream(f'{prefix}-ligand.mol2') as ofs:
        oechem.OEWriteMolecule(ofs, ligand)
    with oechem.oemolostream(f'{prefix}-ligand.pdb') as ofs:
        oechem.OEWriteMolecule(ofs, ligand)
    with oechem.oemolostream(f'{prefix}-ligand.sdf') as ofs:
        oechem.OEWriteMolecule(ofs, ligand)

    # Filter out UNK from PDB files (which have covalent adducts)
    pdbfile_lines = [
        line for line in open(f'{prefix}-protein.pdb', 'r')
        if 'UNK' not in line
    ]
    with open(f'{prefix}-protein.pdb', 'wt') as outfile:
        outfile.write(''.join(pdbfile_lines))

    # Adjust protonation state of CYS145 to generate thiolate form
    #print('Deprotonating CYS145...') # DEBUG
    #pred = oechem.OEAtomMatchResidue(["CYS:145: :A"])
    pred = oechem.OEAtomMatchResidue(["CYS:145:.*:.*:.*"])
    place_hydrogens_opts.SetBypassPredicate(pred)
    for atom in protein.GetAtoms(pred):
        if oechem.OEGetPDBAtomIndex(atom) == oechem.OEPDBAtomName_SG:
            #print('Modifying CYS 145 SG')
            oechem.OESuppressHydrogens(atom)
            atom.SetFormalCharge(-1)
            atom.SetImplicitHCount(0)
    #print('Protonating HIS41...') # DEBUG
    #pred = oechem.OEAtomMatchResidue(["HIS:41: :A"])
    pred = oechem.OEAtomMatchResidue(["HIS:41:.*:.*:.*"])
    place_hydrogens_opts.SetBypassPredicate(pred)
    for atom in protein.GetAtoms(pred):
        if oechem.OEGetPDBAtomIndex(atom) == oechem.OEPDBAtomName_ND1:
            #print('Protonating HIS 41 ND1')
            oechem.OESuppressHydrogens(atom)  # strip hydrogens from residue
            atom.SetFormalCharge(+1)
            atom.SetImplicitHCount(1)
    # Update the design unit with the modified formal charge for CYS 145 SG
    oechem.OEUpdateDesignUnit(design_unit, protein,
                              oechem.OEDesignUnitComponents_Protein)

    # Don't flip Gln189
    #pred = oechem.OEAtomMatchResidue(["GLN:189: :A"])
    #protonate_opts = opts.GetPrepOptions().GetProtonateOptions();
    #place_hydrogens_opts = protonate_opts.GetPlaceHydrogensOptions()
    #place_hydrogens_opts.SetNoFlipPredicate(pred)

    # Adjust protonation states
    #print('Re-optimizing hydrogen positions...') # DEBUG
    #place_hydrogens_opts = oechem.OEPlaceHydrogensOptions()
    #place_hydrogens_opts.SetBypassPredicate(pred)
    #protonate_opts = oespruce.OEProtonateDesignUnitOptions(place_hydrogens_opts)
    success = oespruce.OEProtonateDesignUnit(design_unit, protonate_opts)
    design_unit.GetProtein(protein)

    # Write thiolate form of receptor
    receptor = oechem.OEGraphMol()
    oedocking.OEMakeReceptor(receptor, protein, ligand)
    oedocking.OEWriteReceptorFile(receptor, thiolate_receptor_filename)

    with oechem.oemolostream(f'{prefix}-protein-thiolate.pdb') as ofs:
        oechem.OEWriteMolecule(ofs, protein)

    # Filter out UNK from PDB files (which have covalent adducts)
    pdbfile_lines = [
        line for line in open(f'{prefix}-protein-thiolate.pdb', 'r')
        if 'UNK' not in line
    ]
    with open(f'{prefix}-protein-thiolate.pdb', 'wt') as outfile:
        outfile.write(''.join(pdbfile_lines))
Esempio n. 24
0
def prepare_receptor(complex_pdb_filename, output_basepath, dimer=False):
    """
    Parameters
    ----------
    complex_pdb_filename : str
        The complex PDB file to read in
    output_basepath : str
        Base path for output
    dimer : bool, optional, default=False
        If True, generate the dimer as the biological unit
    """
    import os
    basepath, filename = os.path.split(complex_pdb_filename)
    prefix, extension = os.path.splitext(filename)
    prefix = os.path.join(output_basepath, prefix)

    # Check if receptor already exists
    receptor_filename = f'{prefix}-receptor.oeb.gz'
    thiolate_receptor_filename = f'{prefix}-receptor-thiolate.oeb.gz'
    if os.path.exists(receptor_filename) and os.path.exists(
            thiolate_receptor_filename):
        return

    # Read in PDB file
    pdbfile_lines = [
        line for line in open(complex_pdb_filename, 'r') if 'UNK' not in line
    ]

    # If monomer is specified, drop crystal symmetry lines
    if not dimer:
        pdbfile_lines = [
            line for line in pdbfile_lines if 'REMARK 350' not in line
        ]

    # Reconstruct PDBFile contents
    pdbfile_contents = ''.join(pdbfile_lines)

    # Read the receptor and identify design units
    from openeye import oespruce, oechem
    from tempfile import NamedTemporaryFile
    with NamedTemporaryFile(delete=False, mode='wt', suffix='.pdb') as pdbfile:
        pdbfile.write(pdbfile_contents)
        pdbfile.close()
        complex = read_pdb_file(pdbfile.name)
        # TODO: Clean up

    #print('Identifying design units...')
    design_units = list(oespruce.OEMakeDesignUnits(complex))
    if len(design_units) == 1:
        design_unit = design_units[0]
    elif len(design_units) > 1:
        #print('More than one design unit found---using first one')
        design_unit = design_units[0]
    elif len(design_units) == 0:
        raise Exception(f' * No design units found for {complex_pdb_filename}')

    # Prepare the receptor
    #print('Preparing receptor...')
    from openeye import oedocking
    protein = oechem.OEGraphMol()
    design_unit.GetProtein(protein)
    ligand = oechem.OEGraphMol()
    design_unit.GetLigand(ligand)

    receptor = oechem.OEGraphMol()
    oedocking.OEMakeReceptor(receptor, protein, ligand)
    oedocking.OEWriteReceptorFile(receptor, receptor_filename)

    with oechem.oemolostream(f'{prefix}-protein.pdb') as ofs:
        oechem.OEWriteMolecule(ofs, protein)
    with oechem.oemolostream(f'{prefix}-ligand.mol2') as ofs:
        oechem.OEWriteMolecule(ofs, ligand)
    with oechem.oemolostream(f'{prefix}-ligand.pdb') as ofs:
        oechem.OEWriteMolecule(ofs, ligand)
    with oechem.oemolostream(f'{prefix}-ligand.sdf') as ofs:
        oechem.OEWriteMolecule(ofs, ligand)

    # Filter out UNK from PDB files (which have covalent adducts)
    pdbfile_lines = [
        line for line in open(f'{prefix}-protein.pdb', 'r')
        if 'UNK' not in line
    ]
    with open(f'{prefix}-protein.pdb', 'wt') as outfile:
        outfile.write(''.join(pdbfile_lines))

    # Adjust protonation state of CYS145 to generate thiolate form
    #print('Deprotonating CYS145...')
    pred = oechem.OEAtomMatchResidue(["CYS:145: :A"])
    for atom in protein.GetAtoms(pred):
        if oechem.OEGetPDBAtomIndex(atom) == oechem.OEPDBAtomName_SG:
            oechem.OESuppressHydrogens(atom)
            atom.SetFormalCharge(-1)
            atom.SetImplicitHCount(0)
    # Adjust protonation states
    #print('Re-optimizing hydrogen positions...')
    place_hydrogens_opts = oechem.OEPlaceHydrogensOptions()
    place_hydrogens_opts.SetBypassPredicate(pred)
    protonate_opts = oespruce.OEProtonateDesignUnitOptions(
        place_hydrogens_opts)
    success = oespruce.OEProtonateDesignUnit(design_unit, protonate_opts)
    design_unit.GetProtein(protein)

    # Old hacky way to adjust protonation states
    #opts = oechem.OEPlaceHydrogensOptions()
    #opts.SetBypassPredicate(pred)
    #describe = oechem.OEPlaceHydrogensDetails()
    #success = oechem.OEPlaceHydrogens(protein, describe, opts)
    #if success:
    #    oechem.OEUpdateDesignUnit(design_unit, protein, oechem.OEDesignUnitComponents_Protein)

    # Write thiolate form of receptor
    receptor = oechem.OEGraphMol()
    oedocking.OEMakeReceptor(receptor, protein, ligand)
    oedocking.OEWriteReceptorFile(receptor, thiolate_receptor_filename)

    with oechem.oemolostream(f'{prefix}-protein-thiolate.pdb') as ofs:
        oechem.OEWriteMolecule(ofs, protein)

    # Filter out UNK from PDB files (which have covalent adducts)
    pdbfile_lines = [
        line for line in open(f'{prefix}-protein-thiolate.pdb', 'r')
        if 'UNK' not in line
    ]
    with open(f'{prefix}-protein-thiolate.pdb', 'wt') as outfile:
        outfile.write(''.join(pdbfile_lines))
Esempio n. 25
0
def hybrid_docking(receptor_path,
                   molecules_path,
                   docked_molecules_path,
                   n_poses=10):
    """Automated hybrid docking of small molecules to a receptor.

    Parameters
    ----------
    receptor_path : str
        Path to PDB file containing receptor and reference ligand, or pre-prepared receptor for docking
    molecules_path : str
        Path to file containing one or more molecules (in OpenEye readable format) to be docked.
        (For example, list of SMILES)
    docked_molecules_path : str
        Path to output file to be created to contain docked molecules
        Uses OpenEye recognized file extension, such as .mol2 or .sdf
    n_poses : int, optional, default=1
        Number of docked poses to generate
    receptor_filename : str, optional, default=None
        If not None, the pre-prepared receptor is loaded

    TODO: How can this API be improved?

    """
    from .docking import create_receptor, load_receptor, pose_molecule
    from openeye import oedocking, oechem
    #import openmoltools as moltools # TODO: Bring these methods into this module

    # Try to load pre-prepared receptor from specified file
    receptor = oechem.OEGraphMol()
    print('Attempting to load receptor from {}...'.format(receptor_path))
    if not oedocking.OEReadReceptorFile(receptor, receptor_path):
        # Load complex of receptor and reference ligand
        complex_istream = oechem.oemolistream(receptor_path)
        complex = oechem.OEGraphMol()
        oechem.OEReadMolecule(complex_istream, complex)

        # Attempt to split into components and build receptor based on reference ligand
        print('Attempting to split complex into components...')
        ligand = oechem.OEGraphMol()
        protein = oechem.OEGraphMol()
        water = oechem.OEGraphMol()
        other = oechem.OEGraphMol()
        if oechem.OESplitMolComplex(ligand, protein, water, other, complex):
            # Create receptor using bound ligand reference
            print('Creating receptor using reference ligand...')
            oedocking.OEMakeReceptor(receptor, protein, ligand)
            # TODO: We can store prepared receptor file if desired
            oedocking.OEWriteReceptorFile(
                receptor,
                '/home/guoj1/projects/INSPIRE/kinomodel/kinomodel/data/docking/prepared_receptor.oeb'
            )

        else:
            raise Exception(
                'Could not split specified PDB file {} into receptor and reference ligand'
                .format(receptor_path))

    # Open file for writing docked molecules
    docked_molecules_ostream = oechem.oemolostream(docked_molecules_path)

    # Configure omega
    # From canonical recipe: https://docs.eyesopen.com/toolkits/cookbook/python/modeling/am1-bcc.html
    from openeye import oeomega
    omega = oeomega.OEOmega()
    omega.SetIncludeInput(False)
    omega.SetCanonOrder(False)
    omega.SetSampleHydrogens(True)
    eWindow = 15.0
    omega.SetEnergyWindow(eWindow)
    omega.SetMaxConfs(800)
    omega.SetRMSThreshold(1.0)

    # Dock all molecules requested
    dock_method = oedocking.OEDockMethod_Hybrid2
    dock_resolution = oedocking.OESearchResolution_Standard
    dock = oedocking.OEDock(dock_method, dock_resolution)
    dock.Initialize(receptor)
    molecules_istream = oechem.oemolistream(molecules_path)
    molecule = oechem.OEGraphMol()
    for molecule in molecules_istream.GetOEMols():
        print("docking", molecule.GetTitle())
        #docked_molecules = pose_molecule(receptor, molecule, n_poses=n_poses)
        #molecule = moltools.openeye.get_charges(molecule, keep_confs=10)

        # Generate conformers
        if not omega(molecule):
            continue

        # Apply charges
        from openeye import oequacpac
        oequacpac.OEAssignCharges(molecule, oequacpac.OEAM1BCCELF10Charges())

        # Dock
        docked_molecule = oechem.OEGraphMol()
        dock.DockMultiConformerMolecule(docked_molecule, molecule)
        sdtag = oedocking.OEDockMethodGetName(dock_method)
        oedocking.OESetSDScore(docked_molecule, dock, sdtag)
        dock.AnnotatePose(docked_molecule)
        oechem.OEWriteMolecule(docked_molecules_ostream, docked_molecule)
Esempio n. 26
0
    def getscores(self,
                  actions,
                  gsmis,
                  prot,
                  lig,
                  num_returns=10,
                  return_docked_pose=False,
                  refmol=None):
        with self.logger("getscores") as logger:
            if num_returns <= 0:
                num_returns = len(actions) - 1
            logger.log("Action space is ", len(actions))
            idxs = list(
                np.random.choice(len(actions),
                                 min(num_returns,
                                     len(actions) - 1),
                                 replace=False).flatten())
            actions = [actions[idx] for idx in idxs]
            gsmis = [gsmis[idx] for idx in idxs]

            protein = oechem.OEMol(prot)
            receptor = oechem.OEGraphMol()

            if not (self.sort == 'iscores' and self.optimize):
                logger.log(
                    "Creating receptor from recent pdb, this might take awhile"
                )
                oedocking.OEMakeReceptor(receptor, protein, lig)
                dockobj = oedocking.OEDock(self.dockmethod)
                dockobj.Initialize(receptor)
                assert (dockobj.IsInitialized())
                logger.log("done")
            else:
                dockobj = None
                logger.log(
                    "Skipping receptor building as optimize is set and sort method is iscore."
                )

            pscores = []
            dscores = []
            ds_old_scores = []
            ds_start_scores = []

            data = []

            with multiprocessing.Pool() as p:
                imapiter = p.imap(
                    self.env.action.aligner.__class__.call_static,
                    zip(actions, gsmis,
                        [copy.deepcopy(refmol)] * len(actions)))

                for idx, res in enumerate(imapiter):
                    try:
                        if res is None:
                            logger.error(
                                "Alignment failed and returned none for ",
                                gsmis[idx])
                            continue
                        ps, ds, ds_start, ds_old = None, None, None, []
                        new_mol, new_mol2, gs, action = res

                        if dockobj is not None:
                            dockedpose = oechem.OEMol()
                            newmol2 = oechem.OEMol(new_mol)
                            dockobj.DockMultiConformerMolecule(
                                dockedpose, newmol2, 1)
                            ds = dockedpose.GetEnergy()
                            ps = dockobj.ScoreLigand(new_mol)
                            dscores.append(ds)
                            pscores.append(ps)
                            if return_docked_pose:
                                new_mol_ = oechem.OEMol(dockedpose)

                        if self.start_dobj is not None:
                            dockedpose2 = oechem.OEMol()
                            newmol2 = oechem.OEMol(new_mol)
                            self.start_dobj.DockMultiConformerMolecule(
                                dockedpose2, newmol2, 1)
                            ds_start = dockedpose2.GetEnergy()
                            ds_start_scores.append(ds_start)
                        if self.track_hscores:
                            for olddobj in self.past_dockobjs:
                                dockedpose2 = oechem.OEMol()
                                newmol2 = oechem.OEMol(new_mol)
                                olddobj.DockMultiConformerMolecule(
                                    dockedpose2, newmol2, 1)
                                ds_old.append(dockedpose2.GetEnergy())
                                ds_old_scores.append(ds_old)

                        if dockobj is not None and return_docked_pose:
                            new_mol = new_mol_
                        oechem.OEAssignAromaticFlags(new_mol)
                        oechem.OEAddExplicitHydrogens(new_mol)
                        oechem.OE3DToInternalStereo(new_mol)
                        new_mol2 = oechem.OEMol(new_mol)

                        gs = oechem.OECreateSmiString(
                            new_mol, oechem.OESMILESFlag_DEFAULT
                            | oechem.OESMILESFlag_Hydrogens
                            | oechem.OESMILESFlag_Isotopes
                            | oechem.OESMILESFlag_BondStereo
                            | oechem.OESMILESFlag_AtomStereo)

                        logger.log(
                            f"(idx / {len(idxs)}: Pose Score {ps}, Dock Score {ds}, Init Score {ds_start}"
                        )

                        data.append((new_mol, new_mol2, gs, action))
                    except Exception as p:
                        logger.error(p)
                        traceback.print_tb(p.__traceback__)

                        continue

            self.past_dockobjs.append(dockobj)
            self.past_receptors.append(receptor)
            logger.log("Sorting on", self.sort)
            if self.sort == 'dscores':
                order = np.argsort(dscores)
                logger.log([dscores[i] for i in order])
            elif self.sort == 'pscores':
                order = np.argsort(pscores)
                logger.log([pscores[i] for i in order])
            elif self.sort == 'iscores':
                order = np.argsort(ds_start_scores)
                logger.log([ds_start_scores[i] for i in order])
            elif self.sort == 'hscores':
                hscores = [
                    np.quantile(np.clip(scoreset, None, 0), 0.)
                    for scoreset in ds_old_scores
                ]
                order = np.argsort(hscores)
                logger.log([hscores[i] for i in order])
            else:
                assert (False)

            self.env.data['dscores'].append(dscores)
            self.env.data['pscores'].append(pscores)
            self.env.data['iscores'].append(ds_start_scores)
            self.env.data['hscores'].append(ds_old_scores)
            data = [data[i] for i in order]
        return data