def convert_dict_to_mols(tot_dict): """ :param tot_dict: :return: """ mol_list = [] for smiles in tot_dict: # Now generate the molecules for that mol = RWMol() atoms = tot_dict[smiles] print(atoms) for atom in atoms: atom = Atom(6) mol.AddAtom(atom) # for i in range(len(atoms)-1): # mol.AddBond(i,i+1) mol = mol.GetMol() AllChem.EmbedMolecule(mol) conf = mol.GetConformer() for i, atom in enumerate(atoms): point_3d = Point3D(atom[0], atom[1], atom[2]) conf.SetAtomPosition(i, point_3d) mol = conf.GetOwningMol() mol.SetProp("_Name", smiles) mol_list.append(mol) return mol_list
def remove_exocyclic_attachments(mol): """ Remove exocyclic and exolinker attachments from a molecule. Parameters ---------- mol : rdkit.Chem.rdchem.Mol Returns ------- rdkit.Chem.rdchem.Mol Molecule with exocyclic/exolinker attachments removed. """ edit = RWMol(mol) remove_atoms = set() for atom in edit.GetAtoms(): degree = atom.GetDegree() if degree == 1: bond = atom.GetBonds()[0] if bond.GetBondTypeAsDouble() == 2.0: nbr = bond.GetOtherAtom(atom) hcount = nbr.GetTotalNumHs() nbr.SetNumExplicitHs(hcount + 2) nbr.SetNoImplicit(True) remove_atoms.add(atom.GetIdx()) for aix in sorted(remove_atoms, reverse=True): edit.RemoveAtom(aix) rdmolops.AssignRadicals(edit) GetSymmSSSR(edit) return edit.GetMol()
def complement_reaction(rxn_template): if rxn_template.GetNumProductTemplates() != 1: print("[ERROR] A reaction template has only one product template.") sys.exit(1) pro = rxn_template.GetProductTemplate(0) rw_pro = RWMol(pro) amaps_pro = {a.GetAtomMapNum() for a in pro.GetAtoms()} amaps_rcts = {a.GetAtomMapNum() for rct in rxn_template.GetReactants() for a in rct.GetAtoms()} amaps_not_in_rcts = amaps_pro.intersection(amaps_rcts) for amap in amaps_not_in_rcts: aidx = [a.GetIdx() for a in rw_pro.GetAtoms() if a.GetAtomMapNum() == amap][0] rw_pro.RemoveAtom(aidx) m = rw_pro.GetMol() if '.' in Chem.MolToSmarts(m): return if (m.GetNumAtoms() == 0) or (m.GetNumAtoms() == 1 and m.GetAtomWithIdx(0).GetSymbol() in {"*", None}): return rxn_template.AddReactantTemplate(m)
def link_li(rebuilt_smi): mol = Chem.MolFromSmiles(rebuilt_smi) mol = RWMol(mol) bons = [x[0] for x in mol.GetSubstructMatches(Chem.MolFromSmarts("[Xe]"))] mol.AddBond(bons[0], bons[1]) return mol.GetMol()
def _join_atoms(self, combo: Chem.RWMol, anchor_A: int, anchor_B: int, distance: float, linking: bool = True): """ extrapolate positions between. by adding linkers if needed. """ conf = combo.GetConformer() pos_A = conf.GetAtomPosition(anchor_A) pos_B = conf.GetAtomPosition(anchor_B) n_new = int(round(distance / 1.22) - 1) xs = np.linspace(pos_A.x, pos_B.x, n_new + 2)[1:-1] ys = np.linspace(pos_A.y, pos_B.y, n_new + 2)[1:-1] zs = np.linspace(pos_A.z, pos_B.z, n_new + 2)[1:-1] # correcting for ring marker atoms def is_ring_atom(anchor: int) -> bool: atom = combo.GetAtomWithIdx(anchor) if atom.HasProp('_ori_i') and atom.GetIntProp('_ori_i') == -1: return True else: return False if is_ring_atom(anchor_A): distance -= 1.35 + 0.2 # Arbitrary + 0.2 to compensate for the ring not reaching (out of plane). n_new -= 1 xs = xs[1:] ys = ys[1:] zs = zs[1:] if is_ring_atom(anchor_B): distance -= 1.35 + 0.2 # Arbitrary + 0.2 to compensate for the ring not reaching (out of plane). n_new -= 1 xs = xs[:-1] ys = ys[:-1] zs = zs[:-1] # notify that things could be leary. if distance < 0: self.journal.debug( f'Two ring atoms detected to be close. Joining for now.' + ' They will be bonded/fused/spiro afterwards') # check if valid. if distance > self.joining_cutoff: msg = f'Atoms {anchor_A}+{anchor_B} are {distance} Å away. Cutoff is {self.joining_cutoff}.' self.journal.warning(msg) raise ConnectionError(msg) # place new atoms self.journal.debug( f'Molecules will be joined via atoms {anchor_A}+{anchor_B} ({distance} Å) via the addition of {n_new} atoms.' ) previous = anchor_A if linking is False and n_new > 0: self.journal.warning( f'Was going to bond {anchor_A} and {anchor_B} but reconsidered.' ) elif linking is True and n_new <= 0: combo.AddBond(previous, anchor_B, Chem.BondType.SINGLE) new_bond = combo.GetBondBetweenAtoms(previous, anchor_B) BondProvenance.set_bond(new_bond, 'main_novel') elif linking is False and n_new <= 0: combo.AddBond(previous, anchor_B, Chem.BondType.SINGLE) new_bond = combo.GetBondBetweenAtoms(previous, anchor_B) BondProvenance.set_bond(new_bond, 'other_novel') elif linking is True and n_new > 0: for i in range(n_new): # make oxygen the first and last bridging atom. if i == 0 and combo.GetAtomWithIdx( anchor_A).GetSymbol() == 'C': new_atomic = 8 elif i > 2 and i == n_new - 1 and combo.GetAtomWithIdx( anchor_B).GetSymbol() == 'C': new_atomic = 8 else: new_atomic = 6 idx = combo.AddAtom(Chem.Atom(new_atomic)) new = combo.GetAtomWithIdx(idx) new.SetBoolProp('_Novel', True) new.SetIntProp('_ori_i', 999) conf.SetAtomPosition( idx, Point3D(float(xs[i]), float(ys[i]), float(zs[i]))) combo.AddBond(idx, previous, Chem.BondType.SINGLE) new_bond = combo.GetBondBetweenAtoms(idx, previous) BondProvenance.set_bond(new_bond, 'linker') previous = idx combo.AddBond(previous, anchor_B, Chem.BondType.SINGLE) new_bond = combo.GetBondBetweenAtoms(previous, anchor_B) BondProvenance.set_bond(new_bond, 'linker') else: raise ValueError('Impossible') return combo.GetMol()