biotite 1.0.0__cp310-cp310-win_amd64.whl → 1.0.1__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 (31) hide show
  1. biotite/sequence/align/banded.cp310-win_amd64.pyd +0 -0
  2. biotite/sequence/align/kmeralphabet.cp310-win_amd64.pyd +0 -0
  3. biotite/sequence/align/kmersimilarity.cp310-win_amd64.pyd +0 -0
  4. biotite/sequence/align/kmertable.cp310-win_amd64.pyd +0 -0
  5. biotite/sequence/align/localgapped.cp310-win_amd64.pyd +0 -0
  6. biotite/sequence/align/localungapped.cp310-win_amd64.pyd +0 -0
  7. biotite/sequence/align/multiple.cp310-win_amd64.pyd +0 -0
  8. biotite/sequence/align/pairwise.cp310-win_amd64.pyd +0 -0
  9. biotite/sequence/align/permutation.cp310-win_amd64.pyd +0 -0
  10. biotite/sequence/align/selector.cp310-win_amd64.pyd +0 -0
  11. biotite/sequence/align/tracetable.cp310-win_amd64.pyd +0 -0
  12. biotite/sequence/codec.cp310-win_amd64.pyd +0 -0
  13. biotite/sequence/phylo/nj.cp310-win_amd64.pyd +0 -0
  14. biotite/sequence/phylo/tree.cp310-win_amd64.pyd +0 -0
  15. biotite/sequence/phylo/upgma.cp310-win_amd64.pyd +0 -0
  16. biotite/structure/atoms.py +27 -3
  17. biotite/structure/bonds.cp310-win_amd64.pyd +0 -0
  18. biotite/structure/celllist.cp310-win_amd64.pyd +0 -0
  19. biotite/structure/charges.cp310-win_amd64.pyd +0 -0
  20. biotite/structure/filter.py +1 -1
  21. biotite/structure/io/pdb/hybrid36.cp310-win_amd64.pyd +0 -0
  22. biotite/structure/io/pdbx/cif.py +79 -51
  23. biotite/structure/io/pdbx/convert.py +34 -21
  24. biotite/structure/io/pdbx/encoding.cp310-win_amd64.pyd +0 -0
  25. biotite/structure/io/trajfile.py +16 -16
  26. biotite/structure/sasa.cp310-win_amd64.pyd +0 -0
  27. biotite/version.py +2 -2
  28. {biotite-1.0.0.dist-info → biotite-1.0.1.dist-info}/METADATA +2 -1
  29. {biotite-1.0.0.dist-info → biotite-1.0.1.dist-info}/RECORD +31 -31
  30. {biotite-1.0.0.dist-info → biotite-1.0.1.dist-info}/WHEEL +0 -0
  31. {biotite-1.0.0.dist-info → biotite-1.0.1.dist-info}/licenses/LICENSE.rst +0 -0
Binary file
@@ -99,9 +99,24 @@ class _AtomArrayBase(Copyable, metaclass=abc.ABCMeta):
99
99
  See Also
100
100
  --------
101
101
  set_annotation
102
+
103
+ Notes
104
+ -----
105
+ If the annotation category already exists, a compatible dtype is chosen,
106
+ that is also able to represent the old values.
102
107
  """
103
108
  if category not in self._annot:
104
109
  self._annot[str(category)] = np.zeros(self._array_length, dtype=dtype)
110
+ elif np.can_cast(self._annot[str(category)].dtype, dtype):
111
+ self._annot[str(category)] = self._annot[str(category)].astype(dtype)
112
+ elif np.can_cast(dtype, self._annot[str(category)].dtype):
113
+ # The existing dtype is more general
114
+ pass
115
+ else:
116
+ raise ValueError(
117
+ f"Cannot cast '{str(category)}' "
118
+ f"with dtype '{self._annot[str(category)].dtype}' into '{dtype}'"
119
+ )
105
120
 
106
121
  def del_annotation(self, category):
107
122
  """
@@ -145,16 +160,25 @@ class _AtomArrayBase(Copyable, metaclass=abc.ABCMeta):
145
160
  array : ndarray or None
146
161
  The new value of the annotation category. The size of the
147
162
  array must be the same as the array length.
163
+
164
+ Notes
165
+ -----
166
+ If the annotation category already exists, a compatible dtype is chosen,
167
+ that is able to represent the old and new array values.
148
168
  """
169
+ array = np.asarray(array)
149
170
  if len(array) != self._array_length:
150
171
  raise IndexError(
151
172
  f"Expected array length {self._array_length}, " f"but got {len(array)}"
152
173
  )
153
174
  if category in self._annot:
154
- # Keep the dtype if the annotation already exists
155
- self._annot[category] = np.asarray(array, dtype=self._annot[category].dtype)
175
+ # If the annotation already exists, find the compatible dtype
176
+ self._annot[category] = array.astype(
177
+ dtype=np.promote_types(self._annot[category].dtype, array.dtype),
178
+ copy=False,
179
+ )
156
180
  else:
157
- self._annot[category] = np.asarray(array)
181
+ self._annot[category] = array
158
182
 
159
183
  def get_annotation_categories(self):
160
184
  """
Binary file
@@ -577,7 +577,7 @@ def filter_highest_occupancy_altloc(atoms, altloc_ids, occupancies):
577
577
  if len(letter_altloc_ids) > 0:
578
578
  highest = -1.0
579
579
  highest_id = None
580
- for id in set(letter_altloc_ids):
580
+ for id in sorted(set(letter_altloc_ids)):
581
581
  occupancy_sum = np.sum(occupancies_in_res[altloc_ids_in_res == id])
582
582
  if occupancy_sum > highest:
583
583
  highest = occupancy_sum
