Example #1
0
 def testIssue3231(self):
     mol = Chem.MolFromSmiles(
         'C[C@H](OC1=C(N)N=CC(C2=CN(C3C[C@H](C)NCC3)N=C2)=C1)C4=C(Cl)C=CC(F)=C4Cl'
     )
     Chem.AssignStereochemistry(mol,
                                force=True,
                                flagPossibleStereoCenters=True)
     l = Chem.FindMolChiralCenters(mol, includeUnassigned=True)
     self.assertEqual(l, [(1, 'S'), (12, '?'), (14, 'S')])
     enumsi_opt = AllChem.StereoEnumerationOptions(maxIsomers=20,
                                                   onlyUnassigned=False)
     isomers = list(AllChem.EnumerateStereoisomers(mol, enumsi_opt))
     chi_cents = []
     for iso in isomers:
         Chem.AssignStereochemistry(iso)
         chi_cents.append(
             Chem.FindMolChiralCenters(iso, includeUnassigned=True))
     self.assertEqual(
         sorted(chi_cents),
         [[(1, 'R'), (12, 'R'),
           (14, 'R')], [(1, 'R'), (12, 'R'),
                        (14, 'S')], [(1, 'R'), (12, 'S'), (14, 'R')],
          [(1, 'R'), (12, 'S'),
           (14, 'S')], [(1, 'S'), (12, 'R'),
                        (14, 'R')], [(1, 'S'), (12, 'R'), (14, 'S')],
          [(1, 'S'), (12, 'S'), (14, 'R')], [(1, 'S'), (12, 'S'),
                                             (14, 'S')]])
Example #2
0
def enumerate_stereoisomers(
    mol,
    n_variants: int = 20,
    undefined_only: bool = False,
    rationalise: bool = True,
):
    """Enumerate the stereocenters and bonds of the current molecule.

    Original source: the `openff-toolkit` lib.

    Warning: this function can be computationnaly intensive.

    Args:
        mol: The molecule whose state we should enumerate.
        n_variants: The maximum amount of molecules that should be returned.
        undefined_only: If we should enumerate all stereocenters and bonds or only those
            with undefined stereochemistry.
        rationalise: If we should try to build and rationalise the molecule to ensure it
            can exist.
    """
    from rdkit.Chem.EnumerateStereoisomers import EnumerateStereoisomers
    from rdkit.Chem.EnumerateStereoisomers import StereoEnumerationOptions

    # safety first
    mol = copy_mol(mol)

    # in case any bonds/centers are missing stereo chem flag it here
    Chem.AssignStereochemistry(mol, force=False, flagPossibleStereoCenters=True, cleanIt=True)  # type: ignore
    Chem.FindPotentialStereoBonds(mol, cleanIt=True)  # type: ignore

    # set up the options
    stereo_opts = StereoEnumerationOptions(
        tryEmbedding=rationalise,
        onlyUnassigned=undefined_only,
        maxIsomers=n_variants,
    )

    try:
        isomers = tuple(EnumerateStereoisomers(mol, options=stereo_opts))
    except:
        # NOTE(hadim): often got "Stereo atoms should be specified before specifying CIS/TRANS bond stereochemistry"
        # for the ligand of reference (coming from the PDB). Not sure how to handle that.
        isomers = []

    variants = []
    for isomer in isomers:
        # isomer has CIS/TRANS tags so convert back to E/Z
        Chem.SetDoubleBondNeighborDirections(isomer)  # type: ignore
        Chem.AssignStereochemistry(isomer, force=True, cleanIt=True)  # type: ignore
        variants.append(isomer)

    return variants
Example #3
0
    def setup(self, starting_ligand_file):
        if self.config.starting_smiles is None:
            self.start_smiles = Chem.MolFromMol2File(starting_ligand_file,
                                                     sanitize=False)
        else:
            self.start_smiles = Chem.MolFromSmiles(self.config.starting_smiles)
        if np.abs(
                Chem.GetFormalCharge(self.start_smiles) -
                int(Chem.GetFormalCharge(self.start_smiles))) != 0:
            print("NONINTEGRAL START CHARGE",
                  Chem.GetFormalCharge(self.start_smiles))
        Chem.SanitizeMol(self.start_smiles)
        Chem.AssignStereochemistry(self.start_smiles, cleanIt=True, force=True)

        mol = oechem.OEMol()
        ifs = oechem.oemolistream(starting_ligand_file)
        oechem.OEReadMolecule(ifs, mol)
        self.mol_aligner = mol
        ifs.close()
        self.mol = molecules.Molecule(
            self.config.atoms,
            self.start_smiles,
            allow_removal=self.config.allow_removal,
            allow_no_modification=self.config.allow_no_modification,
            allow_bonds_between_rings=self.config.allow_no_modification,
            allowed_ring_sizes=self.config.allowed_ring_sizes,
            max_steps=100)
        self.mol.initialize()
