예제 #1
0
 def testMMFFAngleConstraints(self):
     m = Chem.MolFromMolBlock(self.molB, True, False)
     mp = ChemicalForceFields.MMFFGetMoleculeProperties(m)
     ff = ChemicalForceFields.MMFFGetMoleculeForceField(m, mp)
     self.assertTrue(ff)
     ff.MMFFAddAngleConstraint(1, 3, 6, False, 90.0, 90.0, 100.0)
     r = ff.Minimize()
     self.assertTrue(r == 0)
     conf = m.GetConformer()
     angle = rdMolTransforms.GetAngleDeg(conf, 1, 3, 6)
     self.assertTrue(int(angle) == 90)
     ff = ChemicalForceFields.MMFFGetMoleculeForceField(m, mp)
     self.assertTrue(ff)
     ff.MMFFAddAngleConstraint(1, 3, 6, True, -10.0, 10.0, 100.0)
     r = ff.Minimize()
     self.assertTrue(r == 0)
     conf = m.GetConformer()
     angle = rdMolTransforms.GetAngleDeg(conf, 1, 3, 6)
     self.assertTrue(int(angle) == 100)
     ff = ChemicalForceFields.MMFFGetMoleculeForceField(m, mp)
     self.assertTrue(ff)
     ff.MMFFAddAngleConstraint(1, 3, 6, False, -10.0, 10.0, 100.0)
     r = ff.Minimize()
     self.assertTrue(r == 0)
     conf = m.GetConformer()
     angle = rdMolTransforms.GetAngleDeg(conf, 1, 3, 6)
     self.assertEquals(int(angle), 10)  #(int(angle) == 10)
예제 #2
0
 def testUFFAngleConstraints(self):
     m = Chem.MolFromMolBlock(self.molB, True, False)
     ff = ChemicalForceFields.UFFGetMoleculeForceField(m)
     self.assertTrue(ff)
     ff.UFFAddAngleConstraint(1, 3, 6, False, 90.0, 90.0, 100.0)
     r = ff.Minimize()
     self.assertTrue(r == 0)
     conf = m.GetConformer()
     angle = rdMolTransforms.GetAngleDeg(conf, 1, 3, 6)
     self.assertAlmostEqual(angle, 90, delta=0.1)
     ff = ChemicalForceFields.UFFGetMoleculeForceField(m)
     self.assertTrue(ff)
     ff.UFFAddAngleConstraint(1, 3, 6, True, -10.0, 10.0, 100.0)
     r = ff.Minimize()
     self.assertTrue(r == 0)
     conf = m.GetConformer()
     angle = rdMolTransforms.GetAngleDeg(conf, 1, 3, 6)
     self.assertAlmostEqual(angle, 100, delta=0.1)
     ff = ChemicalForceFields.UFFGetMoleculeForceField(m)
     self.assertTrue(ff)
     ff.UFFAddAngleConstraint(1, 3, 6, False, -10.0, 10.0, 100.0)
     r = ff.Minimize()
     self.assertTrue(r == 0)
     conf = m.GetConformer()
     angle = rdMolTransforms.GetAngleDeg(conf, 1, 3, 6)
     self.assertAlmostEqual(angle, 10, delta=0.1)
예제 #3
0
def sp2_indices(mol):
    """
    Determine which atoms in the rdkit-mol object are sp2 hybridized
    by probing for the following criteria:
        1) is the atom bounded by 3 neighbors
        2) is the angle to all neighbors between 109 and 145 degrees

        input: rdkit molecule object
        returns: list of atomic indices being sp2-hybridized
    """
    sp2_index = []
    atoms = mol.GetAtoms()
    bonded = []
    for bond in mol.GetAtoms()[0].GetBonds():
        bonded.append(bond.GetEndAtomIdx())
    for atom in atoms:
        neighbors = atom.GetNeighbors()
        if len(neighbors) == 3:
            for a, b in ((0, 1), (1, 2), (2, 0)):
                angle = rdMolTransforms.GetAngleDeg(mol.GetConformer(),
                                                    bonded[a],
                                                    0,
                                                    bonded[b])
                if (angle > 109 and angle < 145):
                    sp2_index.append(atom.GetIdx())
    return list(set(sp2_index))
예제 #4
0
    def testGetSetAngle(self):
        file = os.path.join(RDConfig.RDBaseDir, 'Code', 'GraphMol',
                            'MolTransforms', 'test_data',
                            '3-cyclohexylpyridine.mol')

        m = Chem.MolFromMolFile(file, True, False)
        conf = m.GetConformer()
        angle = rdmt.GetAngleDeg(conf, 0, 19, 21)
        self.failUnlessAlmostEqual(angle, 109.7, 1)
        rdmt.SetAngleDeg(conf, 0, 19, 21, 125.0)
        angle = rdmt.GetAngleDeg(conf, 0, 19, 21)
        self.failUnlessAlmostEqual(angle, 125.0, 1)
        rdmt.SetAngleRad(conf, 21, 19, 0, math.pi / 2.)
        angle = rdmt.GetAngleRad(conf, 0, 19, 21)
        self.failUnlessAlmostEqual(angle, math.pi / 2., 1)
        angle = rdmt.GetAngleDeg(conf, 0, 19, 21)
        self.failUnlessAlmostEqual(angle, 90.0, 1)
예제 #5
0
 def testUFFAngleConstraints(self):
     m = Chem.MolFromMolBlock(self.molB, True, False)
     ff = ChemicalForceFields.UFFGetMoleculeForceField(m)
     self.failUnless(ff)
     ff.UFFAddAngleConstraint(1, 3, 6, False, 90.0, 90.0, 1.0e5)
     r = ff.Minimize()
     self.failUnless(r == 0)
     conf = m.GetConformer()
     angle = rdMolTransforms.GetAngleDeg(conf, 1, 3, 6)
     self.failUnless(int(angle) == 90)
     ff = ChemicalForceFields.UFFGetMoleculeForceField(m)
     self.failUnless(ff)
     ff.UFFAddAngleConstraint(1, 3, 6, True, -10.0, 10.0, 1.0e5)
     r = ff.Minimize()
     self.failUnless(r == 0)
     conf = m.GetConformer()
     angle = rdMolTransforms.GetAngleDeg(conf, 1, 3, 6)
     self.failUnless(int(angle) == 100)
예제 #6
0
def test_measure_angles(acetone):
    """
    Make sure we can correctly measure all of the angles in the molecule.
    """
    angle_values = acetone.measure_angles()
    rdkit_mol = acetone.to_rdkit()
    for angle, value in angle_values.items():
        assert (pytest.approx(
            rdMolTransforms.GetAngleDeg(rdkit_mol.GetConformer(),
                                        *angle)) == value)
예제 #7
0
def get_angs(f, atid=None):  #rdkit
    mol = Chem.MolFromMolFile(f, removeHs=False, sanitize=False)
    c = mol.GetConformer()
    if atid == None:
        atid = enumerateAngles(f)
    angs = []
    for i in range(len(atid)):
        m = mol.GetAtomWithIdx(atid[i][1])
        if m.GetHybridization() != Chem.HybridizationType.SP:
            angs.append(rdt.GetAngleDeg(c, atid[i][0], atid[i][1], atid[i][2]))
    return np.array(angs), atid
예제 #8
0
def smiles_tors():
    # Given a pdb file, translate into Smiles string (with possible given starting atom)
    # and generate a list of rotatable bonds. Rotatable bond list is written to CHARMM
    # stream files (mc_add.str, mc_delete.str) that are used by the MC module used by EnzyDock.
    # A crucial assumption is that the rotatable bonds are written in an "outwards" manner
    # when covalent docking is done (otherwise CHARMM could rotate protein and not ligand!)

    pdb_file = sys.argv[1]
    pdb_file = pdb_file.lower()   # CHARMM sends in upper case parameters, change to lower
    print("Parsing ligand file: ",pdb_file)

    mcfile1 = "../stream/mc/mc_add.str"
    mcfile2 = "../stream/mc/mc_delete.str"
    # Write the mc_add.str file for EnzyDock
    file = open(mcfile1,"w")
    print_part1(file)
    print("Writing file: ", mcfile1)

    try:
       mol_pdb = Chem.MolFromPDBFile(pdb_file)
       num_atoms = mol_pdb.GetNumAtoms(onlyExplicit=True)
    except:
       print("Error in RDKit read of ligand pdb file %s ..." % pdb_file)
       print("Stopping EnzyDock ...\n")
       file.write("\nstop\n")

    print("Number of ligand atoms: ",num_atoms)
    idx = -1
    # Find atom that serves as seed (covalently bonded)
    if len(sys.argv) > 2:
        for i in range(num_atoms):
            atom = mol_pdb.GetAtomWithIdx(i)
#        print(atom.GetPDBResidueInfo().GetName().strip())
            if (atom.GetPDBResidueInfo().GetName().strip() == sys.argv[2]):
                idx = atom.GetIdx()

    smiles = Chem.MolToSmiles(mol_pdb,True,False,idx)
    print("Ligand Smiles: ",smiles)
    map = mol_pdb.GetProp('_smilesAtomOutputOrder')
    atomorder = [int(i) for i in map.replace('[','').replace(']','').split(',') if i != '''''']
    orderarray = np.array(atomorder)
    indx_array = np.empty(num_atoms)  # index array
    for i in range(num_atoms):
        indx = int(orderarray[i])
#        print(i,indx,mol_pdb.GetAtomWithIdx(indx).GetPDBResidueInfo().GetName())
        indx_array[i] = indx

    mol = Chem.MolFromSmiles(smiles)
    rot_atom_pairs = mol.GetSubstructMatches(RotatableBondSmarts)
    print(rot_atom_pairs)
    ntors = len(rot_atom_pairs)
    k = 0
    for i in range(len(rot_atom_pairs)):
        indx1 = int(indx_array[ rot_atom_pairs[i][0] ])
        indx2 = int(indx_array[ rot_atom_pairs[i][1] ])
        atom1 = mol_pdb.GetAtomWithIdx(indx1).GetPDBResidueInfo().GetName()
        atom2 = mol_pdb.GetAtomWithIdx(indx2).GetPDBResidueInfo().GetName()
        iatom1 = mol_pdb.GetAtomWithIdx(indx1)
        iatom2 = mol_pdb.GetAtomWithIdx(indx2)
        #print(atom1, atom2, iatom1, iatom2)
        conf=mol_pdb.GetConformer(0)
        # Check if any angle is linear (torsion not defined). Using 10 degrees as cutoff.
        tors_flag = True
        for nn in iatom1.GetNeighbors():
           indx3 = nn.GetIdx()
           if (indx3 != indx2):
              angle = rdMolTransforms.GetAngleDeg(conf,indx3, indx1, indx2)
              #print(i, indx1, indx2, indx3, angle)
              if (abs(180.0 - abs(angle)) < 10.0):
                 tors_flag = False
        for nn in iatom2.GetNeighbors():
           indx3 = nn.GetIdx()
           if (indx3 != indx1):
              angle = rdMolTransforms.GetAngleDeg(conf,indx1, indx2, indx3)
              #print(i, indx1, indx2, indx3, angle)
              if (abs(180.0 - abs(angle)) < 10.0):
                 tors_flag = False
        if (tors_flag):
           j = k + 3
           line = "move add mvtp tors weight 1.00 dmax 180.0 label tr" + str(j) + " fewer 0 sele atom ligand_@currligand 1 " \
                   + str(atom1) + " show end -\n"
           file.write(line)
           line = "                                                            sele atom ligand_@currligand 1 " \
                  + str(atom2) + " show end\n"
           file.write(line)
           k += 1
        else:
           ntors -= 1
    line = "\nincr ntors by " + str(ntors) + "\n\n"
    file.write(line)
    print_part2(file)
    file.close()

    # Write the mc_delete.str file for EnzyDock

    file = open(mcfile2,"w")
    print("Writing file: ", mcfile2)

    print_part3(file)
    for i in range(ntors):
        j = i + 3
        line = "move dele label tr" + str(j) + "\n"
        file.write(line)

    line = "decr ntors by " + str(ntors) + "\n"
    file.write(line)
    print_part4(file)
    file.close()

#    print(Chem.MolToMolBlock(mol_pdb))
#    print(Chem.MolToMolBlock(mol))

    map = mol_pdb.GetProp('_smilesAtomOutputOrder')
    atomorder = [int(i) for i in map.replace('[','').replace(']','').split(',') if i != '''''']
    orderarray = np.array(atomorder)
    for i in range(num_atoms):
        indx = int(orderarray[i])
예제 #9
0
def exp_rules_output(mol, args, log):
    if args.exp_rules == 'Ir_bidentate_x3':
        passing = True
        ligand_links = []
        atom_indexes = []
        for atom in mol.GetAtoms():
            # Finds the Ir atom and gets the atom types and indexes of all its neighbours
            if atom.GetSymbol() in args.metal:
                atomic_number = possible_atoms.index(atom.GetSymbol())
                atom.SetAtomicNum(atomic_number)
        for atom in mol.GetAtoms():
            if atom.GetAtomicNum() == atomic_number:
                metal_idx = atom.GetIdx()
                for x in atom.GetNeighbors():
                    ligand_links.append(x.GetSymbol())
                    atom_indexes.append(x.GetIdx())
        # I need to get the only 3D conformer generated in that mol object for rdMolTransforms
        mol_conf = mol.GetConformer(0)
        # This part will identify the pairs of C and N atoms that are part of the same Ph_Py ligand.
        # The shape of the atom pairs is '[[C1_ATOM_NUMBER, N1_ATOM_NUMBER],[C2, N2],...]'.
        # This information is required for the subsequent filtering process based on angles
        if len(atom_indexes) == args.complex_coord[0]:
            ligand_atoms = []
            for i, _ in enumerate(atom_indexes):
                # This is a filter that excludes molecules that fell apart during DFT geometry
                # optimization (i.e. a N atom from one of the ligands separated from Ir). The
                # max distance allowed can be tuned in length_filter
                bond_length = rdMolTransforms.GetBondLength(
                    mol_conf, metal_idx, atom_indexes[i])
                if ligand_links[i] == 'P':
                    length_filter = 2.60
                else:
                    length_filter = 2.25
                if bond_length > length_filter:
                    passing = False
                    break
                for j, _ in enumerate(atom_indexes):
                    # Avoid combinations of the same atom with itself
                    if atom_indexes[i] != atom_indexes[j]:
                        # We know that the ligands never have 2 carbon atoms bonding the Ir atom. We
                        # only use atom_indexes[i] for C atoms, and atom_indexes[j] for the potential
                        # N atoms that are part of the same Ph_Py ligand
                        if ligand_links[i] == 'C':
                            # This part detects the Ir-C bond and breaks it, breaking the Ph_Py ring
                            bond = mol.GetBondBetweenAtoms(
                                atom_indexes[i], metal_idx)
                            new_mol = Chem.FragmentOnBonds(
                                mol, [bond.GetIdx()],
                                addDummies=True,
                                dummyLabels=[(atom_indexes[i], metal_idx)])
                            if new_mol.GetAtomWithIdx(
                                    atom_indexes[i]).IsInRingSize(5):
                                five_mem = True
                            else:
                                five_mem = False
                            # identify whether or not the initial 5-membered ring formed between [-Ir-C-C-C-N-] is broken when we break the Ir-C bond. This works
                            # because Ph_Py units bind Ir in the same way always, through 1 C and 1 N that are in the same position, forming a 5-membered ring.
                            # If this ring is broken, atom_indexes[j] will not be part of a 5-membered ring (atom.IsInRingSize(5) == False) which means that
                            # this atom was initially inside the same ligand as the parent C of atom_indexes[i])
                            if not five_mem:
                                if not new_mol.GetAtomWithIdx(
                                        atom_indexes[j]).IsInRingSize(5):
                                    bond_2 = mol.GetBondBetweenAtoms(
                                        atom_indexes[j], metal_idx)
                                    new_mol_2 = Chem.FragmentOnBonds(
                                        mol, [bond_2.GetIdx()],
                                        addDummies=True,
                                        dummyLabels=[(atom_indexes[j],
                                                      metal_idx)])
                                    #doing backwards as well eg. Ir N bond
                                    if not new_mol_2.GetAtomWithIdx(
                                            atom_indexes[i]).IsInRingSize(5):
                                        ligand_atoms.append(
                                            [atom_indexes[i], atom_indexes[j]])
                                        break
                            else:
                                if not new_mol.GetAtomWithIdx(
                                        atom_indexes[j]).IsInRingSize(5):
                                    if mol.GetAtomWithIdx(
                                            atom_indexes[j]).IsInRingSize(5):
                                        ligand_atoms.append(
                                            [atom_indexes[i], atom_indexes[j]])
                                        break
            if passing:
                # This stop variable and the breaks inside the inner loops will break the nested loop if there
                # is one angle that does not meet the criteria for valid conformers
                stop = False
                # For complexes with 3 Ph_Py ligands:
                if len(ligand_atoms) == 3:
                    for i, _ in enumerate(ligand_atoms):
                        if not stop:
                            for j, _ in enumerate(ligand_atoms):
                                # the i<=j part avoids repeating atoms, the i != j part avoid angles
                                # containing the same number twice (i.e. 4-16-4, this angle will fail)
                                if i <= j and i != j:
                                    # Calculate the angle between 2 N atoms from different Ph_Py ligands.
                                    # When there are 3 Ph_Py ligands, no 2 N atoms must be in 180 degrees
                                    angle = rdMolTransforms.GetAngleDeg(
                                        mol_conf, ligand_atoms[i][1],
                                        metal_idx, ligand_atoms[j][1])
                                    if (180 - args.angle_off) <= angle <= (
                                            180 + args.angle_off):
                                        passing = False
                                        break
                # For complexes with 2 Ph_Py ligands + 1 ligand that is not Ph_Py
                if len(ligand_atoms) == 2:
                    # Since there are only 2 N atoms, we do not need to include a nested loop
                    angle = rdMolTransforms.GetAngleDeg(
                        mol_conf, ligand_atoms[0][1], metal_idx,
                        ligand_atoms[1][1])
                    # Calculate the angle between 2 N atoms from different Ph_Py ligands.
                    # When there are 2 Ph_Py ligands, the 2 N atoms from the 2 Ph_Py ligands must be in 180 degrees
                    if (180 - args.angle_off) <= angle <= (180 +
                                                           args.angle_off):
                        pass
                    else:
                        passing = False
        # it filters off molecules that the SDF only detects 5 Ir neighbours
        else:
            passing = False
        return passing