mdprep 0.2.0__py3-none-any.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.
- mdprep/__init__.py +7 -0
- mdprep/_selftest_data/basic_protein.yaml +33 -0
- mdprep/_selftest_data/ligand_sub.mol2 +11 -0
- mdprep/ambertools/__init__.py +2 -0
- mdprep/ambertools/antechamber.py +110 -0
- mdprep/ambertools/commands.py +33 -0
- mdprep/ambertools/mol2.py +415 -0
- mdprep/ambertools/parmchk2.py +89 -0
- mdprep/ambertools/resp.py +570 -0
- mdprep/charges/__init__.py +1 -0
- mdprep/charges/esp_grid.py +190 -0
- mdprep/cli.py +451 -0
- mdprep/config/__init__.py +9 -0
- mdprep/config/loader.py +146 -0
- mdprep/config/models.py +1100 -0
- mdprep/external/__init__.py +14 -0
- mdprep/external/discovery.py +14 -0
- mdprep/external/runner.py +55 -0
- mdprep/leap/__init__.py +2 -0
- mdprep/leap/builder.py +476 -0
- mdprep/leap/forcefields.py +93 -0
- mdprep/leap/ions.py +112 -0
- mdprep/leap/log_parser.py +170 -0
- mdprep/leap/report.py +99 -0
- mdprep/leap/residues.py +653 -0
- mdprep/leap/runner.py +65 -0
- mdprep/ligands/__init__.py +2 -0
- mdprep/ligands/extract.py +355 -0
- mdprep/ligands/identity.py +39 -0
- mdprep/ligands/pyscf_charges.py +242 -0
- mdprep/ligands/report.py +146 -0
- mdprep/ligands/workflow.py +838 -0
- mdprep/md/__init__.py +5 -0
- mdprep/md/roe_brooks.py +650 -0
- mdprep/metals/__init__.py +2 -0
- mdprep/metals/c4.py +157 -0
- mdprep/metals/coordination.py +313 -0
- mdprep/metals/gxtb_hessian.py +467 -0
- mdprep/metals/hydrogenate.py +344 -0
- mdprep/metals/mace_polar1_hessian.py +357 -0
- mdprep/metals/mace_polar1_worker.py +295 -0
- mdprep/metals/mcpb.py +949 -0
- mdprep/metals/mcpb_compat.py +125 -0
- mdprep/metals/nonbonded.py +294 -0
- mdprep/metals/parameter_comparison.py +563 -0
- mdprep/metals/pyscf_mcpb.py +1388 -0
- mdprep/metals/report.py +119 -0
- mdprep/metals/workflow.py +320 -0
- mdprep/protonation/__init__.py +15 -0
- mdprep/protonation/apply.py +968 -0
- mdprep/protonation/disulfide_states.py +141 -0
- mdprep/protonation/histidine_geometry.py +950 -0
- mdprep/protonation/histidine_xtb.py +390 -0
- mdprep/protonation/overrides.py +64 -0
- mdprep/protonation/pka_rules.py +165 -0
- mdprep/protonation/propka.py +174 -0
- mdprep/protonation/propka_parser.py +140 -0
- mdprep/protonation/report.py +187 -0
- mdprep/protonation/states.py +52 -0
- mdprep/protonation/temporary_hydrogenation.py +238 -0
- mdprep/protonation/xtb_parser.py +79 -0
- mdprep/protonation/xtb_runner.py +108 -0
- mdprep/qm/__init__.py +2 -0
- mdprep/qm/point_charges.py +233 -0
- mdprep/qm/pyscf_esp.py +70 -0
- mdprep/qm/pyscf_runner.py +570 -0
- mdprep/refinement/__init__.py +5 -0
- mdprep/refinement/ash.py +541 -0
- mdprep/refinement/coordinates.py +210 -0
- mdprep/refinement/mapping.py +163 -0
- mdprep/refinement/report.py +66 -0
- mdprep/refinement/selection.py +436 -0
- mdprep/refinement/workflow.py +188 -0
- mdprep/reports/__init__.py +8 -0
- mdprep/reports/structure_report.py +92 -0
- mdprep/structure/__init__.py +14 -0
- mdprep/structure/classify.py +92 -0
- mdprep/structure/disulfides.py +51 -0
- mdprep/structure/inspect.py +105 -0
- mdprep/structure/models.py +86 -0
- mdprep/structure/normalize.py +363 -0
- mdprep/structure/pdb.py +511 -0
- mdprep/structure/repair.py +566 -0
- mdprep/structure/selectors.py +204 -0
- mdprep/structure/writer.py +84 -0
- mdprep/validation/__init__.py +2 -0
- mdprep/validation/openmm_check.py +86 -0
- mdprep/validation/parmed_check.py +43 -0
- mdprep/validation/topology.py +239 -0
- mdprep/workflows/__init__.py +6 -0
- mdprep/workflows/init.py +242 -0
- mdprep/workflows/inspect.py +21 -0
- mdprep/workflows/prepare.py +763 -0
- mdprep/workflows/selftest.py +220 -0
- mdprep/workflows/validate.py +30 -0
- mdprep-0.2.0.dist-info/METADATA +264 -0
- mdprep-0.2.0.dist-info/RECORD +100 -0
- mdprep-0.2.0.dist-info/WHEEL +4 -0
- mdprep-0.2.0.dist-info/entry_points.txt +2 -0
- mdprep-0.2.0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
"""Quick package-level self-test."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from dataclasses import dataclass
|
|
6
|
+
from importlib import import_module
|
|
7
|
+
from importlib.resources import as_file, files
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
from tempfile import TemporaryDirectory
|
|
10
|
+
|
|
11
|
+
from rich.console import Console
|
|
12
|
+
from rich.table import Table
|
|
13
|
+
|
|
14
|
+
import mdprep
|
|
15
|
+
from mdprep.ambertools.mol2 import Mol2File, read_mol2
|
|
16
|
+
from mdprep.ambertools.resp import write_amber_esp
|
|
17
|
+
from mdprep.charges.esp_grid import generate_merz_kollman_grid
|
|
18
|
+
from mdprep.config.loader import load_manifest
|
|
19
|
+
from mdprep.external.discovery import optional_executable_report
|
|
20
|
+
from mdprep.leap.forcefields import protein_leaprc, water_box, water_leaprc
|
|
21
|
+
from mdprep.qm.pyscf_runner import pyscf_available
|
|
22
|
+
from mdprep.validation.openmm_check import openmm_available
|
|
23
|
+
from mdprep.validation.parmed_check import parmed_available
|
|
24
|
+
import numpy as np
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
OPTIONAL_EXECUTABLES = [
|
|
28
|
+
"tleap",
|
|
29
|
+
"antechamber",
|
|
30
|
+
"parmchk2",
|
|
31
|
+
"respgen",
|
|
32
|
+
"resp",
|
|
33
|
+
"propka3",
|
|
34
|
+
"propka",
|
|
35
|
+
"xtb",
|
|
36
|
+
]
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
@dataclass(frozen=True)
|
|
40
|
+
class SelftestSummary:
|
|
41
|
+
passed: bool
|
|
42
|
+
checked_examples: int
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def _project_root() -> Path | None:
|
|
46
|
+
candidates = [
|
|
47
|
+
Path.cwd(),
|
|
48
|
+
Path(__file__).resolve().parents[3],
|
|
49
|
+
]
|
|
50
|
+
for candidate in candidates:
|
|
51
|
+
if (candidate / "examples").is_dir():
|
|
52
|
+
return candidate
|
|
53
|
+
return None
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def _validate_example_manifests(root: Path | None) -> tuple[int, list[str]]:
|
|
57
|
+
if root is not None:
|
|
58
|
+
examples = sorted((root / "examples").glob("*.yaml"))
|
|
59
|
+
errors: list[str] = []
|
|
60
|
+
for example in examples:
|
|
61
|
+
try:
|
|
62
|
+
load_manifest(example)
|
|
63
|
+
except Exception as exc:
|
|
64
|
+
errors.append(f"{example.name}: {exc}")
|
|
65
|
+
return len(examples), errors
|
|
66
|
+
|
|
67
|
+
resource = files("mdprep").joinpath("_selftest_data/basic_protein.yaml")
|
|
68
|
+
with as_file(resource) as example:
|
|
69
|
+
try:
|
|
70
|
+
load_manifest(example)
|
|
71
|
+
except Exception as exc:
|
|
72
|
+
return 1, [f"{example.name}: {exc}"]
|
|
73
|
+
return 1, []
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def _read_mol2_fixture(root: Path | None) -> Mol2File:
|
|
77
|
+
if root is not None:
|
|
78
|
+
return read_mol2(root / "tests" / "data" / "ligands" / "ligand_sub.good.mol2")
|
|
79
|
+
|
|
80
|
+
resource = files("mdprep").joinpath("_selftest_data/ligand_sub.mol2")
|
|
81
|
+
with as_file(resource) as fixture:
|
|
82
|
+
return read_mol2(fixture)
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def _blocked_tokens() -> tuple[str, ...]:
|
|
86
|
+
return (
|
|
87
|
+
"".join(("open", "babel")),
|
|
88
|
+
"".join(("Open", "Babel")),
|
|
89
|
+
"".join(("py", "bel")),
|
|
90
|
+
"".join(("o", "babel")),
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def _source_has_blocked_tokens() -> list[Path]:
|
|
95
|
+
source_root = Path(__file__).resolve().parents[1]
|
|
96
|
+
blocked = _blocked_tokens()
|
|
97
|
+
matches: list[Path] = []
|
|
98
|
+
for path in source_root.rglob("*.py"):
|
|
99
|
+
text = path.read_text(encoding="utf-8")
|
|
100
|
+
if any(token in text for token in blocked):
|
|
101
|
+
matches.append(path)
|
|
102
|
+
return matches
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def run_selftest(*, quick: bool = False, console: Console | None = None) -> SelftestSummary:
|
|
106
|
+
out = console or Console()
|
|
107
|
+
root = _project_root()
|
|
108
|
+
|
|
109
|
+
out.print(f"mdprep {mdprep.__version__}")
|
|
110
|
+
out.print("Mode: quick" if quick else "Mode: standard")
|
|
111
|
+
|
|
112
|
+
checks: list[tuple[str, bool, str]] = []
|
|
113
|
+
|
|
114
|
+
try:
|
|
115
|
+
import_module("mdprep")
|
|
116
|
+
import_module("mdprep.config.loader")
|
|
117
|
+
import_module("mdprep.external.discovery")
|
|
118
|
+
checks.append(("Python imports", True, "ok"))
|
|
119
|
+
except Exception as exc:
|
|
120
|
+
checks.append(("Python imports", False, str(exc)))
|
|
121
|
+
|
|
122
|
+
example_count, example_errors = _validate_example_manifests(root)
|
|
123
|
+
checks.append(
|
|
124
|
+
(
|
|
125
|
+
"Example manifests",
|
|
126
|
+
not example_errors and example_count > 0,
|
|
127
|
+
f"{example_count} validated" if not example_errors else "; ".join(example_errors),
|
|
128
|
+
)
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
blocked_matches = _source_has_blocked_tokens()
|
|
132
|
+
checks.append(
|
|
133
|
+
(
|
|
134
|
+
"Prohibited toolkit source scan",
|
|
135
|
+
not blocked_matches,
|
|
136
|
+
"ok" if not blocked_matches else ", ".join(str(path) for path in blocked_matches),
|
|
137
|
+
)
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
try:
|
|
141
|
+
mol2 = _read_mol2_fixture(root)
|
|
142
|
+
checks.append(("mol2 parser fixture", len(mol2.atoms) == 2, f"{len(mol2.atoms)} atoms"))
|
|
143
|
+
except Exception as exc:
|
|
144
|
+
checks.append(("mol2 parser fixture", False, str(exc)))
|
|
145
|
+
|
|
146
|
+
try:
|
|
147
|
+
ok = (
|
|
148
|
+
protein_leaprc("ff19SB") == "leaprc.protein.ff19SB"
|
|
149
|
+
and water_leaprc("TIP3P") == "leaprc.water.tip3p"
|
|
150
|
+
and water_box("OPC") == "OPCBOX"
|
|
151
|
+
)
|
|
152
|
+
checks.append(("force-field mappings", ok, "ok" if ok else "unexpected mapping"))
|
|
153
|
+
except Exception as exc:
|
|
154
|
+
checks.append(("force-field mappings", False, str(exc)))
|
|
155
|
+
|
|
156
|
+
checks.append(("ParmEd import", True, "available" if parmed_available() else "not available"))
|
|
157
|
+
checks.append(("OpenMM import", True, "available" if openmm_available() else "not available"))
|
|
158
|
+
checks.append(("PySCF import", True, "available" if pyscf_available() else "not available"))
|
|
159
|
+
|
|
160
|
+
try:
|
|
161
|
+
coords = np.asarray([[0.0, 0.0, 0.0], [0.96, 0.0, 0.0]], dtype=float)
|
|
162
|
+
grid_a = generate_merz_kollman_grid(
|
|
163
|
+
elements=["O", "H"],
|
|
164
|
+
coordinates=coords,
|
|
165
|
+
vdw_scale_factors=[1.4],
|
|
166
|
+
point_density_per_square_angstrom=0.25,
|
|
167
|
+
exclude_inside_vdw_scale=1.4,
|
|
168
|
+
max_points=100,
|
|
169
|
+
)
|
|
170
|
+
grid_b = generate_merz_kollman_grid(
|
|
171
|
+
elements=["O", "H"],
|
|
172
|
+
coordinates=coords,
|
|
173
|
+
vdw_scale_factors=[1.4],
|
|
174
|
+
point_density_per_square_angstrom=0.25,
|
|
175
|
+
exclude_inside_vdw_scale=1.4,
|
|
176
|
+
max_points=100,
|
|
177
|
+
)
|
|
178
|
+
checks.append(("ESP grid determinism", bool(np.allclose(grid_a.points, grid_b.points)), f"{len(grid_a.points)} points"))
|
|
179
|
+
except Exception as exc:
|
|
180
|
+
checks.append(("ESP grid determinism", False, str(exc)))
|
|
181
|
+
|
|
182
|
+
try:
|
|
183
|
+
atom_coords = np.asarray([[0.0, 0.0, 0.0], [2.0, 0.0, 0.0]], dtype=float)
|
|
184
|
+
grid_coords = np.asarray(
|
|
185
|
+
[[0.0, 3.0, 0.0], [2.0, 3.0, 0.0], [1.0, 3.5, 0.0], [1.0, -3.0, 0.0]],
|
|
186
|
+
dtype=float,
|
|
187
|
+
)
|
|
188
|
+
esp = np.asarray([-0.1, 0.1, 0.0, 0.0], dtype=float)
|
|
189
|
+
with TemporaryDirectory(prefix="mdprep-selftest-") as temporary_dir:
|
|
190
|
+
path = write_amber_esp(
|
|
191
|
+
atom_coordinates_bohr=atom_coords,
|
|
192
|
+
grid_coordinates_bohr=grid_coords,
|
|
193
|
+
esp_values_au=esp,
|
|
194
|
+
path=Path(temporary_dir) / "test.esp",
|
|
195
|
+
)
|
|
196
|
+
lines = path.read_text(encoding="ascii").splitlines()
|
|
197
|
+
fixed_width_ok = lines[0] == " 2 4" and len(lines[1]) == 65 and len(lines[3]) == 65
|
|
198
|
+
checks.append(("Amber RESP ESP format", fixed_width_ok, "2 atoms, 4 grid points"))
|
|
199
|
+
except Exception as exc:
|
|
200
|
+
checks.append(("Amber RESP ESP format", False, str(exc)))
|
|
201
|
+
|
|
202
|
+
table = Table(title="mdprep self-test")
|
|
203
|
+
table.add_column("Check")
|
|
204
|
+
table.add_column("Status")
|
|
205
|
+
table.add_column("Detail")
|
|
206
|
+
for name, ok, detail in checks:
|
|
207
|
+
table.add_row(name, "PASS" if ok else "FAIL", detail)
|
|
208
|
+
out.print(table)
|
|
209
|
+
|
|
210
|
+
exec_table = Table(title="Optional executables")
|
|
211
|
+
exec_table.add_column("Executable")
|
|
212
|
+
exec_table.add_column("Path")
|
|
213
|
+
for name, path in optional_executable_report(OPTIONAL_EXECUTABLES).items():
|
|
214
|
+
exec_table.add_row(name, path or "not found")
|
|
215
|
+
out.print(exec_table)
|
|
216
|
+
|
|
217
|
+
return SelftestSummary(
|
|
218
|
+
passed=all(ok for _, ok, _ in checks),
|
|
219
|
+
checked_examples=example_count,
|
|
220
|
+
)
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"""Standalone prepared-system validation."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
from mdprep.validation.parmed_check import run_parmed_check
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def validate_system(prmtop: str | Path, inpcrd: str | Path) -> dict[str, object]:
|
|
11
|
+
topology = Path(prmtop)
|
|
12
|
+
coordinates = Path(inpcrd)
|
|
13
|
+
errors: list[str] = []
|
|
14
|
+
for label, path in [("prmtop", topology), ("inpcrd", coordinates)]:
|
|
15
|
+
if not path.exists():
|
|
16
|
+
errors.append(f"Missing {label}: {path}")
|
|
17
|
+
elif path.stat().st_size == 0:
|
|
18
|
+
errors.append(f"Empty {label}: {path}")
|
|
19
|
+
parmed = None
|
|
20
|
+
if not errors:
|
|
21
|
+
parmed = run_parmed_check(topology, coordinates)
|
|
22
|
+
if parmed.get("status") == "error":
|
|
23
|
+
errors.append(f"ParmEd validation failed: {parmed.get('error')}")
|
|
24
|
+
if errors:
|
|
25
|
+
raise ValueError("; ".join(errors))
|
|
26
|
+
return {
|
|
27
|
+
"prmtop": str(topology),
|
|
28
|
+
"inpcrd": str(coordinates),
|
|
29
|
+
"parmed": parmed,
|
|
30
|
+
}
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: mdprep
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Reproducible Amber preparation for proteins, ligands, metal centers, and OpenMM MD.
|
|
5
|
+
Project-URL: Homepage, https://github.com/miqueleg/mdprep
|
|
6
|
+
Project-URL: Issues, https://github.com/miqueleg/mdprep/issues
|
|
7
|
+
Author: Miquel Estévez Gay
|
|
8
|
+
License: MIT
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Keywords: amber,ligand,mcpb,metal,molecular-dynamics,openmm,protein,pyscf,qmmm,resp
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Environment :: Console
|
|
13
|
+
Classifier: Intended Audience :: Science/Research
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
|
|
19
|
+
Classifier: Topic :: Scientific/Engineering :: Chemistry
|
|
20
|
+
Requires-Python: >=3.11
|
|
21
|
+
Requires-Dist: numpy>=1.24
|
|
22
|
+
Requires-Dist: pandas>=2
|
|
23
|
+
Requires-Dist: pydantic-settings>=2
|
|
24
|
+
Requires-Dist: pydantic>=2
|
|
25
|
+
Requires-Dist: pyyaml>=6
|
|
26
|
+
Requires-Dist: rich>=13
|
|
27
|
+
Requires-Dist: scipy>=1.10
|
|
28
|
+
Requires-Dist: typer>=0.12
|
|
29
|
+
Provides-Extra: dev
|
|
30
|
+
Requires-Dist: build>=1; extra == 'dev'
|
|
31
|
+
Requires-Dist: mypy>=1.10; extra == 'dev'
|
|
32
|
+
Requires-Dist: pytest>=8; extra == 'dev'
|
|
33
|
+
Requires-Dist: ruff>=0.6; extra == 'dev'
|
|
34
|
+
Requires-Dist: twine>=5; extra == 'dev'
|
|
35
|
+
Provides-Extra: docs
|
|
36
|
+
Requires-Dist: mkdocs>=1.6; extra == 'docs'
|
|
37
|
+
Provides-Extra: md
|
|
38
|
+
Requires-Dist: openmm>=8.1; extra == 'md'
|
|
39
|
+
Provides-Extra: qm
|
|
40
|
+
Requires-Dist: parmed>=4.2; extra == 'qm'
|
|
41
|
+
Requires-Dist: pyscf>=2.6; extra == 'qm'
|
|
42
|
+
Provides-Extra: test
|
|
43
|
+
Requires-Dist: pytest>=8; extra == 'test'
|
|
44
|
+
Description-Content-Type: text/markdown
|
|
45
|
+
|
|
46
|
+
# mdprep
|
|
47
|
+
|
|
48
|
+
`mdprep` 0.2.0 prepares reproducible Amber molecular-dynamics systems from a
|
|
49
|
+
PDB structure and a validated YAML manifest. It supports standard proteins,
|
|
50
|
+
independent ligands and cofactors, explicit metal models, optional active-site
|
|
51
|
+
QM/MM refinement, final `tleap` assembly, validation, and an optional OpenMM
|
|
52
|
+
equilibration/production stage.
|
|
53
|
+
|
|
54
|
+
The manifest is the source of truth. Chemistry-sensitive decisions—ligand
|
|
55
|
+
charge and multiplicity, catalytic protonation, metal oxidation/spin state,
|
|
56
|
+
coordinating bonds, and QM components—must be supplied explicitly and are
|
|
57
|
+
recorded in the output reports.
|
|
58
|
+
|
|
59
|
+
## Highlights
|
|
60
|
+
|
|
61
|
+
- ff14SB or ff19SB proteins with TIP3P or OPC water.
|
|
62
|
+
- PropKa protonation, manual catalytic overrides, disulfides, and optional
|
|
63
|
+
GFN2-xTB/g-xTB HID–HIE selection.
|
|
64
|
+
- Multiple GAFF or GAFF2 ligands/cofactors with AM1-BCC, user mol2/frcmod,
|
|
65
|
+
PySCF gas-phase RESP, or electrostatically embedded PySCF QMMESP charges.
|
|
66
|
+
- Amber nonbonded metal models or bonded MCPB.py models with explicit
|
|
67
|
+
coordinating atoms, charges, and multiplicities.
|
|
68
|
+
- MCPB Seminario Hessians from PySCF, GFN2-xTB, g-xTB, or MACE-POLAR-1;
|
|
69
|
+
PySCF supplies the embedded large-model ESP/RESP calculation.
|
|
70
|
+
- Optional ASH/OpenMM active-site QM/MM refinement before final
|
|
71
|
+
parameterization.
|
|
72
|
+
- Final `prmtop`, `inpcrd`, and PDB generation through `tleap`, followed by
|
|
73
|
+
topology, coordinate, charge, and optional OpenMM energy validation.
|
|
74
|
+
- Optional Roe–Brooks OpenMM minimization, heating, density equilibration, and
|
|
75
|
+
manifest-sized production MD with GPU-first/CPU-fallback execution.
|
|
76
|
+
|
|
77
|
+
## Installation
|
|
78
|
+
|
|
79
|
+
Conda or Mamba is recommended because the real workflows use AmberTools,
|
|
80
|
+
PropKa, xTB, OpenMM, ParmEd, and PySCF:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
git clone https://github.com/miqueleg/mdprep.git
|
|
84
|
+
cd mdprep
|
|
85
|
+
mamba env create -f environment.yml
|
|
86
|
+
conda activate mdprep
|
|
87
|
+
mdprep selftest --quick
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
For a lighter Python-only installation, which does not install external
|
|
91
|
+
chemistry executables:
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
python -m pip install .
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Optional Python extras are available as `.[md]` for OpenMM and `.[qm]` for
|
|
98
|
+
PySCF/ParmEd. External commands are discovered through `PATH`; manifests may
|
|
99
|
+
also name a reviewed relative executable. No developer-machine path is embedded
|
|
100
|
+
in the distributed examples.
|
|
101
|
+
|
|
102
|
+
## Basic example
|
|
103
|
+
|
|
104
|
+
Start from a standard protein PDB:
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
mdprep inspect input.pdb
|
|
108
|
+
mdprep init input.pdb -o system.yaml
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
A minimal protein-only `system.yaml` is:
|
|
112
|
+
|
|
113
|
+
```yaml
|
|
114
|
+
project:
|
|
115
|
+
name: my_system
|
|
116
|
+
input_structure: input.pdb
|
|
117
|
+
output_dir: prepared/my_system
|
|
118
|
+
|
|
119
|
+
structure:
|
|
120
|
+
keep_crystal_waters: true
|
|
121
|
+
altloc_policy: highest_occupancy
|
|
122
|
+
remove_unknown_heterogens: false
|
|
123
|
+
preserve_chain_ids: true
|
|
124
|
+
remove_input_hydrogens: true
|
|
125
|
+
|
|
126
|
+
protein:
|
|
127
|
+
forcefield: ff14SB
|
|
128
|
+
water_model: TIP3P
|
|
129
|
+
|
|
130
|
+
protonation:
|
|
131
|
+
ph: 7.0
|
|
132
|
+
method: manual_only
|
|
133
|
+
overrides: []
|
|
134
|
+
|
|
135
|
+
disulfides:
|
|
136
|
+
auto_detect: true
|
|
137
|
+
detection_cutoff_angstrom: 2.2
|
|
138
|
+
force: []
|
|
139
|
+
forbid: []
|
|
140
|
+
|
|
141
|
+
ligands: []
|
|
142
|
+
metals: []
|
|
143
|
+
|
|
144
|
+
solvation:
|
|
145
|
+
enabled: true
|
|
146
|
+
box: truncated_octahedron
|
|
147
|
+
buffer_angstrom: 10.0
|
|
148
|
+
neutralize: true
|
|
149
|
+
salt_concentration_molar: 0.15
|
|
150
|
+
positive_ion: Na+
|
|
151
|
+
negative_ion: Cl-
|
|
152
|
+
|
|
153
|
+
validation:
|
|
154
|
+
run_openmm_energy_check: true
|
|
155
|
+
fail_on_warnings: false
|
|
156
|
+
fail_on_missing_parameters: true
|
|
157
|
+
fail_on_noninteger_ligand_charge: true
|
|
158
|
+
|
|
159
|
+
molecular_dynamics:
|
|
160
|
+
enabled: false
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
The same validated manifest is available as
|
|
164
|
+
[`examples/00_basic_protein.yaml`](examples/00_basic_protein.yaml).
|
|
165
|
+
|
|
166
|
+
Validate and prepare it:
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
mdprep config-check system.yaml
|
|
170
|
+
mdprep prepare system.yaml
|
|
171
|
+
mdprep validate \
|
|
172
|
+
prepared/my_system/final/system.prmtop \
|
|
173
|
+
prepared/my_system/final/system.inpcrd
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Relative paths are resolved from the manifest directory. Unknown heterogens
|
|
177
|
+
are not deleted or guessed: configure them under `ligands` or `metals`, or
|
|
178
|
+
explicitly request their removal.
|
|
179
|
+
|
|
180
|
+
## Common workflows
|
|
181
|
+
|
|
182
|
+
Generate a starter manifest using PropKa and ff19SB/OPC:
|
|
183
|
+
|
|
184
|
+
```bash
|
|
185
|
+
mdprep init input.pdb -o system.yaml \
|
|
186
|
+
--forcefield ff19SB \
|
|
187
|
+
--water-model OPC \
|
|
188
|
+
--protonation-method propka
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
Stop after a stage while reviewing a complex system:
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
mdprep prepare system.yaml --stop-after structure
|
|
195
|
+
mdprep prepare system.yaml --stop-after protonation --overwrite
|
|
196
|
+
mdprep prepare system.yaml --stop-after refinement --overwrite
|
|
197
|
+
mdprep prepare system.yaml --stop-after ligands --overwrite
|
|
198
|
+
mdprep prepare system.yaml --stop-after metals --overwrite
|
|
199
|
+
mdprep prepare system.yaml --stop-after tleap --overwrite
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
Run the manifest-configured Roe–Brooks protocol from an existing Amber build:
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
mdprep run-md system.yaml \
|
|
206
|
+
--prmtop prepared/my_system/final/system.prmtop \
|
|
207
|
+
--inpcrd prepared/my_system/final/system.inpcrd
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
When `molecular_dynamics.enabled: true`, an ordinary `mdprep prepare` continues
|
|
211
|
+
through MD. Production length and trajectory/state/checkpoint intervals are
|
|
212
|
+
specified in steps in the manifest.
|
|
213
|
+
|
|
214
|
+
## Where to go next
|
|
215
|
+
|
|
216
|
+
| Task | Documentation | Example |
|
|
217
|
+
| --- | --- | --- |
|
|
218
|
+
| Manifest fields | [Manifest reference](docs/manifest_reference.md) | [All examples](examples/README.md) |
|
|
219
|
+
| Protonation and histidines | [Protonation](docs/protonation.md) | `examples/02_manual_catalytic_protonation.yaml` |
|
|
220
|
+
| Ligands, AM1-BCC, RESP, QMMESP | [Ligands](docs/ligands.md) and [QMMESP](docs/qmmesp_pyscf.md) | `examples/03_multi_ligand_am1bcc.yaml`, `04_qmmesp_pyscf_ligand.yaml` |
|
|
221
|
+
| Metal centers and MCPB.py | [Metal centers](docs/metals.md) | `examples/08_nonbonded_zinc_1264.yaml`, `09_bonded_zinc_mcpb_prepare.yaml` |
|
|
222
|
+
| Active-site QM/MM refinement | [QM/MM refinement](docs/qmmm_refinement.md) | `examples/10_qmmm_refinement_ash.yaml` |
|
|
223
|
+
| Roe–Brooks OpenMM MD | [Molecular dynamics](docs/molecular_dynamics.md) | `examples/15_roe_brooks_openmm.yaml` |
|
|
224
|
+
| Complete Fe(III) workflow | [7E07 tutorial](examples/tutorials/7E07_bonded_fe3/README.md) | `examples/tutorials/7E07_bonded_fe3/system.yaml` |
|
|
225
|
+
|
|
226
|
+
All public example manifests are schema-validated in the test suite.
|
|
227
|
+
|
|
228
|
+
## Outputs and reproducibility
|
|
229
|
+
|
|
230
|
+
A complete run preserves:
|
|
231
|
+
|
|
232
|
+
- the input and locked manifests;
|
|
233
|
+
- normalized/protonated/refined intermediate PDBs;
|
|
234
|
+
- ligand, QM, MCPB.py, and `tleap` inputs and logs;
|
|
235
|
+
- final Amber topology, coordinates, and PDB;
|
|
236
|
+
- structure, protonation, ligand, metal, `tleap`, and validation reports;
|
|
237
|
+
- executable and Python-package version information;
|
|
238
|
+
- optional MD PDBs, density history, trajectory, state log, and restarts.
|
|
239
|
+
|
|
240
|
+
External failures are reported with command, working directory, return code,
|
|
241
|
+
stdout, stderr, and runtime. mdprep does not silently fall back to another
|
|
242
|
+
charge model, protonation, force field, QM method, or metal model.
|
|
243
|
+
|
|
244
|
+
## Current limitations
|
|
245
|
+
|
|
246
|
+
Version 0.2.0 does not support noncanonical amino acids inside peptide chains,
|
|
247
|
+
covalent ligands, mmCIF input, automatic loop modeling, ORCA, Multiwfn,
|
|
248
|
+
multiple independent bonded MCPB sites, or multi-chain MCPB protein inputs.
|
|
249
|
+
Unsupported chemistry fails explicitly.
|
|
250
|
+
|
|
251
|
+
## Development and release checks
|
|
252
|
+
|
|
253
|
+
```bash
|
|
254
|
+
mamba env create -f environment-dev.yml
|
|
255
|
+
conda activate mdprep-dev
|
|
256
|
+
pytest -q
|
|
257
|
+
python -m mdprep.cli --help
|
|
258
|
+
python -m mdprep.cli config-check examples/*.yaml
|
|
259
|
+
python -m mdprep.cli selftest --quick
|
|
260
|
+
python -m hatchling build
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md), [CHANGELOG.md](CHANGELOG.md), and
|
|
264
|
+
[CITATION.cff](CITATION.cff). mdprep is distributed under the MIT license.
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
mdprep/__init__.py,sha256=NFWf_wM1aFwOteTgCQZsHzilC14lueT5DwDkYD_Ptrk,108
|
|
2
|
+
mdprep/cli.py,sha256=G8XKYQnmyu3hSoS6qzEANhdrb4-6rNC4AWxmaH_Lx5I,15903
|
|
3
|
+
mdprep/_selftest_data/basic_protein.yaml,sha256=II2s1MHqocorravC0oN9llxTXWDTzxNKKfBgKthLCB4,479
|
|
4
|
+
mdprep/_selftest_data/ligand_sub.mol2,sha256=iYr_D00W0hwMt-fHF8QSaZqYFWHm6cBoEisuaARNb00,268
|
|
5
|
+
mdprep/ambertools/__init__.py,sha256=11IDxd6TOTzyt3V5WKI8KVhtntDlA3YwmgyYUFdO_Xo,36
|
|
6
|
+
mdprep/ambertools/antechamber.py,sha256=42T2J2b8hQUscIi6LMk6IGfYrW0OgnabuZM7C1zoEBU,2943
|
|
7
|
+
mdprep/ambertools/commands.py,sha256=HtpDZkWUUXZutxFt3KdR1kTJvQr-kvOgY9E6S_rWgs4,997
|
|
8
|
+
mdprep/ambertools/mol2.py,sha256=mPMA6FqhsuzVh5-AJAHwUcTRBU1m8gHHi084XaRF3Go,12755
|
|
9
|
+
mdprep/ambertools/parmchk2.py,sha256=l1hpzfDDCzwmeUIL4MnqhEpyD97P2CICYjt8CHpEIHI,2540
|
|
10
|
+
mdprep/ambertools/resp.py,sha256=o0fbYa05NiWNOsNDwUwoKFwmUhRV-yfR4cQKQUoWeaE,20234
|
|
11
|
+
mdprep/charges/__init__.py,sha256=orUoBoYV7N85A0Z2XBp8HHYrbz2ZW3Z5CvHkZoQESc4,38
|
|
12
|
+
mdprep/charges/esp_grid.py,sha256=ShSWr5IQ0iLsuquzyOaX_GZm9vhLyRkLcx1Z9PA-EbM,6430
|
|
13
|
+
mdprep/config/__init__.py,sha256=dgn349blqEXMOMGDbl5GTAy7IcmeNeQi1L7HC6UzqUY,228
|
|
14
|
+
mdprep/config/loader.py,sha256=2H1i4swe6_JqP62Pd_tGy9cbVS5-E9u7YqaMf8l8KcM,5961
|
|
15
|
+
mdprep/config/models.py,sha256=WmYc-Y1UEyQGyUWOabpxMGlLoSEL0paJZxFnofxyqYs,45591
|
|
16
|
+
mdprep/external/__init__.py,sha256=XFwbRVVJr_q6VPdPQBpbeWBYQtFXX-c3gimVZSKPKqQ,328
|
|
17
|
+
mdprep/external/discovery.py,sha256=VEm5kYk4WUP6WmgkZqxjRQkMgM_QzA4iTEFIFcjhvrY,318
|
|
18
|
+
mdprep/external/runner.py,sha256=bXYeyYff3JA9s49Rs3X-fSvnb92V4J6urVkx92D4TLE,1421
|
|
19
|
+
mdprep/leap/__init__.py,sha256=XOmJw8MMe0urNrQfrafCgKz3w0_fR_ZHD15TkDbgRjs,35
|
|
20
|
+
mdprep/leap/builder.py,sha256=-ZgvrGvjesm4fcx3_dz5kuXOllWo-d2g_u_GhqrkYNM,18686
|
|
21
|
+
mdprep/leap/forcefields.py,sha256=YuBZlPU1Bah3gaXy1741PQlDkG1tM7jxuuPx9gHsYhM,2275
|
|
22
|
+
mdprep/leap/ions.py,sha256=hZbyS2OE7dkF9K-W9poVDhcw7rXVmuUKIv5MEnFAH2o,3555
|
|
23
|
+
mdprep/leap/log_parser.py,sha256=aJMfmug3NV2M-eE3iokbbaX6AG56lHy92fVuUwLmIn0,6074
|
|
24
|
+
mdprep/leap/report.py,sha256=a3X6oGoyOR7WtyU4oS_q9Wgx6ME7QgzXg2ei02516ak,3082
|
|
25
|
+
mdprep/leap/residues.py,sha256=B1y6g1ilcczAUy_Ik5uru8zo4rLGkiVVXzyl6-68ofo,25835
|
|
26
|
+
mdprep/leap/runner.py,sha256=QDOL7wksI_OmEx8tH_9sDmYNqyj2q0Zgvi8H2dlq0ZQ,2028
|
|
27
|
+
mdprep/ligands/__init__.py,sha256=2lyVnqZFYfVrTYZe7tvmXynobk8kPGmWBSkgaPQ6XdE,57
|
|
28
|
+
mdprep/ligands/extract.py,sha256=8LG2nvl6-xltbmCHyFRibcetBQsXDy-a2AVFaL5aYZE,13502
|
|
29
|
+
mdprep/ligands/identity.py,sha256=PJGvIIpQ6o1ZyCo-dOkwLFIOkCMeyUiwQ7X5dmrpFV0,1151
|
|
30
|
+
mdprep/ligands/pyscf_charges.py,sha256=iNUbz518lKVHTZQGAklv7CEYkwo15_AUx_XrO8LxoDk,10730
|
|
31
|
+
mdprep/ligands/report.py,sha256=Fy0Z0JM9bWrenKrkzwBN3FBjFNZ93K47hv-HJJ5u0PI,5782
|
|
32
|
+
mdprep/ligands/workflow.py,sha256=B1M3N6lfTbYagfOkZcDF5qw1wvMQZ1utWnJh6smeiAM,34158
|
|
33
|
+
mdprep/md/__init__.py,sha256=IxNFQXkdY5aoFQEQgw_JwHzFFj6lvbycNF36ayP99g8,168
|
|
34
|
+
mdprep/md/roe_brooks.py,sha256=1NVpShAIFdJ-itEM8wHE4muelFU4lZj74d4bXJHuOxE,26358
|
|
35
|
+
mdprep/metals/__init__.py,sha256=9JFeDdF8kzl554wFX93bqmCwpXfY5VSQn490hpiZ6pU,41
|
|
36
|
+
mdprep/metals/c4.py,sha256=6-cBuJ76-6vL8Ejw2ahmn3j3GQtHJJXwXb0XcvlUqpc,5696
|
|
37
|
+
mdprep/metals/coordination.py,sha256=QFTs7akw9blLTanW-QNKMAyY7v-CJZ_scdFWXb-hm0M,11751
|
|
38
|
+
mdprep/metals/gxtb_hessian.py,sha256=cmv_WEeZO_IyLBaIBne9ek2JxDfHFnqnze5_nlEKX8Y,16960
|
|
39
|
+
mdprep/metals/hydrogenate.py,sha256=pxeD-BLg6iVT-PHMKHt7muqHmEtPCDtJ11pBx16p2DI,12982
|
|
40
|
+
mdprep/metals/mace_polar1_hessian.py,sha256=9Y-lcrdM4KKl7gYmPu9M1s6RFYTxRgMx28ciCBfG0Gc,13433
|
|
41
|
+
mdprep/metals/mace_polar1_worker.py,sha256=O9xQQ_npvcY9t03ghhX9Ew9w5sbrQmTuQPjrHuH_jDk,10468
|
|
42
|
+
mdprep/metals/mcpb.py,sha256=Bov0p8LjGH1ON5MPu4s9-HKbHuyMUczoawLesewuTjM,35723
|
|
43
|
+
mdprep/metals/mcpb_compat.py,sha256=h2cWsJt7pGZk1ud8zktHYTVUluWUNKx3bwDdUaO_XVw,4225
|
|
44
|
+
mdprep/metals/nonbonded.py,sha256=ifto_OdB00ainPCTWeztrbvt_Qa-Yk24-wr8TJCeVo8,10245
|
|
45
|
+
mdprep/metals/parameter_comparison.py,sha256=Ygcn0gQaS97VuhtjdmPVklS2TGGLKU-oTm8aH27hxaQ,21189
|
|
46
|
+
mdprep/metals/pyscf_mcpb.py,sha256=DT5WAgAYi15R1y7_4MQIA7HK6MLbkmA7lwiL9yS0gYQ,54718
|
|
47
|
+
mdprep/metals/report.py,sha256=A8zmYUmCPItFNY5w6pMdd6GyuFcNcbVMZ1pbQBsmTAE,4694
|
|
48
|
+
mdprep/metals/workflow.py,sha256=rk0kB4qKxIPSiiwTiSbApWGrwPYrsRHCDgL-F0Jq5Os,12968
|
|
49
|
+
mdprep/protonation/__init__.py,sha256=DU8KQh6gAaM_zfdnvtZLSCtuM2kbtJ2nYv_dNQgjuFQ,465
|
|
50
|
+
mdprep/protonation/apply.py,sha256=svVgbbbiYGabfLrYyQWyelMq0AyVBO_yQn55nVFBdDI,39519
|
|
51
|
+
mdprep/protonation/disulfide_states.py,sha256=0R4yHQXuSfboqKT3Gzv7TRMmoC7A77CtUbJCsvLRgIQ,4949
|
|
52
|
+
mdprep/protonation/histidine_geometry.py,sha256=NzCPbxIwIMWRcaOZiTrvSAGvMtOgmplreTfv4ORMSMU,33581
|
|
53
|
+
mdprep/protonation/histidine_xtb.py,sha256=IXpwlTWw8tL18H7XtN8FJchA0SaHf3HuVl5XySrGPXo,14017
|
|
54
|
+
mdprep/protonation/overrides.py,sha256=DWa4avlXA0hssUNW0QmQHJdjwiYj4eZcd2nWbl0-CwE,2203
|
|
55
|
+
mdprep/protonation/pka_rules.py,sha256=vgfn4d8pmMJwvjG6NjICtl8crUIDBFxumpUNI7g8pvM,5221
|
|
56
|
+
mdprep/protonation/propka.py,sha256=TUauk9MzmVbQZaOrGkYeh3dW3ex_d9UZcwQPoE7KqVg,6188
|
|
57
|
+
mdprep/protonation/propka_parser.py,sha256=pquqx_dnNv0A8ns2xVuNwqxYoDayaLPNrgMV5NLMn7k,3934
|
|
58
|
+
mdprep/protonation/report.py,sha256=6WhEpvla4WhbtowCr8b5r8Hy25PSaEJGG6T-2HVlKAU,6953
|
|
59
|
+
mdprep/protonation/states.py,sha256=W2pT9FskDmErCyq8MrBXt9tilZE6vypv4x-YSlNkttQ,1590
|
|
60
|
+
mdprep/protonation/temporary_hydrogenation.py,sha256=OO9qmCPJ6tUga7SQBATM2he2qVoMB9Vpjcm6LlA5ebs,9413
|
|
61
|
+
mdprep/protonation/xtb_parser.py,sha256=c0SZlYBqikomIUTNxrG_LSGFJpN-s5UKWEFLc5CZ8bw,2430
|
|
62
|
+
mdprep/protonation/xtb_runner.py,sha256=c-jWif4Tw8i_6N67XvuvmHsd9ISEQgUitxpX-rN2dUU,3532
|
|
63
|
+
mdprep/qm/__init__.py,sha256=Q6hS_uPA2LsQRrnr1NDpAmK03iC82JzVRP-hpJWJsNo,27
|
|
64
|
+
mdprep/qm/point_charges.py,sha256=kJjyFZ4zI-xgRyDrabvnDRvMQUS4QjdKqNEo-RF-o6s,9010
|
|
65
|
+
mdprep/qm/pyscf_esp.py,sha256=DiJkgBQav4X5ceV7I5vdQIrGgQ4P-bf5p9OoV2eb-Y8,2936
|
|
66
|
+
mdprep/qm/pyscf_runner.py,sha256=Y5fATm9OMZV-4YADL9SrFNvy1qqP0qRSp2wjdh5BB9E,23192
|
|
67
|
+
mdprep/refinement/__init__.py,sha256=x_BFoDFNzvI1CPaq5SC5FMPpSUC_0Vt0MgIq4wcLV0c,210
|
|
68
|
+
mdprep/refinement/ash.py,sha256=2-UzOx2HAJilNNM51wSUmnltxRyVysziJc_ADtr5aGI,21916
|
|
69
|
+
mdprep/refinement/coordinates.py,sha256=9Ek79aRXZm0tQZCBzc79sh-wKq2wwyyaLjtdjgbkGVc,8609
|
|
70
|
+
mdprep/refinement/mapping.py,sha256=hmtB2eZmydNM-98y5i1ZPwHwmTT8TSknna8DWnEtbBU,5796
|
|
71
|
+
mdprep/refinement/report.py,sha256=y4qgNd8TY_V7TcHwA67JG3jKxlbb9GQLcph-Cw_6xhI,2623
|
|
72
|
+
mdprep/refinement/selection.py,sha256=u5wrLArzBv5WM0DxcPDHw_kwTfNEM8Jy-Kn9XzK6e8I,17177
|
|
73
|
+
mdprep/refinement/workflow.py,sha256=FJk-cTuHBPiv8MEKw9dVTvjNKPPJVsVx7-rFHXr9Ack,6971
|
|
74
|
+
mdprep/reports/__init__.py,sha256=w91ptuL6SzaywtH0VzEzUBitC0jIsEr3lSe6aoXd4vU,167
|
|
75
|
+
mdprep/reports/structure_report.py,sha256=baX3ekllzVUKXQ-KFUQzY-lIwZBFuFbV9CA9ZFRNtlE,3308
|
|
76
|
+
mdprep/structure/__init__.py,sha256=A_yKx-ixlCy01w7eAOZk6FExwr0vRAr-DTTv9LhkQbw,351
|
|
77
|
+
mdprep/structure/classify.py,sha256=-kcjAXzFEU7wFW1-Rgnz_rnjBhPpiCfRrBLdghkpWSM,2013
|
|
78
|
+
mdprep/structure/disulfides.py,sha256=IGlpAClelrzLFvL3_UtUShmaKSdyikHLP3hnD6ewEKk,1539
|
|
79
|
+
mdprep/structure/inspect.py,sha256=XqGMQKf54WwuyMgIWSB3k4qtkMU42U6BQTNT3PyOWA8,4165
|
|
80
|
+
mdprep/structure/models.py,sha256=nQUakPXfjrM1bsTnK1tne18gTkH7ldfCXWSW-PZ0ST4,2316
|
|
81
|
+
mdprep/structure/normalize.py,sha256=8TVB7osyG46K6u6IQx20I2seIvZfeFDl23EDxtNXXS0,15345
|
|
82
|
+
mdprep/structure/pdb.py,sha256=ccRuijS7PyQU2pBnpQyvk-ISrQ5r86Ik2xxxcka8vV0,13286
|
|
83
|
+
mdprep/structure/repair.py,sha256=gWJQ8yzmlezN9t0kOlUAiS7mdEq2cI-zjxt5awnJfpA,20798
|
|
84
|
+
mdprep/structure/selectors.py,sha256=URjI0liedLqrEoh3aYcZsL9EQfzgav_IiX9EdU-19i8,7986
|
|
85
|
+
mdprep/structure/writer.py,sha256=pI-0z30j0WSdVcw-8Le0s-jbUWzG2WU6AbGkeKNesL0,3225
|
|
86
|
+
mdprep/validation/__init__.py,sha256=yjJhITuigb6aUxakVjoxSfwDD_2Ah059nNLos7O9DoI,42
|
|
87
|
+
mdprep/validation/openmm_check.py,sha256=2p3iATKpdUq5VLx-lF1nogBlueAQAlS2ldxvLIc-IFA,3338
|
|
88
|
+
mdprep/validation/parmed_check.py,sha256=vvyveiTpziV_Xdw55_wipvAlsP1j_XQHWqr0kT3ppXA,1384
|
|
89
|
+
mdprep/validation/topology.py,sha256=cy54stpYi210PmHDcXmUhghcGaDoXelEvTHT53Qy1Fk,9276
|
|
90
|
+
mdprep/workflows/__init__.py,sha256=HuHuTGSCYC_VU7Z1a8wq9DK7VQmqMAdPwMJK07FNF4Y,91
|
|
91
|
+
mdprep/workflows/init.py,sha256=mJwaYU7eqomlP3z_LlsGlXUi1DoXXX2_ze42n3L_8J8,8748
|
|
92
|
+
mdprep/workflows/inspect.py,sha256=ZdtxqkZCYrDugvgltmTvDet70lhq7QOCF-NTqb-6JbA,575
|
|
93
|
+
mdprep/workflows/prepare.py,sha256=BRby5x1nVfUSAVYepfQKUB-Ey2N4f6dvwk0FJ-JQ4w0,32406
|
|
94
|
+
mdprep/workflows/selftest.py,sha256=B4d527b_zIfMxAIVZZVlZGAYbop9-hfToW22qtQYdw8,7517
|
|
95
|
+
mdprep/workflows/validate.py,sha256=ug-3xySmGkB1iv-GOR6OOvNu8KD4aNlmCsGELpjQ5-E,974
|
|
96
|
+
mdprep-0.2.0.dist-info/METADATA,sha256=wmsqw690pY4AknbmvIcmZBXg7eihcscjdbUmrAoRmGQ,8933
|
|
97
|
+
mdprep-0.2.0.dist-info/WHEEL,sha256=zOwg4jB6zX2kU910N-cMawjivD6tO8NEWvE12je1bVk,87
|
|
98
|
+
mdprep-0.2.0.dist-info/entry_points.txt,sha256=Ht5zL5TCWAvC9VBPeVeKws5pD0-Ajx8TM08rJSWJl3A,42
|
|
99
|
+
mdprep-0.2.0.dist-info/licenses/LICENSE,sha256=X3UjXiT5AmegEGyA-AeYktV8_ZtheJktrGGcwwa1CgE,1076
|
|
100
|
+
mdprep-0.2.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Miquel Estévez-Gay
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|