Hi David, Thanks for the clarification. One more computationally-expensive and naive approach would be to generate multiple conformers and check them against a known reference structure.
Here's a quick take on the approach that will be a bit slower. It assumes that mol is a probe molecule that has no conformers, ref_mol is a mol that has the desired geometry, and that you already know what the core scaffold is: mol= Chem.MolFromSmiles('[17OH]C1=C2C=C(N)C=C1CC3=C([17O-])C(CC4=C([17OH])C(CC5=C(N)C(C2)=CC(S(=O)([O-])=O)=C5)=CC(S(=O)([O-])=O)=C4)=CC(N)=C3') add_conformer_match(mol, ref_mol, 'C1(C2)=CC(CC3=CC(CC4=CC=CC(CC5=CC=CC2=C5)=C4)=CC=C3)=CC=C1') def add_conformer_match(probe_mol, # assume no conformers yet reference_mol, # assume the reference has a single correct conf substructure, # the conserved scaffold threshold=0.5, # define an rmsd threshold num_confs=50, num_threads=4): # create a consistent scaffold to match atom_ids scaffold = Chem.MolFromSmiles(substructure) probe_indices = probe_mol.GetSubstructMatch(scaffold) ref_indices = reference_mol.GetSubstructMatch(scaffold) atom_map = list(zip(probe_indices, ref_indices)) # generate diverse conformers for new molecule probe_mol_h = Chem.AddHs(probe_mol) conf_ids = AllChem.EmbedMultipleConfs(probe_mol_h, numConfs=num_confs, numThreads=num_threads, pruneRmsThresh=0.5) probe_mol_confs = Chem.RemoveHs(probe_mol_h) # iterate over conformers to see if they match rms_list = [] for conf_id in conf_ids: rmsd = AllChem.AlignMol(probe_mol_confs, reference_mol, prbCid=conf_id, atomMap=atom_map) rms_list.append(rmsd) # check to see if you find a reasonable match if min(rms_list) > threshold: print(f'No conformer found within RMS threshold of {threshold}') return None else: # add the lowest_rms conformer to the original mol lowest_rms = rms_list.index(min(rms_list)) probe_mol.AddConformer(probe_mol_confs.GetConformer(lowest_rms)) return probe_mol # return the original object with added conformer Kangway ________________________________ From: David Turnbull <david.turnbu...@ucalgary.ca> Sent: Thursday, July 23, 2020 7:58 AM To: rdkit-discuss@lists.sourceforge.net <rdkit-discuss@lists.sourceforge.net>; Chuang, Kangway <kangway.chu...@ucsf.edu> Subject: Re: Conformer generation That is the structure I want, however I found that it doesn't give that structure every time (sometimes it inverts the rings). Get Outlook for Android<https://urldefense.proofpoint.com/v2/url?u=https-3A__aka.ms_ghei36&d=DwMGaQ&c=iORugZls2LlYyCAZRB3XLg&r=Z0E5F87lf3GPcsIl1f2OYQw4iwqHJfffu3dwlNgH2Zs&m=zKUYd_Jfhr2WYR_OBhn5whmIq1pRnUMMWKZXet-DsRg&s=_KGfUMbYuqPwR3m2g7VO79jxh9F-XP_TRtO9itOLZ40&e=> ________________________________ From: Chuang, Kangway <kangway.chu...@ucsf.edu> Sent: Thursday, July 23, 2020 8:55:01 AM To: David Turnbull <david.turnbu...@ucalgary.ca>; rdkit-discuss@lists.sourceforge.net <rdkit-discuss@lists.sourceforge.net> Subject: Re: Conformer generation [△EXTERNAL] Hi David, Do you have a specific example of the bowl conformation you're looking for (e.g. do you have an image of the desired conformation vs what you are seeing)? Running your current code I get the following conformer (shown in two different views). Kangway ________________________________ From: David Turnbull <david.turnbu...@ucalgary.ca> Sent: Thursday, July 23, 2020 6:49 AM To: rdkit-discuss@lists.sourceforge.net <rdkit-discuss@lists.sourceforge.net> Subject: [Rdkit-discuss] Conformer generation Hi all, I am trying to generate structures of calixarenes in a set shape, I am trying to use constrain distances but struggling. The lowest energy conformer is not what I want as I want it in the bowl shape. I labelled 4 oxygens with O17 (for finding purposes) and set the distance of them as that should set the geometry but it isn’t working. Any help would be great. Code below. mol= Chem.MolFromSmiles('[17OH]C1=C2C=C([Y])C=C1CC3=C([17O-])C(CC4=C([17OH])C(CC5=C([17OH])C(C2)=CC(S(=O)([O-])=O)=C5)=CC(S(=O)([O-])=O)=C4)=CC([Y])=C3') y= Chem.MolFromSmiles('OC1=CC=C([Y])C=C1') rxn = AllChem.ReactionFromSmarts("[Y][*:1].[Y][*:2]>>[*:1][*:2]") results=rxn.RunReactants([mol,y]) for products in results: for mol in products: m2=mol results2=rxn.RunReactants([m2,y]) for products in results2: for mol in products: m3=mol m4=Chem.MolToSmiles(m3) x=Chem.MolFromSmiles(m4) index={} k=0 for atom in x.GetAtoms(): if atom.GetSymbol() == 'O': if atom.GetIsotope() == 17: index[k]=atom.GetIdx() k+=1 m5=Chem.AddHs(x) AllChem.EmbedMolecule(m5, useRandomCoords=True) ff=AllChem.UFFGetMoleculeForceField(m5) ff.UFFAddDistanceConstraint( index[0], index[1], False, 3.5, 4.5, 99.0) ff.UFFAddDistanceConstraint( index[0], index[2], False, 3.5, 4.5, 99.0) ff.UFFAddDistanceConstraint( index[0], index[3], False, 3.5, 4.5, 99.0) m6=ff.Minimize(maxIts=50) David
_______________________________________________ Rdkit-discuss mailing list Rdkit-discuss@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/rdkit-discuss