def smi2svg(smi, ref_smi): mol = Chem.MolFromSmiles(smi) ref_mol = Chem.MolFromSmiles(ref_smi) try: Chem.rdmolops.Kekulize(mol) Chem.rdmolops.Kekulize(ref_mol) except: pass mcs = rdFMCS.FindMCS([mol, ref_mol]) mcs_query = Chem.MolFromSmarts(mcs.smartsString) AllChem.Compute2DCoords(mcs_query) AllChem.GenerateDepictionMatching2DStructure(mol,mcs_query) match = mol.GetSubstructMatch(mcs_query) # unmatch = list(map(lambda x: x[0]-x[1], zip(list(range(mol.GetNumAtoms())), list(match)))) unmatch = [] for x in range(mol.GetNumAtoms()): if not x in match: unmatch.append(x) drawer = rdMolDraw2D.MolDraw2DSVG(300, 300) AllChem.Compute2DCoords(mol) opts = drawer.drawOptions() opts.clearBackground=False drawer.DrawMolecule(mol, highlightAtoms=unmatch) drawer.FinishDrawing() svg = drawer.GetDrawingText().replace("svg:", "") return svg
def get_mcs(mol_one: Chem.rdchem.Mol, mol_two: Chem.rdchem.Mol) -> str: """Code to find the maximum common substructure between two molecules.""" return Chem.MolToSmiles( Chem.MolFromSmarts( rdFMCS.FindMCS([mol_one, mol_two], completeRingsOnly=True, matchValences=True).smartsString))
def rename_from_template(self, template: Chem.Mol, overwrite: bool = True): """ Assigns to the atoms in self.mol the names based on the template, which does not need to be a perfect match. See ``_fix_atom_names`` for example usage. Does not change the Params. :param template: mol object with atom names :return: None for now. """ AllChem.SanitizeMol(template) #this is where half my issues come from. mcs = rdFMCS.FindMCS([self.mol, template], atomCompare=rdFMCS.AtomCompare.CompareElements, bondCompare=rdFMCS.BondCompare.CompareAny, ringMatchesRingOnly=True) common = Chem.MolFromSmarts(mcs.smartsString) for acceptor, donor in zip(self.mol.GetSubstructMatch(common), template.GetSubstructMatch(common)): a_atom = self.mol.GetAtomWithIdx(acceptor) d_atom = template.GetAtomWithIdx(donor) info = d_atom.GetPDBResidueInfo() if info: self.rename_atom(a_atom, info.GetName(), overwrite=overwrite) else: self.log.debug.info( f'No info in template for atom {d_atom.GetSymbol()} #{donor}' )
def place_fragmenstein(self): mcs = rdFMCS.FindMCS([self.fragmenstein.positioned_mol, self.pdb_mol], atomCompare=rdFMCS.AtomCompare.CompareElements, bondCompare=rdFMCS.BondCompare.CompareOrder, ringMatchesRingOnly=True) common = Chem.MolFromSmarts(mcs.smartsString) pos_match = self.fragmenstein.positioned_mol.GetSubstructMatch(common) pdb_match = self.pdb_mol.GetSubstructMatch(common) for m, p in zip(pos_match, pdb_match): ma = self.fragmenstein.positioned_mol.GetAtomWithIdx(m) pa = self.pdb_mol.GetAtomWithIdx(p) assert ma.GetSymbol() == pa.GetSymbol( ), f'The indices do not align! {ma.GetIdx()}:{ma.GetSymbol()} vs. {pa.GetIdx()}:{pa.GetSymbol()}' ma.SetMonomerInfo(pa.GetPDBResidueInfo()) #Chem.AddHs(self.fragmenstein.positioned_mol) with GlobalPyMOL() as pymol: pymol.cmd.delete('*') # pymol.cmd.load(self.best_hit.relaxbound_file, 'apo') # # fix drift # pymol.cmd.load(self.best_hit.bound_file, 'ref') # pymol.cmd.align('apo', 'ref') # pymol.cmd.delete('ref') # pymol.cmd.remove('resn LIG') pymol.cmd.load(self.best_hit.apo_file, 'apo') # distort positions pymol.cmd.read_pdbstr( Chem.MolToPDBBlock(self.fragmenstein.positioned_mol), 'scaffold') pymol.cmd.remove('name R') # no dummy atoms! pymol.cmd.remove('resn UNL') # no unmatched stuff. pymol.cmd.save( f'{self.work_path}/{self.name}/{self.name}.scaffold.pdb') pdbblock = pymol.cmd.get_pdbstr('*') pymol.cmd.delete('*') return 'LINK SG CYS A 145 CX LIG B 1 1555 1555 1.8\n' + pdbblock
def draw_not_mmps(not_mmp_paris, save_path): mols = [] matches_list = [] SEED = 42 random.seed(SEED) sampled_index = random.sample(list(range(len(not_mmp_paris))), topk) for i in sampled_index: pairs = not_mmp_paris[i] curr_mols = [ Chem.MolFromSmiles(pairs[0]), Chem.MolFromSmiles(pairs[1]) ] mols.append(Chem.MolFromSmiles(pairs[0])) mols.append(Chem.MolFromSmiles(pairs[1])) res = rdFMCS.FindMCS(curr_mols) patt = Chem.MolFromSmarts(res.smartsString) for mol in curr_mols: matches = mol.GetSubstructMatches(patt) not_matches = tuple( tuple(set(range(len(mol.GetAtoms()))) - set(matches[0]))) matches_list.append(not_matches) image = Draw.MolsToGridImage(mols, molsPerRow=2, subImgSize=(400, 400), highlightAtomLists=matches_list) image.save(os.path.join(save_path, f'{name}.png'), format='png')
def test8MatchParams(self): smis = ("CCC1NC1", "CCC1N(C)C1", "CCC1OC1") ms = [Chem.MolFromSmiles(x) for x in smis] mcs = rdFMCS.FindMCS(ms) self.assertEqual(mcs.numAtoms, 4) ps = rdFMCS.MCSParameters() ps.BondCompareParameters.CompleteRingsOnly = True mcs = rdFMCS.FindMCS(ms, ps) self.assertEqual(mcs.numAtoms, 3) ps = rdFMCS.MCSParameters() ps.SetAtomTyper(rdFMCS.AtomCompare.CompareAny) mcs = rdFMCS.FindMCS(ms, ps) self.assertEqual(mcs.numAtoms, 5)
def _init_map_fragment_smiles_onto_ideal(self): """ Maps the fragment SMILES string onto the user-defined fragment PDB :return: """ # --- Map Fragment SMILES onto fragment PDB --- # fragment_mcs = rdFMCS.FindMCS( [self.fragment_ideal_rdkit_mol, self.fragment_pdb_rdkit_mol], bondCompare=rdFMCS.BondCompare.CompareAny) fragment_substructure_mol = Chem.MolFromSmarts( fragment_mcs.smartsString) fragment_ideal_match = self.fragment_ideal_rdkit_mol.GetSubstructMatch( fragment_substructure_mol) fragment_pdb_match = self.fragment_pdb_rdkit_mol.GetSubstructMatch( fragment_substructure_mol) # Assert 1:1 mapping excluding hydrogens assert len(fragment_ideal_match) == len(fragment_pdb_match) self.ideal_fragment_mapping = { i_idx: p_idx for i_idx, p_idx in zip(fragment_ideal_match, fragment_pdb_match) if self.fragment_pdb_rdkit_mol.GetAtomWithIdx( p_idx).GetAtomicNum() != 1 }
def copy_origins(cls, annotated: Chem.Mol, target: Chem.Mol): """ Fragmenstein leaves a note of what it did. atom prop _Origin is a json of a list of mol _Name dot AtomIdx. However, the atom order seems to be maintained but I dont trust it. Also dummy atoms are stripped. :param annotated: :param target: :return: a list of origins """ mcs = rdFMCS.FindMCS([target, annotated], atomCompare=rdFMCS.AtomCompare.CompareElements, bondCompare=rdFMCS.BondCompare.CompareAny, ringMatchesRingOnly=True) common = Chem.MolFromSmarts(mcs.smartsString) dmapping = dict( zip(target.GetSubstructMatch(common), annotated.GetSubstructMatch(common))) origins = [] for i in range(target.GetNumAtoms()): if i in dmapping: atom = annotated.GetAtomWithIdx(dmapping[i]) tatom = target.GetAtomWithIdx(i) o = cls._get_origin(atom) tatom.SetProp('_Origin', json.dumps(o)) return origins
def mcss(self, reference): """ Determines the maximum common substructure (MCSS) between the input, or reference ligand and itself. The MCSS is stored in an RDkit mol object, which is returned. If no MCSS was found, the returned mol object will be empty. If an error prevents the MCSS calculation from completing, None is returned. Before this method is called, the ligand must have a rd_mol attribute set. For example lig = Ligand() lig.set_rd_mol_from_resname(resname) # where res is a wwPDB ID string mcss_mol = lig.mcss(reference) lig.set_mcss(reference.resname, mcss_mol) :param reference: d3r.blast.Ligand object with the rd_mol attribute set :return: the MCSS (rd mol object) or None """ try: logger.debug('Trying to find MCS') res = rdFMCS.FindMCS([reference.rd_mol, self.rd_mol], timeout=Ligand.FINDMCS_TIMEOUT) mcss = Chem.MolFromSmarts(res.smartsString) return mcss except: logger.exception( 'Caught exception attempting to run rdkit FindMCS or MolFromSmarts' ) return None
def _mcsClustering(mol1, rdkit_mols): """ Returns the weight distance baased on mcs method Parameters ---------- mol1: rdkit.Chem.rdchem.Mol The reference molecule rdkit_mols: list The list of rdkit.Chem.rdchem.Mol objects Returns ------- distancerow: np.array The numpy array containing the distance row """ from rdkit.Chem import rdFMCS MCS_row = [] for mol2 in tqdm(rdkit_mols): sum_numHeavyAtoms = mol1.GetNumHeavyAtoms() + mol2.GetNumHeavyAtoms() mcsHeavyAtoms = rdFMCS.FindMCS([mol1, mol2], ringMatchesRingOnly=True, completeRingsOnly=True, timeout=5) mcsNumHeavyAtoms = float( Chem.MolFromSmarts(mcsHeavyAtoms.smartsString).GetNumHeavyAtoms()) distance = 1 - mcsNumHeavyAtoms * 2 / sum_numHeavyAtoms MCS_row.append(distance) return MCS_row
def SetupCoreScaffoldByMCS(RefMol, Mol, MolCount): """Setup a reference molecule core containing common scaffold atoms between a pair of molecules using MCS.""" MCSParams = OptionsInfo["MCSParams"] Mols = [RefMol, Mol] MCSResultObject = rdFMCS.FindMCS(Mols, maximizeBonds = MCSParams["MaximizeBonds"], threshold = MCSParams["Threshold"], timeout = MCSParams["TimeOut"], verbose = MCSParams["Verbose"], matchValences = MCSParams["MatchValences"], ringMatchesRingOnly = MCSParams["RingMatchesRingOnly"], completeRingsOnly = MCSParams["CompleteRingsOnly"], matchChiralTag = MCSParams["MatchChiralTag"], atomCompare = MCSParams["AtomCompare"], bondCompare = MCSParams["BondCompare"], seedSmarts = MCSParams["SeedSMARTS"]) if MCSResultObject.canceled: if not OptionsInfo["QuietMode"]: MiscUtil.PrintWarning("MCS failed to identify a common core scaffold between reference moecule and input molecule %s. Specify a different set of parameters using \"-m, --mcsParams\" option and try again." % (RDKitUtil.GetMolName(Mol, MolCount))) return None CoreNumAtoms = MCSResultObject.numAtoms CoreNumBonds = MCSResultObject.numBonds SMARTSCore = MCSResultObject.smartsString if not len(SMARTSCore): if not OptionsInfo["QuietMode"]: MiscUtil.PrintWarning("MCS failed to identify a common core scaffold between reference moecule and input molecule %s. Specify a different set of parameters using \"-m, --mcsParams\" option and try again." % (RDKitUtil.GetMolName(Mol, MolCount))) return None if CoreNumAtoms < MCSParams["MinNumAtoms"]: if not OptionsInfo["QuietMode"]: MiscUtil.PrintWarning("Number of atoms, %d, in core scaffold identified by MCS is less than, %d, as specified by \"minNumAtoms\" parameter in \"-m, --mcsParams\" option." % (CoreNumAtoms, MCSParams["MinNumAtoms"])) return None if CoreNumBonds < MCSParams["MinNumBonds"]: if not OptionsInfo["QuietMode"]: MiscUtil.PrintWarning("Number of bonds, %d, in core scaffold identified by MCS is less than, %d, as specified by \"minNumBonds\" parameter in \"-m, --mcsParams\" option." % (CoreNumBonds, MCSParams["MinNumBonds"])) return None return GenerateCoreMol(RefMol, SMARTSCore)
def testAtomCompareAnyHeavyAtom1(self, **kwargs): # O matches C, H does not match O smis = ('[H]c1ccccc1C', 'Oc1ccccc1O') ms = [Chem.MolFromSmiles(x, sanitize=False) for x in smis] if kwargs: params = Common.getParams(**kwargs) params.AtomTyper = CompareAnyHeavyAtom() mcs = rdFMCS.FindMCS(ms, params) else: mcs = rdFMCS.FindMCS(ms, atomCompare=rdFMCS.AtomCompare.CompareAnyHeavyAtom) self.assertEqual(mcs.numBonds, 7) self.assertEqual(mcs.numAtoms, 7) qm = Chem.MolFromSmarts(mcs.smartsString) for m in ms: self.assertTrue(m.HasSubstructMatch(qm))
def maximum_common_substructure_route(): """Calculate maximum common substructure (MCS) of compounds. --- post: summary: Calculate MCS description: Calculate maximum common substructure (MCS) of compounds. requestBody: required: true content: application/json: schema: MCSSchema responses: '200': content: application/json: schema: MCSResultSchema """ data = MCSSchema().load(request.json) query = data["query"] query_mols, query_skipped = convert_compound_request(query) substructure = rdFMCS.FindMCS(list(query_mols.values())) substructure_mol = identifier_mol_mapping["smarts"]( substructure.smartsString) out = { "substructure": { "compounds": mol_identifier_mapping[query["identifier"]](substructure_mol), "identifier": query["identifier"], }, "skipped": query_skipped, } MCSResultSchema().validate(out) return out
def test_timeout_negative(self): try: rdFMCS.FindMCS(lengthy_mols, timeout=-1) except OverflowError: pass else: raise AssertionError("bad range check for timeout")
def align_mcs(mols, num_confs): suppl = [m for m in AllChem.SDMolSupplier('/Users/tom/code_test_repository/arrow_testing/cdk2.sdf', removeHs=False)] ref_mol = suppl[0] print(f'ref mol has atoms = {ref_mol.GetNumAtoms()}') mols_b = copy.deepcopy(mols) mol_blocks = [] for mol in mols_b: mol = AllChem.AddHs(mol) AllChem.EmbedMultipleConfs(mol, numConfs=num_confs) mcs = rdFMCS.FindMCS([mol, ref_mol]) smarts = mcs.smartsString match = Chem.MolFromSmarts(smarts) test_match_atoms = mol.GetSubstructMatch(match) ref_match_atoms = ref_mol.GetSubstructMatch(match) #Find alignments of all conformers of new drug to old drug: alignments_scores =[rdMolAlign.AlignMol(mol, ref_mol, prbCid=i, atomMap=[[i,j] for i,j in zip(test_match_atoms, ref_match_atoms)]) for i in range(num_confs)] confId=int(np.argmin(alignments_scores)) AllChem.CanonicalizeConformer(mol.GetConformer(confId)) # print(Chem.MolToMolBlock(mol)) mol_blocks.append(Chem.MolToMolBlock(mol)) return pa.array(mol_blocks)
def test9MatchCharge(self, **kwargs): smis = ("CCNC", "CCN(C)C", "CC[N+](C)C") ms = [Chem.MolFromSmiles(x) for x in smis] if kwargs: ps = Common.getParams(**kwargs) mcs = rdFMCS.FindMCS(ms, ps) else: mcs = rdFMCS.FindMCS(ms) self.assertEqual(mcs.numAtoms, 4) ps = Common.getParams(**kwargs) ps.AtomCompareParameters.MatchFormalCharge = True mcs = rdFMCS.FindMCS(ms, ps) self.assertEqual(mcs.numAtoms, 2)
def MCSAlignMolecules(ref_mol, ali_mol): from rdkit import Chem from rdkit.Chem import rdMolAlign from rdkit.Chem import rdFMCS from rdkit.Chem.rdFMCS import FindMCS, AtomCompare, BondCompare ''' Do not sanitize the molecules, RDKit will freak out and give errors And All we want is to do MCSS, we dont care much about health of molecule ''' mol1 = Chem.MolFromMol2File(ref_mol, removeHs=False, sanitize=False) mol2 = Chem.MolFromMol2File(ali_mol, removeHs=False, sanitize=False) _fmcs_params = dict(maximizeBonds=False, threshold=1.0, timeout=60, verbose=False, matchValences=True, ringMatchesRingOnly=True, completeRingsOnly=True, atomCompare=AtomCompare.CompareAny, bondCompare=BondCompare.CompareAny) try: mcs = rdFMCS.FindMCS([mol1, mol2], **_fmcs_params) except ValueError: print( '\n Max Common Substructure calculation \n failed for this molecule!! \n Please be judicious ' ) sys.exit() core = Chem.MolFromSmarts(mcs.smartsString) match1 = mol1.GetSubstructMatch(core) match2 = mol2.GetSubstructMatch(core) from rdkit.Chem import AllChem AllChem.AlignMol(mol2, mol1, atomMap=list(zip(match2, match1))) Chem.MolToMolFile(mol2, 'aligned.mol', kekulize=False) return mol2
def copy_all_possible_origins(cls, annotated: Chem.Mol, target: Chem.Mol) -> Tuple[List[Chem.Mol], List[List[int]]]: """ Fragmenstein leaves a note of what it did. atom prop _Origin is a json of a list of mol _Name dot AtomIdx. However, the atom order seems to be maintained but I dont trust it. Also dummy atoms are stripped. :param annotated: :param target: :return: a list of mols and a list of orgins (a list too) """ mcs = rdFMCS.FindMCS([target, annotated], atomCompare=rdFMCS.AtomCompare.CompareElements, bondCompare=rdFMCS.BondCompare.CompareAny, ringMatchesRingOnly=True) common = Chem.MolFromSmarts(mcs.smartsString) options = [] originss = [] for target_match in target.GetSubstructMatches(common): for anno_match in annotated.GetSubstructMatches(common): dmapping = dict(zip(target_match, anno_match)) origins = [] option = Chem.Mol(target) for i in range(option.GetNumAtoms()): if i in dmapping: atom = annotated.GetAtomWithIdx(dmapping[i]) tatom = option.GetAtomWithIdx(i) o = cls._get_origin(atom) tatom.SetProp('_Origin', json.dumps(o)) options.append(option) originss.append(origins) return options, originss
def test_ligand_data(target, ligand_name, lig): m1 = Chem.MolFromSmiles(lig._data["smiles"][0]) m1 = Chem.AddHs(m1) m2 = Chem.SDMolSupplier( os.path.join( targets.data_path, targets.get_target_dir(target), "02_ligands", ligand_name, "crd", f"{ligand_name}.sdf", ), removeHs=False, )[0] assert m1.GetNumAtoms() == m2.GetNumAtoms() m1.RemoveAllConformers() m2.RemoveAllConformers() assert pytest.approx(1.0, 1e-9) == DataStructs.FingerprintSimilarity( Chem.RDKFingerprint(m1), Chem.RDKFingerprint(m2)) # assert Chem.MolToMolBlock(m1) == Chem.MolToMolBlock(m2) res = rdFMCS.FindMCS([m1, m2]) assert res.numAtoms == m1.GetNumAtoms() assert res.numBonds == m1.GetNumBonds() m3 = lig.get_molecule() m2 = Molecule.from_rdkit(m2) assert Molecule.are_isomorphic(m2, m3)
def draw_mols(x_list: list, y_list: list, names: list): error_names = [] error = [] for x, y, name in zip(x_list, y_list, names): e = abs(float(x) - float(y)) if e > 10: error_names.append(name) error.append(e) ps = rdFMCS.MCSParameters() ps.AtomCompareParameters.RingMatchesRingOnly = True ps.SetAtomTyper(rdFMCS.AtomCompare.CompareAny) for name in error_names: mol1, mol2 = ( Chem.MolFromSmiles(exp_results[name]["t1-smiles"]), Chem.MolFromSmiles(exp_results[name]["t2-smiles"]), ) mcs = Chem.MolFromSmarts( rdFMCS.FindMCS( [mol1, mol2], bondCompare=Chem.rdFMCS.BondCompare.CompareOrder.CompareAny, ).smartsString) AllChem.Compute2DCoords(mol1) match1 = mol1.GetSubstructMatch(mcs) match2 = mol2.GetSubstructMatch(mcs) coords = [mol1.GetConformer().GetAtomPosition(x) for x in match1] coords2D = [Geometry.Point2D(pt.x, pt.y) for pt in coords] coordDict = {} for i, coord in enumerate(coords2D): coordDict[match2[i]] = coord AllChem.Compute2DCoords(mol2, coordMap=coordDict) Draw.MolsToGridImage([mol1, mol2], subImgSize=(250, 250), molsPerRow=2)
def test7Seed(self, **kwargs): smis = ['C1CCC1CC1CC1', 'C1CCC1OC1CC1', 'C1CCC1NC1CC1', 'C1CCC1SC1CC1'] ms = [Chem.MolFromSmiles(x) for x in smis] if kwargs: params = Common.getParams(**kwargs) r = rdFMCS.FindMCS(ms, params) else: r = rdFMCS.FindMCS(ms) self.assertEqual(r.smartsString, "[#6]1-[#6]-[#6]-[#6]-1") if kwargs: params = Common.getParams(**kwargs) params.InitialSeed = 'C1CC1' r = rdFMCS.FindMCS(ms, params) else: r = rdFMCS.FindMCS(ms, seedSmarts='C1CC1') self.assertEqual(r.smartsString, "[#6]1-[#6]-[#6]-1") if kwargs: params = Common.getParams(**kwargs) params.InitialSeed = 'C1OC1' r = rdFMCS.FindMCS(ms, params) else: r = rdFMCS.FindMCS(ms, seedSmarts='C1OC1') self.assertEqual(r.smartsString, "[#6]") self.assertEqual(r.numAtoms, 1) self.assertEqual(r.numBonds, 0) if kwargs: params = Common.getParams(**kwargs) params.InitialSeed = 'C1OC1' params.AtomCompareParameters.RingMatchesRingOnly = True r = rdFMCS.FindMCS(ms, params) else: r = rdFMCS.FindMCS(ms, seedSmarts='C1OC1', ringMatchesRingOnly=True) self.assertEqual(r.smartsString, "[#6&R]") self.assertEqual(r.numAtoms, 1) self.assertEqual(r.numBonds, 0) if kwargs: params = Common.getParams(**kwargs) params.InitialSeed = 'C1OC1' params.BondCompareParameters.CompleteRingsOnly = True r = rdFMCS.FindMCS(ms, params) else: r = rdFMCS.FindMCS(ms, seedSmarts='C1OC1', completeRingsOnly=True) self.assertEqual(r.smartsString, "") self.assertEqual(r.numAtoms, 0) self.assertEqual(r.numBonds, 0)
def getMaximumCommonSubstructure(smallmol_list, removeHs=True, returnAtomIdxs=False): """ Returns the maximum common substructure and two list of lists. The first one contains for each molecules the atom indexes that are part of the MCS, the second list contains the indexes that are not part of the MCS. Parameters ---------- smallmol_list: list The list of SmallMol objects removeHs: bool If True, the atom the hydrogens where not considered Default: True returnAtomIdxs: bool If True, the lists of the atom indexes are returned Default: False Returns ------- mcs_mol: rdkit.Chem.rdchem.Mol The MCS molecule atom_mcs_list: list A list of lists containing the atom indexes that are part of the MCS atom_no_mcs_list: list A list of lists containing the atom indexes that are not part of the MCS """ from rdkit.Chem import rdFMCS smallmol_list = [sm.copy() for sm in smallmol_list] for sm in smallmol_list: AllChem.EmbedMolecule(sm._mol, AllChem.ETKDG()) if removeHs: sm._mol = Chem.RemoveHs(sm._mol) rdkitMols_list = [sm._mol for sm in smallmol_list] mcs = rdFMCS.FindMCS(rdkitMols_list) logger.info('MCS found a substructure of {} atoms and {} bonds'.format( mcs.numAtoms, mcs.numBonds)) mcs_mol = Chem.MolFromSmarts(mcs.smartsString) if not returnAtomIdxs: return mcs_mol atoms_mcs_list = [] atoms_no_mcs_list = [] for sm, m in zip(smallmol_list, rdkitMols_list): match = m.GetSubstructMatch(mcs_mol) sel_str = convertToString(match) atoms_mcs = sm.get('idx', 'idx {}'.format(sel_str)) atoms_no_mcs = sm.get('idx', 'idx {}'.format(sel_str), invert=True) atoms_mcs_list.append(atoms_mcs.tolist()) atoms_no_mcs_list.append(atoms_no_mcs.tolist()) return mcs_mol, atoms_mcs_list, atoms_no_mcs_list
def test_timeout(self): t1 = time.time() result = rdFMCS.FindMCS(lengthy_mols, timeout=1) self.assert_result(result, canceled=True) self.assertTrue(result.numAtoms > 1) self.assertTrue(result.numBonds >= result.numAtoms - 1, (result.numAtoms, result.numBonds)) t2 = time.time() self.assertTrue(t2 - t1 < 2, t2 - t1)
def print_rmsd(headA, headB, Head_Linkers): #loading the heads sdf files HeadA = Chem.SDMolSupplier(headA)[0] HeadB = Chem.SDMolSupplier(headB)[0] head_linkers = Chem.SDMolSupplier(Head_Linkers) for head_linker in head_linkers: mcsA = rdFMCS.FindMCS([HeadA, head_linker]) mcsB = rdFMCS.FindMCS([HeadB, head_linker]) pattA = Chem.MolFromSmarts(mcsA.smartsString) pattB = Chem.MolFromSmarts(mcsB.smartsString) HeadA_sub = HeadA.GetSubstructMatches(pattA, uniquify=False) HeadB_sub = HeadB.GetSubstructMatch(pattB) head_A = head_linker.GetSubstructMatches(pattA, uniquify=False) head_B = head_linker.GetSubstructMatch(pattB) for H in HeadA_sub: for h in head_A: print(heads_rmsd(head_linker, HeadA, HeadB, H, HeadB_sub, h, head_B))
def test20AtomCompareCompleteRingsOnly(self): mols = [Chem.MolFromSmiles(smi) for smi in ["C1CCCC1C", "C1CCCC1C1CCCCC1"]] params = rdFMCS.MCSParameters() params.AtomCompareParameters.CompleteRingsOnly = True res = rdFMCS.FindMCS(mols, params) self.assertEqual(res.numAtoms, 5) self.assertEqual(res.numBonds, 5) self.assertEqual(res.smartsString, "[#6&R]1-&@[#6&R]-&@[#6&R]-&@[#6&R]-&@[#6&R]-&@1") params = rdFMCS.MCSParameters() params.AtomCompareParameters.CompleteRingsOnly = True # this will automatically be set to True params.BondCompareParameters.CompleteRingsOnly = False res = rdFMCS.FindMCS(mols, params) self.assertEqual(res.numAtoms, 5) self.assertEqual(res.numBonds, 5) self.assertEqual(res.smartsString, "[#6&R]1-&@[#6&R]-&@[#6&R]-&@[#6&R]-&@[#6&R]-&@1")
def _get_common(self, target: Chem.Mol) -> Chem.Mol: res = rdFMCS.FindMCS( [self.dethio_mol, target] # , # matchValences=True, threshold=0.1 # atomCompare=Chem.rdFMCS.AtomCompare.CompareElements #, # bondCompare=Chem.rdFMCS.BondCompare.CompareAny #CompareOrder ) return Chem.MolFromSmarts(res.smartsString)
def test16MCSProgressCallbackExceptions(self): ps = rdFMCS.MCSParameters() smis = ['CCCC(C)CC(CC)CC', 'OC(N)CC(C)CC(CC)CC'] ms = [Chem.MolFromSmiles(x) for x in smis] self.assertRaises(TypeError, lambda ps: setattr(ps, "ProgressCallback", ProgressCallbackCallbackIsInt())) ps.ProgressCallback = ProgressCallbackNoCallback() self.assertRaises(TypeError, lambda ms, ps: rdFMCS.FindMCS(ms, ps))
def test6MatchValences(self, **kwargs): ms = (Chem.MolFromSmiles('NC1OC1'), Chem.MolFromSmiles('C1OC1[N+](=O)[O-]')) if kwargs: params = Common.getParams(**kwargs) mcs = rdFMCS.FindMCS(ms, params) else: mcs = rdFMCS.FindMCS(ms) self.assertEqual(mcs.numBonds, 4) self.assertEqual(mcs.numAtoms, 4) if kwargs: params = Common.getParams(**kwargs) params.AtomCompareParameters.MatchValences = True mcs = rdFMCS.FindMCS(ms, params) else: mcs = rdFMCS.FindMCS(ms, matchValences=True) self.assertEqual(mcs.numBonds, 3) self.assertEqual(mcs.numAtoms, 3)
def test11Github2034(self): smis = ("C1CC1N2CC2", "C1CC1N") ms = [Chem.MolFromSmiles(x) for x in smis] mcs = rdFMCS.FindMCS(ms) self.assertEqual(mcs.numAtoms, 4) self.assertEqual(mcs.numBonds, 4) mcs = rdFMCS.FindMCS(ms, ringMatchesRingOnly=True) self.assertEqual(mcs.numAtoms, 3) self.assertEqual(mcs.numBonds, 3) ps = rdFMCS.MCSParameters() ps.AtomCompareParameters.RingMatchesRingOnly = True mcs = rdFMCS.FindMCS(ms, ps) self.assertEqual(mcs.numAtoms, 3) self.assertEqual(mcs.numBonds, 3)
def test14MCSBondCompareExceptions(self): ps = rdFMCS.MCSParameters() smis = ['CCCCC', 'CCC1CCCCC1'] ms = [Chem.MolFromSmiles(x) for x in smis] self.assertRaises(TypeError, lambda ps: setattr(ps, "BondTyper", BondCompareCompareIsInt())) ps.BondTyper = BondCompareNoCompare() self.assertRaises(TypeError, lambda ms, ps: rdFMCS.FindMCS(ms, ps))