biotite 1.1.0__cp310-cp310-macosx_10_9_x86_64.whl → 1.2.0__cp310-cp310-macosx_10_9_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.

Files changed (155) 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/localapp.py +2 -2
  6. biotite/application/msaapp.py +10 -10
  7. biotite/application/muscle/app3.py +3 -3
  8. biotite/application/muscle/app5.py +3 -3
  9. biotite/application/sra/app.py +0 -5
  10. biotite/application/util.py +21 -1
  11. biotite/application/viennarna/rnaalifold.py +8 -8
  12. biotite/application/viennarna/rnaplot.py +3 -1
  13. biotite/application/viennarna/util.py +1 -1
  14. biotite/application/webapp.py +1 -1
  15. biotite/database/afdb/__init__.py +12 -0
  16. biotite/database/afdb/download.py +191 -0
  17. biotite/database/entrez/dbnames.py +10 -0
  18. biotite/database/entrez/download.py +9 -10
  19. biotite/database/entrez/key.py +1 -1
  20. biotite/database/entrez/query.py +5 -4
  21. biotite/database/pubchem/download.py +6 -6
  22. biotite/database/pubchem/error.py +10 -0
  23. biotite/database/pubchem/query.py +12 -23
  24. biotite/database/rcsb/download.py +3 -2
  25. biotite/database/rcsb/query.py +2 -3
  26. biotite/database/uniprot/check.py +2 -2
  27. biotite/database/uniprot/download.py +2 -5
  28. biotite/database/uniprot/query.py +3 -4
  29. biotite/file.py +14 -2
  30. biotite/interface/__init__.py +19 -0
  31. biotite/interface/openmm/__init__.py +16 -0
  32. biotite/interface/openmm/state.py +93 -0
  33. biotite/interface/openmm/system.py +227 -0
  34. biotite/interface/pymol/__init__.py +198 -0
  35. biotite/interface/pymol/cgo.py +346 -0
  36. biotite/interface/pymol/convert.py +185 -0
  37. biotite/interface/pymol/display.py +267 -0
  38. biotite/interface/pymol/object.py +1226 -0
  39. biotite/interface/pymol/shapes.py +178 -0
  40. biotite/interface/pymol/startup.py +169 -0
  41. biotite/interface/rdkit/__init__.py +15 -0
  42. biotite/interface/rdkit/mol.py +490 -0
  43. biotite/interface/version.py +71 -0
  44. biotite/interface/warning.py +19 -0
  45. biotite/sequence/align/__init__.py +0 -4
  46. biotite/sequence/align/alignment.py +33 -11
  47. biotite/sequence/align/banded.cpython-310-darwin.so +0 -0
  48. biotite/sequence/align/banded.pyx +21 -21
  49. biotite/sequence/align/cigar.py +2 -2
  50. biotite/sequence/align/kmeralphabet.cpython-310-darwin.so +0 -0
  51. biotite/sequence/align/kmeralphabet.pyx +2 -2
  52. biotite/sequence/align/kmersimilarity.cpython-310-darwin.so +0 -0
  53. biotite/sequence/align/kmertable.cpython-310-darwin.so +0 -0
  54. biotite/sequence/align/kmertable.pyx +6 -6
  55. biotite/sequence/align/localgapped.cpython-310-darwin.so +0 -0
  56. biotite/sequence/align/localgapped.pyx +47 -47
  57. biotite/sequence/align/localungapped.cpython-310-darwin.so +0 -0
  58. biotite/sequence/align/localungapped.pyx +10 -10
  59. biotite/sequence/align/matrix.py +12 -3
  60. biotite/sequence/align/multiple.cpython-310-darwin.so +0 -0
  61. biotite/sequence/align/pairwise.cpython-310-darwin.so +0 -0
  62. biotite/sequence/align/pairwise.pyx +35 -35
  63. biotite/sequence/align/permutation.cpython-310-darwin.so +0 -0
  64. biotite/sequence/align/selector.cpython-310-darwin.so +0 -0
  65. biotite/sequence/align/selector.pyx +2 -2
  66. biotite/sequence/align/statistics.py +1 -1
  67. biotite/sequence/align/tracetable.cpython-310-darwin.so +0 -0
  68. biotite/sequence/alphabet.py +2 -2
  69. biotite/sequence/annotation.py +19 -13
  70. biotite/sequence/codec.cpython-310-darwin.so +0 -0
  71. biotite/sequence/codon.py +1 -2
  72. biotite/sequence/graphics/alignment.py +25 -39
  73. biotite/sequence/graphics/dendrogram.py +4 -2
  74. biotite/sequence/graphics/features.py +2 -2
  75. biotite/sequence/graphics/logo.py +10 -12
  76. biotite/sequence/io/fasta/convert.py +1 -2
  77. biotite/sequence/io/fasta/file.py +1 -1
  78. biotite/sequence/io/fastq/file.py +3 -3
  79. biotite/sequence/io/genbank/file.py +3 -3
  80. biotite/sequence/io/genbank/sequence.py +2 -0
  81. biotite/sequence/io/gff/convert.py +1 -1
  82. biotite/sequence/io/gff/file.py +1 -2
  83. biotite/sequence/phylo/nj.cpython-310-darwin.so +0 -0
  84. biotite/sequence/phylo/tree.cpython-310-darwin.so +0 -0
  85. biotite/sequence/phylo/upgma.cpython-310-darwin.so +0 -0
  86. biotite/sequence/profile.py +19 -25
  87. biotite/sequence/search.py +0 -1
  88. biotite/sequence/seqtypes.py +12 -5
  89. biotite/sequence/sequence.py +1 -2
  90. biotite/structure/__init__.py +2 -0
  91. biotite/structure/alphabet/i3d.py +1 -2
  92. biotite/structure/alphabet/pb.py +1 -2
  93. biotite/structure/alphabet/unkerasify.py +8 -2
  94. biotite/structure/atoms.py +35 -27
  95. biotite/structure/basepairs.py +26 -26
  96. biotite/structure/bonds.cpython-310-darwin.so +0 -0
  97. biotite/structure/bonds.pyx +8 -5
  98. biotite/structure/box.py +19 -21
  99. biotite/structure/celllist.cpython-310-darwin.so +0 -0
  100. biotite/structure/celllist.pyx +83 -67
  101. biotite/structure/chains.py +5 -37
  102. biotite/structure/charges.cpython-310-darwin.so +0 -0
  103. biotite/structure/compare.py +420 -13
  104. biotite/structure/density.py +1 -1
  105. biotite/structure/dotbracket.py +27 -28
  106. biotite/structure/filter.py +8 -8
  107. biotite/structure/geometry.py +15 -15
  108. biotite/structure/hbond.py +17 -19
  109. biotite/structure/info/atoms.py +11 -2
  110. biotite/structure/info/ccd.py +0 -2
  111. biotite/structure/info/components.bcif +0 -0
  112. biotite/structure/info/groups.py +0 -3
  113. biotite/structure/info/misc.py +0 -1
  114. biotite/structure/info/radii.py +92 -22
  115. biotite/structure/info/standardize.py +1 -2
  116. biotite/structure/integrity.py +4 -6
  117. biotite/structure/io/general.py +2 -2
  118. biotite/structure/io/gro/file.py +8 -9
  119. biotite/structure/io/mol/convert.py +1 -1
  120. biotite/structure/io/mol/ctab.py +33 -28
  121. biotite/structure/io/mol/mol.py +1 -1
  122. biotite/structure/io/mol/sdf.py +39 -13
  123. biotite/structure/io/pdb/convert.py +2 -3
  124. biotite/structure/io/pdb/file.py +11 -22
  125. biotite/structure/io/pdb/hybrid36.cpython-310-darwin.so +0 -0
  126. biotite/structure/io/pdbqt/file.py +4 -4
  127. biotite/structure/io/pdbx/bcif.py +22 -7
  128. biotite/structure/io/pdbx/cif.py +20 -7
  129. biotite/structure/io/pdbx/component.py +6 -0
  130. biotite/structure/io/pdbx/compress.py +2 -2
  131. biotite/structure/io/pdbx/convert.py +222 -33
  132. biotite/structure/io/pdbx/encoding.cpython-310-darwin.so +0 -0
  133. biotite/structure/io/trajfile.py +9 -6
  134. biotite/structure/io/util.py +38 -0
  135. biotite/structure/mechanics.py +0 -1
  136. biotite/structure/molecules.py +0 -15
  137. biotite/structure/pseudoknots.py +7 -13
  138. biotite/structure/repair.py +2 -4
  139. biotite/structure/residues.py +13 -24
  140. biotite/structure/rings.py +335 -0
  141. biotite/structure/sasa.cpython-310-darwin.so +0 -0
  142. biotite/structure/sasa.pyx +2 -1
  143. biotite/structure/segments.py +68 -9
  144. biotite/structure/sequence.py +0 -1
  145. biotite/structure/sse.py +0 -2
  146. biotite/structure/superimpose.py +74 -62
  147. biotite/structure/tm.py +581 -0
  148. biotite/structure/transform.py +12 -25
  149. biotite/structure/util.py +3 -3
  150. biotite/version.py +9 -4
  151. biotite/visualize.py +111 -1
  152. {biotite-1.1.0.dist-info → biotite-1.2.0.dist-info}/METADATA +5 -3
  153. {biotite-1.1.0.dist-info → biotite-1.2.0.dist-info}/RECORD +155 -135
  154. {biotite-1.1.0.dist-info → biotite-1.2.0.dist-info}/WHEEL +0 -0
  155. {biotite-1.1.0.dist-info → biotite-1.2.0.dist-info}/licenses/LICENSE.rst +0 -0
