def graph2mol(graph): emol = Chem.RWMol() for v in graph.vs(): emol.AddAtom(Chem.AtomFromSmiles(v["name"])) for e in graph.es(): emol.AddBond(e.source, e.target, rank2bond(e['bond'])) mol = emol.GetMol() return mol
def edit_RCO2H(em, pm, match_combo, L=None): ''' Should return a list of mols Source: Reynolds Class Notes, 9-24-20, p.3 Test SMILES: *c1ccc(*)cc1 ''' o_inds = [em.AddAtom(Chem.AtomFromSmiles('O')) for _ in range(L)] c_inds = [em.AddAtom(Chem.AtomFromSmiles('C')) for _ in range(L)] dbl_o_inds = [em.AddAtom(Chem.AtomFromSmiles('O')) for _ in range(L)] methyl_c_inds = [em.AddAtom(Chem.AtomFromSmiles('C')) for _ in range(L)] for i in range(L): em.AddBond(o_inds[i], match_combo[i][1], Chem.BondType.SINGLE) em.AddBond(c_inds[i], o_inds[i], Chem.BondType.SINGLE) em.AddBond(c_inds[i], dbl_o_inds[i], Chem.BondType.DOUBLE) em.AddBond(c_inds[i], methyl_c_inds[i], Chem.BondType.SINGLE) em = retro.pm_to_lp_em(em, pm) new_mol = em.GetMol() for x in match_combo: new_mol.GetAtomWithIdx(x[1]).SetNumExplicitHs( pm.mol.GetAtomWithIdx(x[1]).GetNumImplicitHs()) new_mol.GetAtomWithIdx(x[0]).SetNumExplicitHs( pm.mol.GetAtomWithIdx(x[0]).GetNumImplicitHs() + 1) return [new_mol]
def edit_HCl(em, pm, match_combo, L=None): ''' Should return a list of mols Source: Reynolds Class Notes, 9-24-20, p.5 Test SMILES: '*/C(C#N)=C/C1C=CC(*)CC1' ''' match_arr = np.array(match_combo) new_mols = [] for i in range(2): em = Chem.EditableMol(pm.mol) cl_inds = [em.AddAtom(Chem.AtomFromSmiles('Cl')) for _ in range(L)] c_inds = match_arr[:, i] for i in range(L): em.RemoveBond(match_combo[i][0], match_combo[i][1]) em.AddBond(match_combo[i][0], match_combo[i][1], Chem.BondType.SINGLE) em.AddBond(int(c_inds[i]), cl_inds[i], Chem.BondType.SINGLE) em = retro.pm_to_lp_em(em, pm) new_mols.append(em.GetMol()) return new_mols
def ring_close_retro(lp, pm=None): ''' Reverse of Ring-closing which will occur after addition of heat Source: Reynolds Class Notes, 8-25-20, p.2 Test SMILES: '*c5ccc(Oc4ccc(n3c(=O)c2cc1c(=O)n(*)c(=O)c1cc2c3=O)cc4)cc5' ''' if type(lp) == str or type( lp ) == Chem.rdchem.Mol: #only for convenience. Pass in LinearPol object when possible lp = ru.LinearPol(lp) start_match = Chem.MolFromSmarts('[c,C;!R0;!R1](=O)[n,N;!R0;!R1]') end_match = Chem.MolFromSmarts('[#6R0](=O)([OH])[C,c][C,c][CR1](=O)[NR1]') if pm is None: pm = lp.PeriodicMol() if pm is not None: pm.GetSSSR() if pm is None: return [] mols = [] if pm.HasSubstructMatch( start_match) and not pm.HasSubstructMatch(end_match): lp_no_connect_inds = np.array( [x for x in range(lp.mol.GetNumAtoms()) if x not in lp.star_inds]) def lp_to_pm_ind(lp_ind): return int(np.argwhere(lp_no_connect_inds == lp_ind)) ar_atom_idx = [a.GetIdx() for a in lp.mol.GetAromaticAtoms()] if len( ar_atom_idx ) != 0: #only execute below for aromatic polymers. There for speed. ri = lp.mol.GetRingInfo() ar = ri.AtomRings() atom_aromaticity = {a: 0 for a in ar_atom_idx} for ring in ar: ar_ring = 1 for a in ring: if a not in atom_aromaticity.keys(): ar_ring = 0 if ar_ring == 1: for a in ring: atom_aromaticity[a] += 1 all_matches = pm.mol.GetSubstructMatches(start_match) seen = set() matches = [] #unique matches for match in all_matches: ms = set(match) #match set #print(seen.difference(ms)) #print(ms.difference(seen)) if len(ms.intersection(seen)) == 0: seen = seen.union(ms) matches.append(match) #matches = pm.mol.GetSubstructMatches(start_match) for L in range(1, len(matches) + 1): #for L in range(2,3): for match_combo in itertools.combinations(matches, L): em = Chem.EditableMol(pm.mol) #print('Match combo:', match_combo) for i_c, i_o, i_n in match_combo: #indices of atoms in pm #print('Matches: %s %s %s' %(i_c,i_o,i_n) ) fix_aromaticity = False if pm.mol.GetBondBetweenAtoms( i_c, i_n).GetBondType() == Chem.BondType.AROMATIC: fix_aromaticity = True ring_atoms = None ring_size = 100 for i in range(len(ar)): ring = ar[i] if lp_no_connect_inds[ i_c] in ring and lp_no_connect_inds[ i_n] in ring and len( ring ) < ring_size: #assume correct ring is the smallest one ring_atoms = set(ring) ring_size = len(ring) o = em.AddAtom(Chem.AtomFromSmiles('O')) em.AddBond(i_c, o, Chem.BondType.SINGLE) #print('bond between %s and %s' %(i_c,o)) em.RemoveBond(i_c, i_n) #print('Bond removed between %s and %s' %(i_c,i_n)) med_mol = em.GetMol() if fix_aromaticity: try: i_n_aromaticity = atom_aromaticity[lp_to_pm_ind( i_n)] except: i_n_aromaticity = 0 for i in ring_atoms: if atom_aromaticity[ i] == i_n_aromaticity: #if an atom was part of same number of aromatic rings as the N atom, it shouldn't be aromatic #print('Ring atom lp:',i) pm_i = lp_to_pm_ind(i) #print('Ring atom pm:',pm_i) med_mol.GetAtomWithIdx(pm_i).SetIsAromatic( False) #remove all aromatic bonds neighs = [ x.GetIdx() for x in med_mol.GetAtoms() [pm_i].GetNeighbors() ] aromatic_neighs = [ x for x in neighs if med_mol.GetBondBetweenAtoms(pm_i, x). GetBondType() == Chem.BondType.AROMATIC ] #print('Aromatic neighs of %s: %s' %(pm_i,aromatic_neighs)) em = Chem.EditableMol(med_mol) for x in aromatic_neighs: em.RemoveBond(x, pm_i) em.AddBond(x, pm_i, Chem.BondType.SINGLE) med_mol = em.GetMol() em = Chem.EditableMol(med_mol) star1 = em.AddAtom(Chem.AtomFromSmiles('*')) star2 = em.AddAtom(Chem.AtomFromSmiles('*')) em.RemoveBond(pm.connector_inds[0], pm.connector_inds[1]) em.AddBond(pm.connector_inds[0], star1, Chem.BondType.SINGLE) em.AddBond(pm.connector_inds[1], star2, Chem.BondType.SINGLE) new_mol = em.GetMol() try: Chem.SanitizeMol(new_mol) mols.append(ru.mol_without_atom_index(new_mol)) except: return [] return mols else: return []
def set_atm_list(self, str_atm_list): atm_list = [] for str_atm in str_atm_list: atm_list.append(Chem.AtomFromSmiles("["+str_atm+"]")) self.prepare_atm(atm_list)