biotite 1.1.0__cp313-cp313-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 (332) hide show
  1. biotite/__init__.py +18 -0
  2. biotite/application/__init__.py +69 -0
  3. biotite/application/application.py +276 -0
  4. biotite/application/autodock/__init__.py +12 -0
  5. biotite/application/autodock/app.py +500 -0
  6. biotite/application/blast/__init__.py +14 -0
  7. biotite/application/blast/alignment.py +92 -0
  8. biotite/application/blast/webapp.py +428 -0
  9. biotite/application/clustalo/__init__.py +12 -0
  10. biotite/application/clustalo/app.py +223 -0
  11. biotite/application/dssp/__init__.py +12 -0
  12. biotite/application/dssp/app.py +159 -0
  13. biotite/application/localapp.py +342 -0
  14. biotite/application/mafft/__init__.py +12 -0
  15. biotite/application/mafft/app.py +116 -0
  16. biotite/application/msaapp.py +363 -0
  17. biotite/application/muscle/__init__.py +13 -0
  18. biotite/application/muscle/app3.py +227 -0
  19. biotite/application/muscle/app5.py +163 -0
  20. biotite/application/sra/__init__.py +18 -0
  21. biotite/application/sra/app.py +452 -0
  22. biotite/application/tantan/__init__.py +12 -0
  23. biotite/application/tantan/app.py +199 -0
  24. biotite/application/util.py +57 -0
  25. biotite/application/viennarna/__init__.py +18 -0
  26. biotite/application/viennarna/rnaalifold.py +310 -0
  27. biotite/application/viennarna/rnafold.py +254 -0
  28. biotite/application/viennarna/rnaplot.py +206 -0
  29. biotite/application/viennarna/util.py +77 -0
  30. biotite/application/webapp.py +76 -0
  31. biotite/copyable.py +71 -0
  32. biotite/database/__init__.py +23 -0
  33. biotite/database/entrez/__init__.py +15 -0
  34. biotite/database/entrez/check.py +60 -0
  35. biotite/database/entrez/dbnames.py +91 -0
  36. biotite/database/entrez/download.py +229 -0
  37. biotite/database/entrez/key.py +44 -0
  38. biotite/database/entrez/query.py +262 -0
  39. biotite/database/error.py +16 -0
  40. biotite/database/pubchem/__init__.py +21 -0
  41. biotite/database/pubchem/download.py +258 -0
  42. biotite/database/pubchem/error.py +20 -0
  43. biotite/database/pubchem/query.py +830 -0
  44. biotite/database/pubchem/throttle.py +98 -0
  45. biotite/database/rcsb/__init__.py +13 -0
  46. biotite/database/rcsb/download.py +159 -0
  47. biotite/database/rcsb/query.py +964 -0
  48. biotite/database/uniprot/__init__.py +13 -0
  49. biotite/database/uniprot/check.py +40 -0
  50. biotite/database/uniprot/download.py +129 -0
  51. biotite/database/uniprot/query.py +293 -0
  52. biotite/file.py +232 -0
  53. biotite/sequence/__init__.py +84 -0
  54. biotite/sequence/align/__init__.py +203 -0
  55. biotite/sequence/align/alignment.py +680 -0
  56. biotite/sequence/align/banded.cp313-win_amd64.pyd +0 -0
  57. biotite/sequence/align/banded.pyx +652 -0
  58. biotite/sequence/align/buckets.py +71 -0
  59. biotite/sequence/align/cigar.py +425 -0
  60. biotite/sequence/align/kmeralphabet.cp313-win_amd64.pyd +0 -0
  61. biotite/sequence/align/kmeralphabet.pyx +595 -0
  62. biotite/sequence/align/kmersimilarity.cp313-win_amd64.pyd +0 -0
  63. biotite/sequence/align/kmersimilarity.pyx +233 -0
  64. biotite/sequence/align/kmertable.cp313-win_amd64.pyd +0 -0
  65. biotite/sequence/align/kmertable.pyx +3411 -0
  66. biotite/sequence/align/localgapped.cp313-win_amd64.pyd +0 -0
  67. biotite/sequence/align/localgapped.pyx +892 -0
  68. biotite/sequence/align/localungapped.cp313-win_amd64.pyd +0 -0
  69. biotite/sequence/align/localungapped.pyx +279 -0
  70. biotite/sequence/align/matrix.py +622 -0
  71. biotite/sequence/align/matrix_data/3Di.mat +24 -0
  72. biotite/sequence/align/matrix_data/BLOSUM100.mat +31 -0
  73. biotite/sequence/align/matrix_data/BLOSUM30.mat +31 -0
  74. biotite/sequence/align/matrix_data/BLOSUM35.mat +31 -0
  75. biotite/sequence/align/matrix_data/BLOSUM40.mat +31 -0
  76. biotite/sequence/align/matrix_data/BLOSUM45.mat +31 -0
  77. biotite/sequence/align/matrix_data/BLOSUM50.mat +31 -0
  78. biotite/sequence/align/matrix_data/BLOSUM50_13p.mat +25 -0
  79. biotite/sequence/align/matrix_data/BLOSUM50_14.3.mat +25 -0
  80. biotite/sequence/align/matrix_data/BLOSUM50_5.0.mat +25 -0
  81. biotite/sequence/align/matrix_data/BLOSUM55.mat +31 -0
  82. biotite/sequence/align/matrix_data/BLOSUM60.mat +31 -0
  83. biotite/sequence/align/matrix_data/BLOSUM62.mat +31 -0
  84. biotite/sequence/align/matrix_data/BLOSUM62_13p.mat +25 -0
  85. biotite/sequence/align/matrix_data/BLOSUM62_14.3.mat +25 -0
  86. biotite/sequence/align/matrix_data/BLOSUM62_5.0.mat +25 -0
  87. biotite/sequence/align/matrix_data/BLOSUM65.mat +31 -0
  88. biotite/sequence/align/matrix_data/BLOSUM70.mat +31 -0
  89. biotite/sequence/align/matrix_data/BLOSUM75.mat +31 -0
  90. biotite/sequence/align/matrix_data/BLOSUM80.mat +31 -0
  91. biotite/sequence/align/matrix_data/BLOSUM85.mat +31 -0
  92. biotite/sequence/align/matrix_data/BLOSUM90.mat +31 -0
  93. biotite/sequence/align/matrix_data/BLOSUMN.mat +31 -0
  94. biotite/sequence/align/matrix_data/CorBLOSUM49_5.0.mat +25 -0
  95. biotite/sequence/align/matrix_data/CorBLOSUM57_13p.mat +25 -0
  96. biotite/sequence/align/matrix_data/CorBLOSUM57_14.3.mat +25 -0
  97. biotite/sequence/align/matrix_data/CorBLOSUM61_5.0.mat +25 -0
  98. biotite/sequence/align/matrix_data/CorBLOSUM66_13p.mat +25 -0
  99. biotite/sequence/align/matrix_data/CorBLOSUM67_14.3.mat +25 -0
  100. biotite/sequence/align/matrix_data/DAYHOFF.mat +32 -0
  101. biotite/sequence/align/matrix_data/GONNET.mat +26 -0
  102. biotite/sequence/align/matrix_data/IDENTITY.mat +25 -0
  103. biotite/sequence/align/matrix_data/MATCH.mat +25 -0
  104. biotite/sequence/align/matrix_data/NUC.mat +25 -0
  105. biotite/sequence/align/matrix_data/PAM10.mat +34 -0
  106. biotite/sequence/align/matrix_data/PAM100.mat +34 -0
  107. biotite/sequence/align/matrix_data/PAM110.mat +34 -0
  108. biotite/sequence/align/matrix_data/PAM120.mat +34 -0
  109. biotite/sequence/align/matrix_data/PAM130.mat +34 -0
  110. biotite/sequence/align/matrix_data/PAM140.mat +34 -0
  111. biotite/sequence/align/matrix_data/PAM150.mat +34 -0
  112. biotite/sequence/align/matrix_data/PAM160.mat +34 -0
  113. biotite/sequence/align/matrix_data/PAM170.mat +34 -0
  114. biotite/sequence/align/matrix_data/PAM180.mat +34 -0
  115. biotite/sequence/align/matrix_data/PAM190.mat +34 -0
  116. biotite/sequence/align/matrix_data/PAM20.mat +34 -0
  117. biotite/sequence/align/matrix_data/PAM200.mat +34 -0
  118. biotite/sequence/align/matrix_data/PAM210.mat +34 -0
  119. biotite/sequence/align/matrix_data/PAM220.mat +34 -0
  120. biotite/sequence/align/matrix_data/PAM230.mat +34 -0
  121. biotite/sequence/align/matrix_data/PAM240.mat +34 -0
  122. biotite/sequence/align/matrix_data/PAM250.mat +34 -0
  123. biotite/sequence/align/matrix_data/PAM260.mat +34 -0
  124. biotite/sequence/align/matrix_data/PAM270.mat +34 -0
  125. biotite/sequence/align/matrix_data/PAM280.mat +34 -0
  126. biotite/sequence/align/matrix_data/PAM290.mat +34 -0
  127. biotite/sequence/align/matrix_data/PAM30.mat +34 -0
  128. biotite/sequence/align/matrix_data/PAM300.mat +34 -0
  129. biotite/sequence/align/matrix_data/PAM310.mat +34 -0
  130. biotite/sequence/align/matrix_data/PAM320.mat +34 -0
  131. biotite/sequence/align/matrix_data/PAM330.mat +34 -0
  132. biotite/sequence/align/matrix_data/PAM340.mat +34 -0
  133. biotite/sequence/align/matrix_data/PAM350.mat +34 -0
  134. biotite/sequence/align/matrix_data/PAM360.mat +34 -0
  135. biotite/sequence/align/matrix_data/PAM370.mat +34 -0
  136. biotite/sequence/align/matrix_data/PAM380.mat +34 -0
  137. biotite/sequence/align/matrix_data/PAM390.mat +34 -0
  138. biotite/sequence/align/matrix_data/PAM40.mat +34 -0
  139. biotite/sequence/align/matrix_data/PAM400.mat +34 -0
  140. biotite/sequence/align/matrix_data/PAM410.mat +34 -0
  141. biotite/sequence/align/matrix_data/PAM420.mat +34 -0
  142. biotite/sequence/align/matrix_data/PAM430.mat +34 -0
  143. biotite/sequence/align/matrix_data/PAM440.mat +34 -0
  144. biotite/sequence/align/matrix_data/PAM450.mat +34 -0
  145. biotite/sequence/align/matrix_data/PAM460.mat +34 -0
  146. biotite/sequence/align/matrix_data/PAM470.mat +34 -0
  147. biotite/sequence/align/matrix_data/PAM480.mat +34 -0
  148. biotite/sequence/align/matrix_data/PAM490.mat +34 -0
  149. biotite/sequence/align/matrix_data/PAM50.mat +34 -0
  150. biotite/sequence/align/matrix_data/PAM500.mat +34 -0
  151. biotite/sequence/align/matrix_data/PAM60.mat +34 -0
  152. biotite/sequence/align/matrix_data/PAM70.mat +34 -0
  153. biotite/sequence/align/matrix_data/PAM80.mat +34 -0
  154. biotite/sequence/align/matrix_data/PAM90.mat +34 -0
  155. biotite/sequence/align/matrix_data/PB.license +21 -0
  156. biotite/sequence/align/matrix_data/PB.mat +18 -0
  157. biotite/sequence/align/matrix_data/RBLOSUM52_5.0.mat +25 -0
  158. biotite/sequence/align/matrix_data/RBLOSUM59_13p.mat +25 -0
  159. biotite/sequence/align/matrix_data/RBLOSUM59_14.3.mat +25 -0
  160. biotite/sequence/align/matrix_data/RBLOSUM64_5.0.mat +25 -0
  161. biotite/sequence/align/matrix_data/RBLOSUM69_13p.mat +25 -0
  162. biotite/sequence/align/matrix_data/RBLOSUM69_14.3.mat +25 -0
  163. biotite/sequence/align/multiple.cp313-win_amd64.pyd +0 -0
  164. biotite/sequence/align/multiple.pyx +620 -0
  165. biotite/sequence/align/pairwise.cp313-win_amd64.pyd +0 -0
  166. biotite/sequence/align/pairwise.pyx +587 -0
  167. biotite/sequence/align/permutation.cp313-win_amd64.pyd +0 -0
  168. biotite/sequence/align/permutation.pyx +313 -0
  169. biotite/sequence/align/primes.txt +821 -0
  170. biotite/sequence/align/selector.cp313-win_amd64.pyd +0 -0
  171. biotite/sequence/align/selector.pyx +954 -0
  172. biotite/sequence/align/statistics.py +264 -0
  173. biotite/sequence/align/tracetable.cp313-win_amd64.pyd +0 -0
  174. biotite/sequence/align/tracetable.pxd +64 -0
  175. biotite/sequence/align/tracetable.pyx +370 -0
  176. biotite/sequence/alphabet.py +555 -0
  177. biotite/sequence/annotation.py +830 -0
  178. biotite/sequence/codec.cp313-win_amd64.pyd +0 -0
  179. biotite/sequence/codec.pyx +155 -0
  180. biotite/sequence/codon.py +477 -0
  181. biotite/sequence/codon_tables.txt +202 -0
  182. biotite/sequence/graphics/__init__.py +33 -0
  183. biotite/sequence/graphics/alignment.py +1115 -0
  184. biotite/sequence/graphics/color_schemes/3di_flower.json +48 -0
  185. biotite/sequence/graphics/color_schemes/autumn.json +51 -0
  186. biotite/sequence/graphics/color_schemes/blossom.json +51 -0
  187. biotite/sequence/graphics/color_schemes/clustalx_dna.json +11 -0
  188. biotite/sequence/graphics/color_schemes/clustalx_protein.json +28 -0
  189. biotite/sequence/graphics/color_schemes/flower.json +51 -0
  190. biotite/sequence/graphics/color_schemes/jalview_buried.json +31 -0
  191. biotite/sequence/graphics/color_schemes/jalview_hydrophobicity.json +31 -0
  192. biotite/sequence/graphics/color_schemes/jalview_prop_helix.json +31 -0
  193. biotite/sequence/graphics/color_schemes/jalview_prop_strand.json +31 -0
  194. biotite/sequence/graphics/color_schemes/jalview_prop_turn.json +31 -0
  195. biotite/sequence/graphics/color_schemes/jalview_taylor.json +28 -0
  196. biotite/sequence/graphics/color_schemes/jalview_zappo.json +28 -0
  197. biotite/sequence/graphics/color_schemes/ocean.json +51 -0
  198. biotite/sequence/graphics/color_schemes/pb_flower.json +40 -0
  199. biotite/sequence/graphics/color_schemes/rainbow_dna.json +11 -0
  200. biotite/sequence/graphics/color_schemes/rainbow_protein.json +30 -0
  201. biotite/sequence/graphics/color_schemes/spring.json +51 -0
  202. biotite/sequence/graphics/color_schemes/sunset.json +51 -0
  203. biotite/sequence/graphics/color_schemes/wither.json +51 -0
  204. biotite/sequence/graphics/colorschemes.py +170 -0
  205. biotite/sequence/graphics/dendrogram.py +229 -0
  206. biotite/sequence/graphics/features.py +544 -0
  207. biotite/sequence/graphics/logo.py +104 -0
  208. biotite/sequence/graphics/plasmid.py +712 -0
  209. biotite/sequence/io/__init__.py +12 -0
  210. biotite/sequence/io/fasta/__init__.py +22 -0
  211. biotite/sequence/io/fasta/convert.py +284 -0
  212. biotite/sequence/io/fasta/file.py +265 -0
  213. biotite/sequence/io/fastq/__init__.py +19 -0
  214. biotite/sequence/io/fastq/convert.py +117 -0
  215. biotite/sequence/io/fastq/file.py +507 -0
  216. biotite/sequence/io/genbank/__init__.py +17 -0
  217. biotite/sequence/io/genbank/annotation.py +269 -0
  218. biotite/sequence/io/genbank/file.py +573 -0
  219. biotite/sequence/io/genbank/metadata.py +336 -0
  220. biotite/sequence/io/genbank/sequence.py +171 -0
  221. biotite/sequence/io/general.py +201 -0
  222. biotite/sequence/io/gff/__init__.py +26 -0
  223. biotite/sequence/io/gff/convert.py +128 -0
  224. biotite/sequence/io/gff/file.py +450 -0
  225. biotite/sequence/phylo/__init__.py +36 -0
  226. biotite/sequence/phylo/nj.cp313-win_amd64.pyd +0 -0
  227. biotite/sequence/phylo/nj.pyx +221 -0
  228. biotite/sequence/phylo/tree.cp313-win_amd64.pyd +0 -0
  229. biotite/sequence/phylo/tree.pyx +1169 -0
  230. biotite/sequence/phylo/upgma.cp313-win_amd64.pyd +0 -0
  231. biotite/sequence/phylo/upgma.pyx +164 -0
  232. biotite/sequence/profile.py +567 -0
  233. biotite/sequence/search.py +118 -0
  234. biotite/sequence/seqtypes.py +713 -0
  235. biotite/sequence/sequence.py +374 -0
  236. biotite/setup_ccd.py +197 -0
  237. biotite/structure/__init__.py +133 -0
  238. biotite/structure/alphabet/__init__.py +25 -0
  239. biotite/structure/alphabet/encoder.py +332 -0
  240. biotite/structure/alphabet/encoder_weights_3di.kerasify +0 -0
  241. biotite/structure/alphabet/i3d.py +110 -0
  242. biotite/structure/alphabet/layers.py +86 -0
  243. biotite/structure/alphabet/pb.license +21 -0
  244. biotite/structure/alphabet/pb.py +171 -0
  245. biotite/structure/alphabet/unkerasify.py +122 -0
  246. biotite/structure/atoms.py +1554 -0
  247. biotite/structure/basepairs.py +1404 -0
  248. biotite/structure/bonds.cp313-win_amd64.pyd +0 -0
  249. biotite/structure/bonds.pyx +1972 -0
  250. biotite/structure/box.py +588 -0
  251. biotite/structure/celllist.cp313-win_amd64.pyd +0 -0
  252. biotite/structure/celllist.pyx +849 -0
  253. biotite/structure/chains.py +314 -0
  254. biotite/structure/charges.cp313-win_amd64.pyd +0 -0
  255. biotite/structure/charges.pyx +520 -0
  256. biotite/structure/compare.py +274 -0
  257. biotite/structure/density.py +109 -0
  258. biotite/structure/dotbracket.py +214 -0
  259. biotite/structure/error.py +39 -0
  260. biotite/structure/filter.py +590 -0
  261. biotite/structure/geometry.py +655 -0
  262. biotite/structure/graphics/__init__.py +13 -0
  263. biotite/structure/graphics/atoms.py +243 -0
  264. biotite/structure/graphics/rna.py +295 -0
  265. biotite/structure/hbond.py +428 -0
  266. biotite/structure/info/__init__.py +24 -0
  267. biotite/structure/info/atom_masses.json +121 -0
  268. biotite/structure/info/atoms.py +81 -0
  269. biotite/structure/info/bonds.py +149 -0
  270. biotite/structure/info/ccd.py +202 -0
  271. biotite/structure/info/components.bcif +0 -0
  272. biotite/structure/info/groups.py +131 -0
  273. biotite/structure/info/masses.py +121 -0
  274. biotite/structure/info/misc.py +138 -0
  275. biotite/structure/info/radii.py +197 -0
  276. biotite/structure/info/standardize.py +186 -0
  277. biotite/structure/integrity.py +215 -0
  278. biotite/structure/io/__init__.py +29 -0
  279. biotite/structure/io/dcd/__init__.py +13 -0
  280. biotite/structure/io/dcd/file.py +67 -0
  281. biotite/structure/io/general.py +243 -0
  282. biotite/structure/io/gro/__init__.py +14 -0
  283. biotite/structure/io/gro/file.py +344 -0
  284. biotite/structure/io/mol/__init__.py +20 -0
  285. biotite/structure/io/mol/convert.py +112 -0
  286. biotite/structure/io/mol/ctab.py +415 -0
  287. biotite/structure/io/mol/header.py +120 -0
  288. biotite/structure/io/mol/mol.py +149 -0
  289. biotite/structure/io/mol/sdf.py +914 -0
  290. biotite/structure/io/netcdf/__init__.py +13 -0
  291. biotite/structure/io/netcdf/file.py +64 -0
  292. biotite/structure/io/pdb/__init__.py +20 -0
  293. biotite/structure/io/pdb/convert.py +307 -0
  294. biotite/structure/io/pdb/file.py +1290 -0
  295. biotite/structure/io/pdb/hybrid36.cp313-win_amd64.pyd +0 -0
  296. biotite/structure/io/pdb/hybrid36.pyx +242 -0
  297. biotite/structure/io/pdbqt/__init__.py +15 -0
  298. biotite/structure/io/pdbqt/convert.py +113 -0
  299. biotite/structure/io/pdbqt/file.py +688 -0
  300. biotite/structure/io/pdbx/__init__.py +23 -0
  301. biotite/structure/io/pdbx/bcif.py +656 -0
  302. biotite/structure/io/pdbx/cif.py +1075 -0
  303. biotite/structure/io/pdbx/component.py +245 -0
  304. biotite/structure/io/pdbx/compress.py +321 -0
  305. biotite/structure/io/pdbx/convert.py +1745 -0
  306. biotite/structure/io/pdbx/encoding.cp313-win_amd64.pyd +0 -0
  307. biotite/structure/io/pdbx/encoding.pyx +1031 -0
  308. biotite/structure/io/trajfile.py +693 -0
  309. biotite/structure/io/trr/__init__.py +13 -0
  310. biotite/structure/io/trr/file.py +43 -0
  311. biotite/structure/io/xtc/__init__.py +13 -0
  312. biotite/structure/io/xtc/file.py +43 -0
  313. biotite/structure/mechanics.py +73 -0
  314. biotite/structure/molecules.py +352 -0
  315. biotite/structure/pseudoknots.py +628 -0
  316. biotite/structure/rdf.py +245 -0
  317. biotite/structure/repair.py +304 -0
  318. biotite/structure/residues.py +572 -0
  319. biotite/structure/sasa.cp313-win_amd64.pyd +0 -0
  320. biotite/structure/sasa.pyx +322 -0
  321. biotite/structure/segments.py +178 -0
  322. biotite/structure/sequence.py +111 -0
  323. biotite/structure/sse.py +308 -0
  324. biotite/structure/superimpose.py +689 -0
  325. biotite/structure/transform.py +530 -0
  326. biotite/structure/util.py +168 -0
  327. biotite/version.py +16 -0
  328. biotite/visualize.py +265 -0
  329. biotite-1.1.0.dist-info/METADATA +190 -0
  330. biotite-1.1.0.dist-info/RECORD +332 -0
  331. biotite-1.1.0.dist-info/WHEEL +4 -0
  332. biotite-1.1.0.dist-info/licenses/LICENSE.rst +30 -0
