biotite 1.1.0__cp313-cp313-macosx_11_0_arm64.whl → 1.3.0__cp313-cp313-macosx_11_0_arm64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of biotite might be problematic. Click here for more details.
- biotite/application/application.py +3 -3
- biotite/application/autodock/app.py +1 -1
- biotite/application/blast/webapp.py +1 -1
- biotite/application/clustalo/app.py +1 -1
- biotite/application/localapp.py +2 -2
- biotite/application/msaapp.py +10 -10
- biotite/application/muscle/app3.py +3 -3
- biotite/application/muscle/app5.py +3 -3
- biotite/application/sra/app.py +0 -5
- biotite/application/util.py +21 -1
- biotite/application/viennarna/rnaalifold.py +8 -8
- biotite/application/viennarna/rnaplot.py +10 -8
- biotite/application/viennarna/util.py +1 -1
- biotite/application/webapp.py +1 -1
- biotite/database/afdb/__init__.py +12 -0
- biotite/database/afdb/download.py +191 -0
- biotite/database/entrez/dbnames.py +10 -0
- biotite/database/entrez/download.py +9 -10
- biotite/database/entrez/key.py +1 -1
- biotite/database/entrez/query.py +5 -4
- biotite/database/pubchem/download.py +6 -6
- biotite/database/pubchem/error.py +10 -0
- biotite/database/pubchem/query.py +12 -23
- biotite/database/rcsb/download.py +3 -2
- biotite/database/rcsb/query.py +2 -3
- biotite/database/uniprot/check.py +2 -2
- biotite/database/uniprot/download.py +2 -5
- biotite/database/uniprot/query.py +3 -4
- biotite/file.py +14 -2
- biotite/interface/__init__.py +19 -0
- biotite/interface/openmm/__init__.py +20 -0
- biotite/interface/openmm/state.py +93 -0
- biotite/interface/openmm/system.py +227 -0
- biotite/interface/pymol/__init__.py +201 -0
- biotite/interface/pymol/cgo.py +346 -0
- biotite/interface/pymol/convert.py +185 -0
- biotite/interface/pymol/display.py +267 -0
- biotite/interface/pymol/object.py +1226 -0
- biotite/interface/pymol/shapes.py +178 -0
- biotite/interface/pymol/startup.py +169 -0
- biotite/interface/rdkit/__init__.py +19 -0
- biotite/interface/rdkit/mol.py +490 -0
- biotite/interface/version.py +94 -0
- biotite/interface/warning.py +19 -0
- biotite/sequence/align/__init__.py +0 -4
- biotite/sequence/align/alignment.py +33 -11
- biotite/sequence/align/banded.cpython-313-darwin.so +0 -0
- biotite/sequence/align/banded.pyx +22 -22
- biotite/sequence/align/cigar.py +2 -2
- biotite/sequence/align/kmeralphabet.cpython-313-darwin.so +0 -0
- biotite/sequence/align/kmeralphabet.pyx +2 -2
- biotite/sequence/align/kmersimilarity.cpython-313-darwin.so +0 -0
- biotite/sequence/align/kmertable.cpython-313-darwin.so +0 -0
- biotite/sequence/align/kmertable.pyx +6 -6
- biotite/sequence/align/localgapped.cpython-313-darwin.so +0 -0
- biotite/sequence/align/localgapped.pyx +47 -47
- biotite/sequence/align/localungapped.cpython-313-darwin.so +0 -0
- biotite/sequence/align/localungapped.pyx +10 -10
- biotite/sequence/align/matrix.py +12 -3
- biotite/sequence/align/multiple.cpython-313-darwin.so +0 -0
- biotite/sequence/align/multiple.pyx +1 -2
- biotite/sequence/align/pairwise.cpython-313-darwin.so +0 -0
- biotite/sequence/align/pairwise.pyx +37 -39
- biotite/sequence/align/permutation.cpython-313-darwin.so +0 -0
- biotite/sequence/align/selector.cpython-313-darwin.so +0 -0
- biotite/sequence/align/selector.pyx +2 -2
- biotite/sequence/align/statistics.py +1 -1
- biotite/sequence/align/tracetable.cpython-313-darwin.so +0 -0
- biotite/sequence/alphabet.py +2 -2
- biotite/sequence/annotation.py +19 -13
- biotite/sequence/codec.cpython-313-darwin.so +0 -0
- biotite/sequence/codon.py +1 -2
- biotite/sequence/graphics/alignment.py +25 -39
- biotite/sequence/graphics/dendrogram.py +4 -2
- biotite/sequence/graphics/features.py +2 -2
- biotite/sequence/graphics/logo.py +10 -12
- biotite/sequence/io/fasta/convert.py +1 -2
- biotite/sequence/io/fasta/file.py +1 -1
- biotite/sequence/io/fastq/file.py +3 -3
- biotite/sequence/io/genbank/file.py +3 -3
- biotite/sequence/io/genbank/sequence.py +2 -0
- biotite/sequence/io/gff/convert.py +1 -1
- biotite/sequence/io/gff/file.py +1 -2
- biotite/sequence/phylo/nj.cpython-313-darwin.so +0 -0
- biotite/sequence/phylo/tree.cpython-313-darwin.so +0 -0
- biotite/sequence/phylo/upgma.cpython-313-darwin.so +0 -0
- biotite/sequence/profile.py +19 -25
- biotite/sequence/search.py +0 -1
- biotite/sequence/seqtypes.py +12 -5
- biotite/sequence/sequence.py +1 -2
- biotite/structure/__init__.py +2 -0
- biotite/structure/alphabet/i3d.py +1 -2
- biotite/structure/alphabet/pb.py +1 -2
- biotite/structure/alphabet/unkerasify.py +8 -2
- biotite/structure/atoms.py +35 -27
- biotite/structure/basepairs.py +39 -40
- biotite/structure/bonds.cpython-313-darwin.so +0 -0
- biotite/structure/bonds.pyx +8 -5
- biotite/structure/box.py +159 -23
- biotite/structure/celllist.cpython-313-darwin.so +0 -0
- biotite/structure/celllist.pyx +83 -68
- biotite/structure/chains.py +17 -55
- biotite/structure/charges.cpython-313-darwin.so +0 -0
- biotite/structure/compare.py +420 -13
- biotite/structure/density.py +1 -1
- biotite/structure/dotbracket.py +31 -32
- biotite/structure/filter.py +8 -8
- biotite/structure/geometry.py +15 -15
- biotite/structure/graphics/rna.py +19 -16
- biotite/structure/hbond.py +18 -21
- biotite/structure/info/atoms.py +11 -2
- biotite/structure/info/ccd.py +0 -2
- biotite/structure/info/components.bcif +0 -0
- biotite/structure/info/groups.py +0 -3
- biotite/structure/info/misc.py +0 -1
- biotite/structure/info/radii.py +92 -22
- biotite/structure/info/standardize.py +1 -2
- biotite/structure/integrity.py +4 -6
- biotite/structure/io/general.py +2 -2
- biotite/structure/io/gro/file.py +8 -9
- biotite/structure/io/mol/convert.py +1 -1
- biotite/structure/io/mol/ctab.py +33 -28
- biotite/structure/io/mol/mol.py +1 -1
- biotite/structure/io/mol/sdf.py +39 -13
- biotite/structure/io/pdb/convert.py +86 -5
- biotite/structure/io/pdb/file.py +90 -24
- biotite/structure/io/pdb/hybrid36.cpython-313-darwin.so +0 -0
- biotite/structure/io/pdbqt/file.py +4 -4
- biotite/structure/io/pdbx/bcif.py +22 -7
- biotite/structure/io/pdbx/cif.py +20 -7
- biotite/structure/io/pdbx/component.py +6 -0
- biotite/structure/io/pdbx/compress.py +71 -34
- biotite/structure/io/pdbx/convert.py +429 -77
- biotite/structure/io/pdbx/encoding.cpython-313-darwin.so +0 -0
- biotite/structure/io/pdbx/encoding.pyx +39 -23
- biotite/structure/io/trajfile.py +9 -6
- biotite/structure/io/util.py +38 -0
- biotite/structure/mechanics.py +0 -1
- biotite/structure/molecules.py +0 -15
- biotite/structure/pseudoknots.py +13 -19
- biotite/structure/repair.py +2 -4
- biotite/structure/residues.py +20 -48
- biotite/structure/rings.py +335 -0
- biotite/structure/sasa.cpython-313-darwin.so +0 -0
- biotite/structure/sasa.pyx +30 -30
- biotite/structure/segments.py +123 -9
- biotite/structure/sequence.py +0 -1
- biotite/structure/spacegroups.json +1567 -0
- biotite/structure/spacegroups.license +26 -0
- biotite/structure/sse.py +0 -2
- biotite/structure/superimpose.py +75 -253
- biotite/structure/tm.py +581 -0
- biotite/structure/transform.py +232 -26
- biotite/structure/util.py +3 -3
- biotite/version.py +9 -4
- biotite/visualize.py +111 -1
- {biotite-1.1.0.dist-info → biotite-1.3.0.dist-info}/METADATA +8 -36
- {biotite-1.1.0.dist-info → biotite-1.3.0.dist-info}/RECORD +160 -138
- {biotite-1.1.0.dist-info → biotite-1.3.0.dist-info}/WHEEL +3 -1
- {biotite-1.1.0.dist-info → biotite-1.3.0.dist-info}/licenses/LICENSE.rst +0 -0
biotite/structure/basepairs.py
CHANGED
|
@@ -338,8 +338,8 @@ def base_pairs_edge(atom_array, base_pairs):
|
|
|
338
338
|
|
|
339
339
|
See Also
|
|
340
340
|
--------
|
|
341
|
-
base_pairs
|
|
342
|
-
base_pairs_glycosidic_bond
|
|
341
|
+
base_pairs : Get the base pairs required for this function.
|
|
342
|
+
base_pairs_glycosidic_bond : Determine the orientation for each base pair.
|
|
343
343
|
|
|
344
344
|
Notes
|
|
345
345
|
-----
|
|
@@ -351,6 +351,11 @@ def base_pairs_edge(atom_array, base_pairs):
|
|
|
351
351
|
The edge returned always corresponds to the edge with the most
|
|
352
352
|
hydrogen bonding interactions.
|
|
353
353
|
|
|
354
|
+
References
|
|
355
|
+
----------
|
|
356
|
+
|
|
357
|
+
.. footbibliography::
|
|
358
|
+
|
|
354
359
|
Examples
|
|
355
360
|
--------
|
|
356
361
|
Compute the interacting base edges for the dna helix with the PDB
|
|
@@ -392,11 +397,6 @@ def base_pairs_edge(atom_array, base_pairs):
|
|
|
392
397
|
WATSON_CRICK to WATSON_CRICK
|
|
393
398
|
WATSON_CRICK to WATSON_CRICK
|
|
394
399
|
WATSON_CRICK to WATSON_CRICK
|
|
395
|
-
|
|
396
|
-
References
|
|
397
|
-
----------
|
|
398
|
-
|
|
399
|
-
.. footbibliography::
|
|
400
400
|
"""
|
|
401
401
|
# Result-``ndarray`` matches the dimensions of the input array
|
|
402
402
|
results = np.zeros_like(base_pairs, dtype="uint8")
|
|
@@ -494,7 +494,7 @@ def base_pairs_glycosidic_bond(atom_array, base_pairs):
|
|
|
494
494
|
|
|
495
495
|
Returns
|
|
496
496
|
-------
|
|
497
|
-
results : ndarray, dtype=
|
|
497
|
+
results : ndarray, dtype=int, shape=(n,)
|
|
498
498
|
The ``ndarray`` has the same dimensions as ``base_pairs``. Each
|
|
499
499
|
cell corresponds to the interacting edge of the referenced base
|
|
500
500
|
in ``base_pairs``.
|
|
@@ -504,15 +504,20 @@ def base_pairs_glycosidic_bond(atom_array, base_pairs):
|
|
|
504
504
|
|
|
505
505
|
See Also
|
|
506
506
|
--------
|
|
507
|
-
base_pairs
|
|
508
|
-
base_pairs_edge
|
|
509
|
-
GlycosidicBond
|
|
507
|
+
base_pairs : Get the base pairs required for this function.
|
|
508
|
+
base_pairs_edge : Determine the interacting edge for each base pair.
|
|
509
|
+
GlycosidicBond : The Enum type for interpretation of the return value.
|
|
510
510
|
|
|
511
511
|
Notes
|
|
512
512
|
-----
|
|
513
513
|
The orientation is found using the geometric centers of the bases
|
|
514
514
|
and the glycosidic bonds as described in :footcite:`Yang2003`.
|
|
515
515
|
|
|
516
|
+
References
|
|
517
|
+
----------
|
|
518
|
+
|
|
519
|
+
.. footbibliography::
|
|
520
|
+
|
|
516
521
|
Examples
|
|
517
522
|
--------
|
|
518
523
|
Compute the glycosidic bond orientations for the dna helix with the
|
|
@@ -544,11 +549,6 @@ def base_pairs_glycosidic_bond(atom_array, base_pairs):
|
|
|
544
549
|
CIS
|
|
545
550
|
CIS
|
|
546
551
|
CIS
|
|
547
|
-
|
|
548
|
-
References
|
|
549
|
-
----------
|
|
550
|
-
|
|
551
|
-
.. footbibliography::
|
|
552
552
|
"""
|
|
553
553
|
results = np.zeros(len(base_pairs), dtype="uint8")
|
|
554
554
|
|
|
@@ -638,7 +638,7 @@ def base_stacking(atom_array, min_atoms_per_base=3):
|
|
|
638
638
|
----------
|
|
639
639
|
atom_array : AtomArray
|
|
640
640
|
The :class:`AtomArray` to find stacked bases in.
|
|
641
|
-
min_atoms_per_base : integer, optional
|
|
641
|
+
min_atoms_per_base : integer, optional
|
|
642
642
|
The number of atoms a nucleotides' base must have to be
|
|
643
643
|
considered a candidate for a stacking interaction.
|
|
644
644
|
|
|
@@ -654,6 +654,11 @@ def base_stacking(atom_array, min_atoms_per_base=3):
|
|
|
654
654
|
Please note that ring normal vectors are assumed to be equal to the
|
|
655
655
|
base normal vectors.
|
|
656
656
|
|
|
657
|
+
References
|
|
658
|
+
----------
|
|
659
|
+
|
|
660
|
+
.. footbibliography::
|
|
661
|
+
|
|
657
662
|
Examples
|
|
658
663
|
--------
|
|
659
664
|
Compute the stacking interactions for a DNA-double-helix (PDB ID
|
|
@@ -685,11 +690,6 @@ def base_stacking(atom_array, min_atoms_per_base=3):
|
|
|
685
690
|
[21 22]
|
|
686
691
|
[22 23]
|
|
687
692
|
[23 24]]
|
|
688
|
-
|
|
689
|
-
References
|
|
690
|
-
----------
|
|
691
|
-
|
|
692
|
-
.. footbibliography::
|
|
693
693
|
"""
|
|
694
694
|
# Get the stacking candidates according to a cutoff distance, where
|
|
695
695
|
# each base is identified as the first index of its respective
|
|
@@ -783,10 +783,10 @@ def base_pairs(atom_array, min_atoms_per_base=3, unique=True):
|
|
|
783
783
|
----------
|
|
784
784
|
atom_array : AtomArray
|
|
785
785
|
The :class:`AtomArray` to find base pairs in.
|
|
786
|
-
min_atoms_per_base : integer, optional
|
|
786
|
+
min_atoms_per_base : integer, optional
|
|
787
787
|
The number of atoms a nucleotides' base must have to be
|
|
788
788
|
considered a candidate for a base pair.
|
|
789
|
-
unique : bool, optional
|
|
789
|
+
unique : bool, optional
|
|
790
790
|
If ``True``, each base is assumed to be only paired with one
|
|
791
791
|
other base. If multiple pairings are plausible, the pairing with
|
|
792
792
|
the most hydrogen bonds is selected.
|
|
@@ -833,6 +833,11 @@ def base_pairs(atom_array, min_atoms_per_base=3, unique=True):
|
|
|
833
833
|
1.00Å and 0.96Å respectively. Thus, including some buffer, a 3.6Å
|
|
834
834
|
cutoff should cover all hydrogen bonds.
|
|
835
835
|
|
|
836
|
+
References
|
|
837
|
+
----------
|
|
838
|
+
|
|
839
|
+
.. footbibliography::
|
|
840
|
+
|
|
836
841
|
Examples
|
|
837
842
|
--------
|
|
838
843
|
Compute the base pairs for the structure with the PDB ID 1QXB:
|
|
@@ -855,11 +860,6 @@ def base_pairs(atom_array, min_atoms_per_base=3, unique=True):
|
|
|
855
860
|
['DG' 'DC']
|
|
856
861
|
['DC' 'DG']
|
|
857
862
|
['DG' 'DC']]
|
|
858
|
-
|
|
859
|
-
References
|
|
860
|
-
----------
|
|
861
|
-
|
|
862
|
-
.. footbibliography::
|
|
863
863
|
"""
|
|
864
864
|
|
|
865
865
|
# Get the nucleotides for the given atom_array
|
|
@@ -1203,26 +1203,25 @@ def map_nucleotide(residue, min_atoms_per_base=3, rmsd_cutoff=0.28):
|
|
|
1203
1203
|
If a different nucleotide is given, it is mapped to the best
|
|
1204
1204
|
fitting base using the algorithm described below.
|
|
1205
1205
|
|
|
1206
|
-
(i) The number of matching atom names with the reference bases is
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
(default 3) the nucleotide cannot be mapped and ``None`` is
|
|
1206
|
+
(i) The number of matching atom names with the reference bases is counted.
|
|
1207
|
+
If the number of matching atoms with all reference bases is less than the
|
|
1208
|
+
specified `min_atoms_per_base` the nucleotide cannot be mapped and ``None`` is
|
|
1210
1209
|
returned.
|
|
1211
1210
|
|
|
1212
|
-
(ii) The bases with maximum number of matching atoms are selected
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
and ``None`` is returned.
|
|
1211
|
+
(ii) The bases with maximum number of matching atoms are selected and superimposed
|
|
1212
|
+
with each reference.
|
|
1213
|
+
The base with lowest RMSD is chosen.
|
|
1214
|
+
If the RMSD is more than the specified `rmsd_cutoff`, the nucleotide cannot be
|
|
1215
|
+
mapped and ``None`` is returned.
|
|
1217
1216
|
|
|
1218
1217
|
Parameters
|
|
1219
1218
|
----------
|
|
1220
1219
|
residue : AtomArray
|
|
1221
1220
|
The nucleotide to be mapped.
|
|
1222
|
-
min_atoms_per_base : int, optional
|
|
1221
|
+
min_atoms_per_base : int, optional
|
|
1223
1222
|
The number of atoms the residue must have in common with the
|
|
1224
1223
|
reference.
|
|
1225
|
-
rmsd_cutoff : float, optional
|
|
1224
|
+
rmsd_cutoff : float, optional
|
|
1226
1225
|
The maximum RSMD that is allowed for a mapping to occur.
|
|
1227
1226
|
|
|
1228
1227
|
Returns
|
|
Binary file
|
biotite/structure/bonds.pyx
CHANGED
|
@@ -60,6 +60,7 @@ class BondType(IntEnum):
|
|
|
60
60
|
- `AROMATIC_SINGLE` - Aromatic bond with a single formal bond
|
|
61
61
|
- `AROMATIC_DOUBLE` - Aromatic bond with a double formal bond
|
|
62
62
|
- `AROMATIC_TRIPLE` - Aromatic bond with a triple formal bond
|
|
63
|
+
- `AROMATIC` - Aromatic bond without specification of the formal bond
|
|
63
64
|
- `COORDINATION` - Coordination complex involving a metal atom
|
|
64
65
|
"""
|
|
65
66
|
ANY = 0
|
|
@@ -71,6 +72,7 @@ class BondType(IntEnum):
|
|
|
71
72
|
AROMATIC_DOUBLE = 6
|
|
72
73
|
AROMATIC_TRIPLE = 7
|
|
73
74
|
COORDINATION = 8
|
|
75
|
+
AROMATIC = 9
|
|
74
76
|
|
|
75
77
|
|
|
76
78
|
def without_aromaticity(self):
|
|
@@ -97,6 +99,8 @@ class BondType(IntEnum):
|
|
|
97
99
|
return BondType.DOUBLE
|
|
98
100
|
elif self == BondType.AROMATIC_TRIPLE:
|
|
99
101
|
return BondType.TRIPLE
|
|
102
|
+
elif self == BondType.AROMATIC:
|
|
103
|
+
return BondType.ANY
|
|
100
104
|
else:
|
|
101
105
|
return self
|
|
102
106
|
|
|
@@ -517,7 +521,8 @@ class BondList(Copyable):
|
|
|
517
521
|
for aromatic_type, non_aromatic_type in [
|
|
518
522
|
(BondType.AROMATIC_SINGLE, BondType.SINGLE),
|
|
519
523
|
(BondType.AROMATIC_DOUBLE, BondType.DOUBLE),
|
|
520
|
-
(BondType.AROMATIC_TRIPLE, BondType.TRIPLE)
|
|
524
|
+
(BondType.AROMATIC_TRIPLE, BondType.TRIPLE),
|
|
525
|
+
(BondType.AROMATIC, BondType.ANY),
|
|
521
526
|
]:
|
|
522
527
|
bond_types[bond_types == aromatic_type] = non_aromatic_type
|
|
523
528
|
|
|
@@ -938,7 +943,6 @@ class BondList(Copyable):
|
|
|
938
943
|
----------
|
|
939
944
|
atom_index : int
|
|
940
945
|
The index of the atom whose bonds should be removed.
|
|
941
|
-
|
|
942
946
|
"""
|
|
943
947
|
cdef uint32 index = _to_positive_index(atom_index, self._atom_count)
|
|
944
948
|
|
|
@@ -1478,7 +1482,7 @@ def connect_via_distances(atoms, dict distance_range=None, bint inter_residue=Tr
|
|
|
1478
1482
|
BondList
|
|
1479
1483
|
The created bond list.
|
|
1480
1484
|
|
|
1481
|
-
See
|
|
1485
|
+
See Also
|
|
1482
1486
|
--------
|
|
1483
1487
|
connect_via_residue_names
|
|
1484
1488
|
|
|
@@ -1617,7 +1621,7 @@ def connect_via_residue_names(atoms, bint inter_residue=True,
|
|
|
1617
1621
|
No bonds are added for residues that are not found in
|
|
1618
1622
|
``components.cif``.
|
|
1619
1623
|
|
|
1620
|
-
See
|
|
1624
|
+
See Also
|
|
1621
1625
|
--------
|
|
1622
1626
|
connect_via_distances
|
|
1623
1627
|
|
|
@@ -1659,7 +1663,6 @@ def connect_via_residue_names(atoms, bint inter_residue=True,
|
|
|
1659
1663
|
('OXT', 'HXT'): <BondType.SINGLE: 1>},
|
|
1660
1664
|
'XYZ': {('A', 'B'): <BondType.SINGLE: 1>,
|
|
1661
1665
|
('B', 'C'): <BondType.SINGLE: 1>}}
|
|
1662
|
-
|
|
1663
1666
|
"""
|
|
1664
1667
|
from .info.bonds import bonds_in_residue
|
|
1665
1668
|
from .residues import get_residue_starts
|
biotite/structure/box.py
CHANGED
|
@@ -4,12 +4,13 @@
|
|
|
4
4
|
|
|
5
5
|
"""
|
|
6
6
|
Functions related to working with the simulation box or unit cell
|
|
7
|
-
of a structure
|
|
7
|
+
of a structure.
|
|
8
8
|
"""
|
|
9
9
|
|
|
10
10
|
__name__ = "biotite.structure"
|
|
11
11
|
__author__ = "Patrick Kunzmann"
|
|
12
12
|
__all__ = [
|
|
13
|
+
"space_group_transforms",
|
|
13
14
|
"vectors_from_unitcell",
|
|
14
15
|
"unitcell_from_vectors",
|
|
15
16
|
"box_volume",
|
|
@@ -23,16 +24,127 @@ __all__ = [
|
|
|
23
24
|
"is_orthogonal",
|
|
24
25
|
]
|
|
25
26
|
|
|
27
|
+
import functools
|
|
28
|
+
import json
|
|
26
29
|
from numbers import Integral
|
|
30
|
+
from pathlib import Path
|
|
27
31
|
import numpy as np
|
|
28
32
|
import numpy.linalg as linalg
|
|
29
33
|
from biotite.structure.atoms import repeat
|
|
30
34
|
from biotite.structure.chains import get_chain_masks, get_chain_starts
|
|
31
35
|
from biotite.structure.error import BadStructureError
|
|
32
36
|
from biotite.structure.molecules import get_molecule_masks
|
|
37
|
+
from biotite.structure.transform import AffineTransformation
|
|
33
38
|
from biotite.structure.util import vector_dot
|
|
34
39
|
|
|
35
40
|
|
|
41
|
+
def space_group_transforms(space_group):
|
|
42
|
+
"""
|
|
43
|
+
Get the coordinate transformations for a given space group.
|
|
44
|
+
|
|
45
|
+
Applying each transformation to a structure (in fractional coordinates) reproduces
|
|
46
|
+
the entire unit cell.
|
|
47
|
+
|
|
48
|
+
Parameters
|
|
49
|
+
----------
|
|
50
|
+
space_group : str or int
|
|
51
|
+
The space group name (full *Hermann-Mauguin* symbol) or
|
|
52
|
+
*International Table*'s number.
|
|
53
|
+
|
|
54
|
+
Returns
|
|
55
|
+
-------
|
|
56
|
+
transformations : list of AffineTransformation
|
|
57
|
+
The transformations that creates the symmetric copies of a structure in a unit
|
|
58
|
+
cell of the given space group.
|
|
59
|
+
Note that the transformations need to be applied to coordinates in fractions
|
|
60
|
+
of the unit cell and also return fractional coordinates, when applied.
|
|
61
|
+
|
|
62
|
+
See Also
|
|
63
|
+
--------
|
|
64
|
+
coord_to_fraction : Used to convert to fractional coordinates.
|
|
65
|
+
fraction_to_coord : Used to convert back to Cartesian coordinates.
|
|
66
|
+
|
|
67
|
+
Examples
|
|
68
|
+
--------
|
|
69
|
+
|
|
70
|
+
>>> transforms = space_group_transforms("P 21 21 21")
|
|
71
|
+
>>> for transform in transforms:
|
|
72
|
+
... print(transform.rotation)
|
|
73
|
+
... print(transform.target_translation)
|
|
74
|
+
... print()
|
|
75
|
+
[[[1. 0. 0.]
|
|
76
|
+
[0. 1. 0.]
|
|
77
|
+
[0. 0. 1.]]]
|
|
78
|
+
[[0. 0. 0.]]
|
|
79
|
+
<BLANKLINE>
|
|
80
|
+
[[[-1. 0. 0.]
|
|
81
|
+
[ 0. -1. 0.]
|
|
82
|
+
[ 0. 0. 1.]]]
|
|
83
|
+
[[0.5 0.0 0.5]]
|
|
84
|
+
<BLANKLINE>
|
|
85
|
+
[[[-1. 0. 0.]
|
|
86
|
+
[ 0. 1. 0.]
|
|
87
|
+
[ 0. 0. -1.]]]
|
|
88
|
+
[[0.0 0.5 0.5]]
|
|
89
|
+
<BLANKLINE>
|
|
90
|
+
[[[ 1. 0. 0.]
|
|
91
|
+
[ 0. -1. 0.]
|
|
92
|
+
[ 0. 0. -1.]]]
|
|
93
|
+
[[0.5 0.5 0.0]]
|
|
94
|
+
<BLANKLINE>
|
|
95
|
+
|
|
96
|
+
Reproduce the unit cell for some coordinates (in this case only one atom).
|
|
97
|
+
|
|
98
|
+
>>> asym_coord = np.array([[1.0, 2.0, 3.0]])
|
|
99
|
+
>>> box = np.eye(3) * 10
|
|
100
|
+
>>> transforms = space_group_transforms("P 21 21 21")
|
|
101
|
+
>>> # Apply the transformations to fractional coordinates of the asymmetric unit
|
|
102
|
+
>>> unit_cell = np.concatenate(
|
|
103
|
+
... [
|
|
104
|
+
... fraction_to_coord(transform.apply(coord_to_fraction(asym_coord, box)), box)
|
|
105
|
+
... for transform in transforms
|
|
106
|
+
... ]
|
|
107
|
+
... )
|
|
108
|
+
>>> print(unit_cell)
|
|
109
|
+
[[ 1. 2. 3.]
|
|
110
|
+
[ 4. -2. 8.]
|
|
111
|
+
[-1. 7. 2.]
|
|
112
|
+
[ 6. 3. -3.]]
|
|
113
|
+
"""
|
|
114
|
+
transformation_data = _get_transformation_data()
|
|
115
|
+
|
|
116
|
+
if isinstance(space_group, str):
|
|
117
|
+
try:
|
|
118
|
+
space_group_index = transformation_data["group_names"][space_group]
|
|
119
|
+
except KeyError:
|
|
120
|
+
raise ValueError(f"Space group '{space_group}' does not exist")
|
|
121
|
+
else:
|
|
122
|
+
try:
|
|
123
|
+
space_group_index = transformation_data["group_numbers"][str(space_group)]
|
|
124
|
+
except KeyError:
|
|
125
|
+
raise ValueError(f"Space group number {space_group} does not exist")
|
|
126
|
+
|
|
127
|
+
space_group = transformation_data["space_groups"][space_group_index]
|
|
128
|
+
transformations = []
|
|
129
|
+
for transformation_index in space_group:
|
|
130
|
+
matrix = np.zeros((3, 3), dtype=np.float32)
|
|
131
|
+
translation = np.zeros(3, dtype=np.float32)
|
|
132
|
+
for i, part_index in enumerate(
|
|
133
|
+
transformation_data["transformations"][transformation_index]
|
|
134
|
+
):
|
|
135
|
+
part = transformation_data["transformation_parts"][part_index]
|
|
136
|
+
matrix[i, :] = part[:3]
|
|
137
|
+
translation[i] = part[3]
|
|
138
|
+
transformations.append(
|
|
139
|
+
AffineTransformation(
|
|
140
|
+
center_translation=np.zeros(3, dtype=np.float32),
|
|
141
|
+
rotation=matrix,
|
|
142
|
+
target_translation=translation,
|
|
143
|
+
)
|
|
144
|
+
)
|
|
145
|
+
return transformations
|
|
146
|
+
|
|
147
|
+
|
|
36
148
|
def vectors_from_unitcell(len_a, len_b, len_c, alpha, beta, gamma):
|
|
37
149
|
"""
|
|
38
150
|
Calculate the three vectors spanning a box from the unit cell
|
|
@@ -45,10 +157,10 @@ def vectors_from_unitcell(len_a, len_b, len_c, alpha, beta, gamma):
|
|
|
45
157
|
----------
|
|
46
158
|
len_a, len_b, len_c : float
|
|
47
159
|
The lengths of the three box/unit cell vectors *a*, *b* and *c*.
|
|
48
|
-
alpha, beta, gamma:
|
|
160
|
+
alpha, beta, gamma : float
|
|
49
161
|
The angles between the box vectors in radians.
|
|
50
162
|
*alpha* is the angle between *b* and *c*,
|
|
51
|
-
*beta* between *a* and *c*, *gamma* between *a* and *b
|
|
163
|
+
*beta* between *a* and *c*, *gamma* between *a* and *b*.
|
|
52
164
|
|
|
53
165
|
Returns
|
|
54
166
|
-------
|
|
@@ -58,9 +170,9 @@ def vectors_from_unitcell(len_a, len_b, len_c, alpha, beta, gamma):
|
|
|
58
170
|
The value can be directly used as :attr:`box` attribute in an
|
|
59
171
|
atom array.
|
|
60
172
|
|
|
61
|
-
See
|
|
173
|
+
See Also
|
|
62
174
|
--------
|
|
63
|
-
unitcell_from_vectors
|
|
175
|
+
unitcell_from_vectors : The reverse operation.
|
|
64
176
|
"""
|
|
65
177
|
a_x = len_a
|
|
66
178
|
b_x = len_b * np.cos(gamma)
|
|
@@ -87,7 +199,7 @@ def unitcell_from_vectors(box):
|
|
|
87
199
|
Parameters
|
|
88
200
|
----------
|
|
89
201
|
box : ndarray, shape=(3,3)
|
|
90
|
-
The box vectors
|
|
202
|
+
The box vectors.
|
|
91
203
|
|
|
92
204
|
Returns
|
|
93
205
|
-------
|
|
@@ -96,9 +208,9 @@ def unitcell_from_vectors(box):
|
|
|
96
208
|
alpha, beta, gamma : float
|
|
97
209
|
The angles between the box vectors in radians.
|
|
98
210
|
|
|
99
|
-
See
|
|
211
|
+
See Also
|
|
100
212
|
--------
|
|
101
|
-
vectors_from_unitcell
|
|
213
|
+
vectors_from_unitcell : The reverse operation.
|
|
102
214
|
"""
|
|
103
215
|
a = box[0]
|
|
104
216
|
b = box[1]
|
|
@@ -124,6 +236,7 @@ def box_volume(box):
|
|
|
124
236
|
Returns
|
|
125
237
|
-------
|
|
126
238
|
volume : float or ndarray, shape=(m,)
|
|
239
|
+
The volume(s) of the given box(es).
|
|
127
240
|
"""
|
|
128
241
|
# Using the triple product
|
|
129
242
|
return np.abs(linalg.det(box))
|
|
@@ -159,14 +272,16 @@ def repeat_box(atoms, amount=1):
|
|
|
159
272
|
The repeated atoms.
|
|
160
273
|
Includes the original atoms (central box) in the beginning of
|
|
161
274
|
the atom array (stack).
|
|
275
|
+
If the input contains the ``sym_id`` annotation, the IDs are continued in the
|
|
276
|
+
repeated atoms, i.e. they do not start at 0 again.
|
|
162
277
|
indices : ndarray, dtype=int, shape=(n,3)
|
|
163
278
|
Indices to the atoms in the original atom array (stack).
|
|
164
279
|
Equal to
|
|
165
280
|
``numpy.tile(np.arange(atoms.array_length()), (1 + 2 * amount) ** 3)``.
|
|
166
281
|
|
|
167
|
-
See
|
|
282
|
+
See Also
|
|
168
283
|
--------
|
|
169
|
-
repeat_box_coord
|
|
284
|
+
repeat_box_coord : Variant that acts directly on coordinates.
|
|
170
285
|
|
|
171
286
|
Examples
|
|
172
287
|
--------
|
|
@@ -233,6 +348,15 @@ def repeat_box(atoms, amount=1):
|
|
|
233
348
|
>>> print(indices)
|
|
234
349
|
[0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0
|
|
235
350
|
1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1]
|
|
351
|
+
|
|
352
|
+
The ``sym_id`` is continued in the repeated atoms.
|
|
353
|
+
|
|
354
|
+
>>> array.set_annotation("sym_id", np.array([0, 0]))
|
|
355
|
+
>>> repeated, indices = repeat_box(array)
|
|
356
|
+
>>> print(repeated.sym_id)
|
|
357
|
+
[ 0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 10 11 11
|
|
358
|
+
12 12 13 13 14 14 15 15 16 16 17 17 18 18 19 19 20 20 21 21 22 22 23 23
|
|
359
|
+
24 24 25 25 26 26]
|
|
236
360
|
"""
|
|
237
361
|
if atoms.box is None:
|
|
238
362
|
raise BadStructureError("Structure has no box")
|
|
@@ -246,7 +370,16 @@ def repeat_box(atoms, amount=1):
|
|
|
246
370
|
atoms.stack_depth(), -1, atoms.array_length(), 3
|
|
247
371
|
)
|
|
248
372
|
repeat_coord = np.swapaxes(repeat_coord, 0, 1)
|
|
249
|
-
|
|
373
|
+
|
|
374
|
+
repeated_atoms = repeat(atoms, repeat_coord)
|
|
375
|
+
if "sym_id" in atoms.get_annotation_categories():
|
|
376
|
+
max_sym_id = np.max(atoms.sym_id)
|
|
377
|
+
# for the first repeat, (max_sym_id + 1) is added,
|
|
378
|
+
# for the second repeat 2*(max_sym_id + 1) etc.
|
|
379
|
+
repeated_atoms.sym_id += (max_sym_id + 1) * (
|
|
380
|
+
np.arange(repeated_atoms.array_length()) // atoms.array_length()
|
|
381
|
+
)
|
|
382
|
+
return repeated_atoms, indices
|
|
250
383
|
|
|
251
384
|
|
|
252
385
|
def repeat_box_coord(coord, box, amount=1):
|
|
@@ -383,9 +516,9 @@ def remove_pbc(atoms, selection=None):
|
|
|
383
516
|
The input structure with removed segmentation over periodic
|
|
384
517
|
boundaries.
|
|
385
518
|
|
|
386
|
-
See
|
|
519
|
+
See Also
|
|
387
520
|
--------
|
|
388
|
-
remove_pbc_from_coord
|
|
521
|
+
remove_pbc_from_coord : Variant that acts directly on coordinates.
|
|
389
522
|
|
|
390
523
|
Notes
|
|
391
524
|
-----
|
|
@@ -430,8 +563,6 @@ def remove_pbc_from_coord(coord, box):
|
|
|
430
563
|
is moved inside the box.
|
|
431
564
|
All other coordinates are assembled relative to the origin by using
|
|
432
565
|
the displacement coordinates in adjacent array positions.
|
|
433
|
-
Basically, this function performs the reverse action of
|
|
434
|
-
:func:`move_inside_box()`.
|
|
435
566
|
|
|
436
567
|
Parameters
|
|
437
568
|
----------
|
|
@@ -447,10 +578,9 @@ def remove_pbc_from_coord(coord, box):
|
|
|
447
578
|
sanitized_coord : ndarray, dtype=float, shape=(m,n,3) or shape=(n,3)
|
|
448
579
|
The reassembled coordinates.
|
|
449
580
|
|
|
450
|
-
See
|
|
581
|
+
See Also
|
|
451
582
|
--------
|
|
452
|
-
|
|
453
|
-
move_inside_box
|
|
583
|
+
move_inside_box : The reverse operation.
|
|
454
584
|
|
|
455
585
|
Notes
|
|
456
586
|
-----
|
|
@@ -501,9 +631,9 @@ def coord_to_fraction(coord, box):
|
|
|
501
631
|
fraction : ndarray, dtype=float, shape=(n,3) or shape=(m,n,3)
|
|
502
632
|
The fractions of the box vectors.
|
|
503
633
|
|
|
504
|
-
See
|
|
634
|
+
See Also
|
|
505
635
|
--------
|
|
506
|
-
fraction_to_coord
|
|
636
|
+
fraction_to_coord : The reverse operation.
|
|
507
637
|
|
|
508
638
|
Examples
|
|
509
639
|
--------
|
|
@@ -548,9 +678,9 @@ def fraction_to_coord(fraction, box):
|
|
|
548
678
|
coord : ndarray, dtype=float, shape=(n,3) or shape=(m,n,3)
|
|
549
679
|
The coordinates.
|
|
550
680
|
|
|
551
|
-
See
|
|
681
|
+
See Also
|
|
552
682
|
--------
|
|
553
|
-
coord_to_fraction
|
|
683
|
+
coord_to_fraction : The reverse operation.
|
|
554
684
|
"""
|
|
555
685
|
return np.matmul(fraction, box)
|
|
556
686
|
|
|
@@ -570,7 +700,7 @@ def is_orthogonal(box):
|
|
|
570
700
|
Returns
|
|
571
701
|
-------
|
|
572
702
|
is_orthgonal : bool or ndarray, shape=(m,), dtype=bool
|
|
573
|
-
True, if the box vectors are orthogonal, false otherwise
|
|
703
|
+
True, if the box vectors are orthogonal, false otherwise.
|
|
574
704
|
|
|
575
705
|
Notes
|
|
576
706
|
-----
|
|
@@ -586,3 +716,9 @@ def is_orthogonal(box):
|
|
|
586
716
|
& (np.abs(vector_dot(box[..., 0, :], box[..., 2, :])) < tol)
|
|
587
717
|
& (np.abs(vector_dot(box[..., 1, :], box[..., 2, :])) < tol)
|
|
588
718
|
)
|
|
719
|
+
|
|
720
|
+
|
|
721
|
+
@functools.cache
|
|
722
|
+
def _get_transformation_data():
|
|
723
|
+
with open(Path(__file__).parent / "spacegroups.json") as file:
|
|
724
|
+
return json.load(file)
|
|
Binary file
|