Example #1
0
  def test0Conformers(self) :
    """Test the conformer data structure"""
    mol = Chem.MolFromSmiles("CC")
    conf = Chem.Conformer(2)
    conf.SetAtomPosition(0, (-0.5, 0.0, 0.0))
    conf.SetAtomPosition(1, (1.0, 0.0, 0.0))
    conf.SetId(0)
    cid = mol.AddConformer(conf)

    self.assertTrue(cid == 0)
    
    conf2 = mol.GetConformer(0)
    self.assertTrue(conf2.GetId() == cid)
    pt1 = conf2.GetAtomPosition(0)
    self.assertTrue(ptEq(pt1, Point3D(-0.5, 0.0, 0.0)))
    
    pt2 = conf2.GetAtomPosition(1)
    self.assertTrue(ptEq(pt2, Point3D(1.0, 0.0, 0.0)))
    
    #changing conf should not change conf2 - related to issue 217
    conf.SetAtomPosition(1, Point3D(2.0, 0.0, 0.0))
    pt2 = conf2.GetAtomPosition(1)
    self.assertTrue(feq(pt2[0], 1.0))

    conf = Chem.Conformer(2)
    conf.SetAtomPosition(0, Point3D(-0.5, 0.0, 0.0))
    conf.SetAtomPosition(1, Point3D(1.0, 0.0, 0.0))
    conf.SetId(2)

    cid = mol.AddConformer(conf, 0)
    self.assertTrue(cid == 2)
    conf3 = mol.GetConformer(2)
Example #2
0
def xyz2ac(atomic_num_list, xyz):
    import numpy as np
    mol = get_proto_mol(atomic_num_list)

    conf = Chem.Conformer(mol.GetNumAtoms())
    for i in range(mol.GetNumAtoms()):
        conf.SetAtomPosition(i, (xyz[i][0], xyz[i][1], xyz[i][2]))
    mol.AddConformer(conf)

    d_mat = Chem.Get3DDistanceMatrix(mol)
    pt = Chem.GetPeriodicTable()

    num_atoms = len(atomic_num_list)
    ac = np.zeros((num_atoms, num_atoms)).astype(int)

    for i in range(num_atoms):
        a_i = mol.GetAtomWithIdx(i)
        rcov_i = pt.GetRcovalent(a_i.GetAtomicNum()) * 1.24
        for j in range(i + 1, num_atoms):
            a_j = mol.GetAtomWithIdx(j)
            rcov_j = pt.GetRcovalent(a_j.GetAtomicNum()) * 1.24
            if d_mat[i, j] <= rcov_i + rcov_j:
                ac[i, j] = 1
                ac[j, i] = 1

    return ac, mol
Example #3
0
def make_rd_mol(xyz, c, bonds, channels):

    rd_mol = Chem.RWMol()

    for c_ in c:
        atomic_num = channels[c_].atomic_num
        rd_atom = Chem.Atom(atomic_num)
        rd_mol.AddAtom(rd_atom)

    n_atoms = rd_mol.GetNumAtoms()
    rd_conf = Chem.Conformer(n_atoms)

    for i, (x, y, z) in enumerate(xyz):
        rd_conf.SetAtomPosition(i, (x, y, z))

    rd_mol.AddConformer(rd_conf)

    if np.any(bonds):
        n_bonds = 0
        for i in range(n_atoms):
            for j in range(i + 1, n_atoms):
                if bonds[i, j]:
                    rd_mol.AddBond(i, j, Chem.BondType.SINGLE)
                    n_bonds += 1

    return rd_mol
Example #4
0
def select_conformer(molobj, method=None):
    """

    Find the conformer with lowest energy

    # TODO Add other energy methods than MMFF
    # TODO Add interface to ppqm.sqm

    """

    res = AllChem.MMFFOptimizeMoleculeConfs(molobj, numThreads=0)
    res = np.array(res)
    energies = res[:,1]
    not_converged = res[:,1]

    # TODO Ignore not_converged != 0

    idx = np.argmin(energies)

    coord = molobj_to_coordinates(molobj, idx=idx)

    conf = Chem.Conformer(len(coord))
    for i, xyz in enumerate(coord):
        conf.SetAtomPosition(i, xyz)

    molobj = copy.deepcopy(molobj)
    molobj.RemoveAllConformers()
    molobj.AddConformer(conf, assignId=True)

    return molobj