@@ -0,0 +1,428 @@
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
+ This module provides functions for hydrogen bonding calculation.
7
+ """
8
+
9
+ __name__ = "biotite.structure"
10
+ __author__ = "Daniel Bauer, Patrick Kunzmann"
11
+ __all__ = ["hbond", "hbond_frequency"]
12
+
13
+ import warnings
14
+ import numpy as np
15
+ from biotite.structure.atoms import AtomArrayStack, stack
16
+ from biotite.structure.celllist import CellList
17
+ from biotite.structure.geometry import angle, distance
18
+
19
+
20
+ def hbond(
21
+ atoms,
22
+ selection1=None,
23
+ selection2=None,
24
+ selection1_type="both",
25
+ cutoff_dist=2.5,
26
+ cutoff_angle=120,
27
+ donor_elements=("O", "N", "S"),
28
+ acceptor_elements=("O", "N", "S"),
29
+ periodic=False,
30
+ ):
31
+ r"""
32
+ Find hydrogen bonds in a structure using the Baker-Hubbard
33
+ algorithm. :footcite:`Baker1984`
34
+
35
+ This function identifies hydrogen bonds based on the bond angle
36
+ :math:`\theta` and the bond distance :math:`d_{H,A}`.
37
+ The default criteria is :math:`\theta > 120^{\circ}`
38
+ and :math:`d_{H,A} \le 2.5 \mathring{A}`.
39
+ Consequently, the given structure must contain hydrogen atoms.
40
+ Otherwise, no hydrogen bonds will be found.
41
+
42
+ Parameters
43
+ ----------
44
+ atoms : AtomArray or AtomArrayStack
45
+ The atoms to find hydrogen bonds in.
46
+ selection1, selection2: ndarray or None
47
+ Boolean mask for atoms to limit the hydrogen bond search to
48
+ specific sections of the model. The shape must match the
49
+ shape of the `atoms` argument. If None is given, the whole atoms
50
+ stack is used instead. (Default: None)
51
+ selection1_type: {'acceptor', 'donor', 'both'}, optional (default: 'both')
52
+ Determines the type of `selection1`.
53
+ The type of `selection2` is chosen accordingly
54
+ ('both' or the opposite).
55
+ (Default: 'both')
56
+ cutoff_dist : float, optional
57
+ The maximal distance between the hydrogen and acceptor to be
58
+ considered a hydrogen bond. (Default: 2.5)
59
+ cutoff_angle : float, optional
60
+ The angle cutoff in degree between Donor-H..Acceptor to be
61
+ considered a hydrogen bond (default: 120).
62
+ donor_elements, acceptor_elements: tuple of str
63
+ Elements to be considered as possible donors or acceptors
64
+ (Default: O, N, S).
65
+ periodic : bool, optional
66
+ If true, hydrogen bonds can also be detected in periodic
67
+ boundary conditions.
68
+ The `box` attribute of `atoms` is required in this case.
69
+ (Default: False).
70
+
71
+ Returns
72
+ -------
73
+ triplets : ndarray, dtype=int, shape=(n,3)
74
+ *n x 3* matrix containing the indices of every Donor-H..Acceptor
75
+ interaction that is available in any of the models.
76
+ *n* is the number of found interactions.
77
+ The three matrix columns are *D_index*, *H_index*, *A_index*.
78
+ If only one model (`AtomArray`) is given, `triplets` contains
79
+ all of its hydrogen bonds.
80
+ mask : ndarry, dtype=bool, shape=(m,n)
81
+ *m x n* matrix that shows if an interaction with index *n* in
82
+ `triplets` is present in the model *m* of the input `atoms`.
83
+ Only returned if `atoms` is an :class:`AtomArrayStack`.
84
+
85
+ Notes
86
+ -----
87
+ The result of this function may include false positives:
88
+ Only the chemical elements and the bond geometry is checked.
89
+ However, there are some cases where a hydrogen bond is still not
90
+ reasonable.
91
+ For example, a nitrogen atom with positive charge could be
92
+ considered as acceptor atom by this method, although this does
93
+ make sense from a chemical perspective.
94
+
95
+ Examples
96
+ --------
97
+ Calculate the total number of hydrogen bonds found in each model:
98
+
99
+ >>> triplets, mask = hbond(atom_array_stack)
100
+ >>> hbonds_per_model = np.count_nonzero(mask, axis=1)
101
+ >>> print(hbonds_per_model)
102
+ [14 14 14 12 11 12 9 13 9 14 13 13 14 11 11 12 11 14 14 13 14 13 15 17
103
+ 14 12 15 12 12 13 13 13 12 12 11 14 10 11]
104
+
105
+ Get hydrogen bond donors of third model:
106
+
107
+ >>> # Third model -> index 2
108
+ >>> triplets = triplets[mask[2,:]]
109
+ >>> # First column contains donors
110
+ >>> print(atom_array_stack[2, triplets[:,0]])
111
+ A 5 GLN N N -5.009 -0.575 -1.365
112
+ A 6 TRP N N -2.154 -0.497 -1.588
113
+ A 7 LEU N N -1.520 -1.904 0.893
114
+ A 8 LYS N N -2.716 -4.413 0.176
115
+ A 8 LYS NZ N -6.352 -4.311 -4.482
116
+ A 9 ASP N N -0.694 -5.301 -1.644
117
+ A 11 GLY N N 2.142 -4.244 1.916
118
+ A 10 GLY N N 1.135 -6.232 0.250
119
+ A 14 SER OG O 4.689 -5.759 -2.390
120
+ A 13 SER N N 6.424 -5.220 3.257
121
+ A 14 SER N N 6.424 -5.506 0.464
122
+ A 15 GLY N N 8.320 -3.632 -0.318
123
+ A 16 ARG N N 8.043 -1.206 -1.866
124
+ A 6 TRP NE1 N 3.420 0.332 -0.121
125
+
126
+ See Also
127
+ --------
128
+ hbond_frequency
129
+
130
+ References
131
+ ----------
132
+
133
+ .. footbibliography::
134
+ """
135
+ if not (atoms.element == "H").any():
136
+ warnings.warn(
137
+ "Input structure does not contain hydrogen atoms, "
138
+ "hence no hydrogen bonds can be identified"
139
+ )
140
+
141
+ # Create AtomArrayStack from AtomArray
142
+ if not isinstance(atoms, AtomArrayStack):
143
+ atoms = stack([atoms])
144
+ single_model = True
145
+ else:
146
+ single_model = False
147
+
148
+ if periodic:
149
+ box = atoms.box
150
+ else:
151
+ box = None
152
+
153
+ # Mask for donor/acceptor elements
154
+ donor_element_mask = np.isin(atoms.element, donor_elements)
155
+ acceptor_element_mask = np.isin(atoms.element, acceptor_elements)
156
+
157
+ if selection1 is None:
158
+ selection1 = np.ones(atoms.array_length(), dtype=bool)
159
+ if selection2 is None:
160
+ selection2 = np.ones(atoms.array_length(), dtype=bool)
161
+
162
+ if selection1_type == "both":
163
+ # The two selections are separated into three selections:
164
+ # the original ones without the overlaping part
165
+ # and one containing the overlap
166
+ # This prevents redundant triplets and unnecessary computation
167
+ overlap_selection = selection1 & selection2
168
+ # Original selections without overlaping part
169
+ exclusive_selection1 = selection1 & (~overlap_selection)
170
+ exclusive_selection2 = selection2 & (~overlap_selection)
171
+
172
+ # Put selections to list for cleaner iteration
173
+ selections = [exclusive_selection1, exclusive_selection2, overlap_selection]
174
+ selection_combinations = [
175
+ # (0,0), is not included, would be same selection
176
+ # as donor and acceptor simultaneously
177
+ (0, 1),
178
+ (0, 2),
179
+ (1, 0),
180
+ # (1,1), # same reason above
181
+ (1, 2),
182
+ (2, 0),
183
+ (2, 1),
184
+ (2, 2), # overlaping part, combination is necessary
185
+ ]
186
+
187
+ all_comb_triplets = []
188
+ all_comb_mask = []
189
+ for selection_index1, selection_index2 in selection_combinations:
190
+ donor_mask = selections[selection_index1]
191
+ acceptor_mask = selections[selection_index2]
192
+ if (
193
+ np.count_nonzero(donor_mask) != 0
194
+ and np.count_nonzero(acceptor_mask) != 0
195
+ ):
196
+ # Calculate triplets and mask
197
+ triplets, mask = _hbond(
198
+ atoms,
199
+ donor_mask,
200
+ acceptor_mask,
201
+ donor_element_mask,
202
+ acceptor_element_mask,
203
+ cutoff_dist,
204
+ cutoff_angle,
205
+ box,
206
+ )
207
+ all_comb_triplets.append(triplets)
208
+ all_comb_mask.append(mask)
209
+ # Merge results from all combinations
210
+ triplets = np.concatenate(all_comb_triplets, axis=0)
211
+ mask = np.concatenate(all_comb_mask, axis=1)
212
+
213
+ elif selection1_type == "donor":
214
+ triplets, mask = _hbond(
215
+ atoms,
216
+ selection1,
217
+ selection2,
218
+ donor_element_mask,
219
+ acceptor_element_mask,
220
+ cutoff_dist,
221
+ cutoff_angle,
222
+ box,
223
+ )
224
+
225
+ elif selection1_type == "acceptor":
226
+ triplets, mask = _hbond(
227
+ atoms,
228
+ selection2,
229
+ selection1,
230
+ donor_element_mask,
231
+ acceptor_element_mask,
232
+ cutoff_dist,
233
+ cutoff_angle,
234
+ box,
235
+ )
236
+
237
+ else:
238
+ raise ValueError(f"Unkown selection type '{selection1_type}'")
239
+
240
+ if single_model:
241
+ # For a atom array (not stack),
242
+ # hbond_mask contains only 'True' values,
243
+ # since all interaction are in the one model
244
+ # -> Simply return triplets without hbond_mask
245
+ return triplets
246
+ else:
247
+ return triplets, mask
248
+
249
+
250
+ def _hbond(
251
+ atoms,
252
+ donor_mask,
253
+ acceptor_mask,
254
+ donor_element_mask,
255
+ acceptor_element_mask,
256
+ cutoff_dist,
257
+ cutoff_angle,
258
+ box,
259
+ ):
260
+ # Filter donor/acceptor elements
261
+ donor_mask &= donor_element_mask
262
+ acceptor_mask &= acceptor_element_mask
263
+
264
+ first_model_box = box[0] if box is not None else None
265
+ if atoms.bonds is not None:
266
+ donor_h_mask, associated_donor_indices = _get_bonded_h(
267
+ atoms[0], donor_mask, atoms.bonds
268
+ )
269
+ else:
270
+ warnings.warn(
271
+ "Input structure has no associated 'BondList', "
272
+ "Hydrogen atoms bonded to donors are detected by distance"
273
+ )
274
+ donor_h_mask, associated_donor_indices = _get_bonded_h_via_distance(
275
+ atoms[0], donor_mask, first_model_box
276
+ )
277
+ donor_h_i = np.where(donor_h_mask)[0]
278
+ acceptor_i = np.where(acceptor_mask)[0]
279
+ if len(donor_h_i) == 0 or len(acceptor_i) == 0:
280
+ # Return empty triplets and mask
281
+ return (
282
+ np.zeros((0, 3), dtype=int),
283
+ np.zeros((atoms.stack_depth(), 0), dtype=bool),
284
+ )
285
+
286
+ # Narrow the amount of possible acceptor to donor-H connections
287
+ # down via the distance cutoff parameter using a cell list
288
+ # Save in acceptor-to-hydrogen matrix
289
+ # (true when distance smaller than cutoff)
290
+ coord = atoms.coord
291
+ possible_bonds = np.zeros((len(acceptor_i), len(donor_h_i)), dtype=bool)
292
+ periodic = False if box is None else True
293
+ for model_i in range(atoms.stack_depth()):
294
+ donor_h_coord = coord[model_i, donor_h_mask]
295
+ acceptor_coord = coord[model_i, acceptor_mask]
296
+ box_for_model = box[model_i] if box is not None else None
297
+ cell_list = CellList(
298
+ donor_h_coord, cell_size=cutoff_dist, periodic=periodic, box=box_for_model
299
+ )
300
+ possible_bonds |= cell_list.get_atoms_in_cells(acceptor_coord, as_mask=True)
301
+ possible_bonds_i = np.where(possible_bonds)
302
+ # Narrow down
303
+ acceptor_i = acceptor_i[possible_bonds_i[0]]
304
+ donor_h_i = donor_h_i[possible_bonds_i[1]]
305
+
306
+ # Build D-H..A triplets
307
+ donor_i = associated_donor_indices[donor_h_i]
308
+ triplets = np.stack((donor_i, donor_h_i, acceptor_i), axis=1)
309
+ # Remove entries where donor and acceptor are the same
310
+ triplets = triplets[donor_i != acceptor_i]
311
+
312
+ hbond_mask = _is_hbond(
313
+ coord[:, triplets[:, 0]], # donors
314
+ coord[:, triplets[:, 1]], # donor hydrogens
315
+ coord[:, triplets[:, 2]], # acceptors
316
+ box,
317
+ cutoff_dist=cutoff_dist,
318
+ cutoff_angle=cutoff_angle,
319
+ )
320
+
321
+ # Reduce output to contain only triplets counted at least once
322
+ is_counted = hbond_mask.any(axis=0)
323
+ triplets = triplets[is_counted]
324
+ hbond_mask = hbond_mask[:, is_counted]
325
+
326
+ return triplets, hbond_mask
327
+
328
+
329
+ def _get_bonded_h(array, donor_mask, bonds):
330
+ """
331
+ Helper function to find indices of associated hydrogens in atoms for
332
+ all donors in atoms[donor_mask].
333
+ A `BondsList` is used for detecting bonded hydrogen atoms.
334
+ """
335
+ hydrogen_mask = array.element == "H"
336
+
337
+ donor_hydrogen_mask = np.zeros(len(array), dtype=bool)
338
+ associated_donor_indices = np.full(len(array), -1, dtype=int)
339
+
340
+ all_bond_indices, _ = bonds.get_all_bonds()
341
+ donor_indices = np.where(donor_mask)[0]
342
+
343
+ for donor_i in donor_indices:
344
+ bonded_indices = all_bond_indices[donor_i]
345
+ # Remove padding values
346
+ bonded_indices = bonded_indices[bonded_indices != -1]
347
+ # Filter hydrogen atoms
348
+ bonded_indices = bonded_indices[hydrogen_mask[bonded_indices]]
349
+ donor_hydrogen_mask[bonded_indices] = True
350
+ associated_donor_indices[bonded_indices] = donor_i
351
+
352
+ return donor_hydrogen_mask, associated_donor_indices
353
+
354
+
355
+ def _get_bonded_h_via_distance(array, donor_mask, box):
356
+ """
357
+ Helper function to find indices of associated hydrogens in atoms for
358
+ all donors in atoms[donor_mask].
359
+ The criterium is that the hydrogen must be in the same residue and
360
+ the distance must be smaller than the cutoff.
361
+ """
362
+ CUTOFF = 1.5
363
+
364
+ coord = array.coord
365
+ res_id = array.res_id
366
+ hydrogen_mask = array.element == "H"
367
+
368
+ donor_hydrogen_mask = np.zeros(len(array), dtype=bool)
369
+ associated_donor_indices = np.full(len(array), -1, dtype=int)
370
+
371
+ donor_indices = np.where(donor_mask)[0]
372
+ for donor_i in donor_indices:
373
+ candidate_mask = hydrogen_mask & (res_id == res_id[donor_i])
374
+ distances = distance(coord[donor_i], coord[candidate_mask], box=box)
375
+ donor_h_indices = np.where(candidate_mask)[0][distances <= CUTOFF]
376
+ for i in donor_h_indices:
377
+ associated_donor_indices[i] = donor_i
378
+ donor_hydrogen_mask[i] = True
379
+
380
+ return donor_hydrogen_mask, associated_donor_indices
381
+
382
+
383
+ def _is_hbond(donor, donor_h, acceptor, box, cutoff_dist, cutoff_angle):
384
+ """
385
+ Filter triplets that meet distance and angle condition.
386
+ """
387
+ cutoff_angle_rad = np.deg2rad(cutoff_angle)
388
+ theta = angle(donor, donor_h, acceptor, box=box)
389
+ dist = distance(donor_h, acceptor, box=box)
390
+ return (theta > cutoff_angle_rad) & (dist <= cutoff_dist)
391
+
392
+
393
+ def hbond_frequency(mask):
394
+ """
395
+ Get the relative frequency of each hydrogen bond in a multi-model
396
+ structure.
397
+
398
+ The frequency is the amount of models, where the respective bond
399
+ exists divided by the total amount of models.
400
+
401
+ Parameters
402
+ ----------
403
+ mask: ndarray, dtype=bool, shape=(m,n)
404
+ Input mask obtained from `hbond` function.
405
+
406
+ Returns
407
+ -------
408
+ ndarray, dtype=Float
409
+ For each individual interaction *n* of the mask, returns the
410
+ percentage of models *m*, in which this hydrogen bond is
411
+ present.
412
+
413
+ See Also
414
+ --------
415
+ hbond
416
+
417
+ Examples
418
+ --------
419
+
420
+ >>> triplets, mask = hbond(atom_array_stack)
421
+ >>> freq = hbond_frequency(mask)
422
+ >>> print(freq)
423
+ [0.263 0.289 0.105 0.105 0.237 0.026 0.053 0.395 1.000 1.000 1.000 0.026
424
+ 0.421 0.026 0.026 0.316 0.816 0.026 0.921 0.026 0.342 0.026 0.105 0.026
425
+ 0.132 0.053 0.026 0.158 0.026 0.868 0.211 0.026 0.921 0.316 0.079 0.237
426
+ 0.105 0.421 0.079 0.026 1.000 0.053 0.132 0.026 0.184]
427
+ """
428
+ return mask.sum(axis=0) / len(mask)
@@ -0,0 +1,24 @@
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 obtaining all kinds of chemical information about atoms
7
+ and residues, including masses, radii, bonds, etc.
8
+
9
+ Most information is extracted from the *Chemical Component Dictionary*
10
+ of the
11
+ `wwPDB <ftp://ftp.wwpdb.org/pub/pdb/data/monomers/components.cif>`_.
12
+ """
13
+
14
+ __name__ = "biotite.structure.info"
15
+ __author__ = "Patrick Kunzmann, Tom David Müller"
16
+
17
+ from .atoms import *
18
+ from .bonds import *
19
+ from .ccd import *
20
+ from .groups import *
21
+ from .masses import *
22
+ from .misc import *
23
+ from .radii import *
24
+ from .standardize import *
@@ -0,0 +1,121 @@
1
+ {
2
+ "H" : 1.008,
3
+ "D" : 2.014,
4
+ "HE" : 4.002,
5
+ "LI" : 6.940,
6
+ "BE" : 9.012,
7
+ "B" : 10.810,
8
+ "C" : 12.011,
9
+ "N" : 14.007,
10
+ "O" : 15.999,
11
+ "F" : 18.998,
12
+ "NE" : 20.180,
13
+ "NA" : 22.989,
14
+ "MG" : 24.305,
15
+ "AL" : 26.981,
16
+ "SI" : 28.085,
17
+ "P" : 30.973,
18
+ "S" : 32.060,
19
+ "CL" : 35.450,
20
+ "AR" : 39.948,
21
+ "K" : 39.098,
22
+ "CA" : 40.078,
23
+ "SC" : 44.955,
24
+ "TI" : 47.867,
25
+ "V" : 50.941,
26
+ "CR" : 51.996,
27
+ "MN" : 54.938,
28
+ "FE" : 55.845,
29
+ "CO" : 58.933,
30
+ "NI" : 58.693,
31
+ "CU" : 63.546,
32
+ "ZN" : 65.380,
33
+ "GA" : 69.723,
34
+ "GE" : 72.630,
35
+ "AS" : 74.921,
36
+ "SE" : 78.971,
37
+ "BR" : 79.904,
38
+ "KR" : 83.798,
39
+ "RB" : 85.468,
40
+ "SR" : 87.620,
41
+ "Y" : 88.905,
42
+ "ZR" : 91.224,
43
+ "NB" : 92.906,
44
+ "MO" : 95.950,
45
+ "TC" : 97.000,
46
+ "RU" : 101.070,
47
+ "RH" : 102.905,
48
+ "PD" : 106.420,
49
+ "AG" : 107.868,
50
+ "CD" : 112.414,
51
+ "IN" : 114.818,
52
+ "SN" : 118.710,
53
+ "SB" : 121.760,
54
+ "TE" : 127.600,
55
+ "I" : 126.904,
56
+ "XE" : 131.293,
57
+ "CS" : 132.905,
58
+ "BA" : 137.327,
59
+ "LA" : 138.905,
60
+ "CE" : 140.116,
61
+ "PR" : 140.907,
62
+ "ND" : 144.242,
63
+ "PM" : 145.000,
64
+ "SM" : 150.360,
65
+ "EU" : 151.964,
66
+ "GD" : 157.250,
67
+ "TB" : 158.925,
68
+ "DY" : 162.500,
69
+ "HO" : 164.930,
70
+ "ER" : 167.259,
71
+ "TM" : 168.934,
72
+ "YB" : 173.045,
73
+ "LU" : 174.967,
74
+ "HF" : 178.490,
75
+ "TA" : 180.947,
76
+ "W" : 183.840,
77
+ "RE" : 186.207,
78
+ "OS" : 190.230,
79
+ "IR" : 192.217,
80
+ "PT" : 195.084,
81
+ "AU" : 196.966,
82
+ "HG" : 200.592,
83
+ "TL" : 204.380,
84
+ "PB" : 207.200,
85
+ "BI" : 208.980,
86
+ "PO" : 209.000,
87
+ "AT" : 210.000,
88
+ "RN" : 222.000,
89
+ "FR" : 223.000,
90
+ "RA" : 226.000,
91
+ "AC" : 227.000,
92
+ "TH" : 232.038,
93
+ "PA" : 231.035,
94
+ "U" : 238.028,
95
+ "NP" : 237.000,
96
+ "PU" : 244.000,
97
+ "AM" : 243.000,
98
+ "CM" : 247.000,
99
+ "BK" : 247.000,
100
+ "CF" : 251.000,
101
+ "ES" : 252.000,
102
+ "FM" : 257.000,
103
+ "MD" : 258.000,
104
+ "NO" : 259.000,
105
+ "LR" : 262.000,
106
+ "RF" : 267.000,
107
+ "DB" : 270.000,
108
+ "SG" : 269.000,
109
+ "BH" : 270.000,
110
+ "HS" : 270.000,
111
+ "MT" : 278.000,
112
+ "DS" : 281.000,
113
+ "RG" : 281.000,
114
+ "CN" : 285.000,
115
+ "NH" : 286.000,
116
+ "FL" : 289.000,
117
+ "MC" : 289.000,
118
+ "LV" : 293.000,
119
+ "TS" : 293.000,
120
+ "OG" : 294.000
121
+ }
@@ -0,0 +1,81 @@
1
+ # This source code is part of the Biotite package and is distributed
2
+ # under the 3-Clause BSD License. Please see 'LICENSE.rst' for further
3
+ # information.
4
+
5
+ __name__ = "biotite.structure.info"
6
+ __author__ = "Patrick Kunzmann"
7
+ __all__ = ["residue"]
8
+
9
+ from biotite.structure.info.ccd import get_ccd
10
+
11
+ # fmt: off
12
+ NON_HETERO_RESIDUES = set([
13
+ "ALA", "ARG", "ASN", "ASP", "CYS", "GLN", "GLU", "GLY", "HIS",
14
+ "ILE", "LEU", "LYS", "MET", "PHE", "PRO", "PYL", "SER", "THR",
15
+ "TRP", "TYR", "VAL", "SEC",
16
+ "A", "DA", "G", "DG", "C", "DC", "U", "DT",
17
+ ])
18
+ # fmt: on
19
+
20
+
21
+ def residue(res_name):
22
+ """
23
+ Get an atom array, representing the residue with the given name.
24
+
25
+ This atom array includes proper values for the ``residue_name``,
26
+ ``hetero``, ``atom_name``, ``element`` and ``charge`` annotation
27
+ arrays and bonds and coordinates.
28
+
29
+ Parameters
30
+ ----------
31
+ res_name : str
32
+ The up to 3-letter name of the residue.
33
+
34
+ Returns
35
+ -------
36
+ atom_array : AtomArray
37
+ The atom array described by `res_name`.
38
+
39
+ Examples
40
+ --------
41
+
42
+ >>> alanine = residue("ALA")
43
+ >>> # Atoms and geometry
44
+ >>> print(alanine)
45
+ 0 ALA N N -0.966 0.493 1.500
46
+ 0 ALA CA C 0.257 0.418 0.692
47
+ 0 ALA C C -0.094 0.017 -0.716
48
+ 0 ALA O O -1.056 -0.682 -0.923
49
+ 0 ALA CB C 1.204 -0.620 1.296
50
+ 0 ALA OXT O 0.661 0.439 -1.742
51
+ 0 ALA H H -1.383 -0.425 1.482
52
+ 0 ALA H2 H -0.676 0.661 2.452
53
+ 0 ALA HA H 0.746 1.392 0.682
54
+ 0 ALA HB1 H 1.459 -0.330 2.316
55
+ 0 ALA HB2 H 0.715 -1.594 1.307
56
+ 0 ALA HB3 H 2.113 -0.676 0.697
57
+ 0 ALA HXT H 0.435 0.182 -2.647
58
+ >>> # Bonds
59
+ >>> print(alanine.atom_name[alanine.bonds.as_array()[:,:2]])
60
+ [['N' 'CA']
61
+ ['N' 'H']
62
+ ['N' 'H2']
63
+ ['CA' 'C']
64
+ ['CA' 'CB']
65
+ ['CA' 'HA']
66
+ ['C' 'O']
67
+ ['C' 'OXT']
68
+ ['CB' 'HB1']
69
+ ['CB' 'HB2']
70
+ ['CB' 'HB3']
71
+ ['OXT' 'HXT']]
72
+ """
73
+ # Avoid circular import
74
+ from biotite.structure.io.pdbx import get_component
75
+
76
+ try:
77
+ component = get_component(get_ccd(), res_name=res_name)
78
+ except KeyError:
79
+ raise KeyError(f"No atom information found for residue '{res_name}' in CCD")
80
+ component.hetero[:] = res_name not in NON_HETERO_RESIDUES
81
+ return component