biotite 1.5.0__cp313-cp313-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-313-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-313-x86_64-linux-gnu.so +0 -0
- biotite/sequence/align/kmeralphabet.pyx +595 -0
- biotite/sequence/align/kmersimilarity.cpython-313-x86_64-linux-gnu.so +0 -0
- biotite/sequence/align/kmersimilarity.pyx +233 -0
- biotite/sequence/align/kmertable.cpython-313-x86_64-linux-gnu.so +0 -0
- biotite/sequence/align/kmertable.pyx +3411 -0
- biotite/sequence/align/localgapped.cpython-313-x86_64-linux-gnu.so +0 -0
- biotite/sequence/align/localgapped.pyx +892 -0
- biotite/sequence/align/localungapped.cpython-313-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-313-x86_64-linux-gnu.so +0 -0
- biotite/sequence/align/multiple.pyx +619 -0
- biotite/sequence/align/pairwise.cpython-313-x86_64-linux-gnu.so +0 -0
- biotite/sequence/align/pairwise.pyx +585 -0
- biotite/sequence/align/permutation.cpython-313-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-313-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-313-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-313-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-313-x86_64-linux-gnu.so +0 -0
- biotite/sequence/phylo/nj.pyx +221 -0
- biotite/sequence/phylo/tree.cpython-313-x86_64-linux-gnu.so +0 -0
- biotite/sequence/phylo/tree.pyx +1169 -0
- biotite/sequence/phylo/upgma.cpython-313-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-313-x86_64-linux-gnu.so +0 -0
- biotite/structure/bonds.pyx +2036 -0
- biotite/structure/box.py +724 -0
- biotite/structure/celllist.cpython-313-x86_64-linux-gnu.so +0 -0
- biotite/structure/celllist.pyx +864 -0
- biotite/structure/chains.py +310 -0
- biotite/structure/charges.cpython-313-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-313-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-313-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-313-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,185 @@
|
|
|
1
|
+
__name__ = "biotite.interface.pymol"
|
|
2
|
+
__author__ = "Patrick Kunzmann"
|
|
3
|
+
__all__ = ["to_model", "from_model"]
|
|
4
|
+
|
|
5
|
+
import warnings
|
|
6
|
+
import numpy as np
|
|
7
|
+
from chempy import Atom, Bond
|
|
8
|
+
from chempy.models import Indexed as IndexedModel
|
|
9
|
+
import biotite.structure as struc
|
|
10
|
+
from biotite.interface import LossyConversionWarning
|
|
11
|
+
from biotite.sequence import ProteinSequence
|
|
12
|
+
|
|
13
|
+
# Bond orders in PyMOL (https://pymolwiki.org/index.php/Valence):
|
|
14
|
+
# 1: single bond, 2: double bond, 3:triple bond, 4:delocalized
|
|
15
|
+
_FORMAL_BOND_ORDER = {
|
|
16
|
+
struc.BondType.SINGLE: 1,
|
|
17
|
+
struc.BondType.DOUBLE: 2,
|
|
18
|
+
struc.BondType.TRIPLE: 3,
|
|
19
|
+
struc.BondType.AROMATIC_SINGLE: 1,
|
|
20
|
+
struc.BondType.AROMATIC_DOUBLE: 2,
|
|
21
|
+
}
|
|
22
|
+
_DELOKALIZED_BOND_ORDER = {
|
|
23
|
+
struc.BondType.SINGLE: 1,
|
|
24
|
+
struc.BondType.DOUBLE: 2,
|
|
25
|
+
struc.BondType.TRIPLE: 3,
|
|
26
|
+
struc.BondType.AROMATIC_SINGLE: 4,
|
|
27
|
+
struc.BondType.AROMATIC_DOUBLE: 4,
|
|
28
|
+
struc.BondType.AROMATIC: 4,
|
|
29
|
+
}
|
|
30
|
+
_BIOTITE_BOND_TYPES = {
|
|
31
|
+
1: struc.BondType.SINGLE,
|
|
32
|
+
2: struc.BondType.DOUBLE,
|
|
33
|
+
3: struc.BondType.TRIPLE,
|
|
34
|
+
4: struc.BondType.AROMATIC,
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def to_model(atom_array, delocalize_bonds=False):
|
|
39
|
+
"""
|
|
40
|
+
Convert an :class:`AtomArray` into a :class:`chempy.models.Indexed`
|
|
41
|
+
object.
|
|
42
|
+
|
|
43
|
+
Parameters
|
|
44
|
+
----------
|
|
45
|
+
atom_array : AtomArray
|
|
46
|
+
The structure to be converted.
|
|
47
|
+
delocalize_bonds : bool, optional
|
|
48
|
+
If set to true, use *PyMOL*'s delocalized bond order for aromatic bonds.
|
|
49
|
+
Otherwise, always use formal bond orders.
|
|
50
|
+
|
|
51
|
+
Returns
|
|
52
|
+
-------
|
|
53
|
+
chempy_model : Indexed
|
|
54
|
+
The converted structure.
|
|
55
|
+
"""
|
|
56
|
+
if not np.isfinite(atom_array.coord).all():
|
|
57
|
+
raise ValueError("PyMOL does not support infinite or NaN coordinates")
|
|
58
|
+
|
|
59
|
+
model = IndexedModel()
|
|
60
|
+
|
|
61
|
+
annot_cat = atom_array.get_annotation_categories()
|
|
62
|
+
for i in range(atom_array.array_length()):
|
|
63
|
+
atom = Atom()
|
|
64
|
+
atom.segi = atom_array.chain_id[i]
|
|
65
|
+
atom.chain = atom_array.chain_id[i]
|
|
66
|
+
atom.resi_number = atom_array.res_id[i]
|
|
67
|
+
atom.ins_code = atom_array.ins_code[i]
|
|
68
|
+
res_name = atom_array.res_name[i]
|
|
69
|
+
atom.resn = res_name
|
|
70
|
+
if len(res_name) == 1:
|
|
71
|
+
atom.resn_code = res_name
|
|
72
|
+
else:
|
|
73
|
+
try:
|
|
74
|
+
atom.resn_code = ProteinSequence.convert_letter_3to1(res_name)
|
|
75
|
+
except KeyError:
|
|
76
|
+
atom.resn_code = "X"
|
|
77
|
+
atom.hetatm = 1 if atom_array.hetero[i] else 0
|
|
78
|
+
atom.name = atom_array.atom_name[i]
|
|
79
|
+
atom.symbol = atom_array.element[i]
|
|
80
|
+
if "b_factor" in annot_cat:
|
|
81
|
+
atom.b = atom_array.b_factor[i]
|
|
82
|
+
if "occupancy" in annot_cat:
|
|
83
|
+
atom.q = atom_array.occupancy[i]
|
|
84
|
+
if "charge" in annot_cat:
|
|
85
|
+
atom.formal_charge = atom_array.charge[i]
|
|
86
|
+
atom.coord = tuple(atom_array.coord[..., i, :])
|
|
87
|
+
atom.index = i + 1
|
|
88
|
+
model.add_atom(atom)
|
|
89
|
+
|
|
90
|
+
bond_order_mapping = (
|
|
91
|
+
_DELOKALIZED_BOND_ORDER if delocalize_bonds else _FORMAL_BOND_ORDER
|
|
92
|
+
)
|
|
93
|
+
unmappable_bond_types = []
|
|
94
|
+
if atom_array.bonds is not None:
|
|
95
|
+
for i, j, bond_type in atom_array.bonds.as_array():
|
|
96
|
+
bond = Bond()
|
|
97
|
+
order = bond_order_mapping.get(bond_type)
|
|
98
|
+
if order is None:
|
|
99
|
+
unmappable_bond_types.append(bond_type)
|
|
100
|
+
order = 1
|
|
101
|
+
bond.order = order
|
|
102
|
+
bond.index = [i, j]
|
|
103
|
+
model.add_bond(bond)
|
|
104
|
+
else:
|
|
105
|
+
warnings.warn("The given atom array (stack) has no associated bond information")
|
|
106
|
+
if unmappable_bond_types:
|
|
107
|
+
warnings.warn(
|
|
108
|
+
"The following bond types could not be mapped to PyMOL: "
|
|
109
|
+
+ ", ".join([struc.BondType(bt).name for bt in set(unmappable_bond_types)]),
|
|
110
|
+
LossyConversionWarning,
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
return model
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def from_model(chempy_model, include_bonds=False):
|
|
117
|
+
"""
|
|
118
|
+
Convert a :class:`chempy.models.Indexed`
|
|
119
|
+
object into an :class:`AtomArray`.
|
|
120
|
+
|
|
121
|
+
The returned :class:`AtomArray` contains the optional annotation
|
|
122
|
+
categories ``b_factor``, ``occupancy``, ``charge`` and
|
|
123
|
+
``altloc_id``.
|
|
124
|
+
No *altloc* ID filtering is performed.
|
|
125
|
+
|
|
126
|
+
Parameters
|
|
127
|
+
----------
|
|
128
|
+
chempy_model : Indexed
|
|
129
|
+
The ``chempy`` model.
|
|
130
|
+
include_bonds : bool, optional
|
|
131
|
+
If set to true, an associated :class:`BondList` will be created
|
|
132
|
+
for the returned atom array.
|
|
133
|
+
|
|
134
|
+
Returns
|
|
135
|
+
-------
|
|
136
|
+
atom_array : AtomArray
|
|
137
|
+
The converted structure.
|
|
138
|
+
"""
|
|
139
|
+
atoms = chempy_model.atom
|
|
140
|
+
|
|
141
|
+
bonds = chempy_model.bond
|
|
142
|
+
|
|
143
|
+
atom_array = struc.AtomArray(len(atoms))
|
|
144
|
+
|
|
145
|
+
# Add annotation arrays
|
|
146
|
+
atom_array.chain_id = np.array([a.chain for a in atoms], dtype="U3")
|
|
147
|
+
atom_array.res_id = np.array([a.resi_number for a in atoms], dtype=int)
|
|
148
|
+
atom_array.ins_code = np.array([a.ins_code for a in atoms], dtype="U1")
|
|
149
|
+
atom_array.res_name = np.array([a.resn for a in atoms], dtype="U3")
|
|
150
|
+
atom_array.hetero = np.array([a.hetatm for a in atoms], dtype=bool)
|
|
151
|
+
atom_array.atom_name = np.array([a.name for a in atoms], dtype="U6")
|
|
152
|
+
atom_array.element = np.array([a.symbol for a in atoms], dtype="U2")
|
|
153
|
+
|
|
154
|
+
atom_array.set_annotation(
|
|
155
|
+
"b_factor",
|
|
156
|
+
np.array([a.b if hasattr(a, "b") else 0 for a in atoms], dtype=float),
|
|
157
|
+
)
|
|
158
|
+
atom_array.set_annotation(
|
|
159
|
+
"occupancy",
|
|
160
|
+
np.array([a.q if hasattr(a, "q") else 1.0 for a in atoms], dtype=float),
|
|
161
|
+
)
|
|
162
|
+
atom_array.set_annotation(
|
|
163
|
+
"charge",
|
|
164
|
+
np.array(
|
|
165
|
+
[a.formal_charge if hasattr(a, "formal_charge") else 0 for a in atoms],
|
|
166
|
+
dtype=int,
|
|
167
|
+
),
|
|
168
|
+
)
|
|
169
|
+
atom_array.set_annotation(
|
|
170
|
+
"altloc_id",
|
|
171
|
+
np.array([a.alt if hasattr(a, "alt") else "" for a in atoms], dtype="U1"),
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
# Set coordinates
|
|
175
|
+
atom_array.coord = np.array([a.coord for a in atoms], dtype=np.float32)
|
|
176
|
+
|
|
177
|
+
# Add bonds
|
|
178
|
+
if include_bonds:
|
|
179
|
+
bond_array = np.array(
|
|
180
|
+
[[b.index[0], b.index[1], _BIOTITE_BOND_TYPES[b.order]] for b in bonds],
|
|
181
|
+
dtype=np.uint32,
|
|
182
|
+
)
|
|
183
|
+
atom_array.bonds = struc.BondList(len(atoms), bond_array)
|
|
184
|
+
|
|
185
|
+
return atom_array
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
__name__ = "biotite.interface.pymol"
|
|
2
|
+
__author__ = "Patrick Kunzmann"
|
|
3
|
+
__all__ = ["TimeoutError", "RenderError", "show", "play"]
|
|
4
|
+
|
|
5
|
+
import datetime
|
|
6
|
+
import shutil
|
|
7
|
+
import subprocess
|
|
8
|
+
import tempfile
|
|
9
|
+
import time
|
|
10
|
+
from os import remove
|
|
11
|
+
from os.path import getsize, join
|
|
12
|
+
from biotite.interface.pymol.startup import get_and_set_pymol_instance
|
|
13
|
+
|
|
14
|
+
_INTERVAL = 0.1
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class TimeoutError(Exception):
|
|
18
|
+
"""
|
|
19
|
+
Exception that is raised after time limit expiry in :func:`show()`.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
pass
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class RenderError(Exception):
|
|
26
|
+
"""
|
|
27
|
+
Exception that is raised when ``imagemagick`` or ``ffmpeg`` fails.
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
pass
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def show(size=None, use_ray=False, timeout=60.0, pymol_instance=None):
|
|
34
|
+
"""
|
|
35
|
+
Render an image of the *PyMOL* session and display it in the current
|
|
36
|
+
*Jupyter* notebook.
|
|
37
|
+
|
|
38
|
+
Note that this function works only in a *Jupyter* notebook.
|
|
39
|
+
|
|
40
|
+
Parameters
|
|
41
|
+
----------
|
|
42
|
+
size : tuple of (int, int), optional
|
|
43
|
+
The width and height of the rendered image in pixels.
|
|
44
|
+
By default, the size of the current *PyMOL* viewport is used.
|
|
45
|
+
use_ray : bool, optional
|
|
46
|
+
If set to true, the a ray-traced image is created.
|
|
47
|
+
This will also increase the rendering time.
|
|
48
|
+
timeout : float
|
|
49
|
+
The number of seconds to wait for image output from *PyMOL*.
|
|
50
|
+
pymol_instance : module or SingletonPyMOL or PyMOL, optional
|
|
51
|
+
If *PyMOL* is used in library mode, the :class:`PyMOL`
|
|
52
|
+
or :class:`SingletonPyMOL` object is given here.
|
|
53
|
+
If otherwise *PyMOL* is used in GUI mode, the :mod:`pymol`
|
|
54
|
+
module is given.
|
|
55
|
+
By default the currently active *PyMOL* instance is used.
|
|
56
|
+
If no *PyMOL* instance is currently running,
|
|
57
|
+
*PyMOL* is started in library mode.
|
|
58
|
+
|
|
59
|
+
Raises
|
|
60
|
+
------
|
|
61
|
+
TimeoutError
|
|
62
|
+
If no image was created after expiry of the `timeout` limit.
|
|
63
|
+
|
|
64
|
+
Notes
|
|
65
|
+
-----
|
|
66
|
+
Internally uses the *PyMOL* ``png`` command.
|
|
67
|
+
"""
|
|
68
|
+
try:
|
|
69
|
+
from IPython.display import Image
|
|
70
|
+
except ImportError:
|
|
71
|
+
raise ImportError("IPython is not installed")
|
|
72
|
+
|
|
73
|
+
pymol_instance = get_and_set_pymol_instance(pymol_instance)
|
|
74
|
+
cmd = pymol_instance.cmd
|
|
75
|
+
|
|
76
|
+
if size is None:
|
|
77
|
+
width = 0
|
|
78
|
+
height = 0
|
|
79
|
+
else:
|
|
80
|
+
width, height = size
|
|
81
|
+
|
|
82
|
+
image_file = tempfile.NamedTemporaryFile(
|
|
83
|
+
delete=False, prefix="biotite_", suffix=".png"
|
|
84
|
+
)
|
|
85
|
+
# Close directly and cleanup later
|
|
86
|
+
# This is necessary, as Windows does not allow writing opened files
|
|
87
|
+
image_file.close()
|
|
88
|
+
|
|
89
|
+
start_time = datetime.datetime.now()
|
|
90
|
+
cmd.png(image_file.name, width, height, ray=int(use_ray))
|
|
91
|
+
while True:
|
|
92
|
+
# After 'timeout' seconds the loop exits with an error
|
|
93
|
+
if (datetime.datetime.now() - start_time).total_seconds() > timeout:
|
|
94
|
+
raise TimeoutError("No PNG image was output within the expected time limit")
|
|
95
|
+
# Check if PyMOL has already written image data to file
|
|
96
|
+
if getsize(image_file.name) > 0:
|
|
97
|
+
break
|
|
98
|
+
time.sleep(_INTERVAL)
|
|
99
|
+
|
|
100
|
+
with open(image_file.name, "rb") as f:
|
|
101
|
+
image_data = f.read()
|
|
102
|
+
remove(image_file.name)
|
|
103
|
+
return Image(image_data, embed=True, metadata={"source": "PyMOL"})
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def play(
|
|
107
|
+
size=None, fps=30, format="gif", html_attributes="controls", pymol_instance=None
|
|
108
|
+
):
|
|
109
|
+
"""
|
|
110
|
+
Render an video of the *PyMOL* video frames and display it in the current
|
|
111
|
+
*Jupyter* notebook.
|
|
112
|
+
|
|
113
|
+
Note that this function works only in a *Jupyter* notebook.
|
|
114
|
+
|
|
115
|
+
Parameters
|
|
116
|
+
----------
|
|
117
|
+
size : tuple of (int, int), optional
|
|
118
|
+
The width and height of the rendered video in pixels.
|
|
119
|
+
By default, the size of the current *PyMOL* viewport is used.
|
|
120
|
+
fps : int
|
|
121
|
+
The number of frames per second.
|
|
122
|
+
format : {"gif", "mp4"}, optional
|
|
123
|
+
The format of the rendered video.
|
|
124
|
+
By default, a GIF is created.
|
|
125
|
+
html_attributes : str, optional
|
|
126
|
+
The HTML attributes that are passed to the ``<video>`` tag.
|
|
127
|
+
Only used, if ``format="mp4"``.
|
|
128
|
+
pymol_instance : module or SingletonPyMOL or PyMOL, optional
|
|
129
|
+
If *PyMOL* is used in library mode, the :class:`PyMOL`
|
|
130
|
+
or :class:`SingletonPyMOL` object is given here.
|
|
131
|
+
If otherwise *PyMOL* is used in GUI mode, the :mod:`pymol`
|
|
132
|
+
module is given.
|
|
133
|
+
By default the currently active *PyMOL* instance is used.
|
|
134
|
+
If no *PyMOL* instance is currently running,
|
|
135
|
+
*PyMOL* is started in library mode.
|
|
136
|
+
|
|
137
|
+
Notes
|
|
138
|
+
-----
|
|
139
|
+
Internally uses the *PyMOL* ``mpng`` command.
|
|
140
|
+
This function requires either the ``ffmpeg`` (``gif`` or ``mp4``)
|
|
141
|
+
or ``imagemagick`` (``gif``) command line tool to be installed.
|
|
142
|
+
"""
|
|
143
|
+
try:
|
|
144
|
+
from IPython.display import Image, Video
|
|
145
|
+
except ImportError:
|
|
146
|
+
raise ImportError("IPython is not installed")
|
|
147
|
+
|
|
148
|
+
pymol_instance = get_and_set_pymol_instance(pymol_instance)
|
|
149
|
+
cmd = pymol_instance.cmd
|
|
150
|
+
|
|
151
|
+
if size is None:
|
|
152
|
+
width = 0
|
|
153
|
+
height = 0
|
|
154
|
+
else:
|
|
155
|
+
width, height = size
|
|
156
|
+
|
|
157
|
+
with tempfile.TemporaryDirectory(prefix="biotite_") as frame_dir:
|
|
158
|
+
# Must use ray tracing, as no window is created
|
|
159
|
+
# Otherwise PyMOL raises 'MoviePNG-Error: Missing rendered image.'
|
|
160
|
+
cmd.mpng(join(frame_dir, "img_"), mode=2, width=width, height=height)
|
|
161
|
+
video_data = _create_video(frame_dir, fps, format)
|
|
162
|
+
|
|
163
|
+
if format == "mp4":
|
|
164
|
+
return Video(
|
|
165
|
+
video_data,
|
|
166
|
+
embed=True,
|
|
167
|
+
mimetype="video/mp4",
|
|
168
|
+
html_attributes=html_attributes,
|
|
169
|
+
)
|
|
170
|
+
else:
|
|
171
|
+
return Image(video_data, embed=True, metadata={"source": "PyMOL"})
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
def _create_video(input_dir, fps, format):
|
|
175
|
+
"""
|
|
176
|
+
Create a video from the images in the given directory using ``ffmpeg```
|
|
177
|
+
or ``imagemagick``.
|
|
178
|
+
|
|
179
|
+
Parameters
|
|
180
|
+
----------
|
|
181
|
+
input_dir : str
|
|
182
|
+
The directory containing the frames to be concatenated into a video.
|
|
183
|
+
The images are consumed in lexographical order.
|
|
184
|
+
fps : int
|
|
185
|
+
The number of frames per second.
|
|
186
|
+
format : {"gif", "mp4"}
|
|
187
|
+
The format of the video.
|
|
188
|
+
|
|
189
|
+
Returns
|
|
190
|
+
-------
|
|
191
|
+
video : bytes
|
|
192
|
+
The video data.
|
|
193
|
+
"""
|
|
194
|
+
if format == "gif":
|
|
195
|
+
# GIFs created with 'imagemagick' have less artifacts
|
|
196
|
+
if _is_installed("magick"):
|
|
197
|
+
return _create_gif_with_imagemagick(input_dir, fps)
|
|
198
|
+
elif _is_installed("ffmpeg"):
|
|
199
|
+
return _create_video_with_ffmpeg(input_dir, fps, format)
|
|
200
|
+
else:
|
|
201
|
+
raise RenderError("Neither 'imagemagick' nor 'ffmpeg' is installed")
|
|
202
|
+
elif format == "mp4":
|
|
203
|
+
if _is_installed("ffmpeg"):
|
|
204
|
+
return _create_video_with_ffmpeg(input_dir, fps, format)
|
|
205
|
+
else:
|
|
206
|
+
raise RenderError("'ffmpeg' is not installed")
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
def _create_gif_with_imagemagick(input_dir, fps):
|
|
210
|
+
# See https://usage.imagemagick.org/anim_basics/ for reference
|
|
211
|
+
completed_process = subprocess.run(
|
|
212
|
+
[
|
|
213
|
+
"magick",
|
|
214
|
+
# GIFs require a multiple of a hundredth of a second to work properly
|
|
215
|
+
"-delay", str(int(100 / fps)),
|
|
216
|
+
# Make animation loop infinitely
|
|
217
|
+
"-loop", "0",
|
|
218
|
+
# Do not overlay images
|
|
219
|
+
"-dispose", "Previous",
|
|
220
|
+
join(input_dir, "*.png"),
|
|
221
|
+
# Decrease GIF size
|
|
222
|
+
"-layers", "Optimize",
|
|
223
|
+
"GIF:-",
|
|
224
|
+
],
|
|
225
|
+
capture_output=True,
|
|
226
|
+
) # fmt: skip
|
|
227
|
+
if completed_process.returncode != 0:
|
|
228
|
+
raise RenderError(completed_process.stderr.decode())
|
|
229
|
+
return completed_process.stdout
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
def _create_video_with_ffmpeg(input_dir, fps, format):
|
|
233
|
+
# 'input_dir' is a temporary directory anyway
|
|
234
|
+
video_path = join(input_dir, f"video.{format}")
|
|
235
|
+
completed_process = subprocess.run(
|
|
236
|
+
[
|
|
237
|
+
"ffmpeg",
|
|
238
|
+
"-i", join(input_dir, "img_%04d.png"),
|
|
239
|
+
"-r", str(fps),
|
|
240
|
+
# Must be set to obtain a non-corrupted video
|
|
241
|
+
"-pix_fmt", "yuv420p",
|
|
242
|
+
video_path,
|
|
243
|
+
],
|
|
244
|
+
capture_output=True,
|
|
245
|
+
) # fmt: skip
|
|
246
|
+
if completed_process.returncode != 0:
|
|
247
|
+
raise RenderError(completed_process.stderr.decode())
|
|
248
|
+
with open(video_path, "rb") as f:
|
|
249
|
+
video_data = f.read()
|
|
250
|
+
return video_data
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
def _is_installed(program):
|
|
254
|
+
"""
|
|
255
|
+
Check whether the given program is installed.
|
|
256
|
+
|
|
257
|
+
Parameters
|
|
258
|
+
----------
|
|
259
|
+
program : str
|
|
260
|
+
The name of the program to check.
|
|
261
|
+
|
|
262
|
+
Returns
|
|
263
|
+
-------
|
|
264
|
+
installed : bool
|
|
265
|
+
True, if the program is installed, false otherwise.
|
|
266
|
+
"""
|
|
267
|
+
return shutil.which(program) is not None
|