Example #5
0
def to_rdmol(plams_mol, sanitize=True):
    """
    Translate a PLAMS molecule into an RDKit molecule type.

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

    """
    if isinstance(plams_mol, Chem.Mol):
        return plams_mol
    # Create rdkit molecule
    e = Chem.EditableMol(Chem.Mol())
    for atom in plams_mol.atoms:
        a = Chem.Atom(atom.atnum)
        if 'charge' in atom.properties:
            a.SetFormalCharge(atom.properties.charge)
        if 'pdb_info' in atom.properties:
            set_PDBresidueInfo(a, atom.properties.pdb_info)
        e.AddAtom(a)
    for bond in plams_mol.bonds:
        a1 = plams_mol.atoms.index(bond.atom1)
        a2 = plams_mol.atoms.index(bond.atom2)
        e.AddBond(a1, a2, Chem.BondType(bond.order))
    rdmol = e.GetMol()
    if sanitize:
        Chem.SanitizeMol(rdmol)
    conf = Chem.Conformer()
    for a in range(len(plams_mol.atoms)):
        atom = plams_mol.atoms[a]
        p = Geometry.Point3D(atom._getx(), atom._gety(), atom._getz())
        conf.SetAtomPosition(a, p)
    rdmol.AddConformer(conf)
    return rdmol
Example #6
0
def AtomListToSubMol(mol, amap, includeConformer=False):
    """
    Parameters
    ----------
        mol: rdkit.Chem.rdchem.Mol
            Molecule
        amap: array-like
            List of atom indices (zero-based)
        includeConformer: bool (default=True)
            Toogle to include atoms coordinates in submolecule.

    Returns
    -------
        submol: rdkit.Chem.rdchem.RWMol
            Submol determined by specified atom list
    """
    if not isinstance(amap, list):
        amap = list(amap)
    submol = Chem.RWMol(Chem.Mol())
    for aix in amap:
        submol.AddAtom(mol.GetAtomWithIdx(aix))
    for i, j in combinations(amap, 2):
        bond = mol.GetBondBetweenAtoms(i, j)
        if bond:
            submol.AddBond(amap.index(i), amap.index(j), bond.GetBondType())
    if includeConformer:
        for conf in mol.GetConformers():
            new_conf = Chem.Conformer(len(amap))
            for i in range(len(amap)):
                new_conf.SetAtomPosition(i, conf.GetAtomPosition(amap[i]))
                new_conf.SetId(conf.GetId())
                new_conf.Set3D(conf.Is3D())
            submol.AddConformer(new_conf)
    return submol
Example #7
0
  def assertBondStereoRoundTrips(self, fname):
    path = os.path.join(RDConfig.RDCodeDir, 'Chem', 'test_data', fname)
    mol = Chem.MolFromMolFile(path)
    refSmiles = mol.GetProp("_Name")
    self.assertTrue(len(refSmiles) > 0)
    self.assertEqual(Chem.MolToSmiles(mol, isomericSmiles=True), refSmiles)

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

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

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

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

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

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

    self.assertEqual(Chem.MolToSmiles(newmol, isomericSmiles=True), refSmiles)
Example #8
0
def xyz2AC_huckel(atomicNumList, xyz, charge):
    import numpy as np
    mol = get_proto_mol(atomicNumList)

    conf = Chem.Conformer(mol.GetNumAtoms())
    for i in range(mol.GetNumAtoms()):
        conf.SetAtomPosition(i, (xyz[i][0], xyz[i][1], xyz[i][2]))
    mol.AddConformer(conf)

    num_atoms = len(atomicNumList)
    AC = np.zeros((num_atoms, num_atoms)).astype(int)

    mol_huckel = Chem.Mol(mol)
    mol_huckel.GetAtomWithIdx(0).SetFormalCharge(
        charge)  #mol charge arbitrarily added to 1st atom

    passed, result = rdEHTTools.RunMol(mol_huckel)
    opop = result.GetReducedOverlapPopulationMatrix()
    tri = np.zeros((num_atoms, num_atoms))
    tri[np.tril(np.ones(
        (num_atoms, num_atoms),
        dtype=bool))] = opop  #lower triangular to square matrix
    for i in range(num_atoms):
        for j in range(i + 1, num_atoms):
            pair_pop = abs(tri[j, i])
            if pair_pop >= 0.15:  #arbitry cutoff for bond. May need adjustment
                AC[i, j] = 1
                AC[j, i] = 1

    return AC, mol