@@ -157,7 +157,7 @@ class Application(metaclass=abc.ABCMeta):
157
157
  if timeout is not None and time.time() - self._start_time > timeout:
158
158
  self.cancel()
159
159
  raise TimeoutError(
160
- f"The application expired its timeout " f"({timeout:.1f} s)"
160
+ f"The application expired its timeout ({timeout:.1f} s)"
161
161
  )
162
162
  else:
163
163
  time.sleep(self.wait_interval())
@@ -214,7 +214,7 @@ class Application(metaclass=abc.ABCMeta):
214
214
  Returns
215
215
  -------
216
216
  finished : bool
217
- True of the application has finished, false otherwise
217
+ True of the application has finished, false otherwise.
218
218
  """
219
219
  pass
220
220
 
@@ -230,7 +230,7 @@ class Application(metaclass=abc.ABCMeta):
230
230
  -------
231
231
  interval : float
232
232
  Time (in seconds) between calls of :func:`is_finished()` in
233
- :func:`join()`
233
+ :func:`join()`.
234
234
  """
235
235
  pass
236
236
 
@@ -153,7 +153,7 @@ class VinaApp(LocalApp):
153
153
 
154
154
  Parameters
155
155
  ----------
156
- number : float
156
+ energy_range : float
157
157
  The energy range (kcal/mol).
158
158
  """
159
159
  self._energy_range = energy_range
@@ -46,7 +46,7 @@ class BlastWebApp(WebApp):
46
46
  obey_rules : bool, optional
47
47
  If true, the application raises an :class:`RuleViolationError`,
48
48
  if the server is contacted too often, based on the NCBI BLAST
49
- usage rules. (Default: True)
49
+ usage rules.
50
50
  mail : str, optional
51
51
  If a mail address is provided, it will be appended in the
52
52
  HTTP request. This allows the NCBI to contact you in case
@@ -172,7 +172,7 @@ class ClustalOmegaApp(MSAApp):
172
172
  """
173
173
  if self._mbed:
174
174
  raise ValueError(
175
- "Getting the distance matrix requires " "'full_matrix_calculation()'"
175
+ "Getting the distance matrix requires 'full_matrix_calculation()'"
176
176
  )
177
177
  return self._dist_matrix
178
178
 
@@ -178,7 +178,7 @@ class LocalApp(Application, metaclass=abc.ABCMeta):
178
178
  Returns
179
179
  -------
180
180
  process : Popen
181
- The `Popen` instance
181
+ The `Popen` instance.
182
182
  """
183
183
  return self._process
184
184
 
@@ -279,7 +279,7 @@ class LocalApp(Application, metaclass=abc.ABCMeta):
279
279
  if exit_code != 0:
280
280
  err_msg = self.get_stderr().replace("\n", " ")
281
281
  raise SubprocessError(
282
- f"'{self._bin_path}' returned with exit code {exit_code}: " f"{err_msg}"
282
+ f"'{self._bin_path}' returned with exit code {exit_code}: {err_msg}"
283
283
  )
284
284
 
285
285
  def clean_up(self):
@@ -68,7 +68,7 @@ class MSAApp(LocalApp, metaclass=abc.ABCMeta):
68
68
  # Check matrix symmetry
69
69
  if matrix is not None and not matrix.is_symmetric():
70
70
  raise ValueError(
71
- "A symmetric matrix is required for " "multiple sequence alignments"
71
+ "A symmetric matrix is required for multiple sequence alignments"
72
72
  )
73
73
 
74
74
  # Check whether the program supports the alignment for the given
@@ -274,12 +274,12 @@ class MSAApp(LocalApp, metaclass=abc.ABCMeta):
274
274
  Check whether this class supports nucleotide sequences for
275
275
  alignment.
276
276
 
277
+ PROTECTED: Override when inheriting.
278
+
277
279
  Returns
278
280
  -------
279
281
  support : bool
280
282
  True, if the class has support, false otherwise.
281
-
282
- PROTECTED: Override when inheriting.
283
283
  """
284
284
  pass
285
285
 
@@ -290,12 +290,12 @@ class MSAApp(LocalApp, metaclass=abc.ABCMeta):
290
290
  Check whether this class supports nucleotide sequences for
291
291
  alignment.
292
292
 
293
+ PROTECTED: Override when inheriting.
294
+
293
295
  Returns
294
296
  -------
295
297
  support : bool
296
298
  True, if the class has support, false otherwise.
297
-
298
- PROTECTED: Override when inheriting.
299
299
  """
300
300
  pass
301
301
 
@@ -306,12 +306,12 @@ class MSAApp(LocalApp, metaclass=abc.ABCMeta):
306
306
  Check whether this class supports custom substitution matrices
307
307
  for protein sequence alignment.
308
308
 
309
+ PROTECTED: Override when inheriting.
310
+
309
311
  Returns
310
312
  -------
311
313
  support : bool
312
314
  True, if the class has support, false otherwise.
313
-
314
- PROTECTED: Override when inheriting.
315
315
  """
316
316
  pass
317
317
 
@@ -322,12 +322,12 @@ class MSAApp(LocalApp, metaclass=abc.ABCMeta):
322
322
  Check whether this class supports custom substitution matrices
323
323
  for nucleotide sequence alignment.
324
324
 
325
+ PROTECTED: Override when inheriting.
326
+
325
327
  Returns
326
328
  -------
327
329
  support : bool
328
330
  True, if the class has support, false otherwise.
329
-
330
- PROTECTED: Override when inheriting.
331
331
  """
332
332
  pass
333
333
 
@@ -342,7 +342,7 @@ class MSAApp(LocalApp, metaclass=abc.ABCMeta):
342
342
  Parameters
343
343
  ----------
344
344
  sequences : iterable object of Sequence
345
- The sequences to be aligned
345
+ The sequences to be aligned.
346
346
  bin_path : str, optional
347
347
  Path of the MSA software binary. By default, the default
348
348
  path will be used.
@@ -29,9 +29,9 @@ class MuscleApp(MSAApp):
29
29
  matrix : SubstitutionMatrix, optional
30
30
  A custom substitution matrix.
31
31
 
32
- See also
32
+ See Also
33
33
  --------
34
- Muscle5App
34
+ Muscle5App : Interface to MUSCLE version ``>=5``.
35
35
 
36
36
  Examples
37
37
  --------
@@ -197,7 +197,7 @@ class MuscleApp(MSAApp):
197
197
  Parameters
198
198
  ----------
199
199
  sequences : iterable object of Sequence
200
- The sequences to be aligned
200
+ The sequences to be aligned.
201
201
  bin_path : str, optional
202
202
  Path of the MSA software binary. By default, the default path
203
203
  will be used.
@@ -22,9 +22,9 @@ class Muscle5App(MSAApp):
22
22
  bin_path : str, optional
23
23
  Path of the MUSCLE binary.
24
24
 
25
- See also
25
+ See Also
26
26
  --------
27
- MuscleApp
27
+ MuscleApp : Interface to MUSCLE version ``<5``.
28
28
 
29
29
  Notes
30
30
  -----
@@ -147,7 +147,7 @@ class Muscle5App(MSAApp):
147
147
  Parameters
148
148
  ----------
149
149
  sequences : iterable object of Sequence
150
- The sequences to be aligned
150
+ The sequences to be aligned.
151
151
  bin_path : str, optional
152
152
  Path of the MSA software binary. By default, the default path
153
153
  will be used.
@@ -45,11 +45,6 @@ class _DumpApp(Application, metaclass=abc.ABCMeta):
45
45
  prefetch_path, fasterq_dump_path : str, optional
46
46
  Path to the ``prefetch_path`` and ``fasterq-dump`` binary,
47
47
  respectively.
48
- offset : int or {'Sanger', 'Solexa', 'Illumina-1.3', 'Illumina-1.5', 'Illumina-1.8'}, optional
49
- This value is subtracted from the FASTQ ASCII code to obtain the
50
- quality score.
51
- Can either be directly the value, or a string that indicates
52
- the score format.
53
48
  """
