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,343 @@
|
|
|
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.io.gro"
|
|
6
|
+
__author__ = "Daniel Bauer, Patrick Kunzmann"
|
|
7
|
+
__all__ = ["GROFile"]
|
|
8
|
+
|
|
9
|
+
import copy
|
|
10
|
+
from datetime import datetime
|
|
11
|
+
import numpy as np
|
|
12
|
+
from biotite.file import InvalidFileError, TextFile
|
|
13
|
+
from biotite.structure.atoms import AtomArray, AtomArrayStack
|
|
14
|
+
from biotite.structure.box import is_orthogonal
|
|
15
|
+
from biotite.structure.error import BadStructureError
|
|
16
|
+
from biotite.structure.repair import infer_elements
|
|
17
|
+
|
|
18
|
+
_atom_records = {
|
|
19
|
+
"res_id": (0, 5),
|
|
20
|
+
"res_name": (5, 10),
|
|
21
|
+
"atom_name": (10, 15),
|
|
22
|
+
"atom_id": (15, 20),
|
|
23
|
+
"coord_x": (20, 28),
|
|
24
|
+
"coord_y": (28, 36),
|
|
25
|
+
"coord_z": (36, 44),
|
|
26
|
+
"v_x": (44, 52),
|
|
27
|
+
"v_y": (52, 60),
|
|
28
|
+
"v_z": (60, 68),
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class GROFile(TextFile):
|
|
33
|
+
r"""
|
|
34
|
+
This class represents a GRO file.
|
|
35
|
+
|
|
36
|
+
This class only provides support for reading/writing the pure atom
|
|
37
|
+
information
|
|
38
|
+
|
|
39
|
+
Examples
|
|
40
|
+
--------
|
|
41
|
+
Load a `\\*.gro` file, modify the structure and save the new
|
|
42
|
+
structure into a new file:
|
|
43
|
+
|
|
44
|
+
>>> import os.path
|
|
45
|
+
>>> file = GROFile.read(os.path.join(path_to_structures, "1l2y.gro"))
|
|
46
|
+
>>> array_stack = file.get_structure()
|
|
47
|
+
>>> array_stack_mod = rotate(array_stack, [1,2,3])
|
|
48
|
+
>>> file = GROFile()
|
|
49
|
+
>>> file.set_structure(array_stack_mod)
|
|
50
|
+
>>> file.write(os.path.join(path_to_directory, "1l2y_mod.gro"))
|
|
51
|
+
"""
|
|
52
|
+
|
|
53
|
+
def get_model_count(self):
|
|
54
|
+
"""
|
|
55
|
+
Get the number of models contained in this GRO file.
|
|
56
|
+
|
|
57
|
+
Returns
|
|
58
|
+
-------
|
|
59
|
+
model_count : int
|
|
60
|
+
The number of models.
|
|
61
|
+
"""
|
|
62
|
+
model_count = 0
|
|
63
|
+
for line in self.lines:
|
|
64
|
+
if _is_int(line):
|
|
65
|
+
model_count += 1
|
|
66
|
+
return model_count
|
|
67
|
+
|
|
68
|
+
def get_structure(self, model=None):
|
|
69
|
+
"""
|
|
70
|
+
Get an :class:`AtomArray` or :class:`AtomArrayStack` from the
|
|
71
|
+
GRO file.
|
|
72
|
+
|
|
73
|
+
Parameters
|
|
74
|
+
----------
|
|
75
|
+
model : int, optional
|
|
76
|
+
If this parameter is given, the function will return an
|
|
77
|
+
:class:`AtomArray` from the atoms corresponding to the given
|
|
78
|
+
model number (starting at 1).
|
|
79
|
+
Negative values are used to index models starting from the
|
|
80
|
+
last model insted of the first model.
|
|
81
|
+
If this parameter is omitted, an :class:`AtomArrayStack`
|
|
82
|
+
containing all models will be returned, even if the
|
|
83
|
+
structure contains only one model.
|
|
84
|
+
|
|
85
|
+
Returns
|
|
86
|
+
-------
|
|
87
|
+
array : AtomArray or AtomArrayStack
|
|
88
|
+
The return type depends on the `model` parameter.
|
|
89
|
+
"""
|
|
90
|
+
|
|
91
|
+
def _get_atom_line_i(model_start_i, model_atom_counts):
|
|
92
|
+
"""
|
|
93
|
+
Helper function to get the indices of all atoms for a model
|
|
94
|
+
"""
|
|
95
|
+
return np.arange(model_start_i + 1, model_start_i + 1 + model_atom_counts)
|
|
96
|
+
|
|
97
|
+
def _set_box_dimen(box_param):
|
|
98
|
+
"""
|
|
99
|
+
Helper function to create the box vectors from the values
|
|
100
|
+
in the GRO file
|
|
101
|
+
|
|
102
|
+
Parameters
|
|
103
|
+
----------
|
|
104
|
+
box_param : list of float
|
|
105
|
+
The box dimensions in the GRO file.
|
|
106
|
+
|
|
107
|
+
Returns
|
|
108
|
+
-------
|
|
109
|
+
box_vectors : ndarray, dtype=float, shape=(3,3)
|
|
110
|
+
The atom array compatible box vectors.
|
|
111
|
+
"""
|
|
112
|
+
if not any(box_param):
|
|
113
|
+
return None
|
|
114
|
+
if len(box_param) == 3:
|
|
115
|
+
x, y, z = box_param
|
|
116
|
+
return np.array([[x, 0, 0], [0, y, 0], [0, 0, z]], dtype=float)
|
|
117
|
+
elif len(box_param) == 9:
|
|
118
|
+
x1, y2, z3, x2, x3, y1, y3, z1, z2 = box_param
|
|
119
|
+
return np.array([[x1, x2, x3], [y1, y2, y3], [z1, z2, z3]], dtype=float)
|
|
120
|
+
else:
|
|
121
|
+
raise InvalidFileError(
|
|
122
|
+
f"Invalid amount of box parameters: {len(box_param)}"
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
# Line indices where a new model starts
|
|
126
|
+
model_start_i = np.array(
|
|
127
|
+
[i for i in range(len(self.lines)) if _is_int(self.lines[i])], dtype=int
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
# Number of atoms in each model
|
|
131
|
+
model_atom_counts = np.array([int(self.lines[i]) for i in model_start_i])
|
|
132
|
+
|
|
133
|
+
if model is None:
|
|
134
|
+
# Check if all models have the same length
|
|
135
|
+
if np.all(model_atom_counts != model_atom_counts[0]):
|
|
136
|
+
raise BadStructureError(
|
|
137
|
+
"The models in the file have unequal "
|
|
138
|
+
"amount of atoms, give an explicit "
|
|
139
|
+
"model instead"
|
|
140
|
+
)
|
|
141
|
+
depth = len(model_start_i)
|
|
142
|
+
length = model_atom_counts[0]
|
|
143
|
+
array = AtomArrayStack(depth, length)
|
|
144
|
+
|
|
145
|
+
# Line indices for annotation determination is determined
|
|
146
|
+
# from model 1
|
|
147
|
+
annot_i = _get_atom_line_i(model_start_i[0], length)
|
|
148
|
+
else:
|
|
149
|
+
if model == 0:
|
|
150
|
+
raise ValueError("The model index must not be 0")
|
|
151
|
+
# Negative models mean index starting from last model
|
|
152
|
+
model = len(model_start_i) + model + 1 if model < 0 else model
|
|
153
|
+
if model > len(model_start_i):
|
|
154
|
+
raise ValueError(
|
|
155
|
+
f"The file has {len(model_start_i)} models, "
|
|
156
|
+
f"the given model {model} does not exist"
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
length = model_atom_counts[model - 1]
|
|
160
|
+
array = AtomArray(length)
|
|
161
|
+
|
|
162
|
+
annot_i = _get_atom_line_i(model_start_i[model - 1], length)
|
|
163
|
+
|
|
164
|
+
# Replace empty strings for elements with guessed types
|
|
165
|
+
# i is index in array, line_i is line index
|
|
166
|
+
for i, line_i in enumerate(annot_i):
|
|
167
|
+
line = self.lines[line_i]
|
|
168
|
+
array.res_id[i] = int(line[0:5])
|
|
169
|
+
array.res_name[i] = line[5:10].strip()
|
|
170
|
+
array.atom_name[i] = line[10:15].strip()
|
|
171
|
+
array.element = infer_elements(array.atom_name)
|
|
172
|
+
|
|
173
|
+
# Fill in coordinates and boxes
|
|
174
|
+
if isinstance(array, AtomArray):
|
|
175
|
+
atom_i = annot_i
|
|
176
|
+
for i, line_i in enumerate(atom_i):
|
|
177
|
+
line = self.lines[line_i]
|
|
178
|
+
# gro files use nm instead of A
|
|
179
|
+
array.coord[i, 0] = float(line[20:28]) * 10
|
|
180
|
+
array.coord[i, 1] = float(line[28:36]) * 10
|
|
181
|
+
array.coord[i, 2] = float(line[36:44]) * 10
|
|
182
|
+
# Box is stored in last line (after coordinates)
|
|
183
|
+
box_i = atom_i[-1] + 1
|
|
184
|
+
box_param = [float(e) * 10 for e in self.lines[box_i].split()]
|
|
185
|
+
array.box = _set_box_dimen(box_param)
|
|
186
|
+
|
|
187
|
+
elif isinstance(array, AtomArrayStack):
|
|
188
|
+
for m in range(len(model_start_i)):
|
|
189
|
+
atom_i = _get_atom_line_i(model_start_i[m], model_atom_counts[m])
|
|
190
|
+
for i, line_i in enumerate(atom_i):
|
|
191
|
+
line = self.lines[line_i]
|
|
192
|
+
array.coord[m, i, 0] = float(line[20:28]) * 10
|
|
193
|
+
array.coord[m, i, 1] = float(line[28:36]) * 10
|
|
194
|
+
array.coord[m, i, 2] = float(line[36:44]) * 10
|
|
195
|
+
# Box is stored in last line (after coordinates)
|
|
196
|
+
box_i = atom_i[-1] + 1
|
|
197
|
+
box_param = [float(e) * 10 for e in self.lines[box_i].split()]
|
|
198
|
+
box = _set_box_dimen(box_param)
|
|
199
|
+
# Create a box in the stack if not already existing
|
|
200
|
+
# and the box is not a dummy
|
|
201
|
+
if box is not None:
|
|
202
|
+
if array.box is None:
|
|
203
|
+
array.box = np.zeros((array.stack_depth(), 3, 3))
|
|
204
|
+
array.box[m] = box
|
|
205
|
+
|
|
206
|
+
return array
|
|
207
|
+
|
|
208
|
+
def set_structure(self, array):
|
|
209
|
+
"""
|
|
210
|
+
Set the :class:`AtomArray` or :class:`AtomArrayStack` for the
|
|
211
|
+
file.
|
|
212
|
+
|
|
213
|
+
Parameters
|
|
214
|
+
----------
|
|
215
|
+
array : AtomArray or AtomArrayStack
|
|
216
|
+
The array or stack to be saved into this file. If a stack
|
|
217
|
+
is given, each array in the stack is saved as separate
|
|
218
|
+
model.
|
|
219
|
+
"""
|
|
220
|
+
|
|
221
|
+
def get_box_dimen(array):
|
|
222
|
+
"""
|
|
223
|
+
GRO files have the box dimensions as last line for each
|
|
224
|
+
model.
|
|
225
|
+
In case, the `box` attribute of the atom array is
|
|
226
|
+
`None`, we simply use the min and max coordinates in xyz
|
|
227
|
+
to get the correct size
|
|
228
|
+
|
|
229
|
+
Parameters
|
|
230
|
+
----------
|
|
231
|
+
array : AtomArray
|
|
232
|
+
The atom array to get the box dimensions from.
|
|
233
|
+
|
|
234
|
+
Returns
|
|
235
|
+
-------
|
|
236
|
+
box : str
|
|
237
|
+
The box, properly formatted for GRO files.
|
|
238
|
+
"""
|
|
239
|
+
if array.box is None:
|
|
240
|
+
coord = array.coord
|
|
241
|
+
bx, by, bz = (coord.max(axis=0) - coord.min(axis=0)) / 10
|
|
242
|
+
return f"{bx:>8.3f} {by:>8.3f} {bz:>8.3f}"
|
|
243
|
+
else:
|
|
244
|
+
box = array.box
|
|
245
|
+
if is_orthogonal(box):
|
|
246
|
+
bx, by, bz = np.diag(box) / 10
|
|
247
|
+
return f"{bx:>9.5f} {by:>9.5f} {bz:>9.5f}"
|
|
248
|
+
else:
|
|
249
|
+
box = box / 10
|
|
250
|
+
box_elements = (
|
|
251
|
+
box[0, 0],
|
|
252
|
+
box[1, 1],
|
|
253
|
+
box[2, 2],
|
|
254
|
+
box[0, 1],
|
|
255
|
+
box[0, 2],
|
|
256
|
+
box[1, 0],
|
|
257
|
+
box[1, 2],
|
|
258
|
+
box[2, 0],
|
|
259
|
+
box[2, 1],
|
|
260
|
+
)
|
|
261
|
+
return " ".join([f"{e:>9.5f}" for e in box_elements])
|
|
262
|
+
|
|
263
|
+
if "atom_id" in array.get_annotation_categories():
|
|
264
|
+
atom_id = array.atom_id
|
|
265
|
+
else:
|
|
266
|
+
atom_id = np.arange(1, array.array_length() + 1)
|
|
267
|
+
# Atom IDs are supported up to 99999,
|
|
268
|
+
# but negative IDs are also possible
|
|
269
|
+
gro_atom_id = np.where(atom_id > 0, ((atom_id - 1) % 99999) + 1, atom_id)
|
|
270
|
+
# Residue IDs are supported up to 9999,
|
|
271
|
+
# but negative IDs are also possible
|
|
272
|
+
gro_res_id = np.where(
|
|
273
|
+
array.res_id > 0, ((array.res_id - 1) % 99999) + 1, array.res_id
|
|
274
|
+
)
|
|
275
|
+
|
|
276
|
+
if isinstance(array, AtomArray):
|
|
277
|
+
self.lines = [None] * (array.array_length() + 3)
|
|
278
|
+
|
|
279
|
+
# Write header lines
|
|
280
|
+
self.lines[0] = f"Generated by Biotite at {datetime.now()}"
|
|
281
|
+
self.lines[1] = str(array.array_length())
|
|
282
|
+
|
|
283
|
+
# Write atom lines
|
|
284
|
+
fmt = "{:>5d}{:5s}{:>5s}{:>5d}{:>8.3f}{:>8.3f}{:>8.3f}"
|
|
285
|
+
for i in range(array.array_length()):
|
|
286
|
+
# gro format is in nm -> multiply coords by 10
|
|
287
|
+
self.lines[i + 2] = fmt.format(
|
|
288
|
+
gro_res_id[i],
|
|
289
|
+
array.res_name[i],
|
|
290
|
+
array.atom_name[i],
|
|
291
|
+
gro_atom_id[i],
|
|
292
|
+
array.coord[i, 0] / 10,
|
|
293
|
+
array.coord[i, 1] / 10,
|
|
294
|
+
array.coord[i, 2] / 10,
|
|
295
|
+
)
|
|
296
|
+
# Write box lines
|
|
297
|
+
self.lines[-1] = get_box_dimen(array)
|
|
298
|
+
elif isinstance(array, AtomArrayStack):
|
|
299
|
+
self.lines = []
|
|
300
|
+
# The entire information, but the coordinates,
|
|
301
|
+
# is equal for each model
|
|
302
|
+
# Therefore template lines are created
|
|
303
|
+
# which are afterwards applied for each model
|
|
304
|
+
templines = [None] * array.array_length()
|
|
305
|
+
fmt = "{:>5d}{:5s}{:>5s}{:5d}"
|
|
306
|
+
for i in range(array.array_length()):
|
|
307
|
+
templines[i] = fmt.format(
|
|
308
|
+
gro_res_id[i], array.res_name[i], array.atom_name[i], gro_atom_id[i]
|
|
309
|
+
)
|
|
310
|
+
|
|
311
|
+
for i in range(array.stack_depth()):
|
|
312
|
+
self.lines.append(
|
|
313
|
+
f"Generated by Biotite at {datetime.now()}, model={i + 1}"
|
|
314
|
+
)
|
|
315
|
+
self.lines.append(str(array.array_length()))
|
|
316
|
+
|
|
317
|
+
# Fill in coordinates for each model
|
|
318
|
+
modellines = copy.copy(templines)
|
|
319
|
+
for j, line in enumerate(modellines):
|
|
320
|
+
# Insert coordinates
|
|
321
|
+
line = line + "{:>8.3f}{:>8.3f}{:>8.3f}".format(
|
|
322
|
+
array.coord[i, j, 0] / 10,
|
|
323
|
+
array.coord[i, j, 1] / 10,
|
|
324
|
+
array.coord[i, j, 2] / 10,
|
|
325
|
+
)
|
|
326
|
+
modellines[j] = line
|
|
327
|
+
self.lines.extend(modellines)
|
|
328
|
+
self.lines.append(get_box_dimen(array[i]))
|
|
329
|
+
else:
|
|
330
|
+
raise TypeError("An atom array or stack must be provided")
|
|
331
|
+
# Add terminal newline, since PyMOL requires it
|
|
332
|
+
self.lines.append("")
|
|
333
|
+
|
|
334
|
+
|
|
335
|
+
def _is_int(string):
|
|
336
|
+
"""
|
|
337
|
+
Return ``True`, if the string can be parsed to an int.
|
|
338
|
+
"""
|
|
339
|
+
try:
|
|
340
|
+
int(string)
|
|
341
|
+
return True
|
|
342
|
+
except ValueError:
|
|
343
|
+
return False
|
|
@@ -0,0 +1,20 @@
|
|
|
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
|
+
The MOL format is used to depict atom positions and bonds for small
|
|
7
|
+
molecules.
|
|
8
|
+
This subpackage is used for reading and writing an :class:`AtomArray`
|
|
9
|
+
in this format.
|
|
10
|
+
Additionally, reading data from the SDF format, which is a wrapper
|
|
11
|
+
around MOL, is also supported.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
__name__ = "biotite.structure.io.mol"
|
|
15
|
+
__author__ = "Patrick Kunzmann"
|
|
16
|
+
|
|
17
|
+
from .convert import *
|
|
18
|
+
from .header import *
|
|
19
|
+
from .mol import *
|
|
20
|
+
from .sdf import *
|
|
@@ -0,0 +1,112 @@
|
|
|
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.io.mol"
|
|
6
|
+
__author__ = "Patrick Kunzmann"
|
|
7
|
+
__all__ = ["get_structure", "set_structure"]
|
|
8
|
+
|
|
9
|
+
from biotite.structure.bonds import BondType
|
|
10
|
+
from biotite.structure.io.mol.mol import MOLFile
|
|
11
|
+
from biotite.structure.io.mol.sdf import SDFile, SDRecord
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def get_structure(mol_file, record_name=None):
|
|
15
|
+
"""
|
|
16
|
+
Get an :class:`AtomArray` from the MOL file.
|
|
17
|
+
|
|
18
|
+
Ths function is a thin wrapper around
|
|
19
|
+
:meth:`MOLFile.get_structure()`.
|
|
20
|
+
|
|
21
|
+
Parameters
|
|
22
|
+
----------
|
|
23
|
+
mol_file : MOLFile or SDFile or SDRecord
|
|
24
|
+
The file.
|
|
25
|
+
record_name : str, optional
|
|
26
|
+
Has only an effect when `mol_file` is a :class:`SDFile`.
|
|
27
|
+
The name of the record in the SD file.
|
|
28
|
+
By default, the first record is used.
|
|
29
|
+
|
|
30
|
+
Returns
|
|
31
|
+
-------
|
|
32
|
+
array : AtomArray
|
|
33
|
+
This :class:`AtomArray` contains the optional ``charge``
|
|
34
|
+
annotation and has an associated :class:`BondList`.
|
|
35
|
+
All other annotation categories, except ``element`` are
|
|
36
|
+
empty.
|
|
37
|
+
"""
|
|
38
|
+
record = _get_record(mol_file, record_name)
|
|
39
|
+
return record.get_structure()
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def set_structure(
|
|
43
|
+
mol_file, atoms, default_bond_type=BondType.ANY, version=None, record_name=None
|
|
44
|
+
):
|
|
45
|
+
"""
|
|
46
|
+
Set the :class:`AtomArray` for the MOL file.
|
|
47
|
+
|
|
48
|
+
Ths function is a thin wrapper around
|
|
49
|
+
:meth:`MOLFile.set_structure()`.
|
|
50
|
+
|
|
51
|
+
Parameters
|
|
52
|
+
----------
|
|
53
|
+
mol_file : MOLFile
|
|
54
|
+
The MOL file.
|
|
55
|
+
atoms : AtomArray
|
|
56
|
+
The array to be saved into this file.
|
|
57
|
+
Must have an associated :class:`BondList`.
|
|
58
|
+
Bond type fallback for the *Bond block*, if a
|
|
59
|
+
:class:`BondType` has no CTAB counterpart.
|
|
60
|
+
By default, each such bond is treated as
|
|
61
|
+
:attr:`BondType.ANY`.
|
|
62
|
+
default_bond_type : BondType, optional
|
|
63
|
+
Bond type fallback for the *Bond block*, if a :class:`BondType`
|
|
64
|
+
has no CTAB counterpart.
|
|
65
|
+
By default, each such bond is treated as :attr:`BondType.ANY`.
|
|
66
|
+
version : {"V2000", "V3000"}, optional
|
|
67
|
+
The version of the CTAB format.
|
|
68
|
+
``"V2000"`` uses the *Atom* and *Bond* block, while ``"V3000"``
|
|
69
|
+
uses the *Properties* block.
|
|
70
|
+
By default, ``"V2000"`` is used, unless the number of atoms or
|
|
71
|
+
bonds exceeds 999, in which case ``"V3000"`` is used.
|
|
72
|
+
record_name : str, optional
|
|
73
|
+
Has only an effect when `mol_file` is a :class:`SDFile`.
|
|
74
|
+
The name of the record.
|
|
75
|
+
Default is the first record of the file.
|
|
76
|
+
If the file is empty, a new record will be created.
|
|
77
|
+
"""
|
|
78
|
+
record = _get_or_create_record(mol_file, record_name)
|
|
79
|
+
record.set_structure(atoms, default_bond_type, version)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def _get_record(file, record_name):
|
|
83
|
+
if isinstance(file, (MOLFile, SDRecord)):
|
|
84
|
+
return file
|
|
85
|
+
elif isinstance(file, SDFile):
|
|
86
|
+
# Determine record
|
|
87
|
+
if record_name is None:
|
|
88
|
+
return file.record
|
|
89
|
+
else:
|
|
90
|
+
return file[record_name]
|
|
91
|
+
else:
|
|
92
|
+
raise TypeError(f"Unsupported file type '{type(file).__name__}'")
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def _get_or_create_record(file, record_name):
|
|
96
|
+
if isinstance(file, (MOLFile, SDRecord)):
|
|
97
|
+
return file
|
|
98
|
+
elif isinstance(file, SDFile):
|
|
99
|
+
if record_name is None:
|
|
100
|
+
if len(file) > 0:
|
|
101
|
+
# Choose first record by default
|
|
102
|
+
record_name = next(iter(file.keys()))
|
|
103
|
+
else:
|
|
104
|
+
# File is empty -> invent a new record name
|
|
105
|
+
record_name = "Molecule"
|
|
106
|
+
|
|
107
|
+
if record_name not in file:
|
|
108
|
+
record = SDRecord()
|
|
109
|
+
file[record_name] = record
|
|
110
|
+
return file[record_name]
|
|
111
|
+
else:
|
|
112
|
+
raise TypeError(f"Unsupported file type '{type(file).__name__}'")
|