biotite 0.41.1__cp310-cp310-win_amd64.whl → 1.0.0__cp310-cp310-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 +36 -10
  3. biotite/application/application.py +22 -11
  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 +16 -5
  52. biotite/sequence/align/__init__.py +160 -6
  53. biotite/sequence/align/alignment.py +99 -90
  54. biotite/sequence/align/banded.cp310-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.cp310-win_amd64.pyd +0 -0
  58. biotite/sequence/align/kmeralphabet.pyx +55 -51
  59. biotite/sequence/align/kmersimilarity.cp310-win_amd64.pyd +0 -0
  60. biotite/sequence/align/kmertable.cp310-win_amd64.pyd +0 -0
  61. biotite/sequence/align/kmertable.pyx +3 -2
  62. biotite/sequence/align/localgapped.cp310-win_amd64.pyd +0 -0
  63. biotite/sequence/align/localungapped.cp310-win_amd64.pyd +0 -0
  64. biotite/sequence/align/matrix.py +81 -82
  65. biotite/sequence/align/multiple.cp310-win_amd64.pyd +0 -0
  66. biotite/sequence/align/multiple.pyx +35 -35
  67. biotite/sequence/align/pairwise.cp310-win_amd64.pyd +0 -0
  68. biotite/sequence/align/permutation.cp310-win_amd64.pyd +0 -0
  69. biotite/sequence/align/permutation.pyx +12 -4
  70. biotite/sequence/align/selector.cp310-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.cp310-win_amd64.pyd +0 -0
  74. biotite/sequence/alphabet.py +112 -126
  75. biotite/sequence/annotation.py +78 -77
  76. biotite/sequence/codec.cp310-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.cp310-win_amd64.pyd +0 -0
  102. biotite/sequence/phylo/tree.cp310-win_amd64.pyd +0 -0
  103. biotite/sequence/phylo/upgma.cp310-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 +64 -64
  108. biotite/structure/__init__.py +3 -3
  109. biotite/structure/atoms.py +226 -240
  110. biotite/structure/basepairs.py +260 -271
  111. biotite/structure/bonds.cp310-win_amd64.pyd +0 -0
  112. biotite/structure/bonds.pyx +88 -100
  113. biotite/structure/box.py +67 -71
  114. biotite/structure/celllist.cp310-win_amd64.pyd +0 -0
  115. biotite/structure/chains.py +55 -39
  116. biotite/structure/charges.cp310-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 +82 -77
  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 +21 -7
  130. biotite/structure/info/groups.py +10 -15
  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.cp310-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 -52
  159. biotite/structure/io/pdbx/cif.py +64 -62
  160. biotite/structure/io/pdbx/component.py +10 -16
  161. biotite/structure/io/pdbx/convert.py +235 -246
  162. biotite/structure/io/pdbx/encoding.cp310-win_amd64.pyd +0 -0
  163. biotite/structure/io/trajfile.py +76 -93
  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.cp310-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.1.dist-info → biotite-1.0.0.dist-info}/METADATA +6 -6
  184. biotite-1.0.0.dist-info/RECORD +322 -0
  185. {biotite-0.41.1.dist-info → biotite-1.0.0.dist-info}/WHEEL +1 -1
  186. biotite/structure/io/ctab.py +0 -72
  187. biotite/structure/io/mmtf/__init__.py +0 -21
  188. biotite/structure/io/mmtf/assembly.py +0 -214
  189. biotite/structure/io/mmtf/convertarray.cp310-win_amd64.pyd +0 -0
  190. biotite/structure/io/mmtf/convertarray.pyx +0 -341
  191. biotite/structure/io/mmtf/convertfile.cp310-win_amd64.pyd +0 -0
  192. biotite/structure/io/mmtf/convertfile.pyx +0 -501
  193. biotite/structure/io/mmtf/decode.cp310-win_amd64.pyd +0 -0
  194. biotite/structure/io/mmtf/decode.pyx +0 -152
  195. biotite/structure/io/mmtf/encode.cp310-win_amd64.pyd +0 -0
  196. biotite/structure/io/mmtf/encode.pyx +0 -183
  197. biotite/structure/io/mmtf/file.py +0 -233
  198. biotite/structure/io/npz/__init__.py +0 -20
  199. biotite/structure/io/npz/file.py +0 -152
  200. biotite/structure/io/pdbx/legacy.py +0 -267
  201. biotite/structure/io/tng/__init__.py +0 -13
  202. biotite/structure/io/tng/file.py +0 -46
  203. biotite/temp.py +0 -86
  204. biotite-0.41.1.dist-info/RECORD +0 -340
  205. {biotite-0.41.1.dist-info → biotite-1.0.0.dist-info}/licenses/LICENSE.rst +0 -0
Binary file
@@ -85,8 +85,8 @@ class BondType(IntEnum):
85
85
  Examples
86
86
  --------
87
87
 
88
- >>> print(BondType.AROMATIC_DOUBLE.without_aromaticity())
89
- BondType.DOUBLE
88
+ >>> print(BondType.AROMATIC_DOUBLE.without_aromaticity().name)
89
+ DOUBLE
90
90
  """
91
91
  difference = BondType.AROMATIC_SINGLE - BondType.SINGLE
92
92
  if self >= BondType.AROMATIC_SINGLE:
@@ -212,21 +212,21 @@ class BondList(Copyable):
212
212
  ... )
213
213
  >>> for i, j, bond_type in benzene.bonds.as_array():
214
214
  ... print(
215
- ... f"{str(BondType(bond_type))} bond between "
215
+ ... f"{BondType(bond_type).name} bond between "
216
216
  ... f"{benzene.atom_name[i]} and {benzene.atom_name[j]}"
217
217
  ... )
218
- BondType.AROMATIC_SINGLE bond between C1 and C2
219
- BondType.AROMATIC_DOUBLE bond between C2 and C3
220
- BondType.AROMATIC_SINGLE bond between C3 and C4
221
- BondType.AROMATIC_DOUBLE bond between C4 and C5
222
- BondType.AROMATIC_SINGLE bond between C5 and C6
223
- BondType.AROMATIC_DOUBLE bond between C1 and C6
224
- BondType.SINGLE bond between C1 and H1
225
- BondType.SINGLE bond between C2 and H2
226
- BondType.SINGLE bond between C3 and H3
227
- BondType.SINGLE bond between C4 and H4
228
- BondType.SINGLE bond between C5 and H5
229
- BondType.SINGLE bond between C6 and H6
218
+ AROMATIC_SINGLE bond between C1 and C2
219
+ AROMATIC_DOUBLE bond between C2 and C3
220
+ AROMATIC_SINGLE bond between C3 and C4
221
+ AROMATIC_DOUBLE bond between C4 and C5
222
+ AROMATIC_SINGLE bond between C5 and C6
223
+ AROMATIC_DOUBLE bond between C1 and C6
224
+ SINGLE bond between C1 and H1
225
+ SINGLE bond between C2 and H2
226
+ SINGLE bond between C3 and H3
227
+ SINGLE bond between C4 and H4
228
+ SINGLE bond between C5 and H5
229
+ SINGLE bond between C6 and H6
230
230
 
231
231
  Obtain the bonded atoms for the :math:`C_1`:
232
232
 
@@ -248,14 +248,14 @@ class BondList(Copyable):
248
248
  ... ]
249
249
  >>> for i, j, bond_type in half_benzene.bonds.as_array():
250
250
  ... print(
251
- ... f"{str(BondType(bond_type))} bond between "
251
+ ... f"{BondType(bond_type).name} bond between "
252
252
  ... f"{half_benzene.atom_name[i]} and {half_benzene.atom_name[j]}"
253
253
  ... )
254
- BondType.AROMATIC_DOUBLE bond between C4 and C5
255
- BondType.AROMATIC_SINGLE bond between C5 and C6
256
- BondType.SINGLE bond between C4 and H4
257
- BondType.SINGLE bond between C5 and H5
258
- BondType.SINGLE bond between C6 and H6
254
+ AROMATIC_DOUBLE bond between C4 and C5
255
+ AROMATIC_SINGLE bond between C5 and C6
256
+ SINGLE bond between C4 and H4
257
+ SINGLE bond between C5 and H5
258
+ SINGLE bond between C6 and H6
259
259
  """
260
260
 
261
261
  def __init__(self, uint32 atom_count, np.ndarray bonds=None):
@@ -449,9 +449,9 @@ class BondList(Copyable):
449
449
  >>> bond_list.add_bond(1, 2, BondType.AROMATIC_DOUBLE)
450
450
  >>> bond_list.remove_aromaticity()
451
451
  >>> for i, j, bond_type in bond_list.as_array():
452
- ... print(i, j, BondType(bond_type))
453
- 0 1 BondType.SINGLE
454
- 1 2 BondType.DOUBLE
452
+ ... print(i, j, BondType(bond_type).name)
453
+ 0 1 SINGLE
454
+ 1 2 DOUBLE
455
455
  """
456
456
  bonds = self._bonds
457
457
  difference = BondType.AROMATIC_SINGLE - BondType.SINGLE
@@ -1005,14 +1005,13 @@ class BondList(Copyable):
1005
1005
  # maximum and redundant bond calculation
1006
1006
  merged_bond_list._bonds = merged_bonds
1007
1007
  merged_bond_list._max_bonds_per_atom = max(
1008
- self._max_bonds_per_atom, merged_bond_list._max_bonds_per_atom
1008
+ self._max_bonds_per_atom, bond_list._max_bonds_per_atom
1009
1009
  )
1010
1010
  return merged_bond_list
1011
1011
 
1012
1012
  def __getitem__(self, index):
1013
1013
  ## Variables for both, integer and boolean index arrays
1014
1014
  cdef uint32[:,:] all_bonds_v
1015
- cdef int32 new_index
1016
1015
  cdef int i
1017
1016
  cdef uint32* index1_ptr
1018
1017
  cdef uint32* index2_ptr
@@ -1020,7 +1019,7 @@ class BondList(Copyable):
1020
1019
  cdef uint8[:] removal_filter_v
1021
1020
 
1022
1021
  ## Variables for integer arrays
1023
- cdef int32[:] index_v, inverse_index
1022
+ cdef int32[:] inverse_index_v
1024
1023
  cdef int32 new_index1, new_index2
1025
1024
 
1026
1025
  ## Variables for boolean mask
@@ -1035,54 +1034,13 @@ class BondList(Copyable):
1035
1034
  ## Handle single index
1036
1035
  return self.get_bonds(index)
1037
1036
 
1038
- elif isinstance(index, np.ndarray) \
1039
- and np.issubdtype(index.dtype, np.integer):
1040
- ## Handle index array
1041
- copy = self.copy()
1042
- all_bonds_v = copy._bonds
1043
-
1044
- index = _to_positive_index_array(index, self._atom_count)
1045
- # The inverse index is required to efficiently obtain
1046
- # the new index of an atom in case of an unsorted index
1047
- # array
1048
- inverse_index_v = _invert_index(index, self._atom_count)
1049
- removal_filter = np.ones(all_bonds_v.shape[0], dtype=np.uint8)
1050
- removal_filter_v = removal_filter
1051
- for i in range(all_bonds_v.shape[0]):
1052
- # Usage of pointer to increase performance
1053
- # as redundant indexing is avoided
1054
- index1_ptr = &all_bonds_v[i,0]
1055
- index2_ptr = &all_bonds_v[i,1]
1056
- new_index1 = inverse_index_v[index1_ptr[0]]
1057
- new_index2 = inverse_index_v[index2_ptr[0]]
1058
- if new_index1 != -1 and new_index2 != -1:
1059
- # Both atoms involved in bond are included
1060
- # by index array
1061
- # -> assign new atom indices
1062
- index1_ptr[0] = <int32>new_index1
1063
- index2_ptr[0] = <int32>new_index2
1064
- else:
1065
- # At least one atom in bond is not included
1066
- # -> remove bond
1067
- removal_filter_v[i] = False
1068
-
1069
- copy._bonds = copy._bonds[
1070
- removal_filter.astype(bool, copy=False)
1071
- ]
1072
- # Again, sort indices per bond
1073
- # as the correct order is not guaranteed anymore
1074
- # for unsorted index arrays
1075
- copy._bonds[:,:2] = np.sort(copy._bonds[:,:2], axis=1)
1076
- copy._atom_count = len(index)
1077
- copy._max_bonds_per_atom = copy._get_max_bonds_per_atom()
1078
- return copy
1079
-
1080
- else:
1081
- ## Handle all other arrays as boolean mask
1037
+ elif isinstance(index, np.ndarray) and index.dtype == bool:
1038
+ ## Handle boolean masks
1082
1039
  copy = self.copy()
1083
1040
  all_bonds_v = copy._bonds
1041
+ # Use 'uint8' instead of 'bool' for memory view
1042
+ mask = np.frombuffer(index, dtype=np.uint8)
1084
1043
 
1085
- mask = _to_bool_mask(index, length=copy._atom_count)
1086
1044
  # Each time an atom is missing in the mask,
1087
1045
  # the offset is increased by one
1088
1046
  offsets = np.cumsum(
@@ -1118,6 +1076,48 @@ class BondList(Copyable):
1118
1076
  copy._max_bonds_per_atom = copy._get_max_bonds_per_atom()
1119
1077
  return copy
1120
1078
 
1079
+ else:
1080
+ ## Convert any other type of index into index array, as it preserves order
1081
+ copy = self.copy()
1082
+ all_bonds_v = copy._bonds
1083
+ index = _to_index_array(index, self._atom_count)
1084
+ index = _to_positive_index_array(index, self._atom_count)
1085
+
1086
+ # The inverse index is required to efficiently obtain
1087
+ # the new index of an atom in case of an unsorted index
1088
+ # array
1089
+ inverse_index_v = _invert_index(index, self._atom_count)
1090
+ removal_filter = np.ones(all_bonds_v.shape[0], dtype=np.uint8)
1091
+ removal_filter_v = removal_filter
1092
+ for i in range(all_bonds_v.shape[0]):
1093
+ # Usage of pointer to increase performance
1094
+ # as redundant indexing is avoided
1095
+ index1_ptr = &all_bonds_v[i,0]
1096
+ index2_ptr = &all_bonds_v[i,1]
1097
+ new_index1 = inverse_index_v[index1_ptr[0]]
1098
+ new_index2 = inverse_index_v[index2_ptr[0]]
1099
+ if new_index1 != -1 and new_index2 != -1:
1100
+ # Both atoms involved in bond are included
1101
+ # by index array
1102
+ # -> assign new atom indices
1103
+ index1_ptr[0] = <int32>new_index1
1104
+ index2_ptr[0] = <int32>new_index2
1105
+ else:
1106
+ # At least one atom in bond is not included
1107
+ # -> remove bond
1108
+ removal_filter_v[i] = False
1109
+
1110
+ copy._bonds = copy._bonds[
1111
+ removal_filter.astype(bool, copy=False)
1112
+ ]
1113
+ # Again, sort indices per bond
1114
+ # as the correct order is not guaranteed anymore
1115
+ # for unsorted index arrays
1116
+ copy._bonds[:,:2] = np.sort(copy._bonds[:,:2], axis=1)
1117
+ copy._atom_count = len(index)
1118
+ copy._max_bonds_per_atom = copy._get_max_bonds_per_atom()
1119
+ return copy
1120
+
1121
1121
  def __iter__(self):
1122
1122
  raise TypeError("'BondList' object is not iterable")
1123
1123
 
@@ -1266,6 +1266,18 @@ def _to_positive_index_array(index_array, length):
1266
1266
  return index_array.reshape(orig_shape)
1267
1267
 
1268
1268
 
1269
+ def _to_index_array(object index, uint32 length):
1270
+ """
1271
+ Convert an index of arbitrary type into an index array.
1272
+ """
1273
+ if isinstance(index, np.ndarray) and np.issubdtype(index.dtype, np.integer):
1274
+ return index
1275
+ else:
1276
+ # Convert into index array
1277
+ all_indices = np.arange(length, dtype=np.uint32)
1278
+ return all_indices[index]
1279
+
1280
+
1269
1281
  cdef inline bint _in_array(uint32* array, uint32 atom_index, int array_length):
1270
1282
  """
1271
1283
  Test whether a value (`atom_index`) is in a C-array `array`.
@@ -1316,29 +1328,9 @@ def _invert_index(IndexType[:] index_v, uint32 length):
1316
1328
  return inverse_index
1317
1329
 
1318
1330
 
1319
- def _to_bool_mask(object index, uint32 length):
1320
- """
1321
- Convert an index of arbitrary type into a boolean mask
1322
- with given length.
1323
- """
1324
- if isinstance(index, np.ndarray) and index.dtype == bool:
1325
- # Index is already boolean mask -> simply return as uint8
1326
- if len(index) != length:
1327
- raise IndexError(
1328
- f"Boolean mask has length {len(index)}, expected {length}"
1329
- )
1330
- # Use 'uint8' instead of 'bool' for memory view
1331
- return index.astype(np.uint8, copy=False)
1332
- else:
1333
- # Use 'uint8' instead of 'bool' for memory view
1334
- mask = np.zeros(length, dtype=np.uint8)
1335
- # 1 -> True
1336
- mask[index] = 1
1337
- return mask
1338
-
1339
-
1340
1331
 
1341
1332
 
1333
+ # fmt: off
1342
1334
  _DEFAULT_DISTANCE_RANGE = {
1343
1335
  # Taken from Allen et al.
1344
1336
  # min - 2*std max + 2*std
@@ -1385,9 +1377,9 @@ _DEFAULT_DISTANCE_RANGE = {
1385
1377
  ("SE", "SE") : (2.340 - 2*0.024, 2.340 + 2*0.024),
1386
1378
  ("SI", "SE") : (2.359 - 2*0.012, 2.359 + 2*0.012),
1387
1379
  }
1380
+ # fmt: on
1388
1381
 
1389
- def connect_via_distances(atoms, dict distance_range=None, atom_mask=None,
1390
- bint inter_residue=True,
1382
+ def connect_via_distances(atoms, dict distance_range=None, bint inter_residue=True,
1391
1383
  default_bond_type=BondType.ANY, bint periodic=False):
1392
1384
  """
1393
1385
  connect_via_distances(atoms, distance_range=None, atom_mask=None,
@@ -1419,8 +1411,6 @@ def connect_via_distances(atoms, dict distance_range=None, atom_mask=None,
1419
1411
  Hence, the default bond distances for missing element pairs are
1420
1412
  still taken from the default dictionary.
1421
1413
  The default bond distances are taken from :footcite:`Allen1987`.
1422
- atom_mask : ndarray, dtype=bool, shape=(n,), optional
1423
- DEPRECATED: This option has no effect.
1424
1414
  inter_residue : bool, optional
1425
1415
  If true, connections between consecutive amino acids and
1426
1416
  nucleotides are also added.
@@ -1541,7 +1531,7 @@ def connect_via_distances(atoms, dict distance_range=None, atom_mask=None,
1541
1531
 
1542
1532
 
1543
1533
 
1544
- def connect_via_residue_names(atoms, atom_mask=None, bint inter_residue=True,
1534
+ def connect_via_residue_names(atoms, bint inter_residue=True,
1545
1535
  dict custom_bond_dict=None):
1546
1536
  """
1547
1537
  connect_via_residue_names(atoms, atom_mask=None, inter_residue=True)
@@ -1558,8 +1548,6 @@ def connect_via_residue_names(atoms, atom_mask=None, bint inter_residue=True,
1558
1548
  ----------
1559
1549
  atoms : AtomArray, shape=(n,) or AtomArrayStack, shape=(m,n)
1560
1550
  The structure to create the :class:`BondList` for.
1561
- atom_mask : ndarray, dtype=bool, shape=(n,), optional
1562
- DEPRECATED: This option has no effect.
1563
1551
  inter_residue : bool, optional
1564
1552
  If true, connections between consecutive amino acids and
1565
1553
  nucleotides are also added.
biotite/structure/box.py CHANGED
@@ -4,25 +4,33 @@
4
4
 
5
5
  """
6
6
  Functions related to working with the simulation box or unit cell
7
- of a structure
7
+ of a structure
8
8
  """
9
9
 
10
10
  __name__ = "biotite.structure"
11
11
  __author__ = "Patrick Kunzmann"
12
- __all__ = ["vectors_from_unitcell", "unitcell_from_vectors", "box_volume",
13
- "repeat_box", "repeat_box_coord", "move_inside_box",
14
- "remove_pbc", "remove_pbc_from_coord",
15
- "coord_to_fraction", "fraction_to_coord", "is_orthogonal"]
12
+ __all__ = [
13
+ "vectors_from_unitcell",
14
+ "unitcell_from_vectors",
15
+ "box_volume",
16
+ "repeat_box",
17
+ "repeat_box_coord",
18
+ "move_inside_box",
19
+ "remove_pbc",
20
+ "remove_pbc_from_coord",
21
+ "coord_to_fraction",
22
+ "fraction_to_coord",
23
+ "is_orthogonal",
24
+ ]
16
25
 
17
- from collections.abc import Iterable
18
26
  from numbers import Integral
19
27
  import numpy as np
20
28
  import numpy.linalg as linalg
21
- from .util import vector_dot
22
- from .atoms import repeat
23
- from .molecules import get_molecule_masks
24
- from .chains import get_chain_masks, get_chain_starts
25
- from .error import BadStructureError
29
+ from biotite.structure.atoms import repeat
30
+ from biotite.structure.chains import get_chain_masks, get_chain_starts
31
+ from biotite.structure.error import BadStructureError
32
+ from biotite.structure.molecules import get_molecule_masks
33
+ from biotite.structure.util import vector_dot
26
34
 
27
35
 
28
36
  def vectors_from_unitcell(len_a, len_b, len_c, alpha, beta, gamma):
@@ -41,7 +49,7 @@ def vectors_from_unitcell(len_a, len_b, len_c, alpha, beta, gamma):
41
49
  The angles between the box vectors in radians.
42
50
  *alpha* is the angle between *b* and *c*,
43
51
  *beta* between *a* and *c*, *gamma* between *a* and *b*
44
-
52
+
45
53
  Returns
46
54
  -------
47
55
  box : ndarray, dtype=float, shape=(3,3)
@@ -49,7 +57,7 @@ def vectors_from_unitcell(len_a, len_b, len_c, alpha, beta, gamma):
49
57
  The vector components are in the last dimension.
50
58
  The value can be directly used as :attr:`box` attribute in an
51
59
  atom array.
52
-
60
+
53
61
  See also
54
62
  --------
55
63
  unitcell_from_vectors
@@ -58,19 +66,15 @@ def vectors_from_unitcell(len_a, len_b, len_c, alpha, beta, gamma):
58
66
  b_x = len_b * np.cos(gamma)
59
67
  b_y = len_b * np.sin(gamma)
60
68
  c_x = len_c * np.cos(beta)
61
- c_y = len_c * (np.cos(alpha) - np.cos(beta)*np.cos(gamma)) / np.sin(gamma)
62
- c_z = np.sqrt(len_c*len_c - c_x*c_x - c_y*c_y)
63
- box = np.array([
64
- [a_x, 0, 0],
65
- [b_x, b_y, 0],
66
- [c_x, c_y, c_z]
67
- ], dtype=np.float32)
68
-
69
+ c_y = len_c * (np.cos(alpha) - np.cos(beta) * np.cos(gamma)) / np.sin(gamma)
70
+ c_z = np.sqrt(len_c * len_c - c_x * c_x - c_y * c_y)
71
+ box = np.array([[a_x, 0, 0], [b_x, b_y, 0], [c_x, c_y, c_z]], dtype=np.float32)
72
+
69
73
  # Fix numerical errors, as values, that are actually 0,
70
74
  # might not be calculated as such
71
75
  tol = 1e-4 * (len_a + len_b + len_c)
72
76
  box[np.abs(box) < tol] = 0
73
-
77
+
74
78
  return box
75
79
 
76
80
 
@@ -84,7 +88,7 @@ def unitcell_from_vectors(box):
84
88
  ----------
85
89
  box : ndarray, shape=(3,3)
86
90
  The box vectors
87
-
91
+
88
92
  Returns
89
93
  -------
90
94
  len_a, len_b, len_c : float
@@ -103,7 +107,7 @@ def unitcell_from_vectors(box):
103
107
  len_b = linalg.norm(b)
104
108
  len_c = linalg.norm(c)
105
109
  alpha = np.arccos(np.dot(b, c) / (len_b * len_c))
106
- beta = np.arccos(np.dot(a, c) / (len_a * len_c))
110
+ beta = np.arccos(np.dot(a, c) / (len_a * len_c))
107
111
  gamma = np.arccos(np.dot(a, b) / (len_a * len_b))
108
112
  return len_a, len_b, len_c, alpha, beta, gamma
109
113
 
@@ -116,7 +120,7 @@ def box_volume(box):
116
120
  ----------
117
121
  box : ndarray, shape=(3,3) or shape=(m,3,3)
118
122
  One or multiple boxes to get the volume for.
119
-
123
+
120
124
  Returns
121
125
  -------
122
126
  volume : float or ndarray, shape=(m,)
@@ -159,7 +163,7 @@ def repeat_box(atoms, amount=1):
159
163
  Indices to the atoms in the original atom array (stack).
160
164
  Equal to
161
165
  ``numpy.tile(np.arange(atoms.array_length()), (1 + 2 * amount) ** 3)``.
162
-
166
+
163
167
  See also
164
168
  --------
165
169
  repeat_box_coord
@@ -232,12 +236,12 @@ def repeat_box(atoms, amount=1):
232
236
  """
233
237
  if atoms.box is None:
234
238
  raise BadStructureError("Structure has no box")
235
-
239
+
236
240
  repeat_coord, indices = repeat_box_coord(atoms.coord, atoms.box)
237
241
  # Unroll repeated coordinates for input to 'repeat()'
238
242
  if repeat_coord.ndim == 2:
239
243
  repeat_coord = repeat_coord.reshape(-1, atoms.array_length(), 3)
240
- else: # ndim == 3
244
+ else: # ndim == 3
241
245
  repeat_coord = repeat_coord.reshape(
242
246
  atoms.stack_depth(), -1, atoms.array_length(), 3
243
247
  )
@@ -283,16 +287,15 @@ def repeat_box_coord(coord, box, amount=1):
283
287
  raise TypeError("The amount must be an integer")
284
288
  # List of numpy arrays for each box repeat
285
289
  coords_for_boxes = [coord]
286
- for i in range(-amount, amount+1):
287
- for j in range(-amount, amount+1):
288
- for k in range(-amount, amount+1):
290
+ for i in range(-amount, amount + 1):
291
+ for j in range(-amount, amount + 1):
292
+ for k in range(-amount, amount + 1):
289
293
  # Omit the central box
290
294
  if i != 0 or j != 0 or k != 0:
291
295
  temp_coord = coord.copy()
292
296
  # Shift coordinates to adjacent box/unit cell
293
297
  translation_vec = np.sum(
294
- box * np.array([i,j,k])[:, np.newaxis],
295
- axis=-2
298
+ box * np.array([i, j, k])[:, np.newaxis], axis=-2
296
299
  )
297
300
  # 'newaxis' to perform same translation on all
298
301
  # atoms for each model
@@ -300,7 +303,7 @@ def repeat_box_coord(coord, box, amount=1):
300
303
  coords_for_boxes.append(temp_coord)
301
304
  return (
302
305
  np.concatenate(coords_for_boxes, axis=-2),
303
- np.tile(np.arange(coord.shape[-2]), (1 + 2 * amount) ** 3)
306
+ np.tile(np.arange(coord.shape[-2]), (1 + 2 * amount) ** 3),
304
307
  )
305
308
 
306
309
 
@@ -323,16 +326,16 @@ def move_inside_box(coord, box):
323
326
  The box(es) for one or multiple models.
324
327
  When `coord` is given for multiple models, :attr:`box` must be
325
328
  given for multiple models as well.
326
-
329
+
327
330
  Returns
328
331
  -------
329
332
  moved_coord : ndarray, dtype=float, shape=(n,3) or shape=(m,n,3)
330
333
  The moved coordinates.
331
334
  Has the same shape is the input `coord`.
332
-
335
+
333
336
  Examples
334
337
  --------
335
-
338
+
336
339
  >>> box = np.array([[10,0,0], [0,10,0], [0,0,10]], dtype=float)
337
340
  >>> inside_coord = [ 1, 2, 3]
338
341
  >>> outside_coord = [ 1, 22, 54]
@@ -363,7 +366,7 @@ def remove_pbc(atoms, selection=None):
363
366
  To determine the molecules the structure is required to have an
364
367
  associated `BondList`.
365
368
  Otherwise segmentation removal is performed on a per-chain basis.
366
-
369
+
367
370
  Parameters
368
371
  ----------
369
372
  atoms : AtomArray, shape=(n,) or AtomArrayStack, shape=(m,n)
@@ -373,13 +376,13 @@ def remove_pbc(atoms, selection=None):
373
376
  selection : ndarray, dtype=bool, shape=(n,)
374
377
  Specifies which parts of `atoms` are sanitized, i.e the
375
378
  segmentation is removed.
376
-
379
+
377
380
  Returns
378
381
  -------
379
382
  sanitized_atoms : AtomArray or AtomArrayStack
380
383
  The input structure with removed segmentation over periodic
381
384
  boundaries.
382
-
385
+
383
386
  See also
384
387
  --------
385
388
  remove_pbc_from_coord
@@ -392,12 +395,10 @@ def remove_pbc(atoms, selection=None):
392
395
  half box size.
393
396
  """
394
397
  # Avoid circular import
395
- from .geometry import centroid
396
-
398
+ from biotite.structure.geometry import centroid
399
+
397
400
  if atoms.box is None:
398
- raise BadStructureError(
399
- "The 'box' attribute must be set in the structure"
400
- )
401
+ raise BadStructureError("The 'box' attribute must be set in the structure")
401
402
  new_atoms = atoms.copy()
402
403
 
403
404
  if atoms.bonds is not None:
@@ -414,10 +415,8 @@ def remove_pbc(atoms, selection=None):
414
415
  )
415
416
  # Put center of molecule into box
416
417
  center = centroid(new_atoms.coord[..., mask, :])[..., np.newaxis, :]
417
- center_in_box = move_inside_box(
418
- center, new_atoms.box
419
- )
420
- new_atoms.coord[..., mask, :] += (center_in_box - center)
418
+ center_in_box = move_inside_box(center, new_atoms.box)
419
+ new_atoms.coord[..., mask, :] += center_in_box - center
421
420
 
422
421
  return new_atoms
423
422
 
@@ -433,11 +432,11 @@ def remove_pbc_from_coord(coord, box):
433
432
  the displacement coordinates in adjacent array positions.
434
433
  Basically, this function performs the reverse action of
435
434
  :func:`move_inside_box()`.
436
-
435
+
437
436
  Parameters
438
437
  ----------
439
438
  coord : ndarray, dtype=float, shape=(m,n,3) or shape=(n,3)
440
- The coordinates of the potentially segmented structure.
439
+ The coordinates of the potentially segmented structure.
441
440
  box : ndarray, dtype=float, shape=(m,3,3) or shape=(3,3)
442
441
  The simulation box or unit cell that is used as periodic
443
442
  boundary.
@@ -447,7 +446,7 @@ def remove_pbc_from_coord(coord, box):
447
446
  -------
448
447
  sanitized_coord : ndarray, dtype=float, shape=(m,n,3) or shape=(n,3)
449
448
  The reassembled coordinates.
450
-
449
+
451
450
  See also
452
451
  --------
453
452
  remove_pbc_from_coord
@@ -463,19 +462,14 @@ def remove_pbc_from_coord(coord, box):
463
462
  """
464
463
 
465
464
  # Import in function to avoid circular import
466
- from .geometry import index_displacement
465
+ from biotite.structure.geometry import index_displacement
466
+
467
467
  # Get the PBC-sanitized displacements of all coordinates
468
468
  # to the respective next coordinate
469
469
  index_pairs = np.stack(
470
- [
471
- np.arange(0, coord.shape[-2] - 1),
472
- np.arange(1, coord.shape[-2] )
473
- ],
474
- axis=1
475
- )
476
- neighbour_disp = index_displacement(
477
- coord, index_pairs, box=box, periodic=True
470
+ [np.arange(0, coord.shape[-2] - 1), np.arange(1, coord.shape[-2])], axis=1
478
471
  )
472
+ neighbour_disp = index_displacement(coord, index_pairs, box=box, periodic=True)
479
473
  # Get the PBC-sanitized displacements of all but the first
480
474
  # coordinates to (0,0,0)
481
475
  absolute_disp = np.cumsum(neighbour_disp, axis=-2)
@@ -501,19 +495,19 @@ def coord_to_fraction(coord, box):
501
495
  The box(es) for one or multiple models.
502
496
  When `coord` is given for multiple models, :attr:`box` must be
503
497
  given for multiple models as well.
504
-
498
+
505
499
  Returns
506
500
  -------
507
501
  fraction : ndarray, dtype=float, shape=(n,3) or shape=(m,n,3)
508
502
  The fractions of the box vectors.
509
-
503
+
510
504
  See also
511
505
  --------
512
506
  fraction_to_coord
513
507
 
514
508
  Examples
515
509
  --------
516
-
510
+
517
511
  >>> box = np.array([[5,0,0], [0,5,0], [0,5,5]], dtype=float)
518
512
  >>> coord = np.array(
519
513
  ... [[1,1,1], [10,0,0], [0,0,10], [-5,2,1]],
@@ -548,12 +542,12 @@ def fraction_to_coord(fraction, box):
548
542
  The box(es) for one or multiple models.
549
543
  When `coord` is given for multiple models, :attr:`box` must be
550
544
  given for multiple models as well.
551
-
545
+
552
546
  Returns
553
547
  -------
554
548
  coord : ndarray, dtype=float, shape=(n,3) or shape=(m,n,3)
555
549
  The coordinates.
556
-
550
+
557
551
  See also
558
552
  --------
559
553
  coord_to_fraction
@@ -572,12 +566,12 @@ def is_orthogonal(box):
572
566
  ----------
573
567
  box : ndarray, dtype=float, shape=(3,3) or shape=(m,3,3)
574
568
  A single box or multiple boxes.
575
-
569
+
576
570
  Returns
577
571
  -------
578
572
  is_orthgonal : bool or ndarray, shape=(m,), dtype=bool
579
573
  True, if the box vectors are orthogonal, false otherwise
580
-
574
+
581
575
  Notes
582
576
  -----
583
577
  Due to possible numerical errors, this function also evaluates two
@@ -587,6 +581,8 @@ def is_orthogonal(box):
587
581
  # Fix numerical errors, as values, that are actually 0,
588
582
  # might not be calculated as such
589
583
  tol = 1e-6
590
- return (np.abs(vector_dot(box[..., 0, :], box[..., 1, :])) < tol) & \
591
- (np.abs(vector_dot(box[..., 0, :], box[..., 2, :])) < tol) & \
592
- (np.abs(vector_dot(box[..., 1, :], box[..., 2, :])) < tol)
584
+ return (
585
+ (np.abs(vector_dot(box[..., 0, :], box[..., 1, :])) < tol)
586
+ & (np.abs(vector_dot(box[..., 0, :], box[..., 2, :])) < tol)
587
+ & (np.abs(vector_dot(box[..., 1, :], box[..., 2, :])) < tol)
588
+ )