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
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
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
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('../')