예제 #1
0
    def rmsd_to_me(self, other_conf):
        """Calculate the rms distance between this conformer and another one.

        :param other_conf: The other conformer to align.
        :type other_conf: MyConformer
        :return: The rmsd, a float.
        :rtype: float
        """

        # Make a new molecule.
        amol = Chem.MolFromSmiles(self.smiles, sanitize=False)
        amol = MOH.check_sanitization(amol)
        amol = MOH.try_reprotanation(amol)

        # Add the conformer of the other MyConformer object.
        amol.AddConformer(self.conformer(), assignId=True)
        amol.AddConformer(other_conf.conformer(), assignId=True)

        # Get the two confs.
        first_conf = amol.GetConformers()[0]
        last_conf = amol.GetConformers()[-1]

        # Return the RMSD.
        amol = MOH.try_deprotanation(amol)
        rmsd = AllChem.GetConformerRMS(amol,
                                       first_conf.GetId(),
                                       last_conf.GetId(),
                                       prealigned=True)

        return rmsd
예제 #2
0
    def make_mol_frm_smiles_sanitze(self):
        """Construct a rdkit.mol for this object, in case you only received
        the smiles. Also, sanitize the molecule regardless.

        :return: Returns the rdkit.mol object, though it's also stored in
           self.rdkit_mol.
        :rtype: rdkit.mol object.
        """

        # If given a SMILES string.
        if self.rdkit_mol == "":
            try:
                # sanitize = False makes it respect double-bond stereochemistry
                m = Chem.MolFromSmiles(self.orig_smi_deslt, sanitize=False)
            except:
                m = None
        else:  # If given a RDKit Mol Obj
            m = self.rdkit_mol

        if m is not None:
            # Sanitize and hopefully correct errors in the smiles string such
            # as incorrect nitrogen charges.
            m = MOH.check_sanitization(m)
        self.rdkit_mol = m
        return m
예제 #3
0
    def smiles(self, noh=False):
        """Get the desalted, canonical smiles string associated with this
           object. (Not the input smiles!)

        :param noh: Whether or not hydrogen atoms should be included in the
           canonical smiles string., defaults to False
        :param noh: bool, optional
        :return: The canonical smiles string, or None if it cannot be
           determined.
        :rtype: str or None
        """

        # See if it's already been calculated.
        if noh == False:
            # They want the hydrogen atoms.
            if self.can_smi != "":
                # Return previously determined canonical SMILES.
                return self.can_smi
            else:
                # Need to determine canonical SMILES.
                try:
                    can_smi = Chem.MolToSmiles(self.rdkit_mol,
                                               isomericSmiles=True,
                                               canonical=True)
                except:
                    # Sometimes this conversion just can't happen. Happened
                    # once with this beast, for example:
                    # CC(=O)NC1=CC(=C=[N+]([O-])O)C=C1O
                    Utils.log("Warning: Couldn't put " + self.orig_smi + " (" +
                              self.name +
                              ") in canonical form. Got this error: " +
                              str(sys.exc_info()[0]) +
                              ". This molecule will be " + "discarded.")
                    self.can_smi = None
                    return None

                self.can_smi = can_smi
                return can_smi
        else:
            # They don't want the hydrogen atoms.
            if self.can_smi_noh != "":
                # Return previously determined string.
                return self.can_smi_noh

            # So remove hydrogens. Note that this assumes you will have called
            # this function previously with noh = False
            amol = copy.copy(self.rdkit_mol)
            amol = MOH.try_deprotanation(amol)
            self.can_smi_noh = Chem.MolToSmiles(amol,
                                                isomericSmiles=True,
                                                canonical=True)
            return self.can_smi_noh
예제 #4
0
    def make_first_3d_conf_no_min(self):
        """Makes the associated rdkit.mol object 3D by adding the first
           conformer. This also adds hydrogen atoms to the associated rdkit.mol
           object. Note that it does not perform a minimization, so it is not
           too expensive."""

        # Set the first 3D conformer
        if len(self.conformers) > 0:
            # It's already been done.
            return

        # Add hydrogens. JDD: I don't think this undoes dimorphite-dl, but we
        # need to check that.
        self.rdkit_mol = MOH.try_reprotanation(self.rdkit_mol)

        # Add a single conformer. RMSD cutoff very small so all conformers
        # will be accepted. And not minimizing (False).
        self.add_conformers(1, 1e60, False)
예제 #5
0
    def make_first_3d_conf_no_min(self):
        """Makes the associated rdkit.mol object 3D by adding the first
           conformer. This also adds hydrogen atoms to the associated rdkit.mol
           object. Note that it does not perform a minimization, so it is not
           too expensive."""

        # Set the first 3D conformer
        if len(self.conformers) > 0:
            # It's already been done.
            return

        # Add hydrogens. This adds explicit hydrogens, while respecting
        # Dimorphite-DL protonation states.
        self.rdkit_mol = MOH.try_reprotanation(self.rdkit_mol)

        # Add a single conformer. RMSD cutoff very small so all conformers
        # will be accepted. And not minimizing (False).
        self.add_conformers(1, 1e60, False)
예제 #6
0
def parallel_make_taut(contnr, mol_index, max_variants_per_compound):
    """Makes alternate tautomers for a given molecule container. This is the
       function that gets fed into the parallelizer.

    :param contnr: The molecule container.
    :type contnr: MolContainer.MolContainer
    :param mol_index: The molecule index.
    :type mol_index: int
    :param max_variants_per_compound: To control the combinatorial explosion,
       only this number of variants (molecules) will be advanced to the next
       step.
    :type max_variants_per_compound: int
    :return: A list of MyMol.MyMol objects, containing the alternate
        tautomeric forms.
    :rtype: list
    """

    # Get the MyMol.MyMol within the molecule container corresponding to the
    # given molecule index.
    mol = contnr.mols[mol_index]

    # Create a temporary RDKit mol object, since that's what MolVS works with.
    # TODO: There should be a copy function
    m = MyMol.MyMol(mol.smiles()).rdkit_mol

    # For tautomers to work, you need to not have any explicit hydrogens.
    m = Chem.RemoveHs(m)

    # Make sure it's not None.
    if m is None:
        Utils.log("\tCould not generate tautomers for " + contnr.orig_smi +
                  ". I'm deleting it.")
        return

    # Molecules should be kekulized already, but let's double check that.
    # Because MolVS requires kekulized input.
    Chem.Kekulize(m)
    m = MOH.check_sanitization(m)
    if m is None:
        return None

    # Limit to max_variants_per_compound tauts. Note that another batch could
    # add more, so you'll need to once again trim to this number later. But
    # this could at least help prevent the combinatorial explosion at this
    # stage.
    enum = tautomer.TautomerEnumerator(max_tautomers=max_variants_per_compound)
    tauts_rdkit_mols = enum.enumerate(m)

    # Make all those tautomers into MyMol objects.
    tauts_mols = [MyMol.MyMol(m) for m in tauts_rdkit_mols]

    # Keep only those that have reasonable substructures.
    tauts_mols = [
        t for t in tauts_mols if t.remove_bizarre_substruc() == False
    ]

    # If there's more than one, let the user know that.
    if len(tauts_mols) > 1:
        Utils.log("\t" + mol.smiles(True) + " has tautomers.")

    # Now collect the final results.
    results = []

    for tm in tauts_mols:
        tm.inherit_contnr_props(contnr)
        tm.genealogy = mol.genealogy[:]
        tm.name = mol.name

        if tm.smiles() != mol.smiles():
            tm.genealogy.append(tm.smiles(True) + " (tautomer)")

        results.append(tm)

    return results