@@ -370,7 +370,7 @@ class CIFCategory(_Component, MutableMapping):
370
370
  if category_name is None:
371
371
  raise DeserializationError("Failed to parse category name")
372
372
 
373
- lines = _to_single(lines, is_looped)
373
+ lines = _to_single(lines)
374
374
  if is_looped:
375
375
  category_dict = CIFCategory._deserialize_looped(lines, expect_whitespace)
376
376
  else:
@@ -439,11 +439,28 @@ class CIFCategory(_Component, MutableMapping):
439
439
  Process a category where each field has a single value.
440
440
  """
441
441
  category_dict = {}
442
- for line in lines:
442
+ line_i = 0
443
+ while line_i < len(lines):
444
+ line = lines[line_i]
443
445
  parts = _split_one_line(line)
444
- column_name = parts[0].split(".")[1]
445
- column = parts[1]
446
- category_dict[column_name] = CIFColumn(column)
446
+ if len(parts) == 2:
447
+ # Standard case -> name and value in one line
448
+ name_part, value_part = parts
449
+ line_i += 1
450
+ elif len(parts) == 1:
451
+ # Value is a multiline value on the next line
452
+ name_part = parts[0]
453
+ parts = _split_one_line(lines[line_i + 1])
454
+ if len(parts) == 1:
455
+ value_part = parts[0]
456
+ else:
457
+ raise DeserializationError(f"Failed to parse line '{line}'")
458
+ line_i += 2
459
+ elif len(parts) == 0:
460
+ raise DeserializationError("Empty line within category")
461
+ else:
462
+ raise DeserializationError(f"Failed to parse line '{line}'")
463
+ category_dict[name_part.split(".")[1]] = CIFColumn(value_part)
447
464
  return category_dict
448
465
 
449
466
  @staticmethod
@@ -468,7 +485,7 @@ class CIFCategory(_Component, MutableMapping):
468
485
  data_lines = lines[i:]
469
486
  # Rows may be split over multiple lines -> do not rely on
470
487
  # row-line-alignment at all and simply cycle through columns
471
- column_names = itertools.cycle(column_names)
488
+ column_indices = itertools.cycle(range(len(column_names)))
472
489
  for data_line in data_lines:
473
490
  # If whitespace is expected in quote protected values,
474
491
  # use regex-based _split_one_line() to split
@@ -485,9 +502,18 @@ class CIFCategory(_Component, MutableMapping):
485
502
  ):
486
503
  values[k] = values[k][1:-1]
487
504
  for val in values:
488
- column_name = next(column_names)
505
+ column_index = next(column_indices)
506
+ column_name = column_names[column_index]
489
507
  category_dict[column_name].append(val)
490
508
 
509
+ # Check if all columns have the same length
510
+ # Otherwise, this would indicate a parsing error or an invalid CIF file
511
+ column_index = next(column_indices)
512
+ if column_index != 0:
513
+ raise DeserializationError(
514
+ "Category contains columns with different lengths"
515
+ )
516
+
491
517
  return category_dict
492
518
 
493
519
  def _serialize_single(self):
@@ -496,7 +522,8 @@ class CIFCategory(_Component, MutableMapping):
496
522
  # "+3" Because of three whitespace chars after longest key
497
523
  req_len = max_len + 3
498
524
  return [
499
- key.ljust(req_len) + _multiline(_quote(column.as_item()))
525
+ # Remove potential terminal newlines from multiline values
526
+ (key.ljust(req_len) + _escape(column.as_item())).strip()
500
527
  for key, column in zip(keys, self.values())
501
528
  ]
502
529
 
@@ -508,7 +535,7 @@ class CIFCategory(_Component, MutableMapping):
508
535
  array = column.as_array(str)
509
536
  # Quote before measuring the number of chars,
510
537
  # as the quote characters modify the length
511
- array = np.array([_multiline(_quote(element)) for element in array])
538
+ array = np.array([_escape(element) for element in array])
512
539
  column_arrays.append(array)
513
540
 
514
541
  # Number of characters the longest string in the column needs
@@ -522,7 +549,8 @@ class CIFCategory(_Component, MutableMapping):
522
549
  for j, array in enumerate(column_arrays):
523
550
  value_lines[i] += array[i].ljust(column_n_chars[j])
524
551
  # Remove trailing justification of last column
525
- value_lines[i].rstrip()
552
+ # and potential terminal newlines from multiline values
553
+ value_lines[i] = value_lines[i].strip()
526
554
 
527
555
  return ["loop_"] + key_lines + value_lines
528
556
 
@@ -927,52 +955,50 @@ def _is_loop_start(line):
927
955
  return line.startswith("loop_")
928
956
 
929
957
 
930
- def _to_single(lines, is_looped):
931
- """
958
+ def _to_single(lines):
959
+ r"""
932
960
  Convert multiline values into singleline values
933
961
  (in terms of 'lines' list elements).
934
- Linebreaks are preserved.
962
+ Linebreaks are preserved as ``'\n'`` characters within a list element.
963
+ The initial ``';'`` character is also preserved, while the final ``';'`` character
964
+ is removed.
935
965
  """
936
- processed_lines = [None] * len(lines)
937
- in_i = 0
938
- out_i = 0
939
- while in_i < len(lines):
940
- if lines[in_i][0] == ";":
941
- # Multiline value
942
- multi_line_str = lines[in_i][1:]
943
- j = in_i + 1
944
- while lines[j] != ";":
945
- # Preserve linebreaks
946
- multi_line_str += "\n" + lines[j]
947
- j += 1
948
- if is_looped:
949
- # Create a line for the multiline string only
950
- processed_lines[out_i] = f"'{multi_line_str}'"
951
- out_i += 1
966
+ processed_lines = []
967
+ in_multi_line = False
968
+ mutli_line_value = []
969
+ for line in lines:
970
+ # Multiline value are enclosed by ';' at the start of the beginning and end line
971
+ if line[0] == ";":
972
+ if not in_multi_line:
973
+ # Start of multiline value
974
+ in_multi_line = True
975
+ mutli_line_value.append(line)
952
976
  else:
