예제 #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
예제 #2
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
예제 #3
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
예제 #4
0
    def _properties(self, A_smiles, B_smiles, C_smiles, id):
        with open(f'lowest_conformers/{id}_lowest-conformer.mol', 'r') as f:
            molfile = f.read()
        molfile = rdkit.MolFromMolBlock(molfile)
        molfile = rdkit.AddHs(molfile)
        rdkit.AllChem.EmbedMolecule(molfile, rdkit.AllChem.ETKDG())
        dirname = str(id)+'_properties'
        os.mkdir(dirname)
        os.chdir(dirname)
        xyz = generate_xyz(molfile)

        if self.solvent != None:
            p = sp.Popen(['xtb','xyz','-opt','-gbsa', self.solvent], stdout=sp.PIPE)
            output, _ = p.communicate()

        else:
            p = sp.Popen(['xtb','xyz','-opt'], stdout=sp.PIPE)
            output, _ = p.communicate()

        if self.solvent != None:
            p = sp.Popen(['xtb','xtbopt.xyz', '-vip', '-gbsa', self.solvent], stdout=sp.PIPE)
            output, _ = p.communicate()

        else:
            p = sp.Popen(['xtb','xtbopt.xyz', '-vip'], stdout=sp.PIPE)
            output, _ = p.communicate()

        with open('temp.txt', 'wb') as f:
            f.write(output)

        with open('temp.txt', 'rb') as f:
            temp = f.read()
            temp = str(temp)

        pattern = re.compile('(?<=delta SCC IP [(]eV[)].).*\d\.\d{4}')
        ip = pattern.findall(temp)

        rt = sp.Popen(['rm','temp.txt'], stdout=sp.PIPE)
        o, e = rt.communicate()

        if self.solvent != None:
            p = sp.Popen(['xtb','xtbopt.xyz', '-vea', '-gbsa', self.solvent], stdout=sp.PIPE)
            output, _ = p.communicate()

        else:
            p = sp.Popen(['xtb','xtbopt.xyz', '-vea'], stdout=sp.PIPE)
            output, _ = p.communicate()

        with open('temp.txt', 'wb') as f:
            f.write(output)

        with open('temp.txt', 'rb') as f:
            temp = f.read()
            temp = str(temp)

        pattern = re.compile('(?<=delta SCC EA [(]eV[)].).*\d\.\d{4}')
        ea = pattern.findall(temp)

        rt = sp.Popen(['rm','temp.txt'], stdout=sp.PIPE)
        o, e = rt.communicate()

        p = sp.Popen(['xtb','xtbopt.xyz'], stdout=sp.PIPE)
        output, _ = p.communicate()

        p = sp.Popen(['stda','-xtb', '-e', '8'], stdout=sp.PIPE)
        output, _ = p.communicate()
        with open('temp.txt', 'wb') as f:
            f.write(output)

        with open('temp.txt', 'rb') as f:
            temp = f.read()
            temp = str(temp)

        pattern = re.compile(r'\\n\s+\d+\s+(\d\.\d+)\s+[\d.-]+\s+(\d+\.\d+)[>\(\)\s\d.-]*')
        og = pattern.findall(temp)

        rt = sp.Popen(['rm','temp.txt'], stdout=sp.PIPE)
        o, e = rt.communicate()

        smilenoH = rdkit.RemoveHs(molfile)
        smiles = rdkit.MolToSmiles(smilenoH, canonical=True)

        string = str(id)+'\t'
        for match in ip:
            match = match.strip()
            string += match+'\t'
        for match in ea:
            match = match.strip()
            string += match+'\t'
        opgap = []
        osc = []
        for match in og:
            if float(match[1]) > self.min_osc_strength:
                opgap.append(match[0])
                osc.append(match[1])
                break
        string += opgap[0]+'\t'
        string += osc[0]+'\t'
        string += smiles+'\t'
        string += A_smiles+'\t'
        string += B_smiles+'\t'
        string += C_smiles+'\n'

        with open('props.txt', 'w') as f:
            f.write(string)
        os.chdir('../')