Example #4
0
def initialize_rxn_from_smarts(reaction_smarts):
    # Initialize reaction
    rxn = AllChem.ReactionFromSmarts(reaction_smarts)
    rxn.Initialize()
    if rxn.Validate()[1] != 0:
        raise ValueError('validation failed')
    if PLEVEL >= 2: print('Validated rxn without errors')

    unmapped = 700
    for rct in rxn.GetReactants():
        rct.UpdatePropertyCache()
        Chem.AssignStereochemistry(rct)
        # Fill in atom map numbers
        for a in rct.GetAtoms():
            if not a.HasProp('molAtomMapNumber'):
                a.SetIntProp('molAtomMapNumber', unmapped)
                unmapped += 1
    if PLEVEL >= 2:
        print(
            ('Added {} map nums to unmapped reactants'.format(unmapped - 700)))
    if unmapped > 800:
        raise ValueError(
            'Why do you have so many unmapped atoms in the template reactants?'
        )

    return rxn
def enumerateStereoChem(compoundID, sampleDir, db, xtal):
    # first need to recreate the original CIF file with phenix.elbow because we cannot be sure
    # which program was used to create the initial restrains
    # this is because funny things happen to aromatic rings in case the file was made with GRADE
    os.chdir(os.path.join(sampleDir, 'compound'))
    sql = "select CompoundSMILESproduct from mainTable where CrystalName = '%s'" % xtal
    query = db.execute_statement(sql)
    originalSMILES = query[0][0]
    cmd = 'phenix.elbow --smiles="%s" --id=LIG --output=tmp' % (originalSMILES)
    os.system(cmd)

    stereosmiles = None
    if os.path.isfile(os.path.join(sampleDir, 'compound', 'tmp.pdb')):
        pdb = os.path.join(sampleDir, 'compound', 'tmp.pdb')
    else:
        print 'cannot find tmp.pdb'
        pass
    mol = Chem.MolFromPDBFile(pdb)
    Chem.AssignStereochemistry(mol,
                               cleanIt=True,
                               force=True,
                               flagPossibleStereoCenters=True)
    if Chem.FindMolChiralCenters(mol, includeUnassigned=True) == []:
        print 'no chiral centres found'
        db_dict = {}
        db_dict['CompoundStereo'] = 'FALSE'
        updateDB(db, db_dict, xtal)
    else:
        stereosmiles = Chem.MolToSmiles(mol, isomericSmiles=True)
        generateRestraints(compoundID, sampleDir, db, stereosmiles, xtal)
Example #6
0
def chiral_stereo_check(mol):
    Chem.SanitizeMol(mol)
    Chem.DetectBondStereochemistry(mol, -1)
    Chem.AssignStereochemistry(mol, flagPossibleStereoCenters=True, force=True)
    Chem.AssignAtomChiralTagsFromStructure(mol, -1)

    return mol
Example #7
0
def pdbqt2molblock(pdbqt_block, smi, mol_id):
    mol_block = None
    mol = Chem.MolFromPDBBlock('\n'.join(
        [i[:66] for i in pdbqt_block.split('MODEL')[1].split('\n')]),
                               removeHs=False,
                               sanitize=False)
    if mol:
        try:
            template_mol = Chem.MolFromSmiles(smi)
            # explicit hydrogends are removed from carbon atoms (chiral hydrogens) to match pdbqt mol,
            # e.g. [NH3+][C@H](C)C(=O)[O-]
            template_mol = Chem.AddHs(template_mol,
                                      explicitOnly=True,
                                      onlyOnAtoms=[
                                          a.GetIdx()
                                          for a in template_mol.GetAtoms()
                                          if a.GetAtomicNum() != 6
                                      ])
            mol = AllChem.AssignBondOrdersFromTemplate(template_mol, mol)
            Chem.SanitizeMol(mol)
            Chem.AssignStereochemistry(mol,
                                       cleanIt=True,
                                       force=True,
                                       flagPossibleStereoCenters=True)
            mol.SetProp('_Name', mol_id)
            mol_block = Chem.MolToMolBlock(mol)
        except Exception:
            sys.stderr.write(
                f'Could not assign bond orders while parsing PDB: {mol_id}\n')
    return mol_block