953
- # Append multiline string to previous line
954
- processed_lines[out_i - 1] += " " + f"'{multi_line_str}'"
955
- in_i = j + 1
956
-
957
- elif not is_looped and lines[in_i][0] != "_":
958
- # Singleline value in the line after the corresponding key
959
- processed_lines[out_i - 1] += " " + lines[in_i]
960
- in_i += 1
961
-
977
+ # End of multiline value
978
+ in_multi_line = False
979
+ # The current line contains only the end character ';'
980
+ # Hence this line is not added to the processed lines
981
+ processed_lines.append("\n".join(mutli_line_value))
982
+ mutli_line_value = []
962
983
  else:
963
- # Normal singleline value in the same row as the key
964
- processed_lines[out_i] = lines[in_i]
965
- in_i += 1
966
- out_i += 1
967
-
968
- return [line for line in processed_lines if line is not None]
984
+ if in_multi_line:
985
+ mutli_line_value.append(line)
986
+ else:
987
+ processed_lines.append(line)
988
+ return processed_lines
969
989
 
970
990
 
971
- def _quote(value):
991
+ def _escape(value):
972
992
  """
973
- A less secure but much quicker version of ``shlex.quote()``.
993
+ Escape special characters in a value to make it compatible with CIF.
974
994
  """
975
- if len(value) == 0:
995
+ if "\n" in value:
996
+ # A value with linebreaks must be represented as multiline value
997
+ return _multiline(value)
998
+ elif "'" in value and '"' in value:
999
+ # If both quote types are present, you cannot use them for escaping
1000
+ return _multiline(value)
1001
+ elif len(value) == 0:
976
1002
  return "''"
977
1003
  elif value[0] == "_":
978
1004
  return "'" + value + "'"
@@ -990,12 +1016,10 @@ def _quote(value):
990
1016
 
991
1017
  def _multiline(value):
992
1018
  """
993
- Convert a string containing linebreaks into CIF-compatible
1019
+ Convert a string that may contain linebreaks into CIF-compatible
994
1020
  multiline string.
995
1021
  """
996
- if "\n" in value:
997
- return "\n;" + value + "\n;\n"
998
- return value
1022
+ return "\n;" + value + "\n;\n"
999
1023
 
1000
1024
 
1001
1025
  def _split_one_line(line):
@@ -1003,6 +1027,10 @@ def _split_one_line(line):
1003
1027
  Split a line into its fields.
1004
1028
  Supporting embedded quotes (' or "), like `'a dog's life'` to `a dog's life`
1005
1029
  """
1030
+ # Special case of multiline value, where the line starts with ';'
1031
+ if line[0] == ";":
1032
+ return [line[1:]]
1033
+
1006
1034
  # Define the patterns for different types of fields
1007
1035
  single_quote_pattern = r"('(?:'(?! )|[^'])*')(?:\s|$)"
1008
1036
  double_quote_pattern = r'("(?:"(?! )|[^"])*")(?:\s|$)'
@@ -450,7 +450,7 @@ def _fill_annotations(array, atom_site, extra_fields, use_author_fields):
450
450
  "chain_id",
451
451
  _get_or_fallback(
452
452
  atom_site, f"{prefix}_asym_id", f"{alt_prefix}_asym_id"
453
- ).as_array("U4"),
453
+ ).as_array(str),
454
454
  )
455
455
  array.set_annotation(
456
456
  "res_id",
@@ -458,21 +458,21 @@ def _fill_annotations(array, atom_site, extra_fields, use_author_fields):
458
458
  atom_site, f"{prefix}_seq_id", f"{alt_prefix}_seq_id"
459
459
  ).as_array(int, -1),
460
460
  )
461
- array.set_annotation("ins_code", atom_site["pdbx_PDB_ins_code"].as_array("U1", ""))
461
+ array.set_annotation("ins_code", atom_site["pdbx_PDB_ins_code"].as_array(str, ""))
462
462
  array.set_annotation(
463
463
  "res_name",
464
464
  _get_or_fallback(
465
465
  atom_site, f"{prefix}_comp_id", f"{alt_prefix}_comp_id"
466
- ).as_array("U5"),
466
+ ).as_array(str),
467
467
  )
468
468
  array.set_annotation("hetero", atom_site["group_PDB"].as_array(str) == "HETATM")
469
469
  array.set_annotation(
470
470
  "atom_name",
471
471
  _get_or_fallback(
472
472
  atom_site, f"{prefix}_atom_id", f"{alt_prefix}_atom_id"
473
- ).as_array("U6"),
473
+ ).as_array(str),
474
474
  )
475
- array.set_annotation("element", atom_site["type_symbol"].as_array("U2"))
475
+ array.set_annotation("element", atom_site["type_symbol"].as_array(str))
476
476
 
477
477
  if "atom_id" in extra_fields:
478
478
  array.set_annotation("atom_id", atom_site["id"].as_array(int))
@@ -577,7 +577,7 @@ def _parse_inter_residue_bonds(atom_site, struct_conn):
577
577
  atoms_indices_2 = atoms_indices_2[mapping_exists_mask]
578
578
 
579
579
  # Interpret missing values as ANY bonds
580
- bond_order = struct_conn["pdbx_value_order"].as_array("U4", "")
580
+ bond_order = struct_conn["pdbx_value_order"].as_array(str, "")
581
581
  # Consecutively apply the same masks as applied to the atom indices
582
582
  # Logical combination does not work here,
583
583
  # as the second mask was created based on already filtered data
@@ -964,25 +964,38 @@ def _set_intra_residue_bonds(array, atom_site):
964
964
  aromatic_flag[i] = aromatic
965
965
  any_mask = bond_array[:, 2] == BondType.ANY
966
966
 
967
- chem_comp_bond = Category()
967
+ # Remove already existing residue and atom name combinations
968
+ # These appear when the structure contains a residue multiple times
969
+ atom_id_1 = array.atom_name[bond_array[:, 0]]
970
+ atom_id_2 = array.atom_name[bond_array[:, 1]]
968
971
  # Take the residue name from the first atom index, as the residue
969
972
  # name is the same for both atoms, since we have only intra bonds
970
- chem_comp_bond["comp_id"] = array.res_name[bond_array[:, 0]]
971
- chem_comp_bond["atom_id_1"] = array.atom_name[bond_array[:, 0]]
972
- chem_comp_bond["atom_id_2"] = array.atom_name[bond_array[:, 1]]
973
+ comp_id = array.res_name[bond_array[:, 0]]
974
+ _, unique_indices = np.unique(
975
+ np.stack([comp_id, atom_id_1, atom_id_2], axis=-1), axis=0, return_index=True
976
+ )
977
+ unique_indices.sort()
978
+
979
+ chem_comp_bond = Category()
980
+ n_bonds = len(unique_indices)
981
+ chem_comp_bond["pdbx_ordinal"] = np.arange(1, n_bonds + 1, dtype=np.int32)
982
+ chem_comp_bond["comp_id"] = comp_id[unique_indices]
983
+ chem_comp_bond["atom_id_1"] = atom_id_1[unique_indices]
984
+ chem_comp_bond["atom_id_2"] = atom_id_2[unique_indices]
973
985
  chem_comp_bond["value_order"] = Column(
974
- value_order, np.where(any_mask, MaskValue.MISSING, MaskValue.PRESENT)
986
+ value_order[unique_indices],
987
+ np.where(any_mask[unique_indices], MaskValue.MISSING, MaskValue.PRESENT),
975
988
  )
976
989
  chem_comp_bond["pdbx_aromatic_flag"] = Column(
977
- aromatic_flag, np.where(any_mask, MaskValue.MISSING, MaskValue.PRESENT)
990
+ aromatic_flag[unique_indices],
991
+ np.where(any_mask[unique_indices], MaskValue.MISSING, MaskValue.PRESENT),
978
992
  )
979
993
  # BondList does not contain stereo information
980
994
  # -> all values are missing
981
995
  chem_comp_bond["pdbx_stereo_config"] = Column(
982
- np.zeros(len(bond_array), dtype="U1"),
983
- np.full(len(bond_array), MaskValue.MISSING),
996
+ np.zeros(n_bonds, dtype="U1"),
997
+ np.full(n_bonds, MaskValue.MISSING),
984
998
  )
985
- chem_comp_bond["pdbx_ordinal"] = np.arange(1, len(bond_array) + 1, dtype=np.int32)
986
999
  return chem_comp_bond
987
1000
 
988
1001
 
@@ -1007,6 +1020,7 @@ def _set_inter_residue_bonds(array, atom_site):
1007
1020
  bond_array = _filter_bonds(array, "inter")
1008
1021
  if len(bond_array) == 0:
1009
1022
  return None
1023
+
1010
1024
  struct_conn = Category()
1011
1025
  struct_conn["id"] = np.arange(1, len(bond_array) + 1)
1012
1026
  struct_conn["conn_type_id"] = np.full(len(bond_array), "covale")
@@ -1135,12 +1149,11 @@ def get_component(pdbx_file, data_block=None, use_ideal_coord=True, res_name=Non
1135
1149
 
1136
1150
  array = AtomArray(atom_category.row_count)
1137
1151
 
1138
- array.hetero[:] = True
1139
- array.res_name = atom_category["comp_id"].as_array("U5")
1140
- array.atom_name = atom_category["atom_id"].as_array("U6")
1141
- array.element = atom_category["type_symbol"].as_array("U2")
1142
- array.add_annotation("charge", int)
1143
- array.charge = atom_category["charge"].as_array(int, 0)
1152
+ array.set_annotation("hetero", np.full(len(atom_category["comp_id"]), True))
1153
+ array.set_annotation("res_name", atom_category["comp_id"].as_array(str))
1154
+ array.set_annotation("atom_name", atom_category["atom_id"].as_array(str))
1155
+ array.set_annotation("element", atom_category["type_symbol"].as_array(str))
1156
+ array.set_annotation("charge", atom_category["charge"].as_array(int, 0))
1144
1157
 
1145
1158
  coord_fields = [f"pdbx_model_Cartn_{dim}_ideal" for dim in ("x", "y", "z")]
1146
1159
  alt_coord_fields = [f"model_Cartn_{dim}" for dim in ("x", "y", "z")]
@@ -54,9 +54,9 @@ class TrajectoryFile(File, metaclass=abc.ABCMeta):
54
54
 
55
55
  Parameters
56
56
  ----------
57
- file_name : str
57
+ file_name : str or Path
58
58
  The path of the file to be read.
59
- A file-like-object cannot be used.
59
+ Any other file-like object cannot be used.
60
60
  start : int, optional
61
61
  The frame index, where file parsing is started. If no value
62
62
  is given, parsing starts at the first frame.
@@ -101,7 +101,7 @@ class TrajectoryFile(File, metaclass=abc.ABCMeta):
101
101
  chunk_size = ((chunk_size // step) + 1) * step
102
102
 
103
103
  traj_type = cls.traj_type()
104
- with traj_type(file_name, "r") as f:
104
+ with traj_type(str(file_name), "r") as f:
105
105
  if start is None:
106
106
  start = 0
107
107
  # Discard atoms before start
@@ -153,9 +153,9 @@ class TrajectoryFile(File, metaclass=abc.ABCMeta):
153
153
 
154
154
  Parameters
155
155
  ----------
156
- file_name : str
156
+ file_name : str or Path
157
157
  The path of the file to be read.
158
- A file-like-object cannot be used.
158
+ Any other file-like object cannot be used.
159
159
  start : int, optional
160
160
  The frame index, where file parsing is started. If no value
161
161
  is given, parsing starts at the first frame.
@@ -196,7 +196,7 @@ class TrajectoryFile(File, metaclass=abc.ABCMeta):
196
196
  The `step` parameter does currently not work for *DCD* files.
197
197
  """
198
198
  traj_type = cls.traj_type()
199
- with traj_type(file_name, "r") as f:
199
+ with traj_type(str(file_name), "r") as f:
200
200
  if start is None:
201
201
  start = 0
202
202
  # Discard atoms before start
@@ -280,9 +280,9 @@ class TrajectoryFile(File, metaclass=abc.ABCMeta):
280
280
 
281
281
  Parameters
282
282
  ----------
283
- file_name : str
283
+ file_name : str or Path
284
284
  The path of the file to be read.
285
- A file-like-object cannot be used.
285
+ Any other file-like object cannot be used.
286
286
  template : AtomArray or AtomArrayStack
287
287
  The template array or stack, where the atom annotation data
288
288
  is taken from.
@@ -354,13 +354,13 @@ class TrajectoryFile(File, metaclass=abc.ABCMeta):
354
354
 
355
355
  Parameters
356
356
  ----------
357
- file_name : str
358
- The path of the file to be written to.
359
- A file-like-object cannot be used.
357
+ file_name : str or Path
358
+ The path of the file to be read.
359
+ Any other file-like object cannot be used.
360
360
  """
361
361
  traj_type = self.traj_type()
362
362
  param = self.prepare_write_values(self._coord, self._box, self._time)
363
- with traj_type(file_name, "w") as f:
363
+ with traj_type(str(file_name), "w") as f:
364
364
  f.write(**param)
365
365
 
366
366
  @classmethod
@@ -378,9 +378,9 @@ class TrajectoryFile(File, metaclass=abc.ABCMeta):
378
378
 
379
379
  Parameters
380
380
  ----------
381
- file_name : str
382
- The path of the file to be written to.
383
- A file-like-object cannot be used.
381
+ file_name : str or Path
382
+ The path of the file to be read.
383
+ Any other file-like object cannot be used.
384
384
  coord : generator or array-like of ndarray, shape=(n,3), dtype=float
385
385
  The atom coordinates for each frame.
386
386
  box : generator or array-like of ndarray, shape=(3,3), dtype=float, optional
@@ -398,7 +398,7 @@ class TrajectoryFile(File, metaclass=abc.ABCMeta):
398
398
  time = itertools.repeat(None)
399
399
 
400
400
  traj_type = cls.traj_type()
401
- with traj_type(file_name, "w") as f:
401
+ with traj_type(str(file_name), "w") as f:
402
402
  for c, b, t in zip(coord, box, time):
403
403
  if c.ndim != 2:
404
404
  raise IndexError(
Binary file
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 = '1.0.0'
16
- __version_tuple__ = version_tuple = (1, 0, 0)
15
+ __version__ = version = '1.0.1'
16
+ __version_tuple__ = version_tuple = (1, 0, 1)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: biotite
3
- Version: 1.0.0
3
+ Version: 1.0.1
4
4
  Summary: A comprehensive library for computational molecular biology
5
5
  Project-URL: homepage, https://www.biotite-python.org
6
6
  Project-URL: repository, https://github.com/biotite-dev/biotite
@@ -56,6 +56,7 @@ Requires-Dist: numpy>=1.25
56
56
  Requires-Dist: requests>=2.12
57
57
  Provides-Extra: test
58
58
  Requires-Dist: pytest; extra == 'test'
59
+ Requires-Dist: pytest-codspeed; extra == 'test'
59
60
  Description-Content-Type: text/x-rst
60
61
 
61
62
  .. image:: https://img.shields.io/pypi/v/biotite.svg
@@ -1,7 +1,7 @@
1
1
  biotite/__init__.py,sha256=gzqOy5P7Zf667uYuUwqjLLW0GiBdqc23NLcZaXMuHKw,563
2
2
  biotite/copyable.py,sha256=Qnja44k58dAc3WkIUM0svqrbvqO9pSV-Atr9MUJSoCI,1968
3
3
  biotite/file.py,sha256=oZdBRv34nrGFJ7ZIrSW9uf4NSk9H3Mg0WxgbQqxibbU,6756
4
- biotite/version.py,sha256=dJiaCltLFgci5aFfMnwDnv8BAhveHDCtWSHatUxAG1Q,427
4
+ biotite/version.py,sha256=XglbmfebHuSdifAMbIgy8xq3Isq3dxwcF1ZQoKBpUa0,427
5
5
  biotite/visualize.py,sha256=d926kscZJdQKYM9v7CUaAeMial11N8l_NyC7_fVv7wQ,10277
6
6
  biotite/application/__init__.py,sha256=Rei3EwlpCnC_cJNQoTJYY_Gw_qLdsqgnRxV5b1slHJU,3148
7
7
  biotite/application/application.py,sha256=WKGVuCJ5WTwuoOmSWAklZwAGbEgJaTdf3fFmb4f1Iv8,8374
@@ -217,7 +217,7 @@ biotite/sequence/phylo/nj.pyx,sha256=YOseJP7fKCnqhh8w3mK1z3fw6cKF5sU5oRkb1D3X9vI
217
217
  biotite/sequence/phylo/tree.pyx,sha256=kmT2kO9cH3svQOxsyuPLfbUsWnTNdfVrx5xaxcmTC3I,40374
218
218
  biotite/sequence/phylo/upgma.pyx,sha256=llgc-9fEOU-D1a-ESMSIAoPjHvsd_L0-GnwkL-uzWNc,5376
219
219
  biotite/structure/__init__.py,sha256=KwHwWyOA4EETmuAvS894YV7jWXopuCh1CWfKY9rmfCc,5456
220
- biotite/structure/atoms.py,sha256=sSheTLrfkEFQTh2aD3I4WVym-UMndS1v4iNsAfsMrAs,47922
220
+ biotite/structure/atoms.py,sha256=6eFRFYTXVokF-0NehXxhxcP_AoWxZKjJGk-UpP-Iig8,48876
221
221
  biotite/structure/basepairs.py,sha256=eZF67fnecHkvDYnIlfeejdJC7sCDWYqOghjbweLoxFE,51163
222
222
  biotite/structure/bonds.pyx,sha256=hR_vTYigOv06EdV9TnxdGFSM6WdZrCAV6w9coquSFWg,69917
223
223
  biotite/structure/box.py,sha256=zp80_Q4Xv5t2KIfrSK-SachkIbbK1mctl91mVrk5T3A,19186
@@ -228,7 +228,7 @@ biotite/structure/compare.py,sha256=jf4L3xuPz_ZBNhdMHpxNaEu27qVgy5z1mXRz-dfoyFc,
228
228
  biotite/structure/density.py,sha256=jlWog4xJcaHRvtMiLQueeJJwzIH3ZnRiZSb-ZCDq9B8,4305
229
229
  biotite/structure/dotbracket.py,sha256=MjJf6x67jME_tdFhKGhQtGUpwsgJkHKjmNL77bpxG7c,7048
230
230
  biotite/structure/error.py,sha256=NaQBi7CGUYpa7-Y9t0We8iVEJwqpsNWLXkr1PTBKlxQ,822
231
- biotite/structure/filter.py,sha256=fDEC0XT_4EGFpgDPAViDRr_BDuaHI_CXOLOmCoTMJUA,18549
231
+ biotite/structure/filter.py,sha256=e3xLwZobrhRJ-7uX4HeerstE5sC8b7RpIJ_mg9TTPEM,18557
232
232
  biotite/structure/geometry.py,sha256=1myUT4HVwMzcz6e_CA2yf6BOKPx5ZFK4xCykA_wLHm0,25766
233
233
  biotite/structure/hbond.py,sha256=7eULKwg94uQY2G-3ea8M0yOOHi0-tl_2TV-Ia2lzLhI,15646
234
234
  biotite/structure/integrity.py,sha256=ubkv2vA5yhb-3GIsX4ZHsAGiB-zQ30Pr_hUlpWHJcHw,7041
@@ -265,7 +265,7 @@ biotite/structure/info/ccd/components.bcif,sha256=xgvErxils9GNg5s0sGI33B7w4lWeUB
265
265
  biotite/structure/info/ccd/nucleotides.txt,sha256=rVTN65IGs1rfwDzjdhiaIZQ3mCGg3WvllNPSUWCBsoY,3934
266
266
  biotite/structure/io/__init__.py,sha256=d9zsCIGeTRQ_R8n5xBwi5jrfanRMEeCIh9E9xjmnqVQ,1027
267
267
  biotite/structure/io/general.py,sha256=uZPbBq35Mp4TuqxAEMWFhUztvolzUzAxSKXXdMI6Pb8,8691
268
- biotite/structure/io/trajfile.py,sha256=Jcr_vnBt4kumgF0aqZvVPXAH-blDU0Txf_4ak40rIKo,25789
268
+ biotite/structure/io/trajfile.py,sha256=XnLmQ7AvD9mIbSclgQqAev069qqCL0hBRBG6mXtUO8k,25877
269
269
  biotite/structure/io/dcd/__init__.py,sha256=oy8P1khM60o8M5grpSoGNZkudTBrTUPF33xuLub5sNQ,401
270
270
  biotite/structure/io/dcd/file.py,sha256=zLvngfNmF8pBM6J6kw-i_-rtFiJj1Bh4HSCAmN0EegI,2291
271
271
  biotite/structure/io/gro/__init__.py,sha256=jPh0RWv2vbpmgB0U0lZ6yo7SkVZycYfx2UQqKWCkOHg,422
@@ -287,36 +287,36 @@ biotite/structure/io/pdbqt/convert.py,sha256=M2SytCYO2ihvpcUQCqz4PD4DAKwCPxcjGbh
287
287
  biotite/structure/io/pdbqt/file.py,sha256=aXhDPIkoDrQEoZm5-iPCF0JwRdrsHocezLNUzHjPO2A,27321
288
288
  biotite/structure/io/pdbx/__init__.py,sha256=6l-w3pEY3LYCnVC55bFe50K5nEFCk1zxzgacV1sQ4H8,715
289
289
  biotite/structure/io/pdbx/bcif.py,sha256=9yoYIW6ea617mz461ps5bqMc36OEjuNi2uk9Cp4odCw,20452
290
- biotite/structure/io/pdbx/cif.py,sha256=tqzZYc7Vx9pzexajDZ1EE2FVA3x_3Ujyd2sz5SS6EMc,33959
290
+ biotite/structure/io/pdbx/cif.py,sha256=4gZk9mPslZoFEROiCg_8W6Lc6CPcI_yc7S5LybkxUNo,35517
291
291
  biotite/structure/io/pdbx/component.py,sha256=B5QxWiaCABuauX4GJiqoaTExAGnzzZQxksj46-AWZQg,8266
292
- biotite/structure/io/pdbx/convert.py,sha256=hEBHslvgsv_mpL8dFaYImp0S5e8uvsv3tYo4nyZk23E,61215
292
+ biotite/structure/io/pdbx/convert.py,sha256=F1s2RBcR73ea_RYI36tE6kAGmX4C0k6_Tq2woFJXVtA,61807
293
293
  biotite/structure/io/pdbx/encoding.pyx,sha256=fjob-qQN3qiIo6KfmKla6401oIM5zjMaeK4LqdJbmU4,29674
294
294
  biotite/structure/io/trr/__init__.py,sha256=xp4FpuAy_ESqzVWyugRXUHZ0iF8j5ox6EfCxSWhkcUY,372
295
295
  biotite/structure/io/trr/file.py,sha256=XcdYOf9M2tjRXMM87p9U7jMdQb0PlTFvDHXHgSdjbl8,1278
296
296
  biotite/structure/io/xtc/__init__.py,sha256=P17UBQnG-KmOlScHp46FXAb5i7d-ZCMlyljcOkFolMw,370
297
297
  biotite/structure/io/xtc/file.py,sha256=X4iIDjAWn1ZySg3NjbPeSMNByoyH1y8asmtqcBYycpE,1278
298
- biotite/sequence/codec.cp310-win_amd64.pyd,sha256=P2nWNSg1x45x5fEZ0SL_cdybZCYpnizgMk-n18O43YY,247808
299
- biotite/structure/bonds.cp310-win_amd64.pyd,sha256=-A7ZdCxfQkLB_S9iCcEfI4vKJkL80JJ-KeDANlW2ih8,486912
300
- biotite/structure/celllist.cp310-win_amd64.pyd,sha256=k1trH4jtnKDjw9gxHCoZqYCR0krLI3wQsdNnrwcXeS0,256000
301
- biotite/structure/charges.cp310-win_amd64.pyd,sha256=OZFeX8842pbd9mvewEWeF0G5lPRZwByrgI492bjxneI,221184
302
- biotite/structure/sasa.cp310-win_amd64.pyd,sha256=Ka95zRZY0YlhmgRro_tvgZV4DfYI-eqa-3nZrChB6EA,193024
303
- biotite/sequence/align/banded.cp310-win_amd64.pyd,sha256=63rA4X8BHco02VjjMzX6QZpTdk4AXaqF_WF1DavXWe8,497664
304
- biotite/sequence/align/kmeralphabet.cp310-win_amd64.pyd,sha256=5lyYwSUuO5ycD_yexPwxY5YflzcuQiwo--qnt5AxUYU,316928
305
- biotite/sequence/align/kmersimilarity.cp310-win_amd64.pyd,sha256=ITxu3J18T1xgs4-_EYISe1WGfMRn5nFT6Oxy4wQ-BNU,175616
306
- biotite/sequence/align/kmertable.cp310-win_amd64.pyd,sha256=73RG6jZn2gRWWu6vxd-OJebNQ5IfWUrsu4kvWHyvBuE,607744
307
- biotite/sequence/align/localgapped.cp310-win_amd64.pyd,sha256=yiPS691JMxDf5zdRe1Wsqw-qa6GByf5d92Q56CT3Hk8,995840
308
- biotite/sequence/align/localungapped.cp310-win_amd64.pyd,sha256=c6LRAFquQ4fgH0vEWMbRew-8I9fux3sEwY8L4avx1Bs,260608
309
- biotite/sequence/align/multiple.cp310-win_amd64.pyd,sha256=bJ4nHITzYVz5FQ2IMEA20Z10qaN6KAg4u5GwRMjJ_Ks,414720
310
- biotite/sequence/align/pairwise.cp310-win_amd64.pyd,sha256=Ldn-BVSM_ylE_tswuGy_gmFcbP4AT4608cBa_7MqKew,540672
311
- biotite/sequence/align/permutation.cp310-win_amd64.pyd,sha256=SpFM4-2xQifpJ2x5Hptbnl-MPrFC9wWkVoZifIe7CWw,185344
312
- biotite/sequence/align/selector.cp310-win_amd64.pyd,sha256=pbmgis_3GY7DOItgsPS9WkJWUy7RL5RmiQx6rShIRX0,258048
313
- biotite/sequence/align/tracetable.cp310-win_amd64.pyd,sha256=dVZWRuBVlvtvU-tEekVAveqSzc2EmK2j5rjzjfc_2B8,151552
314
- biotite/sequence/phylo/nj.cp310-win_amd64.pyd,sha256=sRGgzko9nSyFUTT7VITugjejzqYK4nXnfYnvgN3ZA5I,172544
315
- biotite/sequence/phylo/tree.cp310-win_amd64.pyd,sha256=EqdCivP7A0AKoC9I5vVtcuHQ8SNCqXFe5qqV2NdccEg,211968
316
- biotite/sequence/phylo/upgma.cp310-win_amd64.pyd,sha256=zaRjWWzlv3DjdL2bwJEwKak_E0G_kpenBgKbStRogDw,164864
317
- biotite/structure/io/pdb/hybrid36.cp310-win_amd64.pyd,sha256=CWz5wOybpLf_bS1hamDqYbyiHFjLe-qza7idGymwf4Y,152576
318
- biotite/structure/io/pdbx/encoding.cp310-win_amd64.pyd,sha256=RF4lyar8WEkGcNQLBPxjTlaIE3ogH0BS05j9A8YTzgQ,1000960
319
- biotite-1.0.0.dist-info/METADATA,sha256=C6tIVbg8HfB-DgcNYsM7sb56iNpH-n4EulEWtL_-2fQ,7111
320
- biotite-1.0.0.dist-info/WHEEL,sha256=eNBqRHhwAIHkRN0IzK2Y894ATsq8QRbcKdgIDwxguGM,97
321
- biotite-1.0.0.dist-info/licenses/LICENSE.rst,sha256=wDDtR8LuBedgqNIor2N5YGv4nj9flZltCDSu2fhjGbo,1564
322
- biotite-1.0.0.dist-info/RECORD,,
298
+ biotite/sequence/codec.cp310-win_amd64.pyd,sha256=wbXCIXtAtG91zaSSvLXmsFINbXJm_Fpg0sVpF7qMcXA,247808
299
+ biotite/structure/bonds.cp310-win_amd64.pyd,sha256=hDD5L2SUmEMDONdfcxo3ketHMl0E2QcEXOdqC9NeYO4,486912
300
+ biotite/structure/celllist.cp310-win_amd64.pyd,sha256=bKZdPSRFKwxbwsloQp8j6t_iW3wukPqI_lA_qt-T94o,256000
301
+ biotite/structure/charges.cp310-win_amd64.pyd,sha256=4YtinHYeMAxfkRi97f1ILwMlajRY4IXOMMEd4Ig8qFI,221184
302
+ biotite/structure/sasa.cp310-win_amd64.pyd,sha256=aoypqWUshTgJ8dOLvd6eFVEtKNjvLtV3LTDNUHjhIi4,193024
303
+ biotite/sequence/align/banded.cp310-win_amd64.pyd,sha256=U5MtjNw6huvII_rVyOLPDFEO1ajgUV9HzIg6VFW798A,497664
304
+ biotite/sequence/align/kmeralphabet.cp310-win_amd64.pyd,sha256=dZYY4AgBhQAr_J2yzfbXA_KnbQxDiNTeeNV_diQU4_o,316928
305
+ biotite/sequence/align/kmersimilarity.cp310-win_amd64.pyd,sha256=mg6q-Yl0Z9BWh_IgvW-BegDvc4fzk-ZBMghrms4nGHE,175616
306
+ biotite/sequence/align/kmertable.cp310-win_amd64.pyd,sha256=VP_X5FrGAYz_i-7cCNkDssGH9RBNJf57ugUi4yjLRF4,607744
307
+ biotite/sequence/align/localgapped.cp310-win_amd64.pyd,sha256=7ucfAG3XdI9wPF4isQx4Uej9XYCQfDY4qiuWq810FF4,995840
308
+ biotite/sequence/align/localungapped.cp310-win_amd64.pyd,sha256=jjEQhr9lTob-E5rK00NOY6p-f5E0i2TxUBAVEykiksM,260608
309
+ biotite/sequence/align/multiple.cp310-win_amd64.pyd,sha256=V84RfYVHlFdlns8HrIKR7d0huKbKHSkq0bDtgIe7aBE,414720
310
+ biotite/sequence/align/pairwise.cp310-win_amd64.pyd,sha256=oQl_GMADtW8HKuOY0lYyu-Hw6462cqK1HJUULSneslM,540672
311
+ biotite/sequence/align/permutation.cp310-win_amd64.pyd,sha256=u3V7eNS1Y6FaVN1XBiSp-Lvu2BGNrxXVLnk_BysOosw,185344
312
+ biotite/sequence/align/selector.cp310-win_amd64.pyd,sha256=zNItwqP5mhgZsw97Ny4GpPg5NBkfujCjRTmZb1SsIvo,258048
313
+ biotite/sequence/align/tracetable.cp310-win_amd64.pyd,sha256=5P66GOXovv4MY92_3sIfj0xSNDfkTFvXMVv3Sgoax0w,151552
314
+ biotite/sequence/phylo/nj.cp310-win_amd64.pyd,sha256=2Gko2SRccpPENx5KL4sZfd_r51Eo0m2oBuLmOCQpE5E,172544
315
+ biotite/sequence/phylo/tree.cp310-win_amd64.pyd,sha256=e_KiuW3nLFCVW5JdTQPAAU1yraHwXy8kt-U03bsEP6A,211968
316
+ biotite/sequence/phylo/upgma.cp310-win_amd64.pyd,sha256=H0P8ke4CQOsV3zVKr7CuBUoAMAW8tKZuz_Ve2T5PcS8,164864
317
+ biotite/structure/io/pdb/hybrid36.cp310-win_amd64.pyd,sha256=95OyRZxwG_8oKZVixELTcrj1ZCDfKuR20DlmDsQilZs,152576
318
+ biotite/structure/io/pdbx/encoding.cp310-win_amd64.pyd,sha256=pZhonXiKCXl0-4efKP_IL-W46GQ2awRYIY5IwMUWPko,1000960
319
+ biotite-1.0.1.dist-info/METADATA,sha256=lnwl1IjHDLJ5EVhHYSUQplx3-4Ql4gbbezrkspTCRK8,7159
320
+ biotite-1.0.1.dist-info/WHEEL,sha256=eNBqRHhwAIHkRN0IzK2Y894ATsq8QRbcKdgIDwxguGM,97
321
+ biotite-1.0.1.dist-info/licenses/LICENSE.rst,sha256=wDDtR8LuBedgqNIor2N5YGv4nj9flZltCDSu2fhjGbo,1564
322
+ biotite-1.0.1.dist-info/RECORD,,