stjames 0.0.47__tar.gz → 0.0.48__tar.gz

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 stjames might be problematic. Click here for more details.

Files changed (66) hide show
  1. {stjames-0.0.47/stjames.egg-info → stjames-0.0.48}/PKG-INFO +3 -2
  2. {stjames-0.0.47 → stjames-0.0.48}/pyproject.toml +5 -3
  3. {stjames-0.0.47 → stjames-0.0.48}/stjames/method.py +12 -4
  4. stjames-0.0.48/stjames/pdb.py +197 -0
  5. {stjames-0.0.47 → stjames-0.0.48}/stjames/settings.py +6 -4
  6. {stjames-0.0.47 → stjames-0.0.48}/stjames/workflows/hydrogen_bond_basicity.py +3 -0
  7. {stjames-0.0.47 → stjames-0.0.48/stjames.egg-info}/PKG-INFO +3 -2
  8. {stjames-0.0.47 → stjames-0.0.48}/stjames.egg-info/SOURCES.txt +2 -0
  9. {stjames-0.0.47 → stjames-0.0.48}/stjames.egg-info/requires.txt +1 -0
  10. stjames-0.0.48/tests/test_pdb.py +44 -0
  11. {stjames-0.0.47 → stjames-0.0.48}/LICENSE +0 -0
  12. {stjames-0.0.47 → stjames-0.0.48}/README.md +0 -0
  13. {stjames-0.0.47 → stjames-0.0.48}/setup.cfg +0 -0
  14. {stjames-0.0.47 → stjames-0.0.48}/stjames/__init__.py +0 -0
  15. {stjames-0.0.47 → stjames-0.0.48}/stjames/_deprecated_solvent_settings.py +0 -0
  16. {stjames-0.0.47 → stjames-0.0.48}/stjames/atom.py +0 -0
  17. {stjames-0.0.47 → stjames-0.0.48}/stjames/base.py +0 -0
  18. {stjames-0.0.47 → stjames-0.0.48}/stjames/basis_set.py +0 -0
  19. {stjames-0.0.47 → stjames-0.0.48}/stjames/calculation.py +0 -0
  20. {stjames-0.0.47 → stjames-0.0.48}/stjames/constraint.py +0 -0
  21. {stjames-0.0.47 → stjames-0.0.48}/stjames/correction.py +0 -0
  22. {stjames-0.0.47 → stjames-0.0.48}/stjames/data/__init__.py +0 -0
  23. {stjames-0.0.47 → stjames-0.0.48}/stjames/data/bragg_radii.json +0 -0
  24. {stjames-0.0.47 → stjames-0.0.48}/stjames/data/elements.py +0 -0
  25. {stjames-0.0.47 → stjames-0.0.48}/stjames/data/isotopes.json +0 -0
  26. {stjames-0.0.47 → stjames-0.0.48}/stjames/data/nist_isotopes.json +0 -0
  27. {stjames-0.0.47 → stjames-0.0.48}/stjames/data/read_nist_isotopes.py +0 -0
  28. {stjames-0.0.47 → stjames-0.0.48}/stjames/data/symbol_element.json +0 -0
  29. {stjames-0.0.47 → stjames-0.0.48}/stjames/diis_settings.py +0 -0
  30. {stjames-0.0.47 → stjames-0.0.48}/stjames/grid_settings.py +0 -0
  31. {stjames-0.0.47 → stjames-0.0.48}/stjames/int_settings.py +0 -0
  32. {stjames-0.0.47 → stjames-0.0.48}/stjames/message.py +0 -0
  33. {stjames-0.0.47 → stjames-0.0.48}/stjames/mode.py +0 -0
  34. {stjames-0.0.47 → stjames-0.0.48}/stjames/molecule.py +0 -0
  35. {stjames-0.0.47 → stjames-0.0.48}/stjames/opt_settings.py +0 -0
  36. {stjames-0.0.47 → stjames-0.0.48}/stjames/periodic_cell.py +0 -0
  37. {stjames-0.0.47 → stjames-0.0.48}/stjames/py.typed +0 -0
  38. {stjames-0.0.47 → stjames-0.0.48}/stjames/scf_settings.py +0 -0
  39. {stjames-0.0.47 → stjames-0.0.48}/stjames/solvent.py +0 -0
  40. {stjames-0.0.47 → stjames-0.0.48}/stjames/status.py +0 -0
  41. {stjames-0.0.47 → stjames-0.0.48}/stjames/task.py +0 -0
  42. {stjames-0.0.47 → stjames-0.0.48}/stjames/thermochem_settings.py +0 -0
  43. {stjames-0.0.47 → stjames-0.0.48}/stjames/types.py +0 -0
  44. {stjames-0.0.47 → stjames-0.0.48}/stjames/workflows/__init__.py +0 -0
  45. {stjames-0.0.47 → stjames-0.0.48}/stjames/workflows/admet.py +0 -0
  46. {stjames-0.0.47 → stjames-0.0.48}/stjames/workflows/basic_calculation.py +0 -0
  47. {stjames-0.0.47 → stjames-0.0.48}/stjames/workflows/bde.py +0 -0
  48. {stjames-0.0.47 → stjames-0.0.48}/stjames/workflows/conformer.py +0 -0
  49. {stjames-0.0.47 → stjames-0.0.48}/stjames/workflows/conformer_search.py +0 -0
  50. {stjames-0.0.47 → stjames-0.0.48}/stjames/workflows/descriptors.py +0 -0
  51. {stjames-0.0.47 → stjames-0.0.48}/stjames/workflows/electronic_properties.py +0 -0
  52. {stjames-0.0.47 → stjames-0.0.48}/stjames/workflows/fukui.py +0 -0
  53. {stjames-0.0.47 → stjames-0.0.48}/stjames/workflows/molecular_dynamics.py +0 -0
  54. {stjames-0.0.47 → stjames-0.0.48}/stjames/workflows/multistage_opt.py +0 -0
  55. {stjames-0.0.47 → stjames-0.0.48}/stjames/workflows/pka.py +0 -0
  56. {stjames-0.0.47 → stjames-0.0.48}/stjames/workflows/redox_potential.py +0 -0
  57. {stjames-0.0.47 → stjames-0.0.48}/stjames/workflows/scan.py +0 -0
  58. {stjames-0.0.47 → stjames-0.0.48}/stjames/workflows/spin_states.py +0 -0
  59. {stjames-0.0.47 → stjames-0.0.48}/stjames/workflows/tautomer.py +0 -0
  60. {stjames-0.0.47 → stjames-0.0.48}/stjames/workflows/workflow.py +0 -0
  61. {stjames-0.0.47 → stjames-0.0.48}/stjames.egg-info/dependency_links.txt +0 -0
  62. {stjames-0.0.47 → stjames-0.0.48}/stjames.egg-info/top_level.txt +0 -0
  63. {stjames-0.0.47 → stjames-0.0.48}/tests/test_constraints.py +0 -0
  64. {stjames-0.0.47 → stjames-0.0.48}/tests/test_from_extxyz.py +0 -0
  65. {stjames-0.0.47 → stjames-0.0.48}/tests/test_molecule.py +0 -0
  66. {stjames-0.0.47 → stjames-0.0.48}/tests/test_settings.py +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: stjames
3
- Version: 0.0.47
3
+ Version: 0.0.48
4
4
  Summary: standardized JSON atom/molecule encoding scheme
5
5
  Author-email: Corin Wagen <corin@rowansci.com>
6
6
  Project-URL: Homepage, https://github.com/rowansci/stjames
@@ -8,6 +8,7 @@ Project-URL: Bug Tracker, https://github.com/rowansci/stjames/issues
8
8
  Requires-Python: >=3.11
9
9
  Description-Content-Type: text/markdown
10
10
  License-File: LICENSE
11
+ Requires-Dist: atomium<2,>=1
11
12
  Requires-Dist: pydantic>=2.4
12
13
  Requires-Dist: numpy
13
14
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "stjames"
3
- version = "0.0.47"
3
+ version = "0.0.48"
4
4
  description = "standardized JSON atom/molecule encoding scheme"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
@@ -9,6 +9,7 @@ authors = [
9
9
  ]
10
10
 
11
11
  dependencies = [
12
+ "atomium>=1,<2",
12
13
  "pydantic>=2.4",
13
14
  "numpy",
14
15
  ]
@@ -48,10 +49,11 @@ ignore = ["E741"]
48
49
 
49
50
  [tool.pytest.ini_options]
50
51
  testpaths = ["stjames", "tests"]
51
- addopts = "--doctest-modules"
52
+ addopts = "--doctest-modules --durations=5 -m 'not regression'"
52
53
  doctest_optionflags = "NORMALIZE_WHITESPACE"
53
54
  markers = [
54
- "smoke: sanity tests to reveal simple failures"
55
+ "smoke: sanity tests to reveal simple failures",
56
+ "regression: tests to make sure bugs stay closed",
55
57
  ]
56
58
 
57
59
  [tool.mypy]
@@ -32,8 +32,10 @@ class Method(LowercaseStrEnum):
32
32
 
33
33
  AIMNET2_WB97MD3 = "aimnet2_wb97md3"
34
34
  MACE_MP_0 = "mace_mp_0"
35
+ MACE_MP_0B2_L = "mace_mp_0b2_l"
35
36
  OCP24_S = "ocp24_s"
36
37
  OCP24_L = "ocp24_l"
38
+ ORB_V2 = "orb_v2"
37
39
 
38
40
  GFN_FF = "gfn_ff"
39
41
  GFN0_XTB = "gfn0_xtb"
@@ -46,8 +48,14 @@ class Method(LowercaseStrEnum):
46
48
  OFF_SAGE_2_2_1 = "off_sage_2_2_1"
47
49
 
48
50
 
49
- NNPMethod = Literal[Method.AIMNET2_WB97MD3]
50
- NNP_METHODS = [Method.AIMNET2_WB97MD3]
51
+ PrepackagedNNPMethod = Literal[Method.AIMNET2_WB97MD3, Method.OCP24_S, Method.OCP24_L]
52
+ PREPACKAGED_NNP_METHODS = [Method.AIMNET2_WB97MD3, Method.OCP24_S, Method.OCP24_L]
53
+
54
+ CorrectableNNPMethod = Literal[Method.MACE_MP_0B2_L, Method.ORB_V2]
55
+ CORRECTABLE_NNP_METHODS = [Method.MACE_MP_0B2_L, Method.ORB_V2]
56
+
57
+ NNPMethod = PrepackagedNNPMethod | CorrectableNNPMethod
58
+ NNP_METHODS = [*PREPACKAGED_NNP_METHODS, *CORRECTABLE_NNP_METHODS]
51
59
 
52
60
  XTBMethod = Literal[Method.GFN_FF, Method.GFN0_XTB, Method.GFN1_XTB, Method.GFN2_XTB]
53
61
  XTB_METHODS = [Method.GFN_FF, Method.GFN0_XTB, Method.GFN1_XTB, Method.GFN2_XTB]
@@ -58,8 +66,8 @@ COMPOSITE_METHODS = [Method.HF3C, Method.B973C, Method.R2SCAN3C, Method.WB97X3C]
58
66
  FFMethod = Literal[Method.OFF_SAGE_2_2_1]
59
67
  FF_METHODS = [Method.OFF_SAGE_2_2_1]
60
68
 
61
- PrepackagedMethod = XTBMethod | CompositeMethod | NNPMethod | FFMethod
62
- PREPACKAGED_METHODS = [*XTB_METHODS, *COMPOSITE_METHODS, *NNP_METHODS, *FF_METHODS]
69
+ PrepackagedMethod = XTBMethod | CompositeMethod | PrepackagedNNPMethod | FFMethod
70
+ PREPACKAGED_METHODS = [*XTB_METHODS, *COMPOSITE_METHODS, *PREPACKAGED_NNP_METHODS, *FF_METHODS]
63
71
 
64
72
  MethodWithCorrection = Literal[Method.WB97XD3, Method.WB97XV, Method.WB97MV, Method.WB97MD3BJ, Method.DSDBLYPD3BJ]
65
73
  METHODS_WITH_CORRECTION = [Method.WB97XD3, Method.WB97XV, Method.WB97MV, Method.WB97MD3BJ, Method.DSDBLYPD3BJ, Method.B97D3BJ]
@@ -0,0 +1,197 @@
1
+ from datetime import date
2
+ from pathlib import Path
3
+ from typing import Any, Literal
4
+
5
+ import atomium # type: ignore [import-untyped]
6
+ from atomium.pdb import pdb_dict_to_data_dict, pdb_string_to_pdb_dict # type: ignore [import-untyped]
7
+ from pydantic import BaseModel, ConfigDict, Field
8
+
9
+ from stjames.types import Matrix3x3, Vector3D
10
+
11
+ # Mostly for testing purposes
12
+ EXTRA: Literal["allow", "ignore", "forbid"] = "allow"
13
+
14
+
15
+ class PDBAtom(BaseModel):
16
+ """An atom within a residue."""
17
+
18
+ model_config = ConfigDict(extra=EXTRA)
19
+
20
+ x: float
21
+ y: float
22
+ z: float
23
+ element: str
24
+ name: str
25
+ charge: float
26
+ occupancy: float
27
+ alt_loc: str | None
28
+ anisotropy: list[float]
29
+ bvalue: float
30
+ is_hetatm: bool
31
+
32
+
33
+ class PDBWater(BaseModel):
34
+ """A water molecule."""
35
+
36
+ model_config = ConfigDict(extra=EXTRA)
37
+
38
+ name: str | None
39
+ full_name: str | None
40
+ atoms: dict[int, PDBAtom] = {}
41
+ internal_id: str | None
42
+ polymer: str
43
+
44
+
45
+ class PDBResidue(BaseModel):
46
+ """A structure."""
47
+
48
+ model_config = ConfigDict(extra=EXTRA)
49
+
50
+ name: str | None
51
+ full_name: str | None = None
52
+ atoms: dict[int, PDBAtom] = {}
53
+ number: int
54
+
55
+
56
+ class PDBPolymer(BaseModel):
57
+ """A polymer chain."""
58
+
59
+ model_config = ConfigDict(extra=EXTRA)
60
+
61
+ internal_id: str
62
+ helices: list[list[str]] = []
63
+ residues: dict[str, PDBResidue] = {}
64
+ sequence: str | None
65
+ strands: list[list[str]] = []
66
+
67
+
68
+ class PDBNonPolymer(BaseModel):
69
+ """Non-polymeric molecules/atoms (e.g. ions and ligands)."""
70
+
71
+ model_config = ConfigDict(extra=EXTRA)
72
+
73
+ name: str
74
+ full_name: str | None = None
75
+ atoms: dict[int, PDBAtom]
76
+ internal_id: str
77
+ polymer: str
78
+
79
+
80
+ class PDBModel(BaseModel):
81
+ """Structure data."""
82
+
83
+ model_config = ConfigDict(extra=EXTRA)
84
+
85
+ polymer: dict[str, PDBPolymer] = {}
86
+ non_polymer: dict[str, PDBNonPolymer] = Field(alias="non-polymer", default_factory=dict)
87
+ branched: dict[str, Any] = {}
88
+ water: dict[str, PDBWater] = {}
89
+
90
+
91
+ class PDBTransformations(BaseModel):
92
+ """Transformations applied to the structure."""
93
+
94
+ model_config = ConfigDict(extra=EXTRA)
95
+
96
+ chains: list[str]
97
+ matrix: Matrix3x3
98
+ vector: Vector3D
99
+
100
+
101
+ class PDBAssembly(BaseModel):
102
+ """How the structure was assembled."""
103
+
104
+ model_config = ConfigDict(extra=EXTRA)
105
+
106
+ transformations: list[PDBTransformations]
107
+ software: str | None
108
+ buried_surface_area: float | None
109
+ surface_area: float | None
110
+ delta_energy: float | None
111
+ id: int
112
+
113
+
114
+ class PDBCrystallography(BaseModel):
115
+ """Crystallography related information."""
116
+
117
+ model_config = ConfigDict(extra=EXTRA)
118
+
119
+ space_group: str | None = None
120
+ unit_cell: list[float] | None = None
121
+
122
+
123
+ class PDBGeometry(BaseModel):
124
+ """Details of the geometry."""
125
+
126
+ model_config = ConfigDict(extra=EXTRA)
127
+
128
+ assemblies: list[PDBAssembly] = []
129
+ crystallography: PDBCrystallography = Field(default_factory=PDBCrystallography)
130
+
131
+
132
+ class PDBQuality(BaseModel):
133
+ """Quality metrics."""
134
+
135
+ model_config = ConfigDict(extra=EXTRA)
136
+
137
+ resolution: float | None = None
138
+ rfree: float | None = None
139
+ rvalue: float | None = None
140
+
141
+
142
+ class PDBMissingResidue(BaseModel):
143
+ model_config = ConfigDict(extra=EXTRA)
144
+
145
+ name: str
146
+ id: str
147
+
148
+
149
+ class PDBExperiment(BaseModel):
150
+ """Details of the experiment."""
151
+
152
+ model_config = ConfigDict(extra=EXTRA)
153
+
154
+ expression_system: str | None
155
+ missing_residues: list[PDBMissingResidue] = []
156
+ source_organism: str | None
157
+ technique: str | None
158
+
159
+
160
+ class PDBDescription(BaseModel):
161
+ """A description of the molecule."""
162
+
163
+ model_config = ConfigDict(extra=EXTRA)
164
+
165
+ code: str | None
166
+ title: str | None
167
+ authors: list[str] = []
168
+ classification: str | None
169
+ deposition_date: date | None
170
+ keywords: list[str] = []
171
+
172
+
173
+ class PDB(BaseModel):
174
+ """A PDB formatted file."""
175
+
176
+ model_config = ConfigDict(extra=EXTRA)
177
+
178
+ description: PDBDescription
179
+ experiment: PDBExperiment
180
+ geometry: PDBGeometry
181
+ models: list[PDBModel] = []
182
+ quality: PDBQuality = Field(default_factory=PDBQuality)
183
+
184
+
185
+ def read_pdb(path: Path | str) -> PDB:
186
+ """Read a pdb located at path."""
187
+ return PDB.model_validate(atomium.open(str(path), data_dict=True))
188
+
189
+
190
+ def fetch_pdb(code: str) -> PDB:
191
+ """Fetch a pdb from the Protein Data Bank."""
192
+ return PDB.model_validate(atomium.fetch(code, data_dict=True))
193
+
194
+
195
+ def pdb_from_string(pdb: str) -> PDB:
196
+ """Read a PDB from a string."""
197
+ return PDB.model_validate(pdb_dict_to_data_dict(pdb_string_to_pdb_dict(pdb)))
@@ -5,7 +5,7 @@ from pydantic import computed_field, field_validator, model_validator
5
5
  from .base import Base, UniqueList
