def get_sgs(record_dict, n_min, n_max, method="exhaustive"): if method == "exhaustive": return Chem.rdmolops.FindAllSubgraphsOfLengthMToN( record_dict["mol"], n_min, n_max) elif method == "RECAP": hierarchy = Recap.RecapDecompose(record_dict["mol"]) sgs = [] for substructure in hierarchy.GetAllChildren().values(): substructure = Chem.DeleteSubstructs(substructure.mol, Chem.MolFromSmarts('[#0]')) edge_idxs = get_substructure_bond_idx(substructure, record_dict["mol"]) if edge_idxs is not None: sgs.append(edge_idxs) return subset_sgs_sizes([sgs], n_min, n_max) elif method == "BRICS": substructures = BRICS.BRICSDecompose(record_dict["mol"]) sgs = [] for substructure in substructures: substructure = Chem.DeleteSubstructs( Chem.MolFromSmiles(substructure), Chem.MolFromSmarts('[#0]')) edge_idxs = get_substructure_bond_idx(substructure, record_dict["mol"]) if edge_idxs is not None: sgs.append(edge_idxs) return subset_sgs_sizes([sgs], n_min, n_max)
def get_match_score(self, query: Mol, match: Mol) -> float: score = 0 mcs = rdFMCS.FindMCS([query, match], completeRingsOnly=True) mcs_mol = Chem.MolFromSmarts(mcs.smartsString) smiles = Chem.MolToSmiles(mcs_mol) mcs_mol = Chem.MolFromSmiles(smiles, sanitize=False) if '#0' not in mcs.smartsString: return float("-inf") def get_atom_symbol(atom): if atom.GetIsAromatic(): return atom.GetSymbol().lower() return atom.GetSymbol() matching_atoms = "" for atom in mcs_mol.GetAtoms(): matching_atoms += str(get_atom_symbol(atom)) if atom.GetIdx() == 0: continue w = self.get_root_distance_weight(mcs_mol, atom.GetIdx()) score += (atom_scores.get(get_atom_symbol(atom)) or 1) * w m_copy = deepcopy(match) for atom in m_copy.GetAtoms(): atom.SetAtomMapNum(atom.GetIdx()) match_remainder = Chem.DeleteSubstructs(m_copy, mcs_mol) remaining_match_atoms = "" for atom in match_remainder.GetAtoms(): remaining_match_atoms += str(get_atom_symbol(atom)) w = self.get_root_distance_weight(match, atom.GetAtomMapNum()) score -= (atom_scores.get(get_atom_symbol(atom)) or 1) * w q_copy = deepcopy(query) for atom in q_copy.GetAtoms(): atom.SetAtomMapNum(atom.GetIdx()) query_remainder = Chem.DeleteSubstructs(q_copy, mcs_mol) remaining_query_atoms = "" for atom in query_remainder.GetAtoms(): remaining_query_atoms += str(get_atom_symbol(atom)) w = self.get_root_distance_weight(query, atom.GetAtomMapNum()) score -= (atom_scores.get(get_atom_symbol(atom)) or 1) * w match_count = q_copy.GetSubstructMatches(mcs_mol) if len(match_count) > 1: indices = [x for x in match_count[0] if x not in match_count[1]] for index in indices: atom = q_copy.GetAtomWithIdx(index) score -= (atom_scores.get(get_atom_symbol(atom)) or 1) * w return score
def metallocene(smiles: str) -> LigandResult: molecule = reduce( lambda mol, smiles: Chem.DeleteSubstructs( mol, Chem.MolFromSmiles(smiles, sanitize=False) ), [ 'Cl[Ti]Cl', '[Ti]', '[Cl-]', ], smiles ) root_pattern = Chem.MolFromSmiles("c1cccc1.c1cccc1", sanitize=False) chains = Chem.ReplaceCore(molecule, root_pattern, labelByIndex=True) pieces = Chem.GetMolFrags(chains, asMols=True) ligands = [Chem.MolToSmiles(x, True) for x in pieces] rs = [] for ligand in ligands: ligand = replace_rounds(ligand, [(r'\[C+@+H*\]', 'C'), (r"\[\d\*\]", "*"), (r'\[N+@+H*\]', 'N')]) if ligand.count("*") > 1: rs.append(ligand.split('C(*)')[0]) rs.append("*C" + ligand.split("C(*)")[1]) return [*rs, *([None] * (6 - len(rs)))], None if len(ligand) < 5: continue else: rs.append(re.sub(r"\[\d\*\]", "*", ligand)) ligands = [*rs, *([""] * (2 - len(rs)))] return [*ligands, *([None] * (6 - len(ligands)))], None
def properties(mol): """ Calculates the properties that are required to calculate the QED descriptor. """ if mol is None: raise ValueError('You need to provide a mol argument.') mol = Chem.RemoveHs(mol) qedProperties = QEDproperties( MW=rdmd._CalcMolWt(mol), ALOGP=Crippen.MolLogP(mol), HBA=sum( len(mol.GetSubstructMatches(pattern)) for pattern in Acceptors if mol.HasSubstructMatch(pattern)), HBD=rdmd.CalcNumHBD(mol), PSA=MolSurf.TPSA(mol), ROTB=rdmd.CalcNumRotatableBonds(mol, rdmd.NumRotatableBondsOptions.Strict), AROM=Chem.GetSSSR(Chem.DeleteSubstructs(Chem.Mol(mol), AliphaticRings)), ALERTS=sum(1 for alert in StructuralAlerts if mol.HasSubstructMatch(alert)), ) # The replacement # AROM=Lipinski.NumAromaticRings(mol), # is not identical. The expression above tends to count more rings # N1C2=CC=CC=C2SC3=C1C=CC4=C3C=CC=C4 # OC1=C(O)C=C2C(=C1)OC3=CC(=O)C(=CC3=C2C4=CC=CC=C4)O # CC(C)C1=CC2=C(C)C=CC2=C(C)C=C1 uses 2, should be 0 ? return qedProperties
def properties(mol): """ Calculates the properties that are required to calculate the QED descriptor. """ matches = [] if mol is None: raise WrongArgument("properties(mol)", "mol argument is \'None\'") x = [0] * 9 x[0] = Descriptors.MolWt(mol) # MW x[1] = Descriptors.MolLogP(mol) # ALOGP for hba in Acceptors: # HBA if mol.HasSubstructMatch(hba): matches = mol.GetSubstructMatches(hba) x[2] += len(matches) x[3] = Descriptors.NumHDonors(mol) # HBD x[4] = Descriptors.TPSA(mol) # PSA x[5] = Descriptors.NumRotatableBonds(mol) # ROTB x[6] = Chem.GetSSSR(Chem.DeleteSubstructs(deepcopy(mol), AliphaticRings)) # AROM for alert in StructuralAlerts: # ALERTS if (mol.HasSubstructMatch(alert)): x[7] += 1 ro5_failed = 0 if x[3] > 5: ro5_failed += 1 #HBD if x[2] > 10: ro5_failed += 1 #HBA if x[0] >= 500: ro5_failed += 1 if x[1] > 5: ro5_failed += 1 x[8] = ro5_failed return x
def Explode(template, sidechains, outF, autoNames=True, do3D=False, useTethers=False): chainIndices = [] core = Chem.DeleteSubstructs(template, Chem.MolFromSmiles('[*]')) try: templateName = template.GetProp('_Name') except KeyError: templateName = "template" for mol in _exploder(template, 0, sidechains, core, chainIndices, autoNames=autoNames, templateName=templateName, do3D=do3D, useTethers=useTethers): outF.write(Chem.MolToMolBlock(mol)) for pN in mol.GetPropNames(): print('> <%s>\n%s\n' % (pN, mol.GetProp(pN)), file=outF) print('$$$$', file=outF)
def transform(self, cmpd): # sys.stderr.write('\tTRANSFORM: %s\n'%(Chem.MolToSmiles(cmpd))) for patt in self._patterns: cmpd = Chem.DeleteSubstructs(cmpd, patt, onlyFrags=self._wholeFragments) # sys.stderr.write('\t\tAfter %s: %s\n'%(Chem.MolToSmiles(patt),Chem.MolToSmiles(cmpd))) return cmpd
def combAlignedOptLigHCore(core,lig,list): """Aligns ligand carboxylate to core carboxylate. Identifies which atom will need to be connected across ligand/core. Deletes ligand carboxylate. Combines ligand and core molecules to one molecule. """ atomnums=lig.GetSubstructMatch(Chem.MolFromSmarts('[CX3](=O)[OX1H0-,OX2H1]')) print "Alignment result: ", AllChem.AlignMol(lig,core,atomMap=zip(atomnums,list)) connect_atom=lig.GetAtomWithIdx(lig.GetSubstructMatch(Chem.MolFromSmarts('*[CX3](=O)[OX1H0-,OX2H1]'))[0]) connect_atom.SetProp('connect','Y') trunc=Chem.DeleteSubstructs(lig,Chem.MolFromSmarts('[CX3](=O)[OX2H1][H]')) if trunc.GetNumAtoms() == lig.GetNumAtoms(): trunc=Chem.DeleteSubstructs(lig,Chem.MolFromSmarts('[CX3](=O)[OX1H0-]')) allatoms=trunc.GetAtoms() combo=Chem.CombineMols(core,trunc) return combo
def Modify(self): # Construct an intermediate form self.interm = self if self.modifArg == "-B": # drop the carboxylic group self.interm = Chem.DeleteSubstructs(self, Chem.MolFromSmiles('C(=O)O')) # Evaluate the rest modification arguments elif self.modifArg == "-OH": self.interm = Chem.ReplaceSubstructs( self, Chem.MolFromSmiles('C(=O)O'), Chem.MolFromSmarts('[C:6]=[O:10]'), replaceAll=True)[0] elif self.modifArg == "+H": if self.reactAtom == 5: # keep the reacting oxygen self.interm = Chem.ReplaceSubstructs( self, Chem.MolFromSmiles('C(=O)O'), Chem.MolFromSmarts('[C:6](-[O:5])[O:10]'), replaceAll=True)[0] else: # remove alcohol self.interm = Chem.ReplaceSubstructs( self, Chem.MolFromSmarts('C(=O)O'), Chem.MolFromSmarts('[C:6][O:10]'), replaceAll=True)[0] elif self.modifArg == "+H2": if self.reactAtom == 5: # keep the reacting oxygen self.interm = Chem.ReplaceSubstructs( self, Chem.MolFromSmiles('C(=O)O'), Chem.MolFromSmarts('[C:6][O:5]'), replaceAll=True)[0] else: # fully reduce all oxygens self.interm = Chem.ReplaceSubstructs( self, Chem.MolFromSmarts('C(=O)O'), Chem.MolFromSmarts('[C:6]'), replaceAll=True)[0] elif self.modifArg == None and self.reactAtom == 6: # remove the alcohol if reaction atom is B[C] self.interm = Chem.ReplaceSubstructs( self, Chem.MolFromSmiles('C(=O)O'), Chem.MolFromSmarts('[C:6]=[O:10]'), replaceAll=True)[0] # return self if no modification on other reaction atoms return self.interm
def find_context(atom_ids, my_mol, my_sub_m, cont_sub): """Function to get the context - by adding all the atoms in a substructure and adding them to the fragment""" # First combine the tuples # Get the atoms in this match out_m = [] for x in my_mol.GetSubstructMatches(cont_sub): for y in x: # If it's in both substructures if y in my_sub_m: out_m.append(y) # Add the core structure out_m.extend(atom_ids) # get an editable mol em = Chem.EditableMol(my_mol) # Loop through the atoms and remove them for my_id in my_mol.GetAtoms(): if my_id.GetIdx() in out_m: continue else: # Replace with a gap em.ReplaceAtom(my_id.GetIdx(), Chem.Atom(0)) # Now remove all these atoms star_mol = em.GetMol() out_mol = Chem.DeleteSubstructs(star_mol, Chem.MolFromSmarts('[#0]')) out_ans = Chem.MolToSmiles(out_mol) print "ORIG MOL", Chem.MolToSmiles(my_mol) print "FRACT MOL", out_ans return out_ans
def _applyPattern(m, salt, notEverything): nAts = m.GetNumAtoms() if not nAts: return m res = m t = Chem.DeleteSubstructs(res, salt, True) if not t or (notEverything and t.GetNumAtoms() == 0): return res res = t while res.GetNumAtoms() and nAts > res.GetNumAtoms(): nAts = res.GetNumAtoms() t = Chem.DeleteSubstructs(res, salt, True) if notEverything and t.GetNumAtoms() == 0: break res = t return res
def get_frag_sdf(request, frag_id): """View to get the fragment information (in 3D) for a mol""" # Get the fragment mol_id = request.GET["MOL_ID"] my_frag = MMPFrag.objects.filter(keycluster__pk=int(frag_id), mol_id=int(mol_id))[0] in_mol = Chem.MolFromMolBlock(str(my_frag.sdf_info)) # Remove the zero atoms out_mol = Chem.DeleteSubstructs(in_mol, Chem.MolFromSmarts('[#0]')) return HttpResponse(Chem.MolToMolBlock(out_mol))
def remove_dummies(mol: Chem.rdchem.Mol, dummy: str = "*") -> Optional[Chem.rdchem.Mol]: """Remove dummy atoms from molecules.""" du = dm.to_mol(dummy) out = mol try: out = Chem.ReplaceSubstructs(mol, du, dm.to_mol("[H]"), True)[0] out = Chem.RemoveHs(out) except Exception as e: out = Chem.DeleteSubstructs(mol, du) return out
def remove_custom_fragment(childGenes, GeneSet, oldGene): geneSet = GeneSet.CustomFrags newGene = Chromosome(geneSet.GetEntryDescription(\ random.sample(range(geneSet.GetNumEntries()), 1)[0]),0) try: truncate = Chem.DeleteSubstructs(childGenes.Mol, newGene.Mol) childGenes = truncate childGenes = Chromosome(Chem.MolToSmiles(childGenes), 0) return childGenes except: return 0
def weld_r_groups(mol): """Accepts `mol` rdkit molecule of a scaffold and with numbered wildcards and fragments with corresponding wildcards and returns a fused molecule. Based on code posted by Patrick Walters on the RDkit forums. Parameters ---------- mol : rdkit.Chem.rdchem.Mol object Returns ------- final_mol : rdkit.Chem.rdchem.Mol object """ # First pass loop over atoms and find the atoms with an AtomMapNum join_dict = defaultdict(list) for atom in mol.GetAtoms(): map_num = atom.GetAtomMapNum() if map_num > 0: join_dict[map_num].append(atom) # Second pass, transfer the atom maps to the neighbor atoms for idx, atom_list in join_dict.items(): if len(atom_list) == 2: atm_1, atm_2 = atom_list nbr_1 = [x.GetOtherAtom(atm_1) for x in atm_1.GetBonds()][0] nbr_1.SetAtomMapNum(idx) nbr_2 = [x.GetOtherAtom(atm_2) for x in atm_2.GetBonds()][0] nbr_2.SetAtomMapNum(idx) # Nuke all of the dummy atoms new_mol = Chem.DeleteSubstructs(mol, Chem.MolFromSmarts('[#0]')) # Third pass - arrange the atoms with AtomMapNum, these will be connected bond_join_dict = defaultdict(list) for atom in new_mol.GetAtoms(): map_num = atom.GetAtomMapNum() if map_num > 0: bond_join_dict[map_num].append(atom.GetIdx()) # Make an editable molecule and add bonds between atoms with corresponding AtomMapNum em = EditableMol(new_mol) for idx, atom_list in bond_join_dict.items(): if len(atom_list) == 2: start_atm, end_atm = atom_list em.AddBond(start_atm, end_atm, order=Chem.rdchem.BondType.SINGLE) final_mol = em.GetMol() # remove the AtomMapNum values for atom in final_mol.GetAtoms(): atom.SetAtomMapNum(0) final_mol = Chem.RemoveHs(final_mol) return final_mol
def get_ring_removals(smi): rw_mol = RWMol(Chem.MolFromSmiles(smi)) rings = rw_mol.GetRingInfo().AtomRings() out_mols = {} for ring in rings: new_mol = Chem.MolFromSmiles(smi) for atom in ring: new_mol.GetAtomWithIdx(atom).SetAtomicNum(0) Chem.DeleteSubstructs(new_mol, Chem.MolFromSmarts("[#0]")) Chem.GetMolFrags(new_mol) out_mols[Chem.MolToSmiles(new_mol, isomericSmiles=True)] = ring return out_mols
def find_reaction_difference(rxn: Reaction) -> List[ReactionDiff]: # return type? """Finds difference between products and reactants.""" rxn_diff_list: list = [] # ~ for mol_product in rxn.mol_products: # ~ for mol_reactant in rxn.mol_reactants: # ~ ms = [mol_reactant, mol_product] # ~ mcs = rdFMCS.FindMCS(ms) # ~ patt = mcs.smartsString # ~ commonMol = Chem.MolFromSmarts(patt) # ~ mol_diffs = [Chem.DeleteSubstructs(x,commonMol) for x in ms] # ~ diff_list.append([Chem.MolToSmiles(x) for x in mol_diffs]) for i, fp_product in enumerate(rxn.fp_products): tamimoto_scores = [ DataStructs.FingerprintSimilarity(x, fp_product) for x in rxn.fp_reactants ] j, max_tamimoto_score = max( enumerate(tamimoto_scores), key=operator.itemgetter(1) ) mol_product = rxn.mol_products[i] mol_reactant = rxn.mol_reactants[j] ms = [mol_reactant, mol_product] mcs = rdFMCS.FindMCS(ms, maximizeBonds=False, timeout=10) if mcs.canceled == False: patt = mcs.smartsString commonMol = Chem.MolFromSmarts(patt) mol_diffs = [Chem.DeleteSubstructs(x, commonMol) for x in ms] diffs = ReactionDiff( mol_rel_reactant=mol_reactant, mol_product=mol_product, mol_reactant_dissim=mol_diffs[0], mol_product_dissim=mol_diffs[1], mol_reactants=Chem.MolFromSmiles(".".join(rxn.reactants)), ) rxn_diff_list.append(diffs) else: diffs = ReactionDiff( mol_rel_reactant=mol_reactant, mol_product=mol_product, mol_reactant_dissim=Chem.MolFromSmiles(""), mol_product_dissim=Chem.MolFromSmiles(""), mol_reactants=Chem.MolFromSmiles(".".join(rxn.reactants)), ) rxn_diff_list.append(diffs) # ~ diff_list = [ # ~ rxn.reactants[j], # ~ [Chem.MolToSmiles(x) for x in mol_diffs], # ~ rxn.products[i], # ~ ] # ~ rxn_diff_list.append(diff_list) return rxn_diff_list
def process_mol(self, test_mol: Chem.Mol) -> list: """ Decompose molecule in sidechains @param test_mol: input molecule @return: list of R-groups as SMILES """ # The subgraph match of the scaffold onto the molecule match_list = test_mol.GetSubstructMatches(self.rg_mol, False) if len(match_list) == 0: return [] # Loop over matches to take care of all symmetry mappings rgroup_smiles_lst = [] for match_idx, lst in enumerate(match_list): [atm.SetAtomMapNum(0) for atm in test_mol.GetAtoms()] match_set = set(lst) # map atom map numbers from the scaffold to the molecule for test_idx, query_idx in zip(lst, self.rg_map_lst): match_atm = test_mol.GetAtomWithIdx(test_idx) match_atm.SetAtomMapNum(query_idx) # Push the atom map numbers to the non-scaffold neighbors for nbr in match_atm.GetNeighbors(): if nbr.GetAtomMapNum() == 0 and (int(nbr.GetIdx()) not in match_set): nbr.SetAtomMapNum(query_idx) # Delete the scaffold, should only leave labeled R-groups rgroup_mol = Chem.DeleteSubstructs(test_mol, self.rg_mol) for atm in rgroup_mol.GetAtoms(): # Get rid of implicit hydrogens on the terminal atoms of the substituents if atm.GetAtomMapNum() > 0: atm.SetNoImplicit(True) # Initialize a list of hydrogen substituents [[H:1],[H:2],...] rgroup_smiles_lst.append( ["[H][*:%d]" % x for x in self.rg_idx_lst]) # Loop over substituents and place them in the appropriate place in the list for frag in Chem.GetMolFrags(rgroup_mol, asMols=True, sanitizeFrags=False): frag_idx = get_fragment_idx(frag) # This enables us to skip over stray fragments that may not have R-group labels if frag_idx > 0: new_frag = grow_rgroup_atoms(frag) rgroup_smiles_lst[match_idx][frag_idx - 1] = Chem.MolToSmiles( new_frag, True) # Here's where we handle symmetry mapping. There may be multiple ways to map the scaffold onto # the molecule. We want to pick the mapping that results in the largest number of non-hydrogen # R-groups. Calculate the number of hydrogens used as rgroups. Sort to put the mapping with # the largest number of non-hydrogen R-groups first. augmented_list = [(count_hydrogens(x), x) for x in rgroup_smiles_lst] augmented_list.sort(key=itemgetter(0)) return augmented_list[0][1]
def _pyGetScaffoldForMol(mol): while mol.HasSubstructMatch(murckoQ): for patt in murckoPatts: mol = Chem.DeleteSubstructs(mol, patt) for atom in mol.GetAtoms(): if atom.GetAtomicNum() == 6 and atom.GetNoImplicit( ) and atom.GetExplicitValence() < 4: atom.SetNoImplicit(False) h = Chem.MolFromSmiles('[H]') mol = Chem.ReplaceSubstructs(mol, Chem.MolFromSmarts('[D1;$([D1]-n)]'), h, True)[0] mol = Chem.RemoveHs(mol) return mol
def join_by_dummy(cls, a: Chem.Mol, b: Chem.Mol) -> Chem.Mol: # So I was worried that joining by the connect neighbour and then deleting the dummy # may cause issues of valence. So I did it this more convoluted way. # but did not check first... and this approach leads to sanitisation... for atom in a.GetAtoms(): atom.SetDoubleProp('_originalIdx', atom.GetIdx()) conn = cls.get_conn(a) mod_a = Chem.DeleteSubstructs(a, Chem.MolFromSmiles('*')) i = cls._get_new_index(mod_a, conn.GetIdx()) combo = Chem.ReplaceSubstructs(b, Chem.MolFromSmiles('*'), mod_a, replacementConnectionPoint=i)[0] combo.UpdatePropertyCache() Chem.SanitizeMol(combo) return combo
def remove_rdkit_fragment(childGenes, GeneSet, oldGene): geneSet = GeneSet.RdkitFrags try: newGene = Chromosome(Chem.MolToSmiles(geneSet.GetFuncGroup(\ random.sample(range(geneSet.GetNumFuncGroups()), 1)[0])),0) except: return 0 try: truncate = Chem.DeleteSubstructs(childGenes.Mol, newGene.Mol) childGenes = truncate childGenes = Chromosome(Chem.MolToSmiles(childGenes), 0) return childGenes except: return 0
def ring_check_res(res, clean_frag): check = True gen_mol = Chem.MolFromSmiles(res[1]) linker = Chem.DeleteSubstructs(gen_mol, clean_frag) # Get linker rings ssr = Chem.GetSymmSSSR(linker) # Check rings for ring in ssr: for atom_idx in ring: for bond in linker.GetAtomWithIdx(atom_idx).GetBonds(): if bond.GetBondType() == 2 and bond.GetBeginAtomIdx() in ring and bond.GetEndAtomIdx() in ring: check = False return check
def replace_isotope(smiles): """Replace an added atom with an attachment point""" rdmol = Chem.MolFromSmiles(str(smiles)) em = Chem.EditableMol(rdmol) for my_id in rdmol.GetAtoms(): if my_id.GetIsotope() == 0: continue else: # Replace with a gap em.ReplaceAtom(my_id.GetIdx(), Chem.Atom(0)) # Now remove all these atoms star_mol = em.GetMol() out_mol = Chem.DeleteSubstructs(star_mol, Chem.MolFromSmarts('[#0]')) return Chem.MolToSmiles(out_mol, isomericSmiles=True)
def trim_side_chain(mol: Chem.rdchem.Mol, core, unwanted_side_chains): """Trim list of side chain from a molecule.""" mol = Chem.AddHs(mol) match = mol.GetSubstructMatch(core) map2idx = {} map2nei = {} unwanted2map = {} for patt in unwanted_side_chains: unwanted2map[patt] = [ a.GetAtomMapNum() for a in patt.GetAtoms() if a.GetAtomMapNum() ] unwanted_mapping = list( itertools.chain.from_iterable(unwanted2map.values())) for atom in core.GetAtoms(): num = atom.GetAtomMapNum() if num and num in unwanted_mapping: mol_atom_idx = match[atom.GetIdx()] map2idx[mol_atom_idx] = num nei_atoms = mol.GetAtomWithIdx(mol_atom_idx).GetNeighbors() map2nei[mol_atom_idx] = [ n.GetIdx() for n in nei_atoms if n.GetIdx() in match ] emol = Chem.EditableMol(mol) for atom_idx, atom_map in map2idx.items(): dummy = Chem.rdchem.Atom("*") dummy.SetAtomMapNum(atom_map) nei_idx = map2nei.get(atom_idx, [None])[0] if nei_idx: bond = mol.GetBondBetweenAtoms(atom_idx, nei_idx) emol.RemoveBond(atom_idx, nei_idx) new_ind = emol.AddAtom(dummy) emol.AddBond(nei_idx, new_ind, bond.GetBondType()) mol = emol.GetMol() mol = Chem.RemoveHs(mol) query_param = AdjustQueryParameters() query_param.makeDummiesQueries = False query_param.adjustDegree = False query_param.aromatizeIfPossible = True for patt, _ in unwanted2map.items(): cur_frag = dm.fix_mol(patt) mol = Chem.DeleteSubstructs(mol, cur_frag, onlyFrags=True) return dm.keep_largest_fragment(mol)
def get_bridge_idty(ligand: Mol, class_pattern: str) -> Optional[List[str]]: ligand = Chem.DeleteSubstructs( ligand, Chem.MolFromSmiles("[N+](=O)[O-]", sanitize=False)) root_pattern = Chem.MolFromSmiles(class_pattern, sanitize=False) chains = Chem.ReplaceCore(ligand, root_pattern) # display(chains) if chains is None: return None pieces = Chem.GetMolFrags(chains, asMols=True) ligands = sorted([Chem.MolToSmiles(x, True) for x in pieces], key=len) bridge = [] for ligand in ligands: if (Chem.MolFromSmiles(ligand) ).GetNumAtoms() < 20 and ligand.count("*") > 1: bridge.append(re.sub(r"\[\d\*\]", "*", ligand)) return bridge
def weld_r_groups(input_mol): """ Take an input molecule with a labeled core and labeled R-groups and attach the R-groups (e.g. R1 to R1) @param input_mol: input molecule @return: nothing """ # First pass loop over atoms and find the atoms with an AtomMapNum join_dict = defaultdict(list) for atom in input_mol.GetAtoms(): map_num = atom.GetAtomMapNum() if map_num > 0: join_dict[map_num].append(atom) # Second pass, transfer the atom maps to the neighbor atoms for idx, atom_list in join_dict.items(): if len(atom_list) == 2: atm_1, atm_2 = atom_list nbr_1 = [x.GetOtherAtom(atm_1) for x in atm_1.GetBonds()][0] nbr_1.SetAtomMapNum(idx) nbr_2 = [x.GetOtherAtom(atm_2) for x in atm_2.GetBonds()][0] nbr_2.SetAtomMapNum(idx) # Nuke all of the dummy atoms new_mol = Chem.DeleteSubstructs(input_mol, Chem.MolFromSmarts('[#0]')) # Third pass - arrange the atoms with AtomMapNum, these will be connected bond_join_dict = defaultdict(list) for atom in new_mol.GetAtoms(): map_num = atom.GetAtomMapNum() if map_num > 0: bond_join_dict[map_num].append(atom.GetIdx()) # Make an editable molecule and add bonds between atoms with corresponding AtomMapNum em = EditableMol(new_mol) for idx, atom_list in bond_join_dict.items(): if len(atom_list) == 2: start_atm, end_atm = atom_list em.AddBond(start_atm, end_atm, order=Chem.rdchem.BondType.SINGLE) final_mol = em.GetMol() # remove the AtomMapNum values for atom in final_mol.GetAtoms(): atom.SetAtomMapNum(0) final_mol = Chem.RemoveHs(final_mol) return final_mol
def Weld_R_Groups(input_mol): from rdkit import Geometry from rdkit.Chem import Draw from rdkit.Chem.rdchem import EditableMol from rdkit.Chem.Draw import IPythonConsole # First pass loop over atoms and find the atoms with an AtomMapNum join_dict = defaultdict(list) for atom in input_mol.GetAtoms(): map_num = atom.GetAtomMapNum() if map_num > 0: join_dict[map_num].append(atom) # Second pass, transfer the atom maps to the neighbor atoms for idx, atom_list in join_dict.items(): if len(atom_list) == 2: atm_1, atm_2 = atom_list nbr_1 = [x.GetOtherAtom(atm_1) for x in atm_1.GetBonds()][0] nbr_1.SetAtomMapNum(idx) nbr_2 = [x.GetOtherAtom(atm_2) for x in atm_2.GetBonds()][0] nbr_2.SetAtomMapNum(idx) # Nuke all of the dummy atoms new_mol = Chem.DeleteSubstructs(input_mol, Chem.MolFromSmarts('[#0]')) # Third pass - arrange the atoms with AtomMapNum, these will be connected bond_join_dict = defaultdict(list) for atom in new_mol.GetAtoms(): map_num = atom.GetAtomMapNum() if map_num > 0: bond_join_dict[map_num].append(atom.GetIdx()) # Make an editable molecule and add bonds between atoms with correspoing AtomMapNum em = EditableMol(new_mol) for idx, atom_list in bond_join_dict.items(): if len(atom_list) == 2: start_atm, end_atm = atom_list em.AddBond(start_atm, end_atm, order=Chem.rdchem.BondType.SINGLE) final_mol = em.GetMol() # remove the AtomMapNum values for atom in final_mol.GetAtoms(): atom.SetAtomMapNum(0) final_mol = Chem.RemoveHs(final_mol) return final_mol
def _pyGetScaffoldForMol(mol): while mol.HasSubstructMatch(murckoQ): for patt in murckoPatts: mol = Chem.DeleteSubstructs(mol,patt) for atom in mol.GetAtoms(): if atom.GetAtomicNum()==6 and atom.GetNoImplicit() and atom.GetExplicitValence()<4: atom.SetNoImplicit(False) h = Chem.MolFromSmiles('[H]') mol = Chem.ReplaceSubstructs(mol,Chem.MolFromSmarts('[D1;$([D1]-n)]'),h,True)[0]; mol=Chem.RemoveHs(mol) #while 1: # ps = aromaticNTransform.RunReactants([mol]) # if ps: # mol = ps[0][0] # else: # break return mol
def remove_zero_atoms(mol_block): "Function to take a molecule and remove all atoms with no mass" rdmol = Chem.MolFromMolBlock(str(mol_block)) conf = rdmol.GetConformer() em = Chem.EditableMol(rdmol) out_lines = [] [ em.ReplaceAtom(x.GetIdx(), Chem.Atom(0)) for x in rdmol.GetAtoms() if [0.0, 0.0, 0.0] == [ conf.GetAtomPosition(x.GetIdx()).x, conf.GetAtomPosition(x.GetIdx()).z, conf.GetAtomPosition(x.GetIdx()).z ] ] star_mol = em.GetMol() out_mol = Chem.DeleteSubstructs(star_mol, Chem.MolFromSmarts('[#0]')) return Chem.MolToMolBlock(out_mol)
def MoveDummyNeighborsToBeginning(mol, useAll=False): dummyPatt = Chem.MolFromSmiles('[*]') matches = mol.GetSubstructMatches(dummyPatt) res = [] for match in matches: smi = Chem.MolToSmiles(mol, rootedAtAtom=match[0]) entry = Chem.MolFromSmiles(smi) # entry now has [*] as atom 0 and the neighbor # as atom 1. Cleave the [*]: entry = Chem.DeleteSubstructs(entry, dummyPatt) for propN in mol.GetPropNames(): entry.SetProp(propN, mol.GetProp(propN)) # now we have a molecule with the atom to be joined # in position zero; Keep that: res.append(entry) if not useAll: break return res