Example #9
0
    def createMol(self, resTuples):
        proteinCoords = getCoordinates(self.protein)
        asite = Chem.RWMol()

        self.atomMap['A:P'] = {}
        for atom in self.protein.GetAtoms():
            if atom.GetAtomicNum() == 1:
                continue
            res = getIdTupleFromPDBAtom(atom)
            if res in resTuples:
                asiteIdx = asite.AddAtom(atom)
                self.atomMap['A:P'][asiteIdx] = atom.GetIdx()
        self.atomMap['P:A'] = {v: k for k, v in self.atomMap['A:P'].items()}

        asiteNatoms = asite.GetNumAtoms()
        asiteConf = Chem.Conformer(asiteNatoms)
        for atom in asite.GetAtoms():
            asiteConf.SetAtomPosition(
                atom.GetIdx(),
                proteinCoords[self.atomMap['A:P'][atom.GetIdx()]])
        asite.AddConformer(asiteConf)

        for atom in asite.GetAtoms():
            atom.SetIsAromatic(False)

        asite = Chem.Mol(asite)

        return asite
Example #10
0
  def test0AddHds(self) :
    mol = Chem.MolFromSmiles("CC")
    conf = Chem.Conformer(1)
    conf.SetAtomPosition(0, Point3D(-0.5, 0.0, 0.0))
    conf.SetAtomPosition(1, Point3D(1.0, 0.0, 0.0))
    cid = mol.AddConformer(conf)

    conf2 = mol.GetConformer()
    self.assertTrue(conf2.GetNumAtoms() == 2)

    nmol = Chem.AddHs(mol, 0,1)
    conf3 = nmol.GetConformer()
    self.assertTrue(conf3.GetNumAtoms() == 8)
    self.assertTrue(conf2.GetNumAtoms() == 2)

    targetCoords = [[-0.5, 0.0, 0.0],
                    [1.0, 0.0, 0.0],
                    [-0.8667, 0.0, 1.03709],
                    [-0.8667, 0.8981, -0.5185],
                    [-0.8667, -0.8981, -0.5185],
                    [1.3667, 0.0, -1.0371],
                    [1.36667, 0.8981, 0.5185],
                    [1.36667, -0.8981, 0.5185]]

    for i in range(8) :
      pt = conf3.GetAtomPosition(i)
      self.assertTrue(ptEq(pt, Point3D(*tuple(targetCoords[i]))))
Example #11
0
    def to_RDKMol(self):
        """Return an RDKMol object for the configuration, template, or subset."""
        index = {}
        indices = []
        rdk_mol = Chem.RWMol()
        for atno, _id in zip(self.atoms.atomic_numbers, self.atoms.ids):
            idx = rdk_mol.AddAtom(Chem.Atom(atno))
            index[_id] = idx
            indices.append(idx)

        bond_types = {
            1: Chem.BondType.SINGLE,
            2: Chem.BondType.DOUBLE,
            3: Chem.BondType.TRIPLE,
        }
        for row in self.bonds.bonds():
            rdk_mol.AddBond(index[row["i"]], index[row["j"]],
                            bond_types[row["bondorder"]])

        natom = self.atoms.n_atoms
        conf = Chem.Conformer(natom)
        for idx, xyz in zip(indices, self.atoms.coordinates):
            conf.SetAtomPosition(idx, xyz)

        rdk_mol.AddConformer(conf)
        Chem.rdmolops.SanitizeMol(rdk_mol)

        return rdk_mol
Example #12
0
def to_rdmol(plams_mol, sanitize=True):
    """
    Translate a PLAMS molecule into an RDKit molecule type
    """
    # Create rdkit molecule
    e = Chem.EditableMol(Chem.Mol())
    for atom in plams_mol.atoms:
        a = Chem.Atom(atom.atnum)
        ch = atom.properties.charge
        if isinstance(ch, int):
            a.SetFormalCharge(ch)
        e.AddAtom(a)
    for bond in plams_mol.bonds:
        a1 = plams_mol.atoms.index(bond.atom1)
        a2 = plams_mol.atoms.index(bond.atom2)
        e.AddBond(a1, a2, Chem.BondType(bond.order))
    rdmol = e.GetMol()
    if sanitize:
        Chem.SanitizeMol(rdmol)
    conf = Chem.Conformer()
    for a in range(len(plams_mol.atoms)):
        atom = plams_mol.atoms[a]
        p = Geometry.Point3D(atom._getx(), atom._gety(), atom._getz())
        conf.SetAtomPosition(a, p)
    rdmol.AddConformer(conf)
    return rdmol
