imdclient 0.1.2__tar.gz → 0.1.4__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.
- imdclient-0.1.4/LICENSE +5 -0
- imdclient-0.1.4/PKG-INFO +132 -0
- {imdclient-0.1.2 → imdclient-0.1.4}/README.md +10 -5
- imdclient-0.1.2/imdclient/IMDREADER.py → imdclient-0.1.4/imdclient/IMD.py +5 -4
- {imdclient-0.1.2 → imdclient-0.1.4}/imdclient/IMDClient.py +118 -15
- {imdclient-0.1.2 → imdclient-0.1.4}/imdclient/IMDProtocol.py +1 -0
- {imdclient-0.1.2 → imdclient-0.1.4}/imdclient/data/gromacs/md/gromacs_v3_nst1.mdp +3 -3
- imdclient-0.1.4/imdclient/data/gromacs/md/gromacs_v3_nst8.mdp +58 -0
- imdclient-0.1.2/imdclient/data/lammps/md/lammps_v3.in → imdclient-0.1.4/imdclient/data/lammps/md/lammps_v3_nst_1.in +3 -3
- imdclient-0.1.4/imdclient/data/lammps/md/lammps_v3_nst_8.in +71 -0
- imdclient-0.1.2/imdclient/data/namd/md/namd_v3.namd → imdclient-0.1.4/imdclient/data/namd/md/namd_v3_nst_1.namd +17 -5
- imdclient-0.1.4/imdclient/data/namd/md/namd_v3_nst_8.namd +59 -0
- imdclient-0.1.4/imdclient/tests/base.py +256 -0
- imdclient-0.1.4/imdclient/tests/conftest.py +3 -0
- imdclient-0.1.4/imdclient/tests/datafiles.py +57 -0
- imdclient-0.1.4/imdclient/tests/docker_testing/docker.md +25 -0
- imdclient-0.1.4/imdclient/tests/hpc_testing/gromacs/README.md +112 -0
- imdclient-0.1.4/imdclient/tests/hpc_testing/gromacs/gmx_gpu_test.mdp +58 -0
- imdclient-0.1.4/imdclient/tests/hpc_testing/gromacs/gmx_gpu_test.top +11764 -0
- imdclient-0.1.4/imdclient/tests/hpc_testing/gromacs/struct.gro +21151 -0
- imdclient-0.1.4/imdclient/tests/hpc_testing/gromacs/validate_gmx.sh +90 -0
- imdclient-0.1.4/imdclient/tests/hpc_testing/lammps/README.md +62 -0
- imdclient-0.1.4/imdclient/tests/hpc_testing/lammps/lammps_v3_nst_1.in +71 -0
- imdclient-0.1.4/imdclient/tests/hpc_testing/lammps/topology_after_min.data +8022 -0
- imdclient-0.1.4/imdclient/tests/hpc_testing/lammps/validate_lmp.sh +66 -0
- imdclient-0.1.4/imdclient/tests/hpc_testing/namd/README.md +73 -0
- imdclient-0.1.4/imdclient/tests/hpc_testing/namd/alanin.params +402 -0
- imdclient-0.1.4/imdclient/tests/hpc_testing/namd/alanin.pdb +77 -0
- imdclient-0.1.4/imdclient/tests/hpc_testing/namd/alanin.psf +206 -0
- imdclient-0.1.4/imdclient/tests/hpc_testing/namd/namd_v3_nst_1.namd +59 -0
- imdclient-0.1.4/imdclient/tests/hpc_testing/namd/validate_namd.sh +71 -0
- {imdclient-0.1.2 → imdclient-0.1.4}/imdclient/tests/server.py +2 -11
- imdclient-0.1.4/imdclient/tests/test_gromacs.py +55 -0
- {imdclient-0.1.2 → imdclient-0.1.4}/imdclient/tests/test_imdclient.py +69 -0
- {imdclient-0.1.2 → imdclient-0.1.4}/imdclient/tests/test_imdreader.py +74 -1
- imdclient-0.1.4/imdclient/tests/test_lammps.py +83 -0
- imdclient-0.1.4/imdclient/tests/test_manual.py +249 -0
- imdclient-0.1.4/imdclient/tests/test_namd.py +125 -0
- {imdclient-0.1.2 → imdclient-0.1.4}/imdclient/tests/test_stream_analysis.py +1 -1
- {imdclient-0.1.2 → imdclient-0.1.4}/imdclient/tests/utils.py +0 -1
- imdclient-0.1.4/imdclient.egg-info/PKG-INFO +132 -0
- {imdclient-0.1.2 → imdclient-0.1.4}/imdclient.egg-info/SOURCES.txt +23 -8
- {imdclient-0.1.2 → imdclient-0.1.4}/imdclient.egg-info/requires.txt +1 -0
- {imdclient-0.1.2 → imdclient-0.1.4}/pyproject.toml +1 -0
- imdclient-0.1.2/LICENSE +0 -674
- imdclient-0.1.2/PKG-INFO +0 -795
- imdclient-0.1.2/imdclient/data/gromacs/md/gromacs_v3_nst1.tpr +0 -0
- imdclient-0.1.2/imdclient/data/gromacs/md/gromacs_v3_nst1.trr +0 -0
- imdclient-0.1.2/imdclient/data/lammps/md/lammps_trj.h5md +0 -0
- imdclient-0.1.2/imdclient/data/namd/md/alanin.dcd +0 -0
- imdclient-0.1.2/imdclient/tests/base.py +0 -122
- imdclient-0.1.2/imdclient/tests/conftest.py +0 -42
- imdclient-0.1.2/imdclient/tests/datafiles.py +0 -34
- imdclient-0.1.2/imdclient/tests/test_gromacs.py +0 -33
- imdclient-0.1.2/imdclient/tests/test_lammps.py +0 -38
- imdclient-0.1.2/imdclient/tests/test_manual.py +0 -91
- imdclient-0.1.2/imdclient/tests/test_namd.py +0 -38
- imdclient-0.1.2/imdclient.egg-info/PKG-INFO +0 -795
- {imdclient-0.1.2 → imdclient-0.1.4}/AUTHORS.md +0 -0
- {imdclient-0.1.2 → imdclient-0.1.4}/CHANGELOG.md +0 -0
- {imdclient-0.1.2 → imdclient-0.1.4}/CODE_OF_CONDUCT.md +0 -0
- {imdclient-0.1.2 → imdclient-0.1.4}/MANIFEST.in +0 -0
- {imdclient-0.1.2 → imdclient-0.1.4}/imdclient/__init__.py +0 -0
- {imdclient-0.1.2 → imdclient-0.1.4}/imdclient/backends.py +0 -0
- {imdclient-0.1.2 → imdclient-0.1.4}/imdclient/data/__init__.py +0 -0
- {imdclient-0.1.2 → imdclient-0.1.4}/imdclient/data/gromacs/md/gromacs_struct.gro +0 -0
- {imdclient-0.1.2 → imdclient-0.1.4}/imdclient/data/gromacs/md/gromacs_v3.top +0 -0
- {imdclient-0.1.2 → imdclient-0.1.4}/imdclient/data/lammps/md/lammps_topol.data +0 -0
- {imdclient-0.1.2 → imdclient-0.1.4}/imdclient/data/namd/md/alanin.params +0 -0
- {imdclient-0.1.2 → imdclient-0.1.4}/imdclient/data/namd/md/alanin.pdb +0 -0
- {imdclient-0.1.2 → imdclient-0.1.4}/imdclient/data/namd/md/alanin.psf +0 -0
- {imdclient-0.1.2 → imdclient-0.1.4}/imdclient/results.py +0 -0
- {imdclient-0.1.2 → imdclient-0.1.4}/imdclient/streamanalysis.py +0 -0
- {imdclient-0.1.2 → imdclient-0.1.4}/imdclient/streambase.py +0 -0
- {imdclient-0.1.2 → imdclient-0.1.4}/imdclient/tests/__init__.py +0 -0
- {imdclient-0.1.2 → imdclient-0.1.4}/imdclient/utils.py +0 -0
- {imdclient-0.1.2 → imdclient-0.1.4}/imdclient.egg-info/dependency_links.txt +0 -0
- {imdclient-0.1.2 → imdclient-0.1.4}/imdclient.egg-info/top_level.txt +0 -0
- {imdclient-0.1.2 → imdclient-0.1.4}/setup.cfg +0 -0
imdclient-0.1.4/LICENSE
ADDED
@@ -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.
|
imdclient-0.1.4/PKG-INFO
ADDED
@@ -0,0 +1,132 @@
|
|
1
|
+
Metadata-Version: 2.1
|
2
|
+
Name: imdclient
|
3
|
+
Version: 0.1.4
|
4
|
+
Summary: Receiver for IMD v2 and v3 data from simulation engines like Gromacs, LAMMPS, and NAMD
|
5
|
+
Author-email: Lawson <ljwoods2@asu.edu>
|
6
|
+
Maintainer-email: Lawson <ljwoods2@asu.edu>
|
7
|
+
License: Copyright 2024 Lawson Woods
|
8
|
+
|
9
|
+
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:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
12
|
+
Keywords: molecular simulations
|
13
|
+
Requires-Python: >=3.9
|
14
|
+
Description-Content-Type: text/markdown
|
15
|
+
License-File: LICENSE
|
16
|
+
License-File: AUTHORS.md
|
17
|
+
Requires-Dist: MDAnalysis>=2.7.0
|
18
|
+
Provides-Extra: test
|
19
|
+
Requires-Dist: pytest>=6.0; extra == "test"
|
20
|
+
Requires-Dist: pytest-xdist>=2.5; extra == "test"
|
21
|
+
Requires-Dist: pytest-cov>=3.0; extra == "test"
|
22
|
+
Requires-Dist: MDAnalysisTests>=2.7.0; extra == "test"
|
23
|
+
Requires-Dist: docker-py; extra == "test"
|
24
|
+
Provides-Extra: doc
|
25
|
+
Requires-Dist: sphinx; extra == "doc"
|
26
|
+
Requires-Dist: sphinx_rtd_theme; extra == "doc"
|
27
|
+
|
28
|
+
IMDClient
|
29
|
+
==============================
|
30
|
+
[//]: # (Badges)
|
31
|
+
|
32
|
+
| **Latest release** | [![Last release tag][badge_release]][url_latest_release] ![GitHub commits since latest release (by date) for a branch][badge_commits_since] [![Documentation Status][badge_docs]][url_docs]|
|
33
|
+
| :----------------- | :------- |
|
34
|
+
| **Status** | [![GH Actions Status][badge_actions]][url_actions] [![codecov][badge_codecov]][url_codecov] |
|
35
|
+
| **Community** | [![License: MIT][badge_license]][url_license] [![Powered by MDAnalysis][badge_mda]][url_mda]|
|
36
|
+
|
37
|
+
[badge_actions]: https://github.com/becksteinlab/imdclient/actions/workflows/gh-ci.yaml/badge.svg
|
38
|
+
[badge_codecov]: https://codecov.io/gh/becksteinlab/imdclient/branch/main/graph/badge.svg
|
39
|
+
[badge_commits_since]: https://img.shields.io/github/commits-since/becksteinlab/imdclient/latest
|
40
|
+
[badge_docs]: https://readthedocs.org/projects/imdclient/badge/?version=latest
|
41
|
+
[badge_license]: https://img.shields.io/badge/License-MIT-blue.svg
|
42
|
+
[badge_mda]: https://img.shields.io/badge/powered%20by-MDAnalysis-orange.svg?logoWidth=16&logo=data:image/x-icon;base64,AAABAAEAEBAAAAEAIAAoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJD+XwCY/fEAkf3uAJf97wGT/a+HfHaoiIWE7n9/f+6Hh4fvgICAjwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACT/yYAlP//AJ///wCg//8JjvOchXly1oaGhv+Ghob/j4+P/39/f3IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJH8aQCY/8wAkv2kfY+elJ6al/yVlZX7iIiI8H9/f7h/f38UAAAAAAAAAAAAAAAAAAAAAAAAAAB/f38egYF/noqAebF8gYaagnx3oFpUUtZpaWr/WFhY8zo6OmT///8BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgICAn46Ojv+Hh4b/jouJ/4iGhfcAAADnAAAA/wAAAP8AAADIAAAAAwCj/zIAnf2VAJD/PAAAAAAAAAAAAAAAAICAgNGHh4f/gICA/4SEhP+Xl5f/AwMD/wAAAP8AAAD/AAAA/wAAAB8Aov9/ALr//wCS/Z0AAAAAAAAAAAAAAACBgYGOjo6O/4mJif+Pj4//iYmJ/wAAAOAAAAD+AAAA/wAAAP8AAABhAP7+FgCi/38Axf4fAAAAAAAAAAAAAAAAiIiID4GBgYKCgoKogoB+fYSEgZhgYGDZXl5e/m9vb/9ISEjpEBAQxw8AAFQAAAAAAAAANQAAADcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjo6Mb5iYmP+cnJz/jY2N95CQkO4pKSn/AAAA7gAAAP0AAAD7AAAAhgAAAAEAAAAAAAAAAACL/gsAkv2uAJX/QQAAAAB9fX3egoKC/4CAgP+NjY3/c3Nz+wAAAP8AAAD/AAAA/wAAAPUAAAAcAAAAAAAAAAAAnP4NAJL9rgCR/0YAAAAAfX19w4ODg/98fHz/i4uL/4qKivwAAAD/AAAA/wAAAP8AAAD1AAAAGwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALGxsVyqqqr/mpqa/6mpqf9KSUn/AAAA5QAAAPkAAAD5AAAAhQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADkUFBSuZ2dn/3V1df8uLi7bAAAATgBGfyQAAAA2AAAAMwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB0AAADoAAAA/wAAAP8AAAD/AAAAWgC3/2AAnv3eAJ/+dgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9AAAA/wAAAP8AAAD/AAAA/wAKDzEAnP3WAKn//wCS/OgAf/8MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIQAAANwAAADtAAAA7QAAAMAAABUMAJn9gwCe/e0Aj/2LAP//AQAAAAAAAAAA
|
43
|
+
[badge_release]: https://img.shields.io/github/release-pre/becksteinlab/imdclient.svg
|
44
|
+
[url_actions]: https://github.com/becksteinlab/imdclient/actions?query=branch%3Amain+workflow%3Agh-ci
|
45
|
+
[url_codecov]: https://codecov.io/gh/becksteinlab/imdclient/branch/main
|
46
|
+
[url_docs]: https://imdclient.readthedocs.io/en/latest/?badge=latest
|
47
|
+
[url_latest_release]: https://github.com/becksteinlab/imdclient/releases
|
48
|
+
[url_license]: https://opensource.org/license/mit
|
49
|
+
[url_mda]: https://www.mdanalysis.org
|
50
|
+
|
51
|
+
Receiver for [IMDv3 protocol](https://imdclient.readthedocs.io/en/latest/protocol_v3.html) from simulation engines like Gromacs, LAMMPS, and NAMD.
|
52
|
+
|
53
|
+
IMDClient is bound by a [Code of Conduct](https://github.com/becksteinlab/imdreader/blob/main/CODE_OF_CONDUCT.md).
|
54
|
+
|
55
|
+
### Installation
|
56
|
+
|
57
|
+
IMDClient is available via PyPi and can be installed with pip:
|
58
|
+
```bash
|
59
|
+
pip install imdclient
|
60
|
+
```
|
61
|
+
|
62
|
+
To build IMDClient from source,
|
63
|
+
we highly recommend using virtual environments.
|
64
|
+
If possible, we strongly recommend that you use
|
65
|
+
[Anaconda](https://docs.conda.io/en/latest/) as your package manager.
|
66
|
+
Below we provide instructions both for `conda` and
|
67
|
+
for `pip`.
|
68
|
+
|
69
|
+
#### With conda
|
70
|
+
|
71
|
+
Ensure that you have [conda](https://docs.conda.io/projects/conda/en/latest/user-guide/install/index.html) installed.
|
72
|
+
|
73
|
+
Create a virtual environment and activate it:
|
74
|
+
|
75
|
+
```
|
76
|
+
conda create --name imdclient
|
77
|
+
conda activate imdclient
|
78
|
+
```
|
79
|
+
|
80
|
+
<!-- Install the development and documentation dependencies:
|
81
|
+
|
82
|
+
```
|
83
|
+
conda env update --name imdreader --file devtools/conda-envs/test_env.yaml
|
84
|
+
conda env update --name imdreader --file docs/requirements.yaml
|
85
|
+
``` -->
|
86
|
+
|
87
|
+
Build this package from source:
|
88
|
+
|
89
|
+
```
|
90
|
+
pip install -e .
|
91
|
+
```
|
92
|
+
|
93
|
+
If you want to update your dependencies (which can be risky!), run:
|
94
|
+
|
95
|
+
```
|
96
|
+
conda update --all
|
97
|
+
```
|
98
|
+
|
99
|
+
And when you are finished, you can exit the virtual environment with:
|
100
|
+
|
101
|
+
```
|
102
|
+
conda deactivate
|
103
|
+
```
|
104
|
+
|
105
|
+
#### With pip
|
106
|
+
|
107
|
+
To build the package from source, run:
|
108
|
+
|
109
|
+
```
|
110
|
+
pip install .
|
111
|
+
```
|
112
|
+
|
113
|
+
If you want to create a development environment, install
|
114
|
+
the dependencies required for tests and docs with:
|
115
|
+
|
116
|
+
```
|
117
|
+
pip install ".[test,doc]"
|
118
|
+
```
|
119
|
+
|
120
|
+
### Copyright
|
121
|
+
|
122
|
+
The IMDClient source code is hosted at https://github.com/becksteinlab/imdclient
|
123
|
+
and is available under the MIT license (see the file [LICENSE](https://github.com/becksteinlab/imdclient/blob/main/LICENSE)).
|
124
|
+
|
125
|
+
Copyright (c) 2024, Lawson
|
126
|
+
|
127
|
+
|
128
|
+
#### Acknowledgements
|
129
|
+
|
130
|
+
Project based on the
|
131
|
+
[MDAnalysis Cookiecutter](https://github.com/MDAnalysis/cookiecutter-mda) version 0.1.
|
132
|
+
<!-- Please cite [MDAnalysis](https://github.com/MDAnalysis/mdanalysis#citation) when using IMDReader in published work. -->
|
@@ -5,28 +5,33 @@ IMDClient
|
|
5
5
|
| **Latest release** | [![Last release tag][badge_release]][url_latest_release] ![GitHub commits since latest release (by date) for a branch][badge_commits_since] [![Documentation Status][badge_docs]][url_docs]|
|
6
6
|
| :----------------- | :------- |
|
7
7
|
| **Status** | [![GH Actions Status][badge_actions]][url_actions] [![codecov][badge_codecov]][url_codecov] |
|
8
|
-
| **Community** | [![License:
|
8
|
+
| **Community** | [![License: MIT][badge_license]][url_license] [![Powered by MDAnalysis][badge_mda]][url_mda]|
|
9
9
|
|
10
10
|
[badge_actions]: https://github.com/becksteinlab/imdclient/actions/workflows/gh-ci.yaml/badge.svg
|
11
11
|
[badge_codecov]: https://codecov.io/gh/becksteinlab/imdclient/branch/main/graph/badge.svg
|
12
12
|
[badge_commits_since]: https://img.shields.io/github/commits-since/becksteinlab/imdclient/latest
|
13
13
|
[badge_docs]: https://readthedocs.org/projects/imdclient/badge/?version=latest
|
14
|
-
[badge_license]: https://img.shields.io/badge/License-
|
14
|
+
[badge_license]: https://img.shields.io/badge/License-MIT-blue.svg
|
15
15
|
[badge_mda]: https://img.shields.io/badge/powered%20by-MDAnalysis-orange.svg?logoWidth=16&logo=data:image/x-icon;base64,AAABAAEAEBAAAAEAIAAoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJD+XwCY/fEAkf3uAJf97wGT/a+HfHaoiIWE7n9/f+6Hh4fvgICAjwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACT/yYAlP//AJ///wCg//8JjvOchXly1oaGhv+Ghob/j4+P/39/f3IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJH8aQCY/8wAkv2kfY+elJ6al/yVlZX7iIiI8H9/f7h/f38UAAAAAAAAAAAAAAAAAAAAAAAAAAB/f38egYF/noqAebF8gYaagnx3oFpUUtZpaWr/WFhY8zo6OmT///8BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgICAn46Ojv+Hh4b/jouJ/4iGhfcAAADnAAAA/wAAAP8AAADIAAAAAwCj/zIAnf2VAJD/PAAAAAAAAAAAAAAAAICAgNGHh4f/gICA/4SEhP+Xl5f/AwMD/wAAAP8AAAD/AAAA/wAAAB8Aov9/ALr//wCS/Z0AAAAAAAAAAAAAAACBgYGOjo6O/4mJif+Pj4//iYmJ/wAAAOAAAAD+AAAA/wAAAP8AAABhAP7+FgCi/38Axf4fAAAAAAAAAAAAAAAAiIiID4GBgYKCgoKogoB+fYSEgZhgYGDZXl5e/m9vb/9ISEjpEBAQxw8AAFQAAAAAAAAANQAAADcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjo6Mb5iYmP+cnJz/jY2N95CQkO4pKSn/AAAA7gAAAP0AAAD7AAAAhgAAAAEAAAAAAAAAAACL/gsAkv2uAJX/QQAAAAB9fX3egoKC/4CAgP+NjY3/c3Nz+wAAAP8AAAD/AAAA/wAAAPUAAAAcAAAAAAAAAAAAnP4NAJL9rgCR/0YAAAAAfX19w4ODg/98fHz/i4uL/4qKivwAAAD/AAAA/wAAAP8AAAD1AAAAGwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALGxsVyqqqr/mpqa/6mpqf9KSUn/AAAA5QAAAPkAAAD5AAAAhQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADkUFBSuZ2dn/3V1df8uLi7bAAAATgBGfyQAAAA2AAAAMwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB0AAADoAAAA/wAAAP8AAAD/AAAAWgC3/2AAnv3eAJ/+dgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9AAAA/wAAAP8AAAD/AAAA/wAKDzEAnP3WAKn//wCS/OgAf/8MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIQAAANwAAADtAAAA7QAAAMAAABUMAJn9gwCe/e0Aj/2LAP//AQAAAAAAAAAA
|
16
16
|
[badge_release]: https://img.shields.io/github/release-pre/becksteinlab/imdclient.svg
|
17
17
|
[url_actions]: https://github.com/becksteinlab/imdclient/actions?query=branch%3Amain+workflow%3Agh-ci
|
18
18
|
[url_codecov]: https://codecov.io/gh/becksteinlab/imdclient/branch/main
|
19
19
|
[url_docs]: https://imdclient.readthedocs.io/en/latest/?badge=latest
|
20
20
|
[url_latest_release]: https://github.com/becksteinlab/imdclient/releases
|
21
|
-
[url_license]: https://
|
21
|
+
[url_license]: https://opensource.org/license/mit
|
22
22
|
[url_mda]: https://www.mdanalysis.org
|
23
23
|
|
24
|
-
Receiver for IMDv3 protocol from simulation engines like Gromacs, LAMMPS, and NAMD.
|
24
|
+
Receiver for [IMDv3 protocol](https://imdclient.readthedocs.io/en/latest/protocol_v3.html) from simulation engines like Gromacs, LAMMPS, and NAMD.
|
25
25
|
|
26
26
|
IMDClient is bound by a [Code of Conduct](https://github.com/becksteinlab/imdreader/blob/main/CODE_OF_CONDUCT.md).
|
27
27
|
|
28
28
|
### Installation
|
29
29
|
|
30
|
+
IMDClient is available via PyPi and can be installed with pip:
|
31
|
+
```bash
|
32
|
+
pip install imdclient
|
33
|
+
```
|
34
|
+
|
30
35
|
To build IMDClient from source,
|
31
36
|
we highly recommend using virtual environments.
|
32
37
|
If possible, we strongly recommend that you use
|
@@ -88,7 +93,7 @@ pip install ".[test,doc]"
|
|
88
93
|
### Copyright
|
89
94
|
|
90
95
|
The IMDClient source code is hosted at https://github.com/becksteinlab/imdclient
|
91
|
-
and is available under the
|
96
|
+
and is available under the MIT license (see the file [LICENSE](https://github.com/becksteinlab/imdclient/blob/main/LICENSE)).
|
92
97
|
|
93
98
|
Copyright (c) 2024, Lawson
|
94
99
|
|
@@ -50,6 +50,7 @@ class IMDReader(StreamReaderBase):
|
|
50
50
|
):
|
51
51
|
super(IMDReader, self).__init__(filename, **kwargs)
|
52
52
|
|
53
|
+
self._imdclient = None
|
53
54
|
logger.debug("IMDReader initializing")
|
54
55
|
|
55
56
|
if n_atoms is None:
|
@@ -83,9 +84,8 @@ class IMDReader(StreamReaderBase):
|
|
83
84
|
|
84
85
|
try:
|
85
86
|
imdf = self._imdclient.get_imdframe()
|
86
|
-
except EOFError:
|
87
|
-
|
88
|
-
raise StopIteration
|
87
|
+
except EOFError as e:
|
88
|
+
raise e
|
89
89
|
|
90
90
|
self._frame = frame
|
91
91
|
self._load_imdframe_into_ts(imdf)
|
@@ -126,6 +126,7 @@ class IMDReader(StreamReaderBase):
|
|
126
126
|
def close(self):
|
127
127
|
"""Gracefully shut down the reader. Stops the producer thread."""
|
128
128
|
logger.debug("IMDReader close() called")
|
129
|
-
self._imdclient
|
129
|
+
if self._imdclient is not None:
|
130
|
+
self._imdclient.stop()
|
130
131
|
# NOTE: removeme after testing
|
131
132
|
logger.debug("IMDReader shut down gracefully.")
|
@@ -25,6 +25,7 @@ import time
|
|
25
25
|
import numpy as np
|
26
26
|
from typing import Union, Dict
|
27
27
|
import signal
|
28
|
+
import atexit
|
28
29
|
|
29
30
|
logger = logging.getLogger(__name__)
|
30
31
|
|
@@ -42,7 +43,13 @@ class IMDClient:
|
|
42
43
|
socket_bufsize : int, (optional)
|
43
44
|
Size of the socket buffer in bytes. Default is to use the system default
|
44
45
|
buffer_size : int (optional)
|
45
|
-
IMDFramebuffer will be filled with as many :class:`IMDFrame` fit in `buffer_size` [``10MB``]
|
46
|
+
IMDFramebuffer will be filled with as many :class:`IMDFrame` fit in `buffer_size` bytes [``10MB``]
|
47
|
+
timeout : int, optional
|
48
|
+
Timeout for the socket in seconds [``5``]
|
49
|
+
continue_after_disconnect : bool, optional [``None``]
|
50
|
+
If True, the client will attempt to change the simulation engine's waiting behavior to
|
51
|
+
non-blocking after the client disconnects. If False, the client will attempt to change it
|
52
|
+
to blocking. If None, the client will not attempt to change the simulation engine's behavior.
|
46
53
|
**kwargs : dict (optional)
|
47
54
|
Additional keyword arguments to pass to the :class:`BaseIMDProducer` and :class:`IMDFrameBuffer`
|
48
55
|
"""
|
@@ -54,6 +61,7 @@ class IMDClient:
|
|
54
61
|
n_atoms,
|
55
62
|
socket_bufsize=None,
|
56
63
|
multithreaded=True,
|
64
|
+
continue_after_disconnect=None,
|
57
65
|
**kwargs,
|
58
66
|
):
|
59
67
|
|
@@ -61,6 +69,7 @@ class IMDClient:
|
|
61
69
|
self._conn = self._connect_to_server(host, port, socket_bufsize)
|
62
70
|
self._imdsinfo = self._await_IMD_handshake()
|
63
71
|
self._multithreaded = multithreaded
|
72
|
+
self._continue_after_disconnect = continue_after_disconnect
|
64
73
|
|
65
74
|
if self._multithreaded:
|
66
75
|
self._buf = IMDFrameBuffer(
|
@@ -68,8 +77,10 @@ class IMDClient:
|
|
68
77
|
n_atoms,
|
69
78
|
**kwargs,
|
70
79
|
)
|
80
|
+
self._error_queue = queue.Queue()
|
71
81
|
else:
|
72
82
|
self._buf = None
|
83
|
+
self._error_queue = None
|
73
84
|
if self._imdsinfo.version == 2:
|
74
85
|
self._producer = IMDProducerV2(
|
75
86
|
self._conn,
|
@@ -77,6 +88,7 @@ class IMDClient:
|
|
77
88
|
self._imdsinfo,
|
78
89
|
n_atoms,
|
79
90
|
multithreaded,
|
91
|
+
self._error_queue,
|
80
92
|
**kwargs,
|
81
93
|
)
|
82
94
|
elif self._imdsinfo.version == 3:
|
@@ -86,23 +98,60 @@ class IMDClient:
|
|
86
98
|
self._imdsinfo,
|
87
99
|
n_atoms,
|
88
100
|
multithreaded,
|
101
|
+
self._error_queue,
|
89
102
|
**kwargs,
|
90
103
|
)
|
91
104
|
|
92
105
|
self._go()
|
93
106
|
|
94
107
|
if self._multithreaded:
|
108
|
+
# Disconnect MUST occur. This covers typical cases (Python, IPython interpreter)
|
95
109
|
signal.signal(signal.SIGINT, self.signal_handler)
|
110
|
+
signal.signal(signal.SIGTERM, self.signal_handler)
|
111
|
+
|
112
|
+
# Disconnect and socket shutdown MUST occur. This covers Jupyter use
|
113
|
+
# since in jupyter, the signal handler is reset to the default
|
114
|
+
# by pre- and post- hooks
|
115
|
+
# https://stackoverflow.com/questions/70841648/jupyter-reverts-signal-handler-to-default-when-running-next-cell
|
116
|
+
try:
|
117
|
+
import IPython
|
118
|
+
except ImportError:
|
119
|
+
has_ipython = False
|
120
|
+
else:
|
121
|
+
has_ipython = True
|
122
|
+
|
123
|
+
if has_ipython:
|
124
|
+
try:
|
125
|
+
from IPython import get_ipython
|
126
|
+
|
127
|
+
if get_ipython() is not None:
|
128
|
+
kernel = get_ipython().kernel
|
129
|
+
kernel.pre_handler_hook = lambda: None
|
130
|
+
kernel.post_handler_hook = lambda: None
|
131
|
+
logger.debug("Running in Jupyter")
|
132
|
+
except NameError:
|
133
|
+
logger.debug("Running in non-jupyter IPython environment")
|
134
|
+
|
135
|
+
# Final case: error is raised outside of IMDClient code
|
136
|
+
logger.debug("Registering atexit")
|
137
|
+
atexit.register(self.stop)
|
138
|
+
|
96
139
|
self._producer.start()
|
97
140
|
|
98
141
|
def signal_handler(self, sig, frame):
|
99
142
|
"""Catch SIGINT to allow clean shutdown on CTRL+C
|
100
143
|
This also ensures that main thread execution doesn't get stuck
|
101
144
|
waiting in buf.pop_full_imdframe()"""
|
145
|
+
logger.debug("Intercepted signal")
|
102
146
|
self.stop()
|
147
|
+
logger.debug("Shutdown success")
|
103
148
|
|
104
149
|
def get_imdframe(self):
|
105
150
|
"""
|
151
|
+
Returns
|
152
|
+
-------
|
153
|
+
IMDFrame
|
154
|
+
The next frame from the IMD server
|
106
155
|
Raises
|
107
156
|
------
|
108
157
|
EOFError
|
@@ -116,6 +165,9 @@ class IMDClient:
|
|
116
165
|
# and doesn't need to be notified
|
117
166
|
self._disconnect()
|
118
167
|
self._stopped = True
|
168
|
+
|
169
|
+
if self._error_queue.qsize():
|
170
|
+
raise EOFError(f"{self._error_queue.get()}")
|
119
171
|
raise EOFError
|
120
172
|
else:
|
121
173
|
try:
|
@@ -125,14 +177,23 @@ class IMDClient:
|
|
125
177
|
raise EOFError
|
126
178
|
|
127
179
|
def get_imdsessioninfo(self):
|
180
|
+
"""
|
181
|
+
Returns
|
182
|
+
-------
|
183
|
+
IMDSessionInfo
|
184
|
+
Information about the IMD session
|
185
|
+
"""
|
128
186
|
return self._imdsinfo
|
129
187
|
|
130
188
|
def stop(self):
|
189
|
+
"""
|
190
|
+
Stop the client and close the connection
|
191
|
+
"""
|
131
192
|
if self._multithreaded:
|
132
193
|
if not self._stopped:
|
133
|
-
self._buf.notify_consumer_finished()
|
134
|
-
self._disconnect()
|
135
194
|
self._stopped = True
|
195
|
+
self._disconnect()
|
196
|
+
self._buf.notify_consumer_finished()
|
136
197
|
else:
|
137
198
|
self._disconnect()
|
138
199
|
|
@@ -239,6 +300,17 @@ class IMDClient:
|
|
239
300
|
self._conn.sendall(go)
|
240
301
|
logger.debug("IMDClient: Sent go packet to server")
|
241
302
|
|
303
|
+
if self._continue_after_disconnect is not None:
|
304
|
+
wait_behavior = (int)(not self._continue_after_disconnect)
|
305
|
+
wait_packet = create_header_bytes(
|
306
|
+
IMDHeaderType.IMD_WAIT, wait_behavior
|
307
|
+
)
|
308
|
+
self._conn.sendall(wait_packet)
|
309
|
+
logger.debug(
|
310
|
+
"IMDClient: Attempted to change wait behavior to %s",
|
311
|
+
not self._continue_after_disconnect
|
312
|
+
)
|
313
|
+
|
242
314
|
def _disconnect(self):
|
243
315
|
# MUST disconnect before stopping execution
|
244
316
|
# if simulation already ended, this method will do nothing
|
@@ -254,6 +326,13 @@ class IMDClient:
|
|
254
326
|
finally:
|
255
327
|
self._conn.close()
|
256
328
|
|
329
|
+
def __enter__(self):
|
330
|
+
return self
|
331
|
+
|
332
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
333
|
+
self.stop()
|
334
|
+
return False
|
335
|
+
|
257
336
|
|
258
337
|
class BaseIMDProducer(threading.Thread):
|
259
338
|
"""
|
@@ -269,11 +348,14 @@ class BaseIMDProducer(threading.Thread):
|
|
269
348
|
Information about the IMD session
|
270
349
|
n_atoms : int
|
271
350
|
Number of atoms in the simulation
|
272
|
-
multithreaded : bool
|
351
|
+
multithreaded : bool
|
273
352
|
If True, socket interaction will occur in a separate thread &
|
274
353
|
frames will be buffered. Single-threaded, blocking IMDClient
|
275
|
-
should only be used in testing
|
276
|
-
|
354
|
+
should only be used in testing
|
355
|
+
error_queue: queue.Queue
|
356
|
+
Queue to hold errors produced by the producer thread
|
357
|
+
timeout : int, optional
|
358
|
+
Timeout for the socket in seconds [``5``]
|
277
359
|
"""
|
278
360
|
|
279
361
|
def __init__(
|
@@ -282,7 +364,8 @@ class BaseIMDProducer(threading.Thread):
|
|
282
364
|
buffer,
|
283
365
|
sinfo,
|
284
366
|
n_atoms,
|
285
|
-
multithreaded
|
367
|
+
multithreaded,
|
368
|
+
error_queue,
|
286
369
|
timeout=5,
|
287
370
|
**kwargs,
|
288
371
|
):
|
@@ -291,6 +374,7 @@ class BaseIMDProducer(threading.Thread):
|
|
291
374
|
self._imdsinfo = sinfo
|
292
375
|
self._paused = False
|
293
376
|
|
377
|
+
self.error_queue = error_queue
|
294
378
|
# Timeout for first frame should be longer
|
295
379
|
# than rest of frames
|
296
380
|
self._timeout = timeout
|
@@ -385,6 +469,7 @@ class BaseIMDProducer(threading.Thread):
|
|
385
469
|
logger.debug("IMDProducer: Simulation ended normally, cleaning up")
|
386
470
|
except Exception as e:
|
387
471
|
logger.debug("IMDProducer: An unexpected error occurred: %s", e)
|
472
|
+
self.error_queue.put(e)
|
388
473
|
finally:
|
389
474
|
logger.debug("IMDProducer: Stopping run loop")
|
390
475
|
# Tell consumer not to expect more frames to be added
|
@@ -400,9 +485,19 @@ class BaseIMDProducer(threading.Thread):
|
|
400
485
|
)
|
401
486
|
# Sometimes we do not care what the value is
|
402
487
|
if expected_value is not None and header.length != expected_value:
|
403
|
-
|
404
|
-
|
405
|
-
|
488
|
+
if expected_type in [
|
489
|
+
IMDHeaderType.IMD_FCOORDS,
|
490
|
+
IMDHeaderType.IMD_VELOCITIES,
|
491
|
+
IMDHeaderType.IMD_FORCES,
|
492
|
+
]:
|
493
|
+
raise RuntimeError(
|
494
|
+
f"IMDProducer: Expected n_atoms value {expected_value}, got {header.length}. "
|
495
|
+
+ "Ensure you are using the correct topology file."
|
496
|
+
)
|
497
|
+
else:
|
498
|
+
raise RuntimeError(
|
499
|
+
f"IMDProducer: Expected header value {expected_value}, got {header.length}"
|
500
|
+
)
|
406
501
|
|
407
502
|
def _get_header(self):
|
408
503
|
self._read(self._header)
|
@@ -422,9 +517,18 @@ class BaseIMDProducer(threading.Thread):
|
|
422
517
|
|
423
518
|
|
424
519
|
class IMDProducerV2(BaseIMDProducer):
|
425
|
-
def __init__(
|
520
|
+
def __init__(
|
521
|
+
self,
|
522
|
+
conn,
|
523
|
+
buffer,
|
524
|
+
sinfo,
|
525
|
+
n_atoms,
|
526
|
+
multithreaded,
|
527
|
+
error_queue,
|
528
|
+
**kwargs,
|
529
|
+
):
|
426
530
|
super(IMDProducerV2, self).__init__(
|
427
|
-
conn, buffer, sinfo, n_atoms, multithreaded, **kwargs
|
531
|
+
conn, buffer, sinfo, n_atoms, multithreaded, error_queue, **kwargs
|
428
532
|
)
|
429
533
|
|
430
534
|
self._energies = bytearray(IMDENERGYPACKETLENGTH)
|
@@ -517,6 +621,7 @@ class IMDProducerV3(BaseIMDProducer):
|
|
517
621
|
sinfo,
|
518
622
|
n_atoms,
|
519
623
|
multithreaded,
|
624
|
+
error_queue,
|
520
625
|
**kwargs,
|
521
626
|
):
|
522
627
|
super(IMDProducerV3, self).__init__(
|
@@ -525,6 +630,7 @@ class IMDProducerV3(BaseIMDProducer):
|
|
525
630
|
sinfo,
|
526
631
|
n_atoms,
|
527
632
|
multithreaded,
|
633
|
+
error_queue,
|
528
634
|
**kwargs,
|
529
635
|
)
|
530
636
|
# The body of an x/v/f packet should contain
|
@@ -633,9 +739,6 @@ class IMDProducerV3(BaseIMDProducer):
|
|
633
739
|
).reshape((self._n_atoms, 3)),
|
634
740
|
)
|
635
741
|
|
636
|
-
def __del__(self):
|
637
|
-
logger.debug("IMDProducer: I am being deleted")
|
638
|
-
|
639
742
|
|
640
743
|
class IMDFrameBuffer:
|
641
744
|
"""
|
@@ -1,5 +1,5 @@
|
|
1
1
|
title = PRODUCTION IN NPT
|
2
|
-
ld-seed
|
2
|
+
ld-seed = 1
|
3
3
|
; Run parameters
|
4
4
|
integrator = md ; leap-frog integrator
|
5
5
|
nsteps = 100 ; 1 * 1000 = 1 ps
|
@@ -7,9 +7,9 @@ dt = 0.001 ; 1 fs
|
|
7
7
|
; Output control
|
8
8
|
nstxout = 1 ; save coordinates every 1 fs
|
9
9
|
nstvout = 1 ; save velocities every 1 fs
|
10
|
-
nstfout = 1
|
10
|
+
nstfout = 1 ; save forces every 1 fs
|
11
11
|
nstenergy = 1 ; save energies every 1 fs
|
12
|
-
nstlog = 10
|
12
|
+
nstlog = 10
|
13
13
|
; Center of mass (COM) motion
|
14
14
|
nstcomm = 10 ; remove COM motion every 10 steps
|
15
15
|
comm-mode = Linear ; remove only COM translation (liquids in PBC)
|
@@ -0,0 +1,58 @@
|
|
1
|
+
title = PRODUCTION IN NPT
|
2
|
+
ld-seed = 1
|
3
|
+
; Run parameters
|
4
|
+
integrator = md ; leap-frog integrator
|
5
|
+
nsteps = 100 ; 1 * 1000 = 1 ps
|
6
|
+
dt = 0.001 ; 1 fs
|
7
|
+
; Output control
|
8
|
+
nstxout = 8 ; save coordinates every 1 fs
|
9
|
+
nstvout = 8 ; save velocities every 1 fs
|
10
|
+
nstfout = 8
|
11
|
+
nstenergy = 8 ; save energies every 1 fs
|
12
|
+
nstlog = 10 ; update log file every 1 ps
|
13
|
+
; Center of mass (COM) motion
|
14
|
+
nstcomm = 10 ; remove COM motion every 10 steps
|
15
|
+
comm-mode = Linear ; remove only COM translation (liquids in PBC)
|
16
|
+
; Bond parameters
|
17
|
+
continuation = yes ; first dynamics run
|
18
|
+
constraint_algorithm = lincs ; holonomic constraints
|
19
|
+
constraints = all-bonds ; all bonds lengths are constrained
|
20
|
+
lincs_iter = 1 ; accuracy of LINCS
|
21
|
+
lincs_order = 4 ; also related to accuracy
|
22
|
+
; Nonbonded settings
|
23
|
+
cutoff-scheme = Verlet ; Buffered neighbor searching
|
24
|
+
ns_type = grid ; search neighboring grid cells
|
25
|
+
nstlist = 10 ; 10 fs, largely irrelevant with Verlet
|
26
|
+
rcoulomb = 1.0 ; short-range electrostatic cutoff (in nm)
|
27
|
+
rvdw = 1.0 ; short-range van der Waals cutoff (in nm)
|
28
|
+
DispCorr = EnerPres ; account for cut-off vdW scheme
|
29
|
+
; Electrostatics
|
30
|
+
coulombtype = PME ; Particle Mesh Ewald for long-range electrostatics
|
31
|
+
pme_order = 4 ; cubic interpolation
|
32
|
+
fourierspacing = 0.12 ; grid spacing for FFT
|
33
|
+
; Temperature coupling is on
|
34
|
+
tcoupl = Nose-Hoover ; good for production, after equilibration
|
35
|
+
; we define separate thermostats for the solute and solvent (need to adapt)
|
36
|
+
; see default groups defined by Gromacs for your system or define your own (make_ndx)
|
37
|
+
tc-grps = Protein SOL ; the separate groups for the thermostats
|
38
|
+
tau-t = 1.0 1.0 ; time constants for thermostats (ps)
|
39
|
+
ref-t = 300 300 ; reference temperature for thermostats (K)
|
40
|
+
; Pressure coupling is off
|
41
|
+
pcoupl = Parrinello-Rahman ; good for production, after equilibration
|
42
|
+
tau-p = 2.0 ; time constant for barostat (ps)
|
43
|
+
compressibility = 4.5e-5 ; compressibility (1/bar) set to water at ~300K
|
44
|
+
ref-p = 1.0 ; reference pressure for barostat (bar)
|
45
|
+
; Periodic boundary conditions
|
46
|
+
pbc = xyz ; 3-D PBC
|
47
|
+
; Velocity generation
|
48
|
+
gen_vel = no
|
49
|
+
IMD-group = System
|
50
|
+
IMD-nst = 8
|
51
|
+
IMD-version = 3
|
52
|
+
IMD-time = yes
|
53
|
+
IMD-box = yes
|
54
|
+
IMD-coords = yes
|
55
|
+
IMD-unwrap = no
|
56
|
+
IMD-vels = yes
|
57
|
+
IMD-forces = yes
|
58
|
+
IMD-energies = no
|
@@ -52,8 +52,8 @@ velocity all create 300 102939 dist gaussian mom yes rot yes
|
|
52
52
|
fix 1 all nve
|
53
53
|
|
54
54
|
# Create source of truth trajectory
|
55
|
-
|
56
|
-
|
55
|
+
dump h5md1 all h5md 1 lammps_trj.h5md position velocity force box yes
|
56
|
+
dump_modify h5md1 unwrap no
|
57
57
|
|
58
58
|
## IMD settings
|
59
59
|
# https://docs.lammps.org/fix_imd.html
|
@@ -63,7 +63,7 @@ fix 2 all imd 8888 version 3 unwrap off nowait off
|
|
63
63
|
run 100
|
64
64
|
|
65
65
|
# Stop dumping information to the dump file.
|
66
|
-
|
66
|
+
undump h5md1
|
67
67
|
|
68
68
|
# Unfix the NVE. Additional lines if any will assume that this fix is off.
|
69
69
|
unfix 1
|