Example #8
0
    def standardize(self, mol):
        """Return a standardized version the given molecule.

        The standardization process consists of the following stages: RDKit
        :rdkit:`RemoveHs <Chem.rdmolops-module.html#RemoveHs>`, RDKit
        :rdkit:`SanitizeMol <Chem.rdmolops-module.html#SanitizeMol>`, :class:`~molvs.metal.MetalDisconnector`,
        :class:`~molvs.normalize.Normalizer`, :class:`~molvs.charge.Reionizer`, RDKit
        :rdkit:`AssignStereochemistry <Chem.rdmolops-module.html#AssignStereochemistry>`.

        :param mol: The molecule to standardize.
        :type mol: :rdkit:`Mol <Chem.rdchem.Mol-class.html>`
        :returns: The standardized molecule.
        :rtype: :rdkit:`Mol <Chem.rdchem.Mol-class.html>`
        """
        mol_props = mol.GetPropsAsDict()
        mol = copy.deepcopy(mol)
        Chem.SanitizeMol(mol)
        mol = Chem.RemoveHs(mol)
        mol = self.disconnect_metals(mol)
        mol = self.normalize(mol)
        mol = self.reionize(mol)
        Chem.AssignStereochemistry(mol, force=True, cleanIt=True)
        for k, v in mol_props.items():
            mol.SetProp(k, v)
        # TODO: Check this removes symmetric stereocenters
        return mol
Example #9
0
def graph_from_smiles(smiles):
    graph = MolGraph()
    mol = MolFromSmiles(smiles)
    Chem.DetectBondStereochemistry(mol, -1)
    Chem.AssignStereochemistry(mol, flagPossibleStereoCenters=True, force=True)
    Chem.AssignAtomChiralTagsFromStructure(mol, -1)

    if not mol:
        raise ValueError("Could not parse SMILES string:", smiles)
    atoms_by_rd_idx = {}
    for atom in mol.GetAtoms():
        new_atom_node = graph.new_node('atom',
                                       features=atom_features(atom),
                                       rdkit_ix=atom.GetIdx())
        atoms_by_rd_idx[atom.GetIdx()] = new_atom_node

    for bond in mol.GetBonds():
        atom1_node = atoms_by_rd_idx[bond.GetBeginAtom().GetIdx()]
        atom2_node = atoms_by_rd_idx[bond.GetEndAtom().GetIdx()]
        new_bond_node = graph.new_node('bond', features=bond_features(bond))
        new_bond_node.add_neighbors((atom1_node, atom2_node))
        atom1_node.add_neighbors((atom2_node, ))

    mol_node = graph.new_node('molecule')
    mol_node.add_neighbors(graph.nodes['atom'])
    return graph
Example #10
0
def initialize_rxn_from_smarts(reaction_smarts):
    # Initialize reaction
    rxn = AllChem.ReactionFromSmarts(reaction_smarts)
    rxn.Initialize()
    if rxn.Validate()[1] != 0:
        raise ValueError('validation failed')
    if PLEVEL >= 2: print('Validated rxn without errors')

    # Figure out if there are unnecessary atom map numbers (that are not balanced)
    # e.g., leaving groups for retrosynthetic templates. This is because additional
    # atom map numbers in the input SMARTS template may conflict with the atom map
    # numbers of the molecules themselves
    prd_maps = [
        a.GetAtomMapNum() for prd in rxn.GetProducts() for a in prd.GetAtoms()
        if a.GetAtomMapNum()
    ]

    unmapped = 700
    for rct in rxn.GetReactants():
        rct.UpdatePropertyCache()
        Chem.AssignStereochemistry(rct)
        # Fill in atom map numbers
        for a in rct.GetAtoms():
            if not a.GetAtomMapNum() or a.GetAtomMapNum() not in prd_maps:
                a.SetAtomMapNum(unmapped)
                unmapped += 1
    if PLEVEL >= 2:
        print('Added {} map nums to unmapped reactants'.format(unmapped - 700))
    if unmapped > 800:
        raise ValueError(
            'Why do you have so many unmapped atoms in the template reactants?'
        )

    return rxn