Example #13
0
    def xyz2AC(atomicNumList, xyz):

        mol = get_proto_mol(atomicNumList)

        conf = Chem.Conformer(mol.GetNumAtoms())
        for i in range(mol.GetNumAtoms()):
            conf.SetAtomPosition(i, (xyz[i][0], xyz[i][1], xyz[i][2]))
        mol.AddConformer(conf)

        dMat = Chem.Get3DDistanceMatrix(mol)
        pt = Chem.GetPeriodicTable()

        num_atoms = len(atomicNumList)
        AC = np.zeros((num_atoms, num_atoms)).astype(int)

        for i in range(num_atoms):
            a_i = mol.GetAtomWithIdx(i)
            Rcov_i = pt.GetRcovalent(a_i.GetAtomicNum()) * 1.30
            for j in range(i + 1, num_atoms):
                a_j = mol.GetAtomWithIdx(j)
                Rcov_j = pt.GetRcovalent(a_j.GetAtomicNum()) * 1.30
                if dMat[i, j] <= Rcov_i + Rcov_j:
                    AC[i, j] = 1
                    AC[j, i] = 1

        return AC, mol
Example #14
0
def addConf(mol):
  conf = Chem.Conformer(mol.GetNumAtoms())
  for i in range(mol.GetNumAtoms()):
    conf.SetAtomPosition(i,(0.,0.,0.))
  mol.AddConformer(conf)
  mb = Chem.MolToMolBlock(mol)
  mb = Chem.MolToMolBlock(mol)
Example #15
0
def make_rd_mol(coords, types, bonds, typer):
    '''
    Create an RWMol from numpy arrays of coords
    and types, optional bonds, and an AtomTyper.
    No atomic properties other than the elements
    and coordinates are set.
    '''
    rd_mol = Chem.RWMol()

    for type_vec in types:
        atom_type = typer.get_atom_type(type_vec)
        rd_atom = Chem.Atom(atom_type.atomic_num)
        rd_mol.AddAtom(rd_atom)

    n_atoms = rd_mol.GetNumAtoms()
    rd_conf = Chem.Conformer(n_atoms)

    for i, coord in enumerate(coords):
        x, y, z = [float(c) for c in coord]
        rd_conf.SetAtomPosition(i, (x, y, z)) # must be float64

    rd_mol.AddConformer(rd_conf)

    if bonds is not None and np.any(bonds):
        n_bonds = 0
        for i in range(n_atoms):
            for j in range(i+1, n_atoms):
                if bonds[i,j]:
                    rd_mol.AddBond(i, j, Chem.BondType.SINGLE)
                    n_bonds += 1

    return rd_mol
Example #16
0
def toRDKITmol(mol, protidx, sanitize=True, removeHs=False):
    # Taken from rdkit/Code/GraphMol/FileParsers/PDBParser.cpp
    conformer = Chem.Conformer(len(protidx))
    conformer.Set3D(True)
    conformer.SetId(0)
    rdmol = Chem.RWMol()
    atomlist = []
    for ii, i in enumerate(protidx):
        a = Chem.Atom(mol.element[i])
        a.SetFormalCharge(int(mol.charge[i]))
        info = Chem.AtomPDBResidueInfo(atomName=mol.name[i],
                                       serialNumber=int(mol.serial[i]),
                                       altLoc=mol.altloc[i],
                                       residueName=mol.resname[i],
                                       residueNumber=int(mol.resid[i]),
                                       chainId=mol.chain[i],
                                       insertionCode=mol.insertion[i],
                                       occupancy=float(mol.occupancy[i]),
                                       tempFactor=float(mol.beta[i]),
                                       isHeteroAtom=mol.record[i] == 'HETATM')
        a.SetMonomerInfo(info)

        rdmol.AddAtom(a)
        atomlist.append(a)
        coor = [float(c) for c in mol.coords[i, :, mol.frame]]
        conformer.SetAtomPosition(ii, Point3D(coor[0], coor[1],
                                              coor[2]))  # Correct the atom idx
    rdmol.AddConformer(conformer)

    # Here I diverge from the C++ parser because you cannot instantiate Chem.Bond objects in python
    # I also don't take into account double/triple bonds etc since I don't think we actually store them in Molecule
    for b in mol._getBonds():
        if b[0] in protidx and b[1] in protidx:
            bond = rdmol.GetBondBetweenAtoms(int(b[0]), int(b[1]))
            if bond is None:
                rdmol.AddBond(int(np.where(protidx == b[0])[0]),
                              int(np.where(protidx == b[1])[0]),
                              Chem.BondType.SINGLE)

    # Proximitybonds I already did by using _getBonds which calls _guessBonds
    # TODO: Set PDB double bonds

    # Calculate explicit valence of atoms
    for a in atomlist:
        pass

    if sanitize:
        if removeHs:
            Chem.RemoveHs(rdmol)
        else:
            Chem.SanitizeMol(rdmol)
    else:
        rdmol.UpdatePropertyCache()

    # Set tetrahedral chirality from 3D co-ordinates
    Chem.AssignAtomChiralTagsFromStructure(rdmol)
    StandardPDBResidueChirality(rdmol)

    return rdmol