54
49
 
55
50
  def __init__(
@@ -17,6 +17,16 @@ def map_sequence(sequence):
17
17
  Map a sequence with an arbitrary alphabet into a
18
18
  :class:`ProteinSequence`, in order to support arbitrary sequence
19
19
  types in software that can handle protein sequences.
20
+
21
+ Parameters
22
+ ----------
23
+ sequence : Sequence
24
+ The sequence to be mapped.
25
+
26
+ Returns
27
+ -------
28
+ mapped_sequence : ProteinSequence
29
+ The mapped sequence.
20
30
  """
21
31
  if len(sequence.alphabet) > len(ProteinSequence.alphabet):
22
32
  # Cannot map into a protein sequence if the alphabet
@@ -40,10 +50,20 @@ def map_matrix(matrix):
40
50
  class:`SubstitutionMatrix` for protein sequences, in order to support
41
51
  arbitrary sequence types in software that can handle protein
42
52
  sequences.
53
+
54
+ Parameters
55
+ ----------
56
+ matrix : SubstitutionMatrix
57
+ The substitution matrix to be mapped.
58
+
59
+ Returns
60
+ -------
61
+ mapped_matrix : SubstitutionMatrix
62
+ The mapped substitution matrix.
43
63
  """
44
64
  if matrix is None:
45
65
  raise TypeError(
46
- "A substitution matrix must be provided for custom " "sequence types"
66
+ "A substitution matrix must be provided for custom sequence types"
47
67
  )
48
68
  # Create a protein substitution matrix with the values taken
49
69
  # from the original matrix
@@ -167,15 +167,15 @@ class RNAalifoldApp(LocalApp):
167
167
  free_energy : float
168
168
  The free energy.
169
169
 
170
+ See Also
171
+ --------
172
+ get_covariance_energy : Get the energy of the artificial covariance term.
173
+
170
174
  Notes
171
175
  -----
172
176
  The total energy of the secondary structure regarding the
173
177
  minimization objective is the sum of the free energy and the
174
178
  covariance term.
175
-
176
- See also
177
- --------
178
- get_covariance_energy
179
179
  """
180
180
  return self._free_energy
181
181
 
@@ -190,15 +190,15 @@ class RNAalifoldApp(LocalApp):
190
190
  covariance_energy : float
191
191
  The energy of the covariance term.
192
192
 
193
+ See Also
194
+ --------
195
+ get_free_energy : Get the free energy.
196
+
193
197
  Notes
194
198
  -----
195
199
  The total energy of the secondary structure regarding the
196
200
  minimization objective is the sum of the free energy and the
197
201
  covariance term.
198
-
199
- See also
200
- --------
201
- get_free_energy
202
202
  """
203
203
  return self._covariance_energy
204
204
 
@@ -124,7 +124,7 @@ class RNAplotApp(LocalApp):
124
124
 
125
125
  Parameters
126
126
  ----------
127
- type : RNAplotApp.Layout
127
+ layout_type : RNAplotApp.Layout
128
128
  The layout type.
129
129
  """
130
130
  self._layout_type = str(layout_type)
@@ -185,6 +185,8 @@ class RNAplotApp(LocalApp):
185
185
  length : int, optional (default: None)
186
186
  The number of bases in the strand. This parameter is
187
187
  required if ``base_pairs`` is given.
188
+ layout_type : Layout
189
+ The desired layout of the plot.
188
190
  bin_path : str, optional
189
191
  Path of the *RNAplot* binary.
190
192
 
@@ -39,7 +39,7 @@ def build_constraint_string(
39
39
  Returns
40
40
  -------
41
41
  constraints : str
42
- The constraint string
42
+ The constraint string.
43
43
  """
44
44
  constraints = np.full(sequence_length, ".", dtype="U1")
45
45
 
@@ -29,7 +29,7 @@ class WebApp(Application, metaclass=abc.ABCMeta):
29
29
  URL of the web app.
30
30
  obey_rules : bool, optional
31
31
  If true, the application raises an :class:`RuleViolationError`, if
32
- the server rules are violated. (Default: True)
32
+ the server rules are violated.
33
33
  """
34
34
 
35
35
  def __init__(self, app_url, obey_rules=True):
@@ -0,0 +1,12 @@
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
+ A subpackage for downloading predicted protein structures from the AlphaFold DB.
7
+ """
8
+
9
+ __name__ = "biotite.database.afdb"
10
+ __author__ = "Alex Carlin"
11
+
12
+ from .download import *
@@ -0,0 +1,191 @@
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.database.afdb"
6
+ __author__ = "Patrick Kunzmann, Alex Carlin"
7
+ __all__ = ["fetch"]
8
+
9
+ import io
10
+ import re
11
+ from pathlib import Path
12
+ from xml.etree import ElementTree
13
+ import requests
14
+ from biotite.database.error import RequestError
15
+
16
+ _METADATA_URL = "https://alphafold.com/api/prediction"
17
+ _BINARY_FORMATS = ["bcif"]
18
+ # Adopted from https://www.uniprot.org/help/accession_numbers
19
+ _UNIPROT_PATTERN = (
20
+ "[OPQ][0-9][A-Z0-9]{3}[0-9]|[A-NR-Z][0-9]([A-Z][A-Z0-9]{2}[0-9]){1,2}"
21
+ )
22
+
23
+
24
+ def fetch(ids, format, target_path=None, overwrite=False, verbose=False):
25
+ """
26
+ Download predicted protein structures from the AlphaFold DB.
27
+
28
+ This function requires an internet connection.
29
+
30
+ Parameters
31
+ ----------
32
+ ids : str or iterable object of str
33
+ A single ID or a list of IDs of the file(s) to be downloaded.
34
+ They can be either UniProt IDs (e.g. ``P12345``) or AlphaFold DB IDs
35
+ (e.g. ``AF-P12345F1``).
36
+ format : {'pdb', 'pdbx', 'cif', 'mmcif', 'bcif', 'fasta'}
37
+ The format of the files to be downloaded.
38
+ target_path : str, optional
39
+ The target directory of the downloaded files.
40
+ By default, the file content is stored in a file-like object
41
+ (`StringIO` or `BytesIO`, respectively).
42
+ overwrite : bool, optional
43
+ If true, existing files will be overwritten.
44
+ Otherwise the respective file will only be downloaded if the file does not
45
+ exist yet in the specified target directory or if the file is empty.
46
+ verbose : bool, optional
47
+ If true, the function will output the download progress.
48
+
49
+ Returns
50
+ -------
51
+ files : str or StringIO or BytesIO or list of (str or StringIO or BytesIO)
52
+ The file path(s) to the downloaded files.
53
+ If a single string (a single ID) was given in `ids`, a single string is
54
+ returned.
55
+ If a list (or other iterable object) was given, a list of strings is returned.
56
+ If no `target_path` was given, the file contents are stored in either
57
+ ``StringIO`` or ``BytesIO`` objects.
58
+
59
+ Examples
60
+ --------
61
+
62
+ >>> from pathlib import Path
63
+ >>> file = fetch("P12345", "cif", path_to_directory)
64
+ >>> print(Path(file).name)
65
+ P12345.cif
66
+ >>> files = fetch(["P12345", "Q8K9I1"], "cif", path_to_directory)
67
+ >>> print([Path(file).name for file in files])
68
+ ['P12345.cif', 'Q8K9I1.cif']
69
+ """
70
+ if format not in ["pdb", "pdbx", "cif", "mmcif", "bcif", "fasta"]:
71
+ raise ValueError(f"Format '{format}' is not supported")
72
+ if format in ["pdbx", "mmcif"]:
73
+ format = "cif"
74
+
75
+ # If only a single ID is present,
76
+ # put it into a single element list
77
+ if isinstance(ids, str):
78
+ ids = [ids]
79
+ single_element = True
80
+ else:
81
+ single_element = False
82
+ if target_path is not None:
83
+ target_path = Path(target_path)
84
+ target_path.mkdir(parents=True, exist_ok=True)
85
+
86
+ files = []
87
+ for i, id in enumerate(ids):
88
+ # Verbose output
89
+ if verbose:
90
+ print(f"Fetching file {i + 1:d} / {len(ids):d} ({id})...", end="\r")
91
+ # Fetch file from database
92
+ if target_path is not None:
93
+ file = target_path / f"{id}.{format}"
94
+ else:
95
+ # 'file = None' -> store content in a file-like object
96
+ file = None
97
+ if file is None or not file.is_file() or file.stat().st_size == 0 or overwrite:
98
+ file_response = requests.get(_get_file_url(id, format))
99
+ _assert_valid_file(file_response, id)
100
+ if format in _BINARY_FORMATS:
101
+ content = file_response.content
102
+ else:
103
+ content = file_response.text
104
+
105
+ if file is None:
106
+ if format in _BINARY_FORMATS:
107
+ file = io.BytesIO(content)
108
+ else:
109
+ file = io.StringIO(content)
110
+ else:
111
+ mode = "wb+" if format in _BINARY_FORMATS else "w+"
112
+ with open(file, mode) as f:
113
+ f.write(content)
114
+
115
+ files.append(file)
116
+ if verbose:
117
+ print("\nDone")
118
+
119
+ # Return paths as strings
120
+ files = [file.as_posix() if isinstance(file, Path) else file for file in files]
121
+ # If input was a single ID, return only a single element
122
+ if single_element:
123
+ return files[0]
124
+ else:
125
+ return files
126
+
127
+
128
+ def _get_file_url(id, format):
129
+ """
130
+ Get the actual file URL for the given ID from the ``prediction`` API endpoint.
131
+
132
+ Parameters
133
+ ----------
134
+ id : str
135
+ The ID of the file to be downloaded.
136
+ format : str
137
+ The format of the file to be downloaded.
138
+
139
+ Returns
140
+ -------
141
+ file_url : str
142
+ The URL of the file to be downloaded.
143
+ """
144
+ uniprot_id = _extract_id(id)
145
+ metadata = requests.get(f"{_METADATA_URL}/{uniprot_id}").json()
146
+ if len(metadata) == 0:
147
+ raise RequestError(f"ID {id} is invalid")
148
+ # A list of length 1 is always returned, if the response is valid
149
+ return metadata[0][f"{format}Url"]
150
+
151
+
152
+ def _extract_id(id):
153
+ """
154
+ Extract a AFDB compatible UniProt ID from the given qualifier.
155
+ This may comprise
156
+
157
+ - Directly the UniProt ID (e.g. ``P12345``) (trivial case)
158
+ - Entry ID, as also returned by the RCSB search API (e.g. ``AF-P12345-F1``)
159
+
160
+ Parameters
161
+ ----------
162
+ id : str
163
+ The qualifier to extract the UniProt ID from.
164
+
165
+ Returns
166
+ -------
167
+ uniprot_id : str
168
+ The UniProt ID.
169
+ """
170
+ match = re.search(_UNIPROT_PATTERN, id)
171
+ if match is None:
172
+ raise ValueError(f"Cannot extract AFDB identifier from '{id}'")
173
+ return match.group()
174
+
175
+
176
+ def _assert_valid_file(response, id):
177
+ """
178
+ Checks whether the response is an actual structure file
179
+ or the response a *404* error due to invalid UniProt ID.
180
+ """
181
+ if len(response.text) == 0:
182
+ raise RequestError(f"Received no repsone for '{id}'")
183
+ try:
184
+ root = ElementTree.fromstring(response.text)
185
+ if root.tag == "Error":
186
+ raise RequestError(
187
+ f"Error while fetching '{id}': {root.find('Message').text}"
188
+ )
189
+ except ElementTree.ParseError:
190
+ # This is not XML -> the response is probably a valid file
191
+ pass
@@ -80,6 +80,16 @@ def sanitize_database_name(db_name):
80
80
  database name is not existing.
81
81
 
82
82
  Only for internal usage in ``download.py`` and ``query.py``.
83
+
84
+ Parameters
85
+ ----------
86
+ db_name : str
87
+ Entrez database name.
88
+
89
+ Returns
90
+ -------
91
+ name : str
92
+ E-utility database name.
83
93
  """
84
94
  if db_name in _db_names.keys():
85
95
  # Convert into E-utility database name
@@ -54,17 +54,16 @@ def fetch(
54
54
  db_name : str:
55
55
  E-utility or common database name.
56
56
  ret_type : str
57
- Retrieval type
57
+ Retrieval type.
58
58
  ret_mode : str, optional
59
- Retrieval mode
59
+ Retrieval mode.
60
60
  overwrite : bool, optional
61
61
  If true, existing files will be overwritten. Otherwise the
62
62
  respective file will only be downloaded if the file does not
63
63
  exist yet in the specified target directory or if the file is
64
- empty. (Default: False)
65
- verbose: bool, optional
64
+ empty.
65
+ verbose : bool, optional
66
66
  If true, the function will output the download progress.
67
- (Default: False)
68
67
 
69
68
  Returns
70
69
  -------
@@ -84,9 +83,9 @@ def fetch(
84
83
  When the issue occurs repeatedly, the error is probably in your
85
84
  input.
86
85
 
87
- See also
86
+ See Also
88
87
  --------
89
- fetch_single_file
88
+ fetch_single_file : Fetch multiple entries as a single file.
90
89
 
91
90
  Examples
92
91
  --------
@@ -111,7 +110,7 @@ def fetch(
111
110
  for i, id in enumerate(uids):
112
111
  # Verbose output
113
112
  if verbose:
114
- print(f"Fetching file {i+1:d} / {len(uids):d} ({id})...", end="\r")
113
+ print(f"Fetching file {i + 1:d} / {len(uids):d} ({id})...", end="\r")
115
114
  # Fetch file from database
116
115
  if target_path is not None:
117
116
  file = join(target_path, id + "." + suffix)
@@ -188,9 +187,9 @@ def fetch_single_file(
188
187
  When the issue occurs repeatedly, the error is probably in your
189
188
  input.
190
189
 
191
- See also
190
+ See Also
192
191
  --------
193
- fetch
192
+ fetch : Fetch one or multiple entries as separate files.
194
193
  """
195
194
  if (
196
195
  file_name is not None
@@ -37,7 +37,7 @@ def set_api_key(key):
37
37
 
38
38
  Parameters
39
39
  ----------
40
- api_key : str
40
+ key : str
41
41
  The API key.
42
42
  """
43
43
  global _API_KEY
@@ -60,9 +60,9 @@ class CompositeQuery(Query):
60
60
 
61
61
  Parameters
62
62
  ----------
63
- operator: str, {"AND", "OR", "NOT"}
63
+ operator : str, {"AND", "OR", "NOT"}
64
64
  The combination operator.
65
- queries : iterable object of SimpleQuery
65
+ query1, query2 : SimpleQuery
66
66
  The queries to be combined.
67
67
 
68
68
  Examples
@@ -97,7 +97,7 @@ class SimpleQuery(Query):
97
97
 
98
98
  Parameters
99
99
  ----------
100
- term: str
100
+ term : str
101
101
  The search term.
102
102
  field : str, optional
103
103
  The field to search the term in.
@@ -173,7 +173,8 @@ class SimpleQuery(Query):
173
173
  "SUBS",
174
174
  "WORD",
175
175
  "TI",
176
- "TITL" "VOL",
176
+ "TITL",
177
+ "VOL",
177
178
  ]
178
179
 
179
180
  def __init__(self, term, field=None):
@@ -41,22 +41,22 @@ def fetch(
41
41
  to be downloaded.
42
42
  format : {'sdf', 'asnt' 'asnb', 'xml', 'json', 'jsonp', 'png'}
43
43
  The format of the files to be downloaded.
44
+ target_path : str, optional
45
+ The target directory of the downloaded files.
46
+ By default, the file content is stored in a file-like object
47
+ (:class:`StringIO` or :class:`BytesIO`, respectively).
44
48
  as_structural_formula : bool, optional
45
49
  If set to true, the structural formula is download instead of
46
50
  an 3D conformer.
47
51
  This means that coordinates lie in th xy-plane and represent
48
52
  the positions atoms would have an a structural formula
49
53
  representation.
50
- target_path : str, optional
51
- The target directory of the downloaded files.
52
- By default, the file content is stored in a file-like object
53
- (:class:`StringIO` or :class:`BytesIO`, respectively).
54
54
  overwrite : bool, optional
55
55
  If true, existing files will be overwritten.
56
56
  Otherwise the respective file will only be downloaded, if the
57
57
  file does not exist yet in the specified target directory or if
58
58
  the file is empty.
59
- verbose: bool, optional
59
+ verbose : bool, optional
60
60
  If set to true, the function will output the download progress.
61
61
  throttle_threshold : float or None, optional
62
62
  A value between 0 and 1.
@@ -114,7 +114,7 @@ def fetch(
114
114
  raise TypeError("CIDs must be given as integers, not as string")
115
115
  # Verbose output
116
116
  if verbose:
117
- print(f"Fetching file {i+1:d} / {len(cids):d} ({cid})...", end="\r")
117
+ print(f"Fetching file {i + 1:d} / {len(cids):d} ({cid})...", end="\r")
118
118
 
119
119
  # Fetch file from database
120
120
  if target_path is not None: