pydna 5.5.1__py3-none-any.whl → 5.5.2__py3-none-any.whl
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.
- pydna/__init__.py +116 -134
- pydna/_pretty.py +2 -14
- pydna/all.py +10 -20
- pydna/amplicon.py +25 -20
- pydna/amplify.py +46 -26
- pydna/assembly.py +50 -27
- pydna/assembly2.py +1902 -0
- pydna/common_sub_strings.py +2 -12
- pydna/contig.py +39 -22
- pydna/crispr.py +8 -13
- pydna/design.py +89 -59
- pydna/download.py +10 -18
- pydna/dseq.py +119 -59
- pydna/dseqrecord.py +88 -45
- pydna/fakeseq.py +0 -11
- pydna/fusionpcr.py +3 -1
- pydna/gateway.py +2 -2
- pydna/gel.py +8 -13
- pydna/genbank.py +33 -32
- pydna/genbankfile.py +8 -13
- pydna/genbankfixer.py +41 -28
- pydna/genbankrecord.py +11 -14
- pydna/goldengate.py +2 -2
- pydna/ladders.py +4 -11
- pydna/ligate.py +8 -14
- pydna/parsers.py +5 -12
- pydna/primer.py +3 -12
- pydna/readers.py +0 -11
- pydna/seq.py +21 -18
- pydna/seqrecord.py +19 -19
- pydna/sequence_picker.py +3 -12
- pydna/tm.py +13 -15
- pydna/types.py +41 -0
- pydna/utils.py +173 -58
- {pydna-5.5.1.dist-info → pydna-5.5.2.dist-info}/METADATA +17 -3
- pydna-5.5.2.dist-info/RECORD +43 -0
- pydna/editor.py +0 -119
- pydna/myenzymes.py +0 -51
- pydna/myprimers.py +0 -219
- pydna-5.5.1.dist-info/RECORD +0 -44
- {pydna-5.5.1.dist-info → pydna-5.5.2.dist-info}/LICENSE.txt +0 -0
- {pydna-5.5.1.dist-info → pydna-5.5.2.dist-info}/WHEEL +0 -0
pydna/common_sub_strings.py
CHANGED
|
@@ -389,16 +389,6 @@ def terminal_overlap(stringx: str, stringy: str, limit: int = 15) -> _List[Match
|
|
|
389
389
|
return [
|
|
390
390
|
m
|
|
391
391
|
for m in common_sub_strings(stringx, stringy, limit)
|
|
392
|
-
if (m[0] == 0 and m[1] + m[2] == len(stringy))
|
|
392
|
+
if (m[0] == 0 and m[1] + m[2] == len(stringy))
|
|
393
|
+
or (m[1] == 0 and m[0] + m[2] == len(stringx))
|
|
393
394
|
]
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
if __name__ == "__main__":
|
|
397
|
-
import os as _os
|
|
398
|
-
|
|
399
|
-
cached = _os.getenv("pydna_cached_funcs", "")
|
|
400
|
-
_os.environ["pydna_cached_funcs"] = ""
|
|
401
|
-
import doctest
|
|
402
|
-
|
|
403
|
-
doctest.testmod(verbose=True, optionflags=doctest.ELLIPSIS)
|
|
404
|
-
_os.environ["pydna_cached_funcs"] = cached
|
pydna/contig.py
CHANGED
|
@@ -32,11 +32,15 @@ class Contig(_Dseqrecord):
|
|
|
32
32
|
return obj
|
|
33
33
|
|
|
34
34
|
def __repr__(self):
|
|
35
|
-
return "Contig({}{})".format(
|
|
35
|
+
return "Contig({}{})".format(
|
|
36
|
+
{True: "-", False: "o"}[not self.circular], len(self)
|
|
37
|
+
)
|
|
36
38
|
|
|
37
39
|
def _repr_pretty_(self, p, cycle):
|
|
38
40
|
"""returns a short string representation of the object"""
|
|
39
|
-
p.text(
|
|
41
|
+
p.text(
|
|
42
|
+
"Contig({}{})".format({True: "-", False: "o"}[not self.circular], len(self))
|
|
43
|
+
)
|
|
40
44
|
|
|
41
45
|
def _repr_html_(self):
|
|
42
46
|
return "<pre>" + self.figure() + "</pre>"
|
|
@@ -45,14 +49,22 @@ class Contig(_Dseqrecord):
|
|
|
45
49
|
answer = type(self)(super().reverse_complement())
|
|
46
50
|
g = _nx.DiGraph()
|
|
47
51
|
nm = self.nodemap
|
|
48
|
-
g.add_edges_from(
|
|
52
|
+
g.add_edges_from(
|
|
53
|
+
[(nm[v], nm[u], d) for u, v, d in list(self.graph.edges(data=True))[::-1]]
|
|
54
|
+
)
|
|
49
55
|
g.add_nodes_from((nm[n], d) for n, d in list(self.graph.nodes(data=True))[::-1])
|
|
50
56
|
for u, v, ed in g.edges(data=True):
|
|
51
|
-
ed["name"] =
|
|
57
|
+
ed["name"] = (
|
|
58
|
+
ed["name"][:-3]
|
|
59
|
+
if ed["name"].endswith("_rc")
|
|
60
|
+
else "{}_rc".format(ed["name"])[:13]
|
|
61
|
+
)
|
|
52
62
|
ed["seq"] = _rc(ed["seq"])
|
|
53
63
|
ln = len(ed["seq"])
|
|
54
64
|
start, stop = ed["piece"].start, ed["piece"].stop
|
|
55
|
-
ed["piece"] = slice(
|
|
65
|
+
ed["piece"] = slice(
|
|
66
|
+
ln - stop - g.nodes[u]["length"], ln - start - g.nodes[v]["length"]
|
|
67
|
+
)
|
|
56
68
|
ed["features"] = [f._flip(ln) for f in ed["features"]]
|
|
57
69
|
answer.graph = g
|
|
58
70
|
answer.nodemap = {v: k for k, v in self.nodemap.items()}
|
|
@@ -180,10 +192,16 @@ class Contig(_Dseqrecord):
|
|
|
180
192
|
space = space2 # len(f.name)
|
|
181
193
|
|
|
182
194
|
for i, f in enumerate(edges[1:-1]):
|
|
183
|
-
name = "{o1:>2}|{name}|".format(
|
|
195
|
+
name = "{o1:>2}|{name}|".format(
|
|
196
|
+
o1=nodes[i + 1][1]["length"], name=f[2]["name"]
|
|
197
|
+
)
|
|
184
198
|
space2 = len(name)
|
|
185
199
|
|
|
186
|
-
fig += (
|
|
200
|
+
fig += (
|
|
201
|
+
"{space} {name}{o2:>2}\n"
|
|
202
|
+
"{space} {space2}\\/\n"
|
|
203
|
+
"{space} {space2}/\\\n"
|
|
204
|
+
).format(
|
|
187
205
|
name=name,
|
|
188
206
|
o2=nodes[i + 2][1]["length"],
|
|
189
207
|
space=" " * space,
|
|
@@ -193,7 +211,9 @@ class Contig(_Dseqrecord):
|
|
|
193
211
|
space += space2
|
|
194
212
|
|
|
195
213
|
f = edges[-1]
|
|
196
|
-
fig += ("{space} {o1:>2}|{name}").format(
|
|
214
|
+
fig += ("{space} {o1:>2}|{name}").format(
|
|
215
|
+
name=f[2]["name"], o1=nodes[-2][1]["length"], space=" " * (space)
|
|
216
|
+
)
|
|
197
217
|
|
|
198
218
|
else: # circular
|
|
199
219
|
r"""
|
|
@@ -221,9 +241,15 @@ class Contig(_Dseqrecord):
|
|
|
221
241
|
)
|
|
222
242
|
|
|
223
243
|
for i, f in enumerate(edges[1:]):
|
|
224
|
-
name = "{o1:>2}|{name}|".format(
|
|
244
|
+
name = "{o1:>2}|{name}|".format(
|
|
245
|
+
o1=nodes[i + 1][1]["length"], name=f[2]["name"]
|
|
246
|
+
)
|
|
225
247
|
space2 = len(name)
|
|
226
|
-
fig += (
|
|
248
|
+
fig += (
|
|
249
|
+
"|{space}{name}{o2:>2}\n"
|
|
250
|
+
"|{space}{space2}\\/\n"
|
|
251
|
+
"|{space}{space2}/\\\n"
|
|
252
|
+
).format(
|
|
227
253
|
o2=nodes[i + 2][1]["length"],
|
|
228
254
|
name=name,
|
|
229
255
|
space=" " * space,
|
|
@@ -231,18 +257,9 @@ class Contig(_Dseqrecord):
|
|
|
231
257
|
)
|
|
232
258
|
space += space2
|
|
233
259
|
|
|
234
|
-
fig += "|{space}{o1:>2}-\n".format(
|
|
260
|
+
fig += "|{space}{o1:>2}-\n".format(
|
|
261
|
+
space=" " * (space), o1=nodes[0][1]["length"]
|
|
262
|
+
)
|
|
235
263
|
fig += "|{space} |\n".format(space=" " * (space))
|
|
236
264
|
fig += " {space}".format(space="-" * (space + 3))
|
|
237
265
|
return _pretty_str(_textwrap.dedent(fig))
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
if __name__ == "__main__":
|
|
241
|
-
import os as _os
|
|
242
|
-
|
|
243
|
-
cached = _os.getenv("pydna_cached_funcs", "")
|
|
244
|
-
_os.environ["pydna_cached_funcs"] = ""
|
|
245
|
-
import doctest
|
|
246
|
-
|
|
247
|
-
doctest.testmod(verbose=True, optionflags=doctest.ELLIPSIS)
|
|
248
|
-
_os.environ["pydna_cached_funcs"] = cached
|
pydna/crispr.py
CHANGED
|
@@ -111,21 +111,16 @@ def protospacer(guide_construct, cas=cas9):
|
|
|
111
111
|
"""docstring."""
|
|
112
112
|
in_watson = [
|
|
113
113
|
mobj.group("ps")
|
|
114
|
-
for mobj in re.finditer(
|
|
114
|
+
for mobj in re.finditer(
|
|
115
|
+
f"(?P<ps>.{{{cas.size}}})(?:{cas.scaffold})",
|
|
116
|
+
str(guide_construct.seq).upper(),
|
|
117
|
+
)
|
|
115
118
|
]
|
|
116
119
|
in_crick = [
|
|
117
120
|
rc(mobj.group("ps"))
|
|
118
|
-
for mobj in re.finditer(
|
|
121
|
+
for mobj in re.finditer(
|
|
122
|
+
f"(?:{rc(cas.scaffold)})(?P<ps>.{{{cas.size}}})",
|
|
123
|
+
str(guide_construct.seq).upper(),
|
|
124
|
+
)
|
|
119
125
|
]
|
|
120
126
|
return in_watson + in_crick
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
if __name__ == "__main__":
|
|
124
|
-
import os as _os
|
|
125
|
-
|
|
126
|
-
cached = _os.getenv("pydna_cached_funcs", "")
|
|
127
|
-
_os.environ["pydna_cached_funcs"] = ""
|
|
128
|
-
import doctest
|
|
129
|
-
|
|
130
|
-
doctest.testmod(verbose=True, optionflags=doctest.ELLIPSIS)
|
|
131
|
-
_os.environ["pydna_cached_funcs"] = cached
|
pydna/design.py
CHANGED
|
@@ -16,22 +16,28 @@
|
|
|
16
16
|
|
|
17
17
|
from pydna.tm import tm_default as _tm_default
|
|
18
18
|
import math as _math
|
|
19
|
-
|
|
19
|
+
|
|
20
|
+
# import os as _os
|
|
20
21
|
import copy as _copy
|
|
21
22
|
from pydna.amplicon import Amplicon as _Amplicon
|
|
22
23
|
from pydna.amplify import Anneal as _Anneal
|
|
23
24
|
from pydna.amplify import pcr as _pcr
|
|
24
25
|
from pydna.dseqrecord import Dseqrecord as _Dseqrecord
|
|
25
26
|
from pydna.primer import Primer as _Primer
|
|
26
|
-
|
|
27
|
+
|
|
28
|
+
# import logging as _logging
|
|
27
29
|
import operator as _operator
|
|
28
30
|
from typing import Tuple
|
|
29
31
|
|
|
30
|
-
_module_logger = _logging.getLogger("pydna." + __name__)
|
|
32
|
+
# _module_logger = _logging.getLogger("pydna." + __name__)
|
|
31
33
|
|
|
32
34
|
|
|
33
35
|
def _design_primer(
|
|
34
|
-
target_tm: float,
|
|
36
|
+
target_tm: float,
|
|
37
|
+
template: _Dseqrecord,
|
|
38
|
+
limit: int,
|
|
39
|
+
tm_func,
|
|
40
|
+
starting_length: int = 0,
|
|
35
41
|
) -> Tuple[float, str]:
|
|
36
42
|
"""returns a tuple (temp, primer)"""
|
|
37
43
|
|
|
@@ -63,7 +69,7 @@ def _design_primer(
|
|
|
63
69
|
if length < limit:
|
|
64
70
|
return template.seq[:limit]
|
|
65
71
|
|
|
66
|
-
_module_logger.debug(((p, tmp), (prev_primer, prev_temp)))
|
|
72
|
+
# _module_logger.debug(((p, tmp), (prev_primer, prev_temp)))
|
|
67
73
|
if abs(target_tm - tmp) < abs(target_tm - prev_temp):
|
|
68
74
|
return p
|
|
69
75
|
else:
|
|
@@ -71,7 +77,14 @@ def _design_primer(
|
|
|
71
77
|
|
|
72
78
|
|
|
73
79
|
def primer_design(
|
|
74
|
-
template,
|
|
80
|
+
template,
|
|
81
|
+
fp=None,
|
|
82
|
+
rp=None,
|
|
83
|
+
limit=13,
|
|
84
|
+
target_tm=55.0,
|
|
85
|
+
tm_func=_tm_default,
|
|
86
|
+
estimate_function=None,
|
|
87
|
+
**kwargs,
|
|
75
88
|
):
|
|
76
89
|
"""This function designs a forward primer and a reverse primer for PCR amplification
|
|
77
90
|
of a given template sequence.
|
|
@@ -178,10 +191,10 @@ def primer_design(
|
|
|
178
191
|
return _design_primer(target_tm, template, limit, tm_func)
|
|
179
192
|
|
|
180
193
|
if not fp and not rp:
|
|
181
|
-
_module_logger.debug("no primer given, design forward primer:")
|
|
194
|
+
# _module_logger.debug("no primer given, design forward primer:")
|
|
182
195
|
fp = _Primer((design(target_tm, template)))
|
|
183
196
|
target_tm = tm_func(str(fp.seq))
|
|
184
|
-
_module_logger.debug("no primer given, design reverse primer:")
|
|
197
|
+
# _module_logger.debug("no primer given, design reverse primer:")
|
|
185
198
|
rp = _Primer(design(target_tm, template.reverse_complement()))
|
|
186
199
|
elif fp and not rp:
|
|
187
200
|
try:
|
|
@@ -192,7 +205,7 @@ def primer_design(
|
|
|
192
205
|
print("Unexpected error")
|
|
193
206
|
raise
|
|
194
207
|
target_tm = tm_func(fp.footprint)
|
|
195
|
-
_module_logger.debug("forward primer given, design reverse primer:")
|
|
208
|
+
# _module_logger.debug("forward primer given, design reverse primer:")
|
|
196
209
|
rp = _Primer(design(target_tm, template.reverse_complement()))
|
|
197
210
|
elif not fp and rp:
|
|
198
211
|
try:
|
|
@@ -203,7 +216,7 @@ def primer_design(
|
|
|
203
216
|
print("Unexpected error")
|
|
204
217
|
raise
|
|
205
218
|
target_tm = tm_func(rp.footprint)
|
|
206
|
-
_module_logger.debug("reverse primer given, design forward primer:")
|
|
219
|
+
# _module_logger.debug("reverse primer given, design forward primer:")
|
|
207
220
|
fp = _Primer(design(target_tm, template))
|
|
208
221
|
else:
|
|
209
222
|
raise ValueError("Specify maximum one of the two primers.")
|
|
@@ -231,7 +244,9 @@ def primer_design(
|
|
|
231
244
|
import warnings as _warnings
|
|
232
245
|
from pydna import _PydnaWarning
|
|
233
246
|
|
|
234
|
-
_warnings.warn(
|
|
247
|
+
_warnings.warn(
|
|
248
|
+
"designed primers do not yield a unique PCR product", _PydnaWarning
|
|
249
|
+
)
|
|
235
250
|
|
|
236
251
|
return prod
|
|
237
252
|
|
|
@@ -626,20 +641,29 @@ def assembly_fragments(f, overlap=35, maxlink=40, circular=False):
|
|
|
626
641
|
|
|
627
642
|
# Recursive call for circular assemblies
|
|
628
643
|
if circular:
|
|
629
|
-
fragments = assembly_fragments(
|
|
644
|
+
fragments = assembly_fragments(
|
|
645
|
+
f + f[0:1], overlap=overlap, maxlink=maxlink, circular=False
|
|
646
|
+
)
|
|
630
647
|
|
|
631
648
|
if hasattr(fragments[0], "template"):
|
|
632
|
-
fragments[0] = _pcr(
|
|
649
|
+
fragments[0] = _pcr(
|
|
650
|
+
(fragments[-1].forward_primer, fragments[0].reverse_primer),
|
|
651
|
+
fragments[0].template,
|
|
652
|
+
)
|
|
633
653
|
return fragments[:-1]
|
|
634
654
|
|
|
635
655
|
# sanity check for arguments
|
|
636
656
|
nf = [item for item in f if len(item) > maxlink]
|
|
637
|
-
if not all(
|
|
638
|
-
|
|
657
|
+
if not all(
|
|
658
|
+
hasattr(i[0], "template") or hasattr(i[1], "template") for i in zip(nf, nf[1:])
|
|
659
|
+
):
|
|
660
|
+
raise ValueError(
|
|
661
|
+
"Every second fragment larger than maxlink has to be an Amplicon object"
|
|
662
|
+
)
|
|
639
663
|
|
|
640
|
-
_module_logger.debug("### assembly fragments ###")
|
|
641
|
-
_module_logger.debug("overlap = %s", overlap)
|
|
642
|
-
_module_logger.debug("max_link = %s", maxlink)
|
|
664
|
+
# _module_logger.debug("### assembly fragments ###")
|
|
665
|
+
# _module_logger.debug("overlap = %s", overlap)
|
|
666
|
+
# _module_logger.debug("max_link = %s", maxlink)
|
|
643
667
|
|
|
644
668
|
f = [_copy.copy(f) for f in f]
|
|
645
669
|
|
|
@@ -649,23 +673,24 @@ def assembly_fragments(f, overlap=35, maxlink=40, circular=False):
|
|
|
649
673
|
if first_fragment_length <= maxlink:
|
|
650
674
|
# first fragment should be removed and added to second fragment (new first fragment) forward primer
|
|
651
675
|
f[1].forward_primer = f[0].seq._data.decode("ASCII") + f[1].forward_primer
|
|
652
|
-
_module_logger.debug("first fragment removed since len(f[0]) = %s", first_fragment_length)
|
|
676
|
+
# _module_logger.debug("first fragment removed since len(f[0]) = %s", first_fragment_length)
|
|
653
677
|
f = f[1:]
|
|
654
|
-
else:
|
|
655
|
-
|
|
678
|
+
# else:
|
|
679
|
+
# _module_logger.debug("first fragment stays since len(f[0]) = %s", first_fragment_length)
|
|
656
680
|
|
|
657
681
|
if last_fragment_length <= maxlink:
|
|
658
|
-
f[-2].reverse_primer =
|
|
682
|
+
f[-2].reverse_primer = (
|
|
683
|
+
f[-1].seq.reverse_complement()._data.decode("ASCII") + f[-2].reverse_primer
|
|
684
|
+
)
|
|
659
685
|
f = f[:-1]
|
|
660
|
-
|
|
661
|
-
else:
|
|
662
|
-
|
|
686
|
+
# _module_logger.debug("last fragment removed since len(f[%s]) = %s", len(f), last_fragment_length)
|
|
687
|
+
# else:
|
|
688
|
+
# _module_logger.debug("last fragment stays since len(f[%s]) = %s", len(f), last_fragment_length)
|
|
663
689
|
|
|
664
690
|
empty = _Dseqrecord("")
|
|
665
691
|
|
|
666
|
-
_module_logger.debug(f)
|
|
667
|
-
|
|
668
|
-
_module_logger.debug("loop through fragments in groups of three:")
|
|
692
|
+
# _module_logger.debug(f)
|
|
693
|
+
# _module_logger.debug("loop through fragments in groups of three:")
|
|
669
694
|
|
|
670
695
|
tail_length = _math.ceil(overlap / 2)
|
|
671
696
|
|
|
@@ -675,42 +700,56 @@ def assembly_fragments(f, overlap=35, maxlink=40, circular=False):
|
|
|
675
700
|
|
|
676
701
|
secnd_len = len(secnd)
|
|
677
702
|
|
|
678
|
-
_module_logger.debug("first = %s", str(first.seq))
|
|
679
|
-
_module_logger.debug("secnd = %s", str(secnd.seq))
|
|
703
|
+
# _module_logger.debug("first = %s", str(first.seq))
|
|
704
|
+
# _module_logger.debug("secnd = %s", str(secnd.seq))
|
|
680
705
|
|
|
681
706
|
if secnd_len <= maxlink:
|
|
682
|
-
_module_logger.debug("secnd is smaller or equal to maxlink; should be added to primer(s)")
|
|
707
|
+
# _module_logger.debug("secnd is smaller or equal to maxlink; should be added to primer(s)")
|
|
683
708
|
third = f[i + 2]
|
|
684
|
-
_module_logger.debug("third = %s", str(third.seq))
|
|
709
|
+
# _module_logger.debug("third = %s", str(third.seq))
|
|
685
710
|
if hasattr(f[i], "template") and hasattr(third, "template"):
|
|
686
|
-
_module_logger.debug(
|
|
687
|
-
|
|
688
|
-
)
|
|
711
|
+
# _module_logger.debug(
|
|
712
|
+
# "secnd is is flanked by amplicons, so half of secnd should be added each flanking primers"
|
|
713
|
+
# )
|
|
689
714
|
|
|
690
715
|
first.reverse_primer = (
|
|
691
|
-
secnd.seq.reverse_complement()._data.decode("ASCII")[
|
|
716
|
+
secnd.seq.reverse_complement()._data.decode("ASCII")[
|
|
717
|
+
secnd_len // 2 :
|
|
718
|
+
]
|
|
719
|
+
+ first.reverse_primer
|
|
720
|
+
)
|
|
721
|
+
third.forward_primer = (
|
|
722
|
+
secnd.seq._data.decode("ASCII")[secnd_len // 2 :]
|
|
723
|
+
+ third.forward_primer
|
|
692
724
|
)
|
|
693
|
-
third.forward_primer = secnd.seq._data.decode("ASCII")[secnd_len // 2 :] + third.forward_primer
|
|
694
725
|
|
|
695
726
|
lnk = (
|
|
696
727
|
third.seq.reverse_complement()._data.decode("ASCII")
|
|
697
|
-
+ secnd.reverse_complement().seq._data.decode("ASCII")[
|
|
728
|
+
+ secnd.reverse_complement().seq._data.decode("ASCII")[
|
|
729
|
+
: secnd_len // 2
|
|
730
|
+
]
|
|
698
731
|
)[-tail_length:]
|
|
699
|
-
_module_logger.debug("1 %s", lnk)
|
|
732
|
+
# _module_logger.debug("1 %s", lnk)
|
|
700
733
|
first.reverse_primer = lnk + first.reverse_primer
|
|
701
734
|
|
|
702
|
-
lnk = (
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
735
|
+
lnk = (
|
|
736
|
+
first.seq._data.decode("ASCII")
|
|
737
|
+
+ secnd.seq._data.decode("ASCII")[: secnd_len // 2]
|
|
738
|
+
)[-tail_length:]
|
|
739
|
+
# _module_logger.debug("2 %s", lnk)
|
|
706
740
|
third.forward_primer = lnk + third.forward_primer
|
|
707
741
|
|
|
708
742
|
elif hasattr(first, "template"):
|
|
709
|
-
first.reverse_primer =
|
|
743
|
+
first.reverse_primer = (
|
|
744
|
+
secnd.seq.reverse_complement()._data.decode("ASCII")
|
|
745
|
+
+ first.reverse_primer
|
|
746
|
+
)
|
|
710
747
|
lnk = str(third.seq[:overlap].reverse_complement())
|
|
711
748
|
first.reverse_primer = lnk + first.reverse_primer
|
|
712
749
|
elif hasattr(third, "template"):
|
|
713
|
-
third.forward_primer =
|
|
750
|
+
third.forward_primer = (
|
|
751
|
+
secnd.seq._data.decode("ASCII") + third.forward_primer
|
|
752
|
+
)
|
|
714
753
|
lnk = str(first.seq[-overlap:])
|
|
715
754
|
third.forward_primer = lnk + third.forward_primer
|
|
716
755
|
secnd = empty
|
|
@@ -718,23 +757,23 @@ def assembly_fragments(f, overlap=35, maxlink=40, circular=False):
|
|
|
718
757
|
else: # secnd is larger than maxlink
|
|
719
758
|
if hasattr(first, "template") and hasattr(secnd, "template"):
|
|
720
759
|
lnk = str(first.seq[-tail_length:])
|
|
721
|
-
# _module_logger.debug("4 %s", lnk)
|
|
760
|
+
# #_module_logger.debug("4 %s", lnk)
|
|
722
761
|
secnd.forward_primer = lnk + secnd.forward_primer
|
|
723
762
|
lnk = str(secnd.seq[:tail_length].reverse_complement())
|
|
724
|
-
# _module_logger.debug("5 %s", lnk)
|
|
763
|
+
# #_module_logger.debug("5 %s", lnk)
|
|
725
764
|
first.reverse_primer = lnk + first.reverse_primer
|
|
726
765
|
elif hasattr(first, "template"):
|
|
727
766
|
lnk = str(secnd.seq[:overlap].reverse_complement())
|
|
728
|
-
# _module_logger.debug("6 %s", lnk)
|
|
767
|
+
# #_module_logger.debug("6 %s", lnk)
|
|
729
768
|
first.reverse_primer = lnk + first.reverse_primer
|
|
730
769
|
elif hasattr(secnd, "template"):
|
|
731
770
|
lnk = str(first.seq[-overlap:])
|
|
732
|
-
# _module_logger.debug("7 %s", lnk)
|
|
771
|
+
# #_module_logger.debug("7 %s", lnk)
|
|
733
772
|
secnd.forward_primer = lnk + secnd.forward_primer
|
|
734
773
|
f[i] = first
|
|
735
774
|
f[i + 1] = secnd
|
|
736
775
|
|
|
737
|
-
_module_logger.debug("loop ended")
|
|
776
|
+
# _module_logger.debug("loop ended")
|
|
738
777
|
|
|
739
778
|
f = [item for item in f if len(item)]
|
|
740
779
|
|
|
@@ -767,12 +806,3 @@ def circular_assembly_fragments(f, overlap=35, maxlink=40):
|
|
|
767
806
|
stacklevel=2,
|
|
768
807
|
)
|
|
769
808
|
return assembly_fragments(f, overlap=overlap, maxlink=maxlink, circular=True)
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
if __name__ == "__main__":
|
|
773
|
-
cached = _os.getenv("pydna_cached_funcs", "")
|
|
774
|
-
_os.environ["pydna_cached_funcs"] = ""
|
|
775
|
-
import doctest
|
|
776
|
-
|
|
777
|
-
doctest.testmod(verbose=True, optionflags=doctest.ELLIPSIS)
|
|
778
|
-
_os.environ["pydna_cached_funcs"] = cached
|
pydna/download.py
CHANGED
|
@@ -8,33 +8,25 @@
|
|
|
8
8
|
|
|
9
9
|
import textwrap as _textwrap
|
|
10
10
|
|
|
11
|
-
import os as _os
|
|
11
|
+
# import os as _os
|
|
12
12
|
from pydna._pretty import pretty_str as _pretty_str
|
|
13
|
-
from pydna.utils import memorize as _memorize
|
|
14
|
-
import logging as _logging
|
|
15
13
|
|
|
16
|
-
|
|
14
|
+
# from pydna.utils import memorize as _memorize
|
|
15
|
+
# import logging as _logging
|
|
17
16
|
|
|
17
|
+
# _module_logger = _logging.getLogger("pydna." + __name__)
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
|
|
20
|
+
# @_memorize("pydna.download.download_text")
|
|
20
21
|
def download_text(url):
|
|
21
22
|
"""docstring."""
|
|
22
23
|
import requests
|
|
23
24
|
|
|
24
|
-
_module_logger.info("#### DOWNLOAD TEXT ####")
|
|
25
|
-
_module_logger.info("url = %s", url)
|
|
25
|
+
# _module_logger.info("#### DOWNLOAD TEXT ####")
|
|
26
|
+
# _module_logger.info("url = %s", url)
|
|
26
27
|
req = requests.get(url)
|
|
27
|
-
_module_logger.info("url = %s", str(req))
|
|
28
|
+
# _module_logger.info("url = %s", str(req))
|
|
28
29
|
result = _textwrap.dedent(req.text).strip()
|
|
29
30
|
result = result.replace("\r\n", "\n").replace("\r", "\n")
|
|
30
|
-
_module_logger.info("result[:160] = %s", result[:160])
|
|
31
|
+
# _module_logger.info("result[:160] = %s", result[:160])
|
|
31
32
|
return _pretty_str(result)
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
if __name__ == "__main__":
|
|
35
|
-
cached = _os.getenv("pydna_cached_funcs", "")
|
|
36
|
-
_os.environ["pydna_cached_funcs"] = ""
|
|
37
|
-
import doctest
|
|
38
|
-
|
|
39
|
-
doctest.testmod(verbose=True, optionflags=doctest.ELLIPSIS)
|
|
40
|
-
_os.environ["pydna_cached_funcs"] = cached
|