Example #1
0
    def get_skeleton_template(self):
        """
        Converts skeleton SMILES string into template where possible
        substitution sites are identified.

        Returns
        -------

        template : :class:`str`
            Pseudo-SMILES string with possible substitution sites indicated
            by parentheses '{}'.
        """

        if self.auto_placement:
            mol_h = rdkit.MolFromSmiles(self.skeleton_smiles)
            rdkit.AddHs(mol_h)
            template = rdkit.MolToSmiles(mol_h, allHsExplicit=True)
            template = template.replace('[cH]', 'c{}').replace('[c]', 'c')
            template = template.replace('[CH]', 'C{}').replace('[C]', 'C')
        else:
            template = self.skeleton_smiles.replace('(Br)', '{}')

        self.vacant_sites = template.count('{}')

        if self.nconnect > self.vacant_sites:
            raise SpecificationError(
                "Number of connections cannot be greater than the number of possible substitution sites."
            )
        if self.nmax is not None:
            if self.nconnect > self.nmax:
                raise SpecificationError(
                    "Number of connections cannot be greater than the maximum number of allowed substitutions."
                )

        return template
Example #2
0
    def generate_polymer(self, permutation, monomers_dict, name):

        sequence = string.ascii_uppercase[:len(permutation)]
        isomers = [0 for i in permutation]

        structunits = []
        for id in permutation:
            smiles = rdkit.MolToSmiles(rdkit.MolFromSmiles(monomers_dict[id]),
                                       canonical=True)
            mol = rdkit.AddHs(rdkit.MolFromSmiles(smiles))
            rdkit.AllChem.EmbedMolecule(mol, rdkit.AllChem.ETKDG())
            structunits.append(stk.StructUnit2.rdkit_init(mol, "bromine"))

        repeat = stk.Polymer(structunits,
                             stk.Linear(sequence, isomers, n=1),
                             name=name)
        polymer = stk.Polymer(structunits,
                              stk.Linear(sequence, isomers, n=self.n_repeat),
                              name=name)
        rdkit.MolToMolFile(polymer.mol, 'test.mol')

        return polymer, repeat
Example #3
0
    def _combine_to_dyes(self, i, smile_tuple):
        A_smiles = smile_tuple[0]
        B_smiles = smile_tuple[1]
        C_smiles = smile_tuple[2]

        Amol = rdkit.AddHs(rdkit.MolFromSmiles(A_smiles))
        Bmol = rdkit.AddHs(rdkit.MolFromSmiles(B_smiles))
        Cmol = rdkit.AddHs(rdkit.MolFromSmiles(C_smiles))

        A = stk.StructUnit2.rdkit_init(Amol, 'bromine')
        B = stk.StructUnit2.rdkit_init(Bmol, 'bromine')
        C = stk.StructUnit2.rdkit_init(Cmol, 'bromine')

        try:
            dye1 = stk.Polymer([B, C, B], stk.Linear('ABA', [0,0,1], n=1, ends='fg'))
            X = stk.StructUnit2.rdkit_init(dye1.mol, 'bromine')
            dye = stk.Polymer([A, X, A], stk.Linear('ABA', [0,0,1], n=1))
            dyemol = dye.mol
            stk.rdkit_ETKDG(dye)
            id = '{:08d}'.format(i)
        except Exception as e:
            print(e, 'Build error')
        return A_smiles, B_smiles, C_smiles, dye, id
Example #4
0
    def assign_ring_order(self, skeleton, substituents):
        """
        Assures that ring numbering in substituents is compatible with the
        number of rings present in the skeleton.

        Arguments
        ---------

        skeleton : :class:`str`
            SMILES string representing molecular skeleton onto which substituent
            groups will be placed.

        substituents : :class:`list`
            A list of allowed substituents, represented by SMILES strings.

        Returns
        -------

        substituents : :class:`list`
            The list of allowed substituents, still represented by SMILES
            strings, with their ring open/close numbering adjusted to be
            compatible with the number of rings present in the skeleton.

        """

        n = rdMolDescriptors.CalcNumAromaticRings(
            rdkit.MolFromSmiles(skeleton))

        for i, item in enumerate(substituents):
            rings = rdMolDescriptors.CalcNumAromaticRings(
                rdkit.MolFromSmiles(item[1:-1]))
            if rings > 0:
                for j in reversed(range(rings + 1)):
                    item = item.replace(str(j), str(j + n))
                substituents[i] = item

        return substituents
Example #5
0
    def get_substituent_permutations(self, template):
        """
        Generator that yields all combinations of user-specified substituents.

        Arguments
        ---------

        template : :class:`str` SMILES string representing aromatic skeleton and
            available substitution sites.

        Yields
        -------

        smiles : :class:`str` permutation of a given subset of substituents.

        """

        if self.nmax is not None:
            if self.nmax >= self.vacant_sites:
                vacancies = self.vacant_sites - self.nconnect
            else:
                vacancies = self.nmax - self.nconnect
        else:
            vacancies = self.vacant_sites - self.nconnect

        for i in range(vacancies + 1):
            combinations = itertools.product(self.substituents, repeat=i)

            combinations = [
                (list(i) + ['(' + self.connect_atom + ')'] * self.nconnect)
                for i in combinations
            ]
            combinations = [
                i + [''] * (self.vacant_sites - len(i)) for i in combinations
            ]
            #combinations = self.assign_ring_order(combinations)

            for combination in combinations:
                for permutation in set(itertools.permutations(combination)):
                    smiles = rdkit.MolToSmiles(rdkit.MolFromSmiles(
                        template.format(*permutation)),
                                               canonical=True)
                    yield smiles