6
6
  from .basis_set import BasisSet
7
7
  from .correction import Correction
8
- from .method import METHODS_WITH_CORRECTION, PREPACKAGED_METHODS, Method
8
+ from .method import CORRECTABLE_NNP_METHODS, METHODS_WITH_CORRECTION, PREPACKAGED_METHODS, Method
9
9
  from .mode import Mode
10
10
  from .opt_settings import OptimizationSettings
11
11
  from .scf_settings import SCFSettings
@@ -38,12 +38,14 @@ class Settings(Base):
38
38
  def level_of_theory(self) -> str:
39
39
  corrections = list(filter(lambda x: x not in (None, ""), self.corrections))
40
40
 
41
- if self.method in PREPACKAGED_METHODS or self.basis_set is None:
41
+ if self.method in CORRECTABLE_NNP_METHODS:
42
+ method = self.method.value if not corrections else f"{self.method.value}-{'-'.join(c.value for c in corrections)}"
43
+ elif self.method in PREPACKAGED_METHODS or self.basis_set is None:
42
44
  method = self.method.value
43
- elif self.method in METHODS_WITH_CORRECTION or len(corrections) == 0:
45
+ elif self.method in METHODS_WITH_CORRECTION or not corrections:
44
46
  method = f"{self.method.value}/{self.basis_set.name.lower()}"
45
47
  else:
46
- method = f"{self.method.value}-{'-'.join([c.value for c in corrections])}/{self.basis_set.name.lower()}"
48
+ method = f"{self.method.value}-{'-'.join(c.value for c in corrections)}/{self.basis_set.name.lower()}"
47
49
 
48
50
  if self.solvent_settings is not None:
49
51
  method += f"/{self.solvent_settings.model.value}({self.solvent_settings.solvent.value})"
@@ -11,6 +11,9 @@ class HydrogenBondAcceptorSite(Base):
11
11
 
12
12
 
13
13
  class HydrogenBondBasicityWorkflow(Workflow):
14
+ do_csearch: bool = True
15
+ do_optimization: bool = True
16
+
14
17
  # UUID of optimization
15
18
  optimization: UUID | None = None
16
19
 
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: stjames
3
- Version: 0.0.47
3
+ Version: 0.0.48
4
4
  Summary: standardized JSON atom/molecule encoding scheme
5
5
  Author-email: Corin Wagen <corin@rowansci.com>
6
6
  Project-URL: Homepage, https://github.com/rowansci/stjames
@@ -8,6 +8,7 @@ Project-URL: Bug Tracker, https://github.com/rowansci/stjames/issues
8
8
  Requires-Python: >=3.11
9
9
  Description-Content-Type: text/markdown
10
10
  License-File: LICENSE
11
+ Requires-Dist: atomium<2,>=1
11
12
  Requires-Dist: pydantic>=2.4
12
13
  Requires-Dist: numpy
13
14
 
@@ -17,6 +17,7 @@ stjames/method.py
17
17
  stjames/mode.py
18
18
  stjames/molecule.py
19
19
  stjames/opt_settings.py
20
+ stjames/pdb.py
20
21
  stjames/periodic_cell.py
21
22
  stjames/py.typed
22
23
  stjames/scf_settings.py
@@ -59,4 +60,5 @@ stjames/workflows/workflow.py
59
60
  tests/test_constraints.py
60
61
  tests/test_from_extxyz.py
61
62
  tests/test_molecule.py
63
+ tests/test_pdb.py
62
64
  tests/test_settings.py
@@ -1,2 +1,3 @@
1
+ atomium<2,>=1
1
2
  pydantic>=2.4
2
3
  numpy
@@ -0,0 +1,44 @@
1
+ from pytest import mark
2
+
3
+ from stjames.pdb import fetch_pdb, pdb_from_string
4
+
5
+
6
+ def test_1ema() -> None:
7
+ """Green fluorescent protein."""
8
+ fetch_pdb("1EMA")
9
+
10
+
11
+ def test_read_pdb() -> None:
12
+ """Rest reading of a pdb string."""
13
+ with open("tests/data/1ema.pdb") as f:
14
+ data = f.read()
15
+ pdb = pdb_from_string(data)
16
+ assert pdb.description.code == "1EMA"
17
+
18
+
19
+ # fmt: off
20
+ @mark.regression
21
+ @mark.parametrize(
22
+ "code",
23
+ [
24
+ # Codes from molecules of the month August 2024–January 2025
25
+ "7S6B", "8UCS", "8UPL", "7CGO", "2ZVY", "1F4V", "6YKM", "6E10", "6E11",
26
+ "3VCM", "2X0B", "6OS0", "1N9U", "1O86", "2V0Z", "6KI1", "6KI2", "7YYO",
27
+ "6TJV", "7EGL", "7CYF", "7EGK", "7ZCG", "3FRT", "6AP1",
28
+ # Codes created by o1
29
+ "1CRN", "1MBN", "4HHB", "1HHO", "1BNA", "1CAG", "2JHO", "1EVV", "3ZOJ",
30
+ "4AGG", "2Y69", "6R1V", "6ND2", "7NZ6", "1S72", "3G5U", "7DFT", "6AI0",
31
+ "6NG2", "1A0I", "1B7C", "1C8R", "1D4T", "1E7O", "1F9J", "1G5K", "1H8L",
32
+ "1I2M", "1J3N", "1K4P", "1M7R", "1N8S", "1O9T", "1P0U", "1Q1V", "1R2W",
33
+ "1S3X", "1T4Y", "1U5Z", "1V6A", "1W7B", "1X8C", "1Y9D", "1Z0E", "2A1F",
34
+ "2B2G", "2C3H", "2D4I", "2E5J", "2F6K", "2G7L", "2H8M", "2I9N", "2J0O",
35
+ "2K1P", "2L2Q", "2N4S", "2O5T", "2P6U", "2Q7V", "2R8W", "2V2A", "2W3B",
36
+ "2X4C", "2Y5D", "2Z6E", "3A7F", "3B8G", "3C9H", "3D0I", "3E1J", "3F2K",
37
+ "3G3L", "3H4M", "3I5N", "3J6O", "3K7P", "3L8Q", "3N0S", "3O1T", "3P2U",
38
+ "3Q3V", "3S5X", "3T6Y", "3U7Z", "3V8A", "3W9B", "3X0C", "4A3F", "4B4G",
39
+ "4C5H", "4D6I", "4E7J", "4F8K", "4G9L", "4H0M", "4I1N", "4J2O", "4K3P",
40
+ "4L4Q", "4M5R", "4N6S", "4O7T", "4P8U", "4Q9V", "4R0W", "4S1X",
41
+ ]
42
+ ) # fmt: on
43
+ def test_pdb(code: str) -> None:
44
+ fetch_pdb(code)
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes