biotite 0.41.2__cp312-cp312-win_amd64.whl → 1.0.1__cp312-cp312-win_amd64.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 (205) hide show
  1. biotite/__init__.py +2 -3
  2. biotite/application/__init__.py +1 -1
  3. biotite/application/application.py +20 -10
  4. biotite/application/autodock/__init__.py +1 -1
  5. biotite/application/autodock/app.py +74 -79
  6. biotite/application/blast/__init__.py +1 -1
  7. biotite/application/blast/alignment.py +19 -10
  8. biotite/application/blast/webapp.py +92 -85
  9. biotite/application/clustalo/__init__.py +1 -1
  10. biotite/application/clustalo/app.py +46 -61
  11. biotite/application/dssp/__init__.py +1 -1
  12. biotite/application/dssp/app.py +8 -11
  13. biotite/application/localapp.py +62 -60
  14. biotite/application/mafft/__init__.py +1 -1
  15. biotite/application/mafft/app.py +16 -22
  16. biotite/application/msaapp.py +78 -89
  17. biotite/application/muscle/__init__.py +1 -1
  18. biotite/application/muscle/app3.py +50 -64
  19. biotite/application/muscle/app5.py +23 -31
  20. biotite/application/sra/__init__.py +1 -1
  21. biotite/application/sra/app.py +64 -68
  22. biotite/application/tantan/__init__.py +1 -1
  23. biotite/application/tantan/app.py +22 -45
  24. biotite/application/util.py +7 -9
  25. biotite/application/viennarna/rnaalifold.py +34 -28
  26. biotite/application/viennarna/rnafold.py +24 -39
  27. biotite/application/viennarna/rnaplot.py +36 -21
  28. biotite/application/viennarna/util.py +17 -12
  29. biotite/application/webapp.py +13 -14
  30. biotite/copyable.py +13 -13
  31. biotite/database/__init__.py +1 -1
  32. biotite/database/entrez/__init__.py +1 -1
  33. biotite/database/entrez/check.py +2 -3
  34. biotite/database/entrez/dbnames.py +7 -5
  35. biotite/database/entrez/download.py +55 -49
  36. biotite/database/entrez/key.py +1 -1
  37. biotite/database/entrez/query.py +62 -23
  38. biotite/database/error.py +2 -1
  39. biotite/database/pubchem/__init__.py +1 -1
  40. biotite/database/pubchem/download.py +43 -45
  41. biotite/database/pubchem/error.py +2 -2
  42. biotite/database/pubchem/query.py +34 -31
  43. biotite/database/pubchem/throttle.py +3 -4
  44. biotite/database/rcsb/__init__.py +1 -1
  45. biotite/database/rcsb/download.py +44 -52
  46. biotite/database/rcsb/query.py +85 -80
  47. biotite/database/uniprot/check.py +6 -3
  48. biotite/database/uniprot/download.py +6 -11
  49. biotite/database/uniprot/query.py +115 -31
  50. biotite/file.py +12 -31
  51. biotite/sequence/__init__.py +3 -3
  52. biotite/sequence/align/__init__.py +2 -2
  53. biotite/sequence/align/alignment.py +99 -90
  54. biotite/sequence/align/banded.cp312-win_amd64.pyd +0 -0
  55. biotite/sequence/align/buckets.py +12 -10
  56. biotite/sequence/align/cigar.py +43 -52
  57. biotite/sequence/align/kmeralphabet.cp312-win_amd64.pyd +0 -0
  58. biotite/sequence/align/kmeralphabet.pyx +55 -51
  59. biotite/sequence/align/kmersimilarity.cp312-win_amd64.pyd +0 -0
  60. biotite/sequence/align/kmertable.cp312-win_amd64.pyd +0 -0
  61. biotite/sequence/align/kmertable.pyx +3 -2
  62. biotite/sequence/align/localgapped.cp312-win_amd64.pyd +0 -0
  63. biotite/sequence/align/localungapped.cp312-win_amd64.pyd +0 -0
  64. biotite/sequence/align/matrix.py +81 -82
  65. biotite/sequence/align/multiple.cp312-win_amd64.pyd +0 -0
  66. biotite/sequence/align/multiple.pyx +1 -1
  67. biotite/sequence/align/pairwise.cp312-win_amd64.pyd +0 -0
  68. biotite/sequence/align/permutation.cp312-win_amd64.pyd +0 -0
  69. biotite/sequence/align/permutation.pyx +12 -4
  70. biotite/sequence/align/selector.cp312-win_amd64.pyd +0 -0
  71. biotite/sequence/align/selector.pyx +52 -54
  72. biotite/sequence/align/statistics.py +32 -33
  73. biotite/sequence/align/tracetable.cp312-win_amd64.pyd +0 -0
  74. biotite/sequence/alphabet.py +51 -65
  75. biotite/sequence/annotation.py +78 -77
  76. biotite/sequence/codec.cp312-win_amd64.pyd +0 -0
  77. biotite/sequence/codon.py +90 -79
  78. biotite/sequence/graphics/__init__.py +1 -1
  79. biotite/sequence/graphics/alignment.py +184 -103
  80. biotite/sequence/graphics/colorschemes.py +10 -12
  81. biotite/sequence/graphics/dendrogram.py +79 -34
  82. biotite/sequence/graphics/features.py +133 -99
  83. biotite/sequence/graphics/logo.py +22 -28
  84. biotite/sequence/graphics/plasmid.py +229 -178
  85. biotite/sequence/io/fasta/__init__.py +1 -1
  86. biotite/sequence/io/fasta/convert.py +44 -33
  87. biotite/sequence/io/fasta/file.py +42 -55
  88. biotite/sequence/io/fastq/__init__.py +1 -1
  89. biotite/sequence/io/fastq/convert.py +11 -14
  90. biotite/sequence/io/fastq/file.py +68 -112
  91. biotite/sequence/io/genbank/__init__.py +2 -2
  92. biotite/sequence/io/genbank/annotation.py +12 -20
  93. biotite/sequence/io/genbank/file.py +74 -76
  94. biotite/sequence/io/genbank/metadata.py +74 -62
  95. biotite/sequence/io/genbank/sequence.py +13 -14
  96. biotite/sequence/io/general.py +39 -30
  97. biotite/sequence/io/gff/__init__.py +2 -2
  98. biotite/sequence/io/gff/convert.py +10 -15
  99. biotite/sequence/io/gff/file.py +81 -65
  100. biotite/sequence/phylo/__init__.py +1 -1
  101. biotite/sequence/phylo/nj.cp312-win_amd64.pyd +0 -0
  102. biotite/sequence/phylo/tree.cp312-win_amd64.pyd +0 -0
  103. biotite/sequence/phylo/upgma.cp312-win_amd64.pyd +0 -0
  104. biotite/sequence/profile.py +57 -28
  105. biotite/sequence/search.py +17 -15
  106. biotite/sequence/seqtypes.py +200 -164
  107. biotite/sequence/sequence.py +15 -17
  108. biotite/structure/__init__.py +3 -3
  109. biotite/structure/atoms.py +246 -236
  110. biotite/structure/basepairs.py +260 -271
  111. biotite/structure/bonds.cp312-win_amd64.pyd +0 -0
  112. biotite/structure/bonds.pyx +29 -32
  113. biotite/structure/box.py +67 -71
  114. biotite/structure/celllist.cp312-win_amd64.pyd +0 -0
  115. biotite/structure/chains.py +55 -39
  116. biotite/structure/charges.cp312-win_amd64.pyd +0 -0
  117. biotite/structure/compare.py +32 -32
  118. biotite/structure/density.py +13 -18
  119. biotite/structure/dotbracket.py +20 -22
  120. biotite/structure/error.py +10 -2
  121. biotite/structure/filter.py +83 -78
  122. biotite/structure/geometry.py +130 -119
  123. biotite/structure/graphics/atoms.py +60 -43
  124. biotite/structure/graphics/rna.py +81 -68
  125. biotite/structure/hbond.py +112 -93
  126. biotite/structure/info/__init__.py +0 -2
  127. biotite/structure/info/atoms.py +10 -11
  128. biotite/structure/info/bonds.py +41 -43
  129. biotite/structure/info/ccd.py +4 -5
  130. biotite/structure/info/groups.py +1 -3
  131. biotite/structure/info/masses.py +5 -10
  132. biotite/structure/info/misc.py +1 -1
  133. biotite/structure/info/radii.py +20 -20
  134. biotite/structure/info/standardize.py +15 -26
  135. biotite/structure/integrity.py +18 -71
  136. biotite/structure/io/__init__.py +3 -4
  137. biotite/structure/io/dcd/__init__.py +1 -1
  138. biotite/structure/io/dcd/file.py +22 -20
  139. biotite/structure/io/general.py +47 -61
  140. biotite/structure/io/gro/__init__.py +1 -1
  141. biotite/structure/io/gro/file.py +73 -72
  142. biotite/structure/io/mol/__init__.py +1 -1
  143. biotite/structure/io/mol/convert.py +8 -11
  144. biotite/structure/io/mol/ctab.py +37 -36
  145. biotite/structure/io/mol/header.py +14 -10
  146. biotite/structure/io/mol/mol.py +9 -53
  147. biotite/structure/io/mol/sdf.py +47 -50
  148. biotite/structure/io/netcdf/__init__.py +1 -1
  149. biotite/structure/io/netcdf/file.py +24 -23
  150. biotite/structure/io/pdb/__init__.py +1 -1
  151. biotite/structure/io/pdb/convert.py +32 -20
  152. biotite/structure/io/pdb/file.py +151 -172
  153. biotite/structure/io/pdb/hybrid36.cp312-win_amd64.pyd +0 -0
  154. biotite/structure/io/pdbqt/__init__.py +1 -1
  155. biotite/structure/io/pdbqt/convert.py +17 -11
  156. biotite/structure/io/pdbqt/file.py +128 -80
  157. biotite/structure/io/pdbx/__init__.py +1 -2
  158. biotite/structure/io/pdbx/bcif.py +36 -44
  159. biotite/structure/io/pdbx/cif.py +140 -110
  160. biotite/structure/io/pdbx/component.py +10 -16
  161. biotite/structure/io/pdbx/convert.py +260 -258
  162. biotite/structure/io/pdbx/encoding.cp312-win_amd64.pyd +0 -0
  163. biotite/structure/io/trajfile.py +90 -107
  164. biotite/structure/io/trr/__init__.py +1 -1
  165. biotite/structure/io/trr/file.py +12 -15
  166. biotite/structure/io/xtc/__init__.py +1 -1
  167. biotite/structure/io/xtc/file.py +11 -14
  168. biotite/structure/mechanics.py +9 -11
  169. biotite/structure/molecules.py +3 -4
  170. biotite/structure/pseudoknots.py +53 -67
  171. biotite/structure/rdf.py +23 -21
  172. biotite/structure/repair.py +137 -86
  173. biotite/structure/residues.py +26 -16
  174. biotite/structure/sasa.cp312-win_amd64.pyd +0 -0
  175. biotite/structure/{resutil.py → segments.py} +24 -23
  176. biotite/structure/sequence.py +10 -11
  177. biotite/structure/sse.py +100 -119
  178. biotite/structure/superimpose.py +39 -77
  179. biotite/structure/transform.py +97 -71
  180. biotite/structure/util.py +11 -13
  181. biotite/version.py +2 -2
  182. biotite/visualize.py +69 -55
  183. {biotite-0.41.2.dist-info → biotite-1.0.1.dist-info}/METADATA +6 -5
  184. biotite-1.0.1.dist-info/RECORD +322 -0
  185. biotite/structure/io/ctab.py +0 -72
  186. biotite/structure/io/mmtf/__init__.py +0 -21
  187. biotite/structure/io/mmtf/assembly.py +0 -214
  188. biotite/structure/io/mmtf/convertarray.cp312-win_amd64.pyd +0 -0
  189. biotite/structure/io/mmtf/convertarray.pyx +0 -341
  190. biotite/structure/io/mmtf/convertfile.cp312-win_amd64.pyd +0 -0
  191. biotite/structure/io/mmtf/convertfile.pyx +0 -501
  192. biotite/structure/io/mmtf/decode.cp312-win_amd64.pyd +0 -0
  193. biotite/structure/io/mmtf/decode.pyx +0 -152
  194. biotite/structure/io/mmtf/encode.cp312-win_amd64.pyd +0 -0
  195. biotite/structure/io/mmtf/encode.pyx +0 -183
  196. biotite/structure/io/mmtf/file.py +0 -233
  197. biotite/structure/io/npz/__init__.py +0 -20
  198. biotite/structure/io/npz/file.py +0 -152
  199. biotite/structure/io/pdbx/legacy.py +0 -267
  200. biotite/structure/io/tng/__init__.py +0 -13
  201. biotite/structure/io/tng/file.py +0 -46
  202. biotite/temp.py +0 -86
  203. biotite-0.41.2.dist-info/RECORD +0 -340
  204. {biotite-0.41.2.dist-info → biotite-1.0.1.dist-info}/WHEEL +0 -0
  205. {biotite-0.41.2.dist-info → biotite-1.0.1.dist-info}/licenses/LICENSE.rst +0 -0
@@ -9,20 +9,25 @@ that can be applied on structures.
9
9
 
10
10
  __name__ = "biotite.structure"
11
11
  __author__ = "Patrick Kunzmann", "Claude J. Rogers"
12
- __all__ = ["translate", "rotate", "rotate_centered", "rotate_about_axis",
13
- "orient_principal_components", "align_vectors"]
12
+ __all__ = [
13
+ "translate",
14
+ "rotate",
15
+ "rotate_centered",
16
+ "rotate_about_axis",
17
+ "orient_principal_components",
18
+ "align_vectors",
19
+ ]
14
20
 
15
21
  import numpy as np
16
- from .geometry import centroid
17
- from .error import BadStructureError
18
- from .atoms import Atom, AtomArray, AtomArrayStack, coord
19
- from .util import norm_vector, vector_dot, matrix_rotate
22
+ from biotite.structure.atoms import Atom, AtomArray, AtomArrayStack, coord
23
+ from biotite.structure.geometry import centroid
24
+ from biotite.structure.util import matrix_rotate, norm_vector, vector_dot
20
25
 
21
26
 
22
27
  def translate(atoms, vector):
23
28
  """
24
29
  Translate the given atoms or coordinates by a given vector.
25
-
30
+
26
31
  Parameters
27
32
  ----------
28
33
  atoms : Atom or AtomArray or AtomArrayStack or ndarray, shape=(3,) or shape=(n,3) or shape=(m,n,3)
@@ -30,7 +35,7 @@ def translate(atoms, vector):
30
35
  The coordinates can be directly provided as :class:`ndarray`.
31
36
  vector: array-like, shape=(3,) or shape=(n,3) or shape=(m,n,3)
32
37
  The translation vector :math:`(x, y, z)`.
33
-
38
+
34
39
  Returns
35
40
  -------
36
41
  transformed : Atom or AtomArray or AtomArrayStack or ndarray, shape=(3,) or shape=(n,3) or shape=(m,n,3)
@@ -39,7 +44,7 @@ def translate(atoms, vector):
39
44
  """
40
45
  positions = coord(atoms).copy()
41
46
  vector = np.asarray(vector)
42
-
47
+
43
48
  if vector.shape[-1] != 3:
44
49
  raise ValueError("Translation vector must contain 3 coordinates")
45
50
  positions += vector
@@ -50,10 +55,10 @@ def rotate(atoms, angles):
50
55
  """
51
56
  Rotate the given atoms or coordinates about the *x*, *y* and *z*
52
57
  axes by given angles.
53
-
58
+
54
59
  The rotations are centered at the origin and are performed
55
60
  sequentially in the order *x*, *y*, *z*.
56
-
61
+
57
62
  Parameters
58
63
  ----------
59
64
  atoms : Atom or AtomArray or AtomArrayStack or ndarray, shape=(3,) or shape=(n,3) or shape=(m,n,3)
@@ -61,13 +66,13 @@ def rotate(atoms, angles):
61
66
  The coordinates can be directly provided as :class:`ndarray`.
62
67
  angles: array-like, length=3
63
68
  The rotation angles in radians around *x*, *y* and *z*.
64
-
69
+
65
70
  Returns
66
71
  -------
67
72
  transformed : Atom or AtomArray or AtomArrayStack or ndarray, shape=(3,) or shape=(n,3) or shape=(m,n,3)
68
73
  A copy of the input atoms or coordinates, rotated by the given
69
74
  angles.
70
-
75
+
71
76
  See Also
72
77
  --------
73
78
  rotate_centered
@@ -82,27 +87,39 @@ def rotate(atoms, angles):
82
87
  >>> print(rotated)
83
88
  [1.225e-16 2.000e+00 0.000e+00]
84
89
  """
85
- from numpy import sin, cos
90
+ from numpy import cos, sin
86
91
 
87
92
  # Check if "angles" contains 3 angles for all dimensions
88
93
  if len(angles) != 3:
89
94
  raise ValueError("Translation vector must be container of length 3")
90
95
  # Create rotation matrices for all 3 dimensions
91
- rot_x = np.array([[ 1, 0, 0 ],
92
- [ 0, cos(angles[0]), -sin(angles[0]) ],
93
- [ 0, sin(angles[0]), cos(angles[0]) ]])
94
-
95
- rot_y = np.array([[ cos(angles[1]), 0, sin(angles[1]) ],
96
- [ 0, 1, 0 ],
97
- [ -sin(angles[1]), 0, cos(angles[1]) ]])
98
-
99
- rot_z = np.array([[ cos(angles[2]), -sin(angles[2]), 0 ],
100
- [ sin(angles[2]), cos(angles[2]), 0 ],
101
- [ 0, 0, 1 ]])
102
-
96
+ rot_x = np.array(
97
+ [
98
+ [1, 0, 0],
99
+ [0, cos(angles[0]), -sin(angles[0])],
100
+ [0, sin(angles[0]), cos(angles[0])],
101
+ ]
102
+ )
103
+
104
+ rot_y = np.array(
105
+ [
106
+ [cos(angles[1]), 0, sin(angles[1])],
107
+ [0, 1, 0],
108
+ [-sin(angles[1]), 0, cos(angles[1])],
109
+ ]
110
+ )
111
+
112
+ rot_z = np.array(
113
+ [
114
+ [cos(angles[2]), -sin(angles[2]), 0],
115
+ [sin(angles[2]), cos(angles[2]), 0],
116
+ [0, 0, 1],
117
+ ]
118
+ )
119
+
103
120
  positions = coord(atoms).copy()
104
121
  positions = matrix_rotate(positions, rot_z @ rot_y @ rot_x)
105
-
122
+
106
123
  return _put_back(atoms, positions)
107
124
 
108
125
 
@@ -110,10 +127,10 @@ def rotate_centered(atoms, angles):
110
127
  """
111
128
  Rotate the given atoms or coordinates about the *x*, *y* and *z*
112
129
  axes by given angles.
113
-
130
+
114
131
  The rotations are centered at the centroid of the corresponding
115
132
  structure and are performed sequentially in the order *x*, *y*, *z*.
116
-
133
+
117
134
  Parameters
118
135
  ----------
119
136
  atoms : Atom or AtomArray or AtomArrayStack or ndarray, shape=(3,) or shape=(n,3) or shape=(m,n,3)
@@ -121,13 +138,13 @@ def rotate_centered(atoms, angles):
121
138
  The coordinates can be directly provided as :class:`ndarray`.
122
139
  angles: array-like, length=3
123
140
  The rotation angles in radians around axes *x*, *y* and *z*.
124
-
141
+
125
142
  Returns
126
143
  -------
127
144
  transformed : Atom or AtomArray or AtomArrayStack or ndarray, shape=(3,) or shape=(n,3) or shape=(m,n,3)
128
145
  A copy of the input atoms or coordinates, rotated by the given
129
146
  angles.
130
-
147
+
131
148
  See Also
132
149
  --------
133
150
  rotate
@@ -136,7 +153,7 @@ def rotate_centered(atoms, angles):
136
153
  if len(coord(atoms).shape) == 1:
137
154
  # Single value -> centered rotation does not change coordinates
138
155
  return atoms.copy()
139
-
156
+
140
157
  # Rotation around centroid requires moving centroid to origin
141
158
  center = coord(centroid(atoms))
142
159
  # 'centroid()' removes the second last dimesion
@@ -152,7 +169,7 @@ def rotate_about_axis(atoms, axis, angle, support=None):
152
169
  """
