biotite 0.40.0__cp312-cp312-win_amd64.whl → 0.41.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 (90) hide show
  1. biotite/__init__.py +1 -1
  2. biotite/database/pubchem/download.py +23 -23
  3. biotite/database/pubchem/query.py +7 -7
  4. biotite/file.py +17 -9
  5. biotite/sequence/align/banded.c +117 -117
  6. biotite/sequence/align/banded.cp312-win_amd64.pyd +0 -0
  7. biotite/sequence/align/cigar.py +60 -15
  8. biotite/sequence/align/kmeralphabet.c +117 -117
  9. biotite/sequence/align/kmeralphabet.cp312-win_amd64.pyd +0 -0
  10. biotite/sequence/align/kmersimilarity.c +117 -117
  11. biotite/sequence/align/kmersimilarity.cp312-win_amd64.pyd +0 -0
  12. biotite/sequence/align/kmertable.cp312-win_amd64.pyd +0 -0
  13. biotite/sequence/align/kmertable.cpp +117 -117
  14. biotite/sequence/align/localgapped.c +117 -117
  15. biotite/sequence/align/localgapped.cp312-win_amd64.pyd +0 -0
  16. biotite/sequence/align/localungapped.c +117 -117
  17. biotite/sequence/align/localungapped.cp312-win_amd64.pyd +0 -0
  18. biotite/sequence/align/multiple.c +117 -117
  19. biotite/sequence/align/multiple.cp312-win_amd64.pyd +0 -0
  20. biotite/sequence/align/pairwise.c +117 -117
  21. biotite/sequence/align/pairwise.cp312-win_amd64.pyd +0 -0
  22. biotite/sequence/align/permutation.c +117 -117
  23. biotite/sequence/align/permutation.cp312-win_amd64.pyd +0 -0
  24. biotite/sequence/align/selector.c +117 -117
  25. biotite/sequence/align/selector.cp312-win_amd64.pyd +0 -0
  26. biotite/sequence/align/tracetable.c +117 -117
  27. biotite/sequence/align/tracetable.cp312-win_amd64.pyd +0 -0
  28. biotite/sequence/annotation.py +2 -2
  29. biotite/sequence/codec.c +117 -117
  30. biotite/sequence/codec.cp312-win_amd64.pyd +0 -0
  31. biotite/sequence/io/fasta/convert.py +27 -24
  32. biotite/sequence/phylo/nj.c +117 -117
  33. biotite/sequence/phylo/nj.cp312-win_amd64.pyd +0 -0
  34. biotite/sequence/phylo/tree.c +117 -117
  35. biotite/sequence/phylo/tree.cp312-win_amd64.pyd +0 -0
  36. biotite/sequence/phylo/upgma.c +117 -117
  37. biotite/sequence/phylo/upgma.cp312-win_amd64.pyd +0 -0
  38. biotite/structure/__init__.py +2 -0
  39. biotite/structure/bonds.c +1122 -913
  40. biotite/structure/bonds.cp312-win_amd64.pyd +0 -0
  41. biotite/structure/celllist.c +117 -117
  42. biotite/structure/celllist.cp312-win_amd64.pyd +0 -0
  43. biotite/structure/charges.c +117 -117
  44. biotite/structure/charges.cp312-win_amd64.pyd +0 -0
  45. biotite/structure/dotbracket.py +2 -0
  46. biotite/structure/info/atoms.py +6 -1
  47. biotite/structure/info/bonds.py +1 -1
  48. biotite/structure/info/ccd/amino_acids.txt +17 -0
  49. biotite/structure/info/ccd/carbohydrates.txt +2 -0
  50. biotite/structure/info/ccd/components.bcif +0 -0
  51. biotite/structure/info/ccd/nucleotides.txt +1 -0
  52. biotite/structure/info/misc.py +69 -5
  53. biotite/structure/integrity.py +19 -70
  54. biotite/structure/io/ctab.py +12 -106
  55. biotite/structure/io/general.py +157 -165
  56. biotite/structure/io/gro/file.py +16 -16
  57. biotite/structure/io/mmtf/convertarray.c +117 -117
  58. biotite/structure/io/mmtf/convertarray.cp312-win_amd64.pyd +0 -0
  59. biotite/structure/io/mmtf/convertfile.c +117 -117
  60. biotite/structure/io/mmtf/convertfile.cp312-win_amd64.pyd +0 -0
  61. biotite/structure/io/mmtf/decode.c +117 -117
  62. biotite/structure/io/mmtf/decode.cp312-win_amd64.pyd +0 -0
  63. biotite/structure/io/mmtf/encode.c +117 -117
  64. biotite/structure/io/mmtf/encode.cp312-win_amd64.pyd +0 -0
  65. biotite/structure/io/mol/__init__.py +4 -2
  66. biotite/structure/io/mol/convert.py +71 -7
  67. biotite/structure/io/mol/ctab.py +414 -0
  68. biotite/structure/io/mol/header.py +116 -0
  69. biotite/structure/io/mol/{file.py → mol.py} +69 -82
  70. biotite/structure/io/mol/sdf.py +909 -0
  71. biotite/structure/io/pdb/file.py +84 -31
  72. biotite/structure/io/pdb/hybrid36.cp312-win_amd64.pyd +0 -0
  73. biotite/structure/io/pdbx/__init__.py +0 -1
  74. biotite/structure/io/pdbx/bcif.py +2 -3
  75. biotite/structure/io/pdbx/cif.py +9 -5
  76. biotite/structure/io/pdbx/component.py +4 -1
  77. biotite/structure/io/pdbx/convert.py +203 -79
  78. biotite/structure/io/pdbx/encoding.c +117 -117
  79. biotite/structure/io/pdbx/encoding.cp312-win_amd64.pyd +0 -0
  80. biotite/structure/repair.py +253 -0
  81. biotite/structure/sasa.c +117 -117
  82. biotite/structure/sasa.cp312-win_amd64.pyd +0 -0
  83. biotite/structure/sequence.py +112 -0
  84. biotite/structure/superimpose.py +472 -13
  85. {biotite-0.40.0.dist-info → biotite-0.41.0.dist-info}/METADATA +2 -2
  86. {biotite-0.40.0.dist-info → biotite-0.41.0.dist-info}/RECORD +89 -85
  87. biotite/structure/io/pdbx/error.py +0 -14
  88. {biotite-0.40.0.dist-info → biotite-0.41.0.dist-info}/LICENSE.rst +0 -0
  89. {biotite-0.40.0.dist-info → biotite-0.41.0.dist-info}/WHEEL +0 -0
  90. {biotite-0.40.0.dist-info → biotite-0.41.0.dist-info}/top_level.txt +0 -0
@@ -11,9 +11,10 @@ __name__ = "biotite.structure.io"
11
11
  __author__ = "Patrick Kunzmann"
12
12
  __all__ = ["load_structure", "save_structure"]
13
13
 
14
+ import datetime
14
15
  import os.path
15
16
  import io
16
- from ..atoms import AtomArray, AtomArrayStack
17
+ from ..atoms import AtomArrayStack
17
18
 
18
19
 
19
20
  def load_structure(file_path, template=None, **kwargs):
@@ -61,72 +62,83 @@ def load_structure(file_path, template=None, **kwargs):
61
62
 
62
63
  # We only need the suffix here
63
64
  _, suffix = os.path.splitext(file_path)
64
- if suffix == ".pdb":
65
- from .pdb import PDBFile
66
- file = PDBFile.read(file_path)
67
- array = file.get_structure(**kwargs)
68
- return _as_single_model_if_possible(array)
69
- elif suffix == ".pdbqt":
70
- from .pdbqt import PDBQTFile
71
- file = PDBQTFile.read(file_path)
72
- array = file.get_structure(**kwargs)
73
- return _as_single_model_if_possible(array)
74
- elif suffix == ".cif" or suffix == ".pdbx":
75
- from .pdbx import CIFFile, get_structure
76
- file = CIFFile.read(file_path)
77
- array = get_structure(file, **kwargs)
78
- return _as_single_model_if_possible(array)
79
- elif suffix == ".bcif":
80
- from .pdbx import BinaryCIFFile, get_structure
81
- file = BinaryCIFFile.read(file_path)
82
- array = get_structure(file, **kwargs)
83
- return _as_single_model_if_possible(array)
84
- elif suffix == ".gro":
85
- from .gro import GROFile
86
- file = GROFile.read(file_path)
87
- array = file.get_structure(**kwargs)
88
- return _as_single_model_if_possible(array)
89
- elif suffix == ".mmtf":
90
- from .mmtf import MMTFFile, get_structure
91
- file = MMTFFile.read(file_path)
92
- array = get_structure(file, **kwargs)
93
- return _as_single_model_if_possible(array)
94
- elif suffix == ".npz":
95
- from .npz import NpzFile
96
- file = NpzFile.read(file_path)
97
- array = file.get_structure(**kwargs)
98
- return _as_single_model_if_possible(array)
99
- elif suffix == ".mol" or suffix == ".sdf":
100
- from .mol import MOLFile
101
- file = MOLFile.read(file_path)
102
- array = file.get_structure(**kwargs)
103
- # MOL files only contain a single model
104
- return array
105
- elif suffix in [".trr", ".xtc", ".tng", ".dcd", ".netcdf"]:
106
- if template is None:
107
- raise TypeError("Template must be specified for trajectory files")
108
- # filter template for atom ids if it is an unfiltered template
109
- if "atom_i" in kwargs and template.shape[-1] != len(kwargs["atom_i"]):
110
- template = template[..., kwargs["atom_i"]]
111
- from .trr import TRRFile
112
- from .xtc import XTCFile
113
- from .tng import TNGFile
114
- from .dcd import DCDFile
115
- from .netcdf import NetCDFFile
116
- if suffix == ".trr":
117
- traj_file_cls = TRRFile
118
- if suffix == ".xtc":
119
- traj_file_cls = XTCFile
120
- if suffix == ".tng":
121
- traj_file_cls = TNGFile
122
- if suffix == ".dcd":
123
- traj_file_cls = DCDFile
124
- if suffix == ".netcdf":
125
- traj_file_cls = NetCDFFile
126
- file = traj_file_cls.read(file_path, **kwargs)
127
- return file.get_structure(template)
128
- else:
129
- raise ValueError(f"Unknown file format '{suffix}'")
65
+ match suffix:
66
+ case ".pdb":
67
+ from .pdb import PDBFile
68
+ file = PDBFile.read(file_path)
69
+ array = file.get_structure(**kwargs)
70
+ return _as_single_model_if_possible(array)
71
+ case ".pdbqt":
72
+ from .pdbqt import PDBQTFile
73
+ file = PDBQTFile.read(file_path)
74
+ array = file.get_structure(**kwargs)
75
+ return _as_single_model_if_possible(array)
76
+ case ".cif" | ".pdbx":
77
+ from .pdbx import CIFFile, get_structure
78
+ file = CIFFile.read(file_path)
79
+ array = get_structure(file, **kwargs)
80
+ return _as_single_model_if_possible(array)
81
+ case ".bcif":
82
+ from .pdbx import BinaryCIFFile, get_structure
83
+ file = BinaryCIFFile.read(file_path)
84
+ array = get_structure(file, **kwargs)
85
+ return _as_single_model_if_possible(array)
86
+ case ".gro":
87
+ from .gro import GROFile
88
+ file = GROFile.read(file_path)
89
+ array = file.get_structure(**kwargs)
90
+ return _as_single_model_if_possible(array)
91
+ case ".mmtf":
92
+ from .mmtf import MMTFFile, get_structure
93
+ file = MMTFFile.read(file_path)
94
+ array = get_structure(file, **kwargs)
95
+ return _as_single_model_if_possible(array)
96
+ case ".npz":
97
+ from .npz import NpzFile
98
+ file = NpzFile.read(file_path)
99
+ array = file.get_structure(**kwargs)
100
+ return _as_single_model_if_possible(array)
101
+ case ".mol":
102
+ from .mol import MOLFile
103
+ file = MOLFile.read(file_path)
104
+ array = file.get_structure(**kwargs)
105
+ # MOL and SDF files only contain a single model
106
+ return array
107
+ case ".sdf" | ".sd":
108
+ from .mol import SDFile, get_structure
109
+ file = SDFile.read(file_path)
110
+ array = get_structure(file, **kwargs)
111
+ return array
112
+ case ".trr" | ".xtc" | ".tng" | ".dcd" | ".netcdf":
113
+ if template is None:
114
+ raise TypeError(
115
+ "Template must be specified for trajectory files"
116
+ )
117
+ # Filter template for atom ids, if an unfiltered template
118
+ if (
119
+ "atom_i" in kwargs
120
+ and template.shape[-1] != len(kwargs["atom_i"])
121
+ ):
122
+ template = template[..., kwargs["atom_i"]]
123
+ from .trr import TRRFile
124
+ from .xtc import XTCFile
125
+ from .tng import TNGFile
126
+ from .dcd import DCDFile
127
+ from .netcdf import NetCDFFile
128
+ if suffix == ".trr":
129
+ traj_file_cls = TRRFile
130
+ if suffix == ".xtc":
131
+ traj_file_cls = XTCFile
132
+ if suffix == ".tng":
133
+ traj_file_cls = TNGFile
134
+ if suffix == ".dcd":
135
+ traj_file_cls = DCDFile
136
+ if suffix == ".netcdf":
137
+ traj_file_cls = NetCDFFile
138
+ file = traj_file_cls.read(file_path, **kwargs)
139
+ return file.get_structure(template)
140
+ case unknown_suffix:
141
+ raise ValueError(f"Unknown file format '{unknown_suffix}'")
130
142
 
