biotite 1.5.0__cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.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 +18 -0
- biotite/application/__init__.py +69 -0
- biotite/application/application.py +276 -0
- biotite/application/autodock/__init__.py +12 -0
- biotite/application/autodock/app.py +500 -0
- biotite/application/blast/__init__.py +14 -0
- biotite/application/blast/alignment.py +92 -0
- biotite/application/blast/webapp.py +428 -0
- biotite/application/clustalo/__init__.py +12 -0
- biotite/application/clustalo/app.py +223 -0
- biotite/application/dssp/__init__.py +12 -0
- biotite/application/dssp/app.py +216 -0
- biotite/application/localapp.py +342 -0
- biotite/application/mafft/__init__.py +12 -0
- biotite/application/mafft/app.py +116 -0
- biotite/application/msaapp.py +363 -0
- biotite/application/muscle/__init__.py +13 -0
- biotite/application/muscle/app3.py +227 -0
- biotite/application/muscle/app5.py +163 -0
- biotite/application/sra/__init__.py +18 -0
- biotite/application/sra/app.py +447 -0
- biotite/application/tantan/__init__.py +12 -0
- biotite/application/tantan/app.py +199 -0
- biotite/application/util.py +77 -0
- biotite/application/viennarna/__init__.py +18 -0
- biotite/application/viennarna/rnaalifold.py +310 -0
- biotite/application/viennarna/rnafold.py +254 -0
- biotite/application/viennarna/rnaplot.py +208 -0
- biotite/application/viennarna/util.py +77 -0
- biotite/application/webapp.py +76 -0
- biotite/copyable.py +71 -0
- biotite/database/__init__.py +23 -0
- biotite/database/afdb/__init__.py +12 -0
- biotite/database/afdb/download.py +197 -0
- biotite/database/entrez/__init__.py +15 -0
- biotite/database/entrez/check.py +60 -0
- biotite/database/entrez/dbnames.py +101 -0
- biotite/database/entrez/download.py +228 -0
- biotite/database/entrez/key.py +44 -0
- biotite/database/entrez/query.py +263 -0
- biotite/database/error.py +16 -0
- biotite/database/pubchem/__init__.py +21 -0
- biotite/database/pubchem/download.py +258 -0
- biotite/database/pubchem/error.py +30 -0
- biotite/database/pubchem/query.py +819 -0
- biotite/database/pubchem/throttle.py +98 -0
- biotite/database/rcsb/__init__.py +13 -0
- biotite/database/rcsb/download.py +161 -0
- biotite/database/rcsb/query.py +963 -0
- biotite/database/uniprot/__init__.py +13 -0
- biotite/database/uniprot/check.py +40 -0
- biotite/database/uniprot/download.py +126 -0
- biotite/database/uniprot/query.py +292 -0
- biotite/file.py +244 -0
- 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 +1228 -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/__init__.py +84 -0
- biotite/sequence/align/__init__.py +199 -0
- biotite/sequence/align/alignment.py +702 -0
- biotite/sequence/align/banded.cpython-314-x86_64-linux-gnu.so +0 -0
- biotite/sequence/align/banded.pyx +652 -0
- biotite/sequence/align/buckets.py +71 -0
- biotite/sequence/align/cigar.py +425 -0
- biotite/sequence/align/kmeralphabet.cpython-314-x86_64-linux-gnu.so +0 -0
- biotite/sequence/align/kmeralphabet.pyx +595 -0
- biotite/sequence/align/kmersimilarity.cpython-314-x86_64-linux-gnu.so +0 -0
- biotite/sequence/align/kmersimilarity.pyx +233 -0
- biotite/sequence/align/kmertable.cpython-314-x86_64-linux-gnu.so +0 -0
- biotite/sequence/align/kmertable.pyx +3411 -0
- biotite/sequence/align/localgapped.cpython-314-x86_64-linux-gnu.so +0 -0
- biotite/sequence/align/localgapped.pyx +892 -0
- biotite/sequence/align/localungapped.cpython-314-x86_64-linux-gnu.so +0 -0
- biotite/sequence/align/localungapped.pyx +279 -0
- biotite/sequence/align/matrix.py +631 -0
- biotite/sequence/align/matrix_data/3Di.mat +24 -0
- biotite/sequence/align/matrix_data/BLOSUM100.mat +31 -0
- biotite/sequence/align/matrix_data/BLOSUM30.mat +31 -0
- biotite/sequence/align/matrix_data/BLOSUM35.mat +31 -0
- biotite/sequence/align/matrix_data/BLOSUM40.mat +31 -0
- biotite/sequence/align/matrix_data/BLOSUM45.mat +31 -0
- biotite/sequence/align/matrix_data/BLOSUM50.mat +31 -0
- biotite/sequence/align/matrix_data/BLOSUM50_13p.mat +25 -0
- biotite/sequence/align/matrix_data/BLOSUM50_14.3.mat +25 -0
- biotite/sequence/align/matrix_data/BLOSUM50_5.0.mat +25 -0
- biotite/sequence/align/matrix_data/BLOSUM55.mat +31 -0
- biotite/sequence/align/matrix_data/BLOSUM60.mat +31 -0
- biotite/sequence/align/matrix_data/BLOSUM62.mat +31 -0
- biotite/sequence/align/matrix_data/BLOSUM62_13p.mat +25 -0
- biotite/sequence/align/matrix_data/BLOSUM62_14.3.mat +25 -0
- biotite/sequence/align/matrix_data/BLOSUM62_5.0.mat +25 -0
- biotite/sequence/align/matrix_data/BLOSUM65.mat +31 -0
- biotite/sequence/align/matrix_data/BLOSUM70.mat +31 -0
- biotite/sequence/align/matrix_data/BLOSUM75.mat +31 -0
- biotite/sequence/align/matrix_data/BLOSUM80.mat +31 -0
- biotite/sequence/align/matrix_data/BLOSUM85.mat +31 -0
- biotite/sequence/align/matrix_data/BLOSUM90.mat +31 -0
- biotite/sequence/align/matrix_data/BLOSUMN.mat +31 -0
- biotite/sequence/align/matrix_data/CorBLOSUM49_5.0.mat +25 -0
- biotite/sequence/align/matrix_data/CorBLOSUM57_13p.mat +25 -0
- biotite/sequence/align/matrix_data/CorBLOSUM57_14.3.mat +25 -0
- biotite/sequence/align/matrix_data/CorBLOSUM61_5.0.mat +25 -0
- biotite/sequence/align/matrix_data/CorBLOSUM66_13p.mat +25 -0
- biotite/sequence/align/matrix_data/CorBLOSUM67_14.3.mat +25 -0
- biotite/sequence/align/matrix_data/DAYHOFF.mat +32 -0
- biotite/sequence/align/matrix_data/GONNET.mat +26 -0
- biotite/sequence/align/matrix_data/IDENTITY.mat +25 -0
- biotite/sequence/align/matrix_data/MATCH.mat +25 -0
- biotite/sequence/align/matrix_data/NUC.mat +25 -0
- biotite/sequence/align/matrix_data/PAM10.mat +34 -0
- biotite/sequence/align/matrix_data/PAM100.mat +34 -0
- biotite/sequence/align/matrix_data/PAM110.mat +34 -0
- biotite/sequence/align/matrix_data/PAM120.mat +34 -0
- biotite/sequence/align/matrix_data/PAM130.mat +34 -0
- biotite/sequence/align/matrix_data/PAM140.mat +34 -0
- biotite/sequence/align/matrix_data/PAM150.mat +34 -0
- biotite/sequence/align/matrix_data/PAM160.mat +34 -0
- biotite/sequence/align/matrix_data/PAM170.mat +34 -0
- biotite/sequence/align/matrix_data/PAM180.mat +34 -0
- biotite/sequence/align/matrix_data/PAM190.mat +34 -0
- biotite/sequence/align/matrix_data/PAM20.mat +34 -0
- biotite/sequence/align/matrix_data/PAM200.mat +34 -0
- biotite/sequence/align/matrix_data/PAM210.mat +34 -0
- biotite/sequence/align/matrix_data/PAM220.mat +34 -0
- biotite/sequence/align/matrix_data/PAM230.mat +34 -0
- biotite/sequence/align/matrix_data/PAM240.mat +34 -0
- biotite/sequence/align/matrix_data/PAM250.mat +34 -0
- biotite/sequence/align/matrix_data/PAM260.mat +34 -0
- biotite/sequence/align/matrix_data/PAM270.mat +34 -0
- biotite/sequence/align/matrix_data/PAM280.mat +34 -0
- biotite/sequence/align/matrix_data/PAM290.mat +34 -0
- biotite/sequence/align/matrix_data/PAM30.mat +34 -0
- biotite/sequence/align/matrix_data/PAM300.mat +34 -0
- biotite/sequence/align/matrix_data/PAM310.mat +34 -0
- biotite/sequence/align/matrix_data/PAM320.mat +34 -0
- biotite/sequence/align/matrix_data/PAM330.mat +34 -0
- biotite/sequence/align/matrix_data/PAM340.mat +34 -0
- biotite/sequence/align/matrix_data/PAM350.mat +34 -0
- biotite/sequence/align/matrix_data/PAM360.mat +34 -0
- biotite/sequence/align/matrix_data/PAM370.mat +34 -0
- biotite/sequence/align/matrix_data/PAM380.mat +34 -0
- biotite/sequence/align/matrix_data/PAM390.mat +34 -0
- biotite/sequence/align/matrix_data/PAM40.mat +34 -0
- biotite/sequence/align/matrix_data/PAM400.mat +34 -0
- biotite/sequence/align/matrix_data/PAM410.mat +34 -0
- biotite/sequence/align/matrix_data/PAM420.mat +34 -0
- biotite/sequence/align/matrix_data/PAM430.mat +34 -0
- biotite/sequence/align/matrix_data/PAM440.mat +34 -0
- biotite/sequence/align/matrix_data/PAM450.mat +34 -0
- biotite/sequence/align/matrix_data/PAM460.mat +34 -0
- biotite/sequence/align/matrix_data/PAM470.mat +34 -0
- biotite/sequence/align/matrix_data/PAM480.mat +34 -0
- biotite/sequence/align/matrix_data/PAM490.mat +34 -0
- biotite/sequence/align/matrix_data/PAM50.mat +34 -0
- biotite/sequence/align/matrix_data/PAM500.mat +34 -0
- biotite/sequence/align/matrix_data/PAM60.mat +34 -0
- biotite/sequence/align/matrix_data/PAM70.mat +34 -0
- biotite/sequence/align/matrix_data/PAM80.mat +34 -0
- biotite/sequence/align/matrix_data/PAM90.mat +34 -0
- biotite/sequence/align/matrix_data/PB.license +21 -0
- biotite/sequence/align/matrix_data/PB.mat +18 -0
- biotite/sequence/align/matrix_data/RBLOSUM52_5.0.mat +25 -0
- biotite/sequence/align/matrix_data/RBLOSUM59_13p.mat +25 -0
- biotite/sequence/align/matrix_data/RBLOSUM59_14.3.mat +25 -0
- biotite/sequence/align/matrix_data/RBLOSUM64_5.0.mat +25 -0
- biotite/sequence/align/matrix_data/RBLOSUM69_13p.mat +25 -0
- biotite/sequence/align/matrix_data/RBLOSUM69_14.3.mat +25 -0
- biotite/sequence/align/multiple.cpython-314-x86_64-linux-gnu.so +0 -0
- biotite/sequence/align/multiple.pyx +619 -0
- biotite/sequence/align/pairwise.cpython-314-x86_64-linux-gnu.so +0 -0
- biotite/sequence/align/pairwise.pyx +585 -0
- biotite/sequence/align/permutation.cpython-314-x86_64-linux-gnu.so +0 -0
- biotite/sequence/align/permutation.pyx +313 -0
- biotite/sequence/align/primes.txt +821 -0
- biotite/sequence/align/selector.cpython-314-x86_64-linux-gnu.so +0 -0
- biotite/sequence/align/selector.pyx +954 -0
- biotite/sequence/align/statistics.py +264 -0
- biotite/sequence/align/tracetable.cpython-314-x86_64-linux-gnu.so +0 -0
- biotite/sequence/align/tracetable.pxd +64 -0
- biotite/sequence/align/tracetable.pyx +370 -0
- biotite/sequence/alphabet.py +555 -0
- biotite/sequence/annotation.py +836 -0
- biotite/sequence/codec.cpython-314-x86_64-linux-gnu.so +0 -0
- biotite/sequence/codec.pyx +155 -0
- biotite/sequence/codon.py +476 -0
- biotite/sequence/codon_tables.txt +202 -0
- biotite/sequence/graphics/__init__.py +33 -0
- biotite/sequence/graphics/alignment.py +1101 -0
- biotite/sequence/graphics/color_schemes/3di_flower.json +48 -0
- biotite/sequence/graphics/color_schemes/autumn.json +51 -0
- biotite/sequence/graphics/color_schemes/blossom.json +51 -0
- biotite/sequence/graphics/color_schemes/clustalx_dna.json +11 -0
- biotite/sequence/graphics/color_schemes/clustalx_protein.json +28 -0
- biotite/sequence/graphics/color_schemes/flower.json +51 -0
- biotite/sequence/graphics/color_schemes/jalview_buried.json +31 -0
- biotite/sequence/graphics/color_schemes/jalview_hydrophobicity.json +31 -0
- biotite/sequence/graphics/color_schemes/jalview_prop_helix.json +31 -0
- biotite/sequence/graphics/color_schemes/jalview_prop_strand.json +31 -0
- biotite/sequence/graphics/color_schemes/jalview_prop_turn.json +31 -0
- biotite/sequence/graphics/color_schemes/jalview_taylor.json +28 -0
- biotite/sequence/graphics/color_schemes/jalview_zappo.json +28 -0
- biotite/sequence/graphics/color_schemes/ocean.json +51 -0
- biotite/sequence/graphics/color_schemes/pb_flower.json +40 -0
- biotite/sequence/graphics/color_schemes/rainbow_dna.json +11 -0
- biotite/sequence/graphics/color_schemes/rainbow_protein.json +30 -0
- biotite/sequence/graphics/color_schemes/spring.json +51 -0
- biotite/sequence/graphics/color_schemes/sunset.json +51 -0
- biotite/sequence/graphics/color_schemes/wither.json +51 -0
- biotite/sequence/graphics/colorschemes.py +170 -0
- biotite/sequence/graphics/dendrogram.py +231 -0
- biotite/sequence/graphics/features.py +544 -0
- biotite/sequence/graphics/logo.py +102 -0
- biotite/sequence/graphics/plasmid.py +712 -0
- biotite/sequence/io/__init__.py +12 -0
- biotite/sequence/io/fasta/__init__.py +22 -0
- biotite/sequence/io/fasta/convert.py +283 -0
- biotite/sequence/io/fasta/file.py +265 -0
- biotite/sequence/io/fastq/__init__.py +19 -0
- biotite/sequence/io/fastq/convert.py +117 -0
- biotite/sequence/io/fastq/file.py +507 -0
- biotite/sequence/io/genbank/__init__.py +17 -0
- biotite/sequence/io/genbank/annotation.py +269 -0
- biotite/sequence/io/genbank/file.py +573 -0
- biotite/sequence/io/genbank/metadata.py +336 -0
- biotite/sequence/io/genbank/sequence.py +173 -0
- biotite/sequence/io/general.py +201 -0
- biotite/sequence/io/gff/__init__.py +26 -0
- biotite/sequence/io/gff/convert.py +128 -0
- biotite/sequence/io/gff/file.py +449 -0
- biotite/sequence/phylo/__init__.py +36 -0
- biotite/sequence/phylo/nj.cpython-314-x86_64-linux-gnu.so +0 -0
- biotite/sequence/phylo/nj.pyx +221 -0
- biotite/sequence/phylo/tree.cpython-314-x86_64-linux-gnu.so +0 -0
- biotite/sequence/phylo/tree.pyx +1169 -0
- biotite/sequence/phylo/upgma.cpython-314-x86_64-linux-gnu.so +0 -0
- biotite/sequence/phylo/upgma.pyx +164 -0
- biotite/sequence/profile.py +561 -0
- biotite/sequence/search.py +117 -0
- biotite/sequence/seqtypes.py +720 -0
- biotite/sequence/sequence.py +373 -0
- biotite/setup_ccd.py +197 -0
- biotite/structure/__init__.py +135 -0
- biotite/structure/alphabet/__init__.py +25 -0
- biotite/structure/alphabet/encoder.py +332 -0
- biotite/structure/alphabet/encoder_weights_3di.kerasify +0 -0
- biotite/structure/alphabet/i3d.py +109 -0
- biotite/structure/alphabet/layers.py +86 -0
- biotite/structure/alphabet/pb.license +21 -0
- biotite/structure/alphabet/pb.py +170 -0
- biotite/structure/alphabet/unkerasify.py +128 -0
- biotite/structure/atoms.py +1562 -0
- biotite/structure/basepairs.py +1403 -0
- biotite/structure/bonds.cpython-314-x86_64-linux-gnu.so +0 -0
- biotite/structure/bonds.pyx +2036 -0
- biotite/structure/box.py +724 -0
- biotite/structure/celllist.cpython-314-x86_64-linux-gnu.so +0 -0
- biotite/structure/celllist.pyx +864 -0
- biotite/structure/chains.py +310 -0
- biotite/structure/charges.cpython-314-x86_64-linux-gnu.so +0 -0
- biotite/structure/charges.pyx +520 -0
- biotite/structure/compare.py +683 -0
- biotite/structure/density.py +109 -0
- biotite/structure/dotbracket.py +213 -0
- biotite/structure/error.py +39 -0
- biotite/structure/filter.py +591 -0
- biotite/structure/geometry.py +817 -0
- biotite/structure/graphics/__init__.py +13 -0
- biotite/structure/graphics/atoms.py +243 -0
- biotite/structure/graphics/rna.py +298 -0
- biotite/structure/hbond.py +425 -0
- biotite/structure/info/__init__.py +24 -0
- biotite/structure/info/atom_masses.json +121 -0
- biotite/structure/info/atoms.py +98 -0
- biotite/structure/info/bonds.py +149 -0
- biotite/structure/info/ccd.py +200 -0
- biotite/structure/info/components.bcif +0 -0
- biotite/structure/info/groups.py +128 -0
- biotite/structure/info/masses.py +121 -0
- biotite/structure/info/misc.py +137 -0
- biotite/structure/info/radii.py +267 -0
- biotite/structure/info/standardize.py +185 -0
- biotite/structure/integrity.py +213 -0
- biotite/structure/io/__init__.py +29 -0
- biotite/structure/io/dcd/__init__.py +13 -0
- biotite/structure/io/dcd/file.py +67 -0
- biotite/structure/io/general.py +243 -0
- biotite/structure/io/gro/__init__.py +14 -0
- biotite/structure/io/gro/file.py +343 -0
- biotite/structure/io/mol/__init__.py +20 -0
- biotite/structure/io/mol/convert.py +112 -0
- biotite/structure/io/mol/ctab.py +420 -0
- biotite/structure/io/mol/header.py +120 -0
- biotite/structure/io/mol/mol.py +149 -0
- biotite/structure/io/mol/sdf.py +940 -0
- biotite/structure/io/netcdf/__init__.py +13 -0
- biotite/structure/io/netcdf/file.py +64 -0
- biotite/structure/io/pdb/__init__.py +20 -0
- biotite/structure/io/pdb/convert.py +389 -0
- biotite/structure/io/pdb/file.py +1380 -0
- biotite/structure/io/pdb/hybrid36.cpython-314-x86_64-linux-gnu.so +0 -0
- biotite/structure/io/pdb/hybrid36.pyx +242 -0
- biotite/structure/io/pdbqt/__init__.py +15 -0
- biotite/structure/io/pdbqt/convert.py +113 -0
- biotite/structure/io/pdbqt/file.py +688 -0
- biotite/structure/io/pdbx/__init__.py +23 -0
- biotite/structure/io/pdbx/bcif.py +674 -0
- biotite/structure/io/pdbx/cif.py +1091 -0
- biotite/structure/io/pdbx/component.py +251 -0
- biotite/structure/io/pdbx/compress.py +362 -0
- biotite/structure/io/pdbx/convert.py +2113 -0
- biotite/structure/io/pdbx/encoding.cpython-314-x86_64-linux-gnu.so +0 -0
- biotite/structure/io/pdbx/encoding.pyx +1078 -0
- biotite/structure/io/trajfile.py +696 -0
- biotite/structure/io/trr/__init__.py +13 -0
- biotite/structure/io/trr/file.py +43 -0
- biotite/structure/io/util.py +38 -0
- biotite/structure/io/xtc/__init__.py +13 -0
- biotite/structure/io/xtc/file.py +43 -0
- biotite/structure/mechanics.py +72 -0
- biotite/structure/molecules.py +337 -0
- biotite/structure/pseudoknots.py +622 -0
- biotite/structure/rdf.py +245 -0
- biotite/structure/repair.py +302 -0
- biotite/structure/residues.py +716 -0
- biotite/structure/rings.py +451 -0
- biotite/structure/sasa.cpython-314-x86_64-linux-gnu.so +0 -0
- biotite/structure/sasa.pyx +322 -0
- biotite/structure/segments.py +328 -0
- biotite/structure/sequence.py +110 -0
- biotite/structure/spacegroups.json +1567 -0
- biotite/structure/spacegroups.license +26 -0
- biotite/structure/sse.py +306 -0
- biotite/structure/superimpose.py +511 -0
- biotite/structure/tm.py +581 -0
- biotite/structure/transform.py +736 -0
- biotite/structure/util.py +160 -0
- biotite/version.py +34 -0
- biotite/visualize.py +375 -0
- biotite-1.5.0.dist-info/METADATA +162 -0
- biotite-1.5.0.dist-info/RECORD +354 -0
- biotite-1.5.0.dist-info/WHEEL +6 -0
- biotite-1.5.0.dist-info/licenses/LICENSE.rst +30 -0
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
# This source code is part of the Biotite package and is distributed
|
|
2
|
+
# under the 3-Clause BSD License. Please see 'LICENSE.rst' for further
|
|
3
|
+
# information.
|
|
4
|
+
|
|
5
|
+
"""
|
|
6
|
+
Use this module to calculate the Solvent Accessible Surface Area (SASA) of
|
|
7
|
+
a protein or single atoms.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
__name__ = "biotite.structure"
|
|
11
|
+
__author__ = "Patrick Kunzmann"
|
|
12
|
+
__all__ = ["sasa"]
|
|
13
|
+
|
|
14
|
+
cimport cython
|
|
15
|
+
cimport numpy as np
|
|
16
|
+
from libc.stdlib cimport malloc, free
|
|
17
|
+
|
|
18
|
+
import numpy as np
|
|
19
|
+
from .celllist import CellList
|
|
20
|
+
from .filter import filter_solvent, filter_monoatomic_ions
|
|
21
|
+
from .info.radii import vdw_radius_protor, vdw_radius_single
|
|
22
|
+
|
|
23
|
+
ctypedef np.uint8_t np_bool
|
|
24
|
+
ctypedef np.int64_t int64
|
|
25
|
+
ctypedef np.float32_t float32
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@cython.boundscheck(False)
|
|
29
|
+
@cython.wraparound(False)
|
|
30
|
+
def sasa(array, float probe_radius=1.4, np.ndarray atom_filter=None,
|
|
31
|
+
bint ignore_ions=True, int point_number=1000,
|
|
32
|
+
point_distr="Fibonacci", vdw_radii="ProtOr"):
|
|
33
|
+
"""
|
|
34
|
+
sasa(array, probe_radius=1.4, atom_filter=None, ignore_ions=True,
|
|
35
|
+
point_number=1000, point_distr="Fibonacci", vdw_radii="ProtOr")
|
|
36
|
+
|
|
37
|
+
Calculate the Solvent Accessible Surface Area (SASA) of a protein.
|
|
38
|
+
|
|
39
|
+
This function uses the Shrake-Rupley ("rolling probe")
|
|
40
|
+
algorithm :footcite:`Shrake1973`:
|
|
41
|
+
Every atom is occupied by a evenly distributed point mesh. The
|
|
42
|
+
points that can be reached by the "rolling probe", are surface
|
|
43
|
+
accessible.
|
|
44
|
+
|
|
45
|
+
Parameters
|
|
46
|
+
----------
|
|
47
|
+
array : AtomArray
|
|
48
|
+
The protein model to calculate the SASA for.
|
|
49
|
+
probe_radius : float, optional
|
|
50
|
+
The VdW-radius of the solvent molecules.
|
|
51
|
+
atom_filter : ndarray, dtype=bool, optional
|
|
52
|
+
If this parameter is given, SASA is only calculated for the
|
|
53
|
+
filtered atoms.
|
|
54
|
+
ignore_ions : bool, optional
|
|
55
|
+
If true, all monoatomic ions are removed before SASA calculation.
|
|
56
|
+
point_number : int, optional
|
|
57
|
+
The number of points in the mesh occupying each atom for SASA
|
|
58
|
+
calculation.
|
|
59
|
+
The SASA calculation time is proportional to the amount of sphere points.
|
|
60
|
+
point_distr : str or function, optional
|
|
61
|
+
If a function is given, the function is used to calculate the
|
|
62
|
+
point distribution for the mesh (the function must take `float`
|
|
63
|
+
*n* as parameter and return a *(n x 3)* :class:`ndarray`).
|
|
64
|
+
Alternatively a string can be given to choose a built-in
|
|
65
|
+
distribution:
|
|
66
|
+
|
|
67
|
+
- **Fibonacci** - Distribute points using a golden section
|
|
68
|
+
spiral.
|
|
69
|
+
|
|
70
|
+
By default *Fibonacci* is used.
|
|
71
|
+
vdw_radii : str or ndarray, dtype=float, optional
|
|
72
|
+
Indicates the set of VdW radii to be used. If an `array`-length
|
|
73
|
+
:class:`ndarray` is given, each atom gets the radius at the
|
|
74
|
+
corresponding index. Radii given for atoms that are not used in
|
|
75
|
+
SASA calculation (e.g. solvent atoms) can have arbitrary values
|
|
76
|
+
(e.g. `NaN`). If instead a string is given, one of the
|
|
77
|
+
built-in sets is used:
|
|
78
|
+
|
|
79
|
+
- **ProtOr** - A set, which does not require hydrogen atoms
|
|
80
|
+
in the model. Suitable for crystal structures.
|
|
81
|
+
:footcite:`Tsai1999`
|
|
82
|
+
- **Single** - A set, which uses a defined VdW radius for
|
|
83
|
+
every single atom, therefore hydrogen atoms are required
|
|
84
|
+
in the model (e.g. NMR elucidated structures).
|
|
85
|
+
Values for main group elements are taken from :footcite:`Mantina2009`,
|
|
86
|
+
and for relevant transition metals from the :footcite:`RDKit`.
|
|
87
|
+
|
|
88
|
+
By default *ProtOr* is used.
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
Returns
|
|
92
|
+
-------
|
|
93
|
+
sasa : ndarray, dtype=bool, shape=(n,)
|
|
94
|
+
Atom-wise SASA. `NaN` for atoms where SASA has not been
|
|
95
|
+
calculated
|
|
96
|
+
(solvent atoms, hydrogen atoms (ProtOr), atoms not in `filter`).
|
|
97
|
+
|
|
98
|
+
References
|
|
99
|
+
----------
|
|
100
|
+
|
|
101
|
+
.. footbibliography::
|
|
102
|
+
|
|
103
|
+
"""
|
|
104
|
+
cdef int i=0, j=0, k=0, adj_atom_i=0, rel_atom_i=0
|
|
105
|
+
|
|
106
|
+
cdef np.ndarray sasa_filter
|
|
107
|
+
cdef np.ndarray occl_filter
|
|
108
|
+
if atom_filter is not None:
|
|
109
|
+
# Filter for all atoms to calculate SASA for
|
|
110
|
+
sasa_filter = np.array(atom_filter, dtype=bool)
|
|
111
|
+
else:
|
|
112
|
+
sasa_filter = np.ones(len(array), dtype=bool)
|
|
113
|
+
# Filter for all atoms that are considered for occlusion calculation
|
|
114
|
+
# sasa_filter is subfilter of occlusion_filter
|
|
115
|
+
occl_filter = np.ones(len(array), dtype=bool)
|
|
116
|
+
# Remove water residues, since it is the solvent
|
|
117
|
+
filter = ~filter_solvent(array)
|
|
118
|
+
sasa_filter = sasa_filter & filter
|
|
119
|
+
occl_filter = occl_filter & filter
|
|
120
|
+
if ignore_ions:
|
|
121
|
+
filter = ~filter_monoatomic_ions(array)
|
|
122
|
+
sasa_filter = sasa_filter & filter
|
|
123
|
+
occl_filter = occl_filter & filter
|
|
124
|
+
|
|
125
|
+
cdef np.ndarray sphere_points
|
|
126
|
+
if callable(point_distr):
|
|
127
|
+
sphere_points = point_distr(point_number)
|
|
128
|
+
elif point_distr == "Fibonacci":
|
|
129
|
+
sphere_points = _create_fibonacci_points(point_number)
|
|
130
|
+
else:
|
|
131
|
+
raise ValueError(f"'{point_distr}' is not a valid point distribution")
|
|
132
|
+
sphere_points = sphere_points.astype(np.float32)
|
|
133
|
+
|
|
134
|
+
cdef np.ndarray radii
|
|
135
|
+
if isinstance(vdw_radii, np.ndarray):
|
|
136
|
+
radii = vdw_radii.astype(np.float32)
|
|
137
|
+
if len(radii) != array.array_length():
|
|
138
|
+
raise ValueError(
|
|
139
|
+
f"Amount VdW radii ({len(radii)}) and "
|
|
140
|
+
f"amount of atoms ({array.array_length()}) are not equal"
|
|
141
|
+
)
|
|
142
|
+
elif vdw_radii == "ProtOr":
|
|
143
|
+
filter = (array.element != "H")
|
|
144
|
+
sasa_filter = sasa_filter & filter
|
|
145
|
+
occl_filter = occl_filter & filter
|
|
146
|
+
radii = np.full(len(array), np.nan, dtype=np.float32)
|
|
147
|
+
for i in np.arange(len(radii))[occl_filter]:
|
|
148
|
+
rad = vdw_radius_protor(array.res_name[i], array.atom_name[i])
|
|
149
|
+
# 1.8 is default radius
|
|
150
|
+
radii[i] = rad if rad is not None else 1.8
|
|
151
|
+
elif vdw_radii == "Single":
|
|
152
|
+
radii = np.full(len(array), np.nan, dtype=np.float32)
|
|
153
|
+
for i in np.arange(len(radii))[occl_filter]:
|
|
154
|
+
rad = vdw_radius_single(array.element[i])
|
|
155
|
+
# 1.5 is default radius
|
|
156
|
+
radii[i] = rad if rad is not None else 1.8
|
|
157
|
+
else:
|
|
158
|
+
raise KeyError(f"'{vdw_radii}' is not a valid radii set")
|
|
159
|
+
# Increase atom radii by probe size ("rolling probe")
|
|
160
|
+
radii += probe_radius
|
|
161
|
+
|
|
162
|
+
# Memoryview for filter
|
|
163
|
+
# Problem with creating boolean memoryviews
|
|
164
|
+
# -> Type uint8 is used
|
|
165
|
+
cdef np_bool[:] sasa_filter_view = np.frombuffer(sasa_filter,
|
|
166
|
+
dtype=np.uint8)
|
|
167
|
+
|
|
168
|
+
cdef np.ndarray occl_r = radii[occl_filter]
|
|
169
|
+
# Atom array containing occluding atoms
|
|
170
|
+
occl_array = array[occl_filter]
|
|
171
|
+
|
|
172
|
+
# Memoryviews for coordinates of entire (main) array
|
|
173
|
+
# and for coordinates of occluding atom array
|
|
174
|
+
cdef float32[:,:] main_coord = array.coord.astype(np.float32,
|
|
175
|
+
copy=False)
|
|
176
|
+
cdef float32[:,:] occl_coord = occl_array.coord.astype(np.float32,
|
|
177
|
+
copy=False)
|
|
178
|
+
# Memoryviews for sphere points
|
|
179
|
+
cdef float32[:,:] sphere_coord = sphere_points
|
|
180
|
+
# Check if any of these arrays are empty to prevent segfault
|
|
181
|
+
if main_coord.shape[0] == 0 \
|
|
182
|
+
or occl_coord.shape[0] == 0 \
|
|
183
|
+
or sphere_coord.shape[0] == 0:
|
|
184
|
+
raise ValueError("Coordinates are empty")
|
|
185
|
+
# Memoryviews for radii of SASA and occluding atoms
|
|
186
|
+
# their squares and their sum of sqaures
|
|
187
|
+
cdef float32[:] atom_radii = radii
|
|
188
|
+
cdef float32[:] atom_radii_sq = radii * radii
|
|
189
|
+
cdef float32[:] occl_radii = occl_r
|
|
190
|
+
cdef float32[:] occl_radii_sq = occl_r * occl_r
|
|
191
|
+
# Memoryview for atomwise SASA
|
|
192
|
+
cdef float32[:] sasa = np.full(len(array), np.nan, dtype=np.float32)
|
|
193
|
+
|
|
194
|
+
# Area of a sphere point on a unit sphere
|
|
195
|
+
cdef float32 area_per_point = 4.0 * np.pi / point_number
|
|
196
|
+
|
|
197
|
+
# Define further statically typed variables
|
|
198
|
+
# that are needed for SASA calculation
|
|
199
|
+
cdef int n_accesible = 0
|
|
200
|
+
cdef float32 radius = 0
|
|
201
|
+
cdef float32 radius_sq = 0
|
|
202
|
+
cdef float32 adj_radius = 0
|
|
203
|
+
cdef float32 adj_radius_sq = 0
|
|
204
|
+
cdef float32 dist_sq = 0
|
|
205
|
+
cdef float32 point_x = 0
|
|
206
|
+
cdef float32 point_y = 0
|
|
207
|
+
cdef float32 point_z = 0
|
|
208
|
+
cdef float32 atom_x = 0
|
|
209
|
+
cdef float32 atom_y = 0
|
|
210
|
+
cdef float32 atom_z = 0
|
|
211
|
+
cdef float32 occl_x = 0
|
|
212
|
+
cdef float32 occl_y = 0
|
|
213
|
+
cdef float32 occl_z = 0
|
|
214
|
+
cdef float32[:,:] relevant_occl_coord = None
|
|
215
|
+
|
|
216
|
+
# Cell size is as large as the maximum distance,
|
|
217
|
+
# where two atom can intersect.
|
|
218
|
+
# Therefore intersecting atoms are always in the same or adjacent cell.
|
|
219
|
+
cell_list = CellList(occl_array, np.max(radii[occl_filter])*2)
|
|
220
|
+
cdef np.ndarray cell_indices
|
|
221
|
+
cdef int[:,:] cell_indices_view
|
|
222
|
+
cdef int length
|
|
223
|
+
cdef int max_adj_list_length = 0
|
|
224
|
+
cdef int array_length = array.array_length()
|
|
225
|
+
|
|
226
|
+
cell_indices = cell_list.get_atoms_in_cells(array.coord)
|
|
227
|
+
cell_indices_view = cell_indices
|
|
228
|
+
max_adj_list_length = cell_indices.shape[0]
|
|
229
|
+
|
|
230
|
+
# Later on, this array stores coordinates for actual
|
|
231
|
+
# occluding atoms for a certain atom to calculate the
|
|
232
|
+
# SASA for
|
|
233
|
+
# The first three indices of the second axis
|
|
234
|
+
# are x, y and z, the last one is the squared radius
|
|
235
|
+
# This list is as long as the maximal length of a list of
|
|
236
|
+
# adjacent atoms
|
|
237
|
+
relevant_occl_coord = np.zeros((max_adj_list_length, 4),
|
|
238
|
+
dtype=np.float32)
|
|
239
|
+
|
|
240
|
+
# Actual SASA calculation
|
|
241
|
+
for i in range(array_length):
|
|
242
|
+
# First level: The atoms to calculate SASA for
|
|
243
|
+
if not sasa_filter_view[i]:
|
|
244
|
+
# SASA is not calculated for this atom
|
|
245
|
+
continue
|
|
246
|
+
n_accesible = point_number
|
|
247
|
+
atom_x = main_coord[i,0]
|
|
248
|
+
atom_y = main_coord[i,1]
|
|
249
|
+
atom_z = main_coord[i,2]
|
|
250
|
+
radius = atom_radii[i]
|
|
251
|
+
radius_sq = atom_radii_sq[i]
|
|
252
|
+
# Find occluding atoms from list of adjacent atoms
|
|
253
|
+
rel_atom_i = 0
|
|
254
|
+
for j in range(max_adj_list_length):
|
|
255
|
+
# Remove all atoms, where the distance to the relevant atom
|
|
256
|
+
# is larger than the sum of the radii,
|
|
257
|
+
# since those atoms do not touch
|
|
258
|
+
# If distance is 0, it is the same atom,
|
|
259
|
+
# and the atom is removed from the list as well
|
|
260
|
+
adj_atom_i = cell_indices_view[i,j]
|
|
261
|
+
if adj_atom_i == -1:
|
|
262
|
+
# -1 means end of list
|
|
263
|
+
break
|
|
264
|
+
occl_x = occl_coord[adj_atom_i,0]
|
|
265
|
+
occl_y = occl_coord[adj_atom_i,1]
|
|
266
|
+
occl_z = occl_coord[adj_atom_i,2]
|
|
267
|
+
adj_radius = occl_radii[adj_atom_i]
|
|
268
|
+
adj_radius_sq = occl_radii_sq[adj_atom_i]
|
|
269
|
+
dist_sq = distance_sq(atom_x, atom_y, atom_z,
|
|
270
|
+
occl_x, occl_y, occl_z)
|
|
271
|
+
if dist_sq != 0 \
|
|
272
|
+
and dist_sq < (adj_radius+radius) * (adj_radius+radius):
|
|
273
|
+
relevant_occl_coord[rel_atom_i,0] = occl_x
|
|
274
|
+
relevant_occl_coord[rel_atom_i,1] = occl_y
|
|
275
|
+
relevant_occl_coord[rel_atom_i,2] = occl_z
|
|
276
|
+
relevant_occl_coord[rel_atom_i,3] = adj_radius_sq
|
|
277
|
+
rel_atom_i += 1
|
|
278
|
+
for j in range(sphere_coord.shape[0]):
|
|
279
|
+
# Second level: The sphere points for that atom
|
|
280
|
+
# Transform sphere point to sphere of current atom
|
|
281
|
+
point_x = sphere_coord[j,0] * radius + atom_x
|
|
282
|
+
point_y = sphere_coord[j,1] * radius + atom_y
|
|
283
|
+
point_z = sphere_coord[j,2] * radius + atom_z
|
|
284
|
+
for k in range(rel_atom_i):
|
|
285
|
+
# Third level: Compare point to occluding atoms
|
|
286
|
+
dist_sq = distance_sq(point_x, point_y, point_z,
|
|
287
|
+
relevant_occl_coord[k, 0],
|
|
288
|
+
relevant_occl_coord[k, 1],
|
|
289
|
+
relevant_occl_coord[k, 2])
|
|
290
|
+
# Compare squared distance
|
|
291
|
+
# to squared radius of occluding atom
|
|
292
|
+
# (Radius is relevant_occl_coord[3])
|
|
293
|
+
if dist_sq < relevant_occl_coord[k, 3]:
|
|
294
|
+
# Point is occluded
|
|
295
|
+
# -> Continue with next point
|
|
296
|
+
n_accesible -= 1
|
|
297
|
+
break
|
|
298
|
+
sasa[i] = area_per_point * n_accesible * radius_sq
|
|
299
|
+
return np.asarray(sasa)
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
cdef inline float32 distance_sq(float32 x1, float32 y1, float32 z1,
|
|
303
|
+
float32 x2, float32 y2, float32 z2):
|
|
304
|
+
cdef float32 dx = x2 - x1
|
|
305
|
+
cdef float32 dy = y2 - y1
|
|
306
|
+
cdef float32 dz = z2 - z1
|
|
307
|
+
return dx*dx + dy*dy + dz*dz
|
|
308
|
+
|
|
309
|
+
|
|
310
|
+
def _create_fibonacci_points(n):
|
|
311
|
+
"""
|
|
312
|
+
Get an array of approximately equidistant points on a sphere surface
|
|
313
|
+
using a golden section spiral.
|
|
314
|
+
"""
|
|
315
|
+
phi = (3 - np.sqrt(5)) * np.pi * np.arange(n)
|
|
316
|
+
z = np.linspace(1 - 1.0/n, 1.0/n - 1, n)
|
|
317
|
+
radius = np.sqrt(1 - z*z)
|
|
318
|
+
coords = np.zeros((n, 3))
|
|
319
|
+
coords[:,0] = radius * np.cos(phi)
|
|
320
|
+
coords[:,1] = radius * np.sin(phi)
|
|
321
|
+
coords[:,2] = z
|
|
322
|
+
return coords
|
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
# This source code is part of the Biotite package and is distributed
|
|
2
|
+
# under the 3-Clause BSD License. Please see 'LICENSE.rst' for further
|
|
3
|
+
# information.
|
|
4
|
+
|
|
5
|
+
__name__ = "biotite.structure"
|
|
6
|
+
__author__ = "Patrick Kunzmann"
|
|
7
|
+
__all__ = [
|
|
8
|
+
"get_segment_starts",
|
|
9
|
+
"apply_segment_wise",
|
|
10
|
+
"spread_segment_wise",
|
|
11
|
+
"get_segment_masks",
|
|
12
|
+
"get_segment_starts_for",
|
|
13
|
+
"get_segment_positions",
|
|
14
|
+
"get_all_segment_positions",
|
|
15
|
+
"segment_iter",
|
|
16
|
+
]
|
|
17
|
+
|
|
18
|
+
import numpy as np
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def get_segment_starts(
|
|
22
|
+
array, add_exclusive_stop, continuous_categories=(), equal_categories=()
|
|
23
|
+
):
|
|
24
|
+
"""
|
|
25
|
+
Generalized version of :func:`get_residue_starts()` for residues and chains.
|
|
26
|
+
|
|
27
|
+
The starts are determined from value changes in the given annotations.
|
|
28
|
+
|
|
29
|
+
Parameters
|
|
30
|
+
----------
|
|
31
|
+
array : AtomArray or AtomArrayStack
|
|
32
|
+
The atom array (stack) to get the segment starts from.
|
|
33
|
+
add_exclusive_stop : bool, optional
|
|
34
|
+
If true, the exclusive stop of the input atom array,
|
|
35
|
+
i.e. ``array.array_length()``, is added to the returned array of start indices
|
|
36
|
+
as last element.
|
|
37
|
+
continuous_categories : tuple of str, optional
|
|
38
|
+
Annotation categories that are expected to be continuously increasing within a
|
|
39
|
+
segment.
|
|
40
|
+
This means if the value of such an annotation decreases from one atom to
|
|
41
|
+
another, a new segment is started.
|
|
42
|
+
equal_categories : tuple of str, optional
|
|
43
|
+
Annotation categories that are expected to be equal within a segment.
|
|
44
|
+
This means if the value of such an annotation changes from one atom to
|
|
45
|
+
another, a new segment is started.
|
|
46
|
+
|
|
47
|
+
Returns
|
|
48
|
+
-------
|
|
49
|
+
starts : ndarray, dtype=int
|
|
50
|
+
The start indices of segments in `array`.
|
|
51
|
+
"""
|
|
52
|
+
if array.array_length() == 0:
|
|
53
|
+
return np.array([], dtype=int)
|
|
54
|
+
|
|
55
|
+
segment_start_mask = np.zeros(array.array_length() - 1, dtype=bool)
|
|
56
|
+
for annot_name in continuous_categories:
|
|
57
|
+
annotation = array.get_annotation(annot_name)
|
|
58
|
+
segment_start_mask |= np.diff(annotation) < 0
|
|
59
|
+
for annot_name in equal_categories:
|
|
60
|
+
annotation = array.get_annotation(annot_name)
|
|
61
|
+
segment_start_mask |= annotation[1:] != annotation[:-1]
|
|
62
|
+
|
|
63
|
+
# Convert mask to indices
|
|
64
|
+
# Add 1, to shift the indices from the end of a segment
|
|
65
|
+
# to the start of a new segment
|
|
66
|
+
segment_starts = np.where(segment_start_mask)[0] + 1
|
|
67
|
+
|
|
68
|
+
# The first chain is not included yet -> Insert '[0]'
|
|
69
|
+
if add_exclusive_stop:
|
|
70
|
+
return np.concatenate(([0], segment_starts, [array.array_length()]))
|
|
71
|
+
else:
|
|
72
|
+
return np.concatenate(([0], segment_starts))
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def apply_segment_wise(starts, data, function, axis=None):
|
|
76
|
+
"""
|
|
77
|
+
Generalized version of :func:`apply_residue_wise()` for
|
|
78
|
+
residues and chains.
|
|
79
|
+
|
|
80
|
+
Parameters
|
|
81
|
+
----------
|
|
82
|
+
starts : ndarray, dtype=int
|
|
83
|
+
The sorted start indices of segments.
|
|
84
|
+
Includes exclusive stop, i.e. the length of the corresponding
|
|
85
|
+
atom array.
|
|
86
|
+
data : ndarray
|
|
87
|
+
The data, whose intervals are the parameter for `function`.
|
|
88
|
+
Must have same length as `array`.
|
|
89
|
+
function : function
|
|
90
|
+
The `function` must have either the form *f(data)* or
|
|
91
|
+
*f(data, axis)* in case `axis` is given. Every `function` call
|
|
92
|
+
must return a value with the same shape and data type.
|
|
93
|
+
axis : int, optional
|
|
94
|
+
This value is given to the `axis` parameter of `function`.
|
|
95
|
+
|
|
96
|
+
Returns
|
|
97
|
+
-------
|
|
98
|
+
processed_data : ndarray
|
|
99
|
+
Segment-wise evaluation of `data` by `function`.
|
|
100
|
+
The size of the first dimension of this array is equal to the amount of
|
|
101
|
+
residues.
|
|
102
|
+
"""
|
|
103
|
+
# The result array
|
|
104
|
+
processed_data = None
|
|
105
|
+
for i in range(len(starts) - 1):
|
|
106
|
+
segment = data[starts[i] : starts[i + 1]]
|
|
107
|
+
if axis is None:
|
|
108
|
+
value = function(segment)
|
|
109
|
+
else:
|
|
110
|
+
value = function(segment, axis=axis)
|
|
111
|
+
# Identify the shape of the resulting array by evaluation
|
|
112
|
+
# of the function return value for the first segment
|
|
113
|
+
if processed_data is None:
|
|
114
|
+
if isinstance(value, np.ndarray):
|
|
115
|
+
# Maximum length of the processed data
|
|
116
|
+
# is length of segment of size 1 -> length of all IDs
|
|
117
|
+
# (equal to atom array length)
|
|
118
|
+
processed_data = np.zeros(
|
|
119
|
+
(len(starts) - 1,) + value.shape, dtype=value.dtype
|
|
120
|
+
)
|
|
121
|
+
else:
|
|
122
|
+
# Scalar value -> one dimensional result array
|
|
123
|
+
processed_data = np.zeros(len(starts) - 1, dtype=type(value))
|
|
124
|
+
# Write values into result arrays
|
|
125
|
+
processed_data[i] = value
|
|
126
|
+
return processed_data
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def spread_segment_wise(starts, input_data):
|
|
130
|
+
"""
|
|
131
|
+
Generalized version of :func:`spread_residue_wise()`
|
|
132
|
+
for residues and chains.
|
|
133
|
+
|
|
134
|
+
Parameters
|
|
135
|
+
----------
|
|
136
|
+
starts : ndarray, dtype=int
|
|
137
|
+
The sorted start indices of segments.
|
|
138
|
+
Includes exclusive stop, i.e. the length of the corresponding
|
|
139
|
+
atom array.
|
|
140
|
+
input_data : ndarray
|
|
141
|
+
The data to be spread.
|
|
142
|
+
The length of the 0-th axis must be equal to the amount of different residue IDs
|
|
143
|
+
in `array`.
|
|
144
|
+
|
|
145
|
+
Returns
|
|
146
|
+
-------
|
|
147
|
+
output_data : ndarray
|
|
148
|
+
Segment-wise spread `input_data`.
|
|
149
|
+
Length is the same as `array_length()` of `array`.
|
|
150
|
+
"""
|
|
151
|
+
seg_lens = starts[1:] - starts[:-1]
|
|
152
|
+
return np.repeat(input_data, seg_lens, axis=0)
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
def get_segment_masks(starts, indices):
|
|
156
|
+
"""
|
|
157
|
+
Generalized version of :func:`get_residue_masks()`
|
|
158
|
+
for residues and chains.
|
|
159
|
+
|
|
160
|
+
Parameters
|
|
161
|
+
----------
|
|
162
|
+
starts : ndarray, dtype=int
|
|
163
|
+
The sorted start indices of segments.
|
|
164
|
+
Includes exclusive stop, i.e. the length of the corresponding
|
|
165
|
+
atom array.
|
|
166
|
+
indices : ndarray, dtype=int, shape=(k,)
|
|
167
|
+
These indices indicate the atoms to get the corresponding
|
|
168
|
+
segments for.
|
|
169
|
+
Negative indices are not allowed.
|
|
170
|
+
|
|
171
|
+
Returns
|
|
172
|
+
-------
|
|
173
|
+
residues_masks : ndarray, dtype=bool, shape=(k,n)
|
|
174
|
+
Multiple boolean masks, one for each given index in `indices`.
|
|
175
|
+
Each array masks the atoms that belong to the same segment as
|
|
176
|
+
the atom at the given index.
|
|
177
|
+
"""
|
|
178
|
+
indices = np.asarray(indices)
|
|
179
|
+
length = starts[-1]
|
|
180
|
+
masks = np.zeros((len(indices), length), dtype=bool)
|
|
181
|
+
|
|
182
|
+
if (indices < 0).any():
|
|
183
|
+
raise ValueError("This function does not support negative indices")
|
|
184
|
+
if (indices >= length).any():
|
|
185
|
+
index = np.min(np.where(indices >= length)[0])
|
|
186
|
+
raise ValueError(
|
|
187
|
+
f"Index {index} is out of range for an atom array with length {length}"
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
insertion_points = np.searchsorted(starts, indices, side="right") - 1
|
|
191
|
+
for i, point in enumerate(insertion_points):
|
|
192
|
+
masks[i, starts[point] : starts[point + 1]] = True
|
|
193
|
+
|
|
194
|
+
return masks
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
def get_segment_starts_for(starts, indices):
|
|
198
|
+
"""
|
|
199
|
+
Generalized version of :func:`get_residue_starts_for()`
|
|
200
|
+
for residues and chains.
|
|
201
|
+
|
|
202
|
+
Parameters
|
|
203
|
+
----------
|
|
204
|
+
starts : ndarray, dtype=int
|
|
205
|
+
The sorted start indices of segments.
|
|
206
|
+
Includes exclusive stop, i.e. the length of the corresponding
|
|
207
|
+
atom array.
|
|
208
|
+
indices : ndarray, dtype=int, shape=(k,)
|
|
209
|
+
These indices point to the atoms to get the corresponding
|
|
210
|
+
segment starts for.
|
|
211
|
+
Negative indices are not allowed.
|
|
212
|
+
|
|
213
|
+
Returns
|
|
214
|
+
-------
|
|
215
|
+
start_indices : ndarray, dtype=int, shape=(k,)
|
|
216
|
+
The indices that point to the segment starts for the input
|
|
217
|
+
`indices`.
|
|
218
|
+
"""
|
|
219
|
+
indices = np.asarray(indices)
|
|
220
|
+
length = starts[-1]
|
|
221
|
+
# Remove exclusive stop
|
|
222
|
+
starts = starts[:-1]
|
|
223
|
+
|
|
224
|
+
if (indices < 0).any():
|
|
225
|
+
raise ValueError("This function does not support negative indices")
|
|
226
|
+
if (indices >= length).any():
|
|
227
|
+
index = np.min(np.where(indices >= length)[0])
|
|
228
|
+
raise ValueError(
|
|
229
|
+
f"Index {index} is out of range for an atom array with length {length}"
|
|
230
|
+
)
|
|
231
|
+
|
|
232
|
+
insertion_points = np.searchsorted(starts, indices, side="right") - 1
|
|
233
|
+
return starts[insertion_points]
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
def get_segment_positions(starts, indices):
|
|
237
|
+
"""
|
|
238
|
+
Generalized version of :func:`get_residue_positions()`
|
|
239
|
+
for residues and chains.
|
|
240
|
+
|
|
241
|
+
Parameters
|
|
242
|
+
----------
|
|
243
|
+
starts : ndarray, dtype=int
|
|
244
|
+
The sorted start indices of segments.
|
|
245
|
+
Includes exclusive stop, i.e. the length of the corresponding
|
|
246
|
+
atom array.
|
|
247
|
+
indices : ndarray, shape=(k,)
|
|
248
|
+
These indices point to the atoms to get the corresponding
|
|
249
|
+
residue positions for.
|
|
250
|
+
Negative indices are not allowed.
|
|
251
|
+
|
|
252
|
+
Returns
|
|
253
|
+
-------
|
|
254
|
+
segment_indices : ndarray, shape=(k,)
|
|
255
|
+
The indices that point to the position of the segments.
|
|
256
|
+
|
|
257
|
+
See Also
|
|
258
|
+
--------
|
|
259
|
+
get_all_segment_positions :
|
|
260
|
+
Similar to this function, but for all atoms in the :class:`struc.AtomArray`.
|
|
261
|
+
"""
|
|
262
|
+
indices = np.asarray(indices)
|
|
263
|
+
length = starts[-1]
|
|
264
|
+
# Remove exclusive stop
|
|
265
|
+
starts = starts[:-1]
|
|
266
|
+
|
|
267
|
+
if (indices < 0).any():
|
|
268
|
+
raise ValueError("This function does not support negative indices")
|
|
269
|
+
if (indices >= length).any():
|
|
270
|
+
index = np.min(np.where(indices >= length)[0])
|
|
271
|
+
raise ValueError(
|
|
272
|
+
f"Index {index} is out of range for an atom array with length {length}"
|
|
273
|
+
)
|
|
274
|
+
|
|
275
|
+
return np.searchsorted(starts, indices, side="right") - 1
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
def get_all_segment_positions(starts, length):
|
|
279
|
+
"""
|
|
280
|
+
Generalized version of :func:`get_all_residue_positions()`
|
|
281
|
+
for residues and chains.
|
|
282
|
+
|
|
283
|
+
Parameters
|
|
284
|
+
----------
|
|
285
|
+
starts : ndarray, dtype=int
|
|
286
|
+
The sorted start indices of segments.
|
|
287
|
+
Includes exclusive stop, i.e. the length of the corresponding
|
|
288
|
+
atom array.
|
|
289
|
+
length : int
|
|
290
|
+
The length of the corresponding :class:`struc.AtomArray`.
|
|
291
|
+
|
|
292
|
+
Returns
|
|
293
|
+
-------
|
|
294
|
+
segment_indices : ndarray, shape=(k,)
|
|
295
|
+
For each atom the indices that point to the corresponding position of the
|
|
296
|
+
segments.
|
|
297
|
+
|
|
298
|
+
See Also
|
|
299
|
+
--------
|
|
300
|
+
get_segment_positions :
|
|
301
|
+
Similar to this function, but for a given subset of atom indices.
|
|
302
|
+
"""
|
|
303
|
+
segment_changes = np.zeros(length, dtype=int)
|
|
304
|
+
segment_changes[starts[1:-1]] = 1
|
|
305
|
+
return np.cumsum(segment_changes)
|
|
306
|
+
|
|
307
|
+
|
|
308
|
+
def segment_iter(array, starts):
|
|
309
|
+
"""
|
|
310
|
+
Generalized version of :func:`residue_iter()`
|
|
311
|
+
for residues and chains.
|
|
312
|
+
|
|
313
|
+
Parameters
|
|
314
|
+
----------
|
|
315
|
+
array : AtomArray or AtomArrayStack
|
|
316
|
+
The structure to iterate over.
|
|
317
|
+
starts : ndarray, dtype=int
|
|
318
|
+
The sorted start indices of segments.
|
|
319
|
+
Includes exclusive stop, i.e. the length of the corresponding
|
|
320
|
+
atom array.
|
|
321
|
+
|
|
322
|
+
Yields
|
|
323
|
+
------
|
|
324
|
+
segment : AtomArray or AtomArrayStack
|
|
325
|
+
Each residue or chain of the structure.
|
|
326
|
+
"""
|
|
327
|
+
for i in range(len(starts) - 1):
|
|
328
|
+
yield array[..., starts[i] : starts[i + 1]]
|