biotite 1.1.0__cp311-cp311-macosx_11_0_arm64.whl → 1.3.0__cp311-cp311-macosx_11_0_arm64.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/application/application.py +3 -3
- biotite/application/autodock/app.py +1 -1
- biotite/application/blast/webapp.py +1 -1
- biotite/application/clustalo/app.py +1 -1
- biotite/application/localapp.py +2 -2
- biotite/application/msaapp.py +10 -10
- biotite/application/muscle/app3.py +3 -3
- biotite/application/muscle/app5.py +3 -3
- biotite/application/sra/app.py +0 -5
- biotite/application/util.py +21 -1
- biotite/application/viennarna/rnaalifold.py +8 -8
- biotite/application/viennarna/rnaplot.py +10 -8
- biotite/application/viennarna/util.py +1 -1
- biotite/application/webapp.py +1 -1
- biotite/database/afdb/__init__.py +12 -0
- biotite/database/afdb/download.py +191 -0
- biotite/database/entrez/dbnames.py +10 -0
- biotite/database/entrez/download.py +9 -10
- biotite/database/entrez/key.py +1 -1
- biotite/database/entrez/query.py +5 -4
- biotite/database/pubchem/download.py +6 -6
- biotite/database/pubchem/error.py +10 -0
- biotite/database/pubchem/query.py +12 -23
- biotite/database/rcsb/download.py +3 -2
- biotite/database/rcsb/query.py +2 -3
- biotite/database/uniprot/check.py +2 -2
- biotite/database/uniprot/download.py +2 -5
- biotite/database/uniprot/query.py +3 -4
- biotite/file.py +14 -2
- biotite/interface/__init__.py +19 -0
- biotite/interface/openmm/__init__.py +20 -0
- biotite/interface/openmm/state.py +93 -0
- biotite/interface/openmm/system.py +227 -0
- biotite/interface/pymol/__init__.py +201 -0
- biotite/interface/pymol/cgo.py +346 -0
- biotite/interface/pymol/convert.py +185 -0
- biotite/interface/pymol/display.py +267 -0
- biotite/interface/pymol/object.py +1226 -0
- biotite/interface/pymol/shapes.py +178 -0
- biotite/interface/pymol/startup.py +169 -0
- biotite/interface/rdkit/__init__.py +19 -0
- biotite/interface/rdkit/mol.py +490 -0
- biotite/interface/version.py +94 -0
- biotite/interface/warning.py +19 -0
- biotite/sequence/align/__init__.py +0 -4
- biotite/sequence/align/alignment.py +33 -11
- biotite/sequence/align/banded.cpython-311-darwin.so +0 -0
- biotite/sequence/align/banded.pyx +22 -22
- biotite/sequence/align/cigar.py +2 -2
- biotite/sequence/align/kmeralphabet.cpython-311-darwin.so +0 -0
- biotite/sequence/align/kmeralphabet.pyx +2 -2
- biotite/sequence/align/kmersimilarity.cpython-311-darwin.so +0 -0
- biotite/sequence/align/kmertable.cpython-311-darwin.so +0 -0
- biotite/sequence/align/kmertable.pyx +6 -6
- biotite/sequence/align/localgapped.cpython-311-darwin.so +0 -0
- biotite/sequence/align/localgapped.pyx +47 -47
- biotite/sequence/align/localungapped.cpython-311-darwin.so +0 -0
- biotite/sequence/align/localungapped.pyx +10 -10
- biotite/sequence/align/matrix.py +12 -3
- biotite/sequence/align/multiple.cpython-311-darwin.so +0 -0
- biotite/sequence/align/multiple.pyx +1 -2
- biotite/sequence/align/pairwise.cpython-311-darwin.so +0 -0
- biotite/sequence/align/pairwise.pyx +37 -39
- biotite/sequence/align/permutation.cpython-311-darwin.so +0 -0
- biotite/sequence/align/selector.cpython-311-darwin.so +0 -0
- biotite/sequence/align/selector.pyx +2 -2
- biotite/sequence/align/statistics.py +1 -1
- biotite/sequence/align/tracetable.cpython-311-darwin.so +0 -0
- biotite/sequence/alphabet.py +2 -2
- biotite/sequence/annotation.py +19 -13
- biotite/sequence/codec.cpython-311-darwin.so +0 -0
- biotite/sequence/codon.py +1 -2
- biotite/sequence/graphics/alignment.py +25 -39
- biotite/sequence/graphics/dendrogram.py +4 -2
- biotite/sequence/graphics/features.py +2 -2
- biotite/sequence/graphics/logo.py +10 -12
- biotite/sequence/io/fasta/convert.py +1 -2
- biotite/sequence/io/fasta/file.py +1 -1
- biotite/sequence/io/fastq/file.py +3 -3
- biotite/sequence/io/genbank/file.py +3 -3
- biotite/sequence/io/genbank/sequence.py +2 -0
- biotite/sequence/io/gff/convert.py +1 -1
- biotite/sequence/io/gff/file.py +1 -2
- biotite/sequence/phylo/nj.cpython-311-darwin.so +0 -0
- biotite/sequence/phylo/tree.cpython-311-darwin.so +0 -0
- biotite/sequence/phylo/upgma.cpython-311-darwin.so +0 -0
- biotite/sequence/profile.py +19 -25
- biotite/sequence/search.py +0 -1
- biotite/sequence/seqtypes.py +12 -5
- biotite/sequence/sequence.py +1 -2
- biotite/structure/__init__.py +2 -0
- biotite/structure/alphabet/i3d.py +1 -2
- biotite/structure/alphabet/pb.py +1 -2
- biotite/structure/alphabet/unkerasify.py +8 -2
- biotite/structure/atoms.py +35 -27
- biotite/structure/basepairs.py +39 -40
- biotite/structure/bonds.cpython-311-darwin.so +0 -0
- biotite/structure/bonds.pyx +8 -5
- biotite/structure/box.py +159 -23
- biotite/structure/celllist.cpython-311-darwin.so +0 -0
- biotite/structure/celllist.pyx +83 -68
- biotite/structure/chains.py +17 -55
- biotite/structure/charges.cpython-311-darwin.so +0 -0
- biotite/structure/compare.py +420 -13
- biotite/structure/density.py +1 -1
- biotite/structure/dotbracket.py +31 -32
- biotite/structure/filter.py +8 -8
- biotite/structure/geometry.py +15 -15
- biotite/structure/graphics/rna.py +19 -16
- biotite/structure/hbond.py +18 -21
- biotite/structure/info/atoms.py +11 -2
- biotite/structure/info/ccd.py +0 -2
- biotite/structure/info/components.bcif +0 -0
- biotite/structure/info/groups.py +0 -3
- biotite/structure/info/misc.py +0 -1
- biotite/structure/info/radii.py +92 -22
- biotite/structure/info/standardize.py +1 -2
- biotite/structure/integrity.py +4 -6
- biotite/structure/io/general.py +2 -2
- biotite/structure/io/gro/file.py +8 -9
- biotite/structure/io/mol/convert.py +1 -1
- biotite/structure/io/mol/ctab.py +33 -28
- biotite/structure/io/mol/mol.py +1 -1
- biotite/structure/io/mol/sdf.py +39 -13
- biotite/structure/io/pdb/convert.py +86 -5
- biotite/structure/io/pdb/file.py +90 -24
- biotite/structure/io/pdb/hybrid36.cpython-311-darwin.so +0 -0
- biotite/structure/io/pdbqt/file.py +4 -4
- biotite/structure/io/pdbx/bcif.py +22 -7
- biotite/structure/io/pdbx/cif.py +20 -7
- biotite/structure/io/pdbx/component.py +6 -0
- biotite/structure/io/pdbx/compress.py +71 -34
- biotite/structure/io/pdbx/convert.py +429 -77
- biotite/structure/io/pdbx/encoding.cpython-311-darwin.so +0 -0
- biotite/structure/io/pdbx/encoding.pyx +39 -23
- biotite/structure/io/trajfile.py +9 -6
- biotite/structure/io/util.py +38 -0
- biotite/structure/mechanics.py +0 -1
- biotite/structure/molecules.py +0 -15
- biotite/structure/pseudoknots.py +13 -19
- biotite/structure/repair.py +2 -4
- biotite/structure/residues.py +20 -48
- biotite/structure/rings.py +335 -0
- biotite/structure/sasa.cpython-311-darwin.so +0 -0
- biotite/structure/sasa.pyx +30 -30
- biotite/structure/segments.py +123 -9
- biotite/structure/sequence.py +0 -1
- biotite/structure/spacegroups.json +1567 -0
- biotite/structure/spacegroups.license +26 -0
- biotite/structure/sse.py +0 -2
- biotite/structure/superimpose.py +75 -253
- biotite/structure/tm.py +581 -0
- biotite/structure/transform.py +232 -26
- biotite/structure/util.py +3 -3
- biotite/version.py +9 -4
- biotite/visualize.py +111 -1
- {biotite-1.1.0.dist-info → biotite-1.3.0.dist-info}/METADATA +8 -36
- {biotite-1.1.0.dist-info → biotite-1.3.0.dist-info}/RECORD +160 -138
- {biotite-1.1.0.dist-info → biotite-1.3.0.dist-info}/WHEEL +3 -1
- {biotite-1.1.0.dist-info → biotite-1.3.0.dist-info}/licenses/LICENSE.rst +0 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
The transformations in 'spacegroups.json' are adapted from
|
|
2
|
+
'molstar/src/mol-math/geometry/spacegroup/tables.ts' from the Mol* project
|
|
3
|
+
(https://github.com/molstar/molstar) governed by the following license:
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
The MIT License
|
|
7
|
+
|
|
8
|
+
Copyright (c) 2017 - now, Mol* contributors
|
|
9
|
+
|
|
10
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
11
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
12
|
+
in the Software without restriction, including without limitation the rights
|
|
13
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
14
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
15
|
+
furnished to do so, subject to the following conditions:
|
|
16
|
+
|
|
17
|
+
The above copyright notice and this permission notice shall be included in
|
|
18
|
+
all copies or substantial portions of the Software.
|
|
19
|
+
|
|
20
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
21
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
22
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
23
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
24
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
25
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
26
|
+
THE SOFTWARE.
|
biotite/structure/sse.py
CHANGED
|
@@ -48,7 +48,6 @@ def annotate_sse(atom_array):
|
|
|
48
48
|
Non-peptide residues are also allowed and obtain a ``''``
|
|
49
49
|
SSE.
|
|
50
50
|
|
|
51
|
-
|
|
52
51
|
Returns
|
|
53
52
|
-------
|
|
54
53
|
sse : ndarray
|
|
@@ -81,7 +80,6 @@ def annotate_sse(atom_array):
|
|
|
81
80
|
>>> print(sse)
|
|
82
81
|
['c' 'a' 'a' 'a' 'a' 'a' 'a' 'a' 'a' 'c' 'c' 'c' 'c' 'c' 'c' 'c' 'c' 'c'
|
|
83
82
|
'c' 'c']
|
|
84
|
-
|
|
85
83
|
"""
|
|
86
84
|
residue_starts = get_residue_starts(atom_array)
|
|
87
85
|
# Sort CA coord into the coord array at the respective residue index
|
biotite/structure/superimpose.py
CHANGED
|
@@ -12,200 +12,21 @@ __all__ = [
|
|
|
12
12
|
"superimpose",
|
|
13
13
|
"superimpose_homologs",
|
|
14
14
|
"superimpose_without_outliers",
|
|
15
|
-
"AffineTransformation",
|
|
16
15
|
]
|
|
17
16
|
|
|
18
17
|
|
|
19
18
|
import numpy as np
|
|
20
|
-
from biotite.sequence.align import
|
|
19
|
+
from biotite.sequence.align.alignment import get_codes, remove_gaps
|
|
20
|
+
from biotite.sequence.align.matrix import SubstitutionMatrix
|
|
21
|
+
from biotite.sequence.align.pairwise import align_optimal
|
|
21
22
|
from biotite.sequence.alphabet import common_alphabet
|
|
22
23
|
from biotite.sequence.seqtypes import ProteinSequence
|
|
23
24
|
from biotite.structure.atoms import coord
|
|
25
|
+
from biotite.structure.chains import chain_iter
|
|
24
26
|
from biotite.structure.filter import filter_amino_acids, filter_nucleotides
|
|
25
27
|
from biotite.structure.geometry import centroid, distance
|
|
26
28
|
from biotite.structure.sequence import to_sequence
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
class AffineTransformation:
|
|
30
|
-
"""
|
|
31
|
-
An affine transformation, consisting of translations and a rotation.
|
|
32
|
-
|
|
33
|
-
Parameters
|
|
34
|
-
----------
|
|
35
|
-
center_translation : ndarray, shape=(3,) or shape=(m,3), dtype=float
|
|
36
|
-
The translation vector for moving the centroid into the
|
|
37
|
-
origin.
|
|
38
|
-
rotation : ndarray, shape=(3,3) or shape=(m,3,3), dtype=float
|
|
39
|
-
The rotation matrix.
|
|
40
|
-
target_translation : ndarray, shape=(m,3), dtype=float
|
|
41
|
-
The translation vector for moving the structure onto the
|
|
42
|
-
fixed one.
|
|
43
|
-
|
|
44
|
-
Attributes
|
|
45
|
-
----------
|
|
46
|
-
center_translation, rotation, target_translation : ndarray
|
|
47
|
-
Same as the parameters.
|
|
48
|
-
The dimensions are always expanded to *(m,3)* or *(m,3,3)*,
|
|
49
|
-
respectively.
|
|
50
|
-
"""
|
|
51
|
-
|
|
52
|
-
def __init__(self, center_translation, rotation, target_translation):
|
|
53
|
-
self.center_translation = _expand_dims(center_translation, 2)
|
|
54
|
-
self.rotation = _expand_dims(rotation, 3)
|
|
55
|
-
self.target_translation = _expand_dims(target_translation, 2)
|
|
56
|
-
|
|
57
|
-
def apply(self, atoms):
|
|
58
|
-
"""
|
|
59
|
-
Apply this transformation on the given structure.
|
|
60
|
-
|
|
61
|
-
Parameters
|
|
62
|
-
----------
|
|
63
|
-
atoms : AtomArray or AtomArrayStack or ndarray, shape(n,), dtype=float or ndarray, shape(m,n), dtype=float
|
|
64
|
-
The structure to apply the transformation on.
|
|
65
|
-
|
|
66
|
-
Returns
|
|
67
|
-
-------
|
|
68
|
-
transformed : AtomArray or AtomArrayStack or ndarray, shape(n,), dtype=float or ndarray, shape(m,n), dtype=float
|
|
69
|
-
A copy of the `atoms` structure,
|
|
70
|
-
with transformations applied.
|
|
71
|
-
Only coordinates are returned, if coordinates were given in
|
|
72
|
-
`atoms`.
|
|
73
|
-
|
|
74
|
-
Examples
|
|
75
|
-
--------
|
|
76
|
-
|
|
77
|
-
>>> coord = np.arange(15).reshape(5,3)
|
|
78
|
-
>>> print(coord)
|
|
79
|
-
[[ 0 1 2]
|
|
80
|
-
[ 3 4 5]
|
|
81
|
-
[ 6 7 8]
|
|
82
|
-
[ 9 10 11]
|
|
83
|
-
[12 13 14]]
|
|
84
|
-
>>> # Rotates 90 degrees around the z-axis
|
|
85
|
-
>>> transform = AffineTransformation(
|
|
86
|
-
... center_translation=np.array([0,0,0]),
|
|
87
|
-
... rotation=np.array([
|
|
88
|
-
... [0, -1, 0],
|
|
89
|
-
... [1, 0, 0],
|
|
90
|
-
... [0, 0, 1]
|
|
91
|
-
... ]),
|
|
92
|
-
... target_translation=np.array([0,0,0])
|
|
93
|
-
... )
|
|
94
|
-
>>> print(transform.apply(coord))
|
|
95
|
-
[[ -1. 0. 2.]
|
|
96
|
-
[ -4. 3. 5.]
|
|
97
|
-
[ -7. 6. 8.]
|
|
98
|
-
[-10. 9. 11.]
|
|
99
|
-
[-13. 12. 14.]]
|
|
100
|
-
|
|
101
|
-
"""
|
|
102
|
-
mobile_coord = coord(atoms)
|
|
103
|
-
original_shape = mobile_coord.shape
|
|
104
|
-
mobile_coord = _reshape_to_3d(mobile_coord)
|
|
105
|
-
if mobile_coord.shape[0] != self.rotation.shape[0]:
|
|
106
|
-
raise IndexError(
|
|
107
|
-
f"Number of transformations is {self.rotation.shape[0]}, "
|
|
108
|
-
f"but number of structure models is {mobile_coord.shape[0]}"
|
|
109
|
-
)
|
|
110
|
-
|
|
111
|
-
superimposed_coord = mobile_coord.copy()
|
|
112
|
-
superimposed_coord += self.center_translation[:, np.newaxis, :]
|
|
113
|
-
superimposed_coord = _multi_matmul(self.rotation, superimposed_coord)
|
|
114
|
-
superimposed_coord += self.target_translation[:, np.newaxis, :]
|
|
115
|
-
|
|
116
|
-
superimposed_coord = superimposed_coord.reshape(original_shape)
|
|
117
|
-
if isinstance(atoms, np.ndarray):
|
|
118
|
-
return superimposed_coord
|
|
119
|
-
else:
|
|
120
|
-
superimposed = atoms.copy()
|
|
121
|
-
superimposed.coord = superimposed_coord
|
|
122
|
-
return superimposed
|
|
123
|
-
|
|
124
|
-
def as_matrix(self):
|
|
125
|
-
"""
|
|
126
|
-
Get the translations and rotation as a combined 4x4
|
|
127
|
-
transformation matrix.
|
|
128
|
-
|
|
129
|
-
Multiplying this matrix with coordinates in the form
|
|
130
|
-
*(x, y, z, 1)* will apply the same transformation as
|
|
131
|
-
:meth:`apply()` to coordinates in the form *(x, y, z)*.
|
|
132
|
-
|
|
133
|
-
Returns
|
|
134
|
-
-------
|
|
135
|
-
transformation_matrix : ndarray, shape=(m,4,4), dtype=float
|
|
136
|
-
The transformation matrix.
|
|
137
|
-
*m* is the number of models in the transformation.
|
|
138
|
-
|
|
139
|
-
Examples
|
|
140
|
-
--------
|
|
141
|
-
|
|
142
|
-
>>> coord = np.arange(15).reshape(5,3)
|
|
143
|
-
>>> print(coord)
|
|
144
|
-
[[ 0 1 2]
|
|
145
|
-
[ 3 4 5]
|
|
146
|
-
[ 6 7 8]
|
|
147
|
-
[ 9 10 11]
|
|
148
|
-
[12 13 14]]
|
|
149
|
-
>>> # Rotates 90 degrees around the z-axis
|
|
150
|
-
>>> transform = AffineTransformation(
|
|
151
|
-
... center_translation=np.array([0,0,0]),
|
|
152
|
-
... rotation=np.array([
|
|
153
|
-
... [0, -1, 0],
|
|
154
|
-
... [1, 0, 0],
|
|
155
|
-
... [0, 0, 1]
|
|
156
|
-
... ]),
|
|
157
|
-
... target_translation=np.array([0,0,0])
|
|
158
|
-
... )
|
|
159
|
-
>>> print(transform.apply(coord))
|
|
160
|
-
[[ -1. 0. 2.]
|
|
161
|
-
[ -4. 3. 5.]
|
|
162
|
-
[ -7. 6. 8.]
|
|
163
|
-
[-10. 9. 11.]
|
|
164
|
-
[-13. 12. 14.]]
|
|
165
|
-
>>> # Use a 4x4 matrix for transformation as alternative
|
|
166
|
-
>>> coord_4 = np.concatenate([coord, np.ones((len(coord), 1))], axis=-1)
|
|
167
|
-
>>> print(coord_4)
|
|
168
|
-
[[ 0. 1. 2. 1.]
|
|
169
|
-
[ 3. 4. 5. 1.]
|
|
170
|
-
[ 6. 7. 8. 1.]
|
|
171
|
-
[ 9. 10. 11. 1.]
|
|
172
|
-
[12. 13. 14. 1.]]
|
|
173
|
-
>>> print((transform.as_matrix()[0] @ coord_4.T).T)
|
|
174
|
-
[[ -1. 0. 2. 1.]
|
|
175
|
-
[ -4. 3. 5. 1.]
|
|
176
|
-
[ -7. 6. 8. 1.]
|
|
177
|
-
[-10. 9. 11. 1.]
|
|
178
|
-
[-13. 12. 14. 1.]]
|
|
179
|
-
|
|
180
|
-
"""
|
|
181
|
-
n_models = self.rotation.shape[0]
|
|
182
|
-
rotation_mat = _3d_identity(n_models, 4)
|
|
183
|
-
rotation_mat[:, :3, :3] = self.rotation
|
|
184
|
-
center_translation_mat = _3d_identity(n_models, 4)
|
|
185
|
-
center_translation_mat[:, :3, 3] = self.center_translation
|
|
186
|
-
target_translation_mat = _3d_identity(n_models, 4)
|
|
187
|
-
target_translation_mat[:, :3, 3] = self.target_translation
|
|
188
|
-
return target_translation_mat @ rotation_mat @ center_translation_mat
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
def _expand_dims(array, n_dims):
|
|
192
|
-
"""
|
|
193
|
-
Expand the dimensions of an `ndarray` to a certain number of
|
|
194
|
-
dimensions.
|
|
195
|
-
"""
|
|
196
|
-
while array.ndim < n_dims:
|
|
197
|
-
array = array[np.newaxis, ...]
|
|
198
|
-
return array
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
def _3d_identity(m, n):
|
|
202
|
-
"""
|
|
203
|
-
Create an array of *m* identity matrices of shape *(n, n)*
|
|
204
|
-
"""
|
|
205
|
-
matrices = np.zeros((m, n, n), dtype=float)
|
|
206
|
-
indices = np.arange(n)
|
|
207
|
-
matrices[:, indices, indices] = 1
|
|
208
|
-
return matrices
|
|
29
|
+
from biotite.structure.transform import AffineTransformation
|
|
209
30
|
|
|
210
31
|
|
|
211
32
|
def superimpose(fixed, mobile, atom_mask=None):
|
|
@@ -222,7 +43,7 @@ def superimpose(fixed, mobile, atom_mask=None):
|
|
|
222
43
|
fixed : AtomArray, shape(n,) or AtomArrayStack, shape(m,n) or ndarray, shape(n,), dtype=float or ndarray, shape(m,n), dtype=float
|
|
223
44
|
The fixed structure(s).
|
|
224
45
|
Alternatively coordinates can be given.
|
|
225
|
-
mobile: AtomArray, shape(n,) or AtomArrayStack, shape(m,n) or ndarray, shape(n,), dtype=float or ndarray, shape(m,n), dtype=float
|
|
46
|
+
mobile : AtomArray, shape(n,) or AtomArrayStack, shape(m,n) or ndarray, shape(n,), dtype=float or ndarray, shape(m,n), dtype=float
|
|
226
47
|
The structure(s) which is/are superimposed on the `fixed`
|
|
227
48
|
structure.
|
|
228
49
|
Each atom at index *i* in `mobile` must correspond the
|
|
@@ -231,7 +52,7 @@ def superimpose(fixed, mobile, atom_mask=None):
|
|
|
231
52
|
:class:`AtomArrayStack` objects, they must have the same
|
|
232
53
|
number of models.
|
|
233
54
|
Alternatively coordinates can be given.
|
|
234
|
-
atom_mask: ndarray, dtype=bool, optional
|
|
55
|
+
atom_mask : ndarray, dtype=bool, optional
|
|
235
56
|
If given, only the atoms covered by this boolean mask will be
|
|
236
57
|
considered for superimposition.
|
|
237
58
|
This means that the algorithm will minimize the RMSD based
|
|
@@ -253,8 +74,8 @@ def superimpose(fixed, mobile, atom_mask=None):
|
|
|
253
74
|
|
|
254
75
|
See Also
|
|
255
76
|
--------
|
|
256
|
-
superimpose_without_outliers : Superimposition with outlier removal
|
|
257
|
-
superimpose_homologs : Superimposition of homologous structures
|
|
77
|
+
superimpose_without_outliers : Superimposition with outlier removal.
|
|
78
|
+
superimpose_homologs : Superimposition of homologous structures.
|
|
258
79
|
|
|
259
80
|
Notes
|
|
260
81
|
-----
|
|
@@ -340,13 +161,12 @@ def superimpose_without_outliers(
|
|
|
340
161
|
the remaining atoms (called *anchors*) again until no outlier
|
|
341
162
|
remains.
|
|
342
163
|
|
|
343
|
-
|
|
344
164
|
Parameters
|
|
345
165
|
----------
|
|
346
166
|
fixed : AtomArray, shape(n,) or AtomArrayStack, shape(m,n) or ndarray, shape(n,), dtype=float or ndarray, shape(m,n), dtype=float
|
|
347
167
|
The fixed structure(s).
|
|
348
168
|
Alternatively coordinates can be given.
|
|
349
|
-
mobile: AtomArray, shape(n,) or AtomArrayStack, shape(m,n) or ndarray, shape(n,), dtype=float or ndarray, shape(m,n), dtype=float
|
|
169
|
+
mobile : AtomArray, shape(n,) or AtomArrayStack, shape(m,n) or ndarray, shape(n,), dtype=float or ndarray, shape(m,n), dtype=float
|
|
350
170
|
The structure(s) which is/are superimposed on the `fixed`
|
|
351
171
|
structure.
|
|
352
172
|
Each atom at index *i* in `mobile` must correspond the
|
|
@@ -389,8 +209,8 @@ def superimpose_without_outliers(
|
|
|
389
209
|
|
|
390
210
|
See Also
|
|
391
211
|
--------
|
|
392
|
-
superimpose : Superimposition without outlier removal
|
|
393
|
-
superimpose_homologs : Superimposition of homologous structures
|
|
212
|
+
superimpose : Superimposition without outlier removal.
|
|
213
|
+
superimpose_homologs : Superimposition of homologous structures.
|
|
394
214
|
|
|
395
215
|
Notes
|
|
396
216
|
-----
|
|
@@ -464,10 +284,16 @@ def superimpose_without_outliers(
|
|
|
464
284
|
|
|
465
285
|
|
|
466
286
|
def superimpose_homologs(
|
|
467
|
-
fixed,
|
|
287
|
+
fixed,
|
|
288
|
+
mobile,
|
|
289
|
+
substitution_matrix=None,
|
|
290
|
+
gap_penalty=-10,
|
|
291
|
+
min_anchors=3,
|
|
292
|
+
terminal_penalty=False,
|
|
293
|
+
**kwargs,
|
|
468
294
|
):
|
|
469
295
|
r"""
|
|
470
|
-
Superimpose
|
|
296
|
+
Superimpose a protein or nucleotide structure onto another one,
|
|
471
297
|
considering sequence differences and conformational outliers.
|
|
472
298
|
|
|
473
299
|
The method finds corresponding residues by sequence alignment and
|
|
@@ -480,11 +306,11 @@ def superimpose_homologs(
|
|
|
480
306
|
----------
|
|
481
307
|
fixed : AtomArray, shape(n,) or AtomArrayStack, shape(m,n)
|
|
482
308
|
The fixed structure(s).
|
|
483
|
-
Must comprise a single chain.
|
|
484
309
|
mobile : AtomArray, shape(n,) or AtomArrayStack, shape(m,n)
|
|
485
|
-
The structure(s) which is/are superimposed on the `fixed`
|
|
486
|
-
|
|
487
|
-
|
|
310
|
+
The structure(s) which is/are superimposed on the `fixed` structure.
|
|
311
|
+
Must contain the same number of chains as `fixed` with corresponding chains
|
|
312
|
+
being in the same order.
|
|
313
|
+
The specific chain IDs can be different.
|
|
488
314
|
substitution_matrix : str or SubstitutionMatrix, optional
|
|
489
315
|
The (name of the) substitution matrix used for sequence
|
|
490
316
|
alignment.
|
|
@@ -504,6 +330,9 @@ def superimpose_homologs(
|
|
|
504
330
|
`mobile` in this fallback case, an exception is raised.
|
|
505
331
|
Furthermore, the outlier removal is stopped, if less than
|
|
506
332
|
`min_anchors` anchors would be left.
|
|
333
|
+
terminal_penalty : bool, optional
|
|
334
|
+
If set to true, gap penalties are applied to terminal gaps in the sequence
|
|
335
|
+
alignment.
|
|
507
336
|
**kwargs
|
|
508
337
|
Additional parameters for
|
|
509
338
|
:func:`superimpose_without_outliers()`.
|
|
@@ -525,8 +354,9 @@ def superimpose_homologs(
|
|
|
525
354
|
|
|
526
355
|
See Also
|
|
527
356
|
--------
|
|
528
|
-
superimpose : Superimposition without outlier removal
|
|
529
|
-
superimpose_without_outliers : Internally used for outlier removal
|
|
357
|
+
superimpose : Superimposition without outlier removal.
|
|
358
|
+
superimpose_without_outliers : Internally used for outlier removal.
|
|
359
|
+
superimpose_structural_homologs : Better suited for low sequence similarity.
|
|
530
360
|
|
|
531
361
|
Notes
|
|
532
362
|
-----
|
|
@@ -540,7 +370,7 @@ def superimpose_homologs(
|
|
|
540
370
|
or len(mobile_anchor_indices) < min_anchors
|
|
541
371
|
):
|
|
542
372
|
raise ValueError(
|
|
543
|
-
"Structures have too few
|
|
373
|
+
"Structures have too few backbone atoms for required number of anchors"
|
|
544
374
|
)
|
|
545
375
|
|
|
546
376
|
anchor_indices = _find_matching_anchors(
|
|
@@ -548,18 +378,19 @@ def superimpose_homologs(
|
|
|
548
378
|
mobile[..., mobile_anchor_indices],
|
|
549
379
|
substitution_matrix,
|
|
550
380
|
gap_penalty,
|
|
381
|
+
terminal_penalty,
|
|
551
382
|
)
|
|
552
383
|
if len(anchor_indices) < min_anchors:
|
|
553
384
|
# Fallback: Match all backbone anchors
|
|
554
385
|
if len(fixed_anchor_indices) != len(mobile_anchor_indices):
|
|
555
386
|
raise ValueError(
|
|
556
387
|
"Tried fallback due to low anchor number, "
|
|
557
|
-
"but number of
|
|
388
|
+
"but number of backbone atoms does not match"
|
|
558
389
|
)
|
|
559
390
|
fixed_anchor_indices = fixed_anchor_indices
|
|
560
391
|
mobile_anchor_indices = mobile_anchor_indices
|
|
561
392
|
else:
|
|
562
|
-
# The anchor indices point to the
|
|
393
|
+
# The anchor indices point to the backbone atoms
|
|
563
394
|
# -> get the corresponding indices for the whole structure
|
|
564
395
|
fixed_anchor_indices = fixed_anchor_indices[anchor_indices[:, 0]]
|
|
565
396
|
mobile_anchor_indices = mobile_anchor_indices[anchor_indices[:, 1]]
|
|
@@ -613,16 +444,6 @@ def _get_rotation_matrices(fixed, mobile):
|
|
|
613
444
|
return matrices
|
|
614
445
|
|
|
615
446
|
|
|
616
|
-
def _multi_matmul(matrices, vectors):
|
|
617
|
-
"""
|
|
618
|
-
Calculate the matrix multiplication of m matrices
|
|
619
|
-
with m x n vectors.
|
|
620
|
-
"""
|
|
621
|
-
return np.transpose(
|
|
622
|
-
np.matmul(matrices, np.transpose(vectors, axes=(0, 2, 1))), axes=(0, 2, 1)
|
|
623
|
-
)
|
|
624
|
-
|
|
625
|
-
|
|
626
447
|
def _get_backbone_anchor_indices(atoms):
|
|
627
448
|
"""
|
|
628
449
|
Select one representative anchor atom for each amino acid and
|
|
@@ -639,51 +460,52 @@ def _find_matching_anchors(
|
|
|
639
460
|
mobile_anchors_atoms,
|
|
640
461
|
substitution_matrix,
|
|
641
462
|
gap_penalty,
|
|
463
|
+
terminal_penalty,
|
|
642
464
|
):
|
|
643
465
|
"""
|
|
644
466
|
Find corresponding residues using pairwise sequence alignment.
|
|
645
467
|
"""
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
468
|
+
anchor_list = []
|
|
469
|
+
fixed_seq_offset = 0
|
|
470
|
+
mobile_seq_offset = 0
|
|
471
|
+
for fixed_chain, mobile_chain in zip(
|
|
472
|
+
chain_iter(fixed_anchor_atoms), chain_iter(mobile_anchors_atoms), strict=True
|
|
473
|
+
):
|
|
474
|
+
# The input is a single chain -> expect a single sequence
|
|
475
|
+
fixed_seq = to_sequence(fixed_chain, allow_hetero=True)[0][0]
|
|
476
|
+
mobile_seq = to_sequence(mobile_chain, allow_hetero=True)[0][0]
|
|
477
|
+
|
|
478
|
+
common_alph = common_alphabet([fixed_seq.alphabet, mobile_seq.alphabet])
|
|
479
|
+
if common_alph is None:
|
|
480
|
+
raise ValueError("Cannot superimpose peptides with nucleic acids")
|
|
481
|
+
if substitution_matrix is None:
|
|
482
|
+
if isinstance(fixed_seq, ProteinSequence):
|
|
483
|
+
substitution_matrix = SubstitutionMatrix.std_protein_matrix()
|
|
484
|
+
else:
|
|
485
|
+
substitution_matrix = SubstitutionMatrix.std_nucleotide_matrix()
|
|
486
|
+
elif isinstance(substitution_matrix, str):
|
|
487
|
+
substitution_matrix = SubstitutionMatrix(
|
|
488
|
+
common_alph, common_alph, substitution_matrix
|
|
489
|
+
)
|
|
662
490
|
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
alignment_codes = get_codes(alignment)
|
|
672
|
-
anchor_mask = (
|
|
673
|
-
# Anchors must be similar amino acids
|
|
674
|
-
(score_matrix[alignment_codes[0], alignment_codes[1]] > 0)
|
|
491
|
+
alignment = align_optimal(
|
|
492
|
+
fixed_seq,
|
|
493
|
+
mobile_seq,
|
|
494
|
+
substitution_matrix,
|
|
495
|
+
gap_penalty,
|
|
496
|
+
terminal_penalty=terminal_penalty,
|
|
497
|
+
max_number=1,
|
|
498
|
+
)[0]
|
|
675
499
|
# Cannot anchor gaps
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
500
|
+
alignment = remove_gaps(alignment)
|
|
501
|
+
ali_codes = get_codes(alignment)
|
|
502
|
+
score_matrix = substitution_matrix.score_matrix()
|
|
503
|
+
# Anchors must be similar amino acids
|
|
504
|
+
anchors = alignment.trace[score_matrix[ali_codes[0], ali_codes[1]] > 0]
|
|
681
505
|
|
|
506
|
+
anchors += fixed_seq_offset, mobile_seq_offset
|
|
507
|
+
fixed_seq_offset += len(fixed_seq)
|
|
508
|
+
mobile_seq_offset += len(mobile_seq)
|
|
509
|
+
anchor_list.append(anchors)
|
|
682
510
|
|
|
683
|
-
|
|
684
|
-
sequences, _ = to_sequence(atoms, allow_hetero=True)
|
|
685
|
-
if len(sequences) == 0:
|
|
686
|
-
raise ValueError("Structure does not contain any amino acids or nucleotides")
|
|
687
|
-
if len(sequences) > 1:
|
|
688
|
-
raise ValueError("Structure contains multiple chains, but only one is allowed")
|
|
689
|
-
return sequences[0]
|
|
511
|
+
return np.concatenate(anchor_list, axis=0)
|