biotite 1.0.1__cp311-cp311-win_amd64.whl → 1.2.0__cp311-cp311-win_amd64.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.

Files changed (177) hide show
  1. biotite/application/application.py +3 -3
  2. biotite/application/autodock/app.py +1 -1
  3. biotite/application/blast/webapp.py +1 -1
  4. biotite/application/clustalo/app.py +1 -1
  5. biotite/application/dssp/app.py +13 -3
  6. biotite/application/localapp.py +36 -2
  7. biotite/application/msaapp.py +10 -10
  8. biotite/application/muscle/app3.py +5 -18
  9. biotite/application/muscle/app5.py +5 -5
  10. biotite/application/sra/app.py +0 -5
  11. biotite/application/util.py +22 -2
  12. biotite/application/viennarna/rnaalifold.py +8 -8
  13. biotite/application/viennarna/rnaplot.py +9 -3
  14. biotite/application/viennarna/util.py +1 -1
  15. biotite/application/webapp.py +1 -1
  16. biotite/database/afdb/__init__.py +12 -0
  17. biotite/database/afdb/download.py +191 -0
  18. biotite/database/entrez/dbnames.py +10 -0
  19. biotite/database/entrez/download.py +9 -10
  20. biotite/database/entrez/key.py +1 -1
  21. biotite/database/entrez/query.py +5 -4
  22. biotite/database/pubchem/download.py +6 -6
  23. biotite/database/pubchem/error.py +10 -0
  24. biotite/database/pubchem/query.py +12 -23
  25. biotite/database/rcsb/download.py +3 -2
  26. biotite/database/rcsb/query.py +8 -9
  27. biotite/database/uniprot/check.py +22 -17
  28. biotite/database/uniprot/download.py +3 -6
  29. biotite/database/uniprot/query.py +4 -5
  30. biotite/file.py +14 -2
  31. biotite/interface/__init__.py +19 -0
  32. biotite/interface/openmm/__init__.py +16 -0
  33. biotite/interface/openmm/state.py +93 -0
  34. biotite/interface/openmm/system.py +227 -0
  35. biotite/interface/pymol/__init__.py +198 -0
  36. biotite/interface/pymol/cgo.py +346 -0
  37. biotite/interface/pymol/convert.py +185 -0
  38. biotite/interface/pymol/display.py +267 -0
  39. biotite/interface/pymol/object.py +1226 -0
  40. biotite/interface/pymol/shapes.py +178 -0
  41. biotite/interface/pymol/startup.py +169 -0
  42. biotite/interface/rdkit/__init__.py +15 -0
  43. biotite/interface/rdkit/mol.py +490 -0
  44. biotite/interface/version.py +71 -0
  45. biotite/interface/warning.py +19 -0
  46. biotite/sequence/align/__init__.py +0 -4
  47. biotite/sequence/align/alignment.py +49 -14
  48. biotite/sequence/align/banded.cp311-win_amd64.pyd +0 -0
  49. biotite/sequence/align/banded.pyx +26 -26
  50. biotite/sequence/align/cigar.py +2 -2
  51. biotite/sequence/align/kmeralphabet.cp311-win_amd64.pyd +0 -0
  52. biotite/sequence/align/kmeralphabet.pyx +19 -2
  53. biotite/sequence/align/kmersimilarity.cp311-win_amd64.pyd +0 -0
  54. biotite/sequence/align/kmertable.cp311-win_amd64.pyd +0 -0
  55. biotite/sequence/align/kmertable.pyx +58 -48
  56. biotite/sequence/align/localgapped.cp311-win_amd64.pyd +0 -0
  57. biotite/sequence/align/localgapped.pyx +47 -47
  58. biotite/sequence/align/localungapped.cp311-win_amd64.pyd +0 -0
  59. biotite/sequence/align/localungapped.pyx +10 -10
  60. biotite/sequence/align/matrix.py +284 -57
  61. biotite/sequence/align/matrix_data/3Di.mat +24 -0
  62. biotite/sequence/align/matrix_data/PB.license +21 -0
  63. biotite/sequence/align/matrix_data/PB.mat +18 -0
  64. biotite/sequence/align/multiple.cp311-win_amd64.pyd +0 -0
  65. biotite/sequence/align/pairwise.cp311-win_amd64.pyd +0 -0
  66. biotite/sequence/align/pairwise.pyx +35 -35
  67. biotite/sequence/align/permutation.cp311-win_amd64.pyd +0 -0
  68. biotite/sequence/align/selector.cp311-win_amd64.pyd +0 -0
  69. biotite/sequence/align/selector.pyx +2 -2
  70. biotite/sequence/align/statistics.py +1 -1
  71. biotite/sequence/align/tracetable.cp311-win_amd64.pyd +0 -0
  72. biotite/sequence/alphabet.py +5 -2
  73. biotite/sequence/annotation.py +19 -13
  74. biotite/sequence/codec.cp311-win_amd64.pyd +0 -0
  75. biotite/sequence/codon.py +1 -2
  76. biotite/sequence/graphics/alignment.py +25 -39
  77. biotite/sequence/graphics/color_schemes/3di_flower.json +48 -0
  78. biotite/sequence/graphics/color_schemes/pb_flower.json +2 -1
  79. biotite/sequence/graphics/colorschemes.py +44 -11
  80. biotite/sequence/graphics/dendrogram.py +4 -2
  81. biotite/sequence/graphics/features.py +2 -2
  82. biotite/sequence/graphics/logo.py +10 -12
  83. biotite/sequence/io/fasta/convert.py +1 -2
  84. biotite/sequence/io/fasta/file.py +1 -1
  85. biotite/sequence/io/fastq/file.py +3 -3
  86. biotite/sequence/io/genbank/file.py +3 -3
  87. biotite/sequence/io/genbank/sequence.py +2 -0
  88. biotite/sequence/io/gff/convert.py +1 -1
  89. biotite/sequence/io/gff/file.py +1 -2
  90. biotite/sequence/phylo/nj.cp311-win_amd64.pyd +0 -0
  91. biotite/sequence/phylo/tree.cp311-win_amd64.pyd +0 -0
  92. biotite/sequence/phylo/upgma.cp311-win_amd64.pyd +0 -0
  93. biotite/sequence/profile.py +105 -29
  94. biotite/sequence/search.py +0 -1
  95. biotite/sequence/seqtypes.py +136 -8
  96. biotite/sequence/sequence.py +1 -2
  97. biotite/setup_ccd.py +197 -0
  98. biotite/structure/__init__.py +6 -3
  99. biotite/structure/alphabet/__init__.py +25 -0
  100. biotite/structure/alphabet/encoder.py +332 -0
  101. biotite/structure/alphabet/encoder_weights_3di.kerasify +0 -0
  102. biotite/structure/alphabet/i3d.py +109 -0
  103. biotite/structure/alphabet/layers.py +86 -0
  104. biotite/structure/alphabet/pb.license +21 -0
  105. biotite/structure/alphabet/pb.py +170 -0
  106. biotite/structure/alphabet/unkerasify.py +128 -0
  107. biotite/structure/atoms.py +163 -66
  108. biotite/structure/basepairs.py +26 -26
  109. biotite/structure/bonds.cp311-win_amd64.pyd +0 -0
  110. biotite/structure/bonds.pyx +79 -25
  111. biotite/structure/box.py +19 -21
  112. biotite/structure/celllist.cp311-win_amd64.pyd +0 -0
  113. biotite/structure/celllist.pyx +83 -67
  114. biotite/structure/chains.py +5 -37
  115. biotite/structure/charges.cp311-win_amd64.pyd +0 -0
  116. biotite/structure/compare.py +420 -13
  117. biotite/structure/density.py +1 -1
  118. biotite/structure/dotbracket.py +27 -28
  119. biotite/structure/filter.py +8 -8
  120. biotite/structure/geometry.py +74 -127
  121. biotite/structure/hbond.py +17 -19
  122. biotite/structure/info/__init__.py +1 -0
  123. biotite/structure/info/atoms.py +24 -15
  124. biotite/structure/info/bonds.py +12 -6
  125. biotite/structure/info/ccd.py +125 -34
  126. biotite/structure/info/{ccd/components.bcif → components.bcif} +0 -0
  127. biotite/structure/info/groups.py +62 -19
  128. biotite/structure/info/masses.py +9 -6
  129. biotite/structure/info/misc.py +15 -22
  130. biotite/structure/info/radii.py +92 -22
  131. biotite/structure/info/standardize.py +4 -4
  132. biotite/structure/integrity.py +4 -6
  133. biotite/structure/io/general.py +2 -2
  134. biotite/structure/io/gro/file.py +8 -9
  135. biotite/structure/io/mol/convert.py +1 -1
  136. biotite/structure/io/mol/ctab.py +33 -28
  137. biotite/structure/io/mol/mol.py +1 -1
  138. biotite/structure/io/mol/sdf.py +80 -53
  139. biotite/structure/io/pdb/convert.py +4 -3
  140. biotite/structure/io/pdb/file.py +85 -25
  141. biotite/structure/io/pdb/hybrid36.cp311-win_amd64.pyd +0 -0
  142. biotite/structure/io/pdbqt/file.py +36 -36
  143. biotite/structure/io/pdbx/__init__.py +1 -0
  144. biotite/structure/io/pdbx/bcif.py +54 -15
  145. biotite/structure/io/pdbx/cif.py +92 -66
  146. biotite/structure/io/pdbx/component.py +15 -4
  147. biotite/structure/io/pdbx/compress.py +321 -0
  148. biotite/structure/io/pdbx/convert.py +410 -75
  149. biotite/structure/io/pdbx/encoding.cp311-win_amd64.pyd +0 -0
  150. biotite/structure/io/pdbx/encoding.pyx +98 -17
  151. biotite/structure/io/trajfile.py +9 -6
  152. biotite/structure/io/util.py +38 -0
  153. biotite/structure/mechanics.py +0 -1
  154. biotite/structure/molecules.py +141 -156
  155. biotite/structure/pseudoknots.py +7 -13
  156. biotite/structure/repair.py +2 -4
  157. biotite/structure/residues.py +13 -24
  158. biotite/structure/rings.py +335 -0
  159. biotite/structure/sasa.cp311-win_amd64.pyd +0 -0
  160. biotite/structure/sasa.pyx +2 -1
  161. biotite/structure/segments.py +69 -11
  162. biotite/structure/sequence.py +0 -1
  163. biotite/structure/sse.py +0 -2
  164. biotite/structure/superimpose.py +74 -62
  165. biotite/structure/tm.py +581 -0
  166. biotite/structure/transform.py +12 -25
  167. biotite/structure/util.py +76 -4
  168. biotite/version.py +9 -4
  169. biotite/visualize.py +111 -1
  170. {biotite-1.0.1.dist-info → biotite-1.2.0.dist-info}/METADATA +6 -2
  171. {biotite-1.0.1.dist-info → biotite-1.2.0.dist-info}/RECORD +173 -143
  172. biotite/structure/info/ccd/README.rst +0 -8
  173. biotite/structure/info/ccd/amino_acids.txt +0 -1663
  174. biotite/structure/info/ccd/carbohydrates.txt +0 -1135
  175. biotite/structure/info/ccd/nucleotides.txt +0 -798
  176. {biotite-1.0.1.dist-info → biotite-1.2.0.dist-info}/WHEEL +0 -0
  177. {biotite-1.0.1.dist-info → biotite-1.2.0.dist-info}/licenses/LICENSE.rst +0 -0
@@ -0,0 +1,1226 @@
1
+ __name__ = "biotite.interface.pymol"
2
+ __author__ = "Patrick Kunzmann"
3
+ __all__ = ["PyMOLObject", "NonexistentObjectError", "ModifiedObjectError"]
4
+
5
+ import numbers
6
+ from enum import Enum
7
+ from functools import wraps
8
+ import numpy as np
9
+ import biotite.structure as struc
10
+ from biotite.interface.pymol.convert import (
11
+ from_model,
12
+ to_model,
13
+ )
14
+ from biotite.interface.pymol.startup import get_and_set_pymol_instance
15
+
16
+
17
+ def validate(method):
18
+ """
19
+ Check if the object name still exists and if the atom count has
20
+ been modified.
21
+ If this is the case, raise the appropriate exception.
22
+ """
23
+
24
+ @wraps(method)
25
+ def wrapper(self, *args, **kwargs):
26
+ self._check_existence()
27
+ if self._type == PyMOLObject.Type.MOLECULE:
28
+ new_atom_count = self._cmd.count_atoms(f"model {self._name}")
29
+ if new_atom_count != self._atom_count:
30
+ raise ModifiedObjectError(
31
+ f"The number of atoms in the object changed "
32
+ f"from the original {self._atom_count} atoms "
33
+ f" to {new_atom_count} atoms"
34
+ )
35
+ return method(self, *args, **kwargs)
36
+
37
+ return wrapper
38
+
39
+
40
+ class PyMOLObject:
41
+ """
42
+ A handle to a *PyMOL object* (*PyMOL model*), usually created by the static
43
+ :meth:`from_structure()` method.
44
+
45
+ This class conveniently provides thin wrappers around *PyMOL* commands that
46
+ allows *NumPy*-style atom indices to select atoms instead of *PyMOL* selection
47
+ expressions.
48
+ The following *PyMOL* commands are supported:
49
+
50
+ - :meth:`alter()`
51
+ - :meth:`cartoon()`
52
+ - :meth:`center()`
53
+ - :meth:`clip()`
54
+ - :meth:`color()`
55
+ - :meth:`desaturate()`
56
+ - :meth:`disable()`
57
+ - :meth:`distance()`
58
+ - :meth:`dss()`
59
+ - :meth:`enable()`
60
+ - :meth:`hide()`
61
+ - :meth:`indicate()`
62
+ - :meth:`label()`
63
+ - :meth:`orient()`
64
+ - :meth:`origin()`
65
+ - :meth:`select()`
66
+ - :meth:`set()`
67
+ - :meth:`set_bond()`
68
+ - :meth:`show()`
69
+ - :meth:`show_as()`
70
+ - :meth:`smooth()`
71
+ - :meth:`unset()`
72
+ - :meth:`unset_bond()`
73
+ - :meth:`zoom()`
74
+
75
+ Instances of this class become invalid, when atoms are added to or
76
+ are deleted from the underlying *PyMOL* object.
77
+ Calling methods of such an an invalidated object raises an
78
+ :exc:`ModifiedObjectError`.
79
+ Likewise, calling methods of an object, of which the underlying
80
+ *PyMOL* object does not exist anymore, raises an
81
+ :exc:`NonexistentObjectError`.
82
+
83
+ Parameters
84
+ ----------
85
+ name : str
86
+ The name of the *PyMOL* object.
87
+ pymol_instance : module or SingletonPyMOL or PyMOL, optional
88
+ If *PyMOL* is used in library mode, the :class:`PyMOL` or
89
+ :class:`SingletonPyMOL` object is given here.
90
+ If otherwise *PyMOL* is used in GUI mode, the :mod:`pymol` module is given.
91
+ By default the currently active *PyMOL* instance is used.
92
+ If no *PyMOL* instance is currently running, *PyMOL* is started in library mode.
93
+ delete : PyMOL, optional
94
+ If set to true, the underlying *PyMOL* object will be removed
95
+ from the *PyMOL* session, when this object is garbage collected.
96
+
97
+ Attributes
98
+ ----------
99
+ name : str
100
+ The name of the *PyMOL* object.
101
+ object_type : PyMOLObject.Type
102
+ The type of this *PyMOL* object.
103
+ """
104
+
105
+ class Type(Enum):
106
+ """
107
+ Defines what this :class:`PyMOLObject` represents.
108
+ """
109
+
110
+ MOLECULE = "object:molecule"
111
+ MAP = "object:map"
112
+ MESH = "object:mesh"
113
+ SLICE = "object:slice"
114
+ SURFACE = "object:surface"
115
+ MEASUREMENT = "object:measurement"
116
+ CGO = "object:cgo"
117
+ GROUP = "object:group"
118
+ VOLUME = "object:volume"
119
+ SELECTION = "selection"
120
+
121
+ _object_counter = 0
122
+ _color_counter = 0
123
+
124
+ def __init__(self, name, pymol_instance=None, delete=True):
125
+ self._name = name
126
+ self._pymol = get_and_set_pymol_instance(pymol_instance)
127
+ self._delete = delete
128
+ self._cmd = self._pymol.cmd
129
+ self._type = PyMOLObject.Type(self._cmd.get_type(self._name))
130
+ self._check_existence()
131
+ if self._type == PyMOLObject.Type.MOLECULE:
132
+ self._atom_count = self._cmd.count_atoms(f"%{self._name}")
133
+
134
+ def __del__(self):
135
+ if self._delete:
136
+ try:
137
+ # Try to delete this object from PyMOL
138
+ # Fails if PyMOL itself is already garbage collected
139
+ self._cmd.delete(self._name)
140
+ except Exception:
141
+ pass
142
+
143
+ @staticmethod
144
+ def from_structure(
145
+ atoms, name=None, pymol_instance=None, delete=True, delocalize_bonds=False
146
+ ):
147
+ """
148
+ Create a :class:`PyMOLObject` from an :class:`AtomArray` or
149
+ :class:`AtomArrayStack` and add it to the *PyMOL* session.
150
+
151
+ Parameters
152
+ ----------
153
+ atoms : AtomArray or AtomArrayStack
154
+ The structure to be converted.
155
+ name : str, optional
156
+ The name of the newly created *PyMOL* object.
157
+ If omitted, a unique name is generated.
158
+ pymol_instance : module or SingletonPyMOL or PyMOL, optional
159
+ If *PyMOL* is used in library mode, the :class:`PyMOL`
160
+ or :class:`SingletonPyMOL` object is given here.
161
+ If otherwise *PyMOL* is used in GUI mode, the :mod:`pymol`
162
+ module is given.
163
+ By default the currently active *PyMOL* instance is used.
164
+ If no *PyMOL* instance is currently running,
165
+ *PyMOL* is started in library mode.
166
+ delete : bool, optional
167
+ If set to true, the underlying *PyMOL* object will be
168
+ removed from the *PyMOL* session, when this object is
169
+ garbage collected.
170
+ delocalize_bonds : bool, optional
171
+ If set to true, use *PyMOL*'s delocalized bond order for aromatic bonds.
172
+ Otherwise, always use formal bond orders.
173
+
174
+ Returns
175
+ -------
176
+ pymol_object : PyMOLObject
177
+ The :class:`PyMOLObject` representing the given structure.
178
+ """
179
+ pymol_instance = get_and_set_pymol_instance(pymol_instance)
180
+ cmd = pymol_instance.cmd
181
+
182
+ if name is None:
183
+ name = f"biotite_{PyMOLObject._object_counter}"
184
+ PyMOLObject._object_counter += 1
185
+
186
+ if isinstance(atoms, struc.AtomArray) or (
187
+ isinstance(atoms, struc.AtomArrayStack) and atoms.stack_depth == 1
188
+ ):
189
+ model = to_model(atoms, delocalize_bonds)
190
+ cmd.load_model(model, name)
191
+ elif isinstance(atoms, struc.AtomArrayStack):
192
+ # Use first model as template
193
+ model = to_model(atoms[0])
194
+ cmd.load_model(model, name)
195
+ # Append states corresponding to all following models
196
+ for coord in atoms.coord[1:]:
197
+ cmd.load_coordset(coord, name)
198
+ else:
199
+ raise TypeError("Expected 'AtomArray' or 'AtomArrayStack'")
200
+
201
+ return PyMOLObject(name, pymol_instance, delete)
202
+
203
+ def to_structure(self, state=None, altloc="first", include_bonds=False):
204
+ """
205
+ Convert this object into an :class:`AtomArray` or
206
+ :class:`AtomArrayStack`.
207
+
208
+ The returned :class:`AtomArray` contains the optional annotation
209
+ categories ``b_factor``, ``occupancy`` and ``charge``.
210
+
211
+ Parameters
212
+ ----------
213
+ state : int, optional
214
+ If this parameter is given, the function will return an
215
+ :class:`AtomArray` corresponding to the given state of the
216
+ *PyMOL* object.
217
+ If this parameter is omitted, an :class:`AtomArrayStack`
218
+ containing all states will be returned, even if the *PyMOL*
219
+ object contains only one state.
220
+ altloc : {'first', 'occupancy', 'all'}
221
+ This parameter defines how *altloc* IDs are handled:
222
+
223
+ - ``'first'`` - Use atoms that have the first
224
+ *altloc* ID appearing in a residue.
225
+ - ``'occupancy'`` - Use atoms that have the *altloc* ID
226
+ with the highest occupancy for a residue.
227
+ - ``'all'`` - Use all atoms.
228
+ Note that this leads to duplicate atoms.
229
+ When this option is chosen, the ``altloc_id``
230
+ annotation array is added to the returned structure.
231
+
232
+ include_bonds : bool, optional
233
+ If set to true, an associated :class:`BondList` will be created
234
+ for the returned structure.
235
+
236
+ Returns
237
+ -------
238
+ structure : AtomArray or AtomArrayStack
239
+ The converted structure.
240
+ Whether an :class:`AtomArray` or :class:`AtomArrayStack` is
241
+ returned depends on the `state` parameter.
242
+ """
243
+ if state is None:
244
+ model = self._cmd.get_model(self._name, state=1)
245
+ template = from_model(model, include_bonds)
246
+ expected_length = None
247
+ coord = []
248
+ for i in range(self._cmd.count_states(self._name)):
249
+ state_coord = self._cmd.get_coordset(self._name, state=i + 1)
250
+ if expected_length is None:
251
+ expected_length = len(state_coord)
252
+ elif len(state_coord) != expected_length:
253
+ raise ValueError("The models have different numbers of atoms")
254
+ coord.append(state_coord)
255
+ coord = np.stack(coord)
256
+ structure = struc.from_template(template, coord)
257
+
258
+ else:
259
+ model = self._cmd.get_model(self._name, state=state)
260
+ structure = from_model(model, include_bonds)
261
+
262
+ # Filter altloc IDs and return
263
+ if altloc == "occupancy":
264
+ structure = structure[
265
+ ...,
266
+ struc.filter_highest_occupancy_altloc(
267
+ structure, structure.altloc_id, structure.occupancy
268
+ ),
269
+ ]
270
+ structure.del_annotation("altloc_id")
271
+ return structure
272
+ elif altloc == "first":
273
+ structure = structure[
274
+ ..., struc.filter_first_altloc(structure, structure.altloc_id)
275
+ ]
276
+ structure.del_annotation("altloc_id")
277
+ return structure
278
+ elif altloc == "all":
279
+ return structure
280
+ else:
281
+ raise ValueError(f"'{altloc}' is not a valid 'altloc' option")
282
+
283
+ @property
284
+ def name(self):
285
+ return self._name
286
+
287
+ @property
288
+ def object_type(self):
289
+ return self._type
290
+
291
+ def exists(self):
292
+ """
293
+ Check whether the underlying *PyMOL* object still exists.
294
+
295
+ Returns
296
+ -------
297
+ bool
298
+ True if the *PyMOL* session contains an object with the name
299
+ of this :class:`PyMOLObject`, false otherwise.
300
+ """
301
+ return self._name in self._cmd.get_names("all", enabled_only=False)
302
+
303
+ def _check_existence(self):
304
+ if not self.exists():
305
+ raise NonexistentObjectError(
306
+ f"A PyMOL object with the name {self._name} does not exist anymore"
307
+ )
308
+
309
+ @validate
310
+ def where(self, index):
311
+ """
312
+ Convert a *Biotite*-compatible atom selection index
313
+ (integer, slice, boolean mask, index array) into a *PyMOL*
314
+ selection expression.
315
+
316
+ Parameters
317
+ ----------
318
+ index : int or slice or ndarray, dtype=bool or ndarray, dtype=int
319
+ The boolean mask to be converted into a selection string.
320
+
321
+ Returns
322
+ -------
323
+ expression : str
324
+ A *PyMOL* compatible selection expression.
325
+ """
326
+ if self._type != PyMOLObject.Type.MOLECULE:
327
+ raise TypeError(
328
+ "Can only create atom selection strings "
329
+ "for PyMOL objects representing molecules"
330
+ )
331
+
332
+ if isinstance(index, numbers.Integral):
333
+ # PyMOLs indexing starts at 1
334
+ return f"%{self._name} and index {index}"
335
+
336
+ elif isinstance(index, np.ndarray) and index.dtype == bool:
337
+ mask = index
338
+ if len(mask) != self._atom_count:
339
+ raise IndexError(
340
+ f"Mask has length {len(mask)}, but the number of "
341
+ f"atoms in the PyMOL model is {self._atom_count}"
342
+ )
343
+
344
+ else:
345
+ # Convert any other index type into a boolean mask
346
+ mask = np.zeros(self._atom_count, dtype=bool)
347
+ mask[index] = True
348
+
349
+ # Indices where the mask changes from True to False
350
+ # or from False to True
351
+ # The '+1' makes each index refer to the position
352
+ # after the change i.e. the new value
353
+ changes = np.where(np.diff(mask))[0] + 1
354
+ # If first element is True, insert index 0 at start
355
+ # -> the first change is always from False to True
356
+ if mask[0]:
357
+ changes = np.concatenate(([0], changes))
358
+ # If the last element is True, insert append length of mask
359
+ # as exclusive stop index
360
+ # -> the last change is always from True to False
361
+ if mask[-1]:
362
+ changes = np.concatenate((changes, [len(mask)]))
363
+ # -> Changes are alternating (F->T, T->F, F->T, ..., F->T, T->F)
364
+ # Reshape into pairs ([F->T, T->F], [F->T, T->F], ...)
365
+ # -> these are the intervals where the mask is True
366
+ intervals = np.reshape(changes, (-1, 2))
367
+
368
+ if len(intervals) > 0:
369
+ # Convert interval into selection string
370
+ # Two things to note:
371
+ # - PyMOLs indexing starts at 1-> 'start+1'
372
+ # - Stop in 'intervals' is exclusive -> 'stop+1-1' -> 'stop'
373
+ index_selection = " or ".join(
374
+ [f"index {start + 1}-{stop}" for start, stop in intervals]
375
+ )
376
+ # Constrain the selection to given object name
377
+ return f"%{self._name} and ({index_selection})"
378
+ else:
379
+ return "none"
380
+
381
+ def _into_selection(self, selection, not_none=False):
382
+ """
383
+ Turn a boolean mask into a *PyMOL* selection expression or
384
+ restrict an selection expression to the current *PyMOL* object.
385
+ """
386
+ if selection is None:
387
+ return f"%{self._name}"
388
+ elif isinstance(selection, str):
389
+ return f"%{self._name} and ({selection})"
390
+ else:
391
+ sel = self.where(np.asarray(selection))
392
+ if sel == "none" and not_none:
393
+ raise ValueError("Selection contains no atoms")
394
+ return sel
395
+
396
+ @validate
397
+ def alter(self, selection, expression):
398
+ """
399
+ Change atomic properties using an expression evaluated
400
+ within a temporary namespace for each atom.
401
+
402
+ This method is a thin wrapper around the *PyMOL* ``alter()``
403
+ command.
404
+
405
+ Parameters
406
+ ----------
407
+ selection : str or int or slice or ndarray, dtype=bool or ndarray, dtype=int
408
+ A *Biotite* compatible atom selection index,
409
+ e.g. a boolean mask, or a *PyMOL* selection expression that
410
+ selects the atoms of this *PyMOL* object to apply the
411
+ command on.
412
+ expression : str
413
+ The properties of the selected atoms are changed based on
414
+ this expression.
415
+ """
416
+ self._cmd.alter(self._into_selection(selection), expression)
417
+
418
+ @validate
419
+ def cartoon(self, type, selection=None):
420
+ """
421
+ Change the default cartoon representation for a selection
422
+ of atoms.
423
+
424
+ This method is a thin wrapper around the *PyMOL* ``cartoon()``
425
+ command.
426
+
427
+ Parameters
428
+ ----------
429
+ type : str
430
+ One of
431
+
432
+ - ``'automatic'``,
433
+ - ``'skip'``,
434
+ - ``'loop'``,
435
+ - ``'rectangle'``,
436
+ - ``'oval'``,
437
+ - ``'tube'``,
438
+ - ``'arrow'`` or
439
+ - ``'dumbbell'``.
440
+
441
+ selection : str or int or slice or ndarray, dtype=bool or ndarray, dtype=int
442
+ A *Biotite* compatible atom selection index,
443
+ e.g. a boolean mask, or a *PyMOL* selection expression that
444
+ selects the atoms of this *PyMOL* object to apply the
445
+ command on.
446
+ By default, the command is applied on all atoms of this
447
+ *PyMOL* object.
448
+ """
449
+ self._cmd.cartoon(type, self._into_selection(selection))
450
+
451
+ @validate
452
+ def center(self, selection=None, state=None, origin=True):
453
+ """
454
+ Translate the window, the clipping slab, and the
455
+ origin to a point centered within the atom selection.
456
+
457
+ This method is a thin wrapper around the *PyMOL* ``center()``
458
+ command.
459
+
460
+ Parameters
461
+ ----------
462
+ selection : str or int or slice or ndarray, dtype=bool or ndarray, dtype=int, optional
463
+ A *Biotite* compatible atom selection index,
464
+ e.g. a boolean mask, or a *PyMOL* selection expression that
465
+ selects the atoms of this *PyMOL* object to apply the
466
+ command on.
467
+ By default, the command is applied on all atoms of this
468
+ *PyMOL* object.
469
+ state : int, optional
470
+ The state to apply the command on.
471
+ By default, the command is applied on all states of this
472
+ *PyMOL* object.
473
+ origin : bool, optional
474
+ If set to false, the origin is left unchanged.
475
+ """
476
+ state = 0 if state is None else state
477
+ self._cmd.center(self._into_selection(selection), state, int(origin))
478
+
479
+ @validate
480
+ def clip(self, mode, distance, selection=None, state=None):
481
+ """
482
+ Alter the positions of the near and far clipping planes.
483
+
484
+ This method is a thin wrapper around the *PyMOL* ``clip()``
485
+ command.
486
+
487
+ Parameters
488
+ ----------
489
+ mode : {'near', 'far', 'move', 'slab', 'atoms'}
490
+
491
+ - ``near`` - Move the near plane
492
+ - ``far`` - Move the far plane
493
+ - ``move`` - Move slab
494
+ - ``slab`` - Set slab thickness
495
+ - ``atoms`` - clip selected atoms with the given buffer
496
+
497
+ distance : float
498
+ The meaning of this parameter depends on `mode`.
499
+ selection : str or int or slice or ndarray, dtype=bool or ndarray, dtype=int, optional
500
+ A *Biotite* compatible atom selection index,
501
+ e.g. a boolean mask, or a *PyMOL* selection expression that
502
+ selects the atoms of this *PyMOL* object to apply the
503
+ command on.
504
+ By default, the command is applied on all atoms of this
505
+ *PyMOL* object.
506
+ state : int, optional
507
+ The state to apply the command on.
508
+ By default, the command is applied on all states of this
509
+ *PyMOL* object.
510
+ """
511
+ state = 0 if state is None else state
512
+ self._cmd.clip(mode, distance, self._into_selection(selection), state)
513
+
514
+ @validate
515
+ def color(self, color, selection=None, representation=None):
516
+ """
517
+ Change the color of atoms.
518
+
519
+ This method is a thin wrapper around the *PyMOL* ``color()``
520
+ or ``set("xxx_color")`` command.
521
+
522
+ Parameters
523
+ ----------
524
+ color : str or tuple(float, float, float)
525
+ Either a *PyMOL* color name or a tuple containing an RGB
526
+ value (0.0 to 1.0).
527
+ selection : str or int or slice or ndarray, dtype=bool or ndarray, dtype=int, optional
528
+ A *Biotite* compatible atom selection index,
529
+ e.g. a boolean mask, or a *PyMOL* selection expression that
530
+ selects the atoms of this *PyMOL* object to apply the
531
+ command on.
532
+ By default, the command is applied on all atoms of this
533
+ *PyMOL* object.
534
+ representation : {"sphere", "surface", "mesh", "dot", "cartoon", "ribbon"}, optional
535
+ Colors only the given representation by internally calling
536
+ ``set("xxx_color")``.
537
+ By default, all representations are affected, i.e. ``color()``
538
+ is called internally.
539
+
540
+ Notes
541
+ -----
542
+ If an RGB color is given, the color is registered as a unique
543
+ named color via the ``set_color()`` command.
544
+ """
545
+ if not isinstance(color, str):
546
+ color_name = f"biotite_color_{PyMOLObject._color_counter}"
547
+ PyMOLObject._color_counter += 1
548
+ self._cmd.set_color(color_name, tuple(color))
549
+ else:
550
+ color_name = color
551
+ registered = [name for name, _ in self._cmd.get_color_indices()]
552
+ if color_name not in registered:
553
+ raise ValueError(f"Unknown color '{color_name}'")
554
+
555
+ if representation is None:
556
+ self._cmd.color(color_name, self._into_selection(selection))
557
+ else:
558
+ if representation not in (
559
+ "sphere",
560
+ "surface",
561
+ "mesh",
562
+ "dot",
563
+ "cartoon",
564
+ "ribbon",
565
+ ):
566
+ raise ValueError(
567
+ f"'{representation}' is not a supported representation"
568
+ )
569
+ self._cmd.set(
570
+ f"{representation}_color", color_name, self._into_selection(selection)
571
+ )
572
+
573
+ @validate
574
+ def surface_color(self, color, selection=None):
575
+ """
576
+ Change the color of displayed surfaces.
577
+
578
+ This method is a thin wrapper around *PyMOL*
579
+ ``set("surface_color")``.
580
+
581
+ Parameters
582
+ ----------
583
+ color : str or tuple(float, float, float)
584
+ Either a *PyMOL* color name or a tuple containing an RGB
585
+ value (0.0 to 1.0).
586
+ selection : str or int or slice or ndarray, dtype=bool or ndarray, dtype=int, optional
587
+ A *Biotite* compatible atom selection index,
588
+ e.g. a boolean mask, or a *PyMOL* selection expression that
589
+ selects the atoms of this *PyMOL* object to apply the
590
+ command on.
591
+ By default, the command is applied on all atoms of this
592
+ *PyMOL* object.
593
+
594
+ Notes
595
+ -----
596
+ If an RGB color is given, the color is registered as a unique
597
+ named color via the ``set_color()`` command.
598
+ """
599
+ color_name = self._created_named_color(color)
600
+ self._cmd.set("surface_color", color_name, self._into_selection(selection))
601
+
602
+ @validate
603
+ def desaturate(self, selection=None, a=0.5):
604
+ """
605
+ Desaturate the colors of the selected atoms.
606
+
607
+ This method is a thin wrapper around the *PyMOL*
608
+ ``desaturate()`` command.
609
+
610
+ Parameters
611
+ ----------
612
+ selection : str or int or slice or ndarray, dtype=bool or ndarray, dtype=int, optional
613
+ A *Biotite* compatible atom selection index,
614
+ e.g. a boolean mask, or a *PyMOL* selection expression that
615
+ selects the atoms of this *PyMOL* object to apply the
616
+ command on.
617
+ By default, the command is applied on all atoms of this
618
+ *PyMOL* object.
619
+ a : float
620
+ A desaturation factor between 0.0 and 1.0.
621
+ """
622
+ self._cmd.desaturate(self._into_selection(selection), a)
623
+
624
+ @validate
625
+ def disable(self, selection=None):
626
+ """
627
+ Turn off display of the selected atoms.
628
+
629
+ This method is a thin wrapper around the *PyMOL* ``disable()``
630
+ command.
631
+
632
+ Parameters
633
+ ----------
634
+ selection : str or int or slice or ndarray, dtype=bool or ndarray, dtype=int, optional
635
+ A *Biotite* compatible atom selection index,
636
+ e.g. a boolean mask, or a *PyMOL* selection expression that
637
+ selects the atoms of this *PyMOL* object to apply the
638
+ command on.
639
+ By default, the command is applied on all atoms of this
640
+ *PyMOL* object.
641
+ """
642
+ self._cmd.disable(self._into_selection(selection))
643
+
644
+ @validate
645
+ def distance(
646
+ self,
647
+ name,
648
+ selection1,
649
+ selection2,
650
+ cutoff=None,
651
+ mode=None,
652
+ show_label=True,
653
+ width=None,
654
+ length=None,
655
+ gap=None,
656
+ ):
657
+ """
658
+ Create a new distance object between two atom selections.
659
+
660
+ This method is a thin wrapper around the *PyMOL* ``distance()``
661
+ command.
662
+
663
+ Parameters
664
+ ----------
665
+ name : str
666
+ Name of the distance object to create.
667
+ selection1, selection2 : str or int or slice or ndarray, dtype=bool or ndarray, dtype=int, optional
668
+ A *Biotite* compatible atom selection index,
669
+ e.g. a boolean mask, or a *PyMOL* selection expression that
670
+ selects the atoms of this *PyMOL* object to apply the
671
+ command on.
672
+ cutoff : float, optional
673
+ The longest distance to show.
674
+ mode : {0, 1, 2, 3, 4}, optional
675
+
676
+ - ``0`` - All interatomic distances
677
+ - ``1`` - Only bond distances
678
+ - ``2`` - Only polar contact distances
679
+ - ``3`` - All interatomic distances,
680
+ use distance_exclusion setting
681
+ - ``4`` - Distance between centroids
682
+
683
+ show_label : bool, optional
684
+ Whether to show the distance as label.
685
+ width, length, gap : float optional
686
+ The width and length of each dash and the gap length between
687
+ the dashes.
688
+ """
689
+ self._cmd.distance(
690
+ name,
691
+ self._into_selection(selection1),
692
+ self._into_selection(selection2),
693
+ cutoff,
694
+ mode,
695
+ label=int(show_label),
696
+ width=width,
697
+ length=length,
698
+ gap=gap,
699
+ )
700
+
701
+ @validate
702
+ def dss(self, selection=None, state=None):
703
+ """
704
+ Determine the secondary structure of the selected atoms.
705
+
706
+ This method is a thin wrapper around the *PyMOL* ``dss()``
707
+ command.
708
+
709
+ Parameters
710
+ ----------
711
+ selection : str or int or slice or ndarray, dtype=bool or ndarray, dtype=int, optional
712
+ A *Biotite* compatible atom selection index,
713
+ e.g. a boolean mask, or a *PyMOL* selection expression that
714
+ selects the atoms of this *PyMOL* object to apply the
715
+ command on.
716
+ By default, the command is applied on all atoms of this
717
+ *PyMOL* object.
718
+ state : int, optional
719
+ The state to apply the command on.
720
+ By default, the command is applied on all states of this
721
+ *PyMOL* object.
722
+ """
723
+ state = 0 if state is None else state
724
+ self._cmd.dss(self._into_selection(selection), state)
725
+
726
+ @validate
727
+ def enable(self, selection=None):
728
+ """
729
+ Turn on display of the selected atoms.
730
+
731
+ This method is a thin wrapper around the *PyMOL* ``enable()``
732
+ command.
733
+
734
+ Parameters
735
+ ----------
736
+ selection : str or int or slice or ndarray, dtype=bool or ndarray, dtype=int, optional
737
+ A *Biotite* compatible atom selection index,
738
+ e.g. a boolean mask, or a *PyMOL* selection expression that
739
+ selects the atoms of this *PyMOL* object to apply the
740
+ command on.
741
+ By default, the command is applied on all atoms of this
742
+ *PyMOL* object.
743
+ """
744
+ self._cmd.enable(self._into_selection(selection))
745
+
746
+ @validate
747
+ def hide(self, representation, selection=None):
748
+ """
749
+ Turn off an atom representation (e.g. sticks, spheres, etc.).
750
+
751
+ This method is a thin wrapper around the *PyMOL* ``hide()``
752
+ command.
753
+
754
+ Parameters
755
+ ----------
756
+ representation : str
757
+ One of
758
+
759
+ - ``'lines'``,
760
+ - ``'spheres'``,
761
+ - ``'mesh'``,
762
+ - ``'ribbon'``,
763
+ - ``'cartoon'``,
764
+ - ``'sticks'``,
765
+ - ``'dots'``,
766
+ - ``'surface'``,
767
+ - ``'label'``,
768
+ - ``'extent'``,
769
+ - ``'nonbonded'``,
770
+ - ``'nb_spheres'``,
771
+ - ``'slice'`` or
772
+ - ``'cell'``.
773
+
774
+ selection : str or int or slice or ndarray, dtype=bool or ndarray, dtype=int, optional
775
+ A *Biotite* compatible atom selection index,
776
+ e.g. a boolean mask, or a *PyMOL* selection expression that
777
+ selects the atoms of this *PyMOL* object to apply the
778
+ command on.
779
+ By default, the command is applied on all atoms of this
780
+ *PyMOL* object.
781
+ """
782
+ self._cmd.hide(representation, self._into_selection(selection))
783
+
784
+ @validate
785
+ def indicate(self, selection=None):
786
+ """
787
+ Show a visual representation of the selected atoms.
788
+
789
+ This method is a thin wrapper around the *PyMOL* ``indicate()``
790
+ command.
791
+
792
+ Parameters
793
+ ----------
794
+ selection : str or int or slice or ndarray, dtype=bool or ndarray, dtype=int, optional
795
+ A *Biotite* compatible atom selection index,
796
+ e.g. a boolean mask, or a *PyMOL* selection expression that
797
+ selects the atoms of this *PyMOL* object to apply the
798
+ command on.
799
+ By default, the command is applied on all atoms of this
800
+ *PyMOL* object.
801
+ """
802
+ self._cmd.indicate(self._into_selection(selection))
803
+
804
+ @validate
805
+ def label(self, selection, text):
806
+ """
807
+ Label the selected atoms.
808
+
809
+ This method is a thin wrapper around the *PyMOL* ``label()``
810
+ command.
811
+
812
+ Parameters
813
+ ----------
814
+ selection : str or int or slice or ndarray, dtype=bool or ndarray, dtype=int
815
+ A *Biotite* compatible atom selection index,
816
+ e.g. a boolean mask, or a *PyMOL* selection expression that
817
+ selects the atoms of this *PyMOL* object to apply the
818
+ command on.
819
+ text : str
820
+ The label text.
821
+ """
822
+ self._cmd.label(self._into_selection(selection), f'"{text}"')
823
+
824
+ @validate
825
+ def orient(self, selection=None, state=None):
826
+ """
827
+ Align the principal components of the selected atoms with the
828
+ *xyz* axes.
829
+
830
+ This method is a thin wrapper around the *PyMOL* ``orient()``
831
+ command.
832
+
833
+ Parameters
834
+ ----------
835
+ selection : str or int or slice or ndarray, dtype=bool or ndarray, dtype=int, optional
836
+ A *Biotite* compatible atom selection index,
837
+ e.g. a boolean mask, or a *PyMOL* selection expression that
838
+ selects the atoms of this *PyMOL* object to apply the
839
+ command on.
840
+ By default, the command is applied on all atoms of this
841
+ *PyMOL* object.
842
+ state : int, optional
843
+ The state to apply the command on.
844
+ By default, the command is applied on all states of this
845
+ *PyMOL* object.
846
+ """
847
+ state = 0 if state is None else state
848
+ self._cmd.orient(self._into_selection(selection, True), state)
849
+
850
+ @validate
851
+ def origin(self, selection=None, state=None):
852
+ """
853
+ Set the center of rotation about the selected atoms.
854
+
855
+ This method is a thin wrapper around the *PyMOL* ``origin()``
856
+ command.
857
+
858
+ Parameters
859
+ ----------
860
+ selection : str or int or slice or ndarray, dtype=bool or ndarray, dtype=int, optional
861
+ A *Biotite* compatible atom selection index,
862
+ e.g. a boolean mask, or a *PyMOL* selection expression that
863
+ selects the atoms of this *PyMOL* object to apply the
864
+ command on.
865
+ By default, the command is applied on all atoms of this
866
+ *PyMOL* object.
867
+ state : int, optional
868
+ The state to apply the command on.
869
+ By default, the command is applied on all states of this
870
+ *PyMOL* object.
871
+ """
872
+ state = 0 if state is None else state
873
+ self._cmd.origin(selection=self._into_selection(selection), state=state)
874
+
875
+ @validate
876
+ def select(self, name, selection=None):
877
+ """
878
+ Create a named selection object from the selected atoms.
879
+
880
+ This method is a thin wrapper around the *PyMOL* ``select()``
881
+ command.
882
+
883
+ Parameters
884
+ ----------
885
+ name : str
886
+ Name of the selection object to create.
887
+ selection : str or int or slice or ndarray, dtype=bool or ndarray, dtype=int, optional
888
+ A *Biotite* compatible atom selection index,
889
+ e.g. a boolean mask, or a *PyMOL* selection expression that
890
+ selects the atoms of this *PyMOL* object to apply the
891
+ command on.
892
+ By default, the command is applied on all atoms of this
893
+ *PyMOL* object.
894
+ """
895
+ self._cmd.select(name, self._into_selection(selection))
896
+
897
+ @validate
898
+ def set(self, name, value, selection=None, state=None):
899
+ """
900
+ Change per-atom settings.
901
+
902
+ This method is a thin wrapper around the *PyMOL* ``set()``
903
+ command.
904
+
905
+ Parameters
906
+ ----------
907
+ name : str
908
+ The name of the setting to be changed.
909
+ One of
910
+
911
+ - ``'sphere_color'``,
912
+ - ``'surface_color'``,
913
+ - ``'mesh_color'``,
914
+ - ``'label_color'``,
915
+ - ``'dot_color'``,
916
+ - ``'cartoon_color'``,
917
+ - ``'ribbon_color'``,
918
+ - ``'transparency'`` (for surfaces) or
919
+ - ``'sphere_transparency'``.
920
+
921
+ value : object
922
+ The new value for the given setting name.
923
+ selection : str or int or slice or ndarray, dtype=bool or ndarray, dtype=int, optional
924
+ A *Biotite* compatible atom selection index,
925
+ e.g. a boolean mask, or a *PyMOL* selection expression that
926
+ selects the atoms of this *PyMOL* object to apply the
927
+ command on.
928
+ By default, the command is applied on all atoms of this
929
+ *PyMOL* object.
930
+ state : int, optional
931
+ The state to apply the command on.
932
+ By default, the command is applied on all states of this
933
+ *PyMOL* object.
934
+ """
935
+ state = 0 if state is None else state
936
+ self._cmd.set(name, value, self._into_selection(selection), state)
937
+
938
+ @validate
939
+ def set_bond(self, name, value, selection1=None, selection2=None, state=None):
940
+ """
941
+ Change per-bond settings for all bonds which exist
942
+ between two atom selections.
943
+
944
+ This method is a thin wrapper around the *PyMOL* ``set_bond()``
945
+ command.
946
+
947
+ Parameters
948
+ ----------
949
+ name : str
950
+ The name of the setting to be changed.
951
+ One of
952
+
953
+ - ``'valence'``,
954
+ - ``'line_width'``,
955
+ - ``'line_color'``,
956
+ - ``'stick_radius'``,
957
+ - ``'stick_color'`` or
958
+ - ``'stick_transparency'``.
959
+
960
+ value : object
961
+ The new value for the given setting name.
962
+ selection1, selection2 : str or int or slice or ndarray, dtype=bool or ndarray, dtype=int, optional
963
+ A *Biotite* compatible atom selection index,
964
+ e.g. a boolean mask, or a *PyMOL* selection expression that
965
+ selects the atoms of this *PyMOL* object to apply the
966
+ command on.
967
+ By default, `selection1` applies to all atoms of this
968
+ *PyMOL* object and `selection2` applies to the same atoms as
969
+ `selection1`.
970
+ state : int, optional
971
+ The state to apply the command on.
972
+ By default, the command is applied on all states of this
973
+ *PyMOL* object.
974
+ """
975
+ state = 0 if state is None else state
976
+ selection2 = selection1 if selection2 is None else selection2
977
+ self._cmd.set_bond(
978
+ name,
979
+ value,
980
+ self._into_selection(selection1),
981
+ self._into_selection(selection2),
982
+ state,
983
+ )
984
+
985
+ @validate
986
+ def show(self, representation, selection=None):
987
+ """
988
+ Turn on an atom representation (e.g. sticks, spheres, etc.).
989
+
990
+ This method is a thin wrapper around the *PyMOL* ``show()``
991
+ command.
992
+
993
+ Parameters
994
+ ----------
995
+ representation : str
996
+ One of
997
+
998
+ - ``'lines'``,
999
+ - ``'spheres'``,
1000
+ - ``'mesh'``,
1001
+ - ``'ribbon'``,
1002
+ - ``'cartoon'``,
1003
+ - ``'sticks'``,
1004
+ - ``'dots'``,
1005
+ - ``'surface'``,
1006
+ - ``'label'``,
1007
+ - ``'extent'``,
1008
+ - ``'nonbonded'``,
1009
+ - ``'nb_spheres'``,
1010
+ - ``'slice'`` or
1011
+ - ``'cell'``.
1012
+
1013
+ selection : str or int or slice or ndarray, dtype=bool or ndarray, dtype=int, optional
1014
+ A *Biotite* compatible atom selection index,
1015
+ e.g. a boolean mask, or a *PyMOL* selection expression that
1016
+ selects the atoms of this *PyMOL* object to apply the
1017
+ command on.
1018
+ By default, the command is applied on all atoms of this
1019
+ *PyMOL* object.
1020
+ """
1021
+ self._cmd.show(representation, self._into_selection(selection))
1022
+
1023
+ @validate
1024
+ def show_as(self, representation, selection=None):
1025
+ """
1026
+ Turn on a representation (e.g. sticks, spheres, etc.) and hide
1027
+ all other representations.
1028
+
1029
+ This method is a thin wrapper around the *PyMOL* ``show_as()``
1030
+ command.
1031
+
1032
+ Parameters
1033
+ ----------
1034
+ representation : str
1035
+ One of
1036
+
1037
+ - ``'lines'``,
1038
+ - ``'spheres'``,
1039
+ - ``'mesh'``,
1040
+ - ``'ribbon'``,
1041
+ - ``'cartoon'``,
1042
+ - ``'sticks'``,
1043
+ - ``'dots'``,
1044
+ - ``'surface'``,
1045
+ - ``'label'``,
1046
+ - ``'extent'``,
1047
+ - ``'nonbonded'``,
1048
+ - ``'nb_spheres'``,
1049
+ - ``'slice'`` or
1050
+ - ``'cell'``.
1051
+
1052
+ selection : str or int or slice or ndarray, dtype=bool or ndarray, dtype=int, optional
1053
+ A *Biotite* compatible atom selection index,
1054
+ e.g. a boolean mask, or a *PyMOL* selection expression that
1055
+ selects the atoms of this *PyMOL* object to apply the
1056
+ command on.
1057
+ By default, the command is applied on all atoms of this
1058
+ *PyMOL* object.
1059
+ """
1060
+ self._cmd.show_as(representation, self._into_selection(selection))
1061
+
1062
+ @validate
1063
+ def smooth(self, selection=None, passes=1, window=5, first=1, last=0, ends=False):
1064
+ """
1065
+ Perform a moving average over the coordinate states.
1066
+
1067
+ This method is a thin wrapper around the *PyMOL* ``smooth()``
1068
+ command.
1069
+
1070
+ Parameters
1071
+ ----------
1072
+ selection : str or int or slice or ndarray, dtype=bool or ndarray, dtype=int, optional
1073
+ A *Biotite* compatible atom selection index,
1074
+ e.g. a boolean mask, or a *PyMOL* selection expression that
1075
+ selects the atoms of this *PyMOL* object to apply the
1076
+ command on.
1077
+ By default, the command is applied on all atoms of this
1078
+ *PyMOL* object.
1079
+ passes : int, optional
1080
+ The number of smoothing passes.
1081
+ window : int, optional
1082
+ The size of the moving window.
1083
+ first, last : int, optional
1084
+ The interval of states to smooth.
1085
+ ends : bool, optional
1086
+ If set to true, the end states are also smoothed using a
1087
+ weighted asymmetric window.
1088
+ """
1089
+ self._cmd.smooth(
1090
+ self._into_selection(selection), passes, window, first, last, int(ends)
1091
+ )
1092
+
1093
+ # TODO: def spectrum()
1094
+
1095
+ @validate
1096
+ def unset(self, name, selection=None, state=None):
1097
+ """
1098
+ Clear per-atom settings.
1099
+
1100
+ This method is a thin wrapper around the *PyMOL* ``set()``
1101
+ command.
1102
+
1103
+ Parameters
1104
+ ----------
1105
+ name : str
1106
+ The name of the setting to be cleared.
1107
+ One of
1108
+
1109
+ - ``'sphere_color'``,
1110
+ - ``'surface_color'``,
1111
+ - ``'mesh_color'``,
1112
+ - ``'label_color'``,
1113
+ - ``'dot_color'``,
1114
+ - ``'cartoon_color'``,
1115
+ - ``'ribbon_color'``,
1116
+ - ``'transparency'`` (for surfaces) or
1117
+ - ``'sphere_transparency'``.
1118
+
1119
+ selection : str or int or slice or ndarray, dtype=bool or ndarray, dtype=int, optional
1120
+ A *Biotite* compatible atom selection index,
1121
+ e.g. a boolean mask, or a *PyMOL* selection expression that
1122
+ selects the atoms of this *PyMOL* object to apply the
1123
+ command on.
1124
+ By default, the command is applied on all atoms of this
1125
+ *PyMOL* object.
1126
+ state : int, optional
1127
+ The state to apply the command on.
1128
+ By default, the command is applied on all states of this
1129
+ *PyMOL* object.
1130
+ """
1131
+ state = 0 if state is None else state
1132
+ self._cmd.unset(name, self._into_selection(selection), state)
1133
+
1134
+ @validate
1135
+ def unset_bond(self, name, selection1=None, selection2=None, state=None):
1136
+ """
1137
+ Clear per-bond settings for all bonds which exist
1138
+ between two atom selections.
1139
+
1140
+ This method is a thin wrapper around the *PyMOL* ``unset_bond()``
1141
+ command.
1142
+
1143
+ Parameters
1144
+ ----------
1145
+ name : str
1146
+ The name of the setting to be cleared.
1147
+ One of
1148
+
1149
+ - ``'valence'``,
1150
+ - ``'line_width'``,
1151
+ - ``'line_color'``,
1152
+ - ``'stick_radius'``,
1153
+ - ``'stick_color'`` or
1154
+ - ``'stick_transparency'``.
1155
+
1156
+ selection1, selection2 : str or int or slice or ndarray, dtype=bool or ndarray, dtype=int, optional
1157
+ A *Biotite* compatible atom selection index,
1158
+ e.g. a boolean mask, or a *PyMOL* selection expression that
1159
+ selects the atoms of this *PyMOL* object to apply the
1160
+ command on.
1161
+ By default, `selection1` applies to all atoms of this
1162
+ *PyMOL* object and `selection2` applies to the same atoms as
1163
+ `selection1`.
1164
+ state : int, optional
1165
+ The state to apply the command on.
1166
+ By default, the command is applied on all states of this
1167
+ *PyMOL* object.
1168
+ """
1169
+ state = 0 if state is None else state
1170
+ selection2 = selection1 if selection2 is None else selection2
1171
+ self._cmd.unset_bond(
1172
+ name,
1173
+ self._into_selection(selection1),
1174
+ self._into_selection(selection2),
1175
+ state,
1176
+ )
1177
+
1178
+ @validate
1179
+ def zoom(self, selection=None, buffer=0.0, state=None, complete=False):
1180
+ """
1181
+ Scale and translate the window and the origin to cover the
1182
+ selected atoms.
1183
+
1184
+ This method is a thin wrapper around the *PyMOL* ``zoom()``
1185
+ command.
1186
+
1187
+ Parameters
1188
+ ----------
1189
+ selection : str or int or slice or ndarray, dtype=bool or ndarray, dtype=int, optional
1190
+ A *Biotite* compatible atom selection index,
1191
+ e.g. a boolean mask, or a *PyMOL* selection expression that
1192
+ selects the atoms of this *PyMOL* object to apply the
1193
+ command on.
1194
+ By default, the command is applied on all atoms of this
1195
+ *PyMOL* object.
1196
+ buffer : float, optional
1197
+ An additional distance to the calculated camera position.
1198
+ state : int, optional
1199
+ The state to apply the command on.
1200
+ By default, the command is applied on all states of this
1201
+ *PyMOL* object.
1202
+ complete : bool, optional
1203
+ If set to true, it is insured that no atoms centers are
1204
+ clipped.
1205
+ """
1206
+ state = 0 if state is None else state
1207
+ self._cmd.zoom(
1208
+ self._into_selection(selection, True), buffer, state, int(complete)
1209
+ )
1210
+
1211
+
1212
+ class NonexistentObjectError(Exception):
1213
+ """
1214
+ Indicates that a *PyMOL* object with a given name does not exist.
1215
+ """
1216
+
1217
+ pass
1218
+
1219
+
1220
+ class ModifiedObjectError(Exception):
1221
+ """
1222
+ Indicates that a atoms were added to or removed from the *PyMOL*
1223
+ object after the corresponding :class:`PyMOLObject` was created.
1224
+ """
1225
+
1226
+ pass