def test8MMFFO3A(self): " test MMFFO3A with constraints " #we superimpose two identical coplanar 4-phenylpyridines: #1) the usual way #2) forcing the pyridine nitrogen to match with the para # carbon of the phenyl ring m = Chem.MolFromSmiles('n1ccc(cc1)-c1ccccc1') m1 = Chem.AddHs(m) rdDistGeom.EmbedMolecule(m1) mp = ChemicalForceFields.MMFFGetMoleculeProperties(m1) ff = ChemicalForceFields.MMFFGetMoleculeForceField(m1, mp) ff.Minimize() sub1 = m1.GetSubstructMatch(Chem.MolFromSmarts('nccc-cccc')) nIdx = sub1[0] cIdx = sub1[-1] dihe = sub1[2:6] rdMolTransforms.SetDihedralDeg(m1.GetConformer(), dihe[0], dihe[1], dihe[2], dihe[3], 0) m2 = copy.copy(m1) rdMolAlign.RandomTransform(m2) m3 = copy.copy(m2) pyO3A = rdMolAlign.GetO3A(m2, m1) pyO3A.Align() d = m2.GetConformer().GetAtomPosition(cIdx). \ Distance(m1.GetConformer().GetAtomPosition(cIdx)) self.assertAlmostEqual(d, 0, 0) pyO3A = rdMolAlign.GetO3A(m3, m1, constraintMap=[[cIdx, nIdx]]) pyO3A.Align() d = m3.GetConformer().GetAtomPosition(cIdx). \ Distance(m1.GetConformer().GetAtomPosition(cIdx)) self.assertAlmostEqual(d, 7, 0)
def test9MMFFO3A(self): " test MMFFO3A with variable weight constraints followed by local-only optimization " sdf = os.path.join(RDConfig.RDBaseDir,'Code','GraphMol', 'MolAlign', 'test_data', 'ref_e2.sdf') # alignedSdf = os.path.join(RDConfig.RDBaseDir,'Code','GraphMol', # 'MolAlign', 'test_data', 'localonly.sdf') molS = Chem.SDMolSupplier(sdf, True, False) refNum = 23 prbNum = 32 refMol = molS[refNum] prbMol = molS[prbNum] refPyMP = ChemicalForceFields.MMFFGetMoleculeProperties(refMol) prbPyMP = ChemicalForceFields.MMFFGetMoleculeProperties(prbMol) refSIdx = refMol.GetSubstructMatch(Chem.MolFromSmarts('S'))[0] prbOIdx = prbMol.GetSubstructMatch(Chem.MolFromSmarts('O'))[0] # molW = Chem.SDWriter(alignedSdf) # molW.write(refMol) weights = [10.0, 100.0] distOS = [3.2, 0.3] for i in [0, 1]: pyO3A = rdMolAlign.GetO3A(prbMol, refMol, prbPyMP, refPyMP, constraintMap = [[prbOIdx, refSIdx]], constraintWeights = [weights[i]]) pyO3A.Align() # molW.write(prbMol) pyO3A = rdMolAlign.GetO3A(prbMol, refMol, prbPyMP, refPyMP, options = 4) pyO3A.Align() # molW.write(prbMol) d = prbMol.GetConformer().GetAtomPosition(prbOIdx). \ Distance(refMol.GetConformer().GetAtomPosition(refSIdx)) self.assertAlmostEqual(d, distOS[i], 1)
def test7MMFFO3A(self): " make sure we generate an error if parameters are missing (github issue 158) " m1 = Chem.MolFromSmiles('c1ccccc1Cl') rdDistGeom.EmbedMolecule(m1) m2 = Chem.MolFromSmiles('c1ccccc1B(O)O') rdDistGeom.EmbedMolecule(m1) self.assertRaises(ValueError, lambda: rdMolAlign.GetO3A(m1, m2)) self.assertRaises(ValueError, lambda: rdMolAlign.GetO3A(m2, m1))
def test7MMFFO3A(self): " make sure we generate an error if parameters are missing (github issue 158) " sdf = os.path.join(RDConfig.RDBaseDir,'Code','GraphMol', 'MolAlign', 'test_data', 'ref_e2.sdf') m1 = Chem.MolFromSmiles('c1ccccc1Cl') rdDistGeom.EmbedMolecule(m1) m2 = Chem.MolFromSmiles('c1ccccc1B(O)O') rdDistGeom.EmbedMolecule(m1) self.failUnlessRaises(ValueError,lambda :rdMolAlign.GetO3A(m1, m2)) self.failUnlessRaises(ValueError,lambda :rdMolAlign.GetO3A(m2, m1))
def test14Github385(self): """ test github issue 385: O3A code generating incorrect results for multiconformer molecules """ def _multiConfFromSmiles(smiles, nConfs=10, maxIters=500): """Adds hydrogens to molecule and optimises a chosen number of conformers. Returns the optimised RDKit mol.""" idea = Chem.MolFromSmiles(smiles) idea = Chem.AddHs(idea) confs = rdDistGeom.EmbedMultipleConfs(idea, nConfs) for conf in confs: opt = ChemicalForceFields.MMFFOptimizeMolecule( idea, confId=conf, maxIters=maxIters) return idea def _confsToAlignedMolsList(multiConfMol): """Input is a multiconformer RDKit mol. Output is an aligned set of conformers as a list of RDKit mols.""" rdMolAlign.AlignMolConformers(multiConfMol) ms = [] cids = [x.GetId() for x in multiConfMol.GetConformers()] for cid in cids: newmol = Chem.Mol(multiConfMol) for ocid in cids: if ocid == cid: continue newmol.RemoveConformer(ocid) ms.append(newmol) return ms reference = Chem.MolFromSmiles("c1ccccc1N2CCC(NS(=O)(=O)C(F)(F)F)CC2") reference = Chem.AddHs(reference) rdDistGeom.EmbedMolecule(reference) idea1 = _multiConfFromSmiles("c1ccccc1C2CCCCC2", 10) idea1_mols = _confsToAlignedMolsList(idea1) cids = [x.GetId() for x in idea1.GetConformers()] refParams = ChemicalForceFields.MMFFGetMoleculeProperties(reference) prbParams = ChemicalForceFields.MMFFGetMoleculeProperties(idea1) for i in range(len(cids)): o3a1 = rdMolAlign.GetO3A(idea1_mols[i], reference, prbParams, refParams) score1 = o3a1.Score() o3a2 = rdMolAlign.GetO3A(idea1, reference, prbParams, refParams, prbCid=cids[i]) score2 = o3a2.Score() self.assertAlmostEqual(score1, score2, 3)
def PerformAlignmentAndWrieOutput(RefMol, ProbeMol, RefMolName, ProbeMolName, Writer): """Perform alignment and write to output file.""" Status = True try: if OptionsInfo["UseRMSD"]: RMSD = rdMolAlign.AlignMol(ProbeMol, RefMol, maxIters=OptionsInfo["MaxIters"]) elif OptionsInfo["UseBestRMSD"]: RMSD = AllChem.GetBestRMS(RefMol, ProbeMol) elif OptionsInfo["UseOpen3A"]: O3A = rdMolAlign.GetO3A(ProbeMol, RefMol) Score = O3A.Align() elif OptionsInfo["UseCrippenOpen3A"]: CrippenO3A = rdMolAlign.GetCrippenO3A(ProbeMol, RefMol) Score = CrippenO3A.Align() else: MiscUtil.PrintError( "Alignment couldn't be performed: Specified alignment value, %s, is not supported" % OptionsInfo["Alignment"]) except (RuntimeError, ValueError): Status = False MiscUtil.PrintWarning( "Alignment failed between reference molecule, %s, and probe molecule, %s.\nWriting unaligned probe molecule...\n" % (RefMolName, ProbeMolName)) # Write out aligned probe molecule... Writer.write(ProbeMol) return Status
def test15MultiConfs(self): " test multi-conf alignment " sdf = os.path.join(RDConfig.RDBaseDir, 'Code', 'GraphMol', 'MolAlign', 'test_data', 'ref_e2.sdf') suppl = Chem.SDMolSupplier(sdf, removeHs=False) refMol = suppl[13] sdf = os.path.join(RDConfig.RDBaseDir, 'Code', 'GraphMol', 'MolAlign', 'test_data', 'probe_mol.sdf') prbSuppl = Chem.SDMolSupplier(sdf, removeHs=False) tms = [x for x in prbSuppl] prbMol = tms[0] for tm in tms[1:]: prbMol.AddConformer(tm.GetConformer(), True) self.failUnlessEqual(prbMol.GetNumConformers(), 50) refParams = ChemicalForceFields.MMFFGetMoleculeProperties(refMol) prbParams = ChemicalForceFields.MMFFGetMoleculeProperties(prbMol) cp = Chem.Mol(prbMol) o3s = rdMolAlign.GetO3AForProbeConfs(cp, refMol, 1, prbParams, refParams) for i in range(prbMol.GetNumConformers()): cp2 = Chem.Mol(prbMol) o3 = rdMolAlign.GetO3A(cp2, refMol, prbParams, refParams, prbCid=i) self.failUnlessAlmostEqual(o3s[i].Align(), o3.Align(), 6) self.failUnlessAlmostEqual(o3s[i].Score(), o3.Score(), 6) cp = Chem.Mol(prbMol) o3s = rdMolAlign.GetCrippenO3AForProbeConfs(cp, refMol) for i in range(prbMol.GetNumConformers()): cp2 = Chem.Mol(prbMol) o3 = rdMolAlign.GetCrippenO3A(cp2, refMol, prbCid=i) self.failUnlessAlmostEqual(o3s[i].Align(), o3.Align(), 6) self.failUnlessAlmostEqual(o3s[i].Score(), o3.Score(), 6)
def _shapeClustering(mol1, rdkit_mols): """ Returns the tanimoto row based on shape method Parameters ---------- mol1: rdkit.Chem.rdchem.Mol The reference molecule rdkit_mols: list The list of rdkit.Chem.rdchem.Mol objects Returns ------- tanimotorow: np.array The numpy array containing the tanimoto row """ from rdkit.Chem import rdMolAlign, rdShapeHelpers tanimoto_shape_row = [] for mol2 in rdkit_mols: oa3 = rdMolAlign.GetO3A(mol1, mol2) oa3.Align() tani_shape = rdShapeHelpers.ShapeTanimotoDist(mol1, mol2) tanimoto_shape_row.append(tani_shape) return tanimoto_shape_row
def rmsd_frag_mol(gen_mol, ref_mol, start_pt): try: # Delete linker - Gen mol du = Chem.MolFromSmiles('*') clean_frag = Chem.RemoveHs( AllChem.ReplaceSubstructs(Chem.MolFromSmiles(start_pt), du, Chem.MolFromSmiles('[H]'), True)[0]) fragmented_mol = get_frags(gen_mol, clean_frag, start_pt) if fragmented_mol is not None: # Delete linker - Ref mol clean_frag_ref = Chem.RemoveHs( AllChem.ReplaceSubstructs(Chem.MolFromSmiles(start_pt), du, Chem.MolFromSmiles('[H]'), True)[0]) fragmented_mol_ref = get_frags(ref_mol, clean_frag_ref, start_pt) if fragmented_mol_ref is not None: # Sanitize Chem.SanitizeMol(fragmented_mol) Chem.SanitizeMol(fragmented_mol_ref) # Align pyO3A = rdMolAlign.GetO3A(fragmented_mol, fragmented_mol_ref).Align() rms = rdMolAlign.GetBestRMS(fragmented_mol, fragmented_mol_ref) return rms #score except: return 100 # Dummy RMSD
def SC_RDKit_frag_mol(gen_mol, ref_mol, start_pt): try: # Delete linker - Gen mol du = Chem.MolFromSmiles('*') clean_frag = Chem.RemoveHs( AllChem.ReplaceSubstructs(Chem.MolFromSmiles(start_pt), du, Chem.MolFromSmiles('[H]'), True)[0]) fragmented_mol = get_frags(gen_mol, clean_frag, start_pt) if fragmented_mol is not None: # Delete linker - Ref mol clean_frag_ref = Chem.RemoveHs( AllChem.ReplaceSubstructs(Chem.MolFromSmiles(start_pt), du, Chem.MolFromSmiles('[H]'), True)[0]) fragmented_mol_ref = get_frags(ref_mol, clean_frag_ref, start_pt) if fragmented_mol_ref is not None: # Sanitize Chem.SanitizeMol(fragmented_mol) Chem.SanitizeMol(fragmented_mol_ref) # Align pyO3A = rdMolAlign.GetO3A(fragmented_mol, fragmented_mol_ref).Align() # Calc SC_RDKit score score = calc_SC_RDKit.calc_SC_RDKit_score( fragmented_mol, fragmented_mol_ref) return score except: return -0.5 # Dummy score
def SC_RDKit_full_mol(gen_mol, ref_mol): try: # Align pyO3A = rdMolAlign.GetO3A(gen_mol, ref_mol).Align() # Calc SC_RDKit score score = calc_SC_RDKit.calc_SC_RDKit_score(gen_mol, ref_mol) return score except: return -0.5 # Dummy score
def PerformShapeAlignment(RefMol, ProbeMol): """Perform shape alignment and return alignment score.""" if OptionsInfo["UseCrippenOpen3A"]: CrippenO3A = rdMolAlign.GetCrippenO3A(ProbeMol, RefMol) Score = CrippenO3A.Align() else: O3A = rdMolAlign.GetO3A(ProbeMol, RefMol) Score = O3A.Align() return Score
def test10_SuCOS(self): """Testing to make sure SuCOS score is not > 1 with a molecule and itself""" from rdkit.Chem import rdMolAlign ref_sdf = "test_data/3ivc_ligand.sdf" ref_ms = Chem.SDMolSupplier(ref_sdf) gen_mol = Chem.Mol(ref_ms[0]) ref_mol = Chem.Mol(ref_ms[0]) pyO3A = rdMolAlign.GetO3A(gen_mol, ref_mol).Align() SuCOS_score = calc_SuCOS.main(gen_mol, ref_mol, write=False) assert SuCOS_score <= 1
def test6MMFFO3A(self): " now test where the mmff parameters are generated on call " sdf = os.path.join(RDConfig.RDBaseDir, 'Code', 'GraphMol', 'MolAlign', 'test_data', 'ref_e2.sdf') molS = Chem.SDMolSupplier(sdf, True, False) refNum = 48 refMol = molS[refNum] cumScore = 0.0 cumMsd = 0.0 for prbMol in molS: pyO3A = rdMolAlign.GetO3A(prbMol, refMol) cumScore += pyO3A.Score() rmsd = pyO3A.Align() cumMsd += rmsd * rmsd cumMsd /= len(molS) self.assertAlmostEqual(cumScore, 6942, 0) self.assertAlmostEqual(math.sqrt(cumMsd), .345, 3)
def calc_3d_similarity(ref: str, gen: str) -> float: ref_mol = Chem.MolFromSmiles(ref) gen_mol = Chem.MolFromSmiles(gen) if ref_mol is None or gen_mol is None: return -1.0 try: ref_mol = Chem.AddHs(ref_mol) Chem.AllChem.EmbedMolecule(ref_mol) Chem.AllChem.UFFOptimizeMolecule(ref_mol) gen_mol = Chem.AddHs(gen_mol) Chem.AllChem.EmbedMolecule(gen_mol) Chem.AllChem.UFFOptimizeMolecule(gen_mol) pyO3A = rdMolAlign.GetO3A(gen_mol, ref_mol).Align() return calc_SC_RDKit_score(gen_mol, ref_mol) except Exception: return -1.0
def chec_substructure_match(ligand, ligand_core, core_atoms): import rdkit.Chem.rdMolAlign as rd from rdkit import Chem #Initialize ring information Chem.GetSSSR(ligand) Chem.GetSSSR(ligand_core) #Align and obtain vocabulary between atoms in core and ligand align_obj = rd.GetO3A(ligand, ligand_core) atom_map = align_obj.Matches() vocabulary = {i2: i1 for i1, i2 in atom_map} #Check the substructure search and change indexes if dont agree with alignment for idx_atom_ligand, idx_atom_core in enumerate(core_atoms): if idx_atom_ligand not in vocabulary: #If it's a removed hydrogen pass continue if vocabulary[ idx_atom_ligand] == idx_atom_core: #If indexes are correct pass continue else: #If indexes are incorrect swap indexes core_atoms = list(core_atoms) core_atoms[idx_atom_ligand] = vocabulary[idx_atom_ligand] return core_atoms
def test5MMFFO3A(self): sdf = os.path.join(RDConfig.RDBaseDir, 'Code', 'GraphMol', 'MolAlign', 'test_data', 'ref_e2.sdf') # alignedSdf = os.path.join(RDConfig.RDBaseDir,'Code','GraphMol', # 'MolAlign', 'test_data', 'ref_e2_pyMMFFO3A.sdf') molS = Chem.SDMolSupplier(sdf, True, False) # molW = Chem.SDWriter(alignedSdf) refNum = 48 refMol = molS[refNum] cumScore = 0.0 cumMsd = 0.0 refPyMP = ChemicalForceFields.MMFFGetMoleculeProperties(refMol) for prbMol in molS: prbPyMP = ChemicalForceFields.MMFFGetMoleculeProperties(prbMol) pyO3A = rdMolAlign.GetO3A(prbMol, refMol, prbPyMP, refPyMP) cumScore += pyO3A.Score() rmsd = pyO3A.Align() cumMsd += rmsd * rmsd # molW.write(prbMol) cumMsd /= len(molS) self.assertAlmostEqual(cumScore, 6942, 0) self.assertAlmostEqual(math.sqrt(cumMsd), .345, 3)
def run_comparison(references=None, conformers=None): references = args.references conformers = args.conformers templates = [] lowest_rmsd = [] for reference in AllChem.SDMolSupplier(references): if reference.HasProp('_Name'): ref_id = reference.GetProp('_Name').split('_')[0] templates.append([ref_id, reference]) mol_RMSD = [] mol_references = [] mol_O3A = [] mol_minimized = [] for refer in templates: try: print('Processing:', refer[0]) conformer = [] rmsd = [] similarity_3D = [] O3A_result = [] t_angles = [] r_gyration = [] i_energy = [] f_energy = [] rmsd_minimized = [] for mol in AllChem.SDMolSupplier(conformers): if refer[0] == mol.GetProp('_Name').split('_')[0]: mol_copy = mol name = str(mol.GetProp('_Name')) conformer.append(name) #Aligment and RMSD calculation based on Maximum Common Structure SMARTS r = rdFMCS.FindMCS([mol, refer[1]]) a = refer[1].GetSubstructMatch( Chem.MolFromSmarts(r.smartsString)) b = mol.GetSubstructMatch( Chem.MolFromSmarts(r.smartsString)) mapa = list(zip(b, a)) rms = rdMolAlign.AlignMol(mol, refer[1], atomMap=mapa) rmsd.append(rms) mol.SetProp('RMSD', str(rms)) mol_RMSD.append(mol) mol_references.append(refer[1]) # Tortional fingerprint r_list = Chem.TorsionFingerprints.CalculateTorsionLists( refer[1]) r_angles = Chem.TorsionFingerprints.CalculateTorsionAngles( refer[1], r_list[0], r_list[1]) c_list = Chem.TorsionFingerprints.CalculateTorsionLists( mol) c_angles = Chem.TorsionFingerprints.CalculateTorsionAngles( mol, c_list[0], c_list[1]) torsion = Chem.TorsionFingerprints.CalculateTFD( r_angles, c_angles) t_angles.append(torsion) #Radious of gyration radious = Descriptors3D.RadiusOfGyration(mol) r_gyration.append(radious) mp = AllChem.MMFFGetMoleculeProperties(mol) mmff = AllChem.MMFFGetMoleculeForceField(mol, mp) energy_value = mmff.CalcEnergy() i_energy.append(energy_value) # Energy and minimization m2 = mol AllChem.EmbedMolecule(m2) AllChem.MMFFOptimizeMolecule(m2, mmffVariant='MMFF94') mp = AllChem.MMFFGetMoleculeProperties(m2) mmff = AllChem.MMFFGetMoleculeForceField(m2, mp) energy_value_minimized = mmff.CalcEnergy() f_energy.append(energy_value_minimized) m3 = Chem.RemoveHs(m2) r = rdFMCS.FindMCS([m3, refer[1]]) a = refer[1].GetSubstructMatch( Chem.MolFromSmarts(r.smartsString)) b = m3.GetSubstructMatch(Chem.MolFromSmarts( r.smartsString)) mapa = list(zip(b, a)) rms_2 = rdMolAlign.AlignMol(m3, refer[1], atomMap=mapa) rmsd_minimized.append(rms_2) m3.SetProp('RMSD', str(rms_2)) mol_minimized.append(m3) O3A = rdMolAlign.GetO3A(mol_copy, refer[1]) align = O3A.Align() O3A_result.append(align) mol_copy.SetProp('O3A', str(align)) mol_O3A.append(mol_copy) d = { 'conformer': pd.Series(conformer), 'RMSD': pd.Series(rmsd), 'O3A_value': pd.Series(O3A_result), 'Torsional_Fingerprint': pd.Series(t_angles), 'Radius_of_Gyration': pd.Series(r_gyration), 'Initial_Energy': pd.Series(i_energy), 'Minimization_Energy': pd.Series(f_energy), 'RMSD_after_minimization': pd.Series(rmsd_minimized) } table = pd.DataFrame(d) sort = table.sort_values('RMSD', ascending=True) sort = sort.reset_index(drop=True) sort.to_csv(refer[0] + '.csv') print('data in file:', refer[0] + '.csv') print('-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- ') rog_diff = (float( max(sort['Radius_of_Gyration']) - sort['Radius_of_Gyration'][0])) lowest_rmsd.append( (sort['conformer'][0], sort['RMSD'][0], sort['O3A_value'][0], sort['Torsional_Fingerprint'][0], sort['Radius_of_Gyration'][0], sort['Initial_Energy'][0], sort['Minimization_Energy'][0], sort['RMSD_after_minimization'][0], rog_diff)) except Exception: print('Something wrong with this reference or conformer') print('Omitting') pass print( 'SAVING DATA OF LOWEST RMSD OF CONFORMERS ... ... ... ... ... ... ... ...' ) summary = pd.DataFrame(data=lowest_rmsd, columns=[ 'Conformer', 'RMSD', 'O3A_value', 'Torsional_Fingerprint', 'Radius_of_Gyration', 'Initial_Energy', 'Minimization Energy', 'RMSD_after_minimization', 'Dif_Radious_of_Gyration' ]) summary.to_csv('Lowest_RMSD_Data.csv') print('Lowest RMSD Data in file: Lowest_RMSD_Data.csv') print('***************************************************') print( 'SAVING STRUCTURES (RMSD, O3A, and MINIMIZATION) ... ... ... ... ... ... ... ... ...' ) output_Ref = Chem.SDWriter('Aligned_Refrences.sdf') output_RMSD = Chem.SDWriter('RMSD_alignment.sdf') output_O3A = Chem.SDWriter('O3A_alignment.sdf') output_Min = Chem.SDWriter('Minimization.sdf') mol_references = list(set(mol_references)) [output_Ref.write(element) for element in mol_references] output_Ref.close() [output_RMSD.write(element) for element in mol_RMSD] output_RMSD.close() [output_O3A.write(element) for element in mol_O3A] output_O3A.close() [output_Min.write(element) for element in mol_minimized] output_Min.close() print( 'Structures in files: Aligned_Refrences.sdf, RMSD_alignment.sdf, O3A_alignment.sdf, and Minimization.sdf ' ) print( 'ALL THE CALCULATIONS DONE, FILES SAVED. THANK YOU FOR USING THIS SCRIPT' )
if args.ref: ref = Chem.MolFromPDBFile(args.ref) else: # NumAtoms = [m.GetNumAtoms() for m in mols] # ref = mols[NumAtoms.index(max(NumAtoms))] N = len(mols) score = np.zeros((N, N)) for i in range(N): # copy probe mol probe = Chem.Mol(mols[i]) for j in range(N): if i == j: score[i, j] = 0 try: O3A = rdMolAlign.GetO3A(probe, mols[j]) score[i, j] = O3A.Align() except ValueError as e: score[i, j] = 100 print(mol.file_name) sum_score = score.sum(axis=0) ref = mols[sum_score.argmin()] pdb = Chem.PDBWriter(args.o) for mol in mols: try: O3A = rdMolAlign.GetO3A(mol, ref) score = O3A.Align() print(score) pdb.write(mol) except ValueError as e:
def main(): parser = argparse.ArgumentParser(description='Open3DAlign with RDKit') parser.add_argument('query', help='query molfile') parser.add_argument( '--qmolidx', help="Query molecule index in SD file if not the first", type=int, default=1) parser.add_argument( '-t', '--threshold', type=float, help='score cuttoff relative to alignment of query to itself') parser.add_argument( '-n', '--num', default=0, type=int, help= 'number of conformers to generate, if None then input structures are assumed to already be 3D' ) parser.add_argument('-a', '--attempts', default=0, type=int, help='number of attempts to generate conformers') parser.add_argument('-r', '--rmsd', type=float, default=1.0, help='prune RMSD threshold for excluding conformers') parser.add_argument( '-e', '--emin', type=int, default=0, help= 'energy minimisation iterations for generated confomers (default of 0 means none)' ) utils.add_default_io_args(parser) args = parser.parse_args() utils.log("o3dAlign Args: ", args) qmol = utils.read_single_molecule(args.query, index=args.qmolidx) qmol = Chem.RemoveHs(qmol) qmol2 = Chem.Mol(qmol) source = "conformers.py" datasetMetaProps = { "source": source, "description": "Open3DAlign using RDKit " + rdBase.rdkitVersion } clsMappings = {"O3DAScore": "java.lang.Float"} fieldMetaProps = [{ "fieldName": "O3DAScore", "values": { "source": source, "description": "Open3DAlign alignment score" } }] if args.num > 0: # we generate the conformers so will add energy info clsMappings["EnergyDelta"] = "java.lang.Float" clsMappings["EnergyAbs"] = "java.lang.Float" fieldMetaProps.append({ "fieldName": "EnergyDelta", "values": { "source": source, "description": "Energy difference to lowest energy conformer" } }) fieldMetaProps.append({ "fieldName": "EnergyAbs", "values": { "source": source, "description": "Absolute energy" } }) input, output, suppl, writer, output_base = utils.default_open_input_output( args.input, args.informat, args.output, 'o3dAlign', args.outformat, valueClassMappings=clsMappings, datasetMetaProps=datasetMetaProps, fieldMetaProps=fieldMetaProps) pyO3A = rdMolAlign.GetO3A(qmol2, qmol) perfect_align = pyO3A.Align() perfect_score = pyO3A.Score() utils.log('Perfect score:', perfect_align, perfect_score, Chem.MolToSmiles(qmol, isomericSmiles=True), qmol.GetNumAtoms()) i = 0 count = 0 total = 0 for mol in suppl: if mol is None: continue if args.num > 0: mol.RemoveAllConformers() conformerProps, minEnergy = conformers.process_mol_conformers( mol, i, args.num, args.attempts, args.rmsd, None, None, 0) mol = Chem.RemoveHs(mol) count += doO3Dalign(i, mol, qmol, args.threshold, perfect_score, writer, conformerProps=conformerProps, minEnergy=minEnergy) else: mol = Chem.RemoveHs(mol) count += doO3Dalign(i, mol, qmol, args.threshold, perfect_score, writer) i += 1 total += mol.GetNumConformers() input.close() writer.flush() writer.close() output.close() if args.meta: utils.write_metrics(output_base, { '__InputCount__': i, '__OutputCount__': count, 'RDKitO3DAlign': total })
for j in range(N): if i == j: continue if simi[i][j] < args.tc: continue if ref.id not in pdbs: pdb_name = output / ref.id pdb_name = pdb_name.with_suffix('.pdb') pdbs[ref.id] = Chem.PDBWriter(str(pdb_name)) pdbs[ref.id].write(ref) try: # probe = Chem.Mol(mols[j]) probe = Chem.MolFromSmiles(Chem.MolToSmiles(mols[j])) probe = Chem.AddHs(probe) AllChem.EmbedMolecule(probe) probe = Chem.RemoveHs(probe) pdbs[ref.id].write(probe) O3A = rdMolAlign.GetO3A(probe, ref, maxIters=100) score = O3A.Align() pdbs[ref.id].write(probe) _break = True break except ValueError as e: print(e) print(mol[i].id, mol[j].id) if _break: break for pdb in pdbs.values(): pdb.close()
def calc_3d_score(ref_mol: Mol, gen_mol: Mol): try: pyO3A = rdMolAlign.GetO3A(gen_mol, ref_mol).Align() return calc_SC_RDKit_score(gen_mol, ref_mol) except: return -1.0
from rdkit import Chem from rdkit.Chem import AllChem, rdMolAlign ligands = [lig.strip() for lig in open('ligands.dat').readlines()] align_to = next(Chem.ForwardSDMolSupplier('el.sdf')) for index, ligand in enumerate(ligands): if index not in [0, 1, 2]: continue alignee = Chem.MolFromSmiles(ligand) alignee = Chem.AddHs(alignee) id = AllChem.EmbedMultipleConfs(alignee, numConfs=1)[0] AllChem.UFFOptimizeMolecule(alignee, confId=id) aligner = rdMolAlign.GetO3A(alignee, align_to) aligner.Align() Chem.MolToPDBFile(alignee, 'lig-{:02}.pdb'.format(index + 1))
parser.add_argument('-t', '--tanimoto', action='store_true', help='Output Tanimoto distance') args = parser.parse_args() #load reference file molecules refmols = [mol for mol in Chem.SDMolSupplier(args.ref)] collated = collections.defaultdict(list) #for each test mol compare to all refmols for mol in Chem.SDMolSupplier(args.test): try: vals = [] for r in refmols: o3a = rdMolAlign.GetO3A(r, mol) o3a.Align() if args.tanimoto: score = 1.0 - rdShapeHelpers.ShapeTanimotoDist(r, mol) else: score = o3a.Score() vals.append(score) tc = max(vals) if args.collate: collated[mol.GetProp("_Name")].append(tc) else: print mol.GetProp("_Name"), tc except: pass if args.collate: