biotite 1.0.1__cp312-cp312-win_amd64.whl → 1.2.0__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 (177) hide show
  1. biotite/application/application.py +3 -3
  2. biotite/application/autodock/app.py +1 -1
  3. biotite/application/blast/webapp.py +1 -1
  4. biotite/application/clustalo/app.py +1 -1
  5. biotite/application/dssp/app.py +13 -3
  6. biotite/application/localapp.py +36 -2
  7. biotite/application/msaapp.py +10 -10
  8. biotite/application/muscle/app3.py +5 -18
  9. biotite/application/muscle/app5.py +5 -5
  10. biotite/application/sra/app.py +0 -5
  11. biotite/application/util.py +22 -2
  12. biotite/application/viennarna/rnaalifold.py +8 -8
  13. biotite/application/viennarna/rnaplot.py +9 -3
  14. biotite/application/viennarna/util.py +1 -1
  15. biotite/application/webapp.py +1 -1
  16. biotite/database/afdb/__init__.py +12 -0
  17. biotite/database/afdb/download.py +191 -0
  18. biotite/database/entrez/dbnames.py +10 -0
  19. biotite/database/entrez/download.py +9 -10
  20. biotite/database/entrez/key.py +1 -1
  21. biotite/database/entrez/query.py +5 -4
  22. biotite/database/pubchem/download.py +6 -6
  23. biotite/database/pubchem/error.py +10 -0
  24. biotite/database/pubchem/query.py +12 -23
  25. biotite/database/rcsb/download.py +3 -2
  26. biotite/database/rcsb/query.py +8 -9
  27. biotite/database/uniprot/check.py +22 -17
  28. biotite/database/uniprot/download.py +3 -6
  29. biotite/database/uniprot/query.py +4 -5
  30. biotite/file.py +14 -2
  31. biotite/interface/__init__.py +19 -0
  32. biotite/interface/openmm/__init__.py +16 -0
  33. biotite/interface/openmm/state.py +93 -0
  34. biotite/interface/openmm/system.py +227 -0
  35. biotite/interface/pymol/__init__.py +198 -0
  36. biotite/interface/pymol/cgo.py +346 -0
  37. biotite/interface/pymol/convert.py +185 -0
  38. biotite/interface/pymol/display.py +267 -0
  39. biotite/interface/pymol/object.py +1226 -0
  40. biotite/interface/pymol/shapes.py +178 -0
  41. biotite/interface/pymol/startup.py +169 -0
  42. biotite/interface/rdkit/__init__.py +15 -0
  43. biotite/interface/rdkit/mol.py +490 -0
  44. biotite/interface/version.py +71 -0
  45. biotite/interface/warning.py +19 -0
  46. biotite/sequence/align/__init__.py +0 -4
  47. biotite/sequence/align/alignment.py +49 -14
  48. biotite/sequence/align/banded.cp312-win_amd64.pyd +0 -0
  49. biotite/sequence/align/banded.pyx +26 -26
  50. biotite/sequence/align/cigar.py +2 -2
  51. biotite/sequence/align/kmeralphabet.cp312-win_amd64.pyd +0 -0
  52. biotite/sequence/align/kmeralphabet.pyx +19 -2
  53. biotite/sequence/align/kmersimilarity.cp312-win_amd64.pyd +0 -0
  54. biotite/sequence/align/kmertable.cp312-win_amd64.pyd +0 -0
  55. biotite/sequence/align/kmertable.pyx +58 -48
  56. biotite/sequence/align/localgapped.cp312-win_amd64.pyd +0 -0
  57. biotite/sequence/align/localgapped.pyx +47 -47
  58. biotite/sequence/align/localungapped.cp312-win_amd64.pyd +0 -0
  59. biotite/sequence/align/localungapped.pyx +10 -10
  60. biotite/sequence/align/matrix.py +284 -57
  61. biotite/sequence/align/matrix_data/3Di.mat +24 -0
  62. biotite/sequence/align/matrix_data/PB.license +21 -0
  63. biotite/sequence/align/matrix_data/PB.mat +18 -0
  64. biotite/sequence/align/multiple.cp312-win_amd64.pyd +0 -0
  65. biotite/sequence/align/pairwise.cp312-win_amd64.pyd +0 -0
  66. biotite/sequence/align/pairwise.pyx +35 -35
  67. biotite/sequence/align/permutation.cp312-win_amd64.pyd +0 -0
  68. biotite/sequence/align/selector.cp312-win_amd64.pyd +0 -0
  69. biotite/sequence/align/selector.pyx +2 -2
  70. biotite/sequence/align/statistics.py +1 -1
  71. biotite/sequence/align/tracetable.cp312-win_amd64.pyd +0 -0
  72. biotite/sequence/alphabet.py +5 -2
  73. biotite/sequence/annotation.py +19 -13
  74. biotite/sequence/codec.cp312-win_amd64.pyd +0 -0
  75. biotite/sequence/codon.py +1 -2
  76. biotite/sequence/graphics/alignment.py +25 -39
  77. biotite/sequence/graphics/color_schemes/3di_flower.json +48 -0
  78. biotite/sequence/graphics/color_schemes/pb_flower.json +2 -1
  79. biotite/sequence/graphics/colorschemes.py +44 -11
  80. biotite/sequence/graphics/dendrogram.py +4 -2
  81. biotite/sequence/graphics/features.py +2 -2
  82. biotite/sequence/graphics/logo.py +10 -12
  83. biotite/sequence/io/fasta/convert.py +1 -2
  84. biotite/sequence/io/fasta/file.py +1 -1
  85. biotite/sequence/io/fastq/file.py +3 -3
  86. biotite/sequence/io/genbank/file.py +3 -3
  87. biotite/sequence/io/genbank/sequence.py +2 -0
  88. biotite/sequence/io/gff/convert.py +1 -1
  89. biotite/sequence/io/gff/file.py +1 -2
  90. biotite/sequence/phylo/nj.cp312-win_amd64.pyd +0 -0
  91. biotite/sequence/phylo/tree.cp312-win_amd64.pyd +0 -0
  92. biotite/sequence/phylo/upgma.cp312-win_amd64.pyd +0 -0
  93. biotite/sequence/profile.py +105 -29
  94. biotite/sequence/search.py +0 -1
  95. biotite/sequence/seqtypes.py +136 -8
  96. biotite/sequence/sequence.py +1 -2
  97. biotite/setup_ccd.py +197 -0
  98. biotite/structure/__init__.py +6 -3
  99. biotite/structure/alphabet/__init__.py +25 -0
  100. biotite/structure/alphabet/encoder.py +332 -0
  101. biotite/structure/alphabet/encoder_weights_3di.kerasify +0 -0
  102. biotite/structure/alphabet/i3d.py +109 -0
  103. biotite/structure/alphabet/layers.py +86 -0
  104. biotite/structure/alphabet/pb.license +21 -0
  105. biotite/structure/alphabet/pb.py +170 -0
  106. biotite/structure/alphabet/unkerasify.py +128 -0
  107. biotite/structure/atoms.py +163 -66
  108. biotite/structure/basepairs.py +26 -26
  109. biotite/structure/bonds.cp312-win_amd64.pyd +0 -0
  110. biotite/structure/bonds.pyx +79 -25
  111. biotite/structure/box.py +19 -21
  112. biotite/structure/celllist.cp312-win_amd64.pyd +0 -0
  113. biotite/structure/celllist.pyx +83 -67
  114. biotite/structure/chains.py +5 -37
  115. biotite/structure/charges.cp312-win_amd64.pyd +0 -0
  116. biotite/structure/compare.py +420 -13
  117. biotite/structure/density.py +1 -1
  118. biotite/structure/dotbracket.py +27 -28
  119. biotite/structure/filter.py +8 -8
  120. biotite/structure/geometry.py +74 -127
  121. biotite/structure/hbond.py +17 -19
  122. biotite/structure/info/__init__.py +1 -0
  123. biotite/structure/info/atoms.py +24 -15
  124. biotite/structure/info/bonds.py +12 -6
  125. biotite/structure/info/ccd.py +125 -34
  126. biotite/structure/info/{ccd/components.bcif → components.bcif} +0 -0
  127. biotite/structure/info/groups.py +62 -19
  128. biotite/structure/info/masses.py +9 -6
  129. biotite/structure/info/misc.py +15 -22
  130. biotite/structure/info/radii.py +92 -22
  131. biotite/structure/info/standardize.py +4 -4
  132. biotite/structure/integrity.py +4 -6
  133. biotite/structure/io/general.py +2 -2
  134. biotite/structure/io/gro/file.py +8 -9
  135. biotite/structure/io/mol/convert.py +1 -1
  136. biotite/structure/io/mol/ctab.py +33 -28
  137. biotite/structure/io/mol/mol.py +1 -1
  138. biotite/structure/io/mol/sdf.py +80 -53
  139. biotite/structure/io/pdb/convert.py +4 -3
  140. biotite/structure/io/pdb/file.py +85 -25
  141. biotite/structure/io/pdb/hybrid36.cp312-win_amd64.pyd +0 -0
  142. biotite/structure/io/pdbqt/file.py +36 -36
  143. biotite/structure/io/pdbx/__init__.py +1 -0
  144. biotite/structure/io/pdbx/bcif.py +54 -15
  145. biotite/structure/io/pdbx/cif.py +92 -66
  146. biotite/structure/io/pdbx/component.py +15 -4
  147. biotite/structure/io/pdbx/compress.py +321 -0
  148. biotite/structure/io/pdbx/convert.py +410 -75
  149. biotite/structure/io/pdbx/encoding.cp312-win_amd64.pyd +0 -0
  150. biotite/structure/io/pdbx/encoding.pyx +98 -17
  151. biotite/structure/io/trajfile.py +9 -6
  152. biotite/structure/io/util.py +38 -0
  153. biotite/structure/mechanics.py +0 -1
  154. biotite/structure/molecules.py +141 -156
  155. biotite/structure/pseudoknots.py +7 -13
  156. biotite/structure/repair.py +2 -4
  157. biotite/structure/residues.py +13 -24
  158. biotite/structure/rings.py +335 -0
  159. biotite/structure/sasa.cp312-win_amd64.pyd +0 -0
  160. biotite/structure/sasa.pyx +2 -1
  161. biotite/structure/segments.py +69 -11
  162. biotite/structure/sequence.py +0 -1
  163. biotite/structure/sse.py +0 -2
  164. biotite/structure/superimpose.py +74 -62
  165. biotite/structure/tm.py +581 -0
  166. biotite/structure/transform.py +12 -25
  167. biotite/structure/util.py +76 -4
  168. biotite/version.py +9 -4
  169. biotite/visualize.py +111 -1
  170. {biotite-1.0.1.dist-info → biotite-1.2.0.dist-info}/METADATA +6 -2
  171. {biotite-1.0.1.dist-info → biotite-1.2.0.dist-info}/RECORD +173 -143
  172. biotite/structure/info/ccd/README.rst +0 -8
  173. biotite/structure/info/ccd/amino_acids.txt +0 -1663
  174. biotite/structure/info/ccd/carbohydrates.txt +0 -1135
  175. biotite/structure/info/ccd/nucleotides.txt +0 -798
  176. {biotite-1.0.1.dist-info → biotite-1.2.0.dist-info}/WHEEL +0 -0
  177. {biotite-1.0.1.dist-info → biotite-1.2.0.dist-info}/licenses/LICENSE.rst +0 -0
@@ -7,6 +7,7 @@ __author__ = "Patrick Kunzmann, Daniel Bauer, Claude J. Rogers"
7
7
  __all__ = ["PDBFile"]
8
8
 
9
9
  import warnings
10
+ from collections import namedtuple
10
11
  import numpy as np
11
12
  from biotite.file import InvalidFileError, TextFile
12
13
  from biotite.structure.atoms import AtomArray, AtomArrayStack, repeat
@@ -23,6 +24,7 @@ from biotite.structure.io.pdb.hybrid36 import (
23
24
  encode_hybrid36,
24
25
  max_hybrid36_number,
25
26
  )
27
+ from biotite.structure.io.util import number_of_integer_digits
26
28
  from biotite.structure.repair import infer_elements
27
29
  from biotite.structure.util import matrix_rotate
28
30
 
@@ -53,6 +55,8 @@ _c = slice(24, 33)
53
55
  _alpha = slice(33, 40)
54
56
  _beta = slice(40, 47)
55
57
  _gamma = slice(47, 54)
58
+ _space = slice(55, 66)
59
+ _z = slice(66, 70)
56
60
 
57
61
 
58
62
  class PDBFile(TextFile):
@@ -67,10 +71,10 @@ class PDBFile(TextFile):
67
71
  records cannot be written.
68
72
  Additionally, *REMARK* records can be read
69
73
 
70
- See also
74
+ See Also
71
75
  --------
72
- CIFFile
73
- BinaryCIFFile
76
+ CIFFile : Interface to CIF files, a modern replacement for PDB files.
77
+ BinaryCIFFile : Interface to BinaryCIF files, a binary variant of CIF files.
74
78
 
75
79
  Examples
76
80
  --------
@@ -545,6 +549,38 @@ class PDBFile(TextFile):
545
549
 
546
550
  return array
547
551
 
552
+ def get_space_group(self):
553
+ """
554
+ Extract the space group and Z value from the CRYST1 record.
555
+
556
+ Returns
557
+ -------
558
+ space_group : str
559
+ The extracted space group.
560
+ z_val : int
561
+ The extracted Z value.
562
+ """
563
+ # Initialize the namedtuple
564
+ SpaceGroupInfo = namedtuple("SpaceGroupInfo", ["space_group", "z_val"])
565
+
566
+ # CRYST1 is a one-time record so we can extract it directly
567
+ for line in self.lines:
568
+ if line.startswith("CRYST1"):
569
+ try:
570
+ # Extract space group and Z value
571
+ space_group = str(line[_space])
572
+ z_val = int(line[_z])
573
+ except ValueError:
574
+ # File contains invalid 'CRYST1' record
575
+ raise InvalidFileError(
576
+ "File does not contain valid space group and/or Z values"
577
+ )
578
+ # Set default values
579
+ space_group = "P 1"
580
+ z_val = 1
581
+ break
582
+ return SpaceGroupInfo(space_group=space_group, z_val=z_val)
583
+
548
584
  def set_structure(self, array, hybrid36=False):
549
585
  """
550
586
  Set the :class:`AtomArray` or :class:`AtomArrayStack` for the
@@ -562,7 +598,7 @@ class PDBFile(TextFile):
562
598
  The array or stack to be saved into this file. If a stack
563
599
  is given, each array in the stack is saved as separate
564
600
  model.
565
- hybrid36: bool, optional
601
+ hybrid36 : bool, optional
566
602
  Defines wether the file should be written in hybrid-36
567
603
  format.
568
604
 
@@ -700,6 +736,32 @@ class PDBFile(TextFile):
700
736
 
701
737
  self._index_models_and_atoms()
702
738
 
739
+ def set_space_group(self, info):
740
+ """
741
+ Update the CRYST1 record with the provided space group and Z value.
742
+
743
+ Parameters
744
+ ----------
745
+ info : tuple(str, int) or SpaceGroupInfo
746
+ Contains the space group and Z-value.
747
+ """
748
+ for i, line in enumerate(self.lines):
749
+ if line.startswith("CRYST1"):
750
+ try:
751
+ # Format the replacement string
752
+ space_group_str = info.space_group.ljust(11)
753
+ z_val_str = str(info.z_val).rjust(4)
754
+
755
+ # Replace the existing CRYST1 record
756
+ self.lines[i] = line[:55] + space_group_str + z_val_str + line[70:]
757
+ except (ValueError, AttributeError) as e:
758
+ # Raise an exception with context
759
+ raise AttributeError(
760
+ f"Failed to update CRYST1 record. "
761
+ f"Line: {line.strip()} | Error: {e}"
762
+ )
763
+ break
764
+
703
765
  def list_assemblies(self):
704
766
  """
705
767
  List the biological assemblies that are available for the
@@ -790,6 +852,8 @@ class PDBFile(TextFile):
790
852
  assembly : AtomArray or AtomArrayStack
791
853
  The assembly.
792
854
  The return type depends on the `model` parameter.
855
+ Contains the `sym_id` annotation, which enumerates the copies of the
856
+ asymmetric unit in the assembly.
793
857
 
794
858
  Examples
795
859
  --------
@@ -831,7 +895,7 @@ class PDBFile(TextFile):
831
895
  if assembly_start_i is None:
832
896
  if assembly_id is None:
833
897
  raise InvalidFileError(
834
- "File does not contain transformation " "expressions for assemblies"
898
+ "File does not contain transformation expressions for assemblies"
835
899
  )
836
900
  else:
837
901
  raise KeyError(f"The assembly ID '{assembly_id}' is not found")
@@ -853,8 +917,12 @@ class PDBFile(TextFile):
853
917
  affected_chain_ids = []
854
918
  transform_start = None
855
919
  for j, line in enumerate(assembly_lines[start:stop]):
856
- if line.startswith("APPLY THE FOLLOWING TO CHAINS:") or line.startswith(
857
- " AND CHAINS:"
920
+ if any(
921
+ line.startswith(chain_signal_string)
922
+ for chain_signal_string in [
923
+ "APPLY THE FOLLOWING TO CHAINS:",
924
+ " AND CHAINS:",
925
+ ]
858
926
  ):
859
927
  affected_chain_ids += [
860
928
  chain_id.strip() for chain_id in line[30:].split(",")
@@ -1039,7 +1107,7 @@ class PDBFile(TextFile):
1039
1107
  length = model_length
1040
1108
  if model_length != length:
1041
1109
  raise InvalidFileError(
1042
- f"Model {model_i+1} has {model_length} atoms, "
1110
+ f"Model {model_i + 1} has {model_length} atoms, "
1043
1111
  f"but model 1 has {length} atoms, must be equal"
1044
1112
  )
1045
1113
  return length
@@ -1148,7 +1216,11 @@ def _apply_transformations(structure, rotations, translations):
1148
1216
  coord += translation
1149
1217
  assembly_coord[i] = coord
1150
1218
 
1151
- return repeat(structure, assembly_coord)
1219
+ assembly = repeat(structure, assembly_coord)
1220
+ assembly.set_annotation(
1221
+ "sym_id", np.repeat(np.arange(len(rotations)), structure.array_length())
1222
+ )
1223
+ return assembly
1152
1224
 
1153
1225
 
1154
1226
  def _check_pdb_compatibility(array, hybrid36):
@@ -1177,21 +1249,21 @@ def _check_pdb_compatibility(array, hybrid36):
1177
1249
  if any([len(name) > 4 for name in array.atom_name]):
1178
1250
  raise BadStructureError("Some atom names exceed 4 characters")
1179
1251
  for i, coord_name in enumerate(["x", "y", "z"]):
1180
- n_coord_digits = _number_of_integer_digits(array.coord[..., i])
1252
+ n_coord_digits = number_of_integer_digits(array.coord[..., i])
1181
1253
  if n_coord_digits > 4:
1182
1254
  raise BadStructureError(
1183
1255
  f"4 pre-decimal columns for {coord_name}-coordinates are "
1184
1256
  f"available, but array would require {n_coord_digits}"
1185
1257
  )
1186
1258
  if "b_factor" in annot_categories:
1187
- n_b_factor_digits = _number_of_integer_digits(array.b_factor)
1259
+ n_b_factor_digits = number_of_integer_digits(array.b_factor)
1188
1260
  if n_b_factor_digits > 3:
1189
1261
  raise BadStructureError(
1190
1262
  "3 pre-decimal columns for B-factor are available, "
1191
1263
  f"but array would require {n_b_factor_digits}"
1192
1264
  )
1193
1265
  if "occupancy" in annot_categories:
1194
- n_occupancy_digits = _number_of_integer_digits(array.occupancy)
1266
+ n_occupancy_digits = number_of_integer_digits(array.occupancy)
1195
1267
  if n_occupancy_digits > 3:
1196
1268
  raise BadStructureError(
1197
1269
  "3 pre-decimal columns for occupancy are available, "
@@ -1199,21 +1271,9 @@ def _check_pdb_compatibility(array, hybrid36):
1199
1271
  )
1200
1272
  if "charge" in annot_categories:
1201
1273
  # The sign can be omitted is it is put into the adjacent column
1202
- n_charge_digits = _number_of_integer_digits(np.abs(array.charge))
1274
+ n_charge_digits = number_of_integer_digits(np.abs(array.charge))
1203
1275
  if n_charge_digits > 1:
1204
1276
  raise BadStructureError(
1205
1277
  "1 column for charge is available, "
1206
1278
  f"but array would require {n_charge_digits}"
1207
1279
  )
1208
-
1209
-
1210
- def _number_of_integer_digits(values):
1211
- """
1212
- Get the maximum number of characters needed to represent the
1213
- pre-decimal positions of the given numeric values.
1214
- """
1215
- values = values.astype(int, copy=False)
1216
- n_digits = 0
1217
- n_digits = max(n_digits, len(str(np.min(values))))
1218
- n_digits = max(n_digits, len(str(np.max(values))))
1219
- return n_digits
@@ -58,48 +58,48 @@ class PDBQTFile(TextFile):
58
58
  >>> mask = file.set_structure(ligand, rotatable_bonds="all")
59
59
  >>> # Print removed nonpolar hydrogen atoms
60
60
  >>> print(ligand[~mask])
61
- HET 0 BTN H101 H 3.740 1.170 0.970
62
- HET 0 BTN H102 H 4.070 1.340 -0.770
63
- HET 0 BTN H91 H 2.800 -0.740 -1.210
64
- HET 0 BTN H92 H 2.480 -0.910 0.530
65
- HET 0 BTN H81 H 1.290 1.260 0.520
66
- HET 0 BTN H82 H 1.620 1.440 -1.220
67
- HET 0 BTN H71 H 0.350 -0.650 -1.660
68
- HET 0 BTN H72 H 0.020 -0.820 0.080
69
- HET 0 BTN H2 H -0.840 1.580 -1.630
70
- HET 0 BTN H61 H -3.800 1.840 1.290
71
- HET 0 BTN H62 H -3.370 2.740 -0.200
72
- HET 0 BTN H5 H -4.310 0.810 -1.210
73
- HET 0 BTN H4 H -2.450 -0.040 -2.250
61
+ HET 0 BTN H101 H 3.745 1.171 0.974
62
+ HET 0 BTN H102 H 4.071 1.343 -0.767
63
+ HET 0 BTN H91 H 2.802 -0.740 -1.211
64
+ HET 0 BTN H92 H 2.476 -0.912 0.530
65
+ HET 0 BTN H81 H 1.289 1.265 0.523
66
+ HET 0 BTN H82 H 1.616 1.437 -1.218
67
+ HET 0 BTN H71 H 0.346 -0.646 -1.662
68
+ HET 0 BTN H72 H 0.020 -0.818 0.079
69
+ HET 0 BTN H2 H -0.838 1.576 -1.627
70
+ HET 0 BTN H61 H -3.797 1.837 1.286
71
+ HET 0 BTN H62 H -3.367 2.738 -0.205
72
+ HET 0 BTN H5 H -4.307 0.812 -1.205
73
+ HET 0 BTN H4 H -2.451 -0.038 -2.252
74
74
  >>> print(file)
75
75
  ROOT
76
- HETATM 1 C11 BTN 0 5.090 -0.280 0.170 1.00 0.00 0.258 C
77
- HETATM 2 O11 BTN 0 4.960 -1.470 0.030 1.00 0.00 -0.264 OA
76
+ HETATM 1 C11 BTN 0 5.089 -0.280 0.173 1.00 0.00 0.258 C
77
+ HETATM 2 O11 BTN 0 4.956 -1.473 0.030 1.00 0.00 -0.264 OA
78
78
  ENDROOT
79
79
  BRANCH 1 3
80
- HETATM 3 O12 BTN 0 6.300 0.230 0.440 1.00 0.00 -0.331 OA
81
- HETATM 17 HO2 BTN 0 7.030 -0.390 0.520 1.00 0.00 0.221 HD
80
+ HETATM 3 O12 BTN 0 6.299 0.233 0.444 1.00 0.00 -0.331 OA
81
+ HETATM 17 HO2 BTN 0 7.034 -0.391 0.517 1.00 0.00 0.221 HD
82
82
  ENDBRANCH 1 3
83
83
  BRANCH 1 4
84
- HETATM 4 C10 BTN 0 3.900 0.630 0.040 1.00 0.00 0.105 C
84
+ HETATM 4 C10 BTN 0 3.896 0.631 0.039 1.00 0.00 0.105 C
85
85
  BRANCH 4 5
86
- HETATM 5 C9 BTN 0 2.650 -0.200 -0.280 1.00 0.00 0.010 C
86
+ HETATM 5 C9 BTN 0 2.651 -0.200 -0.276 1.00 0.00 0.010 C
87
87
  BRANCH 5 6
88
- HETATM 6 C8 BTN 0 1.440 0.720 -0.410 1.00 0.00 0.002 C
88
+ HETATM 6 C8 BTN 0 1.440 0.725 -0.412 1.00 0.00 0.002 C
89
89
  BRANCH 6 7
90
- HETATM 7 C7 BTN 0 0.200 -0.110 -0.730 1.00 0.00 0.016 C
90
+ HETATM 7 C7 BTN 0 0.196 -0.106 -0.727 1.00 0.00 0.016 C
91
91
  BRANCH 7 8
92
- HETATM 8 C2 BTN 0 -1.020 0.820 -0.860 1.00 0.00 0.065 C
93
- HETATM 9 S1 BTN 0 -1.420 1.600 0.750 1.00 0.00 -0.154 SA
94
- HETATM 10 C6 BTN 0 -3.200 1.830 0.370 1.00 0.00 0.090 C
95
- HETATM 11 C5 BTN 0 -3.530 0.580 -0.480 1.00 0.00 0.091 C
96
- HETATM 12 N1 BTN 0 -3.970 -0.510 0.410 1.00 0.00 -0.239 NA
97
- HETATM 13 C3 BTN 0 -3.140 -1.550 0.270 1.00 0.00 0.272 C
98
- HETATM 14 O3 BTN 0 -3.270 -2.590 0.890 1.00 0.00 -0.259 OA
99
- HETATM 15 N2 BTN 0 -2.150 -1.340 -0.610 1.00 0.00 -0.239 NA
100
- HETATM 16 C4 BTN 0 -2.290 0.010 -1.170 1.00 0.00 0.093 C
101
- HETATM 18 HN1 BTN 0 -4.740 -0.470 1.000 1.00 0.00 0.132 HD
102
- HETATM 19 HN2 BTN 0 -1.460 -1.980 -0.840 1.00 0.00 0.132 HD
92
+ HETATM 8 C2 BTN 0 -1.015 0.819 -0.863 1.00 0.00 0.065 C
93
+ HETATM 9 S1 BTN 0 -1.419 1.604 0.751 1.00 0.00 -0.154 SA
94
+ HETATM 10 C6 BTN 0 -3.205 1.827 0.371 1.00 0.00 0.090 C
95
+ HETATM 11 C5 BTN 0 -3.530 0.581 -0.476 1.00 0.00 0.091 C
96
+ HETATM 12 N1 BTN 0 -3.970 -0.507 0.412 1.00 0.00 -0.239 NA
97
+ HETATM 13 C3 BTN 0 -3.141 -1.549 0.271 1.00 0.00 0.272 C
98
+ HETATM 14 O3 BTN 0 -3.271 -2.589 0.888 1.00 0.00 -0.259 OA
99
+ HETATM 15 N2 BTN 0 -2.154 -1.343 -0.612 1.00 0.00 -0.239 NA
100
+ HETATM 16 C4 BTN 0 -2.289 0.010 -1.175 1.00 0.00 0.093 C
101
+ HETATM 18 HN1 BTN 0 -4.738 -0.474 1.004 1.00 0.00 0.132 HD
102
+ HETATM 19 HN2 BTN 0 -1.462 -1.982 -0.843 1.00 0.00 0.132 HD
103
103
  ENDBRANCH 7 8
104
104
  ENDBRANCH 6 7
105
105
  ENDBRANCH 5 6
@@ -525,9 +525,9 @@ class PDBQTFile(TextFile):
525
525
  f"{atoms.chain_id[i]:1}"
526
526
  f"{atoms.res_id[i]:>4d}"
527
527
  f"{atoms.ins_code[i]:1} "
528
- f"{atoms.coord[i,0]:>8.3f}"
529
- f"{atoms.coord[i,1]:>8.3f}"
530
- f"{atoms.coord[i,2]:>8.3f}"
528
+ f"{atoms.coord[i, 0]:>8.3f}"
529
+ f"{atoms.coord[i, 1]:>8.3f}"
530
+ f"{atoms.coord[i, 2]:>8.3f}"
531
531
  f"{occupancy[i]:>6.2f}"
532
532
  f"{b_factor[i]:>6.2f} "
533
533
  f"{charges[i]:>6.3f} "
@@ -604,7 +604,7 @@ class PDBQTFile(TextFile):
604
604
  length = model_length
605
605
  if model_length != length:
606
606
  raise InvalidFileError(
607
- f"Model {model_i+1} has {model_length} atoms, "
607
+ f"Model {model_i + 1} has {model_length} atoms, "
608
608
  f"but model 1 has {length} atoms, must be equal"
609
609
  )
610
610
  return length
@@ -18,5 +18,6 @@ __author__ = "Patrick Kunzmann"
18
18
  from .bcif import *
19
19
  from .cif import *
20
20
  from .component import *
21
+ from .compress import *
21
22
  from .convert import *
22
23
  from .encoding import *
@@ -38,8 +38,9 @@ class BinaryCIFData(_Component):
38
38
  array : array_like or int or float or str
39
39
  The data array to be stored.
40
40
  If a single item is given, it is converted into an array.
41
- encoding : list of Encoding
41
+ encoding : list of Encoding , optional
42
42
  The encoding steps that are successively applied to the data.
43
+ By default, the data is stored uncompressed directly as bytes.
43
44
 
44
45
  Attributes
45
46
  ----------
@@ -61,7 +62,7 @@ class BinaryCIFData(_Component):
61
62
  >>> print(data.array)
62
63
  ['apple']
63
64
 
64
- Well-chosen encoding can significantly reduce the serialized data
65
+ A well-chosen encoding can significantly reduce the serialized data
65
66
  size:
66
67
 
67
68
  >>> # Default uncompressed encoding
@@ -194,7 +195,7 @@ class BinaryCIFColumn(_Component):
194
195
  mask = BinaryCIFData(mask)
195
196
  if len(data) != len(mask):
196
197
  raise IndexError(
197
- f"Data has length {len(data)}, " f"but mask has length {len(mask)}"
198
+ f"Data has length {len(data)}, but mask has length {len(mask)}"
198
199
  )
199
200
  self._data = data
200
201
  self._mask = mask
@@ -255,6 +256,11 @@ class BinaryCIFColumn(_Component):
255
256
  ``MaskValue.INAPPLICABLE`` or ``MaskValue.MISSING``.
256
257
  By default, masked elements are converted to ``'.'`` or
257
258
  ``'?'`` depending on the :class:`MaskValue`.
259
+
260
+ Returns
261
+ -------
262
+ array : ndarray
263
+ The column data as array.
258
264
  """
259
265
  if dtype is None:
260
266
  dtype = self._data.array.dtype
@@ -340,12 +346,15 @@ class BinaryCIFCategory(_HierarchicalContainer):
340
346
  into a :class:`BinaryCIFColumn`).
341
347
  By default, an empty category is created.
342
348
  Each column must have the same length.
349
+ row_count : int, optional
350
+ The number of rows in the category.
343
351
 
344
352
  Attributes
345
353
  ----------
346
354
  row_count : int
347
355
  The number of rows in the category, i.e. the length of each
348
356
  column.
357
+ By default, the row count is determined when the first column is added.
349
358
 
350
359
  Examples
351
360
  --------
@@ -457,7 +466,12 @@ class BinaryCIFBlock(_HierarchicalContainer):
457
466
  """
458
467
 
459
468
  def __init__(self, categories=None):
460
- super().__init__(categories)
469
+ if categories is None:
470
+ categories = {}
471
+ super().__init__(
472
+ # Actual bcif files use leading '_' as category names
473
+ {"_" + name: category for name, category in categories.items()}
474
+ )
461
475
 
462
476
  @staticmethod
463
477
  def subcomponent_class():
@@ -470,25 +484,43 @@ class BinaryCIFBlock(_HierarchicalContainer):
470
484
  @staticmethod
471
485
  def deserialize(content):
472
486
  return BinaryCIFBlock(
473
- BinaryCIFBlock._deserialize_elements(content["categories"], "name")
487
+ {
488
+ # The superclass uses leading '_' in category names,
489
+ # but on the level of this class, the leading '_' is omitted
490
+ name.lstrip("_"): category
491
+ for name, category in BinaryCIFBlock._deserialize_elements(
492
+ content["categories"], "name"
493
+ ).items()
494
+ }
474
495
  )
475
496
 
476
497
  def serialize(self):
477
498
  return {"categories": self._serialize_elements("name")}
478
499
 
479
500
  def __getitem__(self, key):
480
- # Actual bcif files use leading '_' as categories
481
- return super().__getitem__("_" + key)
501
+ try:
502
+ return super().__getitem__("_" + key)
503
+ except KeyError:
504
+ raise KeyError(key)
482
505
 
483
506
  def __setitem__(self, key, element):
484
- return super().__setitem__("_" + key, element)
507
+ try:
508
+ return super().__setitem__("_" + key, element)
509
+ except KeyError:
510
+ raise KeyError(key)
485
511
 
486
512
  def __delitem__(self, key):
487
- return super().__setitem__("_" + key)
513
+ try:
514
+ return super().__setitem__("_" + key)
515
+ except KeyError:
516
+ raise KeyError(key)
488
517
 
489
518
  def __iter__(self):
490
519
  return (key.lstrip("_") for key in super().__iter__())
491
520
 
521
+ def __contains__(self, key):
522
+ return super().__contains__("_" + key)
523
+
492
524
 
493
525
  class BinaryCIFFile(File, _HierarchicalContainer):
494
526
  """
@@ -502,6 +534,19 @@ class BinaryCIFFile(File, _HierarchicalContainer):
502
534
  object, use the high-level :func:`get_structure()` or
503
535
  :func:`set_structure()` function respectively.
504
536
 
537
+ Parameters
538
+ ----------
539
+ blocks : dict (str -> BinaryCIFBlock), optional
540
+ The initial blocks of the file.
541
+ Maps the block names to the corresponding :class:`BinaryCIFBlock` objects.
542
+ By default no initial blocks are added.
543
+
544
+ Attributes
545
+ ----------
546
+ block : BinaryCIFBlock
547
+ The sole block of the file.
548
+ If the file contains multiple blocks, an exception is raised.
549
+
505
550
  Notes
506
551
  -----
507
552
  The content of *BinaryCIF* files are lazily deserialized:
@@ -510,12 +555,6 @@ class BinaryCIFFile(File, _HierarchicalContainer):
510
555
  The decoded :class:`BinaryCIFBlock`/:class:`BinaryCIFCategory`
511
556
  objects are cached for subsequent accesses.
512
557
 
513
- Attributes
514
- ----------
515
- block : BinaryCIFBlock
516
- The sole block of the file.
517
- If the file contains multiple blocks, an exception is raised.
518
-
519
558
  Examples
520
559
  --------
521
560
  Read a *BinaryCIF* file and access its content: