biotite 0.41.1__cp311-cp311-win_amd64.whl → 1.0.0__cp311-cp311-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.
- biotite/__init__.py +2 -3
- biotite/application/__init__.py +36 -10
- biotite/application/application.py +22 -11
- biotite/application/autodock/__init__.py +1 -1
- biotite/application/autodock/app.py +74 -79
- biotite/application/blast/__init__.py +1 -1
- biotite/application/blast/alignment.py +19 -10
- biotite/application/blast/webapp.py +92 -85
- biotite/application/clustalo/__init__.py +1 -1
- biotite/application/clustalo/app.py +46 -61
- biotite/application/dssp/__init__.py +1 -1
- biotite/application/dssp/app.py +8 -11
- biotite/application/localapp.py +62 -60
- biotite/application/mafft/__init__.py +1 -1
- biotite/application/mafft/app.py +16 -22
- biotite/application/msaapp.py +78 -89
- biotite/application/muscle/__init__.py +1 -1
- biotite/application/muscle/app3.py +50 -64
- biotite/application/muscle/app5.py +23 -31
- biotite/application/sra/__init__.py +1 -1
- biotite/application/sra/app.py +64 -68
- biotite/application/tantan/__init__.py +1 -1
- biotite/application/tantan/app.py +22 -45
- biotite/application/util.py +7 -9
- biotite/application/viennarna/rnaalifold.py +34 -28
- biotite/application/viennarna/rnafold.py +24 -39
- biotite/application/viennarna/rnaplot.py +36 -21
- biotite/application/viennarna/util.py +17 -12
- biotite/application/webapp.py +13 -14
- biotite/copyable.py +13 -13
- biotite/database/__init__.py +1 -1
- biotite/database/entrez/__init__.py +1 -1
- biotite/database/entrez/check.py +2 -3
- biotite/database/entrez/dbnames.py +7 -5
- biotite/database/entrez/download.py +55 -49
- biotite/database/entrez/key.py +1 -1
- biotite/database/entrez/query.py +62 -23
- biotite/database/error.py +2 -1
- biotite/database/pubchem/__init__.py +1 -1
- biotite/database/pubchem/download.py +43 -45
- biotite/database/pubchem/error.py +2 -2
- biotite/database/pubchem/query.py +34 -31
- biotite/database/pubchem/throttle.py +3 -4
- biotite/database/rcsb/__init__.py +1 -1
- biotite/database/rcsb/download.py +44 -52
- biotite/database/rcsb/query.py +85 -80
- biotite/database/uniprot/check.py +6 -3
- biotite/database/uniprot/download.py +6 -11
- biotite/database/uniprot/query.py +115 -31
- biotite/file.py +12 -31
- biotite/sequence/__init__.py +16 -5
- biotite/sequence/align/__init__.py +160 -6
- biotite/sequence/align/alignment.py +99 -90
- biotite/sequence/align/banded.cp311-win_amd64.pyd +0 -0
- biotite/sequence/align/buckets.py +12 -10
- biotite/sequence/align/cigar.py +43 -52
- biotite/sequence/align/kmeralphabet.cp311-win_amd64.pyd +0 -0
- biotite/sequence/align/kmeralphabet.pyx +55 -51
- biotite/sequence/align/kmersimilarity.cp311-win_amd64.pyd +0 -0
- biotite/sequence/align/kmertable.cp311-win_amd64.pyd +0 -0
- biotite/sequence/align/kmertable.pyx +3 -2
- biotite/sequence/align/localgapped.cp311-win_amd64.pyd +0 -0
- biotite/sequence/align/localungapped.cp311-win_amd64.pyd +0 -0
- biotite/sequence/align/matrix.py +81 -82
- biotite/sequence/align/multiple.cp311-win_amd64.pyd +0 -0
- biotite/sequence/align/multiple.pyx +35 -35
- biotite/sequence/align/pairwise.cp311-win_amd64.pyd +0 -0
- biotite/sequence/align/permutation.cp311-win_amd64.pyd +0 -0
- biotite/sequence/align/permutation.pyx +12 -4
- biotite/sequence/align/selector.cp311-win_amd64.pyd +0 -0
- biotite/sequence/align/selector.pyx +52 -54
- biotite/sequence/align/statistics.py +32 -33
- biotite/sequence/align/tracetable.cp311-win_amd64.pyd +0 -0
- biotite/sequence/alphabet.py +112 -126
- biotite/sequence/annotation.py +78 -77
- biotite/sequence/codec.cp311-win_amd64.pyd +0 -0
- biotite/sequence/codon.py +90 -79
- biotite/sequence/graphics/__init__.py +1 -1
- biotite/sequence/graphics/alignment.py +184 -103
- biotite/sequence/graphics/colorschemes.py +10 -12
- biotite/sequence/graphics/dendrogram.py +79 -34
- biotite/sequence/graphics/features.py +133 -99
- biotite/sequence/graphics/logo.py +22 -28
- biotite/sequence/graphics/plasmid.py +229 -178
- biotite/sequence/io/fasta/__init__.py +1 -1
- biotite/sequence/io/fasta/convert.py +44 -33
- biotite/sequence/io/fasta/file.py +42 -55
- biotite/sequence/io/fastq/__init__.py +1 -1
- biotite/sequence/io/fastq/convert.py +11 -14
- biotite/sequence/io/fastq/file.py +68 -112
- biotite/sequence/io/genbank/__init__.py +2 -2
- biotite/sequence/io/genbank/annotation.py +12 -20
- biotite/sequence/io/genbank/file.py +74 -76
- biotite/sequence/io/genbank/metadata.py +74 -62
- biotite/sequence/io/genbank/sequence.py +13 -14
- biotite/sequence/io/general.py +39 -30
- biotite/sequence/io/gff/__init__.py +2 -2
- biotite/sequence/io/gff/convert.py +10 -15
- biotite/sequence/io/gff/file.py +81 -65
- biotite/sequence/phylo/__init__.py +1 -1
- biotite/sequence/phylo/nj.cp311-win_amd64.pyd +0 -0
- biotite/sequence/phylo/tree.cp311-win_amd64.pyd +0 -0
- biotite/sequence/phylo/upgma.cp311-win_amd64.pyd +0 -0
- biotite/sequence/profile.py +57 -28
- biotite/sequence/search.py +17 -15
- biotite/sequence/seqtypes.py +200 -164
- biotite/sequence/sequence.py +64 -64
- biotite/structure/__init__.py +3 -3
- biotite/structure/atoms.py +226 -240
- biotite/structure/basepairs.py +260 -271
- biotite/structure/bonds.cp311-win_amd64.pyd +0 -0
- biotite/structure/bonds.pyx +88 -100
- biotite/structure/box.py +67 -71
- biotite/structure/celllist.cp311-win_amd64.pyd +0 -0
- biotite/structure/chains.py +55 -39
- biotite/structure/charges.cp311-win_amd64.pyd +0 -0
- biotite/structure/compare.py +32 -32
- biotite/structure/density.py +13 -18
- biotite/structure/dotbracket.py +20 -22
- biotite/structure/error.py +10 -2
- biotite/structure/filter.py +82 -77
- biotite/structure/geometry.py +130 -119
- biotite/structure/graphics/atoms.py +60 -43
- biotite/structure/graphics/rna.py +81 -68
- biotite/structure/hbond.py +112 -93
- biotite/structure/info/__init__.py +0 -2
- biotite/structure/info/atoms.py +10 -11
- biotite/structure/info/bonds.py +41 -43
- biotite/structure/info/ccd.py +21 -7
- biotite/structure/info/groups.py +10 -15
- biotite/structure/info/masses.py +5 -10
- biotite/structure/info/misc.py +1 -1
- biotite/structure/info/radii.py +20 -20
- biotite/structure/info/standardize.py +15 -26
- biotite/structure/integrity.py +18 -71
- biotite/structure/io/__init__.py +3 -4
- biotite/structure/io/dcd/__init__.py +1 -1
- biotite/structure/io/dcd/file.py +22 -20
- biotite/structure/io/general.py +47 -61
- biotite/structure/io/gro/__init__.py +1 -1
- biotite/structure/io/gro/file.py +73 -72
- biotite/structure/io/mol/__init__.py +1 -1
- biotite/structure/io/mol/convert.py +8 -11
- biotite/structure/io/mol/ctab.py +37 -36
- biotite/structure/io/mol/header.py +14 -10
- biotite/structure/io/mol/mol.py +9 -53
- biotite/structure/io/mol/sdf.py +47 -50
- biotite/structure/io/netcdf/__init__.py +1 -1
- biotite/structure/io/netcdf/file.py +24 -23
- biotite/structure/io/pdb/__init__.py +1 -1
- biotite/structure/io/pdb/convert.py +32 -20
- biotite/structure/io/pdb/file.py +151 -172
- biotite/structure/io/pdb/hybrid36.cp311-win_amd64.pyd +0 -0
- biotite/structure/io/pdbqt/__init__.py +1 -1
- biotite/structure/io/pdbqt/convert.py +17 -11
- biotite/structure/io/pdbqt/file.py +128 -80
- biotite/structure/io/pdbx/__init__.py +1 -2
- biotite/structure/io/pdbx/bcif.py +36 -52
- biotite/structure/io/pdbx/cif.py +64 -62
- biotite/structure/io/pdbx/component.py +10 -16
- biotite/structure/io/pdbx/convert.py +235 -246
- biotite/structure/io/pdbx/encoding.cp311-win_amd64.pyd +0 -0
- biotite/structure/io/trajfile.py +76 -93
- biotite/structure/io/trr/__init__.py +1 -1
- biotite/structure/io/trr/file.py +12 -15
- biotite/structure/io/xtc/__init__.py +1 -1
- biotite/structure/io/xtc/file.py +11 -14
- biotite/structure/mechanics.py +9 -11
- biotite/structure/molecules.py +3 -4
- biotite/structure/pseudoknots.py +53 -67
- biotite/structure/rdf.py +23 -21
- biotite/structure/repair.py +137 -86
- biotite/structure/residues.py +26 -16
- biotite/structure/sasa.cp311-win_amd64.pyd +0 -0
- biotite/structure/{resutil.py → segments.py} +24 -23
- biotite/structure/sequence.py +10 -11
- biotite/structure/sse.py +100 -119
- biotite/structure/superimpose.py +39 -77
- biotite/structure/transform.py +97 -71
- biotite/structure/util.py +11 -13
- biotite/version.py +2 -2
- biotite/visualize.py +69 -55
- {biotite-0.41.1.dist-info → biotite-1.0.0.dist-info}/METADATA +6 -6
- biotite-1.0.0.dist-info/RECORD +322 -0
- {biotite-0.41.1.dist-info → biotite-1.0.0.dist-info}/WHEEL +1 -1
- biotite/structure/io/ctab.py +0 -72
- biotite/structure/io/mmtf/__init__.py +0 -21
- biotite/structure/io/mmtf/assembly.py +0 -214
- biotite/structure/io/mmtf/convertarray.cp311-win_amd64.pyd +0 -0
- biotite/structure/io/mmtf/convertarray.pyx +0 -341
- biotite/structure/io/mmtf/convertfile.cp311-win_amd64.pyd +0 -0
- biotite/structure/io/mmtf/convertfile.pyx +0 -501
- biotite/structure/io/mmtf/decode.cp311-win_amd64.pyd +0 -0
- biotite/structure/io/mmtf/decode.pyx +0 -152
- biotite/structure/io/mmtf/encode.cp311-win_amd64.pyd +0 -0
- biotite/structure/io/mmtf/encode.pyx +0 -183
- biotite/structure/io/mmtf/file.py +0 -233
- biotite/structure/io/npz/__init__.py +0 -20
- biotite/structure/io/npz/file.py +0 -152
- biotite/structure/io/pdbx/legacy.py +0 -267
- biotite/structure/io/tng/__init__.py +0 -13
- biotite/structure/io/tng/file.py +0 -46
- biotite/temp.py +0 -86
- biotite-0.41.1.dist-info/RECORD +0 -340
- {biotite-0.41.1.dist-info → biotite-1.0.0.dist-info}/licenses/LICENSE.rst +0 -0
biotite/structure/atoms.py
CHANGED
|
@@ -4,19 +4,27 @@
|
|
|
4
4
|
|
|
5
5
|
"""
|
|
6
6
|
This module contains the main types of the ``structure`` subpackage:
|
|
7
|
-
:class:`Atom`, :class:`AtomArray` and :class:`AtomArrayStack`.
|
|
7
|
+
:class:`Atom`, :class:`AtomArray` and :class:`AtomArrayStack`.
|
|
8
8
|
"""
|
|
9
9
|
|
|
10
10
|
__name__ = "biotite.structure"
|
|
11
11
|
__author__ = "Patrick Kunzmann"
|
|
12
|
-
__all__ = [
|
|
13
|
-
|
|
12
|
+
__all__ = [
|
|
13
|
+
"Atom",
|
|
14
|
+
"AtomArray",
|
|
15
|
+
"AtomArrayStack",
|
|
16
|
+
"array",
|
|
17
|
+
"stack",
|
|
18
|
+
"repeat",
|
|
19
|
+
"from_template",
|
|
20
|
+
"coord",
|
|
21
|
+
]
|
|
14
22
|
|
|
15
|
-
import numbers
|
|
16
23
|
import abc
|
|
24
|
+
import numbers
|
|
17
25
|
import numpy as np
|
|
18
|
-
from .
|
|
19
|
-
from
|
|
26
|
+
from biotite.copyable import Copyable
|
|
27
|
+
from biotite.structure.bonds import BondList
|
|
20
28
|
|
|
21
29
|
|
|
22
30
|
class _AtomArrayBase(Copyable, metaclass=abc.ABCMeta):
|
|
@@ -26,7 +34,7 @@ class _AtomArrayBase(Copyable, metaclass=abc.ABCMeta):
|
|
|
26
34
|
It implements functionality for annotation arrays and also
|
|
27
35
|
rudimentarily for coordinates.
|
|
28
36
|
"""
|
|
29
|
-
|
|
37
|
+
|
|
30
38
|
def __init__(self, length):
|
|
31
39
|
"""
|
|
32
40
|
Create the annotation arrays
|
|
@@ -43,14 +51,14 @@ class _AtomArrayBase(Copyable, metaclass=abc.ABCMeta):
|
|
|
43
51
|
self.add_annotation("hetero", dtype=bool)
|
|
44
52
|
self.add_annotation("atom_name", dtype="U6")
|
|
45
53
|
self.add_annotation("element", dtype="U2")
|
|
46
|
-
|
|
54
|
+
|
|
47
55
|
def array_length(self):
|
|
48
56
|
"""
|
|
49
57
|
Get the length of the atom array.
|
|
50
|
-
|
|
58
|
+
|
|
51
59
|
This value is equivalent to the length of each annotation array.
|
|
52
60
|
For :class:`AtomArray` it is the same as ``len(array)``.
|
|
53
|
-
|
|
61
|
+
|
|
54
62
|
Returns
|
|
55
63
|
-------
|
|
56
64
|
length : int
|
|
@@ -71,15 +79,15 @@ class _AtomArrayBase(Copyable, metaclass=abc.ABCMeta):
|
|
|
71
79
|
shape : tuple of int
|
|
72
80
|
Shape of the object.
|
|
73
81
|
"""
|
|
74
|
-
return
|
|
75
|
-
|
|
82
|
+
return
|
|
83
|
+
|
|
76
84
|
def add_annotation(self, category, dtype):
|
|
77
85
|
"""
|
|
78
86
|
Add an annotation category, if not already existing.
|
|
79
|
-
|
|
87
|
+
|
|
80
88
|
Initially the new annotation is filled with the *zero*
|
|
81
89
|
representation of the given type.
|
|
82
|
-
|
|
90
|
+
|
|
83
91
|
Parameters
|
|
84
92
|
----------
|
|
85
93
|
category : str
|
|
@@ -87,19 +95,18 @@ class _AtomArrayBase(Copyable, metaclass=abc.ABCMeta):
|
|
|
87
95
|
dtype : type or str
|
|
88
96
|
A type instance or a valid *NumPy* *dtype* string.
|
|
89
97
|
Defines the type of the annotation
|
|
90
|
-
|
|
98
|
+
|
|
91
99
|
See Also
|
|
92
100
|
--------
|
|
93
101
|
set_annotation
|
|
94
102
|
"""
|
|
95
103
|
if category not in self._annot:
|
|
96
|
-
self._annot[str(category)] = np.zeros(self._array_length,
|
|
97
|
-
|
|
98
|
-
|
|
104
|
+
self._annot[str(category)] = np.zeros(self._array_length, dtype=dtype)
|
|
105
|
+
|
|
99
106
|
def del_annotation(self, category):
|
|
100
107
|
"""
|
|
101
108
|
Removes an annotation category.
|
|
102
|
-
|
|
109
|
+
|
|
103
110
|
Parameters
|
|
104
111
|
----------
|
|
105
112
|
category : str
|
|
@@ -107,32 +114,30 @@ class _AtomArrayBase(Copyable, metaclass=abc.ABCMeta):
|
|
|
107
114
|
"""
|
|
108
115
|
if category in self._annot:
|
|
109
116
|
del self._annot[str(category)]
|
|
110
|
-
|
|
117
|
+
|
|
111
118
|
def get_annotation(self, category):
|
|
112
119
|
"""
|
|
113
120
|
Return an annotation array.
|
|
114
|
-
|
|
121
|
+
|
|
115
122
|
Parameters
|
|
116
123
|
----------
|
|
117
124
|
category : str
|
|
118
125
|
The annotation category to be returned.
|
|
119
|
-
|
|
126
|
+
|
|
120
127
|
Returns
|
|
121
128
|
-------
|
|
122
129
|
array : ndarray
|
|
123
130
|
The annotation array.
|
|
124
131
|
"""
|
|
125
132
|
if category not in self._annot:
|
|
126
|
-
raise ValueError(
|
|
127
|
-
f"Annotation category '{category}' is not existing"
|
|
128
|
-
)
|
|
133
|
+
raise ValueError(f"Annotation category '{category}' is not existing")
|
|
129
134
|
return self._annot[category]
|
|
130
|
-
|
|
135
|
+
|
|
131
136
|
def set_annotation(self, category, array):
|
|
132
137
|
"""
|
|
133
138
|
Set an annotation array. If the annotation category does not
|
|
134
139
|
exist yet, the category is created.
|
|
135
|
-
|
|
140
|
+
|
|
136
141
|
Parameters
|
|
137
142
|
----------
|
|
138
143
|
category : str
|
|
@@ -143,28 +148,25 @@ class _AtomArrayBase(Copyable, metaclass=abc.ABCMeta):
|
|
|
143
148
|
"""
|
|
144
149
|
if len(array) != self._array_length:
|
|
145
150
|
raise IndexError(
|
|
146
|
-
f"Expected array length {self._array_length}, "
|
|
147
|
-
f"but got {len(array)}"
|
|
151
|
+
f"Expected array length {self._array_length}, " f"but got {len(array)}"
|
|
148
152
|
)
|
|
149
153
|
if category in self._annot:
|
|
150
154
|
# Keep the dtype if the annotation already exists
|
|
151
|
-
self._annot[category] = np.asarray(
|
|
152
|
-
array, dtype=self._annot[category].dtype
|
|
153
|
-
)
|
|
155
|
+
self._annot[category] = np.asarray(array, dtype=self._annot[category].dtype)
|
|
154
156
|
else:
|
|
155
157
|
self._annot[category] = np.asarray(array)
|
|
156
|
-
|
|
158
|
+
|
|
157
159
|
def get_annotation_categories(self):
|
|
158
160
|
"""
|
|
159
161
|
Return a list containing all annotation array categories.
|
|
160
|
-
|
|
162
|
+
|
|
161
163
|
Returns
|
|
162
164
|
-------
|
|
163
165
|
categories : list
|
|
164
166
|
The list containing the names of each annotation array.
|
|
165
167
|
"""
|
|
166
168
|
return list(self._annot.keys())
|
|
167
|
-
|
|
169
|
+
|
|
168
170
|
def _subarray(self, index):
|
|
169
171
|
# Index is one dimensional (boolean mask, index array)
|
|
170
172
|
new_coord = self._coord[..., index, :]
|
|
@@ -180,10 +182,9 @@ class _AtomArrayBase(Copyable, metaclass=abc.ABCMeta):
|
|
|
180
182
|
if self._box is not None:
|
|
181
183
|
new_object._box = self._box
|
|
182
184
|
for annotation in self._annot:
|
|
183
|
-
new_object._annot[annotation] =
|
|
184
|
-
.__getitem__(index))
|
|
185
|
+
new_object._annot[annotation] = self._annot[annotation].__getitem__(index)
|
|
185
186
|
return new_object
|
|
186
|
-
|
|
187
|
+
|
|
187
188
|
def _set_element(self, index, atom):
|
|
188
189
|
try:
|
|
189
190
|
if isinstance(index, (numbers.Integral, np.ndarray)):
|
|
@@ -191,12 +192,10 @@ class _AtomArrayBase(Copyable, metaclass=abc.ABCMeta):
|
|
|
191
192
|
self._annot[name][index] = atom._annot[name]
|
|
192
193
|
self._coord[..., index, :] = atom.coord
|
|
193
194
|
else:
|
|
194
|
-
raise TypeError(
|
|
195
|
-
f"Index must be integer, not '{type(index).__name__}'"
|
|
196
|
-
)
|
|
195
|
+
raise TypeError(f"Index must be integer, not '{type(index).__name__}'")
|
|
197
196
|
except KeyError:
|
|
198
197
|
raise KeyError("The annotations of the 'Atom' are incompatible")
|
|
199
|
-
|
|
198
|
+
|
|
200
199
|
def _del_element(self, index):
|
|
201
200
|
if isinstance(index, numbers.Integral):
|
|
202
201
|
for name in self._annot:
|
|
@@ -208,20 +207,18 @@ class _AtomArrayBase(Copyable, metaclass=abc.ABCMeta):
|
|
|
208
207
|
mask[index] = False
|
|
209
208
|
self._bonds = self._bonds[mask]
|
|
210
209
|
else:
|
|
211
|
-
raise TypeError(
|
|
212
|
-
|
|
213
|
-
)
|
|
214
|
-
|
|
210
|
+
raise TypeError(f"Index must be integer, not '{type(index).__name__}'")
|
|
211
|
+
|
|
215
212
|
def equal_annotations(self, item):
|
|
216
213
|
"""
|
|
217
214
|
Check, if this object shares equal annotation arrays with the
|
|
218
215
|
given :class:`AtomArray` or :class:`AtomArrayStack`.
|
|
219
|
-
|
|
216
|
+
|
|
220
217
|
Parameters
|
|
221
218
|
----------
|
|
222
219
|
item : AtomArray or AtomArrayStack
|
|
223
220
|
The object to compare the annotation arrays with.
|
|
224
|
-
|
|
221
|
+
|
|
225
222
|
Returns
|
|
226
223
|
-------
|
|
227
224
|
equality : bool
|
|
@@ -235,24 +232,24 @@ class _AtomArrayBase(Copyable, metaclass=abc.ABCMeta):
|
|
|
235
232
|
if not np.array_equal(self._annot[name], item._annot[name]):
|
|
236
233
|
return False
|
|
237
234
|
return True
|
|
238
|
-
|
|
235
|
+
|
|
239
236
|
def equal_annotation_categories(self, item):
|
|
240
237
|
"""
|
|
241
238
|
Check, if this object shares equal annotation array categories
|
|
242
239
|
with the given :class:`AtomArray` or :class:`AtomArrayStack`.
|
|
243
|
-
|
|
240
|
+
|
|
244
241
|
Parameters
|
|
245
242
|
----------
|
|
246
243
|
item : AtomArray or AtomArrayStack
|
|
247
244
|
The object to compare the annotation arrays with.
|
|
248
|
-
|
|
245
|
+
|
|
249
246
|
Returns
|
|
250
247
|
-------
|
|
251
248
|
equality : bool
|
|
252
249
|
True, if the annotation array names are equal.
|
|
253
250
|
"""
|
|
254
251
|
return sorted(self._annot.keys()) == sorted(item._annot.keys())
|
|
255
|
-
|
|
252
|
+
|
|
256
253
|
def __getattr__(self, attr):
|
|
257
254
|
"""
|
|
258
255
|
If the attribute is an annotation, the annotation is returned
|
|
@@ -273,7 +270,7 @@ class _AtomArrayBase(Copyable, metaclass=abc.ABCMeta):
|
|
|
273
270
|
raise AttributeError(
|
|
274
271
|
f"'{type(self).__name__}' object has no attribute '{attr}'"
|
|
275
272
|
)
|
|
276
|
-
|
|
273
|
+
|
|
277
274
|
def __setattr__(self, attr, value):
|
|
278
275
|
"""
|
|
279
276
|
If the attribute is an annotation, the :attr:`value` is saved
|
|
@@ -287,15 +284,13 @@ class _AtomArrayBase(Copyable, metaclass=abc.ABCMeta):
|
|
|
287
284
|
if isinstance(self, AtomArray):
|
|
288
285
|
if value.ndim != 2:
|
|
289
286
|
raise ValueError(
|
|
290
|
-
"A 2-dimensional ndarray is expected "
|
|
291
|
-
|
|
292
|
-
)
|
|
287
|
+
"A 2-dimensional ndarray is expected " "for an AtomArray"
|
|
288
|
+
)
|
|
293
289
|
elif isinstance(self, AtomArrayStack):
|
|
294
290
|
if value.ndim != 3:
|
|
295
291
|
raise ValueError(
|
|
296
|
-
"A 3-dimensional ndarray is expected "
|
|
297
|
-
|
|
298
|
-
)
|
|
292
|
+
"A 3-dimensional ndarray is expected " "for an AtomArrayStack"
|
|
293
|
+
)
|
|
299
294
|
if value.shape[-2] != self._array_length:
|
|
300
295
|
raise ValueError(
|
|
301
296
|
f"Expected array length {self._array_length}, "
|
|
@@ -304,7 +299,7 @@ class _AtomArrayBase(Copyable, metaclass=abc.ABCMeta):
|
|
|
304
299
|
if value.shape[-1] != 3:
|
|
305
300
|
raise TypeError("Expected 3 coordinates for each atom")
|
|
306
301
|
super().__setattr__("_coord", value.astype(np.float32, copy=False))
|
|
307
|
-
|
|
302
|
+
|
|
308
303
|
elif attr == "bonds":
|
|
309
304
|
if isinstance(value, BondList):
|
|
310
305
|
if value.get_atom_count() != self._array_length:
|
|
@@ -318,22 +313,21 @@ class _AtomArrayBase(Copyable, metaclass=abc.ABCMeta):
|
|
|
318
313
|
super().__setattr__("_bonds", None)
|
|
319
314
|
else:
|
|
320
315
|
raise TypeError("Value must be 'BondList'")
|
|
321
|
-
|
|
316
|
+
|
|
322
317
|
elif attr == "box":
|
|
323
318
|
if isinstance(value, np.ndarray):
|
|
324
319
|
if isinstance(self, AtomArray):
|
|
325
320
|
if value.ndim != 2:
|
|
326
321
|
raise ValueError(
|
|
327
|
-
"A 2-dimensional ndarray is expected "
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
else: # AtomArrayStack
|
|
322
|
+
"A 2-dimensional ndarray is expected " "for an AtomArray"
|
|
323
|
+
)
|
|
324
|
+
else: # AtomArrayStack
|
|
331
325
|
if value.ndim != 3:
|
|
332
326
|
raise ValueError(
|
|
333
327
|
"A 3-dimensional ndarray is expected "
|
|
334
328
|
"for an AtomArrayStack"
|
|
335
|
-
|
|
336
|
-
if value.shape[-2:] != (3,3):
|
|
329
|
+
)
|
|
330
|
+
if value.shape[-2:] != (3, 3):
|
|
337
331
|
raise TypeError("Box must be a 3x3 matrix (three vectors)")
|
|
338
332
|
box = value.astype(np.float32, copy=False)
|
|
339
333
|
super().__setattr__("_box", box)
|
|
@@ -342,14 +336,14 @@ class _AtomArrayBase(Copyable, metaclass=abc.ABCMeta):
|
|
|
342
336
|
super().__setattr__("_box", None)
|
|
343
337
|
else:
|
|
344
338
|
raise TypeError("Box must be ndarray of floats or None")
|
|
345
|
-
|
|
339
|
+
|
|
346
340
|
elif attr == "_annot":
|
|
347
341
|
super().__setattr__(attr, value)
|
|
348
342
|
elif attr in self._annot:
|
|
349
343
|
self.set_annotation(attr, value)
|
|
350
344
|
else:
|
|
351
345
|
super().__setattr__(attr, value)
|
|
352
|
-
|
|
346
|
+
|
|
353
347
|
def __dir__(self):
|
|
354
348
|
attr = super().__dir__()
|
|
355
349
|
attr.append("coord")
|
|
@@ -358,7 +352,7 @@ class _AtomArrayBase(Copyable, metaclass=abc.ABCMeta):
|
|
|
358
352
|
for name in self._annot.keys():
|
|
359
353
|
attr.append(name)
|
|
360
354
|
return attr
|
|
361
|
-
|
|
355
|
+
|
|
362
356
|
def __eq__(self, item):
|
|
363
357
|
"""
|
|
364
358
|
See Also
|
|
@@ -376,30 +370,31 @@ class _AtomArrayBase(Copyable, metaclass=abc.ABCMeta):
|
|
|
376
370
|
if not np.array_equal(self._box, item._box):
|
|
377
371
|
return False
|
|
378
372
|
return np.array_equal(self._coord, item._coord)
|
|
379
|
-
|
|
373
|
+
|
|
380
374
|
def __len__(self):
|
|
381
375
|
"""
|
|
382
376
|
The length of the annotation arrays.
|
|
383
|
-
|
|
377
|
+
|
|
384
378
|
Returns
|
|
385
379
|
-------
|
|
386
380
|
length : int
|
|
387
381
|
Length of the annotation arrays.
|
|
388
382
|
"""
|
|
389
383
|
return self._array_length
|
|
390
|
-
|
|
384
|
+
|
|
391
385
|
def __add__(self, array):
|
|
392
|
-
if
|
|
386
|
+
if not isinstance(self, type(array)):
|
|
393
387
|
raise TypeError("Can only concatenate two arrays or two stacks")
|
|
394
388
|
# Create either new array or stack, depending of the own type
|
|
395
389
|
if isinstance(self, AtomArray):
|
|
396
|
-
concat = AtomArray(length
|
|
390
|
+
concat = AtomArray(length=self._array_length + array._array_length)
|
|
397
391
|
if isinstance(self, AtomArrayStack):
|
|
398
|
-
concat = AtomArrayStack(
|
|
399
|
-
|
|
400
|
-
|
|
392
|
+
concat = AtomArrayStack(
|
|
393
|
+
self.stack_depth(), self._array_length + array._array_length
|
|
394
|
+
)
|
|
395
|
+
|
|
401
396
|
concat._coord = np.concatenate((self._coord, array.coord), axis=-2)
|
|
402
|
-
|
|
397
|
+
|
|
403
398
|
# Transfer only annotations,
|
|
404
399
|
# which are existent in both operands
|
|
405
400
|
arr_categories = list(array._annot.keys())
|
|
@@ -407,29 +402,29 @@ class _AtomArrayBase(Copyable, metaclass=abc.ABCMeta):
|
|
|
407
402
|
if category in arr_categories:
|
|
408
403
|
annot = self._annot[category]
|
|
409
404
|
arr_annot = array._annot[category]
|
|
410
|
-
concat._annot[category] = np.concatenate((annot,arr_annot))
|
|
411
|
-
|
|
405
|
+
concat._annot[category] = np.concatenate((annot, arr_annot))
|
|
406
|
+
|
|
412
407
|
# Concatenate bonds lists,
|
|
413
408
|
# if at least one of them contains bond information
|
|
414
409
|
if self._bonds is not None or array._bonds is not None:
|
|
415
410
|
bonds1 = self._bonds
|
|
416
411
|
bonds2 = array._bonds
|
|
417
412
|
if bonds1 is None:
|
|
418
|
-
|
|
413
|
+
bonds1 = BondList(self._array_length)
|
|
419
414
|
if bonds2 is None:
|
|
420
415
|
bonds2 = BondList(array._array_length)
|
|
421
416
|
concat._bonds = bonds1 + bonds2
|
|
422
|
-
|
|
417
|
+
|
|
423
418
|
# Copy box
|
|
424
419
|
if self._box is not None:
|
|
425
420
|
concat._box = np.copy(self._box)
|
|
426
421
|
return concat
|
|
427
|
-
|
|
422
|
+
|
|
428
423
|
def __copy_fill__(self, clone):
|
|
429
424
|
super().__copy_fill__(clone)
|
|
430
425
|
self._copy_annotations(clone)
|
|
431
426
|
clone._coord = np.copy(self._coord)
|
|
432
|
-
|
|
427
|
+
|
|
433
428
|
def _copy_annotations(self, clone):
|
|
434
429
|
for name in self._annot:
|
|
435
430
|
clone._annot[name] = np.copy(self._annot[name])
|
|
@@ -437,23 +432,23 @@ class _AtomArrayBase(Copyable, metaclass=abc.ABCMeta):
|
|
|
437
432
|
clone._box = np.copy(self._box)
|
|
438
433
|
if self._bonds is not None:
|
|
439
434
|
clone._bonds = self._bonds.copy()
|
|
440
|
-
|
|
435
|
+
|
|
441
436
|
|
|
442
437
|
class Atom(Copyable):
|
|
443
438
|
"""
|
|
444
439
|
A representation of a single atom.
|
|
445
|
-
|
|
440
|
+
|
|
446
441
|
The coordinates an annotations can be accessed directly.
|
|
447
442
|
A detailed description of each annotation category can be viewed
|
|
448
443
|
:doc:`here </apidoc/biotite.structure>`.
|
|
449
|
-
|
|
444
|
+
|
|
450
445
|
Parameters
|
|
451
446
|
----------
|
|
452
447
|
coord: list or ndarray
|
|
453
448
|
The x, y and z coordinates.
|
|
454
449
|
kwargs
|
|
455
450
|
Atom annotations as key value pair.
|
|
456
|
-
|
|
451
|
+
|
|
457
452
|
Attributes
|
|
458
453
|
----------
|
|
459
454
|
{annot} : scalar
|
|
@@ -463,19 +458,19 @@ class Atom(Copyable):
|
|
|
463
458
|
shape : tuple of int
|
|
464
459
|
Shape of the object.
|
|
465
460
|
In case of an :class:`Atom`, the tuple is empty.
|
|
466
|
-
|
|
461
|
+
|
|
467
462
|
Examples
|
|
468
463
|
--------
|
|
469
|
-
|
|
464
|
+
|
|
470
465
|
>>> atom = Atom([1,2,3], chain_id="A")
|
|
471
466
|
>>> atom.atom_name = "CA"
|
|
472
467
|
>>> print(atom.atom_name)
|
|
473
468
|
CA
|
|
474
469
|
>>> print(atom.coord)
|
|
475
470
|
[1. 2. 3.]
|
|
476
|
-
|
|
471
|
+
|
|
477
472
|
"""
|
|
478
|
-
|
|
473
|
+
|
|
479
474
|
def __init__(self, coord, **kwargs):
|
|
480
475
|
self._annot = {}
|
|
481
476
|
self._annot["chain_id"] = ""
|
|
@@ -498,19 +493,19 @@ class Atom(Copyable):
|
|
|
498
493
|
|
|
499
494
|
def __repr__(self):
|
|
500
495
|
"""Represent Atom as a string for debugging."""
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
annot =
|
|
508
|
-
return f
|
|
496
|
+
# print out key-value pairs and format strings in quotation marks
|
|
497
|
+
annot_parts = [
|
|
498
|
+
f'{key}="{value}"' if isinstance(value, str) else f"{key}={value}"
|
|
499
|
+
for key, value in self._annot.items()
|
|
500
|
+
]
|
|
501
|
+
|
|
502
|
+
annot = ", ".join(annot_parts)
|
|
503
|
+
return f"Atom(np.{np.array_repr(self.coord)}, {annot})"
|
|
509
504
|
|
|
510
505
|
@property
|
|
511
506
|
def shape(self):
|
|
512
507
|
return ()
|
|
513
|
-
|
|
508
|
+
|
|
514
509
|
def __getattr__(self, attr):
|
|
515
510
|
if attr in super().__getattribute__("_annot"):
|
|
516
511
|
return self._annot[attr]
|
|
@@ -518,7 +513,7 @@ class Atom(Copyable):
|
|
|
518
513
|
raise AttributeError(
|
|
519
514
|
f"'{type(self).__name__}' object has no attribute '{attr}'"
|
|
520
515
|
)
|
|
521
|
-
|
|
516
|
+
|
|
522
517
|
def __setattr__(self, attr, value):
|
|
523
518
|
if attr == "_annot":
|
|
524
519
|
super().__setattr__(attr, value)
|
|
@@ -526,16 +521,18 @@ class Atom(Copyable):
|
|
|
526
521
|
super().__setattr__(attr, value)
|
|
527
522
|
else:
|
|
528
523
|
self._annot[attr] = value
|
|
529
|
-
|
|
524
|
+
|
|
530
525
|
def __str__(self):
|
|
531
526
|
hetero = "HET" if self.hetero else ""
|
|
532
|
-
return
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
527
|
+
return (
|
|
528
|
+
f"{hetero:3} {self.chain_id:3} "
|
|
529
|
+
f"{self.res_id:5d}{self.ins_code:1} {self.res_name:3} "
|
|
530
|
+
f"{self.atom_name:6} {self.element:2} "
|
|
531
|
+
f"{self.coord[0]:8.3f} "
|
|
532
|
+
f"{self.coord[1]:8.3f} "
|
|
533
|
+
f"{self.coord[2]:8.3f}"
|
|
534
|
+
)
|
|
535
|
+
|
|
539
536
|
def __eq__(self, item):
|
|
540
537
|
if not isinstance(item, Atom):
|
|
541
538
|
return False
|
|
@@ -547,18 +544,18 @@ class Atom(Copyable):
|
|
|
547
544
|
if self._annot[name] != item._annot[name]:
|
|
548
545
|
return False
|
|
549
546
|
return True
|
|
550
|
-
|
|
547
|
+
|
|
551
548
|
def __ne__(self, item):
|
|
552
549
|
return not self == item
|
|
553
|
-
|
|
550
|
+
|
|
554
551
|
def __copy_create__(self):
|
|
555
552
|
return Atom(self.coord, **self._annot)
|
|
556
553
|
|
|
557
|
-
|
|
554
|
+
|
|
558
555
|
class AtomArray(_AtomArrayBase):
|
|
559
556
|
"""
|
|
560
557
|
An array representation of a model consisting of multiple atoms.
|
|
561
|
-
|
|
558
|
+
|
|
562
559
|
An :class:`AtomArray` can be seen as a list of :class:`Atom`
|
|
563
560
|
instances.
|
|
564
561
|
Instead of using directly a list, this class uses an *NumPy*
|
|
@@ -573,14 +570,14 @@ class AtomArray(_AtomArrayBase):
|
|
|
573
570
|
or :func:`set_annotation()`.
|
|
574
571
|
A detailed description of each annotation category can be viewed
|
|
575
572
|
:doc:`here </apidoc/biotite.structure>`.
|
|
576
|
-
|
|
573
|
+
|
|
577
574
|
In order to get an an subarray of an :class:`AtomArray`,
|
|
578
575
|
*NumPy* style indexing is used.
|
|
579
576
|
This includes slices, boolean arrays, index arrays and even
|
|
580
577
|
*Ellipsis* notation.
|
|
581
578
|
Using a single integer as index returns a single :class:`Atom`
|
|
582
579
|
instance.
|
|
583
|
-
|
|
580
|
+
|
|
584
581
|
Inserting or appending an :class:`AtomArray` to another
|
|
585
582
|
:class:`AtomArray` is done with the '+' operator.
|
|
586
583
|
Only the annotation categories, which are existing in both arrays,
|
|
@@ -611,7 +608,7 @@ class AtomArray(_AtomArrayBase):
|
|
|
611
608
|
----------
|
|
612
609
|
length : int
|
|
613
610
|
The fixed amount of atoms in the array.
|
|
614
|
-
|
|
611
|
+
|
|
615
612
|
Attributes
|
|
616
613
|
----------
|
|
617
614
|
{annot} : ndarray
|
|
@@ -629,44 +626,44 @@ class AtomArray(_AtomArrayBase):
|
|
|
629
626
|
Shape of the atom array.
|
|
630
627
|
The single value in the tuple is
|
|
631
628
|
the length of the atom array.
|
|
632
|
-
|
|
629
|
+
|
|
633
630
|
Examples
|
|
634
631
|
--------
|
|
635
632
|
Creating an atom array from atoms:
|
|
636
|
-
|
|
633
|
+
|
|
637
634
|
>>> atom1 = Atom([1,2,3], chain_id="A")
|
|
638
635
|
>>> atom2 = Atom([2,3,4], chain_id="A")
|
|
639
636
|
>>> atom3 = Atom([3,4,5], chain_id="B")
|
|
640
637
|
>>> atom_array = array([atom1, atom2, atom3])
|
|
641
638
|
>>> print(atom_array.array_length())
|
|
642
639
|
3
|
|
643
|
-
|
|
640
|
+
|
|
644
641
|
Accessing an annotation array:
|
|
645
|
-
|
|
642
|
+
|
|
646
643
|
>>> print(atom_array.chain_id)
|
|
647
644
|
['A' 'A' 'B']
|
|
648
|
-
|
|
645
|
+
|
|
649
646
|
Accessing the coordinates:
|
|
650
|
-
|
|
647
|
+
|
|
651
648
|
>>> print(atom_array.coord)
|
|
652
649
|
[[1. 2. 3.]
|
|
653
650
|
[2. 3. 4.]
|
|
654
651
|
[3. 4. 5.]]
|
|
655
|
-
|
|
652
|
+
|
|
656
653
|
*NumPy* style filtering:
|
|
657
|
-
|
|
654
|
+
|
|
658
655
|
>>> atom_array = atom_array[atom_array.chain_id == "A"]
|
|
659
656
|
>>> print(atom_array.array_length())
|
|
660
657
|
2
|
|
661
|
-
|
|
658
|
+
|
|
662
659
|
Inserting an atom array:
|
|
663
|
-
|
|
660
|
+
|
|
664
661
|
>>> insert = array([Atom([7,8,9], chain_id="C")])
|
|
665
662
|
>>> atom_array = atom_array[0:1] + insert + atom_array[1:2]
|
|
666
663
|
>>> print(atom_array.chain_id)
|
|
667
664
|
['A' 'C' 'A']
|
|
668
665
|
"""
|
|
669
|
-
|
|
666
|
+
|
|
670
667
|
def __init__(self, length):
|
|
671
668
|
super().__init__(length)
|
|
672
669
|
if length is None:
|
|
@@ -676,13 +673,13 @@ class AtomArray(_AtomArrayBase):
|
|
|
676
673
|
|
|
677
674
|
def __repr__(self):
|
|
678
675
|
"""Represent AtomArray as a string for debugging."""
|
|
679
|
-
atoms =
|
|
676
|
+
atoms = ""
|
|
680
677
|
for i in range(0, self.array_length()):
|
|
681
678
|
if len(atoms) == 0:
|
|
682
|
-
atoms =
|
|
679
|
+
atoms = "\n\t" + self.get_atom(i).__repr__()
|
|
683
680
|
else:
|
|
684
|
-
atoms = atoms +
|
|
685
|
-
return f
|
|
681
|
+
atoms = atoms + ",\n\t" + self.get_atom(i).__repr__()
|
|
682
|
+
return f"array([{atoms}\n])"
|
|
686
683
|
|
|
687
684
|
@property
|
|
688
685
|
def shape(self):
|
|
@@ -703,33 +700,33 @@ class AtomArray(_AtomArrayBase):
|
|
|
703
700
|
--------
|
|
704
701
|
array_length
|
|
705
702
|
"""
|
|
706
|
-
return self.array_length(),
|
|
703
|
+
return (self.array_length(),)
|
|
707
704
|
|
|
708
705
|
def get_atom(self, index):
|
|
709
706
|
"""
|
|
710
707
|
Obtain the atom instance of the array at the specified index.
|
|
711
|
-
|
|
708
|
+
|
|
712
709
|
The same as ``array[index]``, if `index` is an integer.
|
|
713
|
-
|
|
710
|
+
|
|
714
711
|
Parameters
|
|
715
712
|
----------
|
|
716
713
|
index : int
|
|
717
714
|
Index of the atom.
|
|
718
|
-
|
|
715
|
+
|
|
719
716
|
Returns
|
|
720
717
|
-------
|
|
721
718
|
atom : Atom
|
|
722
|
-
Atom at position `index`.
|
|
719
|
+
Atom at position `index`.
|
|
723
720
|
"""
|
|
724
721
|
kwargs = {}
|
|
725
722
|
for name, annotation in self._annot.items():
|
|
726
723
|
kwargs[name] = annotation[index]
|
|
727
|
-
return Atom(coord
|
|
728
|
-
|
|
724
|
+
return Atom(coord=self._coord[index], kwargs=kwargs)
|
|
725
|
+
|
|
729
726
|
def __iter__(self):
|
|
730
727
|
"""
|
|
731
728
|
Iterate through the array.
|
|
732
|
-
|
|
729
|
+
|
|
733
730
|
Yields
|
|
734
731
|
------
|
|
735
732
|
atom : Atom
|
|
@@ -738,16 +735,16 @@ class AtomArray(_AtomArrayBase):
|
|
|
738
735
|
while i < len(self):
|
|
739
736
|
yield self.get_atom(i)
|
|
740
737
|
i += 1
|
|
741
|
-
|
|
738
|
+
|
|
742
739
|
def __getitem__(self, index):
|
|
743
740
|
"""
|
|
744
741
|
Obtain a subarray or the atom instance at the specified index.
|
|
745
|
-
|
|
742
|
+
|
|
746
743
|
Parameters
|
|
747
744
|
----------
|
|
748
745
|
index : object
|
|
749
746
|
All index types *NumPy* accepts, are valid.
|
|
750
|
-
|
|
747
|
+
|
|
751
748
|
Returns
|
|
752
749
|
-------
|
|
753
750
|
sub_array : Atom or AtomArray
|
|
@@ -763,16 +760,14 @@ class AtomArray(_AtomArrayBase):
|
|
|
763
760
|
# If first index is "...", just ignore the first index
|
|
764
761
|
return self.__getitem__(index[1])
|
|
765
762
|
else:
|
|
766
|
-
raise IndexError(
|
|
767
|
-
"'AtomArray' does not accept multidimensional indices"
|
|
768
|
-
)
|
|
763
|
+
raise IndexError("'AtomArray' does not accept multidimensional indices")
|
|
769
764
|
else:
|
|
770
765
|
return self._subarray(index)
|
|
771
|
-
|
|
766
|
+
|
|
772
767
|
def __setitem__(self, index, atom):
|
|
773
768
|
"""
|
|
774
769
|
Set the atom at the specified array position.
|
|
775
|
-
|
|
770
|
+
|
|
776
771
|
Parameters
|
|
777
772
|
----------
|
|
778
773
|
index : int
|
|
@@ -781,38 +776,38 @@ class AtomArray(_AtomArrayBase):
|
|
|
781
776
|
The atom to be set.
|
|
782
777
|
"""
|
|
783
778
|
self._set_element(index, atom)
|
|
784
|
-
|
|
779
|
+
|
|
785
780
|
def __delitem__(self, index):
|
|
786
781
|
"""
|
|
787
782
|
Deletes the atom at the specified array position.
|
|
788
|
-
|
|
783
|
+
|
|
789
784
|
Parameters
|
|
790
785
|
----------
|
|
791
786
|
index : int
|
|
792
787
|
The position where the atom should be deleted.
|
|
793
788
|
"""
|
|
794
789
|
self._del_element(index)
|
|
795
|
-
|
|
790
|
+
|
|
796
791
|
def __len__(self):
|
|
797
792
|
"""
|
|
798
793
|
The length of the array.
|
|
799
|
-
|
|
794
|
+
|
|
800
795
|
Returns
|
|
801
796
|
-------
|
|
802
797
|
length : int
|
|
803
798
|
Length of the array.
|
|
804
799
|
"""
|
|
805
800
|
return self.array_length()
|
|
806
|
-
|
|
801
|
+
|
|
807
802
|
def __eq__(self, item):
|
|
808
803
|
"""
|
|
809
804
|
Check if the array equals another :class:`AtomArray`.
|
|
810
|
-
|
|
805
|
+
|
|
811
806
|
Parameters
|
|
812
807
|
----------
|
|
813
808
|
item : object
|
|
814
809
|
Object to campare the array with.
|
|
815
|
-
|
|
810
|
+
|
|
816
811
|
Returns
|
|
817
812
|
-------
|
|
818
813
|
equal : bool
|
|
@@ -824,15 +819,15 @@ class AtomArray(_AtomArrayBase):
|
|
|
824
819
|
if not isinstance(item, AtomArray):
|
|
825
820
|
return False
|
|
826
821
|
return True
|
|
827
|
-
|
|
822
|
+
|
|
828
823
|
def __str__(self):
|
|
829
824
|
"""
|
|
830
825
|
Get a string representation of the array.
|
|
831
|
-
|
|
826
|
+
|
|
832
827
|
Each line contains the attributes of one atom.
|
|
833
828
|
"""
|
|
834
829
|
return "\n".join([str(atom) for atom in self])
|
|
835
|
-
|
|
830
|
+
|
|
836
831
|
def __copy_create__(self):
|
|
837
832
|
return AtomArray(self.array_length())
|
|
838
833
|
|
|
@@ -841,7 +836,7 @@ class AtomArrayStack(_AtomArrayBase):
|
|
|
841
836
|
"""
|
|
842
837
|
A collection of multiple :class:`AtomArray` instances, where each
|
|
843
838
|
atom array has equal annotation arrays.
|
|
844
|
-
|
|
839
|
+
|
|
845
840
|
Effectively, this means that each atom is occuring in every array in
|
|
846
841
|
the stack at differing coordinates. This situation arises e.g. in
|
|
847
842
|
NMR-elucidated or simulated structures. Since the annotations are
|
|
@@ -849,7 +844,7 @@ class AtomArrayStack(_AtomArrayBase):
|
|
|
849
844
|
coordinate array is 3-D (m x n x 3).
|
|
850
845
|
A detailed description of each annotation category can be viewed
|
|
851
846
|
:doc:`here </apidoc/biotite.structure>`.
|
|
852
|
-
|
|
847
|
+
|
|
853
848
|
Indexing works similar to :class:`AtomArray`, with the difference,
|
|
854
849
|
that two index dimensions are possible:
|
|
855
850
|
The first index dimension specifies the array(s), the second index
|
|
@@ -857,24 +852,24 @@ class AtomArrayStack(_AtomArrayBase):
|
|
|
857
852
|
in :class:`AtomArray`).
|
|
858
853
|
Using a single integer as first dimension index returns a single
|
|
859
854
|
:class:`AtomArray` instance.
|
|
860
|
-
|
|
855
|
+
|
|
861
856
|
Concatenation of atoms for each array in the stack is done using the
|
|
862
857
|
'+' operator. For addition of atom arrays onto the stack use the
|
|
863
858
|
:func:`stack()` method.
|
|
864
859
|
|
|
865
860
|
The :attr:`box` attribute has the shape *m x 3 x 3*, as the cell
|
|
866
861
|
might be different for each frame in the atom array stack.
|
|
867
|
-
|
|
862
|
+
|
|
868
863
|
Parameters
|
|
869
864
|
----------
|
|
870
865
|
depth : int
|
|
871
866
|
The fixed amount of arrays in the stack. When indexing, this is
|
|
872
867
|
the length of the first dimension.
|
|
873
|
-
|
|
868
|
+
|
|
874
869
|
length : int
|
|
875
870
|
The fixed amount of atoms in each array in the stack. When
|
|
876
871
|
indexing, this is the length of the second dimension.
|
|
877
|
-
|
|
872
|
+
|
|
878
873
|
Attributes
|
|
879
874
|
----------
|
|
880
875
|
{annot} : ndarray, shape=(n,)
|
|
@@ -892,15 +887,15 @@ class AtomArrayStack(_AtomArrayBase):
|
|
|
892
887
|
Shape of the stack.
|
|
893
888
|
The numbers correspond to the stack depth
|
|
894
889
|
and array length, respectively.
|
|
895
|
-
|
|
890
|
+
|
|
896
891
|
See also
|
|
897
892
|
--------
|
|
898
893
|
AtomArray
|
|
899
|
-
|
|
894
|
+
|
|
900
895
|
Examples
|
|
901
896
|
--------
|
|
902
897
|
Creating an atom array stack from two arrays:
|
|
903
|
-
|
|
898
|
+
|
|
904
899
|
>>> atom1 = Atom([1,2,3], chain_id="A")
|
|
905
900
|
>>> atom2 = Atom([2,3,4], chain_id="A")
|
|
906
901
|
>>> atom3 = Atom([3,4,5], chain_id="B")
|
|
@@ -925,40 +920,40 @@ class AtomArrayStack(_AtomArrayBase):
|
|
|
925
920
|
[5. 6. 7.]
|
|
926
921
|
[6. 7. 8.]]]
|
|
927
922
|
"""
|
|
928
|
-
|
|
923
|
+
|
|
929
924
|
def __init__(self, depth, length):
|
|
930
925
|
super().__init__(length)
|
|
931
|
-
if depth
|
|
926
|
+
if depth is None or length is None:
|
|
932
927
|
self._coord = None
|
|
933
928
|
else:
|
|
934
929
|
self._coord = np.full((depth, length, 3), np.nan, dtype=np.float32)
|
|
935
930
|
|
|
936
931
|
def __repr__(self):
|
|
937
932
|
"""Represent AtomArrayStack as a string for debugging."""
|
|
938
|
-
arrays =
|
|
933
|
+
arrays = ""
|
|
939
934
|
for i in range(0, self.stack_depth()):
|
|
940
935
|
if len(arrays) == 0:
|
|
941
|
-
arrays =
|
|
936
|
+
arrays = "\n\t" + self.get_array(i).__repr__()
|
|
942
937
|
else:
|
|
943
|
-
arrays = arrays +
|
|
944
|
-
return f
|
|
938
|
+
arrays = arrays + ",\n\t" + self.get_array(i).__repr__()
|
|
939
|
+
return f"stack([{arrays}\n])"
|
|
945
940
|
|
|
946
941
|
def get_array(self, index):
|
|
947
942
|
"""
|
|
948
943
|
Obtain the atom array instance of the stack at the specified
|
|
949
944
|
index.
|
|
950
|
-
|
|
945
|
+
|
|
951
946
|
The same as ``stack[index]``, if `index` is an integer.
|
|
952
|
-
|
|
947
|
+
|
|
953
948
|
Parameters
|
|
954
949
|
----------
|
|
955
950
|
index : int
|
|
956
951
|
Index of the atom array.
|
|
957
|
-
|
|
952
|
+
|
|
958
953
|
Returns
|
|
959
954
|
-------
|
|
960
955
|
array : AtomArray
|
|
961
|
-
AtomArray at position `index`.
|
|
956
|
+
AtomArray at position `index`.
|
|
962
957
|
"""
|
|
963
958
|
array = AtomArray(self.array_length())
|
|
964
959
|
for name in self._annot:
|
|
@@ -970,14 +965,14 @@ class AtomArrayStack(_AtomArrayBase):
|
|
|
970
965
|
array._box = self._box[index]
|
|
971
966
|
|
|
972
967
|
return array
|
|
973
|
-
|
|
968
|
+
|
|
974
969
|
def stack_depth(self):
|
|
975
970
|
"""
|
|
976
971
|
Get the depth of the stack.
|
|
977
|
-
|
|
972
|
+
|
|
978
973
|
This value represents the amount of atom arrays in the stack.
|
|
979
974
|
It is the same as ``len(array)``.
|
|
980
|
-
|
|
975
|
+
|
|
981
976
|
Returns
|
|
982
977
|
-------
|
|
983
978
|
length : int
|
|
@@ -1005,7 +1000,7 @@ class AtomArrayStack(_AtomArrayBase):
|
|
|
1005
1000
|
def __iter__(self):
|
|
1006
1001
|
"""
|
|
1007
1002
|
Iterate through the array.
|
|
1008
|
-
|
|
1003
|
+
|
|
1009
1004
|
Yields
|
|
1010
1005
|
------
|
|
1011
1006
|
array : AtomArray
|
|
@@ -1014,17 +1009,17 @@ class AtomArrayStack(_AtomArrayBase):
|
|
|
1014
1009
|
while i < len(self):
|
|
1015
1010
|
yield self.get_array(i)
|
|
1016
1011
|
i += 1
|
|
1017
|
-
|
|
1012
|
+
|
|
1018
1013
|
def __getitem__(self, index):
|
|
1019
1014
|
"""
|
|
1020
1015
|
Obtain the atom array instance or an substack at the specified
|
|
1021
1016
|
index.
|
|
1022
|
-
|
|
1017
|
+
|
|
1023
1018
|
Parameters
|
|
1024
1019
|
----------
|
|
1025
1020
|
index : object
|
|
1026
1021
|
All index types *NumPy* accepts are valid.
|
|
1027
|
-
|
|
1022
|
+
|
|
1028
1023
|
Returns
|
|
1029
1024
|
-------
|
|
1030
1025
|
sub_array : AtomArray or AtomArrayStack
|
|
@@ -1033,7 +1028,7 @@ class AtomArrayStack(_AtomArrayBase):
|
|
|
1033
1028
|
Otherwise an :class:`AtomArrayStack` with reduced depth and
|
|
1034
1029
|
length is returned.
|
|
1035
1030
|
In case the index is a tuple(int, int) an :class:`Atom`
|
|
1036
|
-
instance is returned.
|
|
1031
|
+
instance is returned.
|
|
1037
1032
|
"""
|
|
1038
1033
|
if isinstance(index, numbers.Integral):
|
|
1039
1034
|
return self.get_array(index)
|
|
@@ -1050,7 +1045,7 @@ class AtomArrayStack(_AtomArrayBase):
|
|
|
1050
1045
|
if isinstance(index[1], numbers.Integral):
|
|
1051
1046
|
# Prevent reduction in dimensionality
|
|
1052
1047
|
# in second dimension
|
|
1053
|
-
new_stack = self._subarray(slice(index[1], index[1]+1))
|
|
1048
|
+
new_stack = self._subarray(slice(index[1], index[1] + 1))
|
|
1054
1049
|
else:
|
|
1055
1050
|
new_stack = self._subarray(index[1])
|
|
1056
1051
|
if index[0] is not Ellipsis:
|
|
@@ -1065,14 +1060,13 @@ class AtomArrayStack(_AtomArrayBase):
|
|
|
1065
1060
|
if self._box is not None:
|
|
1066
1061
|
new_stack._box = self._box[index]
|
|
1067
1062
|
return new_stack
|
|
1068
|
-
|
|
1069
|
-
|
|
1063
|
+
|
|
1070
1064
|
def __setitem__(self, index, array):
|
|
1071
1065
|
"""
|
|
1072
1066
|
Set the atom array at the specified stack position.
|
|
1073
|
-
|
|
1067
|
+
|
|
1074
1068
|
The array and the stack must have equal annotation arrays.
|
|
1075
|
-
|
|
1069
|
+
|
|
1076
1070
|
Parameters
|
|
1077
1071
|
----------
|
|
1078
1072
|
index : int
|
|
@@ -1081,26 +1075,20 @@ class AtomArrayStack(_AtomArrayBase):
|
|
|
1081
1075
|
The atom array to be set.
|
|
1082
1076
|
"""
|
|
1083
1077
|
if not self.equal_annotations(array):
|
|
1084
|
-
raise ValueError(
|
|
1085
|
-
"The stack and the array have unequal annotations"
|
|
1086
|
-
)
|
|
1078
|
+
raise ValueError("The stack and the array have unequal annotations")
|
|
1087
1079
|
if self.bonds != array.bonds:
|
|
1088
|
-
raise ValueError(
|
|
1089
|
-
"The stack and the array have unequal bonds"
|
|
1090
|
-
)
|
|
1080
|
+
raise ValueError("The stack and the array have unequal bonds")
|
|
1091
1081
|
if isinstance(index, numbers.Integral):
|
|
1092
1082
|
self.coord[index] = array.coord
|
|
1093
1083
|
if self.box is not None:
|
|
1094
1084
|
self.box[index] = array.box
|
|
1095
1085
|
else:
|
|
1096
|
-
raise TypeError(
|
|
1097
|
-
|
|
1098
|
-
)
|
|
1099
|
-
|
|
1086
|
+
raise TypeError(f"Index must be integer, not '{type(index).__name__}'")
|
|
1087
|
+
|
|
1100
1088
|
def __delitem__(self, index):
|
|
1101
1089
|
"""
|
|
1102
1090
|
Deletes the atom array at the specified stack position.
|
|
1103
|
-
|
|
1091
|
+
|
|
1104
1092
|
Parameters
|
|
1105
1093
|
----------
|
|
1106
1094
|
index : int
|
|
@@ -1109,14 +1097,12 @@ class AtomArrayStack(_AtomArrayBase):
|
|
|
1109
1097
|
if isinstance(index, numbers.Integral):
|
|
1110
1098
|
self._coord = np.delete(self._coord, index, axis=0)
|
|
1111
1099
|
else:
|
|
1112
|
-
raise TypeError(
|
|
1113
|
-
|
|
1114
|
-
)
|
|
1115
|
-
|
|
1100
|
+
raise TypeError(f"Index must be integer, not '{type(index).__name__}'")
|
|
1101
|
+
|
|
1116
1102
|
def __len__(self):
|
|
1117
1103
|
"""
|
|
1118
1104
|
The depth of the stack, i.e. the amount of models.
|
|
1119
|
-
|
|
1105
|
+
|
|
1120
1106
|
Returns
|
|
1121
1107
|
-------
|
|
1122
1108
|
depth : int
|
|
@@ -1124,16 +1110,16 @@ class AtomArrayStack(_AtomArrayBase):
|
|
|
1124
1110
|
"""
|
|
1125
1111
|
# length is determined by length of coord attribute
|
|
1126
1112
|
return self._coord.shape[0]
|
|
1127
|
-
|
|
1113
|
+
|
|
1128
1114
|
def __eq__(self, item):
|
|
1129
1115
|
"""
|
|
1130
1116
|
Check if the array equals another :class:`AtomArray`
|
|
1131
|
-
|
|
1117
|
+
|
|
1132
1118
|
Parameters
|
|
1133
1119
|
----------
|
|
1134
1120
|
item : object
|
|
1135
1121
|
Object to campare the array with.
|
|
1136
|
-
|
|
1122
|
+
|
|
1137
1123
|
Returns
|
|
1138
1124
|
-------
|
|
1139
1125
|
equal : bool
|
|
@@ -1145,20 +1131,20 @@ class AtomArrayStack(_AtomArrayBase):
|
|
|
1145
1131
|
if not isinstance(item, AtomArrayStack):
|
|
1146
1132
|
return False
|
|
1147
1133
|
return True
|
|
1148
|
-
|
|
1134
|
+
|
|
1149
1135
|
def __str__(self):
|
|
1150
1136
|
"""
|
|
1151
1137
|
Get a string representation of the stack.
|
|
1152
|
-
|
|
1138
|
+
|
|
1153
1139
|
:class:`AtomArray` strings eparated by blank lines
|
|
1154
1140
|
and a line indicating the index.
|
|
1155
1141
|
"""
|
|
1156
1142
|
string = ""
|
|
1157
1143
|
for i, array in enumerate(self):
|
|
1158
|
-
string += "Model " + str(i+1) + "\n"
|
|
1144
|
+
string += "Model " + str(i + 1) + "\n"
|
|
1159
1145
|
string += str(array) + "\n" + "\n"
|
|
1160
1146
|
return string
|
|
1161
|
-
|
|
1147
|
+
|
|
1162
1148
|
def __copy_create__(self):
|
|
1163
1149
|
return AtomArrayStack(self.stack_depth(), self.array_length())
|
|
1164
1150
|
|
|
@@ -1166,23 +1152,23 @@ class AtomArrayStack(_AtomArrayBase):
|
|
|
1166
1152
|
def array(atoms):
|
|
1167
1153
|
"""
|
|
1168
1154
|
Create an :class:`AtomArray` from a list of :class:`Atom`.
|
|
1169
|
-
|
|
1155
|
+
|
|
1170
1156
|
Parameters
|
|
1171
1157
|
----------
|
|
1172
1158
|
atoms : iterable object of Atom
|
|
1173
1159
|
The atoms to be combined in an array.
|
|
1174
1160
|
All atoms must share the same annotation categories.
|
|
1175
|
-
|
|
1161
|
+
|
|
1176
1162
|
Returns
|
|
1177
1163
|
-------
|
|
1178
1164
|
array : AtomArray
|
|
1179
1165
|
The listed atoms as array.
|
|
1180
|
-
|
|
1166
|
+
|
|
1181
1167
|
Examples
|
|
1182
1168
|
--------
|
|
1183
|
-
|
|
1169
|
+
|
|
1184
1170
|
Creating an atom array from atoms:
|
|
1185
|
-
|
|
1171
|
+
|
|
1186
1172
|
>>> atom1 = Atom([1,2,3], chain_id="A")
|
|
1187
1173
|
>>> atom2 = Atom([2,3,4], chain_id="A")
|
|
1188
1174
|
>>> atom3 = Atom([3,4,5], chain_id="B")
|
|
@@ -1204,7 +1190,7 @@ def array(atoms):
|
|
|
1204
1190
|
array = AtomArray(len(atoms))
|
|
1205
1191
|
# Add all (also optional) annotation categories
|
|
1206
1192
|
for name in names:
|
|
1207
|
-
array.add_annotation(name, dtype=type(atoms[0]._annot[name]))
|
|
1193
|
+
array.add_annotation(name, dtype=type(atoms[0]._annot[name]))
|
|
1208
1194
|
# Add all atoms to AtomArray
|
|
1209
1195
|
for i in range(len(atoms)):
|
|
1210
1196
|
for name in names:
|
|
@@ -1216,23 +1202,23 @@ def array(atoms):
|
|
|
1216
1202
|
def stack(arrays):
|
|
1217
1203
|
"""
|
|
1218
1204
|
Create an :class:`AtomArrayStack` from a list of :class:`AtomArray`.
|
|
1219
|
-
|
|
1205
|
+
|
|
1220
1206
|
Parameters
|
|
1221
1207
|
----------
|
|
1222
1208
|
arrays : iterable object of AtomArray
|
|
1223
1209
|
The atom arrays to be combined in a stack.
|
|
1224
1210
|
All atom arrays must have an equal number of atoms and equal
|
|
1225
1211
|
annotation arrays.
|
|
1226
|
-
|
|
1212
|
+
|
|
1227
1213
|
Returns
|
|
1228
1214
|
-------
|
|
1229
1215
|
stack : AtomArrayStack
|
|
1230
1216
|
The stacked atom arrays.
|
|
1231
|
-
|
|
1217
|
+
|
|
1232
1218
|
Examples
|
|
1233
1219
|
--------
|
|
1234
1220
|
Creating an atom array stack from two arrays:
|
|
1235
|
-
|
|
1221
|
+
|
|
1236
1222
|
>>> atom1 = Atom([1,2,3], chain_id="A")
|
|
1237
1223
|
>>> atom2 = Atom([2,3,4], chain_id="A")
|
|
1238
1224
|
>>> atom3 = Atom([3,4,5], chain_id="B")
|
|
@@ -1272,7 +1258,7 @@ def stack(arrays):
|
|
|
1272
1258
|
array_stack = AtomArrayStack(array_count, ref_array.array_length())
|
|
1273
1259
|
for name, annotation in ref_array._annot.items():
|
|
1274
1260
|
array_stack._annot[name] = annotation
|
|
1275
|
-
coord_list = [array._coord for array in arrays]
|
|
1261
|
+
coord_list = [array._coord for array in arrays]
|
|
1276
1262
|
array_stack._coord = np.stack(coord_list, axis=0)
|
|
1277
1263
|
# Take bond list from first array
|
|
1278
1264
|
array_stack._bonds = ref_array._bonds
|
|
@@ -1296,14 +1282,14 @@ def repeat(atoms, coord):
|
|
|
1296
1282
|
The length of first dimension determines the number of repeats.
|
|
1297
1283
|
If `atoms` is an :class:`AtomArray` 3 dimensions, otherwise
|
|
1298
1284
|
4 dimensions are required.
|
|
1299
|
-
|
|
1285
|
+
|
|
1300
1286
|
Returns
|
|
1301
1287
|
-------
|
|
1302
1288
|
repeated: AtomArray, shape=(n*k,) or AtomArrayStack, shape=(m,n*k)
|
|
1303
1289
|
The repeated atoms.
|
|
1304
1290
|
Whether an :class:`AtomArray` or an :class:`AtomArrayStack` is
|
|
1305
1291
|
returned depends on the input `atoms`.
|
|
1306
|
-
|
|
1292
|
+
|
|
1307
1293
|
Examples
|
|
1308
1294
|
--------
|
|
1309
1295
|
|
|
@@ -1336,7 +1322,7 @@ def repeat(atoms, coord):
|
|
|
1336
1322
|
raise ValueError(
|
|
1337
1323
|
f"Expected 4 dimensions for the coordinate array, got {coord.ndim}"
|
|
1338
1324
|
)
|
|
1339
|
-
|
|
1325
|
+
|
|
1340
1326
|
repetitions = len(coord)
|
|
1341
1327
|
orig_length = atoms.array_length()
|
|
1342
1328
|
new_length = orig_length * repetitions
|
|
@@ -1358,24 +1344,24 @@ def repeat(atoms, coord):
|
|
|
1358
1344
|
)
|
|
1359
1345
|
repeated = AtomArrayStack(atoms.stack_depth(), new_length)
|
|
1360
1346
|
repeated.coord = coord.reshape((atoms.stack_depth(), new_length, 3))
|
|
1361
|
-
|
|
1347
|
+
|
|
1362
1348
|
else:
|
|
1363
1349
|
raise TypeError(
|
|
1364
1350
|
f"Expected 'AtomArray' or 'AtomArrayStack', "
|
|
1365
1351
|
f"but got {type(atoms).__name__}"
|
|
1366
1352
|
)
|
|
1367
|
-
|
|
1353
|
+
|
|
1368
1354
|
for category in atoms.get_annotation_categories():
|
|
1369
1355
|
annot = np.tile(atoms.get_annotation(category), repetitions)
|
|
1370
1356
|
repeated.set_annotation(category, annot)
|
|
1371
1357
|
if atoms.bonds is not None:
|
|
1372
1358
|
repeated_bonds = atoms.bonds.copy()
|
|
1373
|
-
for _ in range(repetitions-1):
|
|
1359
|
+
for _ in range(repetitions - 1):
|
|
1374
1360
|
repeated_bonds += atoms.bonds
|
|
1375
1361
|
repeated.bonds = repeated_bonds
|
|
1376
1362
|
if atoms.box is not None:
|
|
1377
1363
|
repeated.box = atoms.box.copy()
|
|
1378
|
-
|
|
1364
|
+
|
|
1379
1365
|
return repeated
|
|
1380
1366
|
|
|
1381
1367
|
|
|
@@ -1383,7 +1369,7 @@ def from_template(template, coord, box=None):
|
|
|
1383
1369
|
"""
|
|
1384
1370
|
Create an :class:`AtomArrayStack` using template atoms and given
|
|
1385
1371
|
coordinates.
|
|
1386
|
-
|
|
1372
|
+
|
|
1387
1373
|
Parameters
|
|
1388
1374
|
----------
|
|
1389
1375
|
template : AtomArray, shape=(n,) or AtomArrayStack, shape=(m,n)
|
|
@@ -1393,7 +1379,7 @@ def from_template(template, coord, box=None):
|
|
|
1393
1379
|
The coordinates for each model of the returned stack.
|
|
1394
1380
|
box : ndarray, optional, dtype=float, shape=(l,3,3)
|
|
1395
1381
|
The box for each model of the returned stack.
|
|
1396
|
-
|
|
1382
|
+
|
|
1397
1383
|
Returns
|
|
1398
1384
|
-------
|
|
1399
1385
|
array_stack : AtomArrayStack
|
|
@@ -1409,7 +1395,7 @@ def from_template(template, coord, box=None):
|
|
|
1409
1395
|
|
|
1410
1396
|
# Create empty stack with no models
|
|
1411
1397
|
new_stack = AtomArrayStack(0, template.array_length())
|
|
1412
|
-
|
|
1398
|
+
|
|
1413
1399
|
for category in template.get_annotation_categories():
|
|
1414
1400
|
annot = template.get_annotation(category)
|
|
1415
1401
|
new_stack.set_annotation(category, annot)
|
|
@@ -1417,30 +1403,30 @@ def from_template(template, coord, box=None):
|
|
|
1417
1403
|
new_stack.bonds = template.bonds.copy()
|
|
1418
1404
|
if box is not None:
|
|
1419
1405
|
new_stack.box = box.copy()
|
|
1420
|
-
|
|
1406
|
+
|
|
1421
1407
|
# After setting the coordinates the number of models is the number
|
|
1422
1408
|
# of models in the new coordinates
|
|
1423
1409
|
new_stack.coord = coord
|
|
1424
|
-
|
|
1410
|
+
|
|
1425
1411
|
return new_stack
|
|
1426
1412
|
|
|
1427
1413
|
|
|
1428
1414
|
def coord(item):
|
|
1429
1415
|
"""
|
|
1430
1416
|
Get the atom coordinates of the given array.
|
|
1431
|
-
|
|
1417
|
+
|
|
1432
1418
|
This may be directly and :class:`Atom`, :class:`AtomArray` or
|
|
1433
1419
|
:class:`AtomArrayStack` or
|
|
1434
1420
|
alternatively an (n x 3) or (m x n x 3) :class:`ndarray`
|
|
1435
1421
|
containing the coordinates.
|
|
1436
|
-
|
|
1422
|
+
|
|
1437
1423
|
Parameters
|
|
1438
1424
|
----------
|
|
1439
1425
|
item : Atom or AtomArray or AtomArrayStack or ndarray
|
|
1440
1426
|
Returns the :attr:`coord` attribute, if `item` is an
|
|
1441
1427
|
:class:`Atom`, :class:`AtomArray` or :class:`AtomArrayStack`.
|
|
1442
1428
|
Directly returns the input, if `item` is a :class:`ndarray`.
|
|
1443
|
-
|
|
1429
|
+
|
|
1444
1430
|
Returns
|
|
1445
1431
|
-------
|
|
1446
1432
|
coord : ndarray
|