Skip to content

Commit f17eebb

Browse files
authored
Merge pull request #81 from dwhswenson/load_trajectory
New command: Load trajectory
2 parents de53902 + 9772eef commit f17eebb

File tree

2 files changed

+140
-0
lines changed

2 files changed

+140
-0
lines changed
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import click
2+
3+
import paths_cli.utils
4+
from paths_cli.parameters import APPEND_FILE, ENGINE, MULTI_TAG
5+
from paths_cli import OPSCommandPlugin
6+
7+
8+
@click.command(
9+
"load-trajectory",
10+
short_help="Load an external trajectory file",
11+
)
12+
@click.argument('traj_file')
13+
@click.option(
14+
'--top',
15+
help=(
16+
"Topology file (typically PDB). Only for required "
17+
"formats."
18+
),
19+
default=None,
20+
)
21+
@APPEND_FILE.clicked(required=True)
22+
@MULTI_TAG.clicked()
23+
def load_trajectory(traj_file, top, append_file, tag):
24+
"""Load a trajectory from a file.
25+
26+
This uses MDTraj under the hood, and can load any file format that
27+
MDTraj can. NB: This stores in a format based on OpenMM snapshots.
28+
Trajectories loaded this way will work with engines compatible with
29+
that input (e.g., GROMACS).
30+
"""
31+
from openpathsampling.engines.openmm.tools import ops_load_trajectory
32+
if top:
33+
traj = ops_load_trajectory(traj_file, top=top)
34+
else:
35+
traj = ops_load_trajectory(traj_file)
36+
37+
storage = APPEND_FILE.get(append_file)
38+
storage.save(traj)
39+
for tag_name in tag:
40+
storage.tags[tag_name] = traj
41+
42+
43+
PLUGIN = OPSCommandPlugin(
44+
command=load_trajectory,
45+
section="Miscellaneous",
46+
requires_ops=(1, 6),
47+
requires_cli=(0, 4),
48+
)
49+
50+
if __name__ == "__main__": # -no-cov-
51+
load_trajectory()
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
from click.testing import CliRunner
2+
from contextlib import contextmanager
3+
import pytest
4+
from importlib import resources
5+
from openpathsampling.tests.test_helpers import data_filename
6+
import openpathsampling as paths
7+
8+
from paths_cli.commands.load_trajectory import *
9+
10+
11+
@contextmanager
12+
def run_load_trajectory(args):
13+
runner = CliRunner()
14+
with runner.isolated_filesystem():
15+
storage = paths.Storage("setup.nc", 'w')
16+
storage.close()
17+
results = runner.invoke(
18+
load_trajectory,
19+
args
20+
)
21+
assert results.exit_code == 0
22+
st = paths.Storage("setup.nc", mode='r')
23+
assert len(st.trajectories) == 1
24+
yield st
25+
26+
27+
@pytest.mark.parametrize("with_top", [True, False])
28+
@pytest.mark.parametrize("with_tag", [True, False])
29+
def test_load_trajectory_pdb(with_top, with_tag):
30+
# test that we can load a PDB file with or without topology; also tests
31+
# that the taging works correctly
32+
pytest.importorskip("openmm")
33+
pytest.importorskip("mdtraj")
34+
pdb_path = data_filename("ala_small_traj.pdb")
35+
out_file = "setup.nc"
36+
args = [
37+
pdb_path,
38+
'--append-file', out_file,
39+
]
40+
if with_top:
41+
args.extend(['--top', pdb_path])
42+
43+
if with_tag:
44+
args.extend(['--tag', 'init_snap'])
45+
46+
with run_load_trajectory(args) as st:
47+
traj = st.trajectories[0]
48+
assert len(traj) == 10
49+
if with_tag:
50+
tagged = st.tags['init_snap']
51+
assert tagged == traj
52+
53+
def test_load_trajectory_trr():
54+
pytest.importorskip("openmm")
55+
pytest.importorskip("mdtraj")
56+
trr = data_filename("gromacs_engine/project_trr/0000000.trr")
57+
gro = data_filename("gromacs_engine/conf.gro")
58+
out_file = "setup.nc"
59+
args = [
60+
trr,
61+
'--append-file', out_file,
62+
'--top', gro,
63+
]
64+
with run_load_trajectory(args) as st:
65+
traj = st.trajectories[0]
66+
assert len(traj) == 4
67+
68+
def test_load_trajectory_bad_topology():
69+
pytest.importorskip("openmm")
70+
pytest.importorskip("mdtraj")
71+
trr = data_filename("gromacs_engine/project_trr/0000000.trr")
72+
pdb = data_filename("tip4p_water.pdb")
73+
out_file = "setup.nc"
74+
args = [
75+
trr,
76+
'--append-file', out_file,
77+
'--top', pdb,
78+
]
79+
runner = CliRunner()
80+
with runner.isolated_filesystem():
81+
storage = paths.Storage("setup.nc", 'w')
82+
storage.close()
83+
result = runner.invoke(
84+
load_trajectory,
85+
args
86+
)
87+
assert result.exit_code == 1
88+
assert "topology" in str(result.exception)
89+
assert "same atoms" in str(result.exception)

0 commit comments

Comments
 (0)