153
170
  Rotate the given atoms or coordinates about a given axis by a given
154
171
  angle.
155
-
172
+
156
173
  Parameters
157
174
  ----------
158
175
  atoms : Atom or AtomArray or AtomArrayStack or ndarray, shape=(3,) or shape=(n,3) or shape=(m,n,3)
@@ -167,13 +184,13 @@ def rotate_about_axis(atoms, axis, angle, support=None):
167
184
  An optional support vector for the rotation axis, i.e. the
168
185
  center of the rotation.
169
186
  By default, the center of the rotation is at *(0,0,0)*.
170
-
187
+
171
188
  Returns
172
189
  -------
173
190
  transformed : Atom or AtomArray or AtomArrayStack or ndarray, shape=(3,) or shape=(n,3) or shape=(m,n,3)
174
191
  A copy of the input atoms or coordinates, rotated about the
175
192
  given axis.
176
-
193
+
177
194
  See Also
178
195
  --------
179
196
  rotate
@@ -194,7 +211,7 @@ def rotate_about_axis(atoms, axis, angle, support=None):
194
211
  # Transform coordinates
195
212
  # so that the axis support vector is at (0,0,0)
196
213
  positions -= np.asarray(support)
197
-
214
+
198
215
  # Normalize axis
199
216
  axis = np.asarray(axis, dtype=np.float32).copy()
200
217
  if np.linalg.norm(axis) == 0:
@@ -205,16 +222,30 @@ def rotate_about_axis(atoms, axis, angle, support=None):
205
222
  sin_a = np.sin(angle)
206
223
  cos_a = np.cos(angle)
207
224
  icos_a = 1 - cos_a
208
- x = axis[...,0]
209
- y = axis[...,1]
210
- z = axis[...,2]
225
+ x = axis[..., 0]
226
+ y = axis[..., 1]
227
+ z = axis[..., 2]
211
228
  # Rotation matrix is taken from
212
229
  # https://en.wikipedia.org/wiki/Rotation_matrix#Rotation_matrix_from_axis_and_angle
213
- rot_matrix = np.array([
214
- [ cos_a + icos_a*x**2, icos_a*x*y - z*sin_a, icos_a*x*z + y*sin_a],
215
- [icos_a*x*y + z*sin_a, cos_a + icos_a*y**2, icos_a*y*z - x*sin_a],
216
- [icos_a*x*z - y*sin_a, icos_a*y*z + x*sin_a, cos_a + icos_a*z**2]
217
- ])
230
+ rot_matrix = np.array(
231
+ [
232
+ [
233
+ cos_a + icos_a * x**2,
234
+ icos_a * x * y - z * sin_a,
235
+ icos_a * x * z + y * sin_a,
236
+ ],
237
+ [
238
+ icos_a * x * y + z * sin_a,
239
+ cos_a + icos_a * y**2,
240
+ icos_a * y * z - x * sin_a,
241
+ ],
242
+ [
243
+ icos_a * x * z - y * sin_a,
244
+ icos_a * y * z + x * sin_a,
245
+ cos_a + icos_a * z**2,
246
+ ],
247
+ ]
248
+ )
218
249
 
219
250
  # For proper rotation reshape into a maximum of 2 dimensions
220
251
  orig_ndim = positions.ndim
@@ -230,7 +261,7 @@ def rotate_about_axis(atoms, axis, angle, support=None):
230
261
  if support is not None:
231
262
  # Transform coordinates back to original support vector position
232
263
  positions += np.asarray(support)
233
-
264
+
234
265
  return _put_back(atoms, positions)
235
266
 
236
267
 
@@ -298,9 +329,7 @@ def orient_principal_components(atoms, order=None):
298
329
  else:
299
330
  order = np.asarray(order, dtype=int)
300
331
  if order.shape != (3,):
301
- raise ValueError(
302
- f"Expected order to have shape (3,), not {order.shape}"
303
- )
332
+ raise ValueError(f"Expected order to have shape (3,), not {order.shape}")
304
333
  if not (np.sort(order) == np.arange(3)).all():
305
334
  raise ValueError("Expected order to contain [0, 1, 2].")
306
335
 
@@ -333,8 +362,13 @@ def orient_principal_components(atoms, order=None):
333
362
  return _put_back(atoms, centered)
334
363
 
335
364
 
336
- def align_vectors(atoms, origin_direction, target_direction,
337
- origin_position=None, target_position=None):
365
+ def align_vectors(
366
+ atoms,
367
+ origin_direction,
368
+ target_direction,
369
+ origin_position=None,
370
+ target_position=None,
371
+ ):
338
372
  """
339
373
  Apply a transformation to atoms or coordinates, that would transfer
340
374
  a origin vector to a target vector.
@@ -345,8 +379,8 @@ def align_vectors(atoms, origin_direction, target_direction,
345
379
  This means, that the application of the transformation on the
346
380
  origin vector would give the target vector.
347
381
  Then the same transformation is applied to the given
348
- atoms/coordinates.
349
-
382
+ atoms/coordinates.
383
+
350
384
  Parameters
351
385
  ----------
352
386
  atoms : Atom or AtomArray or AtomArrayStack or ndarray, shape=(3,) or shape=(n,3) or shape=(m,n,3)
@@ -359,13 +393,13 @@ def align_vectors(atoms, origin_direction, target_direction,
359
393
  origin_position, target_position : array-like, length=3, optional
360
394
  Optional support vectors for the origin or target, respectively.
361
395
  By default, origin and target start at *(0,0,0)*.
362
-
396
+
363
397
  Returns
364
398
  -------
365
399
  transformed : Atom or AtomArray or AtomArrayStack or ndarray, shape=(3,) or shape=(n,3) or shape=(m,n,3)
366
400
  A copy of the input atoms or coordinates with the applied
367
401
  transformation.
368
-
402
+
369
403
  See Also
370
404
  --------
371
405
  rotate
@@ -428,12 +462,8 @@ def align_vectors(atoms, origin_direction, target_direction,
428
462
  A 2 LEU HD22 H -6.255 7.544 -2.657
429
463
  A 2 LEU HD23 H -5.592 8.445 -1.281
430
464
  """
431
- origin_direction = np.asarray(
432
- origin_direction, dtype=np.float32
433
- ).squeeze()
434
- target_direction = np.asarray(
435
- target_direction, dtype=np.float32
436
- ).squeeze()
465
+ origin_direction = np.asarray(origin_direction, dtype=np.float32).squeeze()
466
+ target_direction = np.asarray(target_direction, dtype=np.float32).squeeze()
437
467
  # check that original and target direction are vectors of shape (3,)
438
468
  if origin_direction.shape != (3,):
439
469
  raise ValueError(
@@ -449,9 +479,9 @@ def align_vectors(atoms, origin_direction, target_direction,
449
479
  raise ValueError("Length of the origin vector is 0")
450
480
  if np.linalg.norm(target_direction) == 0:
451
481
  raise ValueError("Length of the target vector is 0")
452
- if origin_position is not None:
482
+ if origin_position is not None:
453
483
  origin_position = np.asarray(origin_position, dtype=np.float32)
454
- if target_position is not None:
484
+ if target_position is not None:
455
485
  target_position = np.asarray(target_position, dtype=np.float32)
456
486
 
457
487
  positions = coord(atoms).copy()
@@ -459,7 +489,7 @@ def align_vectors(atoms, origin_direction, target_direction,
459
489
  # Transform coordinates
460
490
  # so that the position of the origin vector is at (0,0,0)
461
491
  positions -= origin_position
462
-
492
+
463
493
  # Normalize direction vectors
464
494
  origin_direction = origin_direction.copy()
465
495
  norm_vector(origin_direction)
@@ -468,11 +498,7 @@ def align_vectors(atoms, origin_direction, target_direction,
468
498
  # Formula is taken from
469
499
  # https://math.stackexchange.com/questions/180418/calculate-rotation-matrix-to-align-vector-a-to-vector-b-in-3d/476311#476311
470
500
  vx, vy, vz = np.cross(origin_direction, target_direction)
471
- v_c = np.array([
472
- [ 0, -vz, vy],
473
- [ vz, 0, -vx],
474
- [-vy, vx, 0]
475
- ], dtype=float)
501
+ v_c = np.array([[0, -vz, vy], [vz, 0, -vx], [-vy, vx, 0]], dtype=float)
476
502
  cos_a = vector_dot(origin_direction, target_direction)
477
503
  if np.all(cos_a == -1):
478
504
  raise ValueError(
@@ -480,9 +506,9 @@ def align_vectors(atoms, origin_direction, target_direction,
480
506
  "cannot calculate rotation matrix"
481
507
  )
482
508
  rot_matrix = np.identity(3) + v_c + (v_c @ v_c) / (1 + cos_a)
483
-
509
+
484
510
  positions = matrix_rotate(positions, rot_matrix)
485
-
511
+
486
512
  if target_position is not None:
487
513
  # Transform coordinates to position of the target vector
488
514
  positions += target_position
@@ -501,4 +527,4 @@ def _put_back(input_atoms, transformed):
501
527
  moved_atoms.coord = transformed
502
528
  return moved_atoms
503
529
  else:
504
- return transformed
530
+ return transformed
biotite/structure/util.py CHANGED
@@ -11,31 +11,30 @@ __author__ = "Patrick Kunzmann"
11
11
  __all__ = ["vector_dot", "norm_vector", "distance", "matrix_rotate"]
12
12
 
13
13
  import numpy as np
14
- from .atoms import Atom, array
15
14
 
16
15
 
17
- def vector_dot(v1,v2):
16
+ def vector_dot(v1, v2):
18
17
  """
19
18
  Calculate vector dot product of two vectors.
20
-
19
+
21
20
  Parameters
22
21
  ----------
23
22
  v1,v2 : ndarray
24
23
  The arrays to calculate the product from.
25
24
  The vectors are represented by the last axis.
26
-
25
+
27
26
  Returns
28
27
  -------
29
28
  product : float or ndarray
30
29
  Scalar product over the last dimension of the arrays.
31
30
  """
32
- return (v1*v2).sum(axis=-1)
31
+ return (v1 * v2).sum(axis=-1)
33
32
 
34
33
 
35
34
  def norm_vector(v):
36
35
  """
37
36
  Normalise a vector.
38
-
37
+
39
38
  Parameters
40
39
  ----------
41
40
  v : ndarray
@@ -47,25 +46,25 @@ def norm_vector(v):
47
46
  v /= factor[..., np.newaxis]
48
47
  else:
49
48
  v /= factor
50
-
51
49
 
52
- def distance(v1,v2):
50
+
51
+ def distance(v1, v2):
53
52
  """
54
53
  Calculate the distance between two position vectors.
55
-
54
+
56
55
  Parameters
57
56
  ----------
58
57
  v1,v2 : ndarray
59
58
  The arrays to calculate the product from.
60
59
  The vectors are represented by the last axis.
61
-
60
+
62
61
  Returns
63
62
  -------
64
63
  product : float or ndarray
65
64
  Vector distance over the last dimension of the array.
66
65
  """
67
66
  dif = v1 - v2
68
- return np.sqrt((dif*dif).sum(axis=-1))
67
+ return np.sqrt((dif * dif).sum(axis=-1))
69
68
 
70
69
 
71
70
  def matrix_rotate(v, matrix):
@@ -78,7 +77,7 @@ def matrix_rotate(v, matrix):
78
77
  The coordinates to rotate.
79
78
  matrix : ndarray
80
79
  The rotation matrix.
81
-
80
+
82
81
  Returns
83
82
  -------
84
83
  rotated : ndarray
@@ -95,4 +94,3 @@ def matrix_rotate(v, matrix):
95
94
  if orig_ndim > 2:
96
95
  v = v.reshape(*orig_shape)
97
96
  return v
98
-
biotite/version.py CHANGED
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '0.41.2'
16
- __version_tuple__ = version_tuple = (0, 41, 2)
15
+ __version__ = version = '1.0.1'
16
+ __version_tuple__ = version_tuple = (1, 0, 1)
biotite/visualize.py CHANGED
@@ -6,25 +6,25 @@ __name__ = "biotite"
6
6
  __author__ = "Patrick Kunzmann"
7
7
  __all__ = ["colors", "set_font_size_in_coord", "AdaptiveFancyArrow"]
8
8
 
9
- import abc
10
9
  from collections import OrderedDict
11
10
  import numpy as np
12
11
  from numpy.linalg import norm
13
12
 
14
-
15
13
  # Biotite themed colors
16
- colors = OrderedDict([
17
- ("brightorange" , "#ffb569ff"),
18
- ("lightorange" , "#ff982dff"),
19
- ("orange" , "#ff8405ff"),
20
- ("dimorange" , "#dc7000ff"),
21
- ("darkorange" , "#b45c00ff"),
22
- ("brightgreen" , "#98e97fff"),
23
- ("lightgreen" , "#6fe04cff"),
24
- ("green" , "#52da2aff"),
25
- ("dimgreen" , "#45bc20ff"),
26
- ("darkgreen" , "#389a1aff"),
27
- ])
14
+ colors = OrderedDict(
15
+ [
16
+ ("brightorange", "#ffb569ff"),
17
+ ("lightorange", "#ff982dff"),
18
+ ("orange", "#ff8405ff"),
19
+ ("dimorange", "#dc7000ff"),
20
+ ("darkorange", "#b45c00ff"),
21
+ ("brightgreen", "#98e97fff"),
22
+ ("lightgreen", "#6fe04cff"),
23
+ ("green", "#52da2aff"),
24
+ ("dimgreen", "#45bc20ff"),
25
+ ("darkgreen", "#389a1aff"),
26
+ ]
27
+ )
28
28
 
29
29
 
30
30
  def set_font_size_in_coord(text, width=None, height=None, mode="unlocked"):
@@ -75,8 +75,8 @@ def set_font_size_in_coord(text, width=None, height=None, mode="unlocked"):
75
75
  This behavior is not equal for all initial font sizes (in 'pt'),
76
76
  the boundaries for an initial size of 1 'pt' seem to be most exact.
77
77
  """
78
- from matplotlib.transforms import Bbox, Affine2D
79
78
  from matplotlib.patheffects import AbstractPathEffect
79
+ from matplotlib.transforms import Affine2D, Bbox
80
80
 
81
81
  class TextScaler(AbstractPathEffect):
82
82
  def __init__(self, text, width, height, mode):
@@ -85,11 +85,11 @@ def set_font_size_in_coord(text, width=None, height=None, mode="unlocked"):
85
85
  self._width = width
86
86
  self._height = height
87
87
 
88
- def draw_path(self, renderer, gc, tpath, affine, rgbFace=None):
88
+ def draw_path(self, renderer, gc, tpath, affine, rgbFace=None): # noqa: N803
89
89
  ax = self._text.axes
90
90
  try:
91
91
  renderer = ax.get_figure().canvas.get_renderer()
92
- except:
92
+ except Exception:
93
93
  # Use cached renderer for backends, where
94
94
  # `get_renderer()` is not available
95
95
  # Based on the strategy from `Text.get_window_extent()`
@@ -127,25 +127,21 @@ def set_font_size_in_coord(text, width=None, height=None, mode="unlocked"):
127
127
 
128
128
  if mode in ["unlocked", "minimum", "maximum"]:
129
129
  if width is None or height is None:
130
- raise TypeError(
131
- f"Width and height must be set in '{mode}' mode"
132
- )
130
+ raise TypeError(f"Width and height must be set in '{mode}' mode")
133
131
  elif mode == "proportional":
134
- if not (width is None and height is not None) or \
135
- not (height is None and width is not None):
136
- raise TypeError(
137
- f"Either width or height must be set in '{mode}' mode"
138
- )
132
+ if not (width is None and height is not None) or not (
133
+ height is None and width is not None
134
+ ):
135
+ raise TypeError(f"Either width or height must be set in '{mode}' mode")
139
136
  else:
140
- raise ValueError(
141
- f"Unknown mode '{mode}'"
142
- )
137
+ raise ValueError(f"Unknown mode '{mode}'")
143
138
  text.set_path_effects([TextScaler(text, width, height, mode)])
144
139
 
140
+
145
141
  try:
146
142
  # Only create this class when matplotlib is installed
147
- from matplotlib.transforms import Bbox
148
143
  from matplotlib.patches import FancyArrow
144
+ from matplotlib.transforms import Bbox
149
145
 
150
146
  class AdaptiveFancyArrow(FancyArrow):
151
147
  """
@@ -177,9 +173,19 @@ try:
177
173
  `FancyArrow`.
178
174
  """
179
175
 
180
- def __init__(self, x, y, dx, dy,
181
- tail_width, head_width, head_ratio, draw_head=True,
182
- shape="full", **kwargs):
176
+ def __init__(
177
+ self,
178
+ x,
179
+ y,
180
+ dx,
181
+ dy,
182
+ tail_width,
183
+ head_width,
184
+ head_ratio,
185
+ draw_head=True,
186
+ shape="full",
187
+ **kwargs,
188
+ ):
183
189
  self._x = x
184
190
  self._y = y
185
191
  self._dx = dx
@@ -193,23 +199,25 @@ try:
193
199
  if not draw_head:
194
200
  head_width = tail_width
195
201
  super().__init__(
196
- x, y, dx, dy,
197
- width=tail_width, head_width=head_width,
198
- overhang=0, shape=shape,
199
- length_includes_head=True, **kwargs
202
+ x,
203
+ y,
204
+ dx,
205
+ dy,
206
+ width=tail_width,
207
+ head_width=head_width,
208
+ overhang=0,
209
+ shape=shape,
210
+ length_includes_head=True,
211
+ **kwargs,
200
212
  )
201
213
 
202
214
  def draw(self, renderer):
203
- arrow_box = Bbox([(0,0), (0,self._head_width)])
215
+ arrow_box = Bbox([(0, 0), (0, self._head_width)])
204
216
  arrow_box_display = self.axes.transData.transform_bbox(arrow_box)
205
- head_length_display = np.abs(
206
- arrow_box_display.height * self._head_ratio
207
- )
217
+ head_length_display = np.abs(arrow_box_display.height * self._head_ratio)
208
218
  arrow_box_display.x1 = arrow_box_display.x0 + head_length_display
209
219
  # Transfrom back to data coordinates for plotting
210
- arrow_box = self.axes.transData.inverted().transform_bbox(
211
- arrow_box_display
212
- )
220
+ arrow_box = self.axes.transData.inverted().transform_bbox(arrow_box_display)
213
221
  head_length = arrow_box.width
214
222
  arrow_length = norm((self._dx, self._dy))
215
223
  if head_length > arrow_length:
@@ -221,11 +229,19 @@ try:
221
229
 
222
230
  # Renew the arrow's properties
223
231
  super().__init__(
224
- self._x, self._y, self._dx, self._dy,
225
- width=self._tail_width, head_width=self._head_width,
226
- overhang=0, shape=self._shape,
227
- head_length=head_length, length_includes_head=True,
228
- axes=self.axes, transform=self.get_transform(), **self._kwargs
232
+ self._x,
233
+ self._y,
234
+ self._dx,
235
+ self._dy,
236
+ width=self._tail_width,
237
+ head_width=self._head_width,
238
+ overhang=0,
239
+ shape=self._shape,
240
+ head_length=head_length,
241
+ length_includes_head=True,
242
+ axes=self.axes,
243
+ transform=self.get_transform(),
244
+ **self._kwargs,
229
245
  )
230
246
  self.set_clip_path(self.axes.patch)
231
247
  super().draw(renderer)
@@ -234,18 +250,16 @@ try:
234
250
  # Removes warning:
235
251
  # unknown document: /tutorials/intermediate/constrainedlayout_guide
236
252
  def get_in_layout(self):
237
- """
238
- """
253
+ """ """
239
254
  return super().get_in_layout()
255
+
240
256
  def set_in_layout(self, in_layout):
241
- """
242
- """
257
+ """ """
243
258
  return super().set_in_layout(in_layout)
244
259
 
245
260
  except ImportError:
246
-
247
261
  # Dummy class that propagates a meaningful error,
248
262
  # i.e. that Matplotlib is not installed
249
- class AdaptiveFancyArrow():
263
+ class AdaptiveFancyArrow:
250
264
  def __init__(*args, **kwargs):
251
- raise ModuleNotFoundError(f"No module named 'matplotlib'")
265
+ raise ModuleNotFoundError("No module named 'matplotlib'")