Beispiel #1
0
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()
Beispiel #3
0
 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)
Beispiel #4
0
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()
Beispiel #5
0
    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()