biotite 0.41.1__cp311-cp311-macosx_10_16_x86_64.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.

Potentially problematic release.


This version of biotite might be problematic. Click here for more details.

Files changed (340) hide show
  1. biotite/__init__.py +19 -0
  2. biotite/application/__init__.py +43 -0
  3. biotite/application/application.py +265 -0
  4. biotite/application/autodock/__init__.py +12 -0
  5. biotite/application/autodock/app.py +505 -0
  6. biotite/application/blast/__init__.py +14 -0
  7. biotite/application/blast/alignment.py +83 -0
  8. biotite/application/blast/webapp.py +421 -0
  9. biotite/application/clustalo/__init__.py +12 -0
  10. biotite/application/clustalo/app.py +238 -0
  11. biotite/application/dssp/__init__.py +12 -0
  12. biotite/application/dssp/app.py +152 -0
  13. biotite/application/localapp.py +306 -0
  14. biotite/application/mafft/__init__.py +12 -0
  15. biotite/application/mafft/app.py +122 -0
  16. biotite/application/msaapp.py +374 -0
  17. biotite/application/muscle/__init__.py +13 -0
  18. biotite/application/muscle/app3.py +254 -0
  19. biotite/application/muscle/app5.py +171 -0
  20. biotite/application/sra/__init__.py +18 -0
  21. biotite/application/sra/app.py +456 -0
  22. biotite/application/tantan/__init__.py +12 -0
  23. biotite/application/tantan/app.py +222 -0
  24. biotite/application/util.py +59 -0
  25. biotite/application/viennarna/__init__.py +18 -0
  26. biotite/application/viennarna/rnaalifold.py +304 -0
  27. biotite/application/viennarna/rnafold.py +269 -0
  28. biotite/application/viennarna/rnaplot.py +187 -0
  29. biotite/application/viennarna/util.py +72 -0
  30. biotite/application/webapp.py +77 -0
  31. biotite/copyable.py +71 -0
  32. biotite/database/__init__.py +23 -0
  33. biotite/database/entrez/__init__.py +15 -0
  34. biotite/database/entrez/check.py +61 -0
  35. biotite/database/entrez/dbnames.py +89 -0
  36. biotite/database/entrez/download.py +223 -0
  37. biotite/database/entrez/key.py +44 -0
  38. biotite/database/entrez/query.py +223 -0
  39. biotite/database/error.py +15 -0
  40. biotite/database/pubchem/__init__.py +21 -0
  41. biotite/database/pubchem/download.py +260 -0
  42. biotite/database/pubchem/error.py +20 -0
  43. biotite/database/pubchem/query.py +827 -0
  44. biotite/database/pubchem/throttle.py +99 -0
  45. biotite/database/rcsb/__init__.py +13 -0
  46. biotite/database/rcsb/download.py +167 -0
  47. biotite/database/rcsb/query.py +959 -0
  48. biotite/database/uniprot/__init__.py +13 -0
  49. biotite/database/uniprot/check.py +32 -0
  50. biotite/database/uniprot/download.py +134 -0
  51. biotite/database/uniprot/query.py +209 -0
  52. biotite/file.py +251 -0
  53. biotite/sequence/__init__.py +73 -0
  54. biotite/sequence/align/__init__.py +49 -0
  55. biotite/sequence/align/alignment.py +658 -0
  56. biotite/sequence/align/banded.cpython-311-darwin.so +0 -0
  57. biotite/sequence/align/banded.pyx +652 -0
  58. biotite/sequence/align/buckets.py +69 -0
  59. biotite/sequence/align/cigar.py +434 -0
  60. biotite/sequence/align/kmeralphabet.cpython-311-darwin.so +0 -0
  61. biotite/sequence/align/kmeralphabet.pyx +574 -0
  62. biotite/sequence/align/kmersimilarity.cpython-311-darwin.so +0 -0
  63. biotite/sequence/align/kmersimilarity.pyx +233 -0
  64. biotite/sequence/align/kmertable.cpython-311-darwin.so +0 -0
  65. biotite/sequence/align/kmertable.pyx +3400 -0
  66. biotite/sequence/align/localgapped.cpython-311-darwin.so +0 -0
  67. biotite/sequence/align/localgapped.pyx +892 -0
  68. biotite/sequence/align/localungapped.cpython-311-darwin.so +0 -0
  69. biotite/sequence/align/localungapped.pyx +279 -0
  70. biotite/sequence/align/matrix.py +405 -0
  71. biotite/sequence/align/matrix_data/BLOSUM100.mat +31 -0
  72. biotite/sequence/align/matrix_data/BLOSUM30.mat +31 -0
  73. biotite/sequence/align/matrix_data/BLOSUM35.mat +31 -0
  74. biotite/sequence/align/matrix_data/BLOSUM40.mat +31 -0
  75. biotite/sequence/align/matrix_data/BLOSUM45.mat +31 -0
  76. biotite/sequence/align/matrix_data/BLOSUM50.mat +31 -0
  77. biotite/sequence/align/matrix_data/BLOSUM50_13p.mat +25 -0
  78. biotite/sequence/align/matrix_data/BLOSUM50_14.3.mat +25 -0
  79. biotite/sequence/align/matrix_data/BLOSUM50_5.0.mat +25 -0
  80. biotite/sequence/align/matrix_data/BLOSUM55.mat +31 -0
  81. biotite/sequence/align/matrix_data/BLOSUM60.mat +31 -0
  82. biotite/sequence/align/matrix_data/BLOSUM62.mat +31 -0
  83. biotite/sequence/align/matrix_data/BLOSUM62_13p.mat +25 -0
  84. biotite/sequence/align/matrix_data/BLOSUM62_14.3.mat +25 -0
  85. biotite/sequence/align/matrix_data/BLOSUM62_5.0.mat +25 -0
  86. biotite/sequence/align/matrix_data/BLOSUM65.mat +31 -0
  87. biotite/sequence/align/matrix_data/BLOSUM70.mat +31 -0
  88. biotite/sequence/align/matrix_data/BLOSUM75.mat +31 -0
  89. biotite/sequence/align/matrix_data/BLOSUM80.mat +31 -0
  90. biotite/sequence/align/matrix_data/BLOSUM85.mat +31 -0
  91. biotite/sequence/align/matrix_data/BLOSUM90.mat +31 -0
  92. biotite/sequence/align/matrix_data/BLOSUMN.mat +31 -0
  93. biotite/sequence/align/matrix_data/CorBLOSUM49_5.0.mat +25 -0
  94. biotite/sequence/align/matrix_data/CorBLOSUM57_13p.mat +25 -0
  95. biotite/sequence/align/matrix_data/CorBLOSUM57_14.3.mat +25 -0
  96. biotite/sequence/align/matrix_data/CorBLOSUM61_5.0.mat +25 -0
  97. biotite/sequence/align/matrix_data/CorBLOSUM66_13p.mat +25 -0
  98. biotite/sequence/align/matrix_data/CorBLOSUM67_14.3.mat +25 -0
  99. biotite/sequence/align/matrix_data/DAYHOFF.mat +32 -0
  100. biotite/sequence/align/matrix_data/GONNET.mat +26 -0
  101. biotite/sequence/align/matrix_data/IDENTITY.mat +25 -0
  102. biotite/sequence/align/matrix_data/MATCH.mat +25 -0
  103. biotite/sequence/align/matrix_data/NUC.mat +25 -0
  104. biotite/sequence/align/matrix_data/PAM10.mat +34 -0
  105. biotite/sequence/align/matrix_data/PAM100.mat +34 -0
  106. biotite/sequence/align/matrix_data/PAM110.mat +34 -0
  107. biotite/sequence/align/matrix_data/PAM120.mat +34 -0
  108. biotite/sequence/align/matrix_data/PAM130.mat +34 -0
  109. biotite/sequence/align/matrix_data/PAM140.mat +34 -0
  110. biotite/sequence/align/matrix_data/PAM150.mat +34 -0
  111. biotite/sequence/align/matrix_data/PAM160.mat +34 -0
  112. biotite/sequence/align/matrix_data/PAM170.mat +34 -0
  113. biotite/sequence/align/matrix_data/PAM180.mat +34 -0
  114. biotite/sequence/align/matrix_data/PAM190.mat +34 -0
  115. biotite/sequence/align/matrix_data/PAM20.mat +34 -0
  116. biotite/sequence/align/matrix_data/PAM200.mat +34 -0
  117. biotite/sequence/align/matrix_data/PAM210.mat +34 -0
  118. biotite/sequence/align/matrix_data/PAM220.mat +34 -0
  119. biotite/sequence/align/matrix_data/PAM230.mat +34 -0
  120. biotite/sequence/align/matrix_data/PAM240.mat +34 -0
  121. biotite/sequence/align/matrix_data/PAM250.mat +34 -0
  122. biotite/sequence/align/matrix_data/PAM260.mat +34 -0
  123. biotite/sequence/align/matrix_data/PAM270.mat +34 -0
  124. biotite/sequence/align/matrix_data/PAM280.mat +34 -0
  125. biotite/sequence/align/matrix_data/PAM290.mat +34 -0
  126. biotite/sequence/align/matrix_data/PAM30.mat +34 -0
  127. biotite/sequence/align/matrix_data/PAM300.mat +34 -0
  128. biotite/sequence/align/matrix_data/PAM310.mat +34 -0
  129. biotite/sequence/align/matrix_data/PAM320.mat +34 -0
  130. biotite/sequence/align/matrix_data/PAM330.mat +34 -0
  131. biotite/sequence/align/matrix_data/PAM340.mat +34 -0
  132. biotite/sequence/align/matrix_data/PAM350.mat +34 -0
  133. biotite/sequence/align/matrix_data/PAM360.mat +34 -0
  134. biotite/sequence/align/matrix_data/PAM370.mat +34 -0
  135. biotite/sequence/align/matrix_data/PAM380.mat +34 -0
  136. biotite/sequence/align/matrix_data/PAM390.mat +34 -0
  137. biotite/sequence/align/matrix_data/PAM40.mat +34 -0
  138. biotite/sequence/align/matrix_data/PAM400.mat +34 -0
  139. biotite/sequence/align/matrix_data/PAM410.mat +34 -0
  140. biotite/sequence/align/matrix_data/PAM420.mat +34 -0
  141. biotite/sequence/align/matrix_data/PAM430.mat +34 -0
  142. biotite/sequence/align/matrix_data/PAM440.mat +34 -0
  143. biotite/sequence/align/matrix_data/PAM450.mat +34 -0
  144. biotite/sequence/align/matrix_data/PAM460.mat +34 -0
  145. biotite/sequence/align/matrix_data/PAM470.mat +34 -0
  146. biotite/sequence/align/matrix_data/PAM480.mat +34 -0
  147. biotite/sequence/align/matrix_data/PAM490.mat +34 -0
  148. biotite/sequence/align/matrix_data/PAM50.mat +34 -0
  149. biotite/sequence/align/matrix_data/PAM500.mat +34 -0
  150. biotite/sequence/align/matrix_data/PAM60.mat +34 -0
  151. biotite/sequence/align/matrix_data/PAM70.mat +34 -0
  152. biotite/sequence/align/matrix_data/PAM80.mat +34 -0
  153. biotite/sequence/align/matrix_data/PAM90.mat +34 -0
  154. biotite/sequence/align/matrix_data/RBLOSUM52_5.0.mat +25 -0
  155. biotite/sequence/align/matrix_data/RBLOSUM59_13p.mat +25 -0
  156. biotite/sequence/align/matrix_data/RBLOSUM59_14.3.mat +25 -0
  157. biotite/sequence/align/matrix_data/RBLOSUM64_5.0.mat +25 -0
  158. biotite/sequence/align/matrix_data/RBLOSUM69_13p.mat +25 -0
  159. biotite/sequence/align/matrix_data/RBLOSUM69_14.3.mat +25 -0
  160. biotite/sequence/align/multiple.cpython-311-darwin.so +0 -0
  161. biotite/sequence/align/multiple.pyx +620 -0
  162. biotite/sequence/align/pairwise.cpython-311-darwin.so +0 -0
  163. biotite/sequence/align/pairwise.pyx +587 -0
  164. biotite/sequence/align/permutation.cpython-311-darwin.so +0 -0
  165. biotite/sequence/align/permutation.pyx +305 -0
  166. biotite/sequence/align/primes.txt +821 -0
  167. biotite/sequence/align/selector.cpython-311-darwin.so +0 -0
  168. biotite/sequence/align/selector.pyx +956 -0
  169. biotite/sequence/align/statistics.py +265 -0
  170. biotite/sequence/align/tracetable.cpython-311-darwin.so +0 -0
  171. biotite/sequence/align/tracetable.pxd +64 -0
  172. biotite/sequence/align/tracetable.pyx +370 -0
  173. biotite/sequence/alphabet.py +566 -0
  174. biotite/sequence/annotation.py +829 -0
  175. biotite/sequence/codec.cpython-311-darwin.so +0 -0
  176. biotite/sequence/codec.pyx +155 -0
  177. biotite/sequence/codon.py +466 -0
  178. biotite/sequence/codon_tables.txt +202 -0
  179. biotite/sequence/graphics/__init__.py +33 -0
  180. biotite/sequence/graphics/alignment.py +1034 -0
  181. biotite/sequence/graphics/color_schemes/autumn.json +51 -0
  182. biotite/sequence/graphics/color_schemes/blossom.json +51 -0
  183. biotite/sequence/graphics/color_schemes/clustalx_dna.json +11 -0
  184. biotite/sequence/graphics/color_schemes/clustalx_protein.json +28 -0
  185. biotite/sequence/graphics/color_schemes/flower.json +51 -0
  186. biotite/sequence/graphics/color_schemes/jalview_buried.json +31 -0
  187. biotite/sequence/graphics/color_schemes/jalview_hydrophobicity.json +31 -0
  188. biotite/sequence/graphics/color_schemes/jalview_prop_helix.json +31 -0
  189. biotite/sequence/graphics/color_schemes/jalview_prop_strand.json +31 -0
  190. biotite/sequence/graphics/color_schemes/jalview_prop_turn.json +31 -0
  191. biotite/sequence/graphics/color_schemes/jalview_taylor.json +28 -0
  192. biotite/sequence/graphics/color_schemes/jalview_zappo.json +28 -0
  193. biotite/sequence/graphics/color_schemes/ocean.json +51 -0
  194. biotite/sequence/graphics/color_schemes/pb_flower.json +39 -0
  195. biotite/sequence/graphics/color_schemes/rainbow_dna.json +11 -0
  196. biotite/sequence/graphics/color_schemes/rainbow_protein.json +30 -0
  197. biotite/sequence/graphics/color_schemes/spring.json +51 -0
  198. biotite/sequence/graphics/color_schemes/sunset.json +51 -0
  199. biotite/sequence/graphics/color_schemes/wither.json +51 -0
  200. biotite/sequence/graphics/colorschemes.py +139 -0
  201. biotite/sequence/graphics/dendrogram.py +184 -0
  202. biotite/sequence/graphics/features.py +510 -0
  203. biotite/sequence/graphics/logo.py +110 -0
  204. biotite/sequence/graphics/plasmid.py +661 -0
  205. biotite/sequence/io/__init__.py +12 -0
  206. biotite/sequence/io/fasta/__init__.py +22 -0
  207. biotite/sequence/io/fasta/convert.py +273 -0
  208. biotite/sequence/io/fasta/file.py +278 -0
  209. biotite/sequence/io/fastq/__init__.py +19 -0
  210. biotite/sequence/io/fastq/convert.py +120 -0
  211. biotite/sequence/io/fastq/file.py +551 -0
  212. biotite/sequence/io/genbank/__init__.py +17 -0
  213. biotite/sequence/io/genbank/annotation.py +277 -0
  214. biotite/sequence/io/genbank/file.py +575 -0
  215. biotite/sequence/io/genbank/metadata.py +324 -0
  216. biotite/sequence/io/genbank/sequence.py +172 -0
  217. biotite/sequence/io/general.py +192 -0
  218. biotite/sequence/io/gff/__init__.py +26 -0
  219. biotite/sequence/io/gff/convert.py +133 -0
  220. biotite/sequence/io/gff/file.py +434 -0
  221. biotite/sequence/phylo/__init__.py +36 -0
  222. biotite/sequence/phylo/nj.cpython-311-darwin.so +0 -0
  223. biotite/sequence/phylo/nj.pyx +221 -0
  224. biotite/sequence/phylo/tree.cpython-311-darwin.so +0 -0
  225. biotite/sequence/phylo/tree.pyx +1169 -0
  226. biotite/sequence/phylo/upgma.cpython-311-darwin.so +0 -0
  227. biotite/sequence/phylo/upgma.pyx +164 -0
  228. biotite/sequence/profile.py +456 -0
  229. biotite/sequence/search.py +116 -0
  230. biotite/sequence/seqtypes.py +556 -0
  231. biotite/sequence/sequence.py +374 -0
  232. biotite/structure/__init__.py +132 -0
  233. biotite/structure/atoms.py +1455 -0
  234. biotite/structure/basepairs.py +1415 -0
  235. biotite/structure/bonds.cpython-311-darwin.so +0 -0
  236. biotite/structure/bonds.pyx +1933 -0
  237. biotite/structure/box.py +592 -0
  238. biotite/structure/celllist.cpython-311-darwin.so +0 -0
  239. biotite/structure/celllist.pyx +849 -0
  240. biotite/structure/chains.py +298 -0
  241. biotite/structure/charges.cpython-311-darwin.so +0 -0
  242. biotite/structure/charges.pyx +520 -0
  243. biotite/structure/compare.py +274 -0
  244. biotite/structure/density.py +114 -0
  245. biotite/structure/dotbracket.py +216 -0
  246. biotite/structure/error.py +31 -0
  247. biotite/structure/filter.py +585 -0
  248. biotite/structure/geometry.py +697 -0
  249. biotite/structure/graphics/__init__.py +13 -0
  250. biotite/structure/graphics/atoms.py +226 -0
  251. biotite/structure/graphics/rna.py +282 -0
  252. biotite/structure/hbond.py +409 -0
  253. biotite/structure/info/__init__.py +25 -0
  254. biotite/structure/info/atom_masses.json +121 -0
  255. biotite/structure/info/atoms.py +82 -0
  256. biotite/structure/info/bonds.py +145 -0
  257. biotite/structure/info/ccd/README.rst +8 -0
  258. biotite/structure/info/ccd/amino_acids.txt +1663 -0
  259. biotite/structure/info/ccd/carbohydrates.txt +1135 -0
  260. biotite/structure/info/ccd/components.bcif +0 -0
  261. biotite/structure/info/ccd/nucleotides.txt +798 -0
  262. biotite/structure/info/ccd.py +95 -0
  263. biotite/structure/info/groups.py +90 -0
  264. biotite/structure/info/masses.py +123 -0
  265. biotite/structure/info/misc.py +144 -0
  266. biotite/structure/info/radii.py +197 -0
  267. biotite/structure/info/standardize.py +196 -0
  268. biotite/structure/integrity.py +268 -0
  269. biotite/structure/io/__init__.py +30 -0
  270. biotite/structure/io/ctab.py +72 -0
  271. biotite/structure/io/dcd/__init__.py +13 -0
  272. biotite/structure/io/dcd/file.py +65 -0
  273. biotite/structure/io/general.py +257 -0
  274. biotite/structure/io/gro/__init__.py +14 -0
  275. biotite/structure/io/gro/file.py +343 -0
  276. biotite/structure/io/mmtf/__init__.py +21 -0
  277. biotite/structure/io/mmtf/assembly.py +214 -0
  278. biotite/structure/io/mmtf/convertarray.cpython-311-darwin.so +0 -0
  279. biotite/structure/io/mmtf/convertarray.pyx +341 -0
  280. biotite/structure/io/mmtf/convertfile.cpython-311-darwin.so +0 -0
  281. biotite/structure/io/mmtf/convertfile.pyx +501 -0
  282. biotite/structure/io/mmtf/decode.cpython-311-darwin.so +0 -0
  283. biotite/structure/io/mmtf/decode.pyx +152 -0
  284. biotite/structure/io/mmtf/encode.cpython-311-darwin.so +0 -0
  285. biotite/structure/io/mmtf/encode.pyx +183 -0
  286. biotite/structure/io/mmtf/file.py +233 -0
  287. biotite/structure/io/mol/__init__.py +20 -0
  288. biotite/structure/io/mol/convert.py +115 -0
  289. biotite/structure/io/mol/ctab.py +414 -0
  290. biotite/structure/io/mol/header.py +116 -0
  291. biotite/structure/io/mol/mol.py +193 -0
  292. biotite/structure/io/mol/sdf.py +916 -0
  293. biotite/structure/io/netcdf/__init__.py +13 -0
  294. biotite/structure/io/netcdf/file.py +63 -0
  295. biotite/structure/io/npz/__init__.py +20 -0
  296. biotite/structure/io/npz/file.py +152 -0
  297. biotite/structure/io/pdb/__init__.py +20 -0
  298. biotite/structure/io/pdb/convert.py +293 -0
  299. biotite/structure/io/pdb/file.py +1240 -0
  300. biotite/structure/io/pdb/hybrid36.cpython-311-darwin.so +0 -0
  301. biotite/structure/io/pdb/hybrid36.pyx +242 -0
  302. biotite/structure/io/pdbqt/__init__.py +15 -0
  303. biotite/structure/io/pdbqt/convert.py +107 -0
  304. biotite/structure/io/pdbqt/file.py +640 -0
  305. biotite/structure/io/pdbx/__init__.py +23 -0
  306. biotite/structure/io/pdbx/bcif.py +648 -0
  307. biotite/structure/io/pdbx/cif.py +1032 -0
  308. biotite/structure/io/pdbx/component.py +246 -0
  309. biotite/structure/io/pdbx/convert.py +1597 -0
  310. biotite/structure/io/pdbx/encoding.cpython-311-darwin.so +0 -0
  311. biotite/structure/io/pdbx/encoding.pyx +950 -0
  312. biotite/structure/io/pdbx/legacy.py +267 -0
  313. biotite/structure/io/tng/__init__.py +13 -0
  314. biotite/structure/io/tng/file.py +46 -0
  315. biotite/structure/io/trajfile.py +710 -0
  316. biotite/structure/io/trr/__init__.py +13 -0
  317. biotite/structure/io/trr/file.py +46 -0
  318. biotite/structure/io/xtc/__init__.py +13 -0
  319. biotite/structure/io/xtc/file.py +46 -0
  320. biotite/structure/mechanics.py +75 -0
  321. biotite/structure/molecules.py +353 -0
  322. biotite/structure/pseudoknots.py +642 -0
  323. biotite/structure/rdf.py +243 -0
  324. biotite/structure/repair.py +253 -0
  325. biotite/structure/residues.py +562 -0
  326. biotite/structure/resutil.py +178 -0
  327. biotite/structure/sasa.cpython-311-darwin.so +0 -0
  328. biotite/structure/sasa.pyx +322 -0
  329. biotite/structure/sequence.py +112 -0
  330. biotite/structure/sse.py +327 -0
  331. biotite/structure/superimpose.py +727 -0
  332. biotite/structure/transform.py +504 -0
  333. biotite/structure/util.py +98 -0
  334. biotite/temp.py +86 -0
  335. biotite/version.py +16 -0
  336. biotite/visualize.py +251 -0
  337. biotite-0.41.1.dist-info/METADATA +187 -0
  338. biotite-0.41.1.dist-info/RECORD +340 -0
  339. biotite-0.41.1.dist-info/WHEEL +4 -0
  340. biotite-0.41.1.dist-info/licenses/LICENSE.rst +30 -0
@@ -0,0 +1,661 @@
1
+ # This source code is part of the Biotite package and is distributed
2
+ # under the 3-Clause BSD License. Please see 'LICENSE.rst' for further
3
+ # information.
4
+
5
+ __name__ = "biotite.sequence.graphics"
6
+ __author__ = "Patrick Kunzmann"
7
+ __all__ = ["plot_plasmid_map"]
8
+
9
+ import copy
10
+ import warnings
11
+ import abc
12
+ import numpy as np
13
+ import re
14
+ from ...visualize import colors
15
+ from ..annotation import Annotation, Feature, Location
16
+
17
+
18
+ def plot_plasmid_map(axes, annotation, plasmid_size, tick_length=0.02,
19
+ tick_step=200, ring_width=0.01, feature_width=0.06,
20
+ spacing=0.01, arrow_head_length=0.04, label=None,
21
+ face_properties=None, label_properties=None,
22
+ omit_oversized_labels=True, feature_formatter=None):
23
+ """
24
+ Plot a plasmid map using the sequence features in the given
25
+ :class:`Annotation`.
26
+
27
+ Each feature location is depicted either by a curved arrow,
28
+ indicating on which strand the feature resides, or an arc.
29
+ The ticks indicate the sequence position.
30
+
31
+ **EXPERIMENTAL**: The API and the resulting plots will probably
32
+ change in future versions.
33
+
34
+ Parameters
35
+ ----------
36
+ axes : PolarAxes
37
+ A *Matplotlib* axes, that is used as plotting area.
38
+ A polar projection is required.
39
+ annotation : Annotation
40
+ The annotation to be visualized.
41
+ plasmid_size : int
42
+ The size of the plasmid, i.e. the length of its sequence.
43
+ tick_length : float, optional
44
+ The length of the axis ticks as percentage of the plot radius.
45
+ tick_step : int, optional
46
+ The interval between the displayed sequence positions.
47
+ For example ``tick_step=200`` means that ticks will be displayed
48
+ at ``1``, ``200``, ``400``, ``600``, etc.
49
+ ring_width : float, optional
50
+ The width of the outer ring as percentage of the plot radius.
51
+ feature_width : float, optional
52
+ The width of each feature arrow/arc as percentage of the
53
+ plot radius.
54
+ spacing : float, optional
55
+ The spacing between the rows of feature arrows/arcs as
56
+ percentage of the plot radius.
57
+ arrow_head_length : float, optional
58
+ The length of the arrow heads as percentage of the radius
59
+ at which the respective arrow is plotted.
60
+ label : str, optional
61
+ The central label of the plot. Ususally the plasmid name.
62
+ face_properties : dict, optional
63
+ A dictionary of properties given to the patches that make up the
64
+ feature arrows/arcs.
65
+ Internally the arrow tail is a *Matplotlib* :class:`Rectangle`,
66
+ and the arrow head is a :class:`Polygon`.
67
+ For example this parameter could be used to add edge lines to
68
+ the arrows/arcs.
69
+ label_properties : dict, optional
70
+ A dictionary of properties given to the feature labels.
71
+ Internally each feature label is one or multiple *Matplotlib*
72
+ :class:`Text` instances.
73
+ For example this parameter could be used to set the font weight
74
+ or size.
75
+ omit_oversized_labels : bool, optional
76
+ If true, a feature label will not be displayed, if the label is
77
+ larger than its containing arc/arrow.
78
+ This ensures, that labels from different features will not
79
+ overlap each other.
80
+ If false, the feature labels will always be displayed.
81
+ feature_formatter : function, optional
82
+ A function that determines *how* each feature is displayed.
83
+ The given function must take a :class:`Feature` and must return
84
+ the following tuple:
85
+
86
+ - *directional* : bool
87
+
88
+ True, if the direction of the feature should be indicated by
89
+ an arrow.
90
+ Otherwise, the feature is plotted is arc.
91
+
92
+ - *face_color* : tuple or str, optional
93
+
94
+ A *Matplotlib* compatible color for the feature arrow/arc.
95
+
96
+ - *label_color* : tuple or str, optional
97
+
98
+ A *Matplotlib* compatible color for the feature label.
99
+
100
+ - *label* : str or None
101
+
102
+ The label to be displayed for this feature.
103
+ None, if no label should be displayed.
104
+ """
105
+ from matplotlib.projections.polar import PolarAxes
106
+
107
+ if not isinstance(axes, PolarAxes):
108
+ raise TypeError("The given axes must be a 'PolarAxes'")
109
+
110
+ ### Setup parameters ###
111
+ if plasmid_size is None:
112
+ # 'stop' of 'get_location_range()' is exclusive -> -1
113
+ plasmid_size = annotation.get_location_range()[1] - 1
114
+ if face_properties is None:
115
+ face_properties = {}
116
+ if label_properties is None:
117
+ label_properties = {}
118
+ if feature_formatter is None:
119
+ feature_formatter = _default_feature_formatter
120
+
121
+
122
+ ### Setup matplotlib ###
123
+ # The x-coordinate is given as angle (rad)
124
+ # Full circle -> 2*pi
125
+ axes.set_xlim(0, 2*np.pi)
126
+ axes.set_ylim(0, 1)
127
+ axes.yaxis.set_visible(False)
128
+ axes.xaxis.set_tick_params(
129
+ bottom=False, labelbottom=True
130
+ )
131
+ axes.set_theta_zero_location("N")
132
+ axes.set_theta_direction("clockwise")
133
+ axes.spines["polar"].set_visible(False)
134
+ axes.grid(False)
135
+ # Setup ticks
136
+ ticks = [1]
137
+ tick_labels = [str(1)]
138
+ for tick in range(tick_step, plasmid_size, tick_step):
139
+ ticks.append(tick)
140
+ tick_labels.append(str(tick))
141
+ # Sequence location is replaced by angle
142
+ axes.xaxis.set_ticks([_loc_to_rad(tick, plasmid_size) for tick in ticks])
143
+ axes.xaxis.set_ticklabels(tick_labels)
144
+ ### Draw plasmid ring with ticks and central label ###
145
+
146
+ # Plasmid ring
147
+ # Use 'barh()' instead of a Rectangle patch to ensure that the axes
148
+ # is properly initialized
149
+ # Otherwise the feature rectangles are not curved, but straight
150
+ axes.barh(
151
+ 1-ring_width-tick_length, 2*np.pi, ring_width,
152
+ align="edge", color="black"
153
+ )
154
+
155
+ # Ticks (ticks itself, not the tick labels)
156
+ for tick in ticks:
157
+ angle = _loc_to_rad(tick, plasmid_size)
158
+ axes.plot(
159
+ (angle, angle), (1-tick_length, 1),
160
+ color="black", linewidth=1, linestyle="-"
161
+ )
162
+
163
+ # Central plasmid label
164
+ if label is not None:
165
+ axes.text(
166
+ 0, 0, label, ha="center", va="center",
167
+ color="black", size=32, fontweight="bold"
168
+ )
169
+
170
+
171
+ ### Draw plasmid interior ###
172
+ inner_radius = 1 - ring_width - tick_length
173
+ features = sorted(
174
+ [
175
+ _merge_over_periodic_boundary(feature, plasmid_size)
176
+ for feature in annotation
177
+ ],
178
+ # Features are sorted by the length of their location range
179
+ # The shortest come first
180
+ key = lambda feature: np.diff(feature.get_location_range())[0],
181
+ reverse = True
182
+ )
183
+ axes.add_artist(PlasmidMap(
184
+ axes, 0, features, plasmid_size, inner_radius, feature_width, spacing,
185
+ arrow_head_length, label, face_properties, label_properties,
186
+ omit_oversized_labels, feature_formatter
187
+ ))
188
+
189
+
190
+ try:
191
+ # Only create these classes when matplotlib is installed
192
+ from matplotlib.artist import Artist
193
+ from matplotlib.transforms import Bbox
194
+ from matplotlib.patches import Rectangle, Polygon
195
+
196
+
197
+ class PlasmidMap(Artist):
198
+ def __init__(self, axes, zorder, features, plasmid_size, radius,
199
+ feature_width, spacing, arrow_head_length, label,
200
+ face_properties, label_properties, omit_oversized_labels,
201
+ feature_formatter):
202
+ super().__init__()
203
+ self._axes = axes
204
+ self.zorder = zorder
205
+ self._features = features
206
+ self._plasmid_size = plasmid_size
207
+ self._radius = radius
208
+ self._feature_width = feature_width
209
+ self._spacing = spacing
210
+
211
+ self._all_indicators = []
212
+ for feature in features:
213
+ indicators_for_feature = []
214
+ for loc in feature.locs:
215
+ # Set proper positions in 'draw()' method
216
+ bbox = Bbox.from_extents(0, 0, 0, 0)
217
+ # Draw features as curved arrows (feature indicator)
218
+ indicator = axes.add_artist(Feature_Indicator(
219
+ axes, self.zorder + 1, feature, loc, bbox,
220
+ arrow_head_length, face_properties, label_properties,
221
+ omit_oversized_labels, feature_formatter
222
+ ))
223
+ indicators_for_feature.append(indicator)
224
+ self._all_indicators.append(indicators_for_feature)
225
+
226
+
227
+ def draw(self, renderer, *args, **kwargs):
228
+ # Find the maximum amount of feature rows
229
+ # (used for overlapping features)
230
+ row_count = int(
231
+ self._radius // (self._feature_width + self._spacing)
232
+ )
233
+ # Tracks the location ranges of feature that were added to
234
+ # a row in order to check if that row is occupied
235
+ ranges_in_row = [[] for i in range(row_count)]
236
+ # Stores the bottom coordinate (radius) for each row
237
+ row_bottoms = [
238
+ self._radius - (row+1) * (self._feature_width + self._spacing)
239
+ for row in range(row_count)
240
+ ]
241
+
242
+ # Arrange the feature indicators in an way,
243
+ # that there is no overlap between them
244
+ for feature, indicators_for_feature in zip(
245
+ self._features, self._all_indicators
246
+ ):
247
+ row_bottom = None
248
+ first, last = feature.get_location_range()
249
+
250
+ for row_i, curr_range in enumerate(ranges_in_row):
251
+ is_occupied = False
252
+ if curr_range is not None:
253
+ # Check if row is occupied
254
+ for curr_first, curr_last in curr_range:
255
+ # If the location extends over periodic
256
+ # boundary the 'first' location is negative
257
+ if first > 0:
258
+ # 'Normal feature'
259
+ if first <= curr_last and last >= curr_first:
260
+ is_occupied = True
261
+ else: # first < 1
262
+ # Location is over periodic boundary
263
+ if first + self._plasmid_size <= curr_last \
264
+ or last >= curr_first:
265
+ is_occupied = True
266
+ if not is_occupied:
267
+ # Row is not occupied by another feature
268
+ # in the location range of the new feature
269
+ # -> Use this row
270
+ if first > 0:
271
+ # 'Normal feature'
272
+ ranges_in_row[row_i].append((first, last))
273
+ else:
274
+ # Location is over periodic boundary
275
+ # Split into 'end' and 'start' part
276
+ ranges_in_row[row_i].append((
277
+ first + self._plasmid_size, self._plasmid_size
278
+ ))
279
+ ranges_in_row[row_i].append((
280
+ 1, last
281
+ ))
282
+ row_bottom = row_bottoms[row_i]
283
+ break
284
+ if row_bottom is None:
285
+ # No free row -> ignore feature and raise warning
286
+ warnings.warn(
287
+ "Too many feature overlaps, try to increase the "
288
+ "radius or decrease the feature width or spacing"
289
+ )
290
+ else:
291
+ for loc, indicator in zip(
292
+ feature.locs, indicators_for_feature
293
+ ):
294
+ # Calculate arrow shape parameters
295
+ row_center = row_bottom + self._feature_width/2
296
+ row_top = row_bottom + self._feature_width
297
+ start_ang = _loc_to_rad(loc.first, self._plasmid_size)
298
+ stop_ang = _loc_to_rad(loc.last, self._plasmid_size)
299
+ bbox = Bbox.from_extents(
300
+ start_ang, row_bottom, stop_ang, row_top
301
+ )
302
+ indicator.set_bbox(bbox)
303
+
304
+
305
+ class Feature_Indicator(Artist):
306
+ def __init__(self, axes, zorder, feature, loc, bbox, head_length,
307
+ arrow_properties, label_properties, omit_oversized_labels,
308
+ feature_formatter):
309
+ super().__init__()
310
+ self._axes = axes
311
+ self.zorder = zorder
312
+ self._direction = loc.strand
313
+ self._bbox = bbox
314
+ self._head_length = head_length
315
+ self._omit_oversized_labels = omit_oversized_labels
316
+
317
+ # Determine how to draw the feature
318
+ directional, face_color, label_color, label \
319
+ = feature_formatter(feature)
320
+
321
+ # Draw arrow as composition of a rectangle and a triangle,
322
+ # as FancyArrow does not properly work for polar plots
323
+
324
+ self._arrow_tail = axes.add_patch(Rectangle(
325
+ # Set positions in 'draw()' method
326
+ (0, 0), 0, 0,
327
+ # Line width is set to 1 to avoid strange artifact in
328
+ # the transition from rectangle (tail) to polygon (head)
329
+ color=face_color, linewidth=1, zorder = self.zorder + 1,
330
+ **arrow_properties
331
+ ))
332
+
333
+ if directional:
334
+ # Only draw any arrow head when feature has a direction,
335
+ # otherwise simply draw the tail (rectangle)
336
+ self._arrow_head = axes.add_patch(Polygon(
337
+ # Set positions in 'draw()' method
338
+ [(0, 0), (0, 0), (0, 0)],
339
+ color=face_color, linewidth=1, zorder = self.zorder + 1,
340
+ **arrow_properties
341
+ ))
342
+ else:
343
+ self._arrow_head = None
344
+
345
+ if label is not None:
346
+ label_properties["color"] = label_color
347
+ self._label = axes.add_artist(CurvedText(
348
+ # Set positions in 'draw()' method
349
+ axes, self.zorder + 1, 0, 0, label, label_properties
350
+ ))
351
+ else:
352
+ self._label = None
353
+
354
+
355
+ def set_bbox(self, bbox):
356
+ self._bbox = bbox
357
+ center_x = (bbox.x0 + bbox.x1) / 2
358
+ center_y = (bbox.y0 + bbox.y1) / 2
359
+ if self._label is not None:
360
+ self._label.set_position(center_x, center_y)
361
+
362
+
363
+ def draw(self, renderer, *args, **kwargs):
364
+ bbox = self._bbox
365
+ center_x = (bbox.x0 + bbox.x1) / 2
366
+ center_y = (bbox.y0 + bbox.y1) / 2
367
+
368
+ # Constant absolute width for all arrows
369
+ # irrespective of the radius in the polar plot
370
+ # Calculate actual angle from given absolute width
371
+ head_length = self._head_length / center_y
372
+
373
+ # Check if the head should be drawn
374
+ if self._arrow_head is None:
375
+ head_length = 0
376
+ # Check if the feature location is too small for
377
+ elif head_length > bbox.width:
378
+ # Limit size of arrow head to range of location
379
+ head_length = bbox.width
380
+
381
+ if self._direction == Location.Strand.FORWARD:
382
+ rect_pos = (bbox.x0, bbox.y0)
383
+ # (x0, y0), (x1, y1), (x2, y2)
384
+ triangle_coord = [
385
+ (bbox.x1 - head_length, bbox.y0), # base 1
386
+ (bbox.x1 - head_length, bbox.y1), # base 2
387
+ (bbox.x1, center_y) # tip
388
+ ]
389
+ else:
390
+ rect_pos = (bbox.x0+head_length, bbox.y0)
391
+ triangle_coord = [
392
+ (bbox.x0 + head_length, bbox.y0), # base 1
393
+ (bbox.x0 + head_length, bbox.y1), # base 2
394
+ (bbox.x0, center_y) # tip
395
+ ]
396
+
397
+ # Update coordinates of sub-artists
398
+ self._arrow_tail.set_xy(rect_pos)
399
+ self._arrow_tail.set_width(bbox.width-head_length)
400
+ self._arrow_tail.set_height(bbox.height)
401
+ if self._arrow_head is not None:
402
+ self._arrow_head.set_xy(triangle_coord)
403
+
404
+ if self._label is not None:
405
+ # Do not draw the labels if it is larger than the
406
+ # indicator
407
+ if self._omit_oversized_labels \
408
+ and self._label.get_total_angle(renderer) > bbox.width:
409
+ self._label.set_visible(False)
410
+ else:
411
+ self._label.set_visible(True)
412
+
413
+
414
+
415
+ class CurvedText(Artist):
416
+ def __init__(self, axes, zorder, angle, radius, string,
417
+ text_properties):
418
+ super().__init__()
419
+ self._axes = axes
420
+ self.zorder = zorder
421
+ self._angle = angle
422
+ self._radius = radius
423
+
424
+ self._texts = []
425
+ for word in _split_into_words(string):
426
+ text = axes.text(
427
+ # Set position in 'draw()' method
428
+ 0, 0,
429
+ word,
430
+ ha="center", va="center",
431
+ zorder=self.zorder + 1,
432
+ **text_properties,
433
+ )
434
+ self._texts.append(text)
435
+
436
+
437
+ def set_visible(self, visible):
438
+ super().set_visible(visible)
439
+ for text in self._texts:
440
+ text.set_visible(visible)
441
+
442
+
443
+ def set_position(self, angle, radius):
444
+ self._angle = angle
445
+ self._radius = radius
446
+
447
+
448
+ def get_total_angle(self, renderer):
449
+ return np.sum(self.get_word_angles(renderer))
450
+
451
+
452
+ def get_word_angles(self, renderer):
453
+ ax_px_radius = self._axes.get_window_extent(renderer).width / 2
454
+ ax_unit_radius = self._axes.get_ylim()[1]
455
+ circle_px_circumference = ax_px_radius * 2*np.pi \
456
+ * (self._radius / ax_unit_radius)
457
+
458
+ rad_angle = 360 - np.rad2deg(self._angle)
459
+ # Avoid to draw the text upside down, when drawn on the
460
+ # bottom half of the map
461
+ if rad_angle > 90 and rad_angle < 270:
462
+ turn_around = True
463
+ else:
464
+ turn_around = False
465
+
466
+ angles = []
467
+ for text in self._texts:
468
+ orig_rot = text.get_rotation()
469
+ orig_visible = text.get_visible()
470
+ # Reset rotation and visibility
471
+ # for correct window extent calculation
472
+ text.set_rotation(0)
473
+ text.set_visible(True)
474
+ word_px_width = text.get_window_extent(renderer).width
475
+ # In some Matplotlib versions the window extent of
476
+ # whitespace characters is 'nan'
477
+ # In this case, assign a fixed width
478
+ if np.isnan(word_px_width):
479
+ word_px_width = 5.0
480
+ word_angle \
481
+ = 2*np.pi * word_px_width / circle_px_circumference
482
+ angles.append(word_angle)
483
+ # Restore
484
+ text.set_rotation(orig_rot)
485
+ text.set_visible(orig_visible)
486
+ return angles
487
+
488
+
489
+ def draw(self, renderer, *args, **kwargs):
490
+ angles = self.get_word_angles(renderer)
491
+ total_angle = np.sum(angles)
492
+
493
+ rad_angle = 360 - np.rad2deg(self._angle)
494
+ # Avoid to draw the text upside down, when drawn on the
495
+ # bottom half of the map
496
+ if rad_angle > 90 and rad_angle < 270:
497
+ turn_around = True
498
+ else:
499
+ turn_around = False
500
+
501
+ # Now that the angle for each word is known,
502
+ # the appropriate position and rotation can be set
503
+ if turn_around:
504
+ # curr_angle is the left-aligned position of the
505
+ # upcoming word
506
+ curr_angle = self._angle + total_angle / 2
507
+ else:
508
+ curr_angle = self._angle - total_angle / 2
509
+ for text, angle in zip(self._texts, angles):
510
+ if turn_around:
511
+ # The text itself is centered
512
+ # -> The position itself must be corrected with
513
+ # half of the word angle
514
+ angle_corrected = curr_angle - angle / 2
515
+ text_rot = 360 - np.rad2deg(angle_corrected) + 180
516
+ curr_angle -= angle
517
+ else:
518
+ angle_corrected = curr_angle + angle / 2
519
+ text_rot = 360 - np.rad2deg(angle_corrected)
520
+ curr_angle += angle
521
+ text.set_position((angle_corrected, self._radius))
522
+ text.set_rotation(text_rot)
523
+
524
+
525
+ except ImportError:
526
+ pass
527
+
528
+
529
+
530
+
531
+ def _loc_to_rad(loc, plasmid_size):
532
+ if loc > plasmid_size:
533
+ raise ValueError(
534
+ f"Location {loc} is larger then the plasmid size of {plasmid_size}"
535
+ )
536
+ # Location starts at 1 -> (loc-1)
537
+ return ((loc-1) / plasmid_size) * 2*np.pi
538
+
539
+
540
+ def _rad_to_loc(rad, plasmid_size):
541
+ # Location starts at 1 -> + 1
542
+ return rad / (2*np.pi) * plasmid_size + 1
543
+
544
+
545
+ def _merge_over_periodic_boundary(feature, plasmid_size):
546
+ if len(feature.locs) == 1:
547
+ # Only one location -> no merge possible
548
+ return feature
549
+ first_loc = None
550
+ last_loc = None
551
+ # Find total first location of the feature
552
+ for loc in feature.locs:
553
+ if first_loc is None or loc.first < first_loc.first:
554
+ first_loc = loc
555
+ # Find total last location of the feature
556
+ for loc in feature.locs:
557
+ if last_loc is None or loc.last > last_loc.last:
558
+ last_loc = loc
559
+ # If the first and last location meet at the periodic boundary of
560
+ # the plasmid -> merge them
561
+ if first_loc.first == 1 and last_loc.last == plasmid_size \
562
+ and first_loc.strand == last_loc.strand:
563
+ new_locs = set(feature.locs)
564
+ new_locs.remove(first_loc)
565
+ new_locs.remove(last_loc)
566
+ new_locs.add(Location(
567
+ # the fist base is now at negative location
568
+ # by shifting by one plasmid 'period'
569
+ first = last_loc.first - plasmid_size,
570
+ last = first_loc.last,
571
+ strand = first_loc.strand,
572
+ defect = first_loc.defect | last_loc.defect
573
+ ))
574
+ return Feature(feature.key, new_locs, feature.qual)
575
+ else:
576
+ return feature
577
+
578
+
579
+ # ' ', '-' and '_' are word delimiters
580
+ separators = re.compile(r"\s|_|-")
581
+ def _split_into_words(string):
582
+ match_indices = sorted(
583
+ [match.start() for match in separators.finditer(string)]
584
+ )
585
+ current_index = 0
586
+ words = []
587
+ for i in match_indices:
588
+ # Add word up to delimiter
589
+ words.append(string[current_index : i])
590
+ # Add delimiter
591
+ words.append(string[i : i+1])
592
+ current_index = i+1
593
+ # If there is a word after the last delimiter, add it too
594
+ if current_index < len(string):
595
+ words.append(string[current_index:])
596
+ return words
597
+
598
+
599
+ def _default_feature_formatter(f):
600
+ """
601
+ Returns
602
+ -------
603
+ directional : bool
604
+ True, if the direction of the feature should be indicated by
605
+ an arrow.
606
+ face_color: tuple or str, optional
607
+ A matplotlib compatible color for the feature indicator.
608
+ label_color: tuple or str, optional
609
+ A matplotlib compatible color for the feature label.
610
+ label: str or None
611
+ The label to be displayed for this feature.
612
+ None, if no label should be displayed.
613
+ """
614
+ # Source
615
+ if f.key == "source":
616
+ if f.qual.get("organism") is not None:
617
+ label = f"Source: {f.qual.get('organism')}"
618
+ else:
619
+ label = None
620
+ return False, "black", "white", label
621
+
622
+ # Origin of Replication
623
+ elif f.key == "rep_origin":
624
+ return False, "indigo", "white", \
625
+ f.qual.get("standard_name", "ori")
626
+
627
+ # Coding sequences
628
+ elif f.key in ["gene", "CDS", "rRNA"]:
629
+ label = f.qual.get("product")
630
+ if label is None:
631
+ label = f.qual.get("gene")
632
+ return True, colors["orange"], "black", label
633
+
634
+ elif f.key == "regulatory":
635
+ # Promoters
636
+ if f.qual.get("regulatory_class") in [
637
+ "promoter",
638
+ "TATA_box",
639
+ "minus_35_signal",
640
+ "minus_10_signal"
641
+ ]:
642
+ return True, colors["dimgreen"], "black", f.qual.get("note")
643
+
644
+ # Terminators
645
+ elif f.qual.get("regulatory_class") in "terminator":
646
+ return False, "firebrick", "white", f.qual.get("note")
647
+
648
+ # RBS
649
+ elif f.qual.get("regulatory_class") == "ribosome_binding_site":
650
+ return False, colors["brightorange"], "white", None
651
+
652
+ # Primers
653
+ elif f.key == "primer_bind":
654
+ return True, "royalblue", "black", f.qual.get("note")
655
+
656
+ # Binding proteins
657
+ elif f.key == "protein_bind":
658
+ return False, colors["lightgreen"], "black", f.qual.get("note")
659
+
660
+ # Misc
661
+ return True, "dimgray", "white", f.qual.get("note")
@@ -0,0 +1,12 @@
1
+ # This source code is part of the Biotite package and is distributed
2
+ # under the 3-Clause BSD License. Please see 'LICENSE.rst' for further
3
+ # information.
4
+
5
+ """
6
+ A subpackage for reading and writing sequence related data.
7
+ """
8
+
9
+ __name__ = "biotite.sequence.io"
10
+ __author__ = "Patrick Kunzmann"
11
+
12
+ from .general import *
@@ -0,0 +1,22 @@
1
+ # This source code is part of the Biotite package and is distributed
2
+ # under the 3-Clause BSD License. Please see 'LICENSE.rst' for further
3
+ # information.
4
+
5
+ """
6
+ This subpackage is used for reading and writing sequence objects
7
+ using the popular FASTA format.
8
+
9
+ This package contains the :class:`FastaFile`, which provides a
10
+ dictionary like interface to FASTA files, where the header lines are
11
+ keys and the strings containing sequence data are the corresponding
12
+ values.
13
+
14
+ Furthermore, the package contains convenience functions for
15
+ getting/setting directly :class:`Sequence` objects, rather than strings.
16
+ """
17
+
18
+ __name__ = "biotite.sequence.io.fasta"
19
+ __author__ = "Patrick Kunzmann"
20
+
21
+ from .file import *
22
+ from .convert import *