genop 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
genop-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,17 @@
1
+ Metadata-Version: 2.4
2
+ Name: genop
3
+ Version: 0.1.0
4
+ Summary: Codon optimization tool
5
+ Home-page: https://github.com/conzaytsev/GeneOptimizer
6
+ Author: Konstantin Zaytsev
7
+ Classifier: License :: OSI Approved :: MIT License
8
+ Classifier: Programming Language :: Python :: 3
9
+ Requires-Python: >3.9
10
+ Dynamic: author
11
+ Dynamic: classifier
12
+ Dynamic: description
13
+ Dynamic: home-page
14
+ Dynamic: requires-python
15
+ Dynamic: summary
16
+
17
+ Python module for codon optimization in genes to achieve specific expression levels.
@@ -0,0 +1 @@
1
+ from .gene_optimizer import Optimizer
@@ -0,0 +1,269 @@
1
+ from random import randint, choices
2
+ from importlib.resources import files
3
+ import pickle
4
+ from . import models
5
+
6
+
7
+ def crossingover(sequence1, sequence2):
8
+ point1 = randint(0, len(sequence1))
9
+ point2 = randint(0, len(sequence1))
10
+ while point2 == point1:
11
+ point2 = randint(0, len(sequence1))
12
+ if point1 > point2:
13
+ point1, point2 = point2, point1
14
+ new_sequence1 = sequence1[: point1] + sequence2[point1: point2] + sequence1[point2:]
15
+ new_sequence2 = sequence2[: point1] + sequence1[point1: point2] + sequence2[point2:]
16
+ return new_sequence1, new_sequence2
17
+
18
+
19
+ def randomize(encoded, codon_dictionary):
20
+ randomized = ''
21
+ for i in encoded:
22
+ randomized += codon_dictionary[i][randint(0, len(codon_dictionary[i]) - 1)]
23
+ return randomized
24
+
25
+
26
+ def nonrandomize(encoded, triplet_encoded, sixplet_dictionary, sixplet_frequencies, codon_dictionary, codon_context):
27
+ randomized = choices(sixplet_dictionary[encoded[0]], sixplet_frequencies[encoded[0]])[0]
28
+ for i in triplet_encoded[2:]:
29
+ randomized += choices(codon_dictionary[i], codon_context[randomized[-3:]][i])[0]
30
+ return randomized
31
+
32
+
33
+ def translate(aa_sequence):
34
+ dictionary = {'F': 'TTT', 'L': 'TTA', 'I': 'ATT', 'M': 'ATG', 'V': 'GTT', 'S': 'TCT', 'P': 'CCT', 'T': 'ACT',
35
+ 'A': 'GCT', 'Y': 'TAT', 'H': 'CAT', 'Q': 'CAA', 'N': 'AAT', 'K': 'AAA', 'D': 'GAT', 'E': 'GAA',
36
+ 'C': 'TGT', 'W': 'TGG', 'R': 'CGT', 'G': 'GGT'}
37
+ nuc_sequence = ''
38
+ for letter in aa_sequence:
39
+ nuc_sequence += dictionary[letter]
40
+ return nuc_sequence
41
+
42
+
43
+ def read_file(filename):
44
+ genes = []
45
+
46
+ if filename.split('.')[-1] == 'csv':
47
+ with open(filename, 'r') as file:
48
+ data = file.readlines()
49
+ for i in range(len(data)):
50
+ if i > 0:
51
+ data_string = data[i].replace('\n', '').split(';')
52
+ genes.append(data_string[2])
53
+
54
+ elif filename.split('.')[-1] == 'txt':
55
+ with open(filename, 'r') as file:
56
+ for line in file:
57
+ if len(line[:-1]) % 3 == 0 and len(line[:-1]) == line.count('A') + line.count('T') + line.count(
58
+ 'G') + line.count('C'):
59
+ genes.append(line[:-1])
60
+
61
+ else:
62
+ gene = ''
63
+ with open(filename, 'r') as file:
64
+ for line in file:
65
+ if line[0] == '>':
66
+ if gene != '' and len(gene) % 3 == 0 and len(gene) == gene.count('A') + gene.count(
67
+ 'T') + gene.count('G') + gene.count('C'):
68
+ genes.append(gene)
69
+ gene = ''
70
+ else:
71
+ gene += line[:-1]
72
+ if gene != '' and len(gene) % 3 == 0 and len(gene) == gene.count('A') + gene.count('T') + gene.count(
73
+ 'G') + gene.count('C'):
74
+ genes.append(gene)
75
+ return genes
76
+
77
+
78
+ def gc_content(sequence):
79
+ return (sequence.count('G') + sequence.count('C')) / len(sequence)
80
+
81
+
82
+ def restriction_check(sequence, restriction_sites):
83
+ for site in restriction_sites:
84
+ if sequence.find(site) > -1:
85
+ return False
86
+ return True
87
+
88
+
89
+ class Optimizer:
90
+ def __init__(self, input_sequence, sequence_type='nucleotide', expression_model='coli', subspace_model='coli', set_size=1000, expression_priority=1,
91
+ subspace_priority=0, center_priority=0, gc_priority=0, n_children=10, max_iterations=300, restriction_sites=''):
92
+ if expression_model == 'coli':
93
+ with open(files(models) / '511145_cei.pkl', 'rb') as file: self.expression_model = pickle.load(file)
94
+ else:
95
+ self.expression_model = expression_model
96
+ if subspace_model == 'coli':
97
+ with open(files(models) / '511145_sub.pkl', 'rb') as file: self.subspace_model = pickle.load(file)
98
+ else:
99
+ self.subspace_model = subspace_model
100
+
101
+ codon_dictionary = [['TTT', 'TTC'],
102
+ ['TTA', 'TTG', 'CTT', 'CTC', 'CTA', 'CTG'],
103
+ ['ATT', 'ATC', 'ATA'],
104
+ ['ATG'],
105
+ ['GTT', 'GTC', 'GTA', 'GTG'],
106
+ ['TCT', 'TCC', 'TCA', 'TCG', 'AGT', 'AGC'],
107
+ ['CCT', 'CCC', 'CCA', 'CCG'],
108
+ ['ACT', 'ACC', 'ACA', 'ACG'],
109
+ ['GCT', 'GCC', 'GCA', 'GCG'],
110
+ ['TAT', 'TAC'],
111
+ ['CAT', 'CAC'],
112
+ ['CAA', 'CAG'],
113
+ ['AAT', 'AAC'],
114
+ ['AAA', 'AAG'],
115
+ ['GAT', 'GAC'],
116
+ ['GAA', 'GAG'],
117
+ ['TGT', 'TGC'],
118
+ ['TGG'],
119
+ ['CGT', 'CGC', 'CGA', 'CGG', 'AGA', 'AGG'],
120
+ ['GGT', 'GGC', 'GGA', 'GGG'],
121
+ ['TAA', 'TAG', 'TGA']] # Stop
122
+
123
+ reverse_dictionary = {}
124
+ for i in range(len(codon_dictionary)):
125
+ for j in codon_dictionary[i]:
126
+ reverse_dictionary[j] = i
127
+
128
+ triplets = []
129
+ for item in codon_dictionary:
130
+ triplets.extend(item)
131
+
132
+ triplet_encoded = []
133
+ if sequence_type == 'protein':
134
+ for i in range(0, len(input_sequence)):
135
+ triplet_encoded.append(reverse_dictionary[translate(input_sequence)[i:i + 3]])
136
+ else:
137
+ for i in range(0, len(input_sequence), 3):
138
+ triplet_encoded.append(reverse_dictionary[input_sequence[i:i + 3]])
139
+
140
+ sequence_set = []
141
+ if subspace_priority == center_priority == 0:
142
+ while len(sequence_set) < set_size:
143
+ sequence_set.append(randomize(triplet_encoded, codon_dictionary))
144
+ else:
145
+ sixplet_dictionary = []
146
+ for first in codon_dictionary:
147
+ for second in codon_dictionary:
148
+ sixplet_dictionary.append([])
149
+ for first_codon in first:
150
+ for second_codon in second:
151
+ sixplet_dictionary[-1].append(first_codon + second_codon)
152
+
153
+ sixplet_reverse_dictionary = {}
154
+ for i in range(len(sixplet_dictionary)):
155
+ for j in sixplet_dictionary[i]:
156
+ sixplet_reverse_dictionary[j] = i
157
+
158
+ sixplets = []
159
+ for i in triplets:
160
+ for j in triplets:
161
+ sixplets.append(i + j)
162
+
163
+ distribution = self.subspace_model.distribution
164
+
165
+ sixplet_frequencies = []
166
+ for item in sixplet_dictionary:
167
+ sixplet_frequencies.append([])
168
+ for sixplet in item:
169
+ sixplet_frequencies[-1].append(distribution[sixplet])
170
+
171
+ codon_context = {}
172
+ for first_triplet in triplets:
173
+ codon_context[first_triplet] = []
174
+ for item in codon_dictionary:
175
+ codon_context[first_triplet].append(
176
+ [distribution[first_triplet + second_triplet] for second_triplet in item])
177
+
178
+ encoded = []
179
+ if sequence_type == 'protein':
180
+ for i in range(0, len(input_sequence) - 1):
181
+ encoded.append(sixplet_reverse_dictionary[translate(input_sequence)[i:i + 6]])
182
+ else:
183
+ for i in range(0, len(input_sequence) - 3, 3):
184
+ encoded.append(sixplet_reverse_dictionary[input_sequence[i:i + 6]])
185
+
186
+ while len(sequence_set) < set_size:
187
+ sequence = nonrandomize(encoded, triplet_encoded, sixplet_dictionary, sixplet_frequencies,
188
+ codon_dictionary, codon_context)
189
+ if restriction_check(sequence, restriction_sites):
190
+ sequence_set.append(sequence)
191
+
192
+ self.sequence_set = sequence_set
193
+ self.expression_priority = expression_priority
194
+ self.subspace_priority = subspace_priority
195
+ self.center_priority = center_priority
196
+ self.gc_priority = gc_priority
197
+ self.max_iterations = max_iterations
198
+ self.n_children = n_children
199
+ self.restriction_sites = restriction_sites
200
+ self.expression_weight = 0
201
+ self.subspace_weight = 0
202
+ self.center_weight = 0
203
+ self.gc_weight = 0
204
+
205
+ def score(self, sequence, target_score, target_distance, target_center, target_gc):
206
+ value = 0
207
+ if self.expression_priority > 0:
208
+ value += abs(self.expression_model.predict(sequence) - target_score) * self.expression_weight
209
+ if self.subspace_priority > 0:
210
+ value += abs(self.subspace_model.distance(sequence) - target_distance) * self.subspace_weight
211
+ if self.center_priority > 0:
212
+ value += abs(self.subspace_model.center_distance(sequence) - target_center) * self.center_weight
213
+ if self.gc_priority > 0:
214
+ value += abs(gc_content(sequence) - target_gc) * self.gc_weight
215
+ return 1 / value
216
+
217
+ def optimize(self, target_score=10, target_distance=0, target_center=0, target_gc=0):
218
+ self.expression_weight = 0.1 * self.expression_priority
219
+
220
+ distance_variation = sorted(self.subspace_model.distances)
221
+ self.subspace_weight = 1 / abs(distance_variation[int(len(distance_variation) * 0.001)] - distance_variation[
222
+ int(len(distance_variation) * 0.999)]) * self.subspace_priority
223
+
224
+ self.center_weight = 1 * self.center_priority
225
+
226
+ self.gc_weight = 1 * self.gc_priority
227
+
228
+ score_set = []
229
+ for sequence in self.sequence_set:
230
+ score_set.append(self.score(sequence, target_score, target_distance, target_center, target_gc))
231
+
232
+ sequence_set = [x for y, x in sorted(zip(score_set, self.sequence_set))]
233
+ score_set.sort()
234
+
235
+ counter = 0
236
+ best_score = 0
237
+ while counter < self.max_iterations:
238
+ counter += 1
239
+ children = []
240
+ while len(children) < self.n_children:
241
+ parent1 = choices(sequence_set, score_set)[0]
242
+ parent2 = choices(sequence_set, score_set)[0]
243
+ while parent2 == parent1:
244
+ parent2 = choices(sequence_set, score_set)[0]
245
+ child1, child2 = crossingover(parent1, parent2)
246
+ if child1 != parent1 and child1 != parent2:
247
+ if restriction_check(child1, self.restriction_sites):
248
+ children.append(child1)
249
+ if restriction_check(child2, self.restriction_sites):
250
+ children.append(child2)
251
+
252
+ children_score = []
253
+ for sequence in children:
254
+ children_score.append(self.score(sequence, target_score, target_distance, target_center, target_gc))
255
+
256
+ sequence_set.extend(children)
257
+ score_set.extend(children_score)
258
+ sequence_set = [x for y, x in sorted(zip(score_set, sequence_set))]
259
+ score_set.sort()
260
+
261
+ for i in range(len(children)):
262
+ sequence_set.pop(0)
263
+ score_set.pop(0)
264
+
265
+ if score_set[-1] > best_score:
266
+ best_score = score_set[-1]
267
+ counter = 0
268
+
269
+ return sequence_set[-1]
Binary file
Binary file
Binary file
@@ -0,0 +1,17 @@
1
+ Metadata-Version: 2.4
2
+ Name: genop
3
+ Version: 0.1.0
4
+ Summary: Codon optimization tool
5
+ Home-page: https://github.com/conzaytsev/GeneOptimizer
6
+ Author: Konstantin Zaytsev
7
+ Classifier: License :: OSI Approved :: MIT License
8
+ Classifier: Programming Language :: Python :: 3
9
+ Requires-Python: >3.9
10
+ Dynamic: author
11
+ Dynamic: classifier
12
+ Dynamic: description
13
+ Dynamic: home-page
14
+ Dynamic: requires-python
15
+ Dynamic: summary
16
+
17
+ Python module for codon optimization in genes to achieve specific expression levels.
@@ -0,0 +1,10 @@
1
+ setup.py
2
+ genop/__init__.py
3
+ genop/gene_optimizer.py
4
+ genop.egg-info/PKG-INFO
5
+ genop.egg-info/SOURCES.txt
6
+ genop.egg-info/dependency_links.txt
7
+ genop.egg-info/top_level.txt
8
+ genop/models/511145_cai.pkl
9
+ genop/models/511145_cei.pkl
10
+ genop/models/511145_sub.pkl
@@ -0,0 +1 @@
1
+ genop
genop-0.1.0/setup.cfg ADDED
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
genop-0.1.0/setup.py ADDED
@@ -0,0 +1,19 @@
1
+ from setuptools import setup
2
+
3
+
4
+ setup(
5
+ name="genop",
6
+ version='0.1.0',
7
+ author="Konstantin Zaytsev",
8
+ url='https://github.com/conzaytsev/GeneOptimizer',
9
+ description='Codon optimization tool',
10
+ long_description='Python module for codon optimization in genes to achieve specific expression levels.',
11
+ packages=['genop'],
12
+ install_requires=[],
13
+ python_requires='>3.9',
14
+ package_data={'genop': ['models/*.pkl']},
15
+ classifiers= [
16
+ 'License :: OSI Approved :: MIT License',
17
+ 'Programming Language :: Python :: 3'
18
+ ]
19
+ )