Example #11
0
def fragment_into_dummy_smiles(offmol, cleave_bonds=[], unique_r_groups=True):
    rdmol = Chem.RWMol(offmol.to_rdkit())
    for atom in rdmol.GetAtoms():
        atom.SetAtomMapNum(0)
    utils.assign_stereochemistry(rdmol)
    dummy = Chem.Atom("*")
    r_linkages = {}

    if unique_r_groups:
        r_groups = [(i, i + 1)
                    for i in range(1, (len(cleave_bonds) + 1) * 2, 2)]
    else:
        r_groups = [(1, 2)] * len(cleave_bonds)
    for bond, rs in zip(cleave_bonds, r_groups):
        bond_type = rdmol.GetBondBetweenAtoms(*bond).GetBondType()
        rdmol.RemoveBond(*bond)
        r_linkages[rs[0]] = [rs[1]]
        for atom_index, r in zip(bond, rs):
            dummy_copy = Chem.Atom(dummy)
            dummy_copy.SetAtomMapNum(r)
            new_atom_index = rdmol.AddAtom(dummy_copy)
            rdmol.AddBond(atom_index, new_atom_index, bond_type)
    mols = Chem.GetMolFrags(rdmol, asMols=True)
    for mol in mols:
        counter = 1
        Chem.AssignStereochemistry(mol)
        for atom in mol.GetAtoms():
            if atom.GetSymbol() != "*":
                atom.SetAtomMapNum(counter)
                counter += 1
    smiles = [utils.mol_to_smiles(m) for m in mols]
    return smiles, r_linkages
Example #12
0
    def find_symmetry_classes(self, mol):
        """
        Generate list of tuples of symmetry-equivalent (homotopic) atoms in the molecular graph
        based on: https://sourceforge.net/p/rdkit/mailman/message/27897393/
        Our thanks to Dr Michal Krompiec for the symmetrisation method and its implementation.
        :param mol: molecule to find symmetry classes for (rdkit mol class object)
        :return: A dict where the keys are the atom indices and the values are their type
        (type is arbitrarily based on index; only consistency is needed, no specific values)
        """

        # Check CIPRank is present for first atom (can assume it is present for all afterwards)
        if not mol.GetAtomWithIdx(0).HasProp('_CIPRank'):
            Chem.AssignStereochemistry(mol,
                                       cleanIt=True,
                                       force=True,
                                       flagPossibleStereoCenters=True)

        # Array of ranks showing matching atoms
        cip_ranks = np.array(
            [int(atom.GetProp('_CIPRank')) for atom in mol.GetAtoms()])

        # Map the ranks to the atoms to produce a list of symmetrical atoms
        atom_symmetry_classes = [
            np.where(cip_ranks == rank)[0].tolist()
            for rank in range(max(cip_ranks) + 1)
        ]

        # Convert from list of classes to dict where each key is an atom and each value is its class (just a str)
        atom_symmetry_classes_dict = {}
        # i will be used to define the class (just index based)
        for i, sym_class in enumerate(atom_symmetry_classes):
            for atom in sym_class:
                atom_symmetry_classes_dict[atom] = str(i)

        return atom_symmetry_classes_dict
    def init_search(self, smiles, algorithmname, algorithm_tag):

        print('Conformational search with a ' + algorithmname + ' method')
        print('Energy method: ' + self.method)
        print('Smiles: ' + smiles)
        print('Job name: ' + self.jobname)

        #init molecule and optimise
        mol = Chem.MolFromSmiles(self.smiles)
        mol = Chem.AddHs(mol, explicitOnly=False)
        AllChem.EmbedMolecule(mol,
                              randomSeed=int(time.time()),
                              useRandomCoords=True)

        #write pre optimised molecule
        self.write_pdb(mol, self.jobname + algorithm_tag + 'preoptimised.pdb')

        #optimise start molecule
        AllChem.MMFFOptimizeMolecule(mol)
        mp = AllChem.MMFFGetMoleculeProperties(mol)
        ffm = AllChem.MMFFGetMoleculeForceField(mol, mp)

        #write optimised molecule
        self.write_pdb(mol, self.jobname + algorithm_tag + 'optimised.pdb')

        Chem.SanitizeMol(mol)
        Chem.DetectBondStereochemistry(mol, -1)
        Chem.AssignStereochemistry(mol,
                                   flagPossibleStereoCenters=True,
                                   force=True)
        Chem.AssignAtomChiralTagsFromStructure(mol, -1)

        self.ring_atoms_nr = self.count_ringatoms(mol)
        print('Number of non aromatic ring atoms:', str(self.ring_atoms_nr))

        #create start conformer
        start_conformer = Conformer(mol)
        start_conformer.update_molecule('MMFF94')

        self.min_conformer = start_conformer
        self.min_energy = start_conformer.energy
        print('Start energy:', self.min_energy)

        self.original_conformer = self.min_conformer
        self.original_smiles = self.get_smiles(
            self.original_conformer.molecule)

        start_angles = start_conformer.get_dihedrals()

        print('Initial angles')
        start_angles_only = []
        for angle in start_angles:
            print(angle)
            self.dihedral_atom_id.append(
                (angle[0], angle[1], angle[2], angle[3]))
            start_angles_only.append(angle)
        print('Number of dihedrals:', len(start_angles))

        return start_conformer
Example #14
0
def pct_stereocentres(mol):
    n_atoms = mol.GetNumAtoms()
    if n_atoms > 0:
        Chem.AssignStereochemistry(mol)
        pct_stereo = CalcNumAtomStereoCenters(mol) / n_atoms
    else:
        pct_stereo = 0
    return pct_stereo
Example #15
0
def chiral_stereo_check(mol):
    # avoid sanitization error e.g., dsgdb9nsd_037900.xyz
    Chem.SanitizeMol(mol, SanitizeFlags.SANITIZE_ALL - SanitizeFlags.SANITIZE_PROPERTIES)
    Chem.DetectBondStereochemistry(mol,-1)
    # ignore stereochemistry for now
    Chem.AssignStereochemistry(mol, flagPossibleStereoCenters=True, force=True)
    Chem.AssignAtomChiralTagsFromStructure(mol,-1)
    return mol
 def updateStereoChemAssignments(self):
     if not self.__rdMol:
         return False
     try:
         Chem.AssignAtomChiralTagsFromStructure(self.__rdMol)
         Chem.AssignStereochemistry(self.__rdMol, True, True, True)
         # self.__rdMol.Debug()
     except Exception as e:
         logger.exception("Failing with %s", str(e))
     return False
Example #17
0
def enumerate_double_bond_stereo(mol):
    bonds = get_unspec_double_bonds(mol)
    res = []
    for p in product([0, 1], repeat=len(bonds)):
        m = deepcopy(mol)
        for value, bond in zip(p, bonds):
            set_double_bond_stereo(m.GetBondWithIdx(bond), value)
        Chem.AssignStereochemistry(m, force=True, cleanIt=True)
        res.append(m)
    return res
Example #18
0
  def prepare_mol(self, compute_conformer):
    """Prepares molecule.

    Args:
      compute_conformer: If true, compute a default conformer for molecule.
    """
    if compute_conformer:
      self.mol.Compute2DCoords()  # Clears any existing conformers.
    Chem.AssignStereochemistry(self.mol)
    self.check_indices()
Example #19
0
def initialize_reactants_from_smiles(reactant_smiles):
    # Initialize reactants
    reactants = Chem.MolFromSmiles(reactant_smiles)
    Chem.AssignStereochemistry(reactants, flagPossibleStereoCenters=True)
    reactants.UpdatePropertyCache()
    # To have the product atoms match reactant atoms, we
    # need to populate the Isotope field, since this field
    # gets copied over during the reaction.
    [a.SetIsotope(i+1) for (i, a) in enumerate(reactants.GetAtoms())]
    vprint(2, 'Initialized reactants, assigned isotopes, stereochem, flagpossiblestereocenters')
    return reactants
Example #20
0
def chiral_stereo_check(mol):
    """
    Find and embed chiral information into the model based on the coordinates
    args:
        mol - rdkit molecule, with embeded conformer
    """
    Chem.SanitizeMol(mol)
    Chem.DetectBondStereochemistry(mol, -1)
    Chem.AssignStereochemistry(mol, flagPossibleStereoCenters=True, force=True)
    Chem.AssignAtomChiralTagsFromStructure(mol, -1)

    return
Example #21
0
def chiral_stereo_check(mol):
    # Chem.SanitizeMol(mol)
    # Chem.DetectBondStereochemistry(mol, -1)
    # Chem.AssignStereochemistry(mol, flagPossibleStereoCenters=True, force=True)
    # Chem.AssignAtomChiralTagsFromStructure(mol, -1)

    from rdkit.Chem.rdmolops import SanitizeFlags
    Chem.SanitizeMol(
        mol, SanitizeFlags.SANITIZE_ALL - SanitizeFlags.SANITIZE_PROPERTIES)
    Chem.DetectBondStereochemistry(mol, -1)
    Chem.AssignStereochemistry(mol, flagPossibleStereoCenters=True, force=True)
    return mol
Example #22
0
def molecule_from_smiles(smiles):
    # MolFromSmiles(m, sanitize=True) should be equivalent to
    # MolFromSmiles(m, sanitize=False) -> SanitizeMol(m) -> AssignStereochemistry(m, ...)
    molecule = Chem.MolFromSmiles(smiles, sanitize=False)

    # If sanitization is unsuccessful, catch the error, and try again without
    # the sanitization step that caused the error
    flag = Chem.SanitizeMol(molecule, catchErrors=True)
    if flag != Chem.SanitizeFlags.SANITIZE_NONE:
        Chem.SanitizeMol(molecule, sanitizeOps=Chem.SanitizeFlags.SANITIZE_ALL ^ flag)

    Chem.AssignStereochemistry(molecule, cleanIt=True, force=True)
    return molecule
Example #23
0
def _removeHs(data):
    mols = _parseMolData(data, loadMol=False, useRDKitChemistry=False)
    ms = []
    for molblock in mols:
        mol = parse_molblock(molblock, useRDKitChemistry=False)
        props = molblock.split("M  END")[1].strip()
        props = props if len(props) > 1 else None
        Chem.FastFindRings(mol)
        mol.UpdatePropertyCache(strict=False)
        Chem.AssignAtomChiralTagsFromStructure(mol)
        Chem.AssignStereochemistry(mol, cleanIt=True, force=True)
        ms.append((remove_hs_from_mol(mol), props))
    return _getSDFString(ms)
Example #24
0
def read_one_molecule(input):
    res_mol = Chem.RWMol()
    atoms_header = input.readline().strip()
    if atoms_header == '':
        raise common.End_of_file  # no EOF in Python...
    nb_atoms, name = common.read_atoms_header(atoms_header)
    old2new = {}
    for _i in range(nb_atoms):
        line = input.readline().strip()
        (index, nb_pi, atomic_num, nb_HA, charge, stereo) = \
          common.read_atom(line)
        # add atom
        a = Chem.Atom(atomic_num)
        a.SetFormalCharge(charge)
        if stereo > 0:  # set chirality
            a.SetChiralTag(common.atom_stereo_code_to_chiral_tag(stereo))
        j = res_mol.AddAtom(a)
        # we need to convert atom indexes
        old2new[index] = j
    bonds_header = input.readline().strip()
    nb_bonds = common.read_bonds_header(bonds_header)
    stereo_bonds = []
    for i in range(nb_bonds):
        line = input.readline().strip()
        (start_i, bt, stop_i, (stereo, c, d)) = common.read_bond(line)
        start = old2new[start_i]
        stop = old2new[stop_i]
        # add bond
        n = res_mol.AddBond(start, stop, bt)
        if stereo != rdkit.Chem.rdchem.BondStereo.STEREONONE:
            bi = n - 1
            # convert stereo bond stereo atoms indexes
            a = old2new[c]
            b = old2new[d]
            stereo_bonds.append((bi, stereo, a, b))
    # all atoms and bonds are here now
    # so stereo bonds info can be set
    for (bi, stereo, a, b) in stereo_bonds:
        bond = res_mol.GetBondWithIdx(bi)
        bond.SetStereo(stereo)
        bond.SetStereoAtoms(a, b)
        print('%s stereo %s on bond %d (%d, %d)' %
              (name, common.char_of_bond_stereo(stereo), bi, a, b),
              file=sys.stderr)
    try:
        Chem.SanitizeMol(res_mol)
        Chem.AssignStereochemistry(res_mol)  # ! MANDATORY; AFTER SanitizeMol !
    except rdkit.Chem.rdchem.KekulizeException:
        print("KekulizeException in %s" % name, file=sys.stderr)
    smi = Chem.MolToSmiles(res_mol)
    return (smi, name)
Example #25
0
    def get_atom_features(self, mol):
        AllChem.ComputeGasteigerCharges(mol)
        Chem.AssignStereochemistry(mol)

        hydrogen_donor_match = sum(mol.GetSubstructMatches(self.hydrogen_donor), ())
        hydrogen_acceptor_match = sum(mol.GetSubstructMatches(self.hydrogen_acceptor), ())
        acidic_match = sum(mol.GetSubstructMatches(self.acidic), ())
        basic_match = sum(mol.GetSubstructMatches(self.basic), ())

        ring = mol.GetRingInfo()

        m = []
        for atom_idx in range(mol.GetNumAtoms()):
            atom = mol.GetAtomWithIdx(atom_idx)

            o = []
            o += one_hot(atom.GetSymbol(), ['C', 'O', 'N', 'S', 'Cl', 'F', 'Br', 'P',
                                            'I', 'Si', 'B', 'Na', 'Sn', 'Se', 'other']) if self.use_atom_symbol else []
            o += one_hot(atom.GetDegree(), [0, 1, 2, 3, 4, 5, 6]) if self.use_degree else []
            o += one_hot(atom.GetHybridization(), [Chem.rdchem.HybridizationType.SP,
                                                   Chem.rdchem.HybridizationType.SP2,
                                                   Chem.rdchem.HybridizationType.SP3,
                                                   Chem.rdchem.HybridizationType.SP3D,
                                                   Chem.rdchem.HybridizationType.SP3D2]) if self.use_hybridization else []
            o += one_hot(atom.GetImplicitValence(), [0, 1, 2, 3, 4, 5, 6]) if self.use_implicit_valence else []
            o += one_hot(atom.GetFormalCharge(), [-3, -2, -1, 0, 1, 2, 3]) if self.use_degree else []
            # o += [atom.GetProp("_GasteigerCharge")] if self.use_partial_charge else [] # some molecules return NaN
            o += [atom.GetIsAromatic()] if self.use_aromaticity else []
            o += [ring.IsAtomInRingOfSize(atom_idx, 3),
                  ring.IsAtomInRingOfSize(atom_idx, 4),
                  ring.IsAtomInRingOfSize(atom_idx, 5),
                  ring.IsAtomInRingOfSize(atom_idx, 6),
                  ring.IsAtomInRingOfSize(atom_idx, 7),
                  ring.IsAtomInRingOfSize(atom_idx, 8)] if self.use_ring_size else []
            o += one_hot(atom.GetTotalNumHs(), [0, 1, 2, 3, 4]) if self.use_num_hydrogen else []

            if self.use_chirality:
                try:
                    o += one_hot(atom.GetProp('_CIPCode'), ["R", "S"]) + [atom.HasProp("_ChiralityPossible")]
                except:
                    o += [False, False] + [atom.HasProp("_ChiralityPossible")]
            if self.use_hydrogen_bonding:
                o += [atom_idx in hydrogen_donor_match]
                o += [atom_idx in hydrogen_acceptor_match]
            if self.use_acid_base:
                o += [atom_idx in acidic_match]
                o += [atom_idx in basic_match]

            m.append(o)

        return np.array(m, dtype=float)
Example #26
0
def _stereoInfo(mrv):
    ret = {
        "headers": {
            "tetraHedral": {
                "name": "tetraHedral",
                "type": "COMPLEX",
                "source": "CALCULATOR"
            },
            "doubleBond": {
                "name": "doubleBond",
                "type": "COMPLEX",
                "source": "CALCULATOR"
            }
        },
        "tetraHedral": [],
        "doubleBond": []
    }

    block = MarvinToMol(mrv)
    mol = Chem.MolFromMolBlock(block)
    if not mol:
        print "No mol for block:\n %s" % block
        return ret
    Chem.AssignStereochemistry(mol, flagPossibleStereoCenters=True, force=True)
    for atom in mol.GetAtoms():
        atomIndex = atom.GetIdx()
        if atom.HasProp('_CIPCode'):
            ret["tetraHedral"].append({
                "atomIndex": atomIndex,
                "chirality": atom.GetProp('_CIPCode')
            })

    for bond in mol.GetBonds():
        stereo = str(bond.GetStereo())
        if stereo != "STEREONONE":
            atom1Index = bond.GetBeginAtomIdx()
            atom2Index = bond.GetEndAtomIdx()
            bondIndex = bond.GetIdx()
            if stereo == "STEREOANY":
                cistrans = "E/Z"
            elif stereo == "STEREOZ":
                cistrans = "Z"
            elif stereo == "STEREOE":
                cistrans = "E"
            ret["doubleBond"].append({
                "atom1Index": atom1Index,
                "atom2Index": atom2Index,
                "bondIndex": bondIndex,
                "cistrans": cistrans
            })
    return ret
Example #27
0
def _find_rd_stereocenters(
    molecule: Molecule,
) -> Tuple[List[int], List[Tuple[int, int]]]:
    """A method which returns the of the stereogenic atom and bonds of a molecule
    using the RDKit.

    Parameters
    ----------
    molecule
        The molecule whose stereocenters should be returned.

    Notes
    -----
    * This method currently deals with RDKit directly and should be removed once
      the API points suggested in openff-toolkit issue #903 have been added.

    Returns
    -------
        The indices of the stereogenic atoms in the molecule and the indices of the
        atoms involved in stereogenic bonds in the molecule.
    """

    from rdkit import Chem

    rd_molecule = molecule.to_rdkit()

    Chem.AssignStereochemistry(
        rd_molecule, cleanIt=True, force=True, flagPossibleStereoCenters=True
    )

    stereogenic_atoms = {
        atom.GetIdx()
        for atom in rd_molecule.GetAtoms()
        if atom.HasProp("_ChiralityPossible")
    }

    # Clear any previous assignments on the bonds, since FindPotentialStereo
    # may not overwrite it
    for bond in rd_molecule.GetBonds():
        bond.SetStereo(Chem.BondStereo.STEREONONE)

    Chem.FindPotentialStereoBonds(rd_molecule, cleanIt=True)

    stereogenic_bonds = {
        (bond.GetBeginAtomIdx(), bond.GetEndAtomIdx())
        for bond in rd_molecule.GetBonds()
        if bond.GetStereo() == Chem.BondStereo.STEREOANY
    }

    return sorted(stereogenic_atoms), sorted(stereogenic_bonds)
Example #28
0
def standardize_mol(mol):
    """Accepts `mol` rdkit molecule returns a sanitized version with properly assigend stereochemistry.

    Parameters
    ----------
    mol : rdkit.Chem.rdchem.Mol object

    Returns
    -------
    mol : rdkit.Chem.rdchem.Mol object
    """
    flag1 = Chem.SanitizeMol(mol)
    flag2 = Chem.AssignStereochemistry(mol)
    return mol
Example #29
0
def initialize_reactants_from_smiles(reactant_smiles):
    # Initialize reactants
    reactants = Chem.MolFromSmiles(reactant_smiles)
    Chem.AssignStereochemistry(reactants, flagPossibleStereoCenters=True)
    reactants.UpdatePropertyCache(strict=False)
    # To have the product atoms match reactant atoms, we
    # need to populate the map number field, since this field
    # gets copied over during the reaction via reactant_atom_idx.
    [a.SetAtomMapNum(i + 1) for (i, a) in enumerate(reactants.GetAtoms())]
    if PLEVEL >= 2:
        print(
            'Initialized reactants, assigned map numbers, stereochem, flagpossiblestereocenters'
        )
    return reactants
Example #30
0
    def embed(self, mol):
        """
        Gives the molecule intial 3D coordinates.

        Args:
            mol (RDKit Mol): The molecule to embed.
        """

        Chem.AssignStereochemistry(
            mol, cleanIt=True,
            force=True)  # necessary if bond had been cut next to double bond
        while not AllChem.EmbedMultipleConfs(
                mol, numConfs=self.num_confs, params=self.params.params):
            self.params.randomSeed = int(time(
            ))  # find new seed because last seed wasnt able to embed molecule