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.
@@ -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)) or (m[1] == 0 and m[0] + m[2] == len(stringx))
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({True: "-", False: "o"}[not self.circular], len(self))
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("Contig({}{})".format({True: "-", False: "o"}[not self.circular], len(self)))
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([(nm[v], nm[u], d) for u, v, d in list(self.graph.edges(data=True))[::-1]])
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"] = ed["name"][:-3] if ed["name"].endswith("_rc") else "{}_rc".format(ed["name"])[:13]
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(ln - stop - g.nodes[u]["length"], ln - start - g.nodes[v]["length"])
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(o1=nodes[i + 1][1]["length"], name=f[2]["name"])
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 += ("{space} {name}{o2:>2}\n" "{space} {space2}\\/\n" "{space} {space2}/\\\n").format(
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(name=f[2]["name"], o1=nodes[-2][1]["length"], space=" " * (space))
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(o1=nodes[i + 1][1]["length"], name=f[2]["name"])
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 += ("|{space}{name}{o2:>2}\n" "|{space}{space2}\\/\n" "|{space}{space2}/\\\n").format(
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(space=" " * (space), o1=nodes[0][1]["length"])
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(f"(?P<ps>.{{{cas.size}}})(?:{cas.scaffold})", str(guide_construct.seq).upper())
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(f"(?:{rc(cas.scaffold)})(?P<ps>.{{{cas.size}}})", str(guide_construct.seq).upper())
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
- import os as _os
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
- import logging as _logging
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, template: _Dseqrecord, limit: int, tm_func, starting_length: int = 0
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, fp=None, rp=None, limit=13, target_tm=55.0, tm_func=_tm_default, estimate_function=None, **kwargs
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("designed primers do not yield a unique PCR product", _PydnaWarning)
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(f + f[0:1], overlap=overlap, maxlink=maxlink, circular=False)
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((fragments[-1].forward_primer, fragments[0].reverse_primer), fragments[0].template)
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(hasattr(i[0], "template") or hasattr(i[1], "template") for i in zip(nf, nf[1:])):
638
- raise ValueError("Every second fragment larger than maxlink has to be an Amplicon object")
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
- _module_logger.debug("first fragment stays since len(f[0]) = %s", first_fragment_length)
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 = f[-1].seq.reverse_complement()._data.decode("ASCII") + 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
- _module_logger.debug("last fragment removed since len(f[%s]) = %s", len(f), last_fragment_length)
661
- else:
662
- _module_logger.debug("last fragment stays since len(f[%s]) = %s", len(f), last_fragment_length)
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
- "secnd is is flanked by amplicons, so half of secnd should be added each flanking primers"
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")[secnd_len // 2 :] + first.reverse_primer
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")[: secnd_len // 2]
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 = (first.seq._data.decode("ASCII") + secnd.seq._data.decode("ASCII")[: secnd_len // 2])[
703
- -tail_length:
704
- ]
705
- _module_logger.debug("2 %s", lnk)
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 = secnd.seq.reverse_complement()._data.decode("ASCII") + 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 = secnd.seq._data.decode("ASCII") + 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
- _module_logger = _logging.getLogger("pydna." + __name__)
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
- @_memorize("pydna.download.download_text")
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