Example #17
0
    def get_3D_mol(self):
        mol = Chem.Mol(self.mol)
        conf = Chem.Conformer(mol.GetNumAtoms())
        for i, xyz in enumerate(self.coord):
            conf.SetAtomPosition(i, xyz)

        mol.AddConformer(conf)
        return mol
Example #18
0
def EmbedMol(mol,
             bm,
             atomMatch=None,
             weight=2.0,
             randomSeed=-1,
             excludedVolumes=None):
    """  Generates an embedding for a molecule based on a bounds matrix and adds
  a conformer (id 0) to the molecule

  if the optional argument atomMatch is provided, it will be used to provide
  supplemental weights for the embedding routine (used in the optimization
  phase to ensure that the resulting geometry really does satisfy the
  pharmacophore).

  if the excludedVolumes is provided, it should be a sequence of
  ExcludedVolume objects

  >>> m = Chem.MolFromSmiles('c1ccccc1C')
  >>> bounds = MolDG.GetMoleculeBoundsMatrix(m)
  >>> bounds.shape == (7, 7)
  True
  >>> m.GetNumConformers()
  0
  >>> EmbedMol(m,bounds,randomSeed=23)
  >>> m.GetNumConformers()
  1


  """
    nAts = mol.GetNumAtoms()
    weights = []
    if (atomMatch):
        for i in range(len(atomMatch)):
            for j in range(i + 1, len(atomMatch)):
                weights.append((i, j, weight))
    if (excludedVolumes):
        for vol in excludedVolumes:
            idx = vol.index
            # excluded volumes affect every other atom:
            for i in range(nAts):
                weights.append((i, idx, weight))
    coords = DG.EmbedBoundsMatrix(bm,
                                  weights=weights,
                                  numZeroFail=1,
                                  randomSeed=randomSeed)
    #for row in coords:
    #  print(', '.join(['%.2f'%x for x in row]))

    conf = Chem.Conformer(nAts)
    conf.SetId(0)
    for i in range(nAts):
        conf.SetAtomPosition(i, list(coords[i]))
    if excludedVolumes:
        for vol in excludedVolumes:
            vol.pos = numpy.array(coords[vol.index])

        #print('   % 7.4f   % 7.4f   % 7.4f Ar  0  0  0  0  0  0  0  0  0  0  0  0'%tuple(coords[-1]), file=sys.stderr)
    mol.AddConformer(conf)
Example #19
0
def RDMolFromGraphs(node_list, adjacency_matrix, xyz_coord, remap=None):
    #xyz_mean = [0.5567917341433811, 0.10013086135351022, 0.006413393431574624]
    #xyz_std = [3.40762324684836, 2.6455335437418093, 2.3609727916942096]
    #print(xyz_coord)
    #xyz_coord = xyz_coord * xyz_std + xyz_mean
    #print(xyz_coord)
    # create empty editable mol object
    mol = Chem.RWMol()
    conformer = Chem.Conformer(len(node_list))
    #print(xyz_coord)
    # add atoms to mol and keep track of index
    node_to_idx = {}
    for i in range(len(node_list)):
        a = Chem.Atom(node_list[i])
        atom_position = Point3D(xyz_coord[i, 0], xyz_coord[i, 1], xyz_coord[i,
                                                                            2])
        #print(a)
        conformer.SetAtomPosition(i, atom_position)
        molIdx = mol.AddAtom(a)
        node_to_idx[i] = molIdx

    # add bonds between adjacent atoms
    xx, yy = np.where(np.triu(adjacency_matrix, k=1))
    vv = adjacency_matrix[xx, yy]
    for ix, iy, bond in zip(xx, yy, vv):
        # add relevant bond type (there are many more of these)
        if remap is not None:
            bond = remap[bond]
        if bond == 1.:
            bond_type = Chem.rdchem.BondType.SINGLE
            mol.AddBond(node_to_idx[ix], node_to_idx[iy], bond_type)
        elif bond == 1.5:
            bond_type = Chem.rdchem.BondType.AROMATIC
            mol.AddBond(node_to_idx[ix], node_to_idx[iy], bond_type)
        elif bond == 2.:
            bond_type = Chem.rdchem.BondType.DOUBLE
            mol.AddBond(node_to_idx[ix], node_to_idx[iy], bond_type)
        elif bond == 3.:
            bond_type = Chem.rdchem.BondType.TRIPLE
            mol.AddBond(node_to_idx[ix], node_to_idx[iy], bond_type)
        else:
            raise ValueError("Invalid bond type in matrix")

    # Convert RWMol to Mol object
    mol = mol.GetMol()
    Chem.Kekulize(mol)
    Chem.SanitizeMol(mol)

    # Convert RWMol to SMILES
    # Chem.RemoveHs(mol)
    smiles = Chem.MolToSmiles(mol, kekuleSmiles=False)
    #print(smiles)

    # Add 3D conformation to RDKit molecule
    added_conformer = mol.AddConformer(conformer, assignId=True)

    return smiles, mol
Example #20
0
def mol_from_json(symbols, connectivity, geometry, permute_xyz=False):
    """
    Generate RDkit.Chem.Mol from QCSchema molecule specs.
    Parameters
    ----------
    inp_molecule: dict
        Must include symbols and connectivity. Geometry is optional. If geometry is given, stereochemistry will be taken
        from coordinates

    Returns
    -------
    molecule: rdkit.Chem.Mol
    """

    from rdkit.Geometry.rdGeometry import Point3D

    _BO_DISPATCH_TABLE = {
        1: Chem.BondType.SINGLE,
        2: Chem.BondType.DOUBLE,
        3: Chem.BondType.TRIPLE
    }

    geometry = geometry.reshape(int(len(geometry) / 3), 3)
    conformer = Chem.Conformer(len(symbols))
    has_geometry = True

    molecule = Chem.Mol()
    em = Chem.RWMol(molecule)
    for i, s in enumerate(symbols):
        atom = em.AddAtom(Chem.Atom(_symbols[s]))
        atom_position = Point3D(geometry[i][0], geometry[i][1], geometry[i][2])
        conformer.SetAtomPosition(atom, atom_position)

    # Add connectivity
    for bond in connectivity:
        bond_type = _BO_DISPATCH_TABLE[bond[-1]]
        em.AddBond(bond[0], bond[1], bond_type)

    molecule = em.GetMol()
    try:
        Chem.SanitizeMol(molecule)
    except:
        raise RuntimeError("Could not sanitize molecule")

    # Add coordinates
    if has_geometry:
        initial_conformer_id = molecule.AddConformer(conformer, assignId=True)
        # Assign stereochemistry from coordinates
        from rdkit.Chem import rdmolops
        rdmolops.AssignStereochemistryFrom3D(molecule,
                                             confId=initial_conformer_id,
                                             replaceExistingTags=True)
        if not permute_xyz:
            # Add a tag to keep current order
            molecule.SetProp("_json_geometry", '1')

    return molecule
Example #21
0
def create_rdkit_mol(species,
                     coords,
                     bond_types,
                     formal_charge=None,
                     name=None,
                     force_sanitize=True):
    """
    Create a rdkit mol from scratch.

    Followed: https://sourceforge.net/p/rdkit/mailman/message/36474923/

    Args:
        species (list): species str of each molecule
        coords (2D array): positions of atoms
        bond_types (dict): with bond indices (2 tuple) as key and bond type
            (e.g. Chem.rdchem.BondType.DOUBLE) as value
        formal_charge (list): formal charge of each atom
        name (str): name of the molecule
        force_sanitize (bool): whether to force the sanitization of molecule.
            If `True` and the sanitization fails, it generally throw an error
            and then stops. If `False`, will try to sanitize first, but if it fails,
            will proceed smoothly giving a warning message.

    Returns:
        rdkit Chem.Mol
    """

    m = Chem.Mol()
    edm = Chem.EditableMol(m)
    conformer = Chem.Conformer(len(species))

    for i, (s, c) in enumerate(zip(species, coords)):
        atom = Chem.Atom(s)
        atom.SetNoImplicit(True)
        if formal_charge is not None:
            cg = formal_charge[i]
            if cg is not None:
                atom.SetFormalCharge(cg)
        atom_idx = edm.AddAtom(atom)
        conformer.SetAtomPosition(atom_idx, Point3D(*c))

    for b, t in bond_types.items():
        edm.AddBond(b[0], b[1], t)

    m = edm.GetMol()
    if force_sanitize:
        Chem.SanitizeMol(m)
    else:
        try:
            Chem.SanitizeMol(m)
        except Exception as e:
            warnings.warn(f"Cannot sanitize molecule {name}, because {str(e)}")
    m.AddConformer(conformer, assignId=False)

    m.SetProp("_Name", str(name))

    return m
Example #22
0
def _generate_conformer(coordinates):
    # generate a conformation object
    new_conf = Chem.Conformer()
    for idx, c in enumerate(coordinates):
        point = Geometry.rdGeometry.Point3D()
        point.x = float(c[0].value_in_unit(unit.angstrom))
        point.y = float(c[1].value_in_unit(unit.angstrom))
        point.z = float(c[2].value_in_unit(unit.angstrom))
        new_conf.SetAtomPosition(idx, point)
    return new_conf
Example #23
0
def add_conformer(molobj, coordinates):

    conf = Chem.Conformer(len(coordinates))

    for i, coordinate in enumerate(coordinates):
        conf.SetAtomPosition(i, coordinate)

    molobj.AddConformer(conf, assignId=True)

    return
Example #24
0
def make_conformer(mol, conf_a, conf_b):
    mol.RemoveAllConformers()
    mol = Chem.CombineMols(mol, mol)
    cc = Chem.Conformer(mol.GetNumAtoms())
    conf = np.concatenate([conf_a, conf_b])
    conf *= 10
    for idx, pos in enumerate(onp.asarray(conf)):
        cc.SetAtomPosition(idx, (float(pos[0]), float(pos[1]), float(pos[2])))
    mol.AddConformer(cc)

    return mol
Example #25
0
 def testGithub4167(self):
     with Chem.SDMolSupplier(os.path.join(self.dataDir, 'github4167.sdf'),
                             removeHs=False,
                             sanitize=True) as suppl:
         m1 = suppl[0]
         m2 = suppl[1]
     m1.AddConformer(Chem.Conformer(m2.GetConformer()), assignId=True)
     v1_0 = rdMD.CalcSpherocityIndex(m1)
     v1_1 = rdMD.CalcSpherocityIndex(m1, confId=1, force=True)
     v2 = rdMD.CalcSpherocityIndex(m2)
     self.assertNotEqual(v1_0, v1_1)
     self.assertEqual(v1_1, v2)
Example #26
0
def _getRDKitEnv(mol, bondPath, baseRad, aromaticColor, extraColor,
                 nonAromaticColor, **kwargs):
    if not mol.GetNumConformers():
        rdDepictor.Compute2DCoords(mol)

    # get the atoms for highlighting
    atomsToUse = set()
    for b in bondPath:
        atomsToUse.add(mol.GetBondWithIdx(b).GetBeginAtomIdx())
        atomsToUse.add(mol.GetBondWithIdx(b).GetEndAtomIdx())

    # set the coordinates of the submol based on the coordinates of the original molecule
    amap = {}
    submol = Chem.PathToSubmol(mol, bondPath, atomMap=amap)
    Chem.FastFindRings(submol)
    conf = Chem.Conformer(submol.GetNumAtoms())
    confOri = mol.GetConformer(0)
    for i1, i2 in amap.items():
        conf.SetAtomPosition(i2, confOri.GetAtomPosition(i1))
    submol.AddConformer(conf)
    envSubmol = []
    for i1, i2 in amap.items():
        for b in bondPath:
            beginAtom = amap[mol.GetBondWithIdx(b).GetBeginAtomIdx()]
            endAtom = amap[mol.GetBondWithIdx(b).GetEndAtomIdx()]
            envSubmol.append(
                submol.GetBondBetweenAtoms(beginAtom, endAtom).GetIdx())

    # color all atoms of the submol in gray which are not part of the bit
    # highlight atoms which are in rings
    atomcolors, bondcolors = {}, {}
    highlightAtoms, highlightBonds = [], []
    highlightRadii = {}
    for aidx in amap.keys():
        if aidx in atomsToUse:
            color = None
            if aromaticColor and mol.GetAtomWithIdx(aidx).GetIsAromatic():
                color = aromaticColor
            elif nonAromaticColor and not mol.GetAtomWithIdx(
                    aidx).GetIsAromatic():
                color = nonAromaticColor
            if color is not None:
                atomcolors[amap[aidx]] = color
                highlightAtoms.append(amap[aidx])
                highlightRadii[amap[aidx]] = baseRad
    color = extraColor
    for bid in submol.GetBonds():
        bidx = bid.GetIdx()
        if bidx not in envSubmol:
            bondcolors[bidx] = color
            highlightBonds.append(bidx)
    return FingerprintEnv(submol, highlightAtoms, atomcolors, highlightBonds,
                          bondcolors, highlightRadii)
Example #27
0
def ob_mol_to_rd_mol(ob_mol):
    '''
    Convert an OBMol to an RWMol, copying
    over the elements, coordinates, formal
    charges, bonds and aromaticity.
    '''
    n_atoms = ob_mol.NumAtoms()
    rd_mol = Chem.RWMol()
    rd_conf = Chem.Conformer(n_atoms)

    for ob_atom in ob.OBMolAtomIter(ob_mol):

        rd_atom = Chem.Atom(ob_atom.GetAtomicNum())
        rd_atom.SetFormalCharge(ob_atom.GetFormalCharge())
        rd_atom.SetIsAromatic(ob_atom.IsAromatic())
        rd_atom.SetNumExplicitHs(ob_atom.GetImplicitHCount())
        rd_atom.SetNoImplicit(True) # don't use rdkit valence model
        rd_atom.SetHybridization(ob_hyb_to_rd_hyb(ob_atom))

        idx = rd_mol.AddAtom(rd_atom)

        rd_coords = Geometry.Point3D(
            ob_atom.GetX(), ob_atom.GetY(), ob_atom.GetZ()
        )
        rd_conf.SetAtomPosition(idx, rd_coords)

    rd_mol.AddConformer(rd_conf)

    for ob_bond in ob.OBMolBondIter(ob_mol):

        # OB uses 1-indexing, rdkit uses 0
        i = ob_bond.GetBeginAtomIdx() - 1
        j = ob_bond.GetEndAtomIdx() - 1

        bond_order = ob_bond.GetBondOrder()
        if bond_order == 1:
            bond_type = Chem.BondType.SINGLE
        elif bond_order == 2:
            bond_type = Chem.BondType.DOUBLE
        elif bond_order == 3:
            bond_type = Chem.BondType.TRIPLE
        else:
            raise Exception('unknown bond order {}'.format(bond_order))

        rd_mol.AddBond(i, j, bond_type)
        rd_bond = rd_mol.GetBondBetweenAtoms(i, j)
        rd_bond.SetIsAromatic(ob_bond.IsAromatic())

    Chem.GetSSSR(rd_mol) # initialize ring info
    rd_mol.UpdatePropertyCache(strict=False) # compute valence

    return rd_mol
Example #28
0
def make_conformer(mol, conf_a, conf_b):
    """Remove all of mol's conformers, make a new mol containing two copies of mol,
    assign positions to each copy using conf_a and conf_b, respectively, assumed in nanometers"""
    mol.RemoveAllConformers()
    mol = Chem.CombineMols(mol, mol)
    cc = Chem.Conformer(mol.GetNumAtoms())
    conf = np.concatenate([conf_a, conf_b])
    conf *= 10  # TODO: label this unit conversion?
    for idx, pos in enumerate(np.asarray(conf)):
        cc.SetAtomPosition(idx, (float(pos[0]), float(pos[1]), float(pos[2])))
    mol.AddConformer(cc)

    return mol
Example #29
0
def xyz2AC_vdW(atoms, xyz):
    # Get mol template
    mol = get_proto_mol(atoms)

    # Set coordinates
    conf = Chem.Conformer(mol.GetNumAtoms())
    for i in range(mol.GetNumAtoms()):
        conf.SetAtomPosition(i, (xyz[i][0], xyz[i][1], xyz[i][2]))
    mol.AddConformer(conf)

    AC = get_AC(mol)

    return AC, mol
Example #30
0
def TransformMol(mol, tform, confId=-1, newConfId=100):
    """  Applies the transformation to a molecule and sets it up with a single conformer """
    newConf = Chem.Conformer()
    newConf.SetId(0)
    refConf = mol.GetConformer(confId)
    for i in range(refConf.GetNumAtoms()):
        pos = list(refConf.GetAtomPosition(i))
        pos.append(1.0)
        newPos = numpy.dot(tform, numpy.array(pos))
        newConf.SetAtomPosition(i, list(newPos)[:3])
    newConf.SetId(newConfId)
    mol.RemoveConformer(newConfId)
    mol.AddConformer(newConf, assignId=False)