imdclient 0.1.2__py3-none-any.whl → 0.1.4__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.
- imdclient/{IMDREADER.py → IMD.py} +5 -4
- imdclient/IMDClient.py +118 -15
- imdclient/IMDProtocol.py +1 -0
- imdclient/data/gromacs/md/gromacs_v3_nst1.mdp +3 -3
- imdclient/data/gromacs/md/gromacs_v3_nst8.mdp +58 -0
- imdclient/data/lammps/md/{lammps_v3.in → lammps_v3_nst_1.in} +3 -3
- imdclient/data/lammps/md/lammps_v3_nst_8.in +71 -0
- imdclient/data/namd/md/{namd_v3.namd → namd_v3_nst_1.namd} +17 -5
- imdclient/data/namd/md/namd_v3_nst_8.namd +59 -0
- imdclient/tests/base.py +179 -45
- imdclient/tests/conftest.py +0 -39
- imdclient/tests/datafiles.py +33 -10
- imdclient/tests/docker_testing/docker.md +25 -0
- imdclient/tests/hpc_testing/gromacs/README.md +112 -0
- imdclient/tests/hpc_testing/gromacs/gmx_gpu_test.mdp +58 -0
- imdclient/tests/hpc_testing/gromacs/gmx_gpu_test.top +11764 -0
- imdclient/tests/hpc_testing/gromacs/struct.gro +21151 -0
- imdclient/tests/hpc_testing/gromacs/validate_gmx.sh +90 -0
- imdclient/tests/hpc_testing/lammps/README.md +62 -0
- imdclient/tests/hpc_testing/lammps/lammps_v3_nst_1.in +71 -0
- imdclient/tests/hpc_testing/lammps/topology_after_min.data +8022 -0
- imdclient/tests/hpc_testing/lammps/validate_lmp.sh +66 -0
- imdclient/tests/hpc_testing/namd/README.md +73 -0
- imdclient/tests/hpc_testing/namd/alanin.params +402 -0
- imdclient/tests/hpc_testing/namd/alanin.pdb +77 -0
- imdclient/tests/hpc_testing/namd/alanin.psf +206 -0
- imdclient/tests/hpc_testing/namd/namd_v3_nst_1.namd +59 -0
- imdclient/tests/hpc_testing/namd/validate_namd.sh +71 -0
- imdclient/tests/server.py +2 -11
- imdclient/tests/test_gromacs.py +32 -10
- imdclient/tests/test_imdclient.py +69 -0
- imdclient/tests/test_imdreader.py +74 -1
- imdclient/tests/test_lammps.py +57 -12
- imdclient/tests/test_manual.py +223 -65
- imdclient/tests/test_namd.py +101 -14
- imdclient/tests/test_stream_analysis.py +1 -1
- imdclient/tests/utils.py +0 -1
- imdclient-0.1.4.dist-info/LICENSE +5 -0
- imdclient-0.1.4.dist-info/METADATA +132 -0
- imdclient-0.1.4.dist-info/RECORD +57 -0
- {imdclient-0.1.2.dist-info → imdclient-0.1.4.dist-info}/WHEEL +1 -1
- imdclient/data/gromacs/md/gromacs_v3_nst1.tpr +0 -0
- imdclient/data/gromacs/md/gromacs_v3_nst1.trr +0 -0
- imdclient/data/lammps/md/lammps_trj.h5md +0 -0
- imdclient/data/namd/md/alanin.dcd +0 -0
- imdclient-0.1.2.dist-info/LICENSE +0 -674
- imdclient-0.1.2.dist-info/METADATA +0 -795
- imdclient-0.1.2.dist-info/RECORD +0 -42
- {imdclient-0.1.2.dist-info → imdclient-0.1.4.dist-info}/AUTHORS.md +0 -0
- {imdclient-0.1.2.dist-info → imdclient-0.1.4.dist-info}/top_level.txt +0 -0
imdclient/tests/test_lammps.py
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
import MDAnalysis as mda
|
2
2
|
import pytest
|
3
|
+
from pathlib import Path
|
3
4
|
import logging
|
4
5
|
from .base import IMDv3IntegrationTest
|
5
|
-
from .datafiles import
|
6
|
+
from .datafiles import LAMMPS_TOPOL, LAMMPS_IN_NST_1, LAMMPS_IN_NST_8
|
6
7
|
|
7
8
|
logger = logging.getLogger("imdclient.IMDClient")
|
8
|
-
file_handler = logging.FileHandler("
|
9
|
+
file_handler = logging.FileHandler("lammps_test.log")
|
9
10
|
formatter = logging.Formatter(
|
10
11
|
"%(asctime)s - %(name)s - %(levelname)s - %(message)s"
|
11
12
|
)
|
@@ -16,23 +17,67 @@ logger.setLevel(logging.DEBUG)
|
|
16
17
|
|
17
18
|
class TestIMDv3Lammps(IMDv3IntegrationTest):
|
18
19
|
|
20
|
+
@pytest.fixture(params=[LAMMPS_IN_NST_1, LAMMPS_IN_NST_8])
|
21
|
+
def inp(self, request):
|
22
|
+
return request.param
|
23
|
+
|
24
|
+
@pytest.fixture()
|
25
|
+
def simulation_command(self, inp):
|
26
|
+
return f"lmp < {Path(inp).name}"
|
27
|
+
|
28
|
+
@pytest.fixture()
|
29
|
+
def topol(self):
|
30
|
+
return Path(LAMMPS_TOPOL).name
|
31
|
+
|
32
|
+
@pytest.fixture()
|
33
|
+
def traj(self):
|
34
|
+
return "lammps_trj.h5md"
|
35
|
+
|
19
36
|
@pytest.fixture()
|
20
|
-
def
|
21
|
-
return
|
37
|
+
def input_files(self, inp):
|
38
|
+
return [inp, LAMMPS_TOPOL]
|
39
|
+
|
40
|
+
# @pytest.fixture()
|
41
|
+
# def match_string(self):
|
42
|
+
# return "Waiting for IMD connection on port 8888"
|
22
43
|
|
23
44
|
@pytest.fixture()
|
24
|
-
def
|
25
|
-
|
45
|
+
def first_frame(self, inp):
|
46
|
+
if inp == LAMMPS_IN_NST_1:
|
47
|
+
return 1
|
48
|
+
else:
|
49
|
+
return 0
|
26
50
|
|
51
|
+
# Not present in lammps-produced H5MD
|
27
52
|
@pytest.fixture()
|
28
|
-
def
|
29
|
-
return
|
53
|
+
def comp_dt(self):
|
54
|
+
return False
|
30
55
|
|
56
|
+
# This must wait until after imd stream has ended
|
31
57
|
@pytest.fixture()
|
32
|
-
def
|
33
|
-
|
34
|
-
|
35
|
-
|
58
|
+
def true_u(self, topol, traj, imd_u, tmp_path):
|
59
|
+
u = mda.Universe(
|
60
|
+
(tmp_path / topol),
|
61
|
+
(tmp_path / traj),
|
36
62
|
atom_style="id type x y z",
|
37
63
|
convert_units=False,
|
38
64
|
)
|
65
|
+
yield u
|
66
|
+
|
67
|
+
@pytest.fixture()
|
68
|
+
def imd_u(self, docker_client, topol, tmp_path, port):
|
69
|
+
u = mda.Universe(
|
70
|
+
(tmp_path / topol),
|
71
|
+
f"imd://localhost:{port}",
|
72
|
+
atom_style="id type x y z",
|
73
|
+
)
|
74
|
+
with mda.Writer(
|
75
|
+
(tmp_path / "imd.trr").as_posix(), u.trajectory.n_atoms
|
76
|
+
) as w:
|
77
|
+
for ts in u.trajectory:
|
78
|
+
w.write(u.atoms)
|
79
|
+
yield mda.Universe(
|
80
|
+
(tmp_path / topol),
|
81
|
+
(tmp_path / "imd.trr"),
|
82
|
+
atom_style="id type x y z",
|
83
|
+
)
|
imdclient/tests/test_manual.py
CHANGED
@@ -1,14 +1,11 @@
|
|
1
|
-
|
2
|
-
import
|
1
|
+
import imdclient
|
2
|
+
from imdclient.IMD import IMDReader
|
3
3
|
import MDAnalysis as mda
|
4
|
-
from
|
5
|
-
from numpy.testing import (
|
6
|
-
assert_allclose,
|
7
|
-
)
|
4
|
+
from numpy.testing import assert_allclose
|
8
5
|
import numpy as np
|
9
|
-
from .base import assert_allclose_with_logging
|
10
6
|
from pathlib import Path
|
11
|
-
|
7
|
+
import time
|
8
|
+
import argparse
|
12
9
|
import logging
|
13
10
|
|
14
11
|
logger = logging.getLogger("imdclient.IMDClient")
|
@@ -20,72 +17,233 @@ file_handler.setFormatter(formatter)
|
|
20
17
|
logger.addHandler(file_handler)
|
21
18
|
logger.setLevel(logging.DEBUG)
|
22
19
|
|
20
|
+
"""
|
21
|
+
Tool for running IMDv3 integration tests via the command line.
|
23
22
|
|
24
|
-
|
25
|
-
|
26
|
-
Tool for running IMDv3 integration tests via the command line.
|
23
|
+
To use, start the simulation, wait for it to be ready for an IMD connection,
|
24
|
+
and then run this command relative to the root of the cloned respository:
|
27
25
|
|
28
|
-
|
29
|
-
|
26
|
+
python imdclient/tests/test_manual.py \
|
27
|
+
--topol_path <path/to/topology> \
|
28
|
+
--traj_path <path/to/trajectory> \
|
29
|
+
--first_frame <first frame to compare> \
|
30
|
+
--tmp_path <temporary directory for IMD trajectory>
|
30
31
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
32
|
+
Where the topology is the same topology as the IMD system, the trajectory is the path where
|
33
|
+
the trajectory of the running simulation is being written, and the first frame is the first frame of the
|
34
|
+
trajectory which should be compared to IMD data read from the socket (0 for GROMACS and NAMD, 1 for LAMMPS)
|
35
|
+
"""
|
36
|
+
|
37
|
+
|
38
|
+
def assert_allclose_with_logging(a, b, rtol=1e-07, atol=0, equal_nan=False):
|
39
|
+
"""
|
40
|
+
Custom function to compare two arrays element-wise, similar to np.testing.assert_allclose,
|
41
|
+
but logs all non-matching values.
|
35
42
|
|
36
|
-
|
37
|
-
|
38
|
-
|
43
|
+
Parameters:
|
44
|
+
a, b : array_like
|
45
|
+
Input arrays to compare.
|
46
|
+
rtol : float
|
47
|
+
Relative tolerance.
|
48
|
+
atol : float
|
49
|
+
Absolute tolerance.
|
50
|
+
equal_nan : bool
|
51
|
+
Whether to compare NaNs as equal.
|
39
52
|
"""
|
53
|
+
# Convert inputs to numpy arrays
|
54
|
+
a = np.asarray(a)
|
55
|
+
b = np.asarray(b)
|
56
|
+
|
57
|
+
# Compute the absolute difference
|
58
|
+
diff = np.abs(a - b)
|
59
|
+
|
60
|
+
# Check if values are within tolerance
|
61
|
+
not_close = diff > (atol + rtol * np.abs(b))
|
62
|
+
|
63
|
+
# Check if there are any NaNs and handle them if necessary
|
64
|
+
if equal_nan:
|
65
|
+
nan_mask = np.isnan(a) & np.isnan(b)
|
66
|
+
not_close &= ~nan_mask
|
67
|
+
|
68
|
+
# Log all the values that are not close
|
69
|
+
if np.any(not_close):
|
70
|
+
print("The following values do not match within tolerance:")
|
71
|
+
for idx in np.argwhere(not_close):
|
72
|
+
logger.debug(
|
73
|
+
f"a[{tuple(idx)}]: {a[tuple(idx)]}, b[{tuple(idx)}]: {b[tuple(idx)]}, diff: {diff[tuple(idx)]}"
|
74
|
+
)
|
75
|
+
# Optionally raise an error after logging if you want it to behave like assert
|
76
|
+
raise AssertionError("Arrays are not almost equal.")
|
77
|
+
else:
|
78
|
+
print("All values are within tolerance.")
|
40
79
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
80
|
+
|
81
|
+
def load_true_universe(topol_path, traj_path):
|
82
|
+
if topol_path.endswith(".data"):
|
83
|
+
return mda.Universe(
|
84
|
+
topol_path,
|
85
|
+
traj_path,
|
86
|
+
atom_style="id type x y z",
|
87
|
+
convert_units=False,
|
88
|
+
)
|
89
|
+
return mda.Universe(topol_path, traj_path)
|
90
|
+
|
91
|
+
|
92
|
+
def load_imd_universe(topol_path, tmp_path):
|
93
|
+
# Pass atom_style (ignored if not using LAMMPS topol)
|
94
|
+
tmp_u = mda.Universe(
|
95
|
+
topol_path,
|
96
|
+
"imd://localhost:8888",
|
97
|
+
atom_style="id type x y z",
|
98
|
+
)
|
99
|
+
tmp_traj_file = f"{tmp_path}/imd_test_traj.trr"
|
100
|
+
with mda.Writer(tmp_traj_file, tmp_u.atoms.n_atoms) as w:
|
101
|
+
for ts in tmp_u.trajectory:
|
102
|
+
w.write(tmp_u.atoms)
|
103
|
+
time.sleep(10) # Give MPI ranks a chance to release FD
|
104
|
+
return mda.Universe(topol_path, tmp_traj_file, atom_style="id type x y z")
|
105
|
+
|
106
|
+
|
107
|
+
def test_compare_imd_to_true_traj_vel(imd_u, true_u_vel, first_frame):
|
108
|
+
for i in range(first_frame, len(true_u_vel.trajectory)):
|
109
|
+
# Manually convert unit
|
110
|
+
assert_allclose_with_logging(
|
111
|
+
true_u_vel.trajectory[i].positions * 20.45482706,
|
112
|
+
imd_u.trajectory[i - first_frame].velocities,
|
113
|
+
atol=1e-03,
|
55
114
|
)
|
56
|
-
yield imd_u
|
57
115
|
|
58
|
-
def test_compare_imd_to_true_traj(self, true_u, imd_u, first_frame_arg):
|
59
116
|
|
60
|
-
|
117
|
+
def test_compare_imd_to_true_traj_forces(imd_u, true_u_force, first_frame):
|
118
|
+
for i in range(first_frame, len(true_u_force.trajectory)):
|
119
|
+
assert_allclose_with_logging(
|
120
|
+
true_u_force.trajectory[i].positions,
|
121
|
+
imd_u.trajectory[i - first_frame].forces,
|
122
|
+
atol=1e-03,
|
123
|
+
)
|
124
|
+
|
125
|
+
|
126
|
+
def test_compare_imd_to_true_traj(imd_u, true_u, first_frame, vel, force, dt):
|
127
|
+
for i in range(first_frame, len(true_u.trajectory)):
|
128
|
+
assert_allclose(
|
129
|
+
true_u.trajectory[i].time,
|
130
|
+
imd_u.trajectory[i - first_frame].time,
|
131
|
+
atol=1e-03,
|
132
|
+
)
|
133
|
+
if dt:
|
61
134
|
assert_allclose(
|
62
|
-
true_u.trajectory[i].
|
135
|
+
true_u.trajectory[i].dt,
|
136
|
+
imd_u.trajectory[i - first_frame].dt,
|
137
|
+
atol=1e-03,
|
63
138
|
)
|
64
|
-
|
65
|
-
|
66
|
-
|
139
|
+
assert_allclose(
|
140
|
+
true_u.trajectory[i].data["step"],
|
141
|
+
imd_u.trajectory[i - first_frame].data["step"],
|
142
|
+
)
|
143
|
+
assert_allclose_with_logging(
|
144
|
+
true_u.trajectory[i].dimensions,
|
145
|
+
imd_u.trajectory[i - first_frame].dimensions,
|
146
|
+
atol=1e-03,
|
147
|
+
)
|
148
|
+
assert_allclose_with_logging(
|
149
|
+
true_u.trajectory[i].positions,
|
150
|
+
imd_u.trajectory[i - first_frame].positions,
|
151
|
+
atol=1e-03,
|
152
|
+
)
|
153
|
+
if vel:
|
154
|
+
assert_allclose_with_logging(
|
155
|
+
true_u.trajectory[i].velocities,
|
156
|
+
imd_u.trajectory[i - first_frame].velocities,
|
157
|
+
atol=1e-03,
|
158
|
+
)
|
159
|
+
if force:
|
160
|
+
assert_allclose_with_logging(
|
161
|
+
true_u.trajectory[i].forces,
|
162
|
+
imd_u.trajectory[i - first_frame].forces,
|
163
|
+
atol=1e-03,
|
164
|
+
)
|
165
|
+
|
166
|
+
|
167
|
+
def main():
|
168
|
+
parser = argparse.ArgumentParser(description="IMDv3 Integration Test Tool")
|
169
|
+
parser.add_argument(
|
170
|
+
"--topol_path", required=True, help="Path to topology file"
|
171
|
+
)
|
172
|
+
parser.add_argument(
|
173
|
+
"--traj_path", required=True, help="Path to trajectory file"
|
174
|
+
)
|
175
|
+
parser.add_argument(
|
176
|
+
"--vel_path",
|
177
|
+
required=False,
|
178
|
+
help="Path to velocities trajectory file (NAMD only)",
|
179
|
+
)
|
180
|
+
parser.add_argument(
|
181
|
+
"--force_path",
|
182
|
+
required=False,
|
183
|
+
help="Path to forces trajectory file (NAMD only)",
|
184
|
+
)
|
185
|
+
parser.add_argument(
|
186
|
+
"--first_frame",
|
187
|
+
type=int,
|
188
|
+
required=True,
|
189
|
+
help="First frame to compare (0 for GROMACS and NAMD, 1 for LAMMPS)",
|
190
|
+
)
|
191
|
+
parser.add_argument(
|
192
|
+
"--tmp_path", default=".", help="Temporary directory for IMD traj"
|
193
|
+
)
|
194
|
+
|
195
|
+
args = parser.parse_args()
|
196
|
+
|
197
|
+
print(
|
198
|
+
"Writing IMD trajectory to temporary directory...\n===================="
|
199
|
+
)
|
200
|
+
imd_u = load_imd_universe(args.topol_path, args.tmp_path)
|
201
|
+
|
202
|
+
print("Loading source of truth trajectory...\n====================")
|
203
|
+
true_u = load_true_universe(args.topol_path, args.traj_path)
|
204
|
+
|
205
|
+
try:
|
206
|
+
print("Comparing trajectories...\n====================")
|
207
|
+
vel_in_trr = args.vel_path is None
|
208
|
+
force_in_trr = args.force_path is None
|
209
|
+
dt_in_trr = not args.topol_path.endswith(".data")
|
210
|
+
|
211
|
+
test_compare_imd_to_true_traj(
|
212
|
+
imd_u,
|
213
|
+
true_u,
|
214
|
+
args.first_frame,
|
215
|
+
vel_in_trr,
|
216
|
+
force_in_trr,
|
217
|
+
dt_in_trr,
|
218
|
+
)
|
219
|
+
|
220
|
+
if args.vel_path is not None:
|
221
|
+
print(
|
222
|
+
"Loading source of truth velocity trajectory...\n===================="
|
223
|
+
)
|
224
|
+
true_vel = load_true_universe(args.topol_path, args.vel_path)
|
225
|
+
print("Comparing velocities...")
|
226
|
+
test_compare_imd_to_true_traj_vel(
|
227
|
+
imd_u, true_vel, args.first_frame
|
228
|
+
)
|
229
|
+
|
230
|
+
if args.force_path is not None:
|
231
|
+
print(
|
232
|
+
"Loading source of truth force trajectory...\n===================="
|
67
233
|
)
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
atol=1e-03,
|
85
|
-
)
|
86
|
-
if true_u.trajectory[i].has_forces:
|
87
|
-
assert_allclose_with_logging(
|
88
|
-
true_u.trajectory[i].forces,
|
89
|
-
imd_u.trajectory[i].forces,
|
90
|
-
atol=1e-03,
|
91
|
-
)
|
234
|
+
true_force = load_true_universe(args.topol_path, args.force_path)
|
235
|
+
print("Comparing forces...")
|
236
|
+
test_compare_imd_to_true_traj_forces(
|
237
|
+
imd_u, true_force, args.first_frame
|
238
|
+
)
|
239
|
+
|
240
|
+
print("All tests passed!")
|
241
|
+
|
242
|
+
except AssertionError as e:
|
243
|
+
logger.error("Comparison failed!")
|
244
|
+
print(f"Test failed: {e}")
|
245
|
+
raise e
|
246
|
+
|
247
|
+
|
248
|
+
if __name__ == "__main__":
|
249
|
+
main()
|
imdclient/tests/test_namd.py
CHANGED
@@ -1,11 +1,21 @@
|
|
1
1
|
import MDAnalysis as mda
|
2
2
|
import pytest
|
3
3
|
import logging
|
4
|
-
from .base import IMDv3IntegrationTest
|
5
|
-
from .datafiles import
|
4
|
+
from .base import IMDv3IntegrationTest, assert_allclose_with_logging
|
5
|
+
from .datafiles import (
|
6
|
+
NAMD_TOPOL,
|
7
|
+
NAMD_CONF_NST_1,
|
8
|
+
NAMD_CONF_NST_8,
|
9
|
+
NAMD_PARAMS,
|
10
|
+
NAMD_PSF,
|
11
|
+
)
|
12
|
+
from pathlib import Path
|
13
|
+
from numpy.testing import (
|
14
|
+
assert_allclose,
|
15
|
+
)
|
6
16
|
|
7
17
|
logger = logging.getLogger("imdclient.IMDClient")
|
8
|
-
file_handler = logging.FileHandler("
|
18
|
+
file_handler = logging.FileHandler("namd_test.log")
|
9
19
|
formatter = logging.Formatter(
|
10
20
|
"%(asctime)s - %(name)s - %(levelname)s - %(message)s"
|
11
21
|
)
|
@@ -16,23 +26,100 @@ logger.setLevel(logging.DEBUG)
|
|
16
26
|
|
17
27
|
class TestIMDv3NAMD(IMDv3IntegrationTest):
|
18
28
|
|
29
|
+
@pytest.fixture(params=[NAMD_CONF_NST_1, NAMD_CONF_NST_8])
|
30
|
+
def inp(self, request):
|
31
|
+
return request.param
|
32
|
+
|
33
|
+
@pytest.fixture()
|
34
|
+
def simulation_command(self, inp):
|
35
|
+
return f"namd3 {Path(inp).name}"
|
36
|
+
|
37
|
+
@pytest.fixture()
|
38
|
+
def input_files(self, inp):
|
39
|
+
return [NAMD_TOPOL, inp, NAMD_PARAMS, NAMD_PSF]
|
40
|
+
|
41
|
+
@pytest.fixture()
|
42
|
+
def topol(self):
|
43
|
+
return Path(NAMD_TOPOL).name
|
44
|
+
|
19
45
|
@pytest.fixture()
|
20
|
-
def
|
21
|
-
|
22
|
-
|
46
|
+
def true_u(self, topol, imd_u, tmp_path):
|
47
|
+
u = mda.Universe(
|
48
|
+
(tmp_path / topol),
|
49
|
+
(tmp_path / "alanin.dcd"),
|
23
50
|
)
|
51
|
+
yield u
|
24
52
|
|
25
53
|
@pytest.fixture()
|
26
|
-
def
|
27
|
-
|
54
|
+
def true_u_vel(self, topol, imd_u, tmp_path):
|
55
|
+
u = mda.Universe(
|
56
|
+
(tmp_path / topol),
|
57
|
+
(tmp_path / "alanin.vel.dcd"),
|
58
|
+
)
|
59
|
+
yield u
|
60
|
+
|
61
|
+
@pytest.fixture()
|
62
|
+
def true_u_force(self, topol, imd_u, tmp_path):
|
63
|
+
u = mda.Universe(
|
64
|
+
(tmp_path / topol),
|
65
|
+
(tmp_path / "alanin.force.dcd"),
|
66
|
+
)
|
67
|
+
yield u
|
68
|
+
|
69
|
+
# @pytest.fixture()
|
70
|
+
# def match_string(self):
|
71
|
+
# return "INTERACTIVE MD AWAITING CONNECTION"
|
28
72
|
|
29
73
|
@pytest.fixture()
|
30
74
|
def first_frame(self):
|
31
75
|
return 0
|
32
76
|
|
33
|
-
|
34
|
-
def
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
77
|
+
# Compare coords, box, time, dt, step
|
78
|
+
def test_compare_imd_to_true_traj(self, imd_u, true_u, first_frame):
|
79
|
+
for i in range(first_frame, len(true_u.trajectory)):
|
80
|
+
assert_allclose(
|
81
|
+
true_u.trajectory[i].time,
|
82
|
+
imd_u.trajectory[i - first_frame].time,
|
83
|
+
atol=1e-03,
|
84
|
+
)
|
85
|
+
assert_allclose(
|
86
|
+
true_u.trajectory[i].dt,
|
87
|
+
imd_u.trajectory[i - first_frame].dt,
|
88
|
+
atol=1e-03,
|
89
|
+
)
|
90
|
+
assert_allclose(
|
91
|
+
true_u.trajectory[i].data["step"],
|
92
|
+
imd_u.trajectory[i - first_frame].data["step"],
|
93
|
+
)
|
94
|
+
assert_allclose_with_logging(
|
95
|
+
true_u.trajectory[i].dimensions,
|
96
|
+
imd_u.trajectory[i - first_frame].dimensions,
|
97
|
+
atol=1e-03,
|
98
|
+
)
|
99
|
+
assert_allclose_with_logging(
|
100
|
+
true_u.trajectory[i].positions,
|
101
|
+
imd_u.trajectory[i - first_frame].positions,
|
102
|
+
atol=1e-03,
|
103
|
+
)
|
104
|
+
|
105
|
+
# Compare velocities
|
106
|
+
def test_compare_imd_to_true_traj_vel(
|
107
|
+
self, imd_u, true_u_vel, first_frame
|
108
|
+
):
|
109
|
+
for i in range(first_frame, len(true_u_vel.trajectory)):
|
110
|
+
assert_allclose_with_logging(
|
111
|
+
true_u_vel.trajectory[i].positions,
|
112
|
+
imd_u.trajectory[i - first_frame].velocities,
|
113
|
+
atol=1e-03,
|
114
|
+
)
|
115
|
+
|
116
|
+
# Compare forces
|
117
|
+
def test_compare_imd_to_true_traj_forces(
|
118
|
+
self, imd_u, true_u_force, first_frame
|
119
|
+
):
|
120
|
+
for i in range(first_frame, len(true_u_force.trajectory)):
|
121
|
+
assert_allclose_with_logging(
|
122
|
+
true_u_force.trajectory[i].positions,
|
123
|
+
imd_u.trajectory[i - first_frame].forces,
|
124
|
+
atol=1e-03,
|
125
|
+
)
|
imdclient/tests/utils.py
CHANGED
@@ -0,0 +1,5 @@
|
|
1
|
+
Copyright 2024 Lawson Woods
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
4
|
+
|
5
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|