131
143
 
132
144
  def save_structure(file_path, array, **kwargs):
@@ -155,67 +167,76 @@ def save_structure(file_path, array, **kwargs):
155
167
  """
156
168
  # We only need the suffix here
157
169
  _, suffix = os.path.splitext(file_path)
158
- if suffix == ".pdb":
159
- from .pdb import PDBFile
160
- file = PDBFile()
161
- file.set_structure(array, **kwargs)
162
- file.write(file_path)
163
- elif suffix == ".pdbqt":
164
- from .pdbqt import PDBQTFile
165
- file = PDBQTFile()
166
- file.set_structure(array, **kwargs)
167
- file.write(file_path)
168
- elif suffix == ".cif" or suffix == ".pdbx":
169
- from .pdbx import CIFFile, set_structure
170
- file = CIFFile()
171
- set_structure(file, array, **kwargs)
172
- file.write(file_path)
173
- elif suffix == ".bcif":
174
- from .pdbx import BinaryCIFFile, set_structure
175
- file = BinaryCIFFile()
176
- set_structure(file, array, **kwargs)
177
- file.write(file_path)
178
- elif suffix == ".gro":
179
- from .gro import GROFile
180
- file = GROFile()
181
- file.set_structure(array, **kwargs)
182
- file.write(file_path)
183
- elif suffix == ".mmtf":
184
- from .mmtf import MMTFFile, set_structure
185
- file = MMTFFile()
186
- set_structure(file, array, **kwargs)
187
- file.write(file_path)
188
- elif suffix == ".npz":
189
- from .npz import NpzFile
190
- file = NpzFile()
191
- file.set_structure(array, **kwargs)
192
- file.write(file_path)
193
- elif suffix == ".mol" or suffix == ".sdf":
194
- from .mol import MOLFile
195
- file = MOLFile()
196
- file.set_structure(array, **kwargs)
197
- file.write(file_path)
198
- elif suffix in [".trr", ".xtc", ".tng", ".dcd", ".netcdf"]:
199
- from .trr import TRRFile
200
- from .xtc import XTCFile
201
- from .tng import TNGFile
202
- from .dcd import DCDFile
203
- from .netcdf import NetCDFFile
204
- if suffix == ".trr":
205
- traj_file_cls = TRRFile
206
- if suffix == ".xtc":
207
- traj_file_cls = XTCFile
208
- if suffix == ".tng":
209
- traj_file_cls = TNGFile
210
- if suffix == ".dcd":
211
- traj_file_cls = DCDFile
212
- if suffix == ".netcdf":
213
- traj_file_cls = NetCDFFile
214
- file = traj_file_cls()
215
- file.set_structure(array, **kwargs)
216
- file.write(file_path)
217
- else:
218
- raise ValueError(f"Unknown file format '{suffix}'")
170
+ match suffix:
171
+ case ".pdb":
172
+ from .pdb import PDBFile
173
+ file = PDBFile()
174
+ file.set_structure(array, **kwargs)
175
+ file.write(file_path)
176
+ case ".pdbqt":
177
+ from .pdbqt import PDBQTFile
178
+ file = PDBQTFile()
179
+ file.set_structure(array, **kwargs)
180
+ file.write(file_path)
181
+ case ".cif" | ".pdbx":
182
+ from .pdbx import CIFFile, set_structure
183
+ file = CIFFile()
184
+ set_structure(file, array, **kwargs)
185
+ file.write(file_path)
186
+ case ".bcif":
187
+ from .pdbx import BinaryCIFFile, set_structure
188
+ file = BinaryCIFFile()
189
+ set_structure(file, array, **kwargs)
190
+ file.write(file_path)
191
+ case ".gro":
192
+ from .gro import GROFile
193
+ file = GROFile()
194
+ file.set_structure(array, **kwargs)
195
+ file.write(file_path)
196
+ case ".mmtf":
197
+ from .mmtf import MMTFFile, set_structure
198
+ file = MMTFFile()
199
+ set_structure(file, array, **kwargs)
200
+ file.write(file_path)
201
+ case ".npz":
202
+ from .npz import NpzFile
203
+ file = NpzFile()
204
+ file.set_structure(array, **kwargs)
205
+ file.write(file_path)
206
+ case ".mol":
207
+ from .mol import MOLFile
208
+ file = MOLFile()
209
+ file.set_structure(array, **kwargs)
210
+ file.header = _mol_header()
211
+ file.write(file_path)
212
+ case ".sdf" | ".sd":
213
+ from .mol import SDFile, SDRecord, set_structure
214
+ record = SDRecord()
215
+ record.set_structure(array, **kwargs)
216
+ record.header = _mol_header()
217
+ file = SDFile({"Molecule": record})
218
+ file.write(file_path)
219
+ case ".trr" | ".xtc" | ".tng" | ".dcd" | ".netcdf":
220
+ from .trr import TRRFile
221
+ from .xtc import XTCFile
222
+ from .tng import TNGFile
223
+ from .dcd import DCDFile
224
+ from .netcdf import NetCDFFile
225
+ if suffix == ".trr":
226
+ traj_file_cls = TRRFile
227
+ if suffix == ".xtc":
228
+ traj_file_cls = XTCFile
229
+ if suffix == ".tng":
230
+ traj_file_cls = TNGFile
231
+ if suffix == ".dcd":
232
+ traj_file_cls = DCDFile
233
+ if suffix == ".netcdf":
234
+ traj_file_cls = NetCDFFile
235
+ file = traj_file_cls()
236
+ file.set_structure(array, **kwargs)
237
+ file.write(file_path)
238
+ case unknown_suffix:
239
+ raise ValueError(f"Unknown file format '{unknown_suffix}'")
219
240
 
220
241
 
221
242
  def _as_single_model_if_possible(atoms):
@@ -226,40 +247,11 @@ def _as_single_model_if_possible(atoms):
226
247
  return atoms
227
248
 
228
249
 
229
- # Helper function to estimate elements from atom names
230
- _elements = [elem.upper() for elem in
231
- ["H", "He", "Li", "Be", "B", "C", "N", "O", "F", "Ne", "Na", "Mg",
232
- "Al", "Si", "P", "S", "Cl", "Ar", "K", "Ca", "Sc", "Ti", "V", "Cr", "Mn", "Fe",
233
- "Co", "Ni", "Cu", "Zn", "Ga", "Ge", "As", "Se", "Br", "Kr", "Rb", "Sr", "Y",
234
- "Zr", "Nb", "Mo", "Tc", "Ru", "Rh", "Pd", "Ag", "Cd", "In", "Sn", "Sb", "Te",
235
- "I", "Xe", "Cs", "Ba", "La", "Ce", "Pr", "Nd", "Pm", "Sm", "Eu", "Gd", "Tb",
236
- "Dy", "Ho", "Er", "Tm", "Yb", "Lu", "Hf", "Ta", "W", "Re", "Os", "Ir", "Pt",
237
- "Au", "Hg", "Tl", "Pb", "Bi", "Po", "At", "Rn", "Fr", "Ra", "Ac", "Th", "Pa",
238
- "U", "Np", "Pu", "Am", "Cm", "Bk", "Cf", "Es", "Fm", "Md", "No", "Lr", "Rf",
239
- "Db", "Sg", "Bh", "Hs", "Mt", "Ds", "Rg", "Cn", "Nh", "Fl", "Mc", "Lv", "Ts",
240
- "Og"]
241
- ]
242
- def _guess_element(atom_name):
243
- # remove digits (1H -> H)
244
- elem = "".join([i for i in atom_name if not i.isdigit()])
245
- elem = elem.upper()
246
- if len(elem) == 0:
247
- return ""
248
-
249
- # Some often used elements for biomolecules
250
- if elem.startswith("C") or elem.startswith("N") or \
251
- elem.startswith("O") or elem.startswith("S") or \
252
- elem.startswith("H"):
253
- return elem[0]
254
-
255
- # Exactly match element abbreviations
256
- try:
257
- return _elements[_elements.index(elem[:2])]
258
- except ValueError:
259
- try:
260
- return _elements[_elements.index(elem[0])]
261
- except ValueError:
262
- pass
263
-
264
- return ""
265
-
250
+ def _mol_header():
251
+ from .mol import Header
252
+ return Header(
253
+ mol_name="Molecule",
254
+ program="Biotite",
255
+ time=datetime.datetime.now(),
256
+ dimensions="3D",
257
+ )
@@ -10,7 +10,7 @@ import numpy as np
10
10
  from ...atoms import AtomArray, AtomArrayStack
11
11
  from ...box import is_orthogonal
12
12
  from ....file import TextFile, InvalidFileError
13
- from ..general import _guess_element as guess_element
13
+ from ...repair import infer_elements
14
14
  from ...error import BadStructureError
15
15
  import copy
16
16
  from datetime import datetime
@@ -38,7 +38,7 @@ class GROFile(TextFile):
38
38
  --------
39
39
  Load a `\\*.gro` file, modify the structure and save the new
40
40
  structure into a new file:
41
-
41
+
42
42
  >>> import os.path
43
43
  >>> file = GROFile.read(os.path.join(path_to_structures, "1l2y.gro"))
44
44
  >>> array_stack = file.get_structure()
@@ -46,7 +46,7 @@ class GROFile(TextFile):
46
46
  >>> file = GROFile()
47
47
  >>> file.set_structure(array_stack_mod)
48
48
  >>> file.write(os.path.join(path_to_directory, "1l2y_mod.gro"))
49
-
49
+
50
50
  """
51
51
  def get_model_count(self):
52
52
  """
@@ -68,7 +68,7 @@ class GROFile(TextFile):
68
68
  """
69
69
  Get an :class:`AtomArray` or :class:`AtomArrayStack` from the
70
70
  GRO file.
71
-
71
+
72
72
  Parameters
73
73
  ----------
74
74
  model : int, optional
@@ -80,13 +80,13 @@ class GROFile(TextFile):
80
80
  If this parameter is omitted, an :class:`AtomArrayStack`
81
81
  containing all models will be returned, even if the
82
82
  structure contains only one model.
83
-
83
+
84
84
  Returns
85
85
  -------
86
86
  array : AtomArray or AtomArrayStack
87
87
  The return type depends on the `model` parameter.
88
88
  """
89
-
89
+
90
90
  def get_atom_line_i(model_start_i, model_atom_counts):
91
91
  """
92
92
  Helper function to get the indices of all atoms for a model
@@ -94,7 +94,7 @@ class GROFile(TextFile):
94
94
  return np.arange(
95
95
  model_start_i+1, model_start_i+1+model_atom_counts
96
96
  )
97
-
97
+
98
98
  def set_box_dimen(box_param):
99
99
  """
100
100
  Helper function to create the box vectors from the values
@@ -104,7 +104,7 @@ class GROFile(TextFile):
104
104
  ----------
105
105
  box_param : list of float
106
106
  The box dimensions in the GRO file.
107
-
107
+
108
108
  Returns
109
109
  -------
110
110
  box_vectors : ndarray, dtype=float, shape=(3,3)
@@ -171,7 +171,7 @@ class GROFile(TextFile):
171
171
  array.res_id[i] = int(line[0:5])
172
172
  array.res_name[i] = line[5:10].strip()
173
173
  array.atom_name[i] = line[10:15].strip()
174
- array.element[i] = guess_element(line[10:15].strip())
174
+ array.element = infer_elements(array.atom_name)
175
175
 
176
176
  # Fill in coordinates and boxes
177
177
  if isinstance(array, AtomArray):
@@ -186,7 +186,7 @@ class GROFile(TextFile):
186
186
  box_i = atom_i[-1] + 1
187
187
  box_param = [float(e)*10 for e in self.lines[box_i].split()]
188
188
  array.box = set_box_dimen(box_param)
189
-
189
+
190
190
  elif isinstance(array, AtomArrayStack):
191
191
  for m in range(len(model_start_i)):
192
192
  atom_i = get_atom_line_i(
@@ -204,18 +204,18 @@ class GROFile(TextFile):
204
204
  # Create a box in the stack if not already existing
205
205
  # and the box is not a dummy
206
206
  if box is not None:
207
- if array.box is None:
207
+ if array.box is None:
208
208
  array.box = np.zeros((array.stack_depth(), 3, 3))
209
209
  array.box[m] = box
210
-
210
+
211
211
  return array
212
212
 
213
-
213
+
214
214
  def set_structure(self, array):
215
215
  """
216
216
  Set the :class:`AtomArray` or :class:`AtomArrayStack` for the
217
217
  file.
218
-
218
+
219
219
  Parameters
220
220
  ----------
221
221
  array : AtomArray or AtomArrayStack
@@ -235,7 +235,7 @@ class GROFile(TextFile):
235
235
  ----------
236
236
  array : AtomArray
237
237
  The atom array to get the box dimensions from.
238
-
238
+
239
239
  Returns
240
240
  -------
241
241
  box : str
@@ -259,7 +259,7 @@ class GROFile(TextFile):
259
259
  box[2,0], box[2,1],
260
260
  )
261
261
  return " ".join([f"{e:>9.5f}" for e in box_elements])
262
-
262
+
263
263
  if "atom_id" in array.get_annotation_categories():
264
264
  atom_id = array.atom_id
265
265
  else: