├── .codecov.yml
├── .gitattributes
├── .github
├── CONTRIBUTING.md
├── PULL_REQUEST_TEMPLATE.md
└── workflows
│ └── CI.yaml
├── .gitignore
├── .lgtm.yml
├── .readthedocs.yaml
├── LICENSE
├── MANIFEST.in
├── README.md
├── devtools
├── README.md
├── conda-envs
│ └── test_env.yaml
├── legacy-miniconda-setup
│ └── before_install.sh
└── scripts
│ └── create_conda_env.py
├── docs
├── Makefile
├── README.md
├── _static
│ ├── README.md
│ ├── entropy_barrier.mp4
│ └── muller_potential.mp4
├── _templates
│ └── README.md
├── api.rst
├── api_examples.rst
├── citations.rst
├── conf.py
├── faq.rst
├── index.rst
├── installation.rst
├── make.bat
├── media
│ ├── tutorial_hostguest_analysis_results.png
│ ├── tutorial_hostguest_directory.png
│ ├── tutorial_hostguest_guest.png
│ ├── tutorial_hostguest_host.png
│ ├── tutorial_hostguest_koff_conv.png
│ ├── tutorial_hostguest_model_input.png
│ ├── tutorial_hostguest_pmf.png
│ ├── tutorial_toy_entropy_barrier.png
│ ├── tutorial_toy_model_input.png
│ └── tutorial_toy_muller_potential.png
├── model_input_files.rst
├── program_options.rst
├── program_options_analyze.rst
├── program_options_converge.rst
├── program_options_prepare.rst
├── program_options_run.rst
├── requirements.txt
├── requirements.yaml
├── running_calculations.rst
├── tutorial.rst
├── tutorial1_hostguest.rst
└── tutorial2_toy_systems.rst
├── pyproject.toml
└── seekr2
├── __init__.py
├── analyze.py
├── continuous_integration
└── run_ci.py
├── converge.py
├── data
├── README.md
├── hostguest_files
│ ├── hostguest.parm7
│ ├── hostguest.rst7
│ ├── hostguest.xml
│ ├── hostguest_at0.5.pdb
│ ├── hostguest_at1.5.pdb
│ ├── hostguest_at10.5.pdb
│ ├── hostguest_at11.5.pdb
│ ├── hostguest_at12.5.pdb
│ ├── hostguest_at2.5.pdb
│ ├── hostguest_at3.5.pdb
│ ├── hostguest_at4.5.pdb
│ ├── hostguest_at5.5.pdb
│ ├── hostguest_at6.5.pdb
│ ├── hostguest_at7.5.pdb
│ ├── hostguest_at8.5.pdb
│ ├── hostguest_at9.5.pdb
│ ├── hostguest_for_NAMD.parm7
│ ├── hostguest_for_xml.pdb
│ ├── hostguest_ligand.pqr
│ ├── hostguest_ligand_same_resid.pqr
│ ├── hostguest_output.pdb
│ ├── hostguest_receptor.pqr
│ ├── hostguest_system.xml
│ └── input_tiwary.xml
├── sample_input_elber_openmm.xml
├── sample_input_mmvt_namd.xml
└── sample_input_mmvt_openmm.xml
├── modules
├── __init__.py
├── check.py
├── common_analyze.py
├── common_base.py
├── common_converge.py
├── common_cv.py
├── common_prepare.py
├── common_sim_browndye2.py
├── common_sim_namd.py
├── common_sim_openmm.py
├── due.py
├── elber_analyze.py
├── elber_cvs
│ ├── __init__.py
│ ├── elber_cv_base.py
│ ├── elber_external_cv.py
│ └── elber_spherical_cv.py
├── elber_sim_openmm.py
├── filetree.py
├── markov_chain_monte_carlo.py
├── mmvt_analyze.py
├── mmvt_base.py
├── mmvt_cvs
│ ├── __init__.py
│ ├── mmvt_closest_pair_cv.py
│ ├── mmvt_count_contacts_cv.py
│ ├── mmvt_cv_base.py
│ ├── mmvt_external_cv.py
│ ├── mmvt_planar_cv.py
│ ├── mmvt_rmsd_cv.py
│ ├── mmvt_spherical_cv.py
│ ├── mmvt_tiwary_cv.py
│ ├── mmvt_voronoi_cv.py
│ └── mmvt_z_distance_cv.py
├── mmvt_sim_namd.py
├── mmvt_sim_openmm.py
├── runner_browndye2.py
├── runner_namd.py
└── runner_openmm.py
├── prepare.py
├── run.py
└── tests
├── __init__.py
├── conftest.py
├── create_model_input.py
├── create_toy_system.py
├── data
├── ala_ala_ala.pdb
├── ala_ala_ala.psf
├── charmm22.par
├── charmm22.rtf
├── hostguest_at0.5_swarm.pdb
├── hostguest_state_a1.xml
├── ligand_for_test.pqr
├── sample_bd_milestone_results.xml
├── sample_bd_results_file.xml
├── sample_bd_results_file2.xml
├── test_analyze_output_elber.txt
├── test_analyze_outputfile.txt
├── test_analyze_outputfile_checkpoint1.txt
├── test_analyze_outputfile_checkpoint2.txt
├── test_analyze_outputfile_namd.txt
├── test_analyze_outputfile_namd_checkpoint1.txt
├── test_analyze_outputfile_namd_checkpoint2.txt
├── test_analyze_outputfile_namd_restart1.txt
├── test_analyze_outputfile_namd_restart2.txt
├── test_analyze_outputfile_restart1.txt
├── test_analyze_outputfile_restart2.txt
├── test_analyze_statistics.txt
├── test_namd.xsc
├── traj_test.index.xml
└── traj_test.xml
├── pytest.ini
├── test_analyze.py
├── test_check.py
├── test_common_analyze.py
├── test_common_base.py
├── test_common_converge.py
├── test_common_cv.py
├── test_common_prepare.py
├── test_common_sim_browndye2.py
├── test_common_sim_openmm.py
├── test_converge.py
├── test_elber_analyze.py
├── test_elber_cv_base.py
├── test_elber_external_cv.py
├── test_elber_sim_openmm.py
├── test_elber_spherical_cv.py
├── test_markov_chain_monte_carlo.py
├── test_mmvt_analyze.py
├── test_mmvt_closest_pair_cv.py
├── test_mmvt_count_contacts_cv.py
├── test_mmvt_cv.py
├── test_mmvt_cv_base.py
├── test_mmvt_external_cv.py
├── test_mmvt_planar_cv.py
├── test_mmvt_rmsd_cv.py
├── test_mmvt_sim_namd.py
├── test_mmvt_sim_openmm.py
├── test_mmvt_spherical_cv.py
├── test_mmvt_tiwary_cv.py
├── test_mmvt_voronoi_cv.py
├── test_prepare.py
├── test_run.py
├── test_runner_browndye2.py
├── test_runner_namd.py
└── test_runner_openmm.py
/.codecov.yml:
--------------------------------------------------------------------------------
1 | # Codecov configuration to make it a bit less noisy
2 | coverage:
3 | status:
4 | patch: false
5 | project:
6 | default:
7 | threshold: 50%
8 | comment:
9 | layout: "header"
10 | require_changes: false
11 | branches: null
12 | behavior: default
13 | flags: null
14 | paths: null
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | seekr2/_version.py export-subst
2 |
--------------------------------------------------------------------------------
/.github/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # How to contribute
2 |
3 | We welcome contributions from external contributors, and this document
4 | describes how to merge code changes into this seekr2.
5 |
6 | ## Getting Started
7 |
8 | * Make sure you have a [GitHub account](https://github.com/signup/free).
9 | * [Fork](https://help.github.com/articles/fork-a-repo/) this repository on GitHub.
10 | * On your local machine,
11 | [clone](https://help.github.com/articles/cloning-a-repository/) your fork of
12 | the repository.
13 |
14 | ## Making Changes
15 |
16 | * Add some really awesome code to your local fork. It's usually a [good
17 | idea](http://blog.jasonmeridth.com/posts/do-not-issue-pull-requests-from-your-master-branch/)
18 | to make changes on a
19 | [branch](https://help.github.com/articles/creating-and-deleting-branches-within-your-repository/)
20 | with the branch name relating to the feature you are going to add.
21 | * When you are ready for others to examine and comment on your new feature,
22 | navigate to your fork of seekr2 on GitHub and open a [pull
23 | request](https://help.github.com/articles/using-pull-requests/) (PR). Note that
24 | after you launch a PR from one of your fork's branches, all
25 | subsequent commits to that branch will be added to the open pull request
26 | automatically. Each commit added to the PR will be validated for
27 | mergability, compilation and test suite compliance; the results of these tests
28 | will be visible on the PR page.
29 | * If you're providing a new feature, you must add test cases and documentation.
30 | * When the code is ready to go, make sure you run the test suite using pytest.
31 | * When you're ready to be considered for merging, check the "Ready to go"
32 | box on the PR page to let the seekr2 devs know that the changes are complete.
33 | The code will not be merged until this box is checked, the continuous
34 | integration returns checkmarks,
35 | and multiple core developers give "Approved" reviews.
36 |
37 | # Additional Resources
38 |
39 | * [General GitHub documentation](https://help.github.com/)
40 | * [PR best practices](http://codeinthehole.com/writing/pull-requests-and-other-good-practices-for-teams-using-github/)
41 | * [A guide to contributing to software packages](http://www.contribution-guide.org)
42 | * [Thinkful PR example](http://www.thinkful.com/learn/github-pull-request-tutorial/#Time-to-Submit-Your-First-PR)
43 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | ## Description
2 | Provide a brief description of the PR's purpose here.
3 |
4 | ## Todos
5 | Notable points that this PR has either accomplished or will accomplish.
6 | - [ ] TODO 1
7 |
8 | ## Questions
9 | - [ ] Question1
10 |
11 | ## Status
12 | - [ ] Ready to go
--------------------------------------------------------------------------------
/.github/workflows/CI.yaml:
--------------------------------------------------------------------------------
1 | name: CI
2 |
3 | on:
4 | # GitHub has started calling new repo's first branch "main" https://github.com/github/renaming
5 | # Existing codes likely still have "master" as the primary branch
6 | # Both are tracked here to keep legacy and new codes working
7 | push:
8 | branches:
9 | - "master"
10 | - "main"
11 | pull_request:
12 | branches:
13 | - "master"
14 | - "main"
15 | # schedule:
16 | # # Nightly tests run on master by default:
17 | # # Scheduled workflows run on the latest commit on the default or base branch.
18 | # # (from https://help.github.com/en/actions/reference/events-that-trigger-workflows#scheduled-events-schedule)
19 | # - cron: "0 0 * * *"
20 |
21 | jobs:
22 | test:
23 | name: Test on ${{ matrix.os }}, Python ${{ matrix.python-version }}
24 | runs-on: ${{ matrix.os }}
25 | strategy:
26 | matrix:
27 | os: [ubuntu-latest] # [macOS-latest, ubuntu-latest, windows-latest]
28 | python-version: [3.8] #, 3.8, 3.9]
29 |
30 | steps:
31 | - uses: actions/checkout@v1
32 |
33 | - name: Additional info about the build
34 | shell: bash
35 | run: |
36 | uname -a
37 | df -h
38 | ulimit -a
39 |
40 |
41 | # More info on options: https://github.com/conda-incubator/setup-miniconda
42 | - uses: conda-incubator/setup-miniconda@v2
43 | with:
44 | python-version: ${{ matrix.python-version }}
45 | environment-file: devtools/conda-envs/test_env.yaml
46 |
47 | channels: conda-forge,defaults
48 |
49 | activate-environment: test
50 | auto-update-conda: false
51 | auto-activate-base: false
52 | show-channel-urls: true
53 |
54 |
55 | #- name: Build OpenMM
56 | # shell: bash -l {0}
57 | # run: |
58 | # git clone https://github.com/openmm/openmm.git
59 | # mkdir -p /home/runner/work/build/bin
60 | # cd openmm
61 | # mkdir build
62 | # cd build
63 | # cmake -DCMAKE_INSTALL_PREFIX=/home/runner/work/build/bin/openmm ..
64 | # make
65 | # make install
66 | # make PythonInstall
67 | # cd ../..
68 |
69 | - name: Get NAMD
70 | shell: bash -l {0}
71 | env:
72 | NAMD_ACCESS_TOKEN3: ${{ secrets.NAMD_ACCESS_TOKEN3 }}
73 | run: |
74 |
75 | git clone https://github.com/UIUC-PPL/charm
76 | cd charm
77 | ./build charm++ multicore-linux-x86_64 --with-production
78 | export CHRMDIR=${PWD}
79 | cd ..
80 | wget http://www.ks.uiuc.edu/Research/namd/libraries/tcl8.5.9-linux-x86_64.tar.gz
81 | tar xzf tcl8.5.9-linux-x86_64.tar.gz
82 | mkdir tcl
83 | mv tcl8.5.9-linux-x86_64 tcl
84 | export TCLINC=${PWD}/tcl/tcl8.5.9-linux-x86_64/lib/
85 | export TCLLIB=${PWD}/tcl/tcl8.5.9-linux-x86_64/include/
86 | export LD_LIBRARY_PATH=${PWD}/tcl/tcl8.5.9-linux-x86_64/include/:$LD_LIBRARY_PATH
87 | export TCLDIR=${PWD}/tcl/tcl8.5.9-linux-x86_64
88 |
89 | # This was commented before
90 | #wget http://www.ks.uiuc.edu/Research/namd/libraries/fftw-linux-x86_64.tar.gz
91 | #tar xzf fftw-linux-x86_64.tar.gz
92 | #mkdir fftw
93 | #mv linux-x86_64 fftw
94 | #export FFTWDIR=${PWD}/fftw/linux-x86_64
95 |
96 | # DON'T FORGET TO MODIFY NAMD_ACCESS_TOKEN3 REFERENCE ABOVE
97 |
98 | git clone https://oauth2:${NAMD_ACCESS_TOKEN3}@gitlab.com/tcbgUIUC/namd.git
99 | cd namd
100 | git checkout master
101 | ./config Linux-x86_64-g++ --charm-base $CHRMDIR --tcl-prefix $TCLDIR --without-fftw #--fftw-prefix ${FFTWDIR}
102 | cd Linux-x86_64-g++
103 | make
104 | pwd
105 | ls
106 | export PATH="$PWD:$PATH"
107 | echo "PATH: $PATH"
108 | cd ../..
109 |
110 |
111 | - name: Install package
112 |
113 | # conda setup requires this special shell
114 | shell: bash -l {0}
115 | run: |
116 | python -m pip install . --no-deps
117 | conda list
118 |
119 | # Install seekr systems repository
120 | git clone https://github.com/seekrcentral/seekr2_systems.git
121 |
122 | # Install seekr openmm plugin
123 | git clone https://github.com/seekrcentral/seekr2_openmm_plugin.git
124 | cd seekr2_openmm_plugin/seekr2plugin
125 | mkdir build
126 | cd build
127 | export OPENMM_INSTALL_DIR=${CONDA_PREFIX}
128 | export OPENMM_LIB_PATH=$OPENMM_INSTALL_DIR/lib
129 | export OPENMM_PLUGIN_DIR=$OPENMM_LIB_PATH/plugins
130 | export LD_LIBRARY_PATH=$OPENMM_LIB_PATH:$OPENMM_PLUGIN_DIR:$LD_LIBRARY_PATH
131 | cmake -DCMAKE_INSTALL_PREFIX=${CONDA_PREFIX} -DSEEKR2_BUILD_OPENCL_LIB=OFF -DOPENMM_DIR=${CONDA_PREFIX} ..
132 | make
133 | make install
134 | make PythonInstall
135 | make test
136 |
137 |
138 | - name: Install BrownDye
139 | shell: bash -l {0}
140 | run: |
141 | sudo apt-get install libexpat1 apbs
142 | wget https://browndye.ucsd.edu/downloads/browndye2-ubuntu-20.04.tar.gz
143 | tar -xzf browndye2-ubuntu-20.04.tar.gz
144 | cd browndye2/bin
145 | export PATH="$PWD:$PATH"
146 | echo "PATH: $PATH"
147 | ls
148 | cd ../..
149 |
150 |
151 | - name: Run tests
152 |
153 | # conda setup requires this special shell
154 | shell: bash -l {0}
155 |
156 | run: |
157 | export PATH="/home/runner/work/seekr2/seekr2/browndye2/bin:$PATH"
158 | export PATH="/home/runner/work/seekr2/seekr2/namd/Linux-x86_64-g++/:$PATH"
159 | python -m pip install .
160 | python -m openmm.testInstallation
161 | pytest -v --cov=seekr2 --cov-report=xml --color=yes -m "not needs_cuda" seekr2/tests/ seekr2_systems/tests/
162 | # pytest -v --cov=seekr2 --cov-report=xml --color=yes -m "not needs_cuda" seekr2/tests/
163 | # pytest -v --cov=seekr2_systems --cov-append --cov-report=xml --color=yes -m "not needs_cuda" seekr2_systems/tests/
164 |
165 | - name: CodeCov
166 | uses: codecov/codecov-action@v1
167 | with:
168 | token: ${{ secrets.CODECOV_TOKEN }}
169 | file: ./coverage.xml
170 | directory: ./coverage/reports/
171 | flags: unittests
172 | name: codecov-${{ matrix.os }}-py${{ matrix.python-version }}
173 | fail_ci_if_error: true
174 | path_to_write_report: ./coverage/codecov_report.txt
175 | verbose: true
176 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | # C extensions
7 | *.so
8 |
9 | # Distribution / packaging
10 | .Python
11 | env/
12 | build/
13 | develop-eggs/
14 | dist/
15 | downloads/
16 | eggs/
17 | .eggs/
18 | lib/
19 | lib64/
20 | parts/
21 | sdist/
22 | var/
23 | wheels/
24 | *.egg-info/
25 | .installed.cfg
26 | *.egg
27 |
28 | # PyInstaller
29 | # Usually these files are written by a python script from a template
30 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
31 | *.manifest
32 | *.spec
33 |
34 | # Installer logs
35 | pip-log.txt
36 | pip-delete-this-directory.txt
37 |
38 | # Unit test / coverage reports
39 | htmlcov/
40 | .tox/
41 | .coverage
42 | .coverage.*
43 | .cache
44 | .pytest_cache
45 | nosetests.xml
46 | coverage.xml
47 | *.cover
48 | .hypothesis/
49 |
50 | # Translations
51 | *.mo
52 | *.pot
53 |
54 | # Django stuff:
55 | *.log
56 | local_settings.py
57 |
58 | # Flask stuff:
59 | instance/
60 | .webassets-cache
61 |
62 | # Scrapy stuff:
63 | .scrapy
64 |
65 | # Sphinx documentation
66 | docs/_build/
67 |
68 | # PyBuilder
69 | target/
70 |
71 | # Jupyter Notebook
72 | .ipynb_checkpoints
73 |
74 | # pyenv
75 | .python-version
76 |
77 | # celery beat schedule file
78 | celerybeat-schedule
79 |
80 | # SageMath parsed files
81 | *.sage.py
82 |
83 | # dotenv
84 | .env
85 |
86 | # virtualenv
87 | .venv
88 | venv/
89 | ENV/
90 |
91 | # Spyder project settings
92 | .spyderproject
93 | .spyproject
94 |
95 | # Rope project settings
96 | .ropeproject
97 |
98 | # mkdocs documentation
99 | /site
100 |
101 | # mypy
102 | .mypy_cache/
103 |
104 | # profraw files from LLVM? Unclear exactly what triggers this
105 | # There are reports this comes from LLVM profiling, but also Xcode 9.
106 | *profraw
107 |
--------------------------------------------------------------------------------
/.lgtm.yml:
--------------------------------------------------------------------------------
1 | # Configure LGTM for this package
2 |
3 | extraction:
4 | python: # Configure Python
5 | python_setup: # Configure the setup
6 | version: 3 # Specify Version 3
7 | path_classifiers:
8 | library:
9 | - versioneer.py # Set Versioneer.py to an external "library" (3rd party code)
10 | - devtools/*
11 | generated:
12 | - seekr2/_version.py
13 |
--------------------------------------------------------------------------------
/.readthedocs.yaml:
--------------------------------------------------------------------------------
1 | # .readthedocs.yml
2 |
3 | version: 2
4 |
5 | build:
6 | os: ubuntu-22.04
7 | tools:
8 | python: "3.12"
9 |
10 | sphinx:
11 | configuration: docs/conf.py
12 |
13 | python:
14 | install:
15 | - requirements: docs/requirements.txt
16 | - method: pip
17 | path: .
18 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 |
2 | MIT License
3 |
4 | Copyright (c) 2021 Lane Votapka
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | SOFTWARE.
23 |
--------------------------------------------------------------------------------
/MANIFEST.in:
--------------------------------------------------------------------------------
1 | include LICENSE
2 | include MANIFEST.in
3 | include versioneer.py
4 |
5 | graft seekr2
6 | global-exclude *.py[cod] __pycache__ *.so
7 | include seekr2/_version.py
8 |
--------------------------------------------------------------------------------
/devtools/README.md:
--------------------------------------------------------------------------------
1 | # Development, testing, and deployment tools
2 |
3 | This directory contains a collection of tools for running Continuous Integration (CI) tests,
4 | conda installation, and other development tools not directly related to the coding process.
5 |
6 |
7 | ## Manifest
8 |
9 | ### Continuous Integration
10 |
11 | You should test your code, but do not feel compelled to use these specific programs. You also may not need Unix and
12 | Windows testing if you only plan to deploy on specific platforms. These are just to help you get started.
13 |
14 | The items in this directory have been left for legacy purposes since the change to GitHub Actions,
15 | They will likely be removed in a future version.
16 |
17 | * `legacy-miniconda-setup`: A preserved copy of a helper directory which made Linux and OSX based testing through [Travis-CI](https://about.travis-ci.com/) simpler
18 | * `before_install.sh`: Pip/Miniconda pre-package installation script for Travis. No longer needed thanks to
19 | [GitHub Actions](https://docs.github.com/en/free-pro-team@latest/actions) and the [conda-incubator/setup-miniconda Action](https://github.com/conda-incubator/setup-miniconda)
20 |
21 | ### Conda Environment:
22 |
23 | This directory contains the files to setup the Conda environment for testing purposes
24 |
25 | * `conda-envs`: directory containing the YAML file(s) which fully describe Conda Environments, their dependencies, and those dependency provenance's
26 | * `test_env.yaml`: Simple test environment file with base dependencies. Channels are not specified here and therefore respect global Conda configuration
27 |
28 | ### Additional Scripts:
29 |
30 | This directory contains OS agnostic helper scripts which don't fall in any of the previous categories
31 | * `scripts`
32 | * `create_conda_env.py`: Helper program for spinning up new conda environments based on a starter file with Python Version and Env. Name command-line options
33 |
34 |
35 | ## How to contribute changes
36 | - Clone the repository if you have write access to the main repo, fork the repository if you are a collaborator.
37 | - Make a new branch with `git checkout -b {your branch name}`
38 | - Make changes and test your code
39 | - Ensure that the test environment dependencies (`conda-envs`) line up with the build and deploy dependencies (`conda-recipe/meta.yaml`)
40 | - Push the branch to the repo (either the main or your fork) with `git push -u origin {your branch name}`
41 | * Note that `origin` is the default name assigned to the remote, yours may be different
42 | - Make a PR on GitHub with your changes
43 | - We'll review the changes and get your code into the repo after lively discussion!
44 |
45 |
46 | ## Checklist for updates
47 | - [ ] Make sure there is an/are issue(s) opened for your specific update
48 | - [ ] Create the PR, referencing the issue
49 | - [ ] Debug the PR as needed until tests pass
50 | - [ ] Tag the final, debugged version
51 | * `git tag -a X.Y.Z [latest pushed commit] && git push --follow-tags`
52 | - [ ] Get the PR merged in
53 |
54 | ## Versioneer Auto-version
55 | [Versioneer](https://github.com/warner/python-versioneer) will automatically infer what version
56 | is installed by looking at the `git` tags and how many commits ahead this version is. The format follows
57 | [PEP 440](https://www.python.org/dev/peps/pep-0440/) and has the regular expression of:
58 | ```regexp
59 | \d+.\d+.\d+(?\+\d+-[a-z0-9]+)
60 | ```
61 | If the version of this commit is the same as a `git` tag, the installed version is the same as the tag,
62 | e.g. `seekr2-0.1.2`, otherwise it will be appended with `+X` where `X` is the number of commits
63 | ahead from the last tag, and then `-YYYYYY` where the `Y`'s are replaced with the `git` commit hash.
64 |
--------------------------------------------------------------------------------
/devtools/conda-envs/test_env.yaml:
--------------------------------------------------------------------------------
1 | name: test
2 | channels:
3 | - conda-forge
4 |
5 | dependencies:
6 | # Base depends
7 | - python
8 | - pip
9 | - numpy
10 | - scipy
11 | - matplotlib
12 | - openmm
13 | - swig
14 |
15 | # Testing
16 | - pytest
17 | - pytest-cov
18 | - codecov
19 |
20 | # Pip-only installs
21 | - pip:
22 | - codecov
23 | - parmed
24 | - mdtraj
25 | - bubblebuster
26 |
27 |
--------------------------------------------------------------------------------
/devtools/legacy-miniconda-setup/before_install.sh:
--------------------------------------------------------------------------------
1 | # Temporarily change directory to $HOME to install software
2 | pushd .
3 | cd $HOME
4 | # Make sure some level of pip is installed
5 | python -m ensurepip
6 |
7 | # Install Miniconda
8 | if [ "$TRAVIS_OS_NAME" == "osx" ]; then
9 | # Make OSX md5 mimic md5sum from linux, alias does not work
10 | md5sum () {
11 | command md5 -r "$@"
12 | }
13 | MINICONDA=Miniconda3-latest-MacOSX-x86_64.sh
14 | else
15 | MINICONDA=Miniconda3-latest-Linux-x86_64.sh
16 | fi
17 | MINICONDA_HOME=$HOME/miniconda
18 | MINICONDA_MD5=$(wget -qO- https://repo.anaconda.com/miniconda/ | grep -A3 $MINICONDA | sed -n '4p' | sed -n 's/ *
\(.*\)<\/td> */\1/p')
19 | wget -q https://repo.anaconda.com/miniconda/$MINICONDA
20 | if [[ $MINICONDA_MD5 != $(md5sum $MINICONDA | cut -d ' ' -f 1) ]]; then
21 | echo "Miniconda MD5 mismatch"
22 | exit 1
23 | fi
24 | bash $MINICONDA -b -p $MINICONDA_HOME
25 |
26 | # Configure miniconda
27 | export PIP_ARGS="-U"
28 | # New to conda >=4.4
29 | echo ". $MINICONDA_HOME/etc/profile.d/conda.sh" >> ~/.bashrc # Source the profile.d file
30 | echo "conda activate" >> ~/.bashrc # Activate conda
31 | source ~/.bashrc # source file to get new commands
32 | #export PATH=$MINICONDA_HOME/bin:$PATH # Old way, should not be needed anymore
33 |
34 | conda config --add channels conda-forge
35 |
36 | conda config --set always_yes yes
37 | conda install conda conda-build jinja2 anaconda-client
38 | conda update --quiet --all
39 |
40 | # Restore original directory
41 | popd
42 |
--------------------------------------------------------------------------------
/devtools/scripts/create_conda_env.py:
--------------------------------------------------------------------------------
1 | import argparse
2 | import os
3 | import re
4 | import glob
5 | import shutil
6 | import subprocess as sp
7 | from tempfile import TemporaryDirectory
8 | from contextlib import contextmanager
9 | # YAML imports
10 | try:
11 | import yaml # PyYAML
12 | loader = yaml.load
13 | except ImportError:
14 | try:
15 | import ruamel_yaml as yaml # Ruamel YAML
16 | except ImportError:
17 | try:
18 | # Load Ruamel YAML from the base conda environment
19 | from importlib import util as import_util
20 | CONDA_BIN = os.path.dirname(os.environ['CONDA_EXE'])
21 | ruamel_yaml_path = glob.glob(os.path.join(CONDA_BIN, '..',
22 | 'lib', 'python*.*', 'site-packages',
23 | 'ruamel_yaml', '__init__.py'))[0]
24 | # Based on importlib example, but only needs to load_module since its the whole package, not just
25 | # a module
26 | spec = import_util.spec_from_file_location('ruamel_yaml', ruamel_yaml_path)
27 | yaml = spec.loader.load_module()
28 | except (KeyError, ImportError, IndexError):
29 | raise ImportError("No YAML parser could be found in this or the conda environment. "
30 | "Could not find PyYAML or Ruamel YAML in the current environment, "
31 | "AND could not find Ruamel YAML in the base conda environment through CONDA_EXE path. "
32 | "Environment not created!")
33 | loader = yaml.YAML(typ="safe").load # typ="safe" avoids odd typing on output
34 |
35 |
36 | @contextmanager
37 | def temp_cd():
38 | """Temporary CD Helper"""
39 | cwd = os.getcwd()
40 | with TemporaryDirectory() as td:
41 | try:
42 | os.chdir(td)
43 | yield
44 | finally:
45 | os.chdir(cwd)
46 |
47 |
48 | # Args
49 | parser = argparse.ArgumentParser(description='Creates a conda environment from file for a given Python version.')
50 | parser.add_argument('-n', '--name', type=str,
51 | help='The name of the created Python environment')
52 | parser.add_argument('-p', '--python', type=str,
53 | help='The version of the created Python environment')
54 | parser.add_argument('conda_file',
55 | help='The file for the created Python environment')
56 |
57 | args = parser.parse_args()
58 |
59 | # Open the base file
60 | with open(args.conda_file, "r") as handle:
61 | yaml_script = loader(handle.read())
62 |
63 | python_replacement_string = "python {}*".format(args.python)
64 |
65 | try:
66 | for dep_index, dep_value in enumerate(yaml_script['dependencies']):
67 | if re.match('python([ ><=*]+[0-9.*]*)?$', dep_value): # Match explicitly 'python' and its formats
68 | yaml_script['dependencies'].pop(dep_index)
69 | break # Making the assumption there is only one Python entry, also avoids need to enumerate in reverse
70 | except (KeyError, TypeError):
71 | # Case of no dependencies key, or dependencies: None
72 | yaml_script['dependencies'] = []
73 | finally:
74 | # Ensure the python version is added in. Even if the code does not need it, we assume the env does
75 | yaml_script['dependencies'].insert(0, python_replacement_string)
76 |
77 | # Figure out conda path
78 | if "CONDA_EXE" in os.environ:
79 | conda_path = os.environ["CONDA_EXE"]
80 | else:
81 | conda_path = shutil.which("conda")
82 | if conda_path is None:
83 | raise RuntimeError("Could not find a conda binary in CONDA_EXE variable or in executable search path")
84 |
85 | print("CONDA ENV NAME {}".format(args.name))
86 | print("PYTHON VERSION {}".format(args.python))
87 | print("CONDA FILE NAME {}".format(args.conda_file))
88 | print("CONDA PATH {}".format(conda_path))
89 |
90 | # Write to a temp directory which will always be cleaned up
91 | with temp_cd():
92 | temp_file_name = "temp_script.yaml"
93 | with open(temp_file_name, 'w') as f:
94 | f.write(yaml.dump(yaml_script))
95 | sp.call("{} env create -n {} -f {}".format(conda_path, args.name, temp_file_name), shell=True)
96 |
--------------------------------------------------------------------------------
/docs/Makefile:
--------------------------------------------------------------------------------
1 | # Minimal makefile for Sphinx documentation
2 | #
3 |
4 | # You can set these variables from the command line.
5 | SPHINXOPTS =
6 | SPHINXBUILD = sphinx-build
7 | SPHINXPROJ = seekr2
8 | SOURCEDIR = .
9 | BUILDDIR = _build
10 |
11 | # Put it first so that "make" without argument is like "make help".
12 | help:
13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
14 |
15 | .PHONY: help Makefile
16 |
17 | # Catch-all target: route all unknown targets to Sphinx using the new
18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
19 | %: Makefile
20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
--------------------------------------------------------------------------------
/docs/README.md:
--------------------------------------------------------------------------------
1 | # Compiling seekr2's Documentation
2 |
3 | The docs for this project are built with [Sphinx](http://www.sphinx-doc.org/en/master/).
4 | To compile the docs, first ensure that Sphinx and the ReadTheDocs theme are installed.
5 |
6 |
7 | ```bash
8 | conda install sphinx sphinx_rtd_theme
9 | ```
10 |
11 |
12 | Once installed, you can use the `Makefile` in this directory to compile static HTML pages by
13 | ```bash
14 | make html
15 | ```
16 |
17 | The compiled docs will be in the `_build` directory and can be viewed by opening `index.html` (which may itself
18 | be inside a directory called `html/` depending on what version of Sphinx is installed).
19 |
20 |
21 | A configuration file for [Read The Docs](https://readthedocs.org/) (readthedocs.yaml) is included in the top level of the repository. To use Read the Docs to host your documentation, go to https://readthedocs.org/ and connect this repository. You may need to change your default branch to `main` under Advanced Settings for the project.
22 |
23 | If you would like to use Read The Docs with `autodoc` (included automatically) and your package has dependencies, you will need to include those dependencies in your documentation yaml file (`docs/requirements.yaml`).
24 |
25 |
--------------------------------------------------------------------------------
/docs/_static/README.md:
--------------------------------------------------------------------------------
1 | # Static Doc Directory
2 |
3 | Add any paths that contain custom static files (such as style sheets) here,
4 | relative to the `conf.py` file's directory.
5 | They are copied after the builtin static files,
6 | so a file named "default.css" will overwrite the builtin "default.css".
7 |
8 | The path to this folder is set in the Sphinx `conf.py` file in the line:
9 | ```python
10 | templates_path = ['_static']
11 | ```
12 |
13 | ## Examples of file to add to this directory
14 | * Custom Cascading Style Sheets
15 | * Custom JavaScript code
16 | * Static logo images
17 |
--------------------------------------------------------------------------------
/docs/_static/entropy_barrier.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seekrcentral/seekr2/93bf27571b0bdbce8133227538261e4cddc7b137/docs/_static/entropy_barrier.mp4
--------------------------------------------------------------------------------
/docs/_static/muller_potential.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seekrcentral/seekr2/93bf27571b0bdbce8133227538261e4cddc7b137/docs/_static/muller_potential.mp4
--------------------------------------------------------------------------------
/docs/_templates/README.md:
--------------------------------------------------------------------------------
1 | # Templates Doc Directory
2 |
3 | Add any paths that contain templates here, relative to
4 | the `conf.py` file's directory.
5 | They are copied after the builtin template files,
6 | so a file named "page.html" will overwrite the builtin "page.html".
7 |
8 | The path to this folder is set in the Sphinx `conf.py` file in the line:
9 | ```python
10 | html_static_path = ['_templates']
11 | ```
12 |
13 | ## Examples of file to add to this directory
14 | * HTML extensions of stock pages like `page.html` or `layout.html`
15 |
--------------------------------------------------------------------------------
/docs/api.rst:
--------------------------------------------------------------------------------
1 | API Documentation
2 | =================
3 |
4 | Normally, one would run SEEKR2 directly on the Linux terminal. However, it is
5 | possible to perform an entire SEEKR2 calculation, along with all of its
6 | auxiliary functions, from a custom python program by using SEEKR2's Application
7 | Programming Interface (API).
8 |
9 | .. toctree::
10 | :maxdepth: 1
11 | :caption: Contents:
12 |
13 | api_examples
14 |
15 |
--------------------------------------------------------------------------------
/docs/api_examples.rst:
--------------------------------------------------------------------------------
1 | API Examples
2 | ============
3 |
4 | An example of a script to run a SEEKR2 calculation can be found in Listing 1.
5 | This script defines a “model input” object, loads its parameters from an XML
6 | file, generates the full model, checks the model for potential problems, runs
7 | any and all of the MD and BD simulations, and analyzes the results.
8 |
9 | **Listing 1:** a sample Python script using the SEEKR2 API to perform a full
10 | SEEKR calculation. NOTE: this script should be run from the seekr2/seekr2/
11 | directory to work as-is.::
12 |
13 | import seekr2
14 | model_input_filename = “data/sample_input_mmvt_openmm.xml"
15 | model_input = seekr2.prepare.common_prepare.Model_input()
16 | model_input.deserialize(model_input_filename, user_input=True)
17 | model, xml_path = seekr2.prepare.prepare(model_input)
18 | model.anchor_rootdir = os.path.dirname(xml_path)
19 | seekr2.modules.check.check_pre_simulation_all(model)
20 | seekr2.run.run(model, "any")
21 | analysis = seekr2.analyze.analyze(model)
22 | analysis.print_results()
23 |
24 | The objects can be accessed/modified from the Python API at any step in the
25 | process. For instance, if one wishes to add or move milestones, one could add
26 | the lines shown in Listing 2 before the model is prepared. Or say that one
27 | wants to access the milestoning matrix directly, one could add the lines in
28 | listing 3 after analysis object is generated.
29 |
30 | **Listing 2:** a an additional snippet of sample Python code to use the SEEKR2
31 | API for first add an anchor to the calculation and generate the model. Then,
32 | to demonstrate that the radius can be changed after the model is generated,
33 | the anchor’s radius is changed and the model is regenerated.::
34 |
35 | from openmm import unit
36 | new_input_anchor = seekr2.modules.common_cv.Spherical_cv_anchor()
37 | new_input_anchor.radius = 0.1 * unit.nanometer
38 | model_input.cv_inputs[0].input_anchors.insert(1, new_input_anchor)
39 | model, xml_path = seekr2.prepare.prepare(model_input, force_overwrite=True)
40 | model_input.cv_inputs[0].input_anchors[1].radius = 0.11 * unit.nanometers
41 | model, xml_path = seekr2.prepare.prepare(model_input, force_overwrite=True)
42 |
43 | **Listing 3:** The milestoning rate matrix “Q” or free energy profile are just
44 | two examples of many quantities that may be accessed directly from the Python
45 | analysis object.::
46 |
47 | print(analysis.main_data_sample.Q)
48 | print(analysis.free_energy_profile)
49 |
50 | This script is just intended to give developers a glimpse of what is possible
51 | when using the API. Please consult the documentation within the code itself
52 | for details about the arguments to each of these functions.
--------------------------------------------------------------------------------
/docs/citations.rst:
--------------------------------------------------------------------------------
1 | Citations
2 | =========
3 |
4 | On this page, you will find a list of BibTex format citations for easy citing.
5 |
6 | Main SEEKR2 Paper
7 | -----------------
8 |
9 | If you wish to cite SEEKR2, please cite the following paper::
10 |
11 | @article{votapka2022seekr2,
12 | title={SEEKR2: Versatile multiscale milestoning utilizing the OpenMM molecular dynamics engine},
13 | author={Votapka, Lane W and Stokely, Andrew M and Ojha, Anupam A and Amaro, Rommie E},
14 | journal={Journal of chemical information and modeling},
15 | volume={62},
16 | number={13},
17 | pages={3253--3262},
18 | year={2022},
19 | publisher={ACS Publications}
20 | }
21 |
22 | Dependencies
23 | ------------
24 |
25 | One should also cite SEEKR2's dependencies::
26 |
27 | @Article{Hunter:2007,
28 | Author = {Hunter, J. D.},
29 | Title = {Matplotlib: A 2D graphics environment},
30 | Journal = {Computing in Science \& Engineering},
31 | Volume = {9},
32 | Number = {3},
33 | Pages = {90--95},
34 | abstract = {Matplotlib is a 2D graphics package used for Python for
35 | application development, interactive scripting, and publication-quality
36 | image generation across user interfaces and operating systems.},
37 | publisher = {IEEE COMPUTER SOC},
38 | doi = {10.1109/MCSE.2007.55},
39 | year = 2007
40 | }
41 |
42 | @article{van2011numpy,
43 | title={The NumPy array: a structure for efficient numerical computation},
44 | author={Van Der Walt, Stefan and Colbert, S Chris and Varoquaux, Gael},
45 | journal={Computing in Science \& Engineering},
46 | volume={13},
47 | number={2},
48 | pages={22--30},
49 | year={2011},
50 | publisher={AIP Publishing},
51 | doi={10.1109/MCSE.2011.37}
52 | }
53 |
54 | @Misc{JOP+01,
55 | author = {Eric Jones and Travis Oliphant and Pearu Peterson and others},
56 | title = {{SciPy}: Open source scientific tools for {Python}},
57 | year = {2001--},
58 | url = "http://www.scipy.org/",
59 | note = {[Online; accessed 2015-07-13]}
60 | }
61 |
62 | @article{doi:10.1021/acs.jctc.9b01211,
63 | author = {Swinburne, Thomas D. and Wales, David J.},
64 | title = {Defining, Calculating, and Converging Observables of a Kinetic Transition Network},
65 | journal = {Journal of Chemical Theory and Computation},
66 | volume = {16},
67 | number = {4},
68 | pages = {2661-2679},
69 | year = {2020},
70 | doi = {10.1021/acs.jctc.9b01211},
71 | note ={PMID: 32155072},
72 | }
73 |
74 | Other SEEKR Papers
75 | ------------------
76 |
77 | One may also optionally cite one or more of the following papers::
78 |
79 | @article{ojha2023qmrebind,
80 | title={QMrebind: incorporating quantum mechanical force field reparameterization at the ligand binding site for improved drug-target kinetics through milestoning simulations},
81 | author={Ojha, Anupam Anand and Votapka, Lane William and Amaro, Rommie Elizabeth},
82 | journal={Chemical Science},
83 | volume={14},
84 | number={45},
85 | pages={13159--13175},
86 | year={2023},
87 | publisher={Royal Society of Chemistry}
88 | }
89 |
90 | @article{doi:10.1021/acs.jcim.2c01589,
91 | author = {Ojha, Anupam Anand and Srivastava, Ambuj and Votapka, Lane William and Amaro, Rommie E.},
92 | title = {Selectivity and Ranking of Tight-Binding JAK-STAT Inhibitors Using Markovian Milestoning with Voronoi Tessellations},
93 | journal = {Journal of Chemical Information and Modeling},
94 | volume = {63},
95 | number = {8},
96 | pages = {2469-2482},
97 | year = {2023},
98 | doi = {10.1021/acs.jcim.2c01589},
99 | note ={PMID: 37023323}
100 | }
101 |
102 | @article{votapka2017seekr,
103 | title={SEEKR: simulation enabled estimation of kinetic rates, a computational tool to estimate molecular kinetics and its application to trypsin--benzamidine binding},
104 | author={Votapka, Lane W and Jagger, Benjamin R and Heyneman, Alexandra L and Amaro, Rommie E},
105 | journal={The Journal of Physical Chemistry B},
106 | volume={121},
107 | number={15},
108 | pages={3597--3606},
109 | year={2017},
110 | publisher={ACS Publications}
111 | }
112 |
113 | @article{jagger2020predicting,
114 | title={Predicting ligand binding kinetics using a Markovian milestoning with voronoi tessellations multiscale approach},
115 | author={Jagger, Benjamin R and Ojha, Anupam A and Amaro, Rommie E},
116 | journal={Journal of Chemical Theory and Computation},
117 | volume={16},
118 | number={8},
119 | pages={5348--5357},
120 | year={2020},
121 | publisher={ACS Publications}
122 | }
123 |
124 | @article{doi:10.1021/acs.jpclett.8b02047,
125 | author = {Jagger, Benjamin R. and Lee, Christopher T. and Amaro, Rommie E.},
126 | title = {Quantitative Ranking of Ligand Binding Kinetics with a Multiscale Milestoning Simulation Approach},
127 | journal = {The Journal of Physical Chemistry Letters},
128 | volume = {9},
129 | number = {17},
130 | pages = {4941-4948},
131 | year = {2018},
132 | doi = {10.1021/acs.jpclett.8b02047},
133 | note ={PMID: 30070844},
134 | }
135 |
136 | @article{10.1371/journal.pcbi.1004381,
137 | doi = {10.1371/journal.pcbi.1004381},
138 | author = {Votapka, Lane W. AND Amaro, Rommie E.},
139 | journal = {PLOS Computational Biology},
140 | publisher = {Public Library of Science},
141 | title = {Multiscale Estimation of Binding Kinetics Using Brownian Dynamics, Molecular Dynamics and Milestoning},
142 | year = {2015},
143 | month = {10},
144 | volume = {11},
145 | url = {https://doi.org/10.1371/journal.pcbi.1004381},
146 | pages = {1-24},
147 | abstract = {The kinetic rate constants of binding were estimated for four biochemically relevant molecular systems by a method that uses milestoning theory to combine Brownian dynamics simulations with more detailed molecular dynamics simulations. The rate constants found using this method agreed well with experimentally and theoretically obtained values. We predicted the association rate of a small charged molecule toward both a charged and an uncharged spherical receptor and verified the estimated value with Smoluchowski theory. We also calculated the kon rate constant for superoxide dismutase with its natural substrate, O2−, in a validation of a previous experiment using similar methods but with a number of important improvements. We also calculated the kon for a new system: the N-terminal domain of Troponin C with its natural substrate Ca2+. The kon calculated for the latter two systems closely resemble experimentally obtained values. This novel multiscale approach is computationally cheaper and more parallelizable when compared to other methods of similar accuracy. We anticipate that this methodology will be useful for predicting kinetic rate constants and for understanding the process of binding between a small molecule and a protein receptor.},
148 | number = {10},
149 | }
150 |
151 |
--------------------------------------------------------------------------------
/docs/conf.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | #
3 | # Configuration file for the Sphinx documentation builder.
4 | #
5 | # This file does only contain a selection of the most common options. For a
6 | # full list see the documentation:
7 | # http://www.sphinx-doc.org/en/stable/config
8 |
9 | # -- Path setup --------------------------------------------------------------
10 |
11 | # If extensions (or modules to document with autodoc) are in another directory,
12 | # add these directories to sys.path here. If the directory is relative to the
13 | # documentation root, use os.path.abspath to make it absolute, like shown here.
14 |
15 | # Incase the project was not installed
16 | import os
17 | import sys
18 | sys.path.insert(0, os.path.abspath('..'))
19 |
20 | import seekr2
21 |
22 |
23 | # -- Project information -----------------------------------------------------
24 |
25 | project = 'seekr2'
26 | copyright = ("2021, Lane Votapka. Project structure based on the "
27 | "Computational Molecular Science Python Cookiecutter version 1.5")
28 | author = 'Lane Votapka'
29 |
30 | # The short X.Y version
31 | version = '2.1'
32 | # The full version, including alpha/beta/rc tags
33 | release = '2.1.4-beta'
34 |
35 |
36 | # -- General configuration ---------------------------------------------------
37 |
38 | # If your documentation needs a minimal Sphinx version, state it here.
39 | #
40 | # needs_sphinx = '1.0'
41 |
42 | # Add any Sphinx extension module names here, as strings. They can be
43 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
44 | # ones.
45 | extensions = [
46 | 'sphinx.ext.autosummary',
47 | 'sphinx.ext.autodoc',
48 | 'sphinx.ext.mathjax',
49 | 'sphinx.ext.viewcode',
50 | 'sphinx.ext.napoleon',
51 | 'sphinx.ext.intersphinx',
52 | 'sphinx.ext.extlinks',
53 | 'sphinx_rtd_theme',
54 | ]
55 |
56 | autosummary_generate = True
57 | napoleon_google_docstring = False
58 | napoleon_use_param = False
59 | napoleon_use_ivar = True
60 |
61 | # Add any paths that contain templates here, relative to this directory.
62 | templates_path = ['_templates']
63 |
64 | # The suffix(es) of source filenames.
65 | # You can specify multiple suffix as a list of string:
66 | #
67 | # source_suffix = ['.rst', '.md']
68 | source_suffix = '.rst'
69 |
70 | # The master toctree document.
71 | master_doc = 'index'
72 |
73 | # The language for content autogenerated by Sphinx. Refer to documentation
74 | # for a list of supported languages.
75 | #
76 | # This is also used if you do content translation via gettext catalogs.
77 | # Usually you set "language" from the command line for these cases.
78 | language = "en"
79 |
80 | # List of patterns, relative to source directory, that match files and
81 | # directories to ignore when looking for source files.
82 | # This pattern also affects html_static_path and html_extra_path .
83 | exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
84 |
85 | # The name of the Pygments (syntax highlighting) style to use.
86 | pygments_style = 'default'
87 |
88 |
89 | # -- Options for HTML output -------------------------------------------------
90 |
91 | # The theme to use for HTML and HTML Help pages. See the documentation for
92 | # a list of builtin themes.
93 | #
94 | html_theme = 'sphinx_rtd_theme'
95 |
96 | # Theme options are theme-specific and customize the look and feel of a theme
97 | # further. For a list of options available for each theme, see the
98 | # documentation.
99 | #
100 | # html_theme_options = {}
101 |
102 | # Add any paths that contain custom static files (such as style sheets) here,
103 | # relative to this directory. They are copied after the builtin static files,
104 | # so a file named "default.css" will overwrite the builtin "default.css".
105 | html_static_path = ['_static']
106 |
107 | # Custom sidebar templates, must be a dictionary that maps document names
108 | # to template names.
109 | #
110 | # The default sidebars (for documents that don't match any pattern) are
111 | # defined by theme itself. Builtin themes are using these templates by
112 | # default: ``['localtoc.html', 'relations.html', 'sourcelink.html',
113 | # 'searchbox.html']``.
114 | #
115 | # html_sidebars = {}
116 |
117 |
118 | # -- Options for HTMLHelp output ---------------------------------------------
119 |
120 | # Output file base name for HTML help builder.
121 | htmlhelp_basename = 'seekr2doc'
122 |
123 |
124 | # -- Options for LaTeX output ------------------------------------------------
125 |
126 | latex_elements = {
127 | # The paper size ('letterpaper' or 'a4paper').
128 | #
129 | # 'papersize': 'letterpaper',
130 |
131 | # The font size ('10pt', '11pt' or '12pt').
132 | #
133 | # 'pointsize': '10pt',
134 |
135 | # Additional stuff for the LaTeX preamble.
136 | #
137 | # 'preamble': '',
138 |
139 | # Latex figure (float) alignment
140 | #
141 | # 'figure_align': 'htbp',
142 | }
143 |
144 | # Grouping the document tree into LaTeX files. List of tuples
145 | # (source start file, target name, title,
146 | # author, documentclass [howto, manual, or own class]).
147 | latex_documents = [
148 | (master_doc, 'seekr2.tex', 'seekr2 Documentation',
149 | 'seekr2', 'manual'),
150 | ]
151 |
152 |
153 | # -- Options for manual page output ------------------------------------------
154 |
155 | # One entry per manual page. List of tuples
156 | # (source start file, name, description, authors, manual section).
157 | man_pages = [
158 | (master_doc, 'seekr2', 'seekr2 Documentation',
159 | [author], 1)
160 | ]
161 |
162 |
163 | # -- Options for Texinfo output ----------------------------------------------
164 |
165 | # Grouping the document tree into Texinfo files. List of tuples
166 | # (source start file, target name, title, author,
167 | # dir menu entry, description, category)
168 | texinfo_documents = [
169 | (master_doc, 'seekr2', 'seekr2 Documentation',
170 | author, 'seekr2', 'Simulation-Enabled Estimation of Kinetic Rates - Version 2',
171 | 'Miscellaneous'),
172 | ]
173 |
174 |
175 | # -- Extension configuration -------------------------------------------------
176 |
--------------------------------------------------------------------------------
/docs/faq.rst:
--------------------------------------------------------------------------------
1 | Frequently Asked Questions
2 | ==========================
3 |
4 | .. contents:: Contents
5 | :depth: 3
6 |
7 | What is SEEKR2?
8 | ---------------
9 | Simulation Enabled Estimation of Kinetic Rates is, simultaneously, a collection
10 | of scientific software programs, and also a technical approach to estimate the
11 | kinetics and thermodynamics of certain molecular processes, especially ligand-
12 | receptor binding, using Milestoning theory. SEEKR2 is the second iteration of
13 | the software, with better speed, capabilities, and usability than the earlier
14 | version.
15 |
16 | What can SEEKR2 do?
17 | -------------------
18 | At present, the main utility of SEEKR2 is to estimate the kinetics of binding
19 | and unbinding (represented by the quantities k-on and k-off), in addition to
20 | the thermodynamics of binding (represented by the Gibbs free energy of
21 | binding).
22 |
23 | Testing and preliminary calculations indicate that SEEKR2 can
24 | consistently obtain binding/unbinding rate constants within an order of
25 | magnitude of the experimental quantity, and sometimes much better, even for
26 | systems with very long residence times. SEEKR2 can also usually obtain Gibbs
27 | free energies of binding within ~1 kcal/mol of experiment. In addition, the
28 | SEEKR method has been able to rank compounds by their residence time and
29 | affinity to a receptor with good accuracy.
30 |
31 | More details about SEEKR2's accuracy and performance can be obtained from the
32 | publications on the :doc:`Index page`.
33 |
34 | Development is ongoing, and more capabilities for SEEKR2 are being actively
35 | pursued. The kinetics and thermodynamics of intramolecular motion (such as
36 | hinge or pocket opening/closing), intersite transfer, peptide folding, and
37 | processes can be estimated using SEEKR2. Publications of these applications
38 | are forthcoming.
39 |
40 | What if I doubt SEEKR2's usefulness/validity?
41 | ---------------------------------------------
42 |
43 |
44 |
45 | How can I use SEEKR2 for my research?
46 | -------------------------------------
47 |
48 |
49 | How does one get a benchmark of a SEEKR2 calculation?
50 | -----------------------------------------------------
51 | If the SEEKR2 run.py program terminates successfully, the last thing it will
52 | print is a benchmark (in ns/day) for an MD anchor. Therefore, if you wish to
53 | obtain a benchmark, consider running a short SEEKR2 calculation by passing a
54 | relatively small number (like 10000) to the "-t" argument of run.py.
55 |
56 |
57 | How many CPUs are optimal for a SEEKR2 calculation?
58 | ---------------------------------------------------
59 | In NAMD mode, using multiple CPUs is likely to make the calculation go faster.
60 | However, in OpenMM mode, the CUDA platform is designed to use only one CPU,
61 | so using multiple CPUs in OpenMM mode is not likely to make the calculation go
62 | any faster.
63 |
64 |
65 | How are the convergence plots calculated in SEEKR2?
66 | ---------------------------------------------------
67 |
68 |
69 |
70 | How does SEEKR2 compute the convergence value for the individual anchors?
71 | -------------------------------------------------------------------------
72 |
--------------------------------------------------------------------------------
/docs/index.rst:
--------------------------------------------------------------------------------
1 | SEEKR2: Multiscale Milestoning Calculations of Kinetics and Thermodynamics
2 | ==========================================================================
3 |
4 | :Release: |release|
5 | :Date: |today|
6 |
7 | **SEEKR2** Simulation Enabled Estimation of Kinetic Rates version 2
8 | is a package to perform simulations at multiple scales for the calculation of
9 | kinetics and thermodynamics quantities.
10 |
11 | Most typically, one would use this package to obtain the kinetics and
12 | thermodynamics of binding and unbinding between a small molecule and
13 | biomolecular receptor. Also typically, this package performs molecular
14 | dynamics (MD) and Brownian dynamics (BD) simulations of the binding process
15 | within multiple regions of phase space, utilizing expensive, but highly
16 | accurate MD for regions where close molecular interaction would require high
17 | accuracy, but utilizing faster, but more approximate BD for regions of greater
18 | intermolecular distance. This way the advantages of each simulation regime is
19 | augmented and their disadvantages are reduced. The regimes are then combined
20 | using the theory of milestoning such that the kinetics and thermodynamics of the
21 | process under interest is obtained.
22 |
23 | Two versions of milestoning theory are available to use in SEEKR2:
24 |
25 | 1. **Markovian milestoning with Voronoi Tesselations (MMVT)**: Vanden-Eijnden, E.; Venturoli, M. Markovian Milestoning with Voronoi Tessellations. J. Chem. Phys. 2009, 130 (19), 194101. https://doi.org/10.1063/1.3129843
26 |
27 | 2. **The original formulation of milestoning theory (Elber milestoning)**: Faradjian, A. K.; Elber, R. Computing Time Scales from Reaction Coordinates by Milestoning. J. Chem. Phys. 2004, 120 (23), 10880–10889. https://doi.org/10.1063/1.1738640
28 |
29 | .. toctree::
30 | :maxdepth: 1
31 | :caption: Contents:
32 |
33 | installation
34 | running_calculations
35 | tutorial
36 | model_input_files
37 | program_options
38 | api
39 | faq
40 | citations
41 |
42 | Cite SEEKR2
43 | ===========
44 |
45 | For BibTex files of any or all of the following citations, please visit: https://seekr2.readthedocs.io/en/latest/citations.html
46 |
47 | If you wish to cite SEEKR2, please cite the following paper:
48 |
49 | * Votapka, L. W.; Stokely, A. M.; Ojha, A. A.; Amaro, R. E. SEEKR2: Versatile Multiscale Milestoning Utilizing the OpenMM Molecular Dynamics Engine. J. Chem. Inf. Mod. 2022 62 (13), 3253-3262. DOI: 10.1021/acs.jcim.2c00501
50 |
51 | One should also cite SEEKR2's dependencies:
52 |
53 | * Van Der Walt, S., Colbert, S.C. & Varoquaux, G., 2011. The NumPy array: a structure for efficient numerical computation. Computing in Science & Engineering, 13(2), pp.22–30.
54 |
55 | * Jones, E. et al., 2001. SciPy: Open source scientific tools for Python.
56 |
57 | * Hunter, J.D., 2007. Matplotlib: A 2D graphics environment. Computing in Science & Engineering, 9(3), pp.90–95.
58 |
59 | * T.D. Swinburne and D.J. Wales, Defining, Calculating, and Converging Observables of a Kinetic Transition Network, J. Chemical Theory and Computation (2020), https://doi.org/10.1021/acs.jctc.9b01211
60 |
61 | One may also optionally cite one or more of the following papers:
62 |
63 | * Ojha, A. A., Votapka L. W., Amaro, R. E. QMrebind: incorporating quantum mechanical force field reparameterization at the ligand binding site for improved drug-target kinetics through milestoning simulations. Chemical Science 14 (45), 13159-13175
64 |
65 | * Ojha A. A., Srivastava A., Votapka L. W., and Amaro R. E. Selectivity and Ranking of Tight-Binding JAK-STAT Inhibitors Using Markovian Milestoning with Voronoi Tessellations. Journal of Chemical Information and Modeling 2023 63 (8), 2469-2482. DOI: 10.1021/acs.jcim.2c01589
66 |
67 | * Votapka, L. W.; Jagger, B. R.; Heyneman, A. L.; Amaro, R. E. SEEKR: Simulation Enabled Estimation of Kinetic Rates, A Computational Tool to Estimate Molecular Kinetics and Its Application to Trypsin–Benzamidine Binding. J. Phys. Chem. B 2017, 121 (15), 3597–3606. https://doi.org/10.1021/acs.jpcb.6b09388.
68 |
69 | * Jagger, B. R.; Ojha, A. A.; Amaro, R. E. Predicting Ligand Binding Kinetics Using a Markovian Milestoning with Voronoi Tessellations Multiscale Approach. J. Chem. Theory Comput. 2020. https://doi.org/10.1021/acs.jctc.0c00495.
70 |
71 | * Jagger, B. R.; Lee, C. T.; Amaro, R. E. Quantitative Ranking of Ligand Binding Kinetics with a Multiscale Milestoning Simulation Approach. J. Phys. Chem. Lett. 2018, 9 (17), 4941–4948. https://doi.org/10.1021/acs.jpclett.8b02047.
72 |
73 | * Votapka LW, Amaro RE (2015) Multiscale Estimation of Binding Kinetics Using Brownian Dynamics, Molecular Dynamics and Milestoning. PLOS Computational Biology 11(10): e1004381. https://doi.org/10.1371/journal.pcbi.1004381
74 |
75 |
76 | Getting Involved
77 | ================
78 |
79 | Please report **bugs** or **enhancement requests** through the `Issue
80 | Tracker`_.
81 |
82 | .. _Issue Tracker: https://github.com/seekrcentral/seekr2/issues
83 |
84 | Indices and tables
85 | ==================
86 |
87 | * :ref:`genindex`
88 | * :ref:`modindex`
89 | * :ref:`search`
90 |
--------------------------------------------------------------------------------
/docs/make.bat:
--------------------------------------------------------------------------------
1 | @ECHO OFF
2 |
3 | pushd %~dp0
4 |
5 | REM Command file for Sphinx documentation
6 |
7 | if "%SPHINXBUILD%" == "" (
8 | set SPHINXBUILD=sphinx-build
9 | )
10 | set SOURCEDIR=.
11 | set BUILDDIR=_build
12 | set SPHINXPROJ=seekr2
13 |
14 | if "%1" == "" goto help
15 |
16 | %SPHINXBUILD% >NUL 2>NUL
17 | if errorlevel 9009 (
18 | echo.
19 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
20 | echo.installed, then set the SPHINXBUILD environment variable to point
21 | echo.to the full path of the 'sphinx-build' executable. Alternatively you
22 | echo.may add the Sphinx directory to PATH.
23 | echo.
24 | echo.If you don't have Sphinx installed, grab it from
25 | echo.http://sphinx-doc.org/
26 | exit /b 1
27 | )
28 |
29 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS%
30 | goto end
31 |
32 | :help
33 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS%
34 |
35 | :end
36 | popd
37 |
--------------------------------------------------------------------------------
/docs/media/tutorial_hostguest_analysis_results.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seekrcentral/seekr2/93bf27571b0bdbce8133227538261e4cddc7b137/docs/media/tutorial_hostguest_analysis_results.png
--------------------------------------------------------------------------------
/docs/media/tutorial_hostguest_directory.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seekrcentral/seekr2/93bf27571b0bdbce8133227538261e4cddc7b137/docs/media/tutorial_hostguest_directory.png
--------------------------------------------------------------------------------
/docs/media/tutorial_hostguest_guest.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seekrcentral/seekr2/93bf27571b0bdbce8133227538261e4cddc7b137/docs/media/tutorial_hostguest_guest.png
--------------------------------------------------------------------------------
/docs/media/tutorial_hostguest_host.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seekrcentral/seekr2/93bf27571b0bdbce8133227538261e4cddc7b137/docs/media/tutorial_hostguest_host.png
--------------------------------------------------------------------------------
/docs/media/tutorial_hostguest_koff_conv.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seekrcentral/seekr2/93bf27571b0bdbce8133227538261e4cddc7b137/docs/media/tutorial_hostguest_koff_conv.png
--------------------------------------------------------------------------------
/docs/media/tutorial_hostguest_model_input.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seekrcentral/seekr2/93bf27571b0bdbce8133227538261e4cddc7b137/docs/media/tutorial_hostguest_model_input.png
--------------------------------------------------------------------------------
/docs/media/tutorial_hostguest_pmf.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seekrcentral/seekr2/93bf27571b0bdbce8133227538261e4cddc7b137/docs/media/tutorial_hostguest_pmf.png
--------------------------------------------------------------------------------
/docs/media/tutorial_toy_entropy_barrier.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seekrcentral/seekr2/93bf27571b0bdbce8133227538261e4cddc7b137/docs/media/tutorial_toy_entropy_barrier.png
--------------------------------------------------------------------------------
/docs/media/tutorial_toy_model_input.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seekrcentral/seekr2/93bf27571b0bdbce8133227538261e4cddc7b137/docs/media/tutorial_toy_model_input.png
--------------------------------------------------------------------------------
/docs/media/tutorial_toy_muller_potential.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seekrcentral/seekr2/93bf27571b0bdbce8133227538261e4cddc7b137/docs/media/tutorial_toy_muller_potential.png
--------------------------------------------------------------------------------
/docs/program_options.rst:
--------------------------------------------------------------------------------
1 | Program Options
2 | ===============
3 |
4 | The arguments and inputs of the various SEEKR2 programs are described here.
5 |
6 | .. toctree::
7 | :maxdepth: 1
8 | :caption: Contents:
9 |
10 | program_options_prepare
11 | program_options_run
12 | program_options_analyze
13 | program_options_converge
14 |
--------------------------------------------------------------------------------
/docs/program_options_analyze.rst:
--------------------------------------------------------------------------------
1 | Analyze.py Inputs and Arguments
2 | ===============================
3 |
4 | The analyze.py program takes the data generated from run.py, constructs a
5 | milestoning model, and computes the kinetics and thermodynamics results.
6 |
7 | usage::
8 |
9 | python analyze.py [-h] [-f] [-n NUM_ERROR_SAMPLES] [-p] [-d IMAGE_DIRECTORY]
10 | [-s] MDOEL_FILE
11 |
12 | Required Arguments
13 | ------------------
14 |
15 | **MODEL_FILE**
16 | Provide a path to a file named "model.xml" which can be found
17 | in the tag of the model input file provided to prepare.py.
18 |
19 | Optional Arguments
20 | ------------------
21 |
22 | **-h, --help**
23 | show help message and exit.
24 |
25 | **-f, --force_warning**
26 | By default, missing statistics for any anchors will
27 | generate fatal errors. Analyze.py will attempt to catch these situations early
28 | and abort gracefully. This option will instead raise a warning and attempt
29 | the calculation anyway.
30 |
31 | **-n NUM_ERROR_SAMPLES, --num_error_samples NUM_ERROR_SAMPLES**
32 | Specify the number of error samples to generate for estimating
33 | error/uncertainty of computed values. Default: 1000.
34 |
35 | **-S STRIDE_ERROR_SAMPLES, --stride_error_samples STRIDE_ERROR_SAMPLES**
36 | Specify the number of strides betweensaved error samples. An argument of
37 | None automatically assigns the quantity at the number of milestones in the
38 | model squared. Default: None
39 |
40 | **-K SKIP_ERROR_SAMPLES, --skip_error_samples SKIP_ERROR_SAMPLES**
41 | Specify the number of error samples. An argument of None automatically
42 | assigns the quantity at ten times the number of milestones in the model
43 | squared. Default: None.
44 |
45 | **-d IMAGE_DIRECTORY, --image_directory IMAGE_DIRECTORY**
46 | Define the directory where all plots and images will be saved. By default,
47 | graphics will be saved to the 'images_and_plots/' directory in the model's
48 | anchor root directory.
49 |
50 | **-s, --skip_checks**
51 | By default, post-simulation checks will be run before
52 | the analysis is started, and if the checks fail, the analysis will not proceed.
53 | This argument bypasses those checks and allows the analysis to proceed anyways.
54 |
55 | **-t MINIMUM_TIME, --minimum_time MINIMUM_TIME**
56 | A user may wish to skip an amount of simulation time for each anchor before
57 | counting the transitions for milestoning analysis. Enter the time (in ps) to
58 | skip a portion of the production simulations when performing analysis.
59 |
60 | **-T MAXIMUM_TIME, --maximum_time MAXIMUM_TIME**
61 | A user may wish to stop the analysis of simulation time for each anchor at
62 | a particular time. Enter the time (in ps) at which to end the analysis at
63 | a given anchor if the simulation time exceeds it.
64 |
--------------------------------------------------------------------------------
/docs/program_options_converge.rst:
--------------------------------------------------------------------------------
1 | Converge.py Inputs and Arguments
2 | ================================
3 |
4 | The converge.py program takes the data generated from run.py and provides the
5 | user with information about simulation progress, including the lengths of
6 | simulations, the number of transitions (bounces) against milestones, and
7 | convergence information.
8 |
9 | In addition, the run.py program can be configured to use the output of
10 | converge.py's API to run simulations to convergence.
11 |
12 | usage::
13 |
14 | python converge.py [-h] [-s K_ON_STATE] [-d IMAGE_DIRECTORY] [-c CUTOFF]
15 | [-m MINIMUM_ANCHOR_TRANSITIONS] [-p] MODEL_FILE
16 |
17 |
18 | Required Arguments
19 | ------------------
20 |
21 | **MODEL_FILE**
22 | Provide a path to a file named "model.xml" which can be found
23 | in the tag of the model input file provided to prepare.py.
24 |
25 | Optional Arguments
26 | ------------------
27 |
28 | -h, --help show help message and exit.
29 |
30 | -s K_ON_STATE, --k_on_state K_ON_STATE
31 | Define the bound state (anchor index) that will be used
32 | to compute k-on. If left blank, and k-on statistics
33 | exist, then the first end state in the model will be
34 | chosen by default.
35 |
36 | -d IMAGE_DIRECTORY, --image_directory IMAGE_DIRECTORY
37 | Define the directory where all plots and images will
38 | be saved. By default, graphics will be saved to the
39 | 'images_and_plots/' directory in the model's anchor root
40 | directory.
41 |
42 | -c CUTOFF, --cutoff CUTOFF
43 | The minimum convergence that must be achieved before
44 | concluding that the calculations have converged for a
45 | given anchor.
46 |
47 | -m MINIMUM_ANCHOR_TRANSITIONS, --minimum_anchor_transitions MINIMUM_ANCHOR_TRANSITIONS
48 | Enter a minimum number of transitions that must be
49 | observed per milestone in a given MD anchor as a
50 | criteria for the simulations to be considered converged.
51 |
--------------------------------------------------------------------------------
/docs/program_options_prepare.rst:
--------------------------------------------------------------------------------
1 | Prepare.py Inputs and Arguments
2 | ===============================
3 |
4 | The prepare.py program takes a :doc:`Model Input File` as
5 | input and generates the files necessary to run a SEEKR2 calculation.
6 |
7 | usage::
8 |
9 | python prepare.py [-h] [-f] [-s] MODEL_INPUT_FILE
10 |
11 | Required Arguments
12 | ------------------
13 |
14 | **MODEL_INPUT_FILE**
15 | The name of a model input XML file for a SEEKR2 calculation. Samples model
16 | files can be found in the following locations::
17 |
18 | seekr2/seekr2/data/sample_input_mmvt_openmm.xml
19 | seekr2/seekr2/data/sample_input_mmvt_namd.xml
20 | seekr2/seekr2/data/sample_input_elber_openmm.xml
21 | seekr2/seekr2/data/trypsin_benzamidine_files/input_tryp_ben_mmvt.xml
22 | seekr2/seekr2/data/trypsin_benzamidine_files/input_tryp_ben_elber.xml
23 |
24 | Also, an :doc:`entire page of documentation` is dedicated
25 | to explaining the inputs of the model input file.
26 |
27 | Optional Arguments
28 | ------------------
29 |
30 | **-h, --help**
31 | show help message and exit
32 |
33 | **-f, --force_overwrite**
34 | Toggle whether to overwrite existing simulation
35 | output files within any anchor that might have existed in an old model that
36 | would be overwritten by generating this new model. If not toggled while
37 | attempting to overwrite an old model with a new model, this program will
38 | throw an exception instead of performing any such overwrite.
39 |
40 | **-s, --skip_checks**
41 | By default, pre-simulation checks will be run after
42 | the preparation is complete, and if the checks fail, prepare.py will terminate
43 | and the SEEKR2 model will not be saved. This argument bypasses those checks
44 | and allows the model to be generated regardless of check outcomes.
45 |
--------------------------------------------------------------------------------
/docs/program_options_run.rst:
--------------------------------------------------------------------------------
1 | Run.py Inputs and Arguments
2 | ===========================
3 |
4 | The run.py program controls the MD or BD simulations in a SEEKR2 calculation,
5 | ensuring that they are run with the correct dynamics settings and milestone
6 | boundary definitions, while also generating restart checkpoints. Upon failure,
7 | run.py can restart a simulation automatically from a saved checkpoint.
8 |
9 | As its primary input, the run.py program takes an INSTRUCTION and the path to
10 | a file named "model.xml" (generated by prepare.py). Other options control
11 | various aspects of the simulations.
12 |
13 | usage::
14 |
15 | python run.py [-h] [-c CUDA_DEVICE_INDEX] [-t MIN_TOTAL_SIMULATION_LENGTH]
16 | [-T MAX_TOTAL_SIMULATION_LENGTH] [-C CONVERGENCE_CUTOFF]
17 | [-m MINIMUM_ANCHOR_TRANSITIONS] [-d DIRECTORY] [-f] [-s] [-S]
18 | [-n NAMD_COMMAND] [-a NAMD_ARGUMENTS]
19 | [-b MINIMUM_B_SURFACE_TRAJECTORIES]
20 | [-y MIN_B_SURFACE_ENCOUNTERS] [-L NUM_REV_LAUNCHES] [-u]
21 | INSTRUCTION MODEL_FILE
22 |
23 |
24 | Required Arguments
25 | ------------------
26 |
27 | **INSTRUCTION**
28 | This argument defines which type of dynamics for which anchor
29 | (region of the calculation) should be run. The possible arguments for
30 | INSTRUCTION are listed below:
31 |
32 | **any** - Instruct run.py to run any anchor, whether MD or BD, that still needs
33 | more sampling. The run.py program will attempt to do this in a "smart" manner,
34 | by focusing attention on anchors and regions that are undersampled, based
35 | on transition counts and/or convergence criteria.
36 |
37 | **any_md** - Instruct run.py to run any MD anchor (excluding BD) that still
38 | needs more sampling. This feature can be useful if MD simulations must be
39 | run on a supercomputer or cluster (or a GPU node), while BD must be run on
40 | a different machine (or a CPU node). As with the **any** instruction, run.py
41 | will attempt to be smart about this, and focus on running undersampled
42 | anchors.
43 |
44 | **any_bd** - Instruct run.py to run any unfinished BD simulations (at this
45 | time, this is only the b-surface). As mentioned with the **any_md**
46 | instruction above, this argument can be useful if one wishes to run BD on a
47 | separate machine than MD.
48 |
49 | **(integer value)** - By entering an integer value (Examples: "0", "1", "2",
50 | etc.), the MD anchor with that index will be run to completion or
51 | interruption.
52 |
53 | **b_surface** - Run the b-surface BD simulations.
54 |
55 | **MODEL_FILE**
56 | Provide a path to a file named "model.xml" which can be found
57 | in the tag of the model input file provided to prepare.py.
58 |
59 | Optional Arguments
60 | ------------------
61 | **-h, --help**
62 | Show help message and exit.
63 |
64 | **-c CUDA_DEVICE_INDEX, --cuda_device_index CUDA_DEVICE_INDEX**
65 | Modify which
66 | cuda_device_index to run the MD simulation on. For example, the number 0 would
67 | instruct the MD engine to run using the GPU with the assigned index of 0. To
68 | run on multiple GPU indices, simply enter comma separated indices.
69 | Example: '0,1'. If a value is not supplied, the value in the MODEL_FILE will
70 | be used by default.
71 |
72 | **-t MIN_TOTAL_SIMULATION_LENGTH, --minimum_total_simulation_length MIN_TOTAL_SIMULATION_LENGTH**
73 | Enter a minimum MD simulation length
74 | (in time steps) to run the simulation if a different number of steps are
75 | desired than what is in the "" (MMVT) or
76 | "" (Elber) tags in the MODEL_FILE. Be aware: A
77 | longer simulation may still occur if other specified criteria are not met,
78 | such as the --convergence_cutoff, for example.
79 |
80 | **-T MAX_TOTAL_SIMULATION_LENGTH, --maximum_total_simulation_length MAX_TOTAL_SIMULATION_LENGTH**
81 | Enter the maximum number of MD simulation
82 | timesteps. Simulations will not exceed this length, even if other criteria,
83 | such as --convergence_cutoff are not met.
84 |
85 | **-C CONVERGENCE_CUTOFF, --convergence_cutoff CONVERGENCE_CUTOFF**
86 | Enter a target convergence for each anchor. See the documentation of
87 | converge.py for more detail about how convergence is calculated.
88 |
89 | **-m MINIMUM_ANCHOR_TRANSITIONS, --minimum_anchor_transitions MINIMUM_ANCHOR_TRANSITIONS**
90 | Enter a minimum number of transitions that
91 | must be observed per milestone in a given anchor as a criteria for the
92 | simulations.
93 |
94 | **-d DIRECTORY, --directory DIRECTORY**
95 | Provide the location of the
96 | directory which contains the anchors. If this argument is omitted, then the
97 | directory within the anchor_rootdir setting of the MODEL_FILE will be used.
98 |
99 | **-f, --force_overwrite**
100 | Toggle whether to overwrite existing files within
101 | an anchor. If this option is enabled then the anchor's production directory
102 | will be emptied of all output, trajectory, and backup files for the new
103 | simulation.
104 |
105 | **-s, --save_state_for_all_boundaries**
106 | Toggle whether to save at least one
107 | state file for each boundary until every boundary has been bounced against.
108 | Warning: can generate very large numbers of files.
109 |
110 | **-S, --save_state_file**
111 | Toggle whether to save a state file every time a
112 | bounce occurs. Warning: can generate very large numbers of files.
113 |
114 | **-n NAMD_COMMAND, --namd_command NAMD_COMMAND**
115 | Define a different NAMD
116 | command. This allows users to define a path to NAMD or to use a
117 | 'charmrun namd2' command. By default, 'namd2' is used. Only valid for NAMD
118 | runs.
119 |
120 | **-a NAMD_ARGUMENTS, --namd_arguments NAMD_ARGUMENTS**
121 | Additional arguments
122 | for NAMD can be entered here. Note: this will require quotation marks around
123 | the arguments. Example: -a '+p8 +devices 0,2'. Only valid for NAMD runs.
124 |
125 | **-b MINIMUM_B_SURFACE_TRAJECTORIES, --minimum_b_surface_trajectories MINIMUM_B_SURFACE_TRAJECTORIES**
126 | Enter a minimum number of BD trajectories
127 | to run for the b-surface if a different number of trajectories are desired
128 | than what is indicated in the tag in the
129 | MODEL_FILE. A longer simulation may be run if other specified criteria are
130 | not met, such as the --min_b_surface_encounters, for example.
131 |
132 | **-y MIN_B_SURFACE_ENCOUNTERS, --min_b_surface_encounters MIN_B_SURFACE_ENCOUNTERS**
133 | Enter a minimum number of encounters that must
134 | be observed for the b-surface as a criteria to finish running simulations.
135 |
136 | **-L NUM_REV_LAUNCHES, --num_rev_launches NUM_REV_LAUNCHES**
137 | In Elber milestoning, this parameter defines how many reversals to launch
138 | for each equilibrium configuration generated by the umbrella stage. For each
139 | launch, the positions will be identical, but the velocities will be
140 | resampled from a Maxwell-Boltzmann distribution.
141 |
142 | **-u, --umbrella_restart_mode**
143 | In Elber milestoning, this option allows
144 | one to use the umbrella simulations that already exist in the anchor, and
145 | just re-run the reversals and forwards simulations.
146 |
--------------------------------------------------------------------------------
/docs/requirements.txt:
--------------------------------------------------------------------------------
1 | sphinx-rtd-theme
2 |
--------------------------------------------------------------------------------
/docs/requirements.yaml:
--------------------------------------------------------------------------------
1 | name: docs
2 | channels:
3 | - defaults
4 | dependencies:
5 | # Base depends
6 | - python=3.12
7 | - pip
8 | - cython
9 |
10 | # Pip-only installs
11 | - pip:
12 | - sphinx-autoapi
13 | - sphinx-rtd-theme
14 |
15 |
--------------------------------------------------------------------------------
/docs/running_calculations.rst:
--------------------------------------------------------------------------------
1 | Running Calculations in SEEKR2
2 | ==============================
3 |
4 | This page provides a cursory overview of a typical SEEKR2 calculation.
5 |
6 | SEEKR2 calculations have three distinct stages:
7 |
8 | 1. Prepare
9 | 2. Run
10 | 3. Analyze
11 |
12 | These are the main components, although there can also be more optional
13 | components to a SEEKR calculation.
14 |
15 | Appropriately, in SEEKR2, the programs that accomplish each of these stages
16 | are named:
17 |
18 | 1. prepare.py
19 | 2. run.py
20 | 3. analyze.py
21 |
22 | Prepare
23 | -------
24 |
25 | In order to run the prepare stage, SEEKR2 typically needs a "model input" XML
26 | file. Some examples of input files can be found in the following locations::
27 |
28 | seekr2/seekr2/data/sample_input_mmvt_openmm.xml
29 | seekr2/seekr2/data/sample_input_mmvt_namd.xml
30 | seekr2/seekr2/data/sample_input_elber_openmm.xml
31 |
32 | Inside these files are entries like temperature, type of calculations, system
33 | parameters, and starting atomic positions. This file also defines the
34 | milestone locations and shapes. More information about the structure of
35 | model input files can be found in the
36 | :doc:`Model Input Files` documentation.
37 |
38 | In addition, a number of input parameter, topology, and structure files must
39 | be provided which provide the simulation engines with forcefield information,
40 | starting atomic positions for each of the anchors (for MD), and waterbox
41 | dimensions. Examples of such files can also be found in the seekr2/seekr2/data/
42 | directory::
43 |
44 | seekr2/seekr2/data/hostguest_files
45 |
46 | The prepare.py script typically takes one argument - the model input XML file.
47 | For example::
48 |
49 | python prepare.py data/sample_input_mmvt_openmm.xml
50 |
51 | The script will construct a directory and file tree located at the path
52 | specified by the tag in the model input XML file.
53 |
54 | More arguments to prepare.py can be found by running prepare.py with the "-h"
55 | argument, or by consulting the :doc:`Program Options`
56 | documentation.
57 |
58 | Additionally, more systems and sample input files can be found in the
59 | seekr2_systems repository: https://github.com/seekrcentral/seekr2_systems.git.
60 |
61 | Run
62 | ---
63 |
64 | The prepare stage will generate a filetree of all necessary files and
65 | directories at the location specified by the tag of the
66 | model input file. Within this directory is a file named *model.xml*. The
67 | path to this file will be the argument of most programs used in SEEKR2
68 | in the run stage and beyond.
69 |
70 | *NOTE: the model.xml file is not intended to be modified directly without
71 | re-running prepare.py on the model input file.*
72 |
73 | The run stage is started with the run.py script::
74 |
75 | python run.py any /path/to/root_directory/model.xml
76 |
77 | The word "any" is the INSTRUCTION argument to run.py, and instructs run.py to
78 | run any unfinished MD or BD simulations. One may use "any_md" or "any_bd" as
79 | inputs to INSTRUCTION if one wishes to simulation only unfinished MD or
80 | unfinished BD simulations, respectively. There are many more inputs to
81 | INSTRUCTION and arguments to run.py, and they are all listed in
82 | :doc:`Program Options`.
83 |
84 | Following the run.py command, simulations will run until completion or
85 | interruption. SEEKR saves checkpoints for MD and BD simulations, so if an
86 | interruption occurs, one may re-enter the run.py command and the calculation
87 | will pick up where it left off.
88 |
89 | One may check on the progress and convergence of the calculation with the
90 | converge.py program::
91 |
92 | python converge.py /path/to/root_directory/model.xml
93 |
94 | The program converge.py will also generate convergence plots and images,
95 | which may be found in the "plots_and_images" subfolder of .
96 |
97 | More arguments to both run.py and converge.py can be found by running
98 | either program with the "-h" argument, or by consulting the
99 | :doc:`Program Options` documentation.
100 |
101 | Analyze
102 | -------
103 |
104 | The final stage of a typical SEEKR2 calculation involves analyzing the results
105 | of the simulations to construct the kinetics and thermodynamics of the
106 | process in question.
107 |
108 | The analyze stage is launches with the analyze.py script::
109 |
110 | python analyze.py /path/to/root_directory/model.xml
111 |
112 | The analyze.py script constructs the milestoning model, populates it with the
113 | probabilities and times from the simulations, and computes other quantities,
114 | like the error margins.
115 |
116 | Upon completion, interesting quantities will be printed to the screen, and
117 | more images will be saved in the "plots_and_images" subfolder of
118 | , including a free energy profile (potential of mean force) of
119 | each milestone.
--------------------------------------------------------------------------------
/docs/tutorial.rst:
--------------------------------------------------------------------------------
1 | Tutorials for SEEKR2
2 | ====================
3 |
4 | Follow these tutorials to learn how to use SEEKR2.
5 |
6 | It is assumed that you have completed the installation and tests outlined in the
7 | :doc:`Installation` documentation.
8 |
9 | **Looking for tutorials on how to prepare systems for a SEEKR2 calculation?**
10 | see the Seekrtools tutorials:
11 | https://seekrtools.readthedocs.io/en/latest/tutorial.html
12 |
13 | .. toctree::
14 | :maxdepth: 1
15 | :caption: Contents:
16 |
17 | tutorial1_hostguest
18 | tutorial2_toy_systems
19 |
--------------------------------------------------------------------------------
/docs/tutorial1_hostguest.rst:
--------------------------------------------------------------------------------
1 | Tutorial 1: Host-guest calculation
2 | ==================================
3 |
4 | In this tutorial, we will be performing a sample SEEKR2 calculation to determine
5 | the kinetics of binding between beta-cyclodextrin (the "host") and the small
6 | molecule 1-butanol (the "guest").
7 |
8 | .. figure:: media/tutorial_hostguest_host.png
9 | :align: center
10 |
11 | The beta-cyclodextrin "host" molecule
12 |
13 |
14 | .. figure:: media/tutorial_hostguest_guest.png
15 | :align: center
16 |
17 | The 1-butanol "guest" molecule
18 |
19 | Navigate to the location where the seekr2/ Git repository was cloned, and enter
20 | the repository's program directory and view the available programs::
21 |
22 | cd seekr2/seekr2
23 | ls
24 |
25 | You should see a number of python programs, as well as a few directories. The
26 | first program we will be using is the "prepare.py" script.
27 |
28 | The prepare.py script requires a "model input" file, which is in XML format.
29 | Using Gedit, Vim, or another editor, open up the file
30 | "data/sample_input_mmvt_openmm.xml", which is a sample model input file.
31 |
32 | .. figure:: media/tutorial_hostguest_model_input.png
33 | :align: center
34 |
35 | Model input file of the host-guest system.
36 |
37 | There is a lot of information in here, the details of which are described in
38 | the :doc:`Model Input Files` documentation. For this
39 | tutorial, we will be using this file as-is, for now.
40 |
41 | There are other provided files we need for this SEEKR2 calculation, they are
42 | described here:
43 |
44 | * **data/hostguest_files/hostguest.parm7** - The AMBER parameter/topology file
45 | which contains parameters for the host and guest molecules, as well as the
46 | water molecules comprising the waterbox.
47 |
48 | * **data/hostguest_files/hostguest_at###.pdb** - Each of these files describe
49 | the starting atomic coordinates and box vectors for each of the anchors in the
50 | MD stage. These PDB files were made using an SMD simulation, where the "guest"
51 | was pulled slowly away from the bound state, and the structures were saved
52 | as the guest molecule reached each of the anchor locations.
53 |
54 | * **hostguest_receptor.pqr** - The host molecule (beta-cyclodextrin) for
55 | Browndye input in PQR format.
56 |
57 | * **hostguest_ligand.pqr** - The guest molecule (1-butanol) for
58 | Browndye input in PQR format.
59 |
60 | If you want to use SEEKR2 on a system of your own choosing, you will need to
61 | generate similar input files for it.
62 |
63 |
64 | Next, run prepare.py on the model input file::
65 |
66 | python prepare.py data/sample_input_mmvt_openmm.xml
67 |
68 | For a few minutes, the script will construct a directory and file tree located
69 | at "~/test_mmvt_openmm/". The program may throw a few warnings, but these can
70 | usually be safely ignored, as long as there are no errors or check failures.
71 |
72 | When the command is complete, enter the new directory and see what is there::
73 |
74 | cd ~/test_mmvt_openmm/
75 | ls
76 |
77 | You'll see a number of directories starting with "anchor", as well as a
78 | "b_surface" directory. Let's talk about each of these
79 | files/directories. (Consider viewing the contents of the files and directories
80 | as we talk about them).
81 |
82 | .. figure:: media/tutorial_hostguest_directory.png
83 | :align: center
84 |
85 | The files and directories of a SEEKR2 calculation.
86 |
87 | * **model.xml** - This is arguably the most important file. It contains most of
88 | the high-level information used by later SEEKR2 stages.
89 |
90 | * **anchor_0/, anchor_1/, etc...** - These directories contain the MD
91 | simulation information in two directories:
92 |
93 | * **building/** - This directory contains the parameter/topology and starting
94 | structure files for the MD simulations.
95 |
96 | * **prod/** - This directory will contain the "production" data generated by the
97 | MD simulation, including trajectory data, restart checkpoint files, and,
98 | most importantly, the "bounce" information needed for the MMVT analysis to
99 | extract transition probabilities and times.
100 |
101 | * **b_surface** - This directory contains the input files for BD simulations
102 | starting from the b-surface and either escaping or ending at the BD milestone.
103 |
104 | The preparation stage is complete. Next, we complete the run stage.
105 |
106 | Navigate to the location where the seekr2/ Git repository was cloned, and enter
107 | the repository's program directory and view the available programs again::
108 |
109 | cd seekr2/seekr2
110 | ls
111 |
112 | This time, we will use the run.py program, and we will use the new model.xml
113 | file as the INPUT FILE argument::
114 |
115 | python run.py any ~/test_mmvt_openmm/model.xml
116 |
117 | The keyword "any" is an INSTRUCTION argument which indicates that SEEKR2
118 | should run any unfinished MD or BD calculations.
119 |
120 | Note that SEEKR2 periodically creates checkpoints, so if your calculation
121 | is ever interrupted, the run.py program can just pick right up where it left
122 | off as long as the INSTRUCTION covers the calculation that was interrupted.
123 | This can be very useful if running SEEKR2 on a supercomputer with a queue for
124 | jobs that run only a limited time.
125 |
126 | Since this is the first time you're running this calculation, there are no
127 | simulations yet complete, so SEEKR2 will run all the needed MD and BD
128 | simulations. This is likely to take an hour or two if you have a relatively
129 | fast GPU running OpenMM. (Warning: Without a GPU, this calculation will probably
130 | take a prohibitively long time).
131 |
132 | Once complete, we are finished with the run stage. We can check the progress of
133 | our simulations with the converge.py program::
134 |
135 | python converge.py ~/test_mmvt_openmm/model.xml
136 |
137 | The output will show how many transitions were observed for the various MD and
138 | BD simulations. One can also see additional convergence information.
139 |
140 | Next, let us perform the analysis stage. Return to the SEEKR2 program
141 | directory::
142 |
143 | cd seekr2/seekr2
144 | ls
145 |
146 | To analyze our results, we use the analyze.py program::
147 |
148 | python analyze.py ~/test_mmvt_openmm/model.xml
149 |
150 | After a few minutes, the script should display kinetic and thermodynamic
151 | results (your results will be different due to the stochastic nature of
152 | simulations):
153 |
154 | .. figure:: media/tutorial_hostguest_analysis_results.png
155 | :align: center
156 |
157 | The script analyze.py outputs the kinetics and thermodynamics of binding.
158 |
159 | in addition, we may look at some generated images and plots::
160 |
161 | cd ~/test_mmvt_openmm
162 | cd images_and_plots
163 |
164 | Now use EOG or another visualization program to view the k-off convergence
165 | image::
166 |
167 | eog k_off_convergence.png
168 |
169 | .. figure:: media/tutorial_hostguest_koff_conv.png
170 | :align: center
171 |
172 | Convergence plots can give hints about whether more sampling is needed.
173 |
174 | Next, take a look at the free energy profile (potential of mean force)::
175 |
176 | eog free_energy_profile.png
177 |
178 | .. figure:: media/tutorial_hostguest_pmf.png
179 | :align: center
180 |
181 | The free energy profile (or potential of mean force).
182 |
183 | *NOTE: all of these results were generated using far too little sampling for a
184 | true SEEKR2 calculation, and simulations were cut very short here for
185 | demonstration purposes, so that a SEEKR2 calculation could be completed within
186 | the span of a couple of hours on a desktop computer with a GPU. The results
187 | generated in this tutorial should not be taken seriously.*
188 |
189 | Congratulations! If you've made it to this point successfully, you've completed
190 | a SEEKR2 calculation.
--------------------------------------------------------------------------------
/docs/tutorial2_toy_systems.rst:
--------------------------------------------------------------------------------
1 | Tutorial 2: Toy Systems
2 | =======================
3 |
4 | In this tutorial, we will be performing a SEEKR2 calculation on a "Toy System",
5 | that is - a system with one or few particle(s) that move on a relatively simple
6 | potential energy surface.
7 |
8 | Toy systems can be very useful to benchmark the accuracy of a new method,
9 | to improve conceptual understanding of the interaction between a method and
10 | a real molecular system, or as a teaching tool about a method.
11 |
12 | In this tutorial, we will be using the Entropy Barrier and Muller Potential
13 | toy systems.
14 |
15 | .. figure:: media/tutorial_toy_entropy_barrier.png
16 | :align: center
17 |
18 | The Entropy Barrier toy system
19 |
20 |
21 | .. figure:: media/tutorial_toy_muller_potential.png
22 | :align: center
23 |
24 | The Muller Potential toy system
25 |
26 | Entropy Barrier Toy System
27 | --------------------------
28 |
29 | First, to prepare and run the toy systems, it will be helpful to have a
30 | sample input XML.
31 |
32 | Move to your home directory or other convenient location and clone the
33 | seekr2_systems repository.::
34 |
35 | cd
36 | git clone https://github.com/seekrcentral/seekr2_systems.git
37 |
38 | A number of useful input files can be found in this repository, but we are
39 | going to use the input files in the seekr2_systems/systems/toy_systems/
40 | directory. Let's start by looking at the Entropy Barrier system input.::
41 |
42 | cd seekr2_systems/systems/toy_systems
43 |
44 | Using Gedit, Vim, or another editor, open up the file
45 | "input_entropy_barrier.xml".
46 |
47 | .. figure:: media/tutorial_toy_model_input.png
48 | :align: center
49 |
50 | Model input file of the Entropy Barrier toy system.
51 |
52 | As with the host/guest system, this input file contains all the information
53 | to prepare a SEEKR calculation. Detailed information for all inputs can be
54 | found in :doc:`Model Input Files` and some should be
55 | familiar from :doc:`Tutorial 1`, but I'm going to
56 | highlight a few key changes unique to toy systems.
57 |
58 | First, toy systems require their own kind of collective variable (CV).
59 | Notice that the CV is of a "Toy_cv_input" type, and its anchors are of the
60 | "Toy_cv_anchor" type. Notice that, for a toy system, none of the input
61 | require any files except the Model Input File, which is an advantage to running
62 | toy systems, as opposed to real molecular systems which need starting
63 | coordinate files as well as parameter and topology files.
64 |
65 |
66 | The value "[[0]]" is a Python list of a list, both dimensions of length 1,
67 | and this entry indicates that this CV only keeps track of a single group,
68 | formed of a single atom, and that's atom index 0. Toy systems can have any
69 | number of atoms, and Toy CVs can keep track of any of those atoms as needed.
70 |
71 |
72 | One may change the string representation of the CV's variable by changing
73 | this string. The string "value" should suffice in most any circumstance,
74 | although some CVs use the string "radius" to represent their variables.
75 |
76 |
77 | This expression is used to determine anchor location, as well as to
78 | construct the mathematical milestone expression. In essence, milestones
79 | are constructed along the surfaces where this expression is constant
80 | (isosurfaces). In this case, the milestones are constructed where the
81 | y-coordinate of the first (and only) atom is constant. (OpenMM expressions
82 | start indexing at 1, not 0).
83 |
84 | Within the input_anchor objects:
85 |
86 |
87 | Instead of providing a PDB file as starting positions, for a toy system,
88 | we provide starting coordinates for each of the particles. This input is
89 | a triple-nested list. The outermost layer are "frames" of a toy simulation,
90 | in order to use or test the "swarm" capabilities of MMVT.
91 | The next layer are the particles in a frame of the swarm. Since this toy
92 | system has only one particle, there is only one item in this list. The
93 | final layer are the x,y,z coordinates of the particle. Notice that in the
94 | first input anchor, there are two frames, making a swarm of size two.
95 | In contrast the second anchor has only a single frame. These are in units
96 | of nanometers.
97 |
98 | At the very end of the Model Input file, one can find the
99 | tag. Inside are a number of other settings for the toy system.
100 |
101 |
102 | Define the function of particle positions that describe the potential
103 | energy surface.
104 |
105 |
106 | The total number of particles in this toy system.
107 |
108 |
109 | A list of masses by particle (in units of AMU).
110 |
111 | Create the correct output directory and we are ready to run prepare.py on
112 | the model input file, run, and analyze.::
113 |
114 | mkdir ~/toy_seekr_systems
115 | cd seekr2/seekr2
116 | python prepare.py input_entropy_barrier.xml.xml
117 | python run.py any ~/toy_seekr_systems/entropy_barrier/model.xml
118 | python converge.py ~/toy_seekr_systems/entropy_barrier/model.xml > converge.txt
119 | python analyze.py ~/toy_seekr_systems/entropy_barrier/model.xml > analyze.txt
120 |
121 | All of these commands should work the same for the toy system as they did
122 | for the molecular host/guest system. View converge.txt and analyze.txt in
123 | Gedit, Vim, or another text file viewer/editor.
124 |
125 | One final step involves visualizing the trajectories in the toy system.
126 | The seekr2_systems repository contains some scripts for visualizing the
127 | results of the toy systems.::
128 |
129 | cd ~/seekr2_systems/systems/toy_systems
130 | python entropy_barrier_plot.py
131 |
132 | A video should appear that shows the trajectories moving around the Voronoi
133 | cells of the Entropy Barrier system. At the bottom of the
134 | entropy_barrier_plot.py script, there are some commented lines that will
135 | generate a movie that can be played.
136 |
137 | .. raw:: html
138 |
139 |
140 |
141 | Entropy Barrier MMVT trajectories
142 |
143 | Muller Potential Toy System
144 | ---------------------------
145 |
146 | Let us perform the same calculation using the Muller potential.
147 |
148 | The model input file for the Muller potential can be found in
149 | seekr2_systems/systems/toy_systems. Using Vim, Gedit, or another text
150 | editor, open the file "input_muller_potential.xml". There are a few
151 | key differences between the Muller potential and the Entropy Barrier system.
152 |
153 | In the tag:
154 |
155 |
156 | Now, the tag has been given a new function:
157 | "1.0*y1 - 0.66*x1". This will cause the milestones to be "slanted" in the
158 | coordinate system, unlike the horizontal lines milestones of the Entropy
159 | Barrier system.
160 |
161 |
162 | One may optionally provide the expression that will be used by OpenMM to
163 | construct the milestone surfaces, though this is optional.
164 |
165 | In the tag:
166 |
167 |
168 | A new expression is needed to use the Muller potential energy landscape.
169 |
170 | We will perform the same steps as before.::
171 |
172 | cd seekr2/seekr2
173 | python prepare.py input_muller_potential.xml.xml
174 | python run.py any ~/toy_seekr_systems/muller_potential/model.xml
175 | python converge.py ~/toy_seekr_systems/muller_potential/model.xml > converge.txt
176 | python analyze.py ~/toy_seekr_systems/muller_potential/model.xml > analyze.txt
177 |
178 | Feel free to examine analyze.txt or converge.txt. One may also make a video
179 | of the MMVT simulations in the Muller potential by using the
180 | muller_potential_plot.py program.::
181 |
182 | cd ~/seekr2_systems/systems/toy_systems
183 | python muller_potential_plot.py
184 |
185 | .. raw:: html
186 |
187 |
188 |
189 | Muller Potential MMVT trajectories
--------------------------------------------------------------------------------
/pyproject.toml:
--------------------------------------------------------------------------------
1 | [build-system]
2 | requires = ["setuptools>=61.0", "versioningit~=2.0"]
3 | build-backend = "setuptools.build_meta"
4 |
5 | # Self-descriptive entries which should always be present
6 | [project]
7 | name = "seekr2"
8 | description = "Simulation-Enabled Estimation of Kinetic Rates - Version 2."
9 | dynamic = ["version"]
10 | readme = "README.md"
11 | authors = [
12 | { name = "Lane Votapka", email = "lvotapka@protonmail.com" }
13 | ]
14 | license = { text = "MIT" }
15 | # See https://pypi.org/classifiers/
16 | classifiers = [
17 | "License :: OSI Approved :: MIT License",
18 | "Programming Language :: Python :: 3",
19 | ]
20 | requires-python = ">=3.8"
21 | # Declare any run-time dependencies that should be installed with the package.
22 | dependencies = [
23 | "numpy",
24 | "scipy",
25 | "pyparsing",
26 | "matplotlib",
27 | "nptyping",
28 | "parmed",
29 | "mdtraj",
30 | "pytest",
31 | "abserdes",
32 | "PyGT",
33 | ]
34 |
35 | # Update the urls once the hosting is set up.
36 | [project.urls]
37 | "Source" = "https://github.com/seekrcentral/seekr2"
38 | "Documentation" = "https://seekr2.readthedocs.io"
39 |
40 | [tool.setuptools]
41 | # This subkey is a beta stage development and keys may change in the future, see https://setuptools.pypa.io/en/latest/userguide/pyproject_config.html for more details
42 | #
43 | # As of version 0.971, mypy does not support type checking of installed zipped
44 | # packages (because it does not actually import the Python packages).
45 | # We declare the package not-zip-safe so that our type hints are also available
46 | # when checking client code that uses our (installed) package.
47 | # Ref:
48 | # https://mypy.readthedocs.io/en/stable/installed_packages.html?highlight=zip#using-installed-packages-with-mypy-pep-561
49 | zip-safe = false
50 | # Let setuptools discover the package in the current directory,
51 | # but be explicit about non-Python files.
52 | # See also:
53 | # https://setuptools.pypa.io/en/latest/userguide/pyproject_config.html#setuptools-specific-configuration
54 | # Note that behavior is currently evolving with respect to how to interpret the
55 | # "data" and "tests" subdirectories. As of setuptools 63, both are automatically
56 | # included if namespaces is true (default), even if the package is named explicitly
57 | # (instead of using 'find'). With 'find', the 'tests' subpackage is discovered
58 | # recursively because of its __init__.py file, but the data subdirectory is excluded
59 | # with include-package-data = false and namespaces = false.
60 | include-package-data = true
61 | [tool.setuptools.packages.find]
62 | namespaces = true
63 | where = ["."]
64 |
65 | # Ref https://setuptools.pypa.io/en/latest/userguide/datafiles.html#package-data
66 | [tool.setuptools.package-data]
67 | qmrebind = [
68 | "py.typed",
69 | # Commenting these so that other packages can easily import seekr2 test data.
70 | # "*.dat",
71 | # "*.txt",
72 | # "*.pdb",
73 | # "*.pqr",
74 | # "*.parm7",
75 | # "*.prmtop",
76 | # "*.rst7",
77 | # "*.xml",
78 | ]
79 |
80 | [tool.versioningit]
81 | default-version = "2.1.0"
82 |
83 | [tool.versioningit.format]
84 | distance = "{base_version}+{distance}.{vcs}{rev}"
85 | dirty = "{base_version}+{distance}.{vcs}{rev}.dirty"
86 | distance-dirty = "{base_version}+{distance}.{vcs}{rev}.dirty"
87 |
88 | [tool.versioningit.vcs]
89 | # The method key:
90 | method = "git" # <- The method name
91 | # Parameters to pass to the method:
92 | match = ["*"]
93 | default-tag = "2.1.0"
94 |
95 | [tool.versioningit.write]
96 | file = "seekr2/_version.py"
97 |
98 |
99 |
--------------------------------------------------------------------------------
/seekr2/__init__.py:
--------------------------------------------------------------------------------
1 | __version__ = "{version}"
2 |
3 | __all__ = [
4 | "analyze",
5 | "converge",
6 | "prepare",
7 | "run",
8 | ]
--------------------------------------------------------------------------------
/seekr2/continuous_integration/run_ci.py:
--------------------------------------------------------------------------------
1 | """
2 | Run entire SEEKR2 calculations to test for problems in the
3 | pipeline.
4 | """
5 | import os
6 | import sys
7 | import time
8 | import tempfile
9 |
10 | import seekr2
11 | import seekr2.tests.create_model_input as create_model_input
12 | import seekr2.prepare as prepare
13 | import seekr2.modules.check as check
14 | import seekr2.run as run
15 | import seekr2.converge as converge
16 | import seekr2.modules.common_converge as common_converge
17 | import seekr2.analyze as analyze
18 | from seekr2.modules.common_prepare import Browndye_settings_input, \
19 | MMVT_input_settings, Elber_input_settings
20 | from seekr2.modules.common_base import Ion, Amber_params, Forcefield_params, \
21 | Box_vectors
22 | from seekr2.modules.common_cv import Spherical_cv_anchor, Spherical_cv_input
23 |
24 | def run_short_ci(model_input, cuda_device_index, long_check=True):
25 | start_dir = os.getcwd()
26 | model, xml_path = prepare.prepare(model_input, force_overwrite=False)
27 |
28 | model_dir = os.path.dirname(xml_path)
29 | model.anchor_rootdir = os.path.abspath(model_dir)
30 | check.check_pre_simulation_all(model)
31 | run.run(model, "any", min_b_surface_simulation_length=1000,
32 | num_rev_launches=10, cuda_device_index=cuda_device_index,
33 | save_state_file=True)
34 | data_sample_list, times_dict = converge.converge(model, k_on_state=0)
35 | rmsd_convergence_results = common_converge.calc_RMSD_conv_amount(
36 | model, data_sample_list)
37 | transition_minima, transition_details, transition_times \
38 | = common_converge.calc_transition_steps(
39 | model, data_sample_list[-1])
40 | converge.print_convergence_results(
41 | model, rmsd_convergence_results, cutoff=0.1,
42 | transition_results=transition_details,
43 | transition_time_results=transition_times,
44 | minimum_anchor_transitions=10,
45 | bd_transition_counts=data_sample_list[-1].bd_transition_counts)
46 | check.check_post_simulation_all(model, long_check=long_check)
47 | analysis = analyze.analyze(model)
48 | analysis.print_results()
49 | os.chdir(start_dir)
50 | return
51 |
52 | def run_generic_hostguest_ci(cuda_device_index):
53 | FF = "system"
54 | #FF = "amber"
55 | TIMESTEP = 0.002
56 | #TIMESTEP = 0.004
57 | with tempfile.TemporaryDirectory() as temp_dir:
58 | host_guest_model_input \
59 | = create_model_input.create_host_guest_mmvt_model_input(
60 | temp_dir, ff=FF)
61 | host_guest_model_input.integrator_type = "langevin"
62 | host_guest_model_input.timestep = TIMESTEP
63 | host_guest_model_input.hydrogenMass = 3.0
64 | host_guest_model_input.calculation_settings.md_output_interval = 2000
65 | host_guest_model_input.calculation_settings.md_steps_per_anchor = 20000
66 | run_short_ci(host_guest_model_input, cuda_device_index)
67 |
68 | return
69 |
70 | def run_generic_namd_hostguest_ci(cuda_device_index):
71 | with tempfile.TemporaryDirectory() as temp_dir:
72 | host_guest_model_input \
73 | = create_model_input.create_host_guest_mmvt_model_input(temp_dir)
74 | host_guest_model_input.md_program = "namd"
75 | for input_anchor in host_guest_model_input.cv_inputs[0].input_anchors:
76 | input_anchor.starting_amber_params.prmtop_filename \
77 | = "../data/hostguest_files/hostguest_for_NAMD.parm7"
78 | run_short_ci(host_guest_model_input, cuda_device_index,
79 | long_check=False)
80 |
81 | return
82 |
83 | def run_elber_hostguest_ci(cuda_device_index):
84 | with tempfile.TemporaryDirectory() as temp_dir:
85 | host_guest_model_input \
86 | = create_model_input.create_host_guest_elber_model_input(temp_dir)
87 | run_short_ci(host_guest_model_input, cuda_device_index,
88 | long_check=False)
89 | host_guest_model_input.calculation_type = "elber"
90 |
91 | return
92 |
93 | def run_multisite_sod_ci(cuda_device_index):
94 | with tempfile.TemporaryDirectory() as temp_dir:
95 | sod_model_input \
96 | = create_model_input.create_sod_mmvt_model_input(temp_dir)
97 | run_short_ci(sod_model_input, cuda_device_index, long_check=False)
98 |
99 | return
100 |
101 | def run_doc_api_examples_ci(cuda_device_index):
102 | os.chdir("..")
103 | with tempfile.TemporaryDirectory() as temp_dir:
104 | model_input_filename = "data/sample_input_mmvt_openmm.xml"
105 | model_input = seekr2.prepare.common_prepare.Model_input()
106 | model_input.deserialize(model_input_filename, user_input=True)
107 | # this line not part of API documentation
108 | model_input.root_directory = os.path.join(temp_dir, "test_api_examples")
109 | model, xml_path = seekr2.prepare.prepare(model_input)
110 | model.anchor_rootdir = os.path.dirname(xml_path)
111 | seekr2.modules.check.check_pre_simulation_all(model)
112 | seekr2.run.run(model, "any")
113 | analysis = seekr2.analyze.analyze(model)
114 | analysis.print_results()
115 |
116 | # listing 2
117 | from openmm import unit
118 | new_input_anchor = seekr2.modules.common_cv.Spherical_cv_anchor()
119 | new_input_anchor.radius = 0.1
120 | model_input.cv_inputs[0].input_anchors.insert(1, new_input_anchor)
121 | model, xml_path = seekr2.prepare.prepare(
122 | model_input, force_overwrite=True)
123 | model_input.cv_inputs[0].input_anchors[1].radius \
124 | = 0.11
125 | model, xml_path = seekr2.prepare.prepare(
126 | model_input, force_overwrite=True)
127 |
128 | # listing 3
129 | print(analysis.main_data_sample.Q)
130 | print(analysis.free_energy_profile)
131 |
132 | if __name__ == "__main__":
133 | if len(sys.argv) <= 1:
134 | argument = "short"
135 | else:
136 | argument = sys.argv[1]
137 |
138 | if len(sys.argv) == 3:
139 | cuda_device_index = sys.argv[2]
140 | else:
141 | cuda_device_index = None
142 |
143 | starttime = time.time()
144 | if argument == "short":
145 | run_generic_hostguest_ci(cuda_device_index)
146 | elif argument == "namd":
147 | run_generic_namd_hostguest_ci(cuda_device_index)
148 | elif argument == "elber":
149 | run_elber_hostguest_ci(cuda_device_index)
150 | elif argument == "multisite":
151 | run_multisite_sod_ci(cuda_device_index)
152 | elif argument == "long":
153 | run_generic_hostguest_ci(cuda_device_index)
154 | run_generic_namd_hostguest_ci(cuda_device_index)
155 | run_elber_hostguest_ci(cuda_device_index)
156 | run_multisite_sod_ci(cuda_device_index)
157 | elif argument == "api_examples":
158 | run_doc_api_examples_ci(cuda_device_index)
159 |
160 | print("Time elapsed: {:.3f}".format(time.time() - starttime))
161 | print("Continuous Integration Tests Passed Successfully.")
--------------------------------------------------------------------------------
/seekr2/data/README.md:
--------------------------------------------------------------------------------
1 | # Sample Package Data
2 |
3 | This directory contains sample additional data you may want to include with your package.
4 | This is a place where non-code related additional information (such as data files, molecular structures, etc.) can
5 | go that you want to ship alongside your code.
6 |
7 | Please note that it is not recommended to place large files in your git directory. If your project requires files larger
8 | than a few megabytes in size it is recommended to host these files elsewhere. This is especially true for binary files
9 | as the `git` structure is unable to correctly take updates to these files and will store a complete copy of every version
10 | in your `git` history which can quickly add up. As a note most `git` hosting services like GitHub have a 1 GB per repository
11 | cap.
12 |
13 | ## Including package data
14 |
15 | Modify your package's `setup.py` file and the `setup()` command. Include the
16 | [`package_data`](http://setuptools.readthedocs.io/en/latest/setuptools.html#basic-use) keyword and point it at the
17 | correct files.
18 |
19 | ## Manifest
20 |
21 | * `look_and_say.dat`: first entries of the "Look and Say" integer series, sequence [A005150](https://oeis.org/A005150)
22 |
--------------------------------------------------------------------------------
/seekr2/data/hostguest_files/hostguest_ligand.pqr:
--------------------------------------------------------------------------------
1 | REMARK 1 File generated by pdb2.py by Lane Votapka
2 | ATOM 1 C43 APN 1 0.066 -0.637 1.175 0.3270 1.700
3 | ATOM 2 H71 APN 2 -0.551 0.272 0.871 0.0250 1.300
4 | ATOM 3 H79 APN 3 -0.180 -1.482 0.450 -0.0390 1.300
5 | ATOM 4 O36 APN 4 1.481 -0.393 1.095 -0.6920 1.500
6 | ATOM 5 H80 APN 5 1.741 -0.633 0.125 0.4070 0.800
7 | ATOM 6 C44 APN 6 -0.265 -1.122 2.579 -0.1440 1.700
8 | ATOM 7 H77 APN 7 -0.772 -2.138 2.478 0.0000 1.300
9 | ATOM 8 H78 APN 8 0.678 -1.273 3.200 0.0270 1.300
10 | ATOM 9 C45 APN 9 -1.251 -0.188 3.283 0.2930 1.700
11 | ATOM 10 H72 APN 10 -1.713 0.484 2.486 -0.0510 1.300
12 | ATOM 11 H73 APN 11 -2.101 -0.768 3.774 -0.0530 1.300
13 | ATOM 12 C46 APN 12 -0.539 0.713 4.284 -0.2350 1.700
14 | ATOM 13 H75 APN 13 0.311 1.294 3.793 0.0480 1.300
15 | ATOM 14 H74 APN 14 -0.077 0.041 5.081 0.0430 1.300
16 | ATOM 15 H76 APN 15 -1.273 1.409 4.809 0.0430 1.300
17 |
--------------------------------------------------------------------------------
/seekr2/data/hostguest_files/hostguest_ligand_same_resid.pqr:
--------------------------------------------------------------------------------
1 | REMARK 1 File generated by pdb2.py by Lane Votapka
2 | ATOM 1 C43 APN 1 0.066 -0.637 1.175 0.3270 1.700
3 | ATOM 2 H71 APN 1 -0.551 0.272 0.871 0.0250 1.300
4 | ATOM 3 H79 APN 1 -0.180 -1.482 0.450 -0.0390 1.300
5 | ATOM 4 O36 APN 1 1.481 -0.393 1.095 -0.6920 1.500
6 | ATOM 5 H80 APN 1 1.741 -0.633 0.125 0.4070 0.800
7 | ATOM 6 C44 APN 1 -0.265 -1.122 2.579 -0.1440 1.700
8 | ATOM 7 H77 APN 1 -0.772 -2.138 2.478 0.0000 1.300
9 | ATOM 8 H78 APN 1 0.678 -1.273 3.200 0.0270 1.300
10 | ATOM 9 C45 APN 1 -1.251 -0.188 3.283 0.2930 1.700
11 | ATOM 10 H72 APN 1 -1.713 0.484 2.486 -0.0510 1.300
12 | ATOM 11 H73 APN 1 -2.101 -0.768 3.774 -0.0530 1.300
13 | ATOM 12 C46 APN 1 -0.539 0.713 4.284 -0.2350 1.700
14 | ATOM 13 H75 APN 1 0.311 1.294 3.793 0.0480 1.300
15 | ATOM 14 H74 APN 1 -0.077 0.041 5.081 0.0430 1.300
16 | ATOM 15 H76 APN 1 -1.273 1.409 4.809 0.0430 1.300
17 |
--------------------------------------------------------------------------------
/seekr2/data/hostguest_files/hostguest_output.pdb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seekrcentral/seekr2/93bf27571b0bdbce8133227538261e4cddc7b137/seekr2/data/hostguest_files/hostguest_output.pdb
--------------------------------------------------------------------------------
/seekr2/modules/__init__.py:
--------------------------------------------------------------------------------
1 | __all__ = [
2 | "check",
3 | "common_analyze",
4 | "common_base",
5 | "common_converge",
6 | "common_cv",
7 | "common_prepare",
8 | "common_sim_browndye2",
9 | "common_sim_namd",
10 | "common_sim_openmm",
11 | "elber_analyze",
12 | "elber_sim_openmm",
13 | "filetree",
14 | "markov_chain_monte_carlo",
15 | "mmvt_analyze",
16 | "mmvt_base",
17 | "mmvt_sim_namd",
18 | "mmvt_sim_openmm",
19 | "runner_browndye2",
20 | "runner_namd",
21 | "runner_openmm"
22 | ]
--------------------------------------------------------------------------------
/seekr2/modules/due.py:
--------------------------------------------------------------------------------
1 | # emacs: at the end of the file
2 | # ex: set sts=4 ts=4 sw=4 et:
3 | # ## ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### #
4 | from __future__ import annotations
5 |
6 | from typing import Any
7 |
8 | """
9 |
10 | Stub file for a guaranteed safe import of duecredit constructs: if duecredit
11 | is not available.
12 |
13 | To use it, place it into your project codebase to be imported, e.g. copy as
14 |
15 | cp stub.py /path/tomodule/module/due.py
16 |
17 | Note that it might be better to avoid naming it duecredit.py to avoid shadowing
18 | installed duecredit.
19 |
20 | Then use in your code as
21 |
22 | from .due import due, Doi, BibTeX, Text
23 |
24 | See https://github.com/duecredit/duecredit/blob/master/README.md for examples.
25 |
26 | Origin: Originally a part of the duecredit
27 | Copyright: 2015-2021 DueCredit developers
28 | License: BSD-2
29 | """
30 |
31 | __version__ = "0.0.9"
32 |
33 |
34 | class InactiveDueCreditCollector:
35 | """Just a stub at the Collector which would not do anything"""
36 |
37 | def _donothing(self, *_args: Any, **_kwargs: Any) -> None:
38 | """Perform no good and no bad"""
39 | pass
40 |
41 | def dcite(self, *_args: Any, **_kwargs: Any):
42 | """If I could cite I would"""
43 |
44 | def nondecorating_decorator(func):
45 | return func
46 |
47 | return nondecorating_decorator
48 |
49 | active = False
50 | activate = add = cite = dump = load = _donothing
51 |
52 | def __repr__(self) -> str:
53 | return self.__class__.__name__ + "()"
54 |
55 |
56 | def _donothing_func(*args: Any, **kwargs: Any) -> None:
57 | """Perform no good and no bad"""
58 | pass
59 |
60 |
61 | try:
62 | from duecredit import BibTeX, Doi, Text, Url, due # lgtm [py/unused-import]
63 |
64 | if "due" in locals() and not hasattr(due, "cite"):
65 | raise RuntimeError("Imported due lacks .cite. DueCredit is now disabled")
66 | except Exception as e:
67 | if not isinstance(e, ImportError):
68 | import logging
69 |
70 | logging.getLogger("duecredit").error(
71 | "Failed to import duecredit due to %s" % str(e)
72 | )
73 | # Initiate due stub
74 | due = InactiveDueCreditCollector() # type: ignore
75 | BibTeX = Doi = Url = Text = _donothing_func # type: ignore
76 |
77 | # Emacs mode definitions
78 | # Local Variables:
79 | # mode: python
80 | # py-indent-offset: 4
81 | # tab-width: 4
82 | # indent-tabs-mode: nil
83 | # End:
84 |
--------------------------------------------------------------------------------
/seekr2/modules/elber_cvs/__init__.py:
--------------------------------------------------------------------------------
1 | __all__ = [
2 | "elber_cv_base",
3 | "elber_external_cv",
4 | "elber_spherical_cv",
5 | ]
--------------------------------------------------------------------------------
/seekr2/modules/markov_chain_monte_carlo.py:
--------------------------------------------------------------------------------
1 | """
2 | markov_chain_monte_carlo.py
3 |
4 | Algorithms used to sample distributions of rate matrices for Elber and MMVT
5 | milestoning calculations.
6 |
7 | Citation: Noe, F. "Probability Distributions of molecular observables
8 | computed from Markov models." J. Chem. Phys. 2008, 128, No. 244103.
9 | Distribution is: p(Q|N) = p(Q)p(N|Q)/p(N) =
10 | p(Q) PI(q_ij**N_ij * exp(-q_ij * Ri))
11 | """
12 | import random
13 | from copy import deepcopy
14 |
15 | import numpy as np
16 | from scipy.stats import expon
17 |
18 | def irreversible_stochastic_matrix_algorithm_sample(
19 | Q, N, R, nonzero_indices=None):
20 | """
21 | Sample an additional matrix Q from the distribution using a Monte-Carlo
22 | method. Use a modified version of Algorithm 1 from Noe 2008.
23 | """
24 | MAX_ITER = 1e7
25 | if (not Q.any()) or (not N.any()) or (not R.any()):
26 | return Q
27 | # step 0 - Generate uniform random variables: i,j members of {1,...,m}
28 | m = Q.shape[0]
29 | if nonzero_indices == None:
30 | i = random.choice(range(m))
31 | j = random.choice(range(m))
32 | counter = 0
33 | while (Q[i,j] == 0.0) or (Q[i,i] == 0.0) or (N[i,j] <= 1) \
34 | or (R[i,0] == 0) or (i==j):
35 | i = random.choice(range(m))
36 | j = random.choice(range(m))
37 | counter += 1
38 | if counter > MAX_ITER:
39 | raise Exception("Maximum iterations exceeded.")
40 | else:
41 | i, j = random.choice(nonzero_indices)
42 | assert i!=j, "Cannot choose same indices i and j"
43 |
44 | # step 1 - Initialize the matrix (already done)
45 | Qnew = deepcopy(Q)
46 | # step 2.1 - delta, r between 0 and 1
47 | # delta must be sampled such that when it's subtracted from q_ij, the
48 | # result doesn't go below zero
49 | delta = Q[i,j] * (1.0 - expon.rvs())
50 | random_uniform = random.random()
51 | # step 2.2 - copy Q to a new matrix - already done
52 |
53 | # step 2.3 - Nonreversible element shift
54 | # prior probability: P(Q)
55 | log_prior_probability_old = np.abs(-Qnew[i,j])
56 | log_prior_probability_new = np.abs(-Qnew[i,j] + delta)
57 | if (log_prior_probability_old == 0.0) or (log_prior_probability_new == 0.0):
58 | p_acc = 0.0
59 | else:
60 | log_p_Q_old = N[i,j] * np.log(np.abs(Qnew[i,j])) - Qnew[i,j] * R[i,0]
61 | log_p_Q_new = N[i,j] * np.log(np.abs(Qnew[i,j] - delta)) \
62 | - (Qnew[i,j] - delta) * R[i,0]
63 | p_acc = log_p_Q_new - log_p_Q_old + log_prior_probability_new \
64 | - log_prior_probability_old
65 |
66 | if np.log(random_uniform) <= p_acc:
67 | #log(r) can be directly compared to
68 | # log-likelihood acceptance, p_acc
69 | Qnew[i,i] = Qnew[i,i] + delta
70 | Qnew[i,j] = Qnew[i,j] - delta
71 |
72 | return Qnew
--------------------------------------------------------------------------------
/seekr2/modules/mmvt_base.py:
--------------------------------------------------------------------------------
1 | """
2 | Exists only for backwards-compatibility.
3 | """
4 |
5 | from seekr2.modules.mmvt_cvs.mmvt_cv_base import MMVT_settings
6 | from seekr2.modules.mmvt_cvs.mmvt_cv_base import MMVT_anchor
7 | from seekr2.modules.mmvt_cvs.mmvt_cv_base import MMVT_toy_anchor
8 | from seekr2.modules.mmvt_cvs.mmvt_spherical_cv import MMVT_spherical_CV
9 | from seekr2.modules.mmvt_cvs.mmvt_tiwary_cv import MMVT_tiwary_CV
10 | from seekr2.modules.mmvt_cvs.mmvt_planar_cv import MMVT_planar_CV
11 | from seekr2.modules.mmvt_cvs.mmvt_rmsd_cv import MMVT_RMSD_CV
12 | from seekr2.modules.mmvt_cvs.mmvt_closest_pair_cv import MMVT_closest_pair_CV
13 | from seekr2.modules.mmvt_cvs.mmvt_count_contacts_cv import MMVT_count_contacts_CV
14 | from seekr2.modules.mmvt_cvs.mmvt_external_cv import MMVT_external_CV
15 | from seekr2.modules.mmvt_cvs.mmvt_voronoi_cv import MMVT_Voronoi_CV
--------------------------------------------------------------------------------
/seekr2/modules/mmvt_cvs/__init__.py:
--------------------------------------------------------------------------------
1 | __all__ = [
2 | "mmvt_closest_pair_cv",
3 | "mmvt_count_contacts_cv",
4 | "mmvt_cv_base",
5 | "mmvt_external_cv",
6 | "mmvt_planar_cv",
7 | "mmvt_rmsd_cv",
8 | "mmvt_spherical_cv",
9 | "mmvt_tiwary_cv",
10 | "mmvt_voronoi_cv",
11 | ]
--------------------------------------------------------------------------------
/seekr2/prepare.py:
--------------------------------------------------------------------------------
1 | """
2 | prepare.py
3 |
4 | Accept a model input file and other arguments and settings for creating a
5 | SEEKR2 calculation. Generated files including the model.xml file as well as
6 | the entire filetree.
7 | """
8 |
9 | import os
10 | import argparse
11 |
12 | import seekr2.modules.common_base as base
13 | import seekr2.modules.common_prepare as common_prepare
14 | import seekr2.modules.filetree as filetree
15 | import seekr2.modules.check as check
16 | # Don't remove the following library imports - needed by deserializer
17 | from seekr2.modules.common_prepare import Browndye_settings_input, \
18 | MMVT_input_settings, Elber_input_settings, Toy_settings_input
19 | from seekr2.modules.common_base import Ion, Amber_params, Forcefield_params, \
20 | Charmm_params, Box_vectors
21 | from seekr2.modules.common_cv import Spherical_cv_anchor, Spherical_cv_input, \
22 | Tiwary_cv_anchor, Tiwary_cv_input, Tiwary_cv_distance_order_parameter, \
23 | Tiwary_cv_angle_order_parameter, Tiwary_cv_torsion_order_parameter, \
24 | RMSD_cv_input, RMSD_cv_anchor, Toy_cv_input, Toy_cv_anchor, \
25 | Z_distance_cv_anchor, Z_distance_cv_input, Grid_combo, \
26 | State_point, Voronoi_cv_input, Voronoi_cv_anchor, Voronoi_cv_toy_anchor, \
27 | Closest_pair_cv_input, Closest_pair_cv_anchor, Count_contacts_cv_input, \
28 | Count_contacts_cv_anchor
29 |
30 | def prepare(model_input, force_overwrite=False):
31 | """
32 | Using the Model_input from the user, prepare the Model
33 | object and the filetree. Then prepare all building files
34 | for each anchor and serialize the Model to XML.
35 | """
36 | curdir = os.getcwd()
37 | model = common_prepare.model_factory(model_input)
38 | root_directory = os.path.abspath(
39 | os.path.expanduser(model_input.root_directory))
40 | model_input.root_directory = root_directory
41 | filetree.generate_filetree_root(model, root_directory)
42 |
43 | xml_path = os.path.join(root_directory, "model.xml")
44 | common_prepare.prepare_model_cvs_and_anchors(model, model_input,
45 | force_overwrite)
46 | filetree.generate_filetree_bd(model, root_directory)
47 | filetree.copy_bd_files(model, model_input, root_directory)
48 | common_prepare.generate_bd_files(model, root_directory)
49 | #model.serialize(xml_path)
50 | base.save_model(model, xml_path)
51 | os.chdir(curdir)
52 | return model, xml_path
53 |
54 | if __name__ == "__main__":
55 | argparser = argparse.ArgumentParser(description=__doc__)
56 | argparser.add_argument(
57 | "model_input_file", metavar="MODEL_INPUT_FILE", type=str,
58 | help="The name of input XML file for a SEEKR2 calculation.")
59 |
60 | argparser.add_argument(
61 | "-f", "--force_overwrite", dest="force_overwrite", default=False,
62 | help="Toggle whether to overwrite existing simulation output files "\
63 | "within any anchor that might have existed in an old model that would "\
64 | "be overwritten by generating this new model. If not toggled, this "\
65 | "program will throw an exception instead of performing any such "\
66 | "overwrite.", action="store_true")
67 | argparser.add_argument(
68 | "-s", "--skip_checks", dest="skip_checks", default=False,
69 | help="By default, pre-simulation checks will be run after the "\
70 | "preparation is complete, and if the checks fail, the SEEKR2 "\
71 | "model will not be saved. This argument bypasses those "\
72 | "checks and allows the model to be generated anyways.",
73 | action="store_true")
74 | args = argparser.parse_args() # parse the args into a dictionary
75 | args = vars(args)
76 | model_input_filename = args["model_input_file"]
77 | force_overwrite = args["force_overwrite"]
78 | skip_checks = args["skip_checks"]
79 | model_input = common_prepare.Model_input()
80 | model_input.deserialize(model_input_filename, user_input=True)
81 | model, xml_path = prepare(model_input, force_overwrite)
82 | if model.anchor_rootdir == ".":
83 | model_dir = os.path.dirname(xml_path)
84 | model.anchor_rootdir = os.path.abspath(model_dir)
85 | if not skip_checks:
86 | check.check_pre_simulation_all(model)
--------------------------------------------------------------------------------
/seekr2/tests/__init__.py:
--------------------------------------------------------------------------------
1 | """
2 | Empty init file in case you choose a package besides PyTest such as Nose which may look for such a file
3 | """
4 |
--------------------------------------------------------------------------------
/seekr2/tests/create_toy_system.py:
--------------------------------------------------------------------------------
1 | """
2 | create_toy_system.py
3 |
4 | For creating systems of dummy particles that can be used to test
5 | boundary and restraining forces, etc.
6 |
7 | """
8 |
9 | import numpy as np
10 |
11 | try:
12 | import openmm.unit as unit
13 | except ImportError:
14 | import simtk.unit as unit
15 |
16 | try:
17 | import openmm
18 | except ImportError:
19 | import simtk.openmm as openmm
20 |
21 | try:
22 | import openmm.app as openmm_app
23 | except ImportError:
24 | import simtk.openmm.app as openmm_app
25 |
26 | import seekr2.modules.mmvt_cvs.mmvt_closest_pair_cv as mmvt_closest_pair_cv
27 |
28 | def make_toy_system_and_topology(num_particles):
29 | """
30 | Make openmm system and topology files for use with a toy system
31 | with n_particles.
32 | """
33 | system = openmm.System()
34 | topology = openmm_app.Topology()
35 | for i in range(num_particles):
36 | mass = 10.0 * openmm.unit.amu
37 | system.addParticle(mass)
38 | atom_name = "X{}".format(i)
39 | if not atom_name in openmm_app.element.Element._elements_by_symbol:
40 | element = openmm_app.element.Element(0, atom_name, atom_name, mass)
41 | else:
42 | element = openmm_app.element.Element._elements_by_symbol[atom_name]
43 | chain = topology.addChain()
44 | residue = topology.addResidue("UNK", chain)
45 | topology.addAtom(atom_name, element, residue)
46 |
47 | return system, topology
48 |
49 | def make_toy_simulation_and_context(system, topology, positions):
50 | integrator = openmm.LangevinIntegrator(
51 | 300.0*unit.kelvin, 1.0/unit.picoseconds, 0.002*unit.picoseconds)
52 | ref_platform = openmm.Platform.getPlatformByName('Reference')
53 | ref_properties = {}
54 | simulation = openmm_app.Simulation(
55 | topology, system, integrator, ref_platform, ref_properties)
56 | simulation.context.setPositions(positions)
57 | simulation.context.setVelocitiesToTemperature(300.0*unit.kelvin)
58 | return simulation
59 |
60 | def assign_nonbonded_cv_info(cv, system, box_vectors, cutoff=None):
61 | """
62 | Update the cv with the correct nonbonded information.
63 | """
64 | cv.num_system_particles = system.getNumParticles()
65 | #forces = { force.__class__.__name__ : force for force in system.getForces() }
66 | #reference_force = forces['NonbondedForce']
67 | cv.exclusion_pairs = []
68 | #for index in range(reference_force.getNumExceptions()):
69 | # [iatom, jatom, chargeprod, sigma, epsilon] \
70 | # = reference_force.getExceptionParameters(index)
71 | # cv.exclusion_pairs.append((iatom, jatom))
72 |
73 | if cutoff is None:
74 | cv.cutoff_distance = 0.4 * box_vectors.get_min_length()
75 | else:
76 | cv.cutoff_distance = cutoff
77 | print("cv.cutoff_distance:", cv.cutoff_distance)
78 |
79 | return
--------------------------------------------------------------------------------
/seekr2/tests/data/ala_ala_ala.pdb:
--------------------------------------------------------------------------------
1 | REMARK *
2 | REMARK DATE: 8/ 5/ 9 14:44:19 CREATED BY USER: mjw
3 | CRYST1 61.208 61.208 85.000 90.00 90.00 90.00 1
4 | ATOM 1 N ALA 1 0.024 -0.103 -0.101 1.00 0.00 AAL
5 | ATOM 2 HT1 ALA 1 0.027 -1.132 -0.239 1.00 0.00 AAL
6 | ATOM 3 HT2 ALA 1 -0.805 0.163 0.471 1.00 0.00 AAL
7 | ATOM 4 HT3 ALA 1 -0.059 0.384 -1.019 1.00 0.00 AAL
8 | ATOM 5 CA ALA 1 1.247 0.375 0.636 1.00 0.00 AAL
9 | ATOM 6 HA ALA 1 0.814 0.861 1.495 1.00 0.00 AAL
10 | ATOM 7 CB ALA 1 2.057 -0.772 1.289 1.00 0.00 AAL
11 | ATOM 8 HB1 ALA 1 3.136 -0.752 1.032 1.00 0.00 AAL
12 | ATOM 9 HB2 ALA 1 1.990 -0.641 2.395 1.00 0.00 AAL
13 | ATOM 10 HB3 ALA 1 1.656 -1.782 1.063 1.00 0.00 AAL
14 | ATOM 11 C ALA 1 1.956 1.579 0.036 1.00 0.00 AAL
15 | ATOM 12 O ALA 1 1.219 2.525 -0.201 1.00 0.00 AAL
16 | ATOM 13 N ALA 2 3.289 1.631 -0.202 1.00 0.00 AAL
17 | ATOM 14 HN ALA 2 3.939 0.868 -0.174 1.00 0.00 AAL
18 | ATOM 15 CA ALA 2 3.990 2.909 -0.215 1.00 0.00 AAL
19 | ATOM 16 HA ALA 2 3.742 3.440 0.695 1.00 0.00 AAL
20 | ATOM 17 CB ALA 2 3.662 3.802 -1.434 1.00 0.00 AAL
21 | ATOM 18 HB1 ALA 2 4.192 4.778 -1.358 1.00 0.00 AAL
22 | ATOM 19 HB2 ALA 2 3.956 3.311 -2.382 1.00 0.00 AAL
23 | ATOM 20 HB3 ALA 2 2.577 4.027 -1.467 1.00 0.00 AAL
24 | ATOM 21 C ALA 2 5.487 2.654 -0.128 1.00 0.00 AAL
25 | ATOM 22 O ALA 2 5.889 1.489 -0.137 1.00 0.00 AAL
26 | ATOM 23 N ALA 3 6.275 3.733 -0.037 1.00 0.00 AAL
27 | ATOM 24 HN ALA 3 5.963 4.691 -0.028 1.00 0.00 AAL
28 | ATOM 25 CA ALA 3 7.707 3.802 0.068 1.00 0.00 AAL
29 | ATOM 26 HA ALA 3 8.160 3.418 -0.833 1.00 0.00 AAL
30 | ATOM 27 CB ALA 3 8.233 3.093 1.333 1.00 0.00 AAL
31 | ATOM 28 HB1 ALA 3 9.342 3.149 1.356 1.00 0.00 AAL
32 | ATOM 29 HB2 ALA 3 7.835 3.593 2.240 1.00 0.00 AAL
33 | ATOM 30 HB3 ALA 3 7.923 2.030 1.332 1.00 0.00 AAL
34 | ATOM 31 C ALA 3 8.018 5.323 0.136 1.00 0.00 AAL
35 | ATOM 32 OT1 ALA 3 7.032 6.119 0.127 1.00 0.00 AAL
36 | ATOM 33 OT2 ALA 3 9.219 5.692 0.188 1.00 0.00 AAL
37 | TER 34 ALA 3
38 | END
39 |
--------------------------------------------------------------------------------
/seekr2/tests/data/ligand_for_test.pqr:
--------------------------------------------------------------------------------
1 | REMARK 1 File generated by pdb2.py by Lane Votapka
2 | ATOM 1 C43 APN 1 0.066 -0.637 1.175 0.3270 1.700
3 | ATOM 2 H71 APN 2 -0.551 0.272 0.871 0.0250 1.300
4 | ATOM 3 H79 APN 3 -0.180 -1.482 0.450 -0.0390 1.300
5 | ATOM 4 O36 APN 4 1.481 -0.393 1.095 -0.6920 1.500
6 | ATOM 5 H80 APN 5 1.741 -0.633 0.125 0.4070 0.800
7 | ATOM 6 C44 APN 6 -0.265 -1.122 2.579 -0.1440 1.700
8 | ATOM 7 H77 APN 7 -0.772 -2.138 2.478 0.0000 1.300
9 | ATOM 8 H78 APN 8 0.678 -1.273 3.200 0.0270 1.300
10 | ATOM 9 C45 APN 9 -1.251 -0.188 3.283 0.2930 1.700
11 | ATOM 10 H72 APN 10 -1.713 0.484 2.486 -0.0510 1.300
12 | ATOM 11 H73 APN 11 -2.101 -0.768 3.774 -0.0530 1.300
13 | ATOM 12 C46 APN 12 -0.539 0.713 4.284 -0.2350 1.700
14 | ATOM 13 H75 APN 13 0.311 1.294 3.793 0.0480 1.300
15 | ATOM 14 H74 APN 14 -0.077 0.041 5.081 0.0430 1.300
16 | ATOM 15 H76 APN 15 -1.273 1.409 4.809 0.0430 1.300
17 |
--------------------------------------------------------------------------------
/seekr2/tests/data/sample_bd_milestone_results.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 1.0005
4 | 1.79769e+308
5 | 78
6 | 0.000142
7 | 0.243
8 | 1
9 |
10 | 1
11 |
12 | 0.2
13 | 0.05
14 | 0
15 | 0
16 |
17 |
18 | 17.3332
19 | 11.2152
20 | 2
21 |
22 |
23 | 100000
24 | 0
25 | 54070
26 |
27 | b_13
28 | 65239
29 |
30 |
31 | 13_12
32 | 45930
33 |
34 |
35 | 181617390
36 |
37 |
--------------------------------------------------------------------------------
/seekr2/tests/data/sample_bd_results_file.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 1
4 | 8.75563
5 | 78
6 | 0.000142
7 | 0.243
8 | 1
9 |
10 | 1
11 |
12 | 0.2
13 | 0.05
14 | 0
15 | 0
16 |
17 |
18 | 71.957
19 | 43.1749
20 | 1
21 |
22 |
23 | 100000
24 | 0
25 | 95447
26 |
27 | b_10
28 | 4553
29 |
30 |
31 | 805045002
32 |
33 |
--------------------------------------------------------------------------------
/seekr2/tests/data/sample_bd_results_file2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 1.0005
4 | 1.79769e+308
5 | 78
6 | 0.000142
7 | 0.243
8 | 1
9 |
10 | 1
11 |
12 | 0.2
13 | 0.05
14 | 0
15 | 0
16 |
17 |
18 | 17.3332
19 | 11.2152
20 | 2
21 |
22 |
23 | 100000
24 | 0
25 | 54070
26 |
27 | b_12
28 | 65239
29 |
30 |
31 | 12_11
32 | 45930
33 |
34 |
35 | 181617390
36 |
37 |
--------------------------------------------------------------------------------
/seekr2/tests/data/test_analyze_output_elber.txt:
--------------------------------------------------------------------------------
1 | #"Crossed boundary ID","crossing counter","total time (ps)"
2 | # An asterisk(*) indicates that source milestone was never crossed - asterisked statistics are invalid and should be excluded.
3 | 3,2,0.11
4 | 3*,3,0.482
5 | 3,5,0.296
6 | 3,6,0.12
7 | 1,7,0.164
8 | 1,10,0.124
9 | 1*,11,0.358
10 | 3,14,0.084
11 | 1,15,0.178
12 | 3,18,0.248
--------------------------------------------------------------------------------
/seekr2/tests/data/test_analyze_outputfile_checkpoint1.txt:
--------------------------------------------------------------------------------
1 | #"Bounced boundary ID","bounce index","total time (ps)"
2 | CHECKPOINT,41.000
3 | 1,0,41.222000000004414
4 | 2,1,41.728000000005032
5 | CHECKPOINT,42.000
6 | CHECKPOINT,43.000
7 | 1,2,43.222000000006858
8 | 1,3,43.964000000007765
9 | CHECKPOINT,44.000
10 | 1,4,44.600000000008542
11 | 1,5,44.954000000008975
12 | CHECKPOINT,45.000
13 | 1,6,45.256000000009344
14 | CHECKPOINT,46.000
15 | 1,6,46.256000000009344
16 |
--------------------------------------------------------------------------------
/seekr2/tests/data/test_analyze_outputfile_checkpoint2.txt:
--------------------------------------------------------------------------------
1 | #"Bounced boundary ID","bounce index","total time (ps)"
2 | CHECKPOINT,46.000
3 | 1,6,46.356000000009344
4 | 1,7,46.534000000009684
5 | 1,8,46.930000000010168
6 | CHECKPOINT,47.000
7 | 1,9,47.306000000010627
8 |
--------------------------------------------------------------------------------
/seekr2/tests/data/test_analyze_outputfile_namd.txt:
--------------------------------------------------------------------------------
1 | #"Bounced boundary ID","bounce index","total time (ps)"
2 | SEEKR: Cell Collision: current: 1, new: 0, stepnum: 110
3 | SEEKR: Milestone Transition: anchor: 1, source: none, destination: 0, stepnum: 110, incubation steps: 110
4 | SEEKR: Cell Collision: current: 1, new: 2, stepnum: 115
5 | SEEKR: Milestone Transition: anchor: 1, source: 0, destination: 1, stepnum: 115, incubation steps: 5
6 | SEEKR: Cell Collision: current: 1, new: 0, stepnum: 120
7 | SEEKR: Milestone Transition: anchor: 1, source: 1, destination: 0, stepnum: 120, incubation steps: 5
8 | SEEKR: Cell Collision: current: 1, new: 0, stepnum: 125
9 | SEEKR: Cell Collision: current: 1, new: 0, stepnum: 130
10 | SEEKR: Cell Collision: current: 1, new: 0, stepnum: 135
11 | SEEKR: Cell Collision: current: 1, new: 0, stepnum: 140
12 | SEEKR: Cell Collision: current: 1, new: 0, stepnum: 145
13 | SEEKR: Cell Collision: current: 1, new: 0, stepnum: 150
14 | SEEKR: Cell Collision: current: 1, new: 0, stepnum: 155
--------------------------------------------------------------------------------
/seekr2/tests/data/test_analyze_outputfile_namd_checkpoint1.txt:
--------------------------------------------------------------------------------
1 | SEEKR: Cell Collision: current: 1, new: 0, stepnum: 110
2 | SEEKR: Milestone Transition: anchor: 1, source: none, destination: 0, stepnum: 110, incubation steps: 110
3 | SEEKR: Cell Collision: current: 1, new: 2, stepnum: 115
4 | SEEKR: Milestone Transition: anchor: 1, source: 0, destination: 1, stepnum: 115, incubation steps: 5
5 | SEEKR: Cell Collision: current: 1, new: 0, stepnum: 120
6 | SEEKR: Milestone Transition: anchor: 1, source: 1, destination: 0, stepnum: 120, incubation steps: 5
7 | CHECKPOINTING AT STEP 120
8 | SEEKR: Cell Collision: current: 1, new: 0, stepnum: 125
9 | SEEKR: Cell Collision: current: 1, new: 0, stepnum: 130
10 | SEEKR: Cell Collision: current: 1, new: 0, stepnum: 135
11 | CHECKPOINTING AT STEP 140
12 | SEEKR: Cell Collision: current: 1, new: 0, stepnum: 140
13 | SEEKR: Cell Collision: current: 1, new: 0, stepnum: 145
14 |
--------------------------------------------------------------------------------
/seekr2/tests/data/test_analyze_outputfile_namd_checkpoint2.txt:
--------------------------------------------------------------------------------
1 | SEEKR: Cell Collision: current: 1, new: 0, stepnum: 142
2 | SEEKR: Cell Collision: current: 1, new: 0, stepnum: 147
3 | SEEKR: Cell Collision: current: 1, new: 0, stepnum: 150
4 | SEEKR: Cell Collision: current: 1, new: 0, stepnum: 155
5 |
--------------------------------------------------------------------------------
/seekr2/tests/data/test_analyze_outputfile_namd_restart1.txt:
--------------------------------------------------------------------------------
1 | SEEKR: Cell Collision: current: 1, new: 0, stepnum: 110
2 | SEEKR: Milestone Transition: anchor: 1, source: none, destination: 0, stepnum: 110, incubation steps: 110
3 | SEEKR: Cell Collision: current: 1, new: 2, stepnum: 115
4 | SEEKR: Milestone Transition: anchor: 1, source: 0, destination: 1, stepnum: 115, incubation steps: 5
5 | SEEKR: Cell Collision: current: 1, new: 0, stepnum: 120
6 | SEEKR: Milestone Transition: anchor: 1, source: 1, destination: 0, stepnum: 120, incubation steps: 5
7 | SEEKR: Cell Collision: current: 1, new: 0, stepnum: 125
8 | SEEKR: Cell Collision: current: 1, new: 0, stepnum: 130
9 | SEEKR: Cell Collision: current: 1, new: 0, stepnum: 135
10 | SEEKR: Cell Collision: current: 1, new: 0, stepnum: 140
11 | SEEKR: Cell Collision: current: 1, new: 0, stepnum: 145
12 |
--------------------------------------------------------------------------------
/seekr2/tests/data/test_analyze_outputfile_namd_restart2.txt:
--------------------------------------------------------------------------------
1 | SEEKR: Cell Collision: current: 1, new: 0, stepnum: 140
2 | SEEKR: Cell Collision: current: 1, new: 0, stepnum: 145
3 | SEEKR: Cell Collision: current: 1, new: 0, stepnum: 150
4 | SEEKR: Cell Collision: current: 1, new: 0, stepnum: 155
5 |
--------------------------------------------------------------------------------
/seekr2/tests/data/test_analyze_outputfile_restart1.txt:
--------------------------------------------------------------------------------
1 | #"Bounced boundary ID","bounce index","total time (ps)"
2 | 1,0,41.222000000004414
3 | 2,1,41.728000000005032
4 | 1,2,43.222000000006858
5 | 1,3,43.964000000007765
6 | 1,4,44.600000000008542
7 | 1,5,44.954000000008975
8 | 1,6,45.256000000009344
--------------------------------------------------------------------------------
/seekr2/tests/data/test_analyze_outputfile_restart2.txt:
--------------------------------------------------------------------------------
1 | #"Bounced boundary ID","bounce index","total time (ps)"
2 | 1,5,44.954000000008975
3 | 1,6,45.256000000009344
4 | 1,7,45.534000000009684
5 | 1,8,45.930000000010168
6 | 1,9,46.306000000010627
--------------------------------------------------------------------------------
/seekr2/tests/data/test_analyze_statistics.txt:
--------------------------------------------------------------------------------
1 | N_alpha_1: 2423
2 | N_alpha_2: 98
3 | N_1_1_alpha: 0
4 | N_1_2_alpha: 52
5 | N_2_1_alpha: 52
6 | N_2_2_alpha: 0
7 | R_1_alpha: 1658.6959999999933
8 | R_2_alpha: 198.91199999999188
9 | T_alpha: 1954.7599999666209
10 |
--------------------------------------------------------------------------------
/seekr2/tests/data/test_namd.xsc:
--------------------------------------------------------------------------------
1 | # NAMD extended system configuration output file
2 | #$LABELS step a_x a_y a_z b_x b_y b_z c_x c_y c_z o_x o_y o_z
3 | 1000 61.359 0 0 -20.451768 57.850256 0 -20.451768 -28.922514 50.1013 0 0 0
4 |
--------------------------------------------------------------------------------
/seekr2/tests/pytest.ini:
--------------------------------------------------------------------------------
1 | # pytest.ini
2 | [pytest]
3 | markers =
4 | needs_cuda: marks tests as needing CUDA to run.
--------------------------------------------------------------------------------
/seekr2/tests/test_check.py:
--------------------------------------------------------------------------------
1 | """
2 | test_check.py
3 | """
4 |
5 | from seekr2.modules import check
6 |
7 | def test_toy_check_systems_within_Voronoi_cells_elber(toy_elber_model):
8 | check.check_systems_within_Voronoi_cells(toy_elber_model)
--------------------------------------------------------------------------------
/seekr2/tests/test_common_base.py:
--------------------------------------------------------------------------------
1 | """
2 | test_common_base.py
3 | """
4 | import os
5 | import pytest
6 | import random
7 |
8 | import numpy as np
9 | from parmed import unit
10 |
11 | import seekr2.modules.common_base as base
12 |
13 | TEST_DIRECTORY = os.path.dirname(__file__)
14 |
15 | def test_strBool():
16 | assert base.strBool('True') == True
17 | assert base.strBool('true') == True
18 | assert base.strBool('TRUE') == True
19 | assert base.strBool('False') == False
20 | assert base.strBool('false') == False
21 | assert base.strBool('FALSE') == False
22 | with pytest.raises(Exception):
23 | base.strBool('balderdash')
24 | return
25 |
26 | def test_order_files_numerically():
27 | string_list = ["/path/to/anchor0/output0_0", "/path/to/anchor0/output0_1",
28 | "/path/to/anchor0/output0_2", "/path/to/anchor0/output1_0",
29 | "/path/to/anchor0/output1_1", "/path/to/anchor0/output1_2",
30 | "/path/to/anchor1/output0_0", "/path/to/anchor1/output0_1",
31 | "/path/to/anchor1/output2_0", "/path/to/anchor1/output10_0"]
32 | desired_list = string_list[:]
33 | random.shuffle(string_list)
34 | ordered_list = base.order_files_numerically(string_list)
35 |
36 | for item1, item2 in zip(ordered_list, desired_list):
37 | assert item1==item2
38 |
39 | scrambled_list = ["me2.345.pdb", "me1.234.pdb", "me-3.456.pdb"]
40 | correct_list = ["me-3.456.pdb", "me1.234.pdb", "me2.345.pdb"]
41 | ordered_list = base.order_files_numerically(scrambled_list, func=float)
42 | for item1, item2 in zip(ordered_list, correct_list):
43 | assert item1==item2
44 |
45 | string_list = ["mmvt.restart1.out", "mmvt.restart2.out"]
46 | desired_list = string_list[:]
47 | random.shuffle(string_list)
48 | ordered_list = base.order_files_numerically(string_list)
49 |
50 | for item1, item2 in zip(ordered_list, desired_list):
51 | assert item1==item2
52 |
53 | string_list = ["/path/to/anchor_0.1/output0_0",
54 | "/path/to/anchor_0.2/output0_1"]
55 |
56 | desired_list = string_list[:]
57 | random.shuffle(string_list)
58 | ordered_list = base.order_files_numerically(string_list)
59 |
60 | return
61 |
62 | def test_box_vectors():
63 | box_vector_q = unit.Quantity(
64 | [[64.9127105, 0.0, 0.0],
65 | [-21.6375684, 61.2002909, 0.0],
66 | [-21.6375684, -30.6001417, 53.0010088]],
67 | unit=unit.angstrom)
68 | box_vector = base.Box_vectors()
69 | box_vector.from_quantity(box_vector_q)
70 | assert np.isclose(box_vector.ax, 6.49127105)
71 | assert np.isclose(box_vector.ay, 0.0)
72 | assert np.isclose(box_vector.az, 0.0)
73 | assert np.isclose(box_vector.bx, -2.16375684)
74 | assert np.isclose(box_vector.by, 6.12002909)
75 | assert np.isclose(box_vector.bz, 0.0)
76 | assert np.isclose(box_vector.cx, -2.16375684)
77 | assert np.isclose(box_vector.cy, -3.06001417)
78 | assert np.isclose(box_vector.cz, 5.30010088)
79 | box_vector_q2 = box_vector.to_quantity()
80 | assert np.isclose(box_vector_q2.value_in_unit(unit.nanometers)[0][0],
81 | 6.49127105)
82 | assert np.isclose(box_vector_q2.value_in_unit(unit.nanometers)[0][1], 0.0)
83 | assert np.isclose(box_vector_q2.value_in_unit(unit.nanometers)[0][2], 0.0)
84 | assert np.isclose(box_vector_q2.value_in_unit(unit.nanometers)[1][0],
85 | -2.16375684)
86 | assert np.isclose(box_vector_q2.value_in_unit(unit.nanometers)[1][1],
87 | 6.12002909)
88 | assert np.isclose(box_vector_q2.value_in_unit(unit.nanometers)[1][2], 0.0)
89 | assert np.isclose(box_vector_q2.value_in_unit(unit.nanometers)[2][0],
90 | -2.16375684)
91 | assert np.isclose(box_vector_q2.value_in_unit(unit.nanometers)[2][1],
92 | -3.06001417)
93 | assert np.isclose(box_vector_q2.value_in_unit(unit.nanometers)[2][2],
94 | 5.30010088)
95 | box_6_vector = [61.239410, 61.239410, 61.239410, 109.471, 109.471, 109.471]
96 | box_vector2 = base.Box_vectors()
97 | box_vector2.from_6_vector(box_6_vector)
98 | assert np.isclose(box_vector2.ax, 6.1239410, atol=0.001)
99 | assert np.isclose(box_vector2.ay, 0.0)
100 | assert np.isclose(box_vector2.az, 0.0)
101 | assert np.isclose(box_vector2.bx, -2.041313667, atol=0.001)
102 | assert np.isclose(box_vector2.by, 5.773707003, atol=0.001)
103 | assert np.isclose(box_vector2.bz, 0.0)
104 | assert np.isclose(box_vector2.cx, -2.041313667, atol=0.001)
105 | assert np.isclose(box_vector2.cy, -2.886853152, atol=0.001)
106 | assert np.isclose(box_vector2.cz, 5.00017714, atol=0.001)
107 | expected_box_6_vector = [6.1239410, 6.1239410, 6.1239410, 109.47122,
108 | 109.47122, 109.47122]
109 | resulting_box_6_vector = box_vector2.to_6_vector()
110 | assert np.isclose(np.array(expected_box_6_vector),
111 | np.array(resulting_box_6_vector)).all()
112 | return
113 |
114 | def test_Barostat_settings():
115 | """
116 | Initialize the Barostat_settings_openmm and Barostat_settings_namd
117 | object to get more coverage.
118 | """
119 | dummy1 = base.Barostat_settings_openmm()
120 | dummy2 = base.Barostat_settings_namd()
121 | return
122 |
123 | def test_Cuda_platform_settings():
124 | """
125 | Initialize the Cuda_platforms_settings() object.
126 | """
127 | cuda_platform_settings = base.Cuda_platform_settings()
128 | properties = cuda_platform_settings.make_properties_dict()
129 | assert properties["CudaDeviceIndex"] == "0"
130 | assert properties["CudaPrecision"] == "mixed"
131 | return
132 |
133 | def test_model_get_type(host_guest_mmvt_model, host_guest_elber_model):
134 | """
135 | Assure that the model.get_type() function is working properly
136 | """
137 | assert host_guest_mmvt_model.get_type() == "mmvt"
138 | assert host_guest_elber_model.get_type() == "elber"
139 | host_guest_mmvt_model.calculation_type = "wrong"
140 | with pytest.raises(Exception) as e_info:
141 | host_guest_mmvt_model.get_type()
142 | return
143 |
144 | def test_model_get_timestep(host_guest_mmvt_model):
145 | """
146 | Assure that the model.get_type() function is working properly
147 | """
148 | assert host_guest_mmvt_model.get_timestep() == 0.002
149 | return
150 |
151 | def test_model_get_bulk_index(host_guest_mmvt_model, toy_multi_model):
152 | assert host_guest_mmvt_model.get_bulk_index() == 13
153 | assert toy_multi_model.get_bulk_index() == None
154 | return
155 |
156 | def test_get_box_vectors_from_pdb():
157 | expected_box_vectors = unit.Quantity(
158 | [[40.142, 0.0, 0.0],
159 | [0.0, 40.329, 0.0],
160 | [0.0, 0.0, 32.472]],
161 | unit=unit.angstrom)
162 | test_pdb_filename = os.path.join(
163 | TEST_DIRECTORY,
164 | "../data/hostguest_files/hostguest_at0.5.pdb")
165 | result = base.get_box_vectors_from_pdb(test_pdb_filename)
166 | assert np.isclose(expected_box_vectors.value_in_unit(unit.angstroms),
167 | result.value_in_unit(unit.angstroms)).all()
168 |
169 | def test_parse_xml_list():
170 | input_list1 = [3,4,5,6]
171 | assert base.parse_xml_list(input_list1) == input_list1
172 | input_range1 = "range(5)"
173 | assert base.parse_xml_list(input_range1) == [0,1,2,3,4]
174 | input_range1 = "range(2,7)"
175 | assert base.parse_xml_list(input_range1) == [2,3,4,5,6]
176 | input_range1 = "range(3,9,2)"
177 | assert base.parse_xml_list(input_range1) == [3,5,7]
178 | with pytest.raises(Exception):
179 | base.parse_xml_list(2)
180 | with pytest.raises(Exception):
181 | base.parse_xml_list("balderdash")
182 | return
183 |
--------------------------------------------------------------------------------
/seekr2/tests/test_common_cv.py:
--------------------------------------------------------------------------------
1 | """
2 | test_common_cv.py
3 |
4 | Testing modules/common_cv.py
5 | """
6 |
7 | import seekr2.modules.common_cv as common_cv
8 |
9 | def test_assign_state_points_toy(toy_mmvt_model_input, toy_mmvt_model):
10 | stateA = common_cv.State_point()
11 | stateA.name = "stateA"
12 | stateA.location = [[0.0, -0.7, 0.0]]
13 | stateB = common_cv.State_point()
14 | stateB.name = "stateB"
15 | stateB.location = [[0.0, 0.7, 0.0]]
16 | toy_mmvt_model_input.cv_inputs[0].state_points = [stateA, stateB]
17 | common_cv.assign_state_points(toy_mmvt_model_input, toy_mmvt_model)
18 | assert toy_mmvt_model.anchors[0].name == "stateA"
19 | assert toy_mmvt_model.anchors[7].name == "stateB"
20 | return
21 |
22 | def test_assign_state_points_hostguest(host_guest_mmvt_model_input,
23 | host_guest_mmvt_model):
24 | bound_state = common_cv.State_point()
25 | bound_state.name = "bound"
26 | bound_state.location = 0.06
27 | bulk_state = common_cv.State_point()
28 | bulk_state.name = "bulk"
29 | bulk_state.location = 1.36
30 | host_guest_mmvt_model_input.cv_inputs[0].state_points \
31 | = [bound_state, bulk_state]
32 | common_cv.assign_state_points(host_guest_mmvt_model_input,
33 | host_guest_mmvt_model)
34 | assert host_guest_mmvt_model.anchors[0].name == "bound"
35 | assert host_guest_mmvt_model.anchors[13].name == "bulk"
36 | return
37 |
38 |
--------------------------------------------------------------------------------
/seekr2/tests/test_common_sim_browndye2.py:
--------------------------------------------------------------------------------
1 | """
2 | test_sim_browndye2.py
3 | """
4 |
5 | import pytest
6 | import os
7 | import re
8 | from shutil import copyfile
9 |
10 | import parmed
11 | import numpy as np
12 |
13 | import seekr2.modules.common_sim_browndye2 as sim_browndye2
14 |
15 | TEST_DIRECTORY = os.path.dirname(__file__)
16 |
17 | def verify_xml_text(filename, tag, text):
18 | with open(filename, 'r') as f:
19 | for line in f.readlines():
20 | result = re.search("<%s>%s%s>" % (tag, text, tag), line)
21 | if result:
22 | return
23 |
24 | raise Exception("tag not found in file: %s" % tag)
25 | return
26 |
27 | def make_test_browndye_input(tmp_path):
28 | test_filename = os.path.join(tmp_path, "test_input.xml")
29 | root = sim_browndye2.Root()
30 | root.n_threads = 3
31 | root.seed = 4567
32 | root.output = "test_output.xml"
33 | root.n_trajectories = 65535
34 | root.n_trajectories_per_output = 5
35 | root.max_n_steps = 123456
36 | root.trajectory_file = "test_traj"
37 | root.n_steps_per_output = 123
38 | root.system.start_at_site = "true"
39 | root.system.reaction_file = "my_rxns.xml"
40 | root.system.hydrodynamic_interactions = "false"
41 | root.system.solvent.dielectric = 77.4
42 | root.system.solvent.relative_viscosity = 0.4
43 | root.system.solvent.debye_length = 9.8
44 | root.system.solvent.kT = 1.456
45 | root.system.solvent.desolvation_parameter = 0.8
46 | ion1 = sim_browndye2.Ion()
47 | ion1.radius = 1.34
48 | ion1.charge = -2.0
49 | ion1.conc = 0.2
50 | ion2 = sim_browndye2.Ion()
51 | ion2.radius = 0.85
52 | ion2.charge = 1.0
53 | ion2.conc = 0.4
54 | root.system.solvent.ions = [ion1, ion2]
55 | root.system.time_step_tolerances = sim_browndye2.Time_step_tolerances()
56 | root.system.time_step_tolerances.minimum_core_dt = 0.1
57 | root.system.time_step_tolerances.minimum_core_reaction_dt = 0.01
58 | group1 = sim_browndye2.Group()
59 | group1.name = "receptor"
60 | core1 = sim_browndye2.Core()
61 | core1.name = "receptor"
62 | core1.atoms = "receptor.xml"
63 | core1.all_in_surface = "true"
64 | core1.is_protein = "true"
65 | core1.dielectric = 5.0
66 | core1.grid_spacing = 0.75
67 | grid1 = "receptor.dx"
68 | core1.electric_field.grid_list.append(grid1)
69 | group1.core_list.append(core1)
70 |
71 | group2 = sim_browndye2.Group()
72 | group2.name = "ligand"
73 | core2 = sim_browndye2.Core()
74 | core2.name = "ligand"
75 | core2.atoms = "ligand.xml"
76 | core1.all_in_surface = "true"
77 | core1.is_protein = "true"
78 | core1.dielectric = 5.0
79 | core2.grid_spacing = 0.5
80 | grid2 = "ligand.dx"
81 | core2.electric_field.grid_list.append(grid2)
82 | group2.core_list.append(core2)
83 |
84 | root.system.group_list.append(group1)
85 | root.system.group_list.append(group2)
86 |
87 | root.write(test_filename)
88 | return test_filename, root
89 |
90 | def make_test_browndye_rxn(tmp_path):
91 | test_filename = os.path.join(tmp_path, "test_rxn.xml")
92 | rxnroot = sim_browndye2.Reaction_root()
93 | rxnroot.first_state = "something1"
94 | rxn = sim_browndye2.Reaction()
95 | rxn.name = "test_rxn1"
96 | rxn.state_before = "something1"
97 | rxn.state_after = "something2"
98 | rxn.molecule0_group = "molec1"
99 | rxn.molecule0_core = "molec1"
100 | rxn.molecule1_group = "molec2"
101 | rxn.molecule1_core = "molec2"
102 | rxn.n_needed = 4
103 | pair = sim_browndye2.Pair()
104 | pair.atom1_index = 5432
105 | pair.atom2_index = 789
106 | pair.distance = 8.45
107 | rxn.pair_list.append(pair)
108 | rxnroot.reaction_list.append(rxn)
109 | rxnroot.write(test_filename)
110 | return test_filename
111 |
112 | def test_add_ghost_atom_to_pqr_from_atoms_center_of_mass(tmp_path):
113 | input_pqr_filename = \
114 | os.path.join(os.path.dirname(__file__),
115 | "../data/hostguest_files/hostguest_ligand.pqr")
116 | atom_index_list = list(range(15))
117 | output_pqr_filename = os.path.join(tmp_path, "test.pqr")
118 | ghost_index = sim_browndye2.add_ghost_atom_to_pqr_from_atoms_center_of_mass(
119 | input_pqr_filename, atom_index_list, output_pqr_filename)
120 | pqr_struct = parmed.load_file(output_pqr_filename, skip_bonds=True)
121 | ghost_atom = pqr_struct.atoms[ghost_index-1]
122 | assert(ghost_atom.name == "GHO")
123 | expected_ghost_location = np.array([[0.0, 0.0, 0.0]])
124 | ghost_location = pqr_struct.coordinates[ghost_index-1]
125 | difference = np.linalg.norm(expected_ghost_location - ghost_location)
126 | assert(difference == 0.0)
127 | return
128 |
129 | def test_make_pqrxml(tmp_path):
130 | pqr_test_filename = os.path.join(TEST_DIRECTORY, "data/ligand_for_test.pqr")
131 | new_pqr_filename = os.path.join(tmp_path, "ligand_for_test.pqr")
132 | copyfile(pqr_test_filename, new_pqr_filename)
133 | xml_filename = sim_browndye2.make_pqrxml(new_pqr_filename)
134 | assert os.path.exists(xml_filename)
135 |
136 | def test_make_and_run_apbs(tmp_path):
137 | os.chdir(tmp_path)
138 | ligand_pqr_filename = \
139 | os.path.join(os.path.dirname(__file__),
140 | "../data/hostguest_files/hostguest_ligand.pqr")
141 | receptor_pqr_filename = \
142 | os.path.join(os.path.dirname(__file__),
143 | "../data/hostguest_files/hostguest_receptor.pqr")
144 | new_pqr_ligand = os.path.join(tmp_path, "ligand.pqr")
145 | new_pqr_receptor = os.path.join(tmp_path, "receptor.pqr")
146 | copyfile(ligand_pqr_filename, new_pqr_ligand)
147 | copyfile(receptor_pqr_filename, new_pqr_receptor)
148 | xml_ligand = sim_browndye2.make_pqrxml(new_pqr_ligand)
149 | xml_receptor = sim_browndye2.make_pqrxml(new_pqr_receptor)
150 | input_apbs_xml, root = make_test_browndye_input(tmp_path)
151 | debye_length = sim_browndye2.make_and_run_apbs(root, input_apbs_xml)
152 | assert float(debye_length) > 0.0
153 |
154 | def test_browndye_input_serializer_apbs_mode(tmp_path):
155 | test_filename, root = make_test_browndye_input(tmp_path)
156 | assert os.path.exists(test_filename)
157 |
158 | verify_xml_text(test_filename, "n_trajectories", "65535")
159 | verify_xml_text(test_filename, "n_threads", "3")
160 | verify_xml_text(test_filename, "seed", "4567")
161 | verify_xml_text(test_filename, "output", "test_output.xml")
162 | verify_xml_text(test_filename, "n_trajectories_per_output", "5")
163 | verify_xml_text(test_filename, "max_n_steps", "123456")
164 | verify_xml_text(test_filename, "trajectory_file", "test_traj")
165 | verify_xml_text(test_filename, "n_steps_per_output", "123")
166 | verify_xml_text(test_filename, "start_at_site", "true")
167 | verify_xml_text(test_filename, "reaction_file", "my_rxns.xml")
168 | verify_xml_text(test_filename, "hydrodynamic_interactions", "false")
169 | verify_xml_text(test_filename, "dielectric", "77.4")
170 | verify_xml_text(test_filename, "relative_viscosity", "0.4")
171 | verify_xml_text(test_filename, "kT", "1.456")
172 | verify_xml_text(test_filename, "desolvation_parameter", "0.8")
173 | verify_xml_text(test_filename, "radius", "1.34")
174 | verify_xml_text(test_filename, "charge", "-2.0")
175 | verify_xml_text(test_filename, "conc", "0.2")
176 | verify_xml_text(test_filename, "radius", "0.85")
177 | verify_xml_text(test_filename, "charge", "1.0")
178 | verify_xml_text(test_filename, "conc", "0.4")
179 | verify_xml_text(test_filename, "minimum_core_dt", "0.1")
180 | verify_xml_text(test_filename, "minimum_core_reaction_dt", "0.01")
181 | verify_xml_text(test_filename, "name", "receptor")
182 | verify_xml_text(test_filename, "atoms", "receptor.xml")
183 | verify_xml_text(test_filename, "all_in_surface", "true")
184 | verify_xml_text(test_filename, "is_protein", "true")
185 | verify_xml_text(test_filename, "dielectric", "5.0")
186 | verify_xml_text(test_filename, "grid_spacing", "0.75")
187 | verify_xml_text(test_filename, "name", "ligand")
188 | verify_xml_text(test_filename, "atoms", "ligand.xml")
189 | verify_xml_text(test_filename, "all_in_surface", "true")
190 | verify_xml_text(test_filename, "is_protein", "true")
191 | verify_xml_text(test_filename, "dielectric", "5.0")
192 | verify_xml_text(test_filename, "grid_spacing", "0.5")
193 |
194 | pytest.raises(Exception, verify_xml_text, test_filename, "gobblygook", "18")
195 |
196 | return
197 |
198 | def test_browndye_input_serializer_apbs_mode_rxn(tmp_path):
199 | test_filename = make_test_browndye_rxn(tmp_path)
200 | assert os.path.exists(test_filename)
201 |
202 | verify_xml_text(test_filename, "first_state", "something1")
203 | verify_xml_text(test_filename, "name", "test_rxn1")
204 | verify_xml_text(test_filename, "state_before", "something1")
205 | verify_xml_text(test_filename, "state_after", "something2")
206 | verify_xml_text(test_filename, "molecule0", "molec1 molec1")
207 | verify_xml_text(test_filename, "molecule1", "molec2 molec2")
208 | verify_xml_text(test_filename, "n_needed", "4")
209 | verify_xml_text(test_filename, "atoms", "5432 789")
210 | verify_xml_text(test_filename, "distance", "8.45")
211 | pytest.raises(Exception, verify_xml_text, test_filename, "gobblygook", "18")
212 |
--------------------------------------------------------------------------------
/seekr2/tests/test_common_sim_openmm.py:
--------------------------------------------------------------------------------
1 | """
2 | test_common_sim_openmm.py
3 | """
4 |
5 | import os
6 |
7 | import pytest
8 | import numpy as np
9 | import mdtraj
10 | try:
11 | import openmm.unit as unit
12 | except ImportError:
13 | import simtk.openmm.unit as unit
14 | from seekr2.modules import common_sim_openmm
15 |
16 | def test_write_toy_pdb_file(toy_mmvt_model):
17 | anchor = toy_mmvt_model.anchors[1]
18 | out_file_name = os.path.join(
19 | toy_mmvt_model.anchor_rootdir, anchor.directory,
20 | anchor.building_directory, "toy.pdb")
21 | system, topology = common_sim_openmm.make_toy_system_object(toy_mmvt_model)
22 | positions = np.array([[3.0, 4.0, 5.0]]) * unit.nanometers
23 | common_sim_openmm.write_toy_pdb_file(topology, positions, out_file_name)
24 | assert os.path.exists(out_file_name)
25 | traj = mdtraj.load(out_file_name)
26 | assert traj.xyz[0,0,0] == 3.0
27 | assert traj.xyz[0,0,1] == 4.0
28 | assert traj.xyz[0,0,2] == 5.0
29 | return
30 |
31 | def test_make_toy_system_object(toy_mmvt_model):
32 | system, topology = common_sim_openmm.make_toy_system_object(toy_mmvt_model)
33 | force = system.getForce(0)
34 | assert force.getNumGroups() == 1
35 | assert force.getGlobalParameterName(0) == "k"
36 | return
37 |
38 | def test_create_openmm_system(toy_mmvt_model, host_guest_mmvt_model):
39 | my_sim_openmm = common_sim_openmm.Common_sim_openmm()
40 | anchor = toy_mmvt_model.anchors[0]
41 | system, topology, positions, box_vectors, num_frames \
42 | = common_sim_openmm.create_openmm_system(
43 | my_sim_openmm, toy_mmvt_model, anchor, frame=0, load_state_file=None)
44 | assert num_frames == 2
45 | assert np.isclose(positions, np.array([[0.0, -0.7, 0.0]])\
46 | *unit.nanometers).all()
47 | system2, topology2, positions2, box_vectors2, num_frames2 \
48 | = common_sim_openmm.create_openmm_system(
49 | my_sim_openmm, toy_mmvt_model, anchor, frame=1, load_state_file=None)
50 | assert np.isclose(positions2, np.array([[0.3, -0.7, 0.0]])\
51 | *unit.nanometers).all()
52 |
53 | anchor2 = host_guest_mmvt_model.anchors[0]
54 | system3, topology3, positions3, box_vectors3, num_frames3 \
55 | = common_sim_openmm.create_openmm_system(
56 | my_sim_openmm, host_guest_mmvt_model, anchor2)
57 |
58 |
59 | def test_add_barostat(host_guest_mmvt_model_npt):
60 | my_sim_openmm = common_sim_openmm.Common_sim_openmm()
61 | anchor = host_guest_mmvt_model_npt.anchors[0]
62 | system, topology, positions, box_vectors, num_frames \
63 | = common_sim_openmm.create_openmm_system(
64 | my_sim_openmm, host_guest_mmvt_model_npt, anchor, frame=0)
65 | forces = system.getForces()
66 | old_force_len = len(forces)
67 | common_sim_openmm.add_barostat(system, host_guest_mmvt_model_npt)
68 | forces2 = system.getForces()
69 | assert len(forces2) == old_force_len + 1
70 | barostat = forces2[-1]
71 | pressure = barostat.getDefaultPressure()
72 | assert pressure == 1.0 * unit.bar
73 | temperature = barostat.getDefaultTemperature()
74 | assert temperature == 298.15 * unit.kelvin
75 |
76 | def test_add_platform_ref(toy_mmvt_model):
77 | my_sim_openmm = common_sim_openmm.Common_sim_openmm()
78 | anchor = toy_mmvt_model.anchors[0]
79 | system, topology, positions, box_vectors, num_frames \
80 | = common_sim_openmm.create_openmm_system(
81 | my_sim_openmm, toy_mmvt_model, anchor, frame=0)
82 | common_sim_openmm.add_platform(my_sim_openmm, toy_mmvt_model)
83 | assert my_sim_openmm.platform.getName() == "Reference"
84 | assert my_sim_openmm.properties == {}
85 |
86 | @pytest.mark.needs_cuda
87 | def test_add_platform_cuda(host_guest_mmvt_model):
88 | host_guest_mmvt_model.openmm_settings.cuda_platform_settings\
89 | .cuda_device_index = "2"
90 | my_sim_openmm = common_sim_openmm.Common_sim_openmm()
91 | anchor = host_guest_mmvt_model.anchors[0]
92 | system, topology, positions, box_vectors, num_frames \
93 | = common_sim_openmm.create_openmm_system(
94 | my_sim_openmm, host_guest_mmvt_model, anchor, frame=0)
95 | common_sim_openmm.add_platform(my_sim_openmm, host_guest_mmvt_model)
96 | assert my_sim_openmm.platform.getName() == "CUDA"
97 | assert my_sim_openmm.properties["CudaPrecision"] == "mixed"
98 | assert my_sim_openmm.properties["CudaDeviceIndex"] == "2"
--------------------------------------------------------------------------------
/seekr2/tests/test_elber_analyze.py:
--------------------------------------------------------------------------------
1 | """
2 | test_elber_analyze.py
3 |
4 | Testing elber_analyze.py
5 | """
6 |
7 | import os
8 |
9 | import numpy as np
10 | import pytest
11 | from shutil import copyfile
12 |
13 | import seekr2.modules.common_base as base
14 | import seekr2.modules.elber_cvs.elber_cv_base as elber_cv_base
15 | import seekr2.modules.common_analyze as common_analyze
16 | import seekr2.modules.elber_analyze as elber_analyze
17 | from seekr2.tests.conftest import compare_dicts
18 | import seekr2.modules.markov_chain_monte_carlo as markov_chain_monte_carlo
19 |
20 | TEST_DIRECTORY = os.path.dirname(os.path.realpath(__file__))
21 |
22 | test_output_filename = os.path.join(TEST_DIRECTORY,
23 | "data/test_analyze_output_elber.txt")
24 |
25 | def test_openmm_read_output_file_list():
26 | N_i_j, R_i_total, lines = elber_analyze.openmm_read_output_file_list(
27 | [test_output_filename])
28 |
29 | N_i_j_exp = {1: 3, 3: 5}
30 | R_i_exp = 1.324
31 | for key in N_i_j:
32 | assert key in N_i_j_exp
33 | assert np.isclose(N_i_j[key], N_i_j_exp[key])
34 |
35 | assert np.isclose(R_i_total, R_i_exp)
36 |
37 | N_i_j, R_i_list, lines = elber_analyze.openmm_read_output_file_list(
38 | [test_output_filename], min_time=1)
39 | assert len(lines) == 10
40 | N_i_j, R_i_list, lines = elber_analyze.openmm_read_output_file_list(
41 | [test_output_filename], max_time=9)
42 | assert len(lines) == 10
43 | return
44 |
45 | def test_Elber_anchor_statistics_read_output_file_list(toy_elber_model):
46 | """
47 | Test the read_output_file_list method of the MMVT_anchor_statistics
48 | object.
49 | """
50 | stats = elber_analyze.Elber_anchor_statistics(1)
51 | engine = "openmm"
52 | output_file_list = [test_output_filename]
53 | min_time = None
54 | max_time = None
55 | stats.read_output_file_list(engine, output_file_list, min_time,
56 | max_time, None, None)
57 |
58 | N_i_j_exp = {1: 3, 3: 5}
59 | R_i_exp = 1.324
60 | for key in stats.N_i_j:
61 | assert key in N_i_j_exp
62 | assert np.isclose(stats.N_i_j[key], N_i_j_exp[key])
63 |
64 | assert np.isclose(stats.R_i_total, R_i_exp)
65 | stats.print_stats()
66 | return
67 |
68 | def make_simple_model():
69 | n_anchors = 3
70 | n_milestones = 3
71 |
72 | # generate data to feed directly into MMVT_data_sample()
73 | model = base.Model()
74 | model.calculation_type = "elber"
75 | model.num_milestones = n_milestones
76 | model.num_anchors = n_anchors
77 | anchor0 = elber_cv_base.Elber_toy_anchor()
78 | anchor0.index = 0
79 | anchor0.endstate = True
80 | milestone_0_0 = base.Milestone()
81 | milestone_0_0.index = 0
82 | milestone_0_0.neighbor_anchor_index = 0
83 | milestone_0_0.alias_index = 2
84 | milestone_0_1 = base.Milestone()
85 | milestone_0_1.index = 1
86 | milestone_0_1.neighbor_anchor_index = 1
87 | milestone_0_1.alias_index = 3
88 | anchor0.milestones = [milestone_0_0, milestone_0_1]
89 |
90 | anchor1 = elber_cv_base.Elber_toy_anchor()
91 | anchor1.index = 1
92 | milestone_1_0 = base.Milestone()
93 | milestone_1_0.index = 0
94 | milestone_1_0.neighbor_anchor_index = 0
95 | milestone_1_0.alias_index = 1
96 | milestone_1_1 = base.Milestone()
97 | milestone_1_1.index = 1
98 | milestone_1_1.neighbor_anchor_index = 1
99 | milestone_1_1.alias_index = 2
100 | milestone_1_2 = base.Milestone()
101 | milestone_1_2.index = 2
102 | milestone_1_2.neighbor_anchor_index = 2
103 | milestone_1_2.alias_index = 3
104 | anchor1.milestones = [milestone_1_0, milestone_1_1, milestone_1_2]
105 |
106 | anchor2 = elber_cv_base.Elber_toy_anchor()
107 | anchor2.index = 2
108 | milestone_2_0 = base.Milestone()
109 | milestone_2_0.index = 1
110 | milestone_2_0.neighbor_anchor_index = 1
111 | milestone_2_0.alias_index = 1
112 | milestone_2_1 = base.Milestone()
113 | milestone_2_1.index = 2
114 | milestone_2_1.neighbor_anchor_index = 2
115 | milestone_2_1.alias_index = 2
116 |
117 | anchor2.milestones = [milestone_2_0, milestone_2_1]
118 | anchor2.bulkstate = True
119 | model.anchors = [anchor0, anchor1, anchor2]
120 | return model
121 |
122 | def test_Elber_data_sample_fill_out_data_quantities():
123 | model = make_simple_model()
124 | N_i_j_list = [{(0,1): 4}, {(1,0): 4, (1,2): 2}, {(2,1): 2}]
125 | R_i_list = [2.4, 2.4]
126 | N_i_j_exp = {(0,1): 4, (1,0): 4, (1,2): 2}
127 | data_sample = elber_analyze.Elber_data_sample(model, N_i_j_list, R_i_list)
128 | data_sample.fill_out_data_quantities()
129 | compare_dicts(N_i_j_exp, data_sample.N_ij)
130 | assert len(R_i_list) == len(data_sample.R_i)
131 | for item1, item2 in zip(R_i_list, data_sample.R_i):
132 | assert item1 == data_sample.R_i[item2]
133 | return
134 |
135 | def test_monte_carlo_milestoning_error():
136 | model = make_simple_model()
137 | N_i_j_list = [{(0,1): 4}, {(1,0): 4, (1,2): 2}, {(2,1): 2, (2,3): 2}]
138 | R_i_list = [2.4, 2.4, 1.2]
139 | N_i_j_exp = {(0,1): 4, (1,0): 4, (1,2): 2, (2,1): 2}
140 | data_sample = elber_analyze.Elber_data_sample(model, N_i_j_list, R_i_list)
141 | data_sample.fill_out_data_quantities()
142 | data_sample.compute_rate_matrix()
143 | data_sample.calculate_thermodynamics()
144 | data_sample.calculate_kinetics()
145 |
146 | # Elber matrix sampler
147 | num = 1000
148 | stride = 10
149 | skip = 10
150 | n_milestones = 3
151 | n_anchors = 3
152 | data_sample_list, p_i_error, free_energy_profile_err, MFPTs_error, \
153 | k_off_error, k_ons_error = elber_analyze.monte_carlo_milestoning_error(
154 | data_sample, num=num, stride=stride, skip=skip, verbose=True)
155 |
156 | result_q1_distribution = []
157 | result_q2_distribution = []
158 | for data_sample in data_sample_list:
159 | result_q1_distribution.append(data_sample.Q[0,1])
160 | result_q2_distribution.append(data_sample.Q[1,0])
161 |
162 | N_i_j = {(0,1): 4, (1,0): 4, (1,2): 2, (2,1): 2}
163 | R_i = {0: 2.4, 1: 2.4, 2: 1.2}
164 | elber_N = np.array([[0, 4, 0],
165 | [4, 0, 2],
166 | [0, 2, 0]])
167 | elber_R = np.array([[2.4],
168 | [2.4],
169 | [1.2]])
170 |
171 | elber_Q = np.zeros((n_milestones, n_milestones))
172 | for i in range(n_milestones):
173 | for j in range(n_milestones):
174 | key = (i,j)
175 | if key in N_i_j:
176 | elber_Q[i,j] = N_i_j[key] / R_i[i]
177 |
178 | for i in range(n_milestones):
179 | elber_Q[i,i] = -np.sum(elber_Q[i,:])
180 |
181 | # Elber matrix sampler
182 | elber_q1_distribution = []
183 | elber_q2_distribution = []
184 | for counter in range(num * (stride) + skip):
185 | #if verbose: print("MCMC stepnum: ", counter)
186 | elber_Qnew = markov_chain_monte_carlo\
187 | .irreversible_stochastic_matrix_algorithm_sample(
188 | elber_Q, elber_N, elber_R)
189 | if counter > skip and counter % stride == 0:
190 | elber_q1_distribution.append(elber_Q[0,1])
191 | elber_q2_distribution.append(elber_Q[1,0])
192 |
193 | elber_Q = elber_Qnew
194 |
195 | assert np.isclose(np.mean(elber_q1_distribution),
196 | np.mean(result_q1_distribution), rtol=0.5, atol=0.01)
197 | assert np.isclose(np.std(elber_q1_distribution),
198 | np.std(result_q1_distribution), rtol=0.5, atol=0.01)
199 | assert np.isclose(np.mean(elber_q2_distribution),
200 | np.mean(result_q2_distribution), rtol=0.5, atol=0.01)
201 | assert np.isclose(np.std(elber_q2_distribution),
202 | np.std(result_q2_distribution), rtol=0.5, atol=0.01)
203 | return
--------------------------------------------------------------------------------
/seekr2/tests/test_elber_cv_base.py:
--------------------------------------------------------------------------------
1 | """
2 | test_elber_cv_base.py
3 |
4 | Testing elber base objects
5 | """
6 |
7 | def test_create_elber_model_input(host_guest_elber_model_input_persistent):
8 | """
9 | Just create the model input to see if it can be done without errors
10 | """
11 | assert host_guest_elber_model_input_persistent.calculation_type == "elber"
12 | return
13 |
14 | def test_create_elber_model(host_guest_elber_model):
15 | """
16 | Create the model based on the model input to ensure that it works
17 | without errors.
18 | """
19 | assert host_guest_elber_model.calculation_type == "elber"
20 | return
--------------------------------------------------------------------------------
/seekr2/tests/test_elber_external_cv.py:
--------------------------------------------------------------------------------
1 | """
2 | test_elber_external_cv.py
3 | """
4 |
5 | try:
6 | import openmm.unit as unit
7 | except ImportError:
8 | import simtk.unit as unit
9 |
10 | import seekr2.modules.common_sim_openmm as common_sim_openmm
11 | import seekr2.modules.elber_cvs.elber_external_cv as elber_external_cv
12 | import seekr2.tests.create_toy_system as create_toy_system
13 |
14 | def test_elber_external_boundary(tmp_path):
15 | # Set initial variables
16 | milestone_variables = {"k":-1.0, "value":0.5}
17 | my_variables = [-1.0, 0.5]
18 | positions1 = [[0.7, 0.0, 0.0], [0.7, 0.4, 0.0]]
19 |
20 | # Initialize the toy system with boundary force
21 | toy_system, toy_topology = create_toy_system.make_toy_system_and_topology(2)
22 | my_cv = elber_external_cv.Elber_external_CV(index=0, groups=[[0],[1]])
23 | my_cv.openmm_fwd_rev_expression = "step(k*(x1 - value))"
24 | boundary_force1 = my_cv.make_fwd_rev_force_object()
25 | boundary_force1.setForceGroup(1)
26 | my_cv.add_fwd_rev_parameters(boundary_force1)
27 | my_cv.add_groups_and_variables(
28 | force=boundary_force1, group_list=[0,1], variables=my_variables)
29 | toy_system.addForce(boundary_force1)
30 | toy_simulation = create_toy_system.make_toy_simulation_and_context(
31 | toy_system, toy_topology, positions1)
32 |
33 | # Check that the particle is within the boundary
34 | toy_state = toy_simulation.context.getState(getEnergy=True, groups={1})
35 | boundary_val1 = toy_state.getPotentialEnergy()
36 | assert boundary_val1.value_in_unit(unit.kilojoules/unit.mole) == 0.0
37 |
38 | # Move the particle outside the boundary
39 | positions2 = [[0.4, 0.0, 0.0], [0.4, 0.4, 0.0]]
40 | toy_simulation.context.setPositions(positions2)
41 |
42 | # Check that the particle is outside the boundary
43 | toy_state = toy_simulation.context.getState(getEnergy=True, groups={1})
44 | boundary_val2 = toy_state.getPotentialEnergy()
45 | assert boundary_val2.value_in_unit(unit.kilojoules/unit.mole) == 1.0
46 |
--------------------------------------------------------------------------------
/seekr2/tests/test_elber_sim_openmm.py:
--------------------------------------------------------------------------------
1 | """
2 | test_elber_sim_openmm.py
3 | """
4 |
5 | import pytest
6 | import os
7 |
8 | try:
9 | import openmm.unit as unit
10 | except ImportError:
11 | import simtk.openmm.unit as unit
12 |
13 | from seekr2.modules import elber_sim_openmm
14 |
15 | def test_add_integrators(toy_elber_model):
16 | my_sim_openmm = elber_sim_openmm.Elber_sim_openmm()
17 | state_prefix = "test_state_prefix"
18 | elber_sim_openmm.add_integrators(my_sim_openmm, toy_elber_model,
19 | state_prefix=state_prefix)
20 | assert my_sim_openmm.umbrella_integrator.getStepSize() \
21 | == toy_elber_model.get_timestep() * unit.picoseconds
22 | assert my_sim_openmm.umbrella_integrator.getTemperature() \
23 | == toy_elber_model.temperature * unit.kelvin
24 | assert my_sim_openmm.umbrella_integrator.getFriction() \
25 | == toy_elber_model.openmm_settings.langevin_integrator\
26 | .friction_coefficient / unit.picoseconds
27 | assert my_sim_openmm.umbrella_integrator.getRandomNumberSeed() \
28 | == toy_elber_model.openmm_settings.langevin_integrator.random_seed
29 |
30 | assert my_sim_openmm.rev_integrator.getOutputFileName() \
31 | == my_sim_openmm.rev_output_filename
32 |
33 | assert my_sim_openmm.fwd_integrator.getOutputFileName() \
34 | == my_sim_openmm.fwd_output_filename
35 | assert my_sim_openmm.fwd_integrator.getSaveStateFileName() \
36 | == state_prefix
37 | return
38 |
39 | def test_add_forces(tmp_path, toy_elber_model):
40 | anchor = toy_elber_model.anchors[1]
41 | output_file = os.path.join(tmp_path, "output.txt")
42 | my_sim_openmm = elber_sim_openmm.create_sim_openmm(
43 | toy_elber_model, anchor, output_file)
44 | umbrella_forces = my_sim_openmm.umbrella_system.getForces()
45 | old_force_len_umbrella = len(umbrella_forces)
46 | rev_forces = my_sim_openmm.rev_system.getForces()
47 | old_force_len_rev = len(rev_forces)
48 | fwd_forces = my_sim_openmm.fwd_system.getForces()
49 | old_force_len_fwd = len(fwd_forces)
50 | assert my_sim_openmm.rev_integrator.getNumSrcMilestoneGroups() \
51 | == 1
52 | assert my_sim_openmm.rev_integrator.getNumDestMilestoneGroups() \
53 | == len(anchor.milestones)-1
54 | assert my_sim_openmm.fwd_integrator.getNumSrcMilestoneGroups() \
55 | == 1
56 | assert my_sim_openmm.fwd_integrator.getNumDestMilestoneGroups() \
57 | == len(anchor.milestones)-1
58 | elber_sim_openmm.add_forces(my_sim_openmm, toy_elber_model, anchor)
59 |
60 | umbrella_forces2 = my_sim_openmm.umbrella_system.getForces()
61 | assert len(umbrella_forces2) == old_force_len_umbrella + 1
62 | rev_forces2 = my_sim_openmm.rev_system.getForces()
63 | assert len(rev_forces2) == old_force_len_rev + len(anchor.milestones)
64 | fwd_forces2 = my_sim_openmm.fwd_system.getForces()
65 | assert len(fwd_forces2) == old_force_len_fwd + len(anchor.milestones)
66 | return
67 |
68 | def test_add_simulation(tmp_path, toy_elber_model):
69 | anchor = toy_elber_model.anchors[0]
70 | output_file = os.path.join(tmp_path, "output.txt")
71 | my_sim_openmm = elber_sim_openmm.create_sim_openmm(
72 | toy_elber_model, anchor, output_file)
73 | assert my_sim_openmm.umbrella_simulation is not None
74 | assert my_sim_openmm.rev_simulation is not None
75 | assert my_sim_openmm.fwd_simulation is not None
76 |
77 | def test_elber_sim_openmm_toy(tmp_path, toy_elber_model):
78 | myanchor = toy_elber_model.anchors[1]
79 | toy_elber_model.openmm_settings.cuda_platform_settings = None
80 | toy_elber_model.openmm_settings.reference_platform = True
81 | output_file = os.path.join(tmp_path, "output.txt")
82 | my_sim_openmm = elber_sim_openmm.create_sim_openmm(
83 | toy_elber_model, myanchor, output_file)
84 | return
85 |
86 | def test_elber_sim_openmm_amber(tmp_path, host_guest_elber_model):
87 | myanchor = host_guest_elber_model.anchors[1]
88 | host_guest_elber_model.openmm_settings.cuda_platform_settings = None
89 | host_guest_elber_model.openmm_settings.reference_platform = True
90 | output_file = os.path.join(tmp_path, "output.txt")
91 | my_sim_openmm = elber_sim_openmm.create_sim_openmm(
92 | host_guest_elber_model, myanchor, output_file)
93 | return
94 |
95 | @pytest.mark.skip
96 | def test_elber_sim_openmm_forcefield(tmp_path, host_guest_elber_model):
97 | # TODO: un-skip this test if forcefield inputs ever become widely-used
98 | myanchor = host_guest_elber_model.anchors[1]
99 | host_guest_elber_model.openmm_settings.cuda_platform_settings = None
100 | host_guest_elber_model.openmm_settings.reference_platform = True
101 | output_file = os.path.join(tmp_path, "output.txt")
102 | my_sim_openmm = elber_sim_openmm.create_sim_openmm(
103 | host_guest_elber_model, myanchor, output_file)
104 | return
105 |
106 | def test_make_elber_umbrella_force(toy_elber_model):
107 | myanchor = toy_elber_model.anchors[1]
108 | mymilestone = myanchor.milestones[1]
109 | cv_index = mymilestone.cv_index
110 | mycv = toy_elber_model.collective_variables[cv_index]
111 | myforce = elber_sim_openmm.make_elber_umbrella_force(
112 | toy_elber_model, myanchor)
113 | assert myforce.getPerBondParameterName(0) == "k"
114 | assert myforce.getPerBondParameterName(1) == "value"
115 | return
116 |
117 | def test_make_elber_boundary_definitions(toy_elber_model):
118 | myanchor = toy_elber_model.anchors[1]
119 | mymilestone = myanchor.milestones[1]
120 | cv_index = mymilestone.cv_index
121 | mycv = toy_elber_model.collective_variables[cv_index]
122 | myforce = elber_sim_openmm.make_elber_boundary_definitions(
123 | mycv, mymilestone)
124 | assert myforce.getPerBondParameterName(0) == "k"
125 | assert myforce.getPerBondParameterName(1) == "value"
126 | return
127 |
--------------------------------------------------------------------------------
/seekr2/tests/test_elber_spherical_cv.py:
--------------------------------------------------------------------------------
1 | """
2 | test_elber_spherical_cv.py
3 | """
4 |
5 | try:
6 | import openmm.unit as unit
7 | except ImportError:
8 | import simtk.unit as unit
9 |
10 | import seekr2.modules.common_sim_openmm as common_sim_openmm
11 | import seekr2.modules.elber_cvs.elber_spherical_cv as elber_spherical_cv
12 | import seekr2.tests.create_toy_system as create_toy_system
13 |
14 | def test_elber_spherical_boundary(tmp_path):
15 | # Set initial variables
16 | milestone_variables = {"k":-1.0, "radius":0.3}
17 | my_variables = [-1.0, 0.3]
18 | positions1 = [[0.0, 0.0, 0.0], [0.3, 0.4, 0.0]]
19 |
20 | # Initialize the toy system with boundary force
21 | toy_system, toy_topology = create_toy_system.make_toy_system_and_topology(2)
22 | my_cv = elber_spherical_cv.Elber_spherical_CV(index=0, groups=[[0],[1]])
23 |
24 | boundary_force1 = my_cv.make_fwd_rev_force_object()
25 | boundary_force1.setForceGroup(1)
26 | my_cv.add_fwd_rev_parameters(boundary_force1)
27 | my_cv.add_groups_and_variables(
28 | force=boundary_force1, group_list=[0,1], variables=my_variables)
29 | toy_system.addForce(boundary_force1)
30 | toy_simulation = create_toy_system.make_toy_simulation_and_context(
31 | toy_system, toy_topology, positions1)
32 |
33 | # Check that the particle is within the boundary
34 | toy_state = toy_simulation.context.getState(getEnergy=True, groups={1})
35 | boundary_val1 = toy_state.getPotentialEnergy()
36 | assert boundary_val1.value_in_unit(unit.kilojoules/unit.mole) == 0.0
37 |
38 | # Move the particle outside the boundary
39 | positions2 = [[0.0, 0.0, 0.0], [0.1, 0.1, 0.0]]
40 | toy_simulation.context.setPositions(positions2)
41 |
42 | # Check that the particle is outside the boundary
43 | toy_state = toy_simulation.context.getState(getEnergy=True, groups={1})
44 | boundary_val2 = toy_state.getPotentialEnergy()
45 | assert boundary_val2.value_in_unit(unit.kilojoules/unit.mole) == 1.0
46 |
--------------------------------------------------------------------------------
/seekr2/tests/test_mmvt_closest_pair_cv.py:
--------------------------------------------------------------------------------
1 | """
2 | test_mmvt_closest_pair_cv.py
3 | """
4 |
5 | import os
6 | import shutil
7 |
8 | import numpy as np
9 |
10 | try:
11 | import openmm.unit as unit
12 | except ImportError:
13 | import simtk.unit as unit
14 |
15 | try:
16 | import openmm
17 | except ImportError:
18 | import simtk.openmm as openmm
19 |
20 | try:
21 | import openmm.app as openmm_app
22 | except ImportError:
23 | import simtk.openmm.app as openmm_app
24 |
25 | import mdtraj
26 |
27 | import seekr2.modules.common_base as base
28 | import seekr2.modules.common_sim_openmm as common_sim_openmm
29 | import seekr2.modules.mmvt_cvs.mmvt_closest_pair_cv as mmvt_closest_pair_cv
30 | import seekr2.tests.create_toy_system as create_toy_system
31 |
32 |
33 | def test_mmvt_closest_pair_boundary(tmp_path):
34 | # Set initial variables
35 | milestone_variables = {"k":-1.0, "value":0.1, "exponent":50.0}
36 | my_variables = [1.0, -1.0, 0.1, 50.0]
37 | positions1 = [[0.0, 0.0, 0.0], [0.1, 0.0, 0.1],
38 | [0.3, 0.0, 0.1], [0.4, 0.0, 0.0]]
39 |
40 | # Initialize the toy system with boundary force
41 | toy_system, toy_topology = create_toy_system.make_toy_system_and_topology(4)
42 | my_cv = mmvt_closest_pair_cv.MMVT_closest_pair_CV(
43 | index=0, groups=[[0,1],[2,3]])
44 |
45 | box_vectors = base.Box_vectors()
46 |
47 | box_vectors.from_quantity(np.array(
48 | [[5.0, 0.0, 0.0], [0.0, 5.0, 0.0], [0.0, 0.0, 5.0]]) \
49 | * unit.nanometers)
50 |
51 | toy_system.setDefaultPeriodicBoxVectors(*box_vectors.to_quantity())
52 | toy_topology.setPeriodicBoxVectors(box_vectors.to_quantity())
53 |
54 | create_toy_system.assign_nonbonded_cv_info(my_cv, toy_system, box_vectors)
55 |
56 | boundary_force1 = my_cv.make_boundary_force(alias_id=1)
57 | boundary_force1.setForceGroup(1)
58 | my_cv.add_parameters(boundary_force1)
59 | my_cv.add_groups_and_variables(
60 | force=boundary_force1, variables=my_variables, alias_id=1)
61 | toy_system.addForce(boundary_force1)
62 | toy_simulation = create_toy_system.make_toy_simulation_and_context(
63 | toy_system, toy_topology, positions1)
64 |
65 | # Check that the particle is within the boundary
66 | toy_state = toy_simulation.context.getState(getEnergy=True, groups={1})
67 | boundary_val1 = toy_state.getPotentialEnergy()
68 | assert boundary_val1.value_in_unit(unit.kilojoules/unit.mole) == 0.0
69 |
70 | # Ensure that check_mdtraj_within_boundary works for this cv
71 | pdb_filename1 = os.path.join(tmp_path, "closest_mmvt_toy1.pdb")
72 | common_sim_openmm.write_toy_pdb_file(toy_topology, positions1, pdb_filename1)
73 | pdbtraj1 = mdtraj.load(pdb_filename1)
74 | assert my_cv.check_mdtraj_within_boundary(
75 | pdbtraj1, milestone_variables, verbose=False, TOL=0.0)
76 |
77 | # Ensure that check_openmm_context_within_boundary works for this cv
78 | assert my_cv.check_openmm_context_within_boundary(
79 | toy_simulation.context, milestone_variables)
80 |
81 | # Move the particle outside the boundary
82 | positions2 = [[0.0, 0.0, 0.0], [0.1, 0.0, 0.1],
83 | [0.15, 0.0, 0.1], [0.25, 0.0, 0.0]]
84 | toy_simulation.context.setPositions(positions2)
85 |
86 | # Check that the particle is outside the boundary
87 | toy_state = toy_simulation.context.getState(getEnergy=True, groups={1})
88 | boundary_val2 = toy_state.getPotentialEnergy()
89 | assert boundary_val2.value_in_unit(unit.kilojoules/unit.mole) == 1.0
90 |
91 | # Move the boundary to inside the interparticle distance
92 | milestone_variables = {"k":-1.0, "value":0.01, "exponent":50.0}
93 | new_variables = [1.0, -1.0, 0.01, 50.0]
94 |
95 | my_cv.update_groups_and_variables(
96 | force=boundary_force1, variables=new_variables, alias_id=1,
97 | context=toy_simulation.context)
98 | toy_simulation.context.reinitialize(preserveState=True)
99 |
100 | # Check that the particle is within the new boundary
101 | toy_state = toy_simulation.context.getState(getEnergy=True, groups={1})
102 | boundary_val3 = toy_state.getPotentialEnergy()
103 | assert boundary_val3.value_in_unit(unit.kilojoules/unit.mole) == 0.0
104 |
105 | # Ensure that check_mdtraj_within_boundary still works
106 | pdb_filename2 = os.path.join(tmp_path, "closest_mmvt_toy2.pdb")
107 | common_sim_openmm.write_toy_pdb_file(toy_topology, positions2, pdb_filename2)
108 | pdbtraj2 = mdtraj.load(pdb_filename2)
109 | assert my_cv.check_mdtraj_within_boundary(
110 | pdbtraj2, milestone_variables, verbose=False, TOL=0.0)
111 |
112 | # Ensure that check_openmm_context_within_boundary still works
113 | assert my_cv.check_openmm_context_within_boundary(
114 | toy_simulation.context, milestone_variables)
115 |
116 | return
117 |
118 | def test_mmvt_count_contacts_voronoi_boundary():
119 | # Set initial variables
120 | me_val = 0.2
121 | neighbor_val = 0.4
122 | positions1 = [[0.0, 0.0, 0.0], [0.1, 0.0, 0.1],
123 | [0.3, 0.0, 0.1], [0.4, 0.0, 0.0]]
124 | toy_system, toy_topology = create_toy_system.make_toy_system_and_topology(4)
125 | # Initialize the toy system with boundary force
126 | box_vectors = base.Box_vectors()
127 | box_vectors.from_quantity(np.array(
128 | [[5.0, 0.0, 0.0], [0.0, 5.0, 0.0], [0.0, 0.0, 5.0]]) \
129 | * unit.nanometers)
130 | toy_system.setDefaultPeriodicBoxVectors(*box_vectors.to_quantity())
131 | toy_topology.setPeriodicBoxVectors(box_vectors.to_quantity())
132 | my_cv = mmvt_closest_pair_cv.MMVT_closest_pair_CV(
133 | index=0, groups=[[0,1],[2,3]])
134 |
135 | create_toy_system.assign_nonbonded_cv_info(my_cv, toy_system, box_vectors)
136 |
137 | me_force, neighbor_force = my_cv.make_voronoi_cv_boundary_forces(
138 | me_val, neighbor_val, 1)
139 | me_force.setForceGroup(1)
140 | neighbor_force.setForceGroup(2)
141 | toy_system.addForce(me_force)
142 | toy_system.addForce(neighbor_force)
143 | toy_simulation = create_toy_system.make_toy_simulation_and_context(
144 | toy_system, toy_topology, positions1)
145 |
146 | # Test if the Voronoi boundary returns the correct number
147 | toy_state_me = toy_simulation.context.getState(getEnergy=True, groups={1})
148 | toy_state_neighbor = toy_simulation.context.getState(getEnergy=True, groups={2})
149 | boundary_val_me = toy_state_me.getPotentialEnergy()
150 | boundary_val_neighbor = toy_state_neighbor.getPotentialEnergy()
151 | assert np.isclose(boundary_val_me.value_in_unit(unit.kilojoules/unit.mole), 0.0)
152 | assert not np.isclose(boundary_val_neighbor.value_in_unit(unit.kilojoules/unit.mole), 0.0)
153 |
154 | # Move the particle outside the boundary and test Voronoi again
155 | positions2 = [[0.0, 0.0, 0.0], [0.1, 0.0, 0.1],
156 | [0.5, 0.0, 0.1], [0.6, 0.0, 0.0]]
157 | toy_simulation.context.setPositions(positions2)
158 | toy_state_me = toy_simulation.context.getState(getEnergy=True, groups={1})
159 | toy_state_neighbor = toy_simulation.context.getState(getEnergy=True, groups={2})
160 | boundary_val_me = toy_state_me.getPotentialEnergy()
161 | boundary_val_neighbor = toy_state_neighbor.getPotentialEnergy()
162 | assert not np.isclose(boundary_val_me.value_in_unit(unit.kilojoules/unit.mole), 0.0)
163 | assert np.isclose(boundary_val_neighbor.value_in_unit(unit.kilojoules/unit.mole), 0.0)
164 |
165 | # Move the boundary inside the particle and test
166 | new_me_val = 0.4
167 | new_neighbor_val = 0.6
168 | my_cv.update_voronoi_cv_boundary_forces(
169 | me_force, new_me_val, neighbor_force, new_neighbor_val, 1,
170 | toy_simulation.context)
171 | toy_simulation.context.reinitialize(preserveState=True)
172 | toy_state_me = toy_simulation.context.getState(getEnergy=True, groups={1})
173 | toy_state_neighbor = toy_simulation.context.getState(getEnergy=True, groups={2})
174 | boundary_val_me = toy_state_me.getPotentialEnergy()
175 | boundary_val_neighbor = toy_state_neighbor.getPotentialEnergy()
176 | assert np.isclose(boundary_val_me.value_in_unit(unit.kilojoules/unit.mole), 0.0)
177 | assert not np.isclose(boundary_val_neighbor.value_in_unit(unit.kilojoules/unit.mole), 0.0)
178 |
179 | return
180 |
--------------------------------------------------------------------------------
/seekr2/tests/test_mmvt_count_contacts_cv.py:
--------------------------------------------------------------------------------
1 | """
2 | test_mmvt_count_contacts_cv.py
3 | """
4 |
5 | import os
6 | import shutil
7 |
8 | import numpy as np
9 |
10 | try:
11 | import openmm.unit as unit
12 | except ImportError:
13 | import simtk.unit as unit
14 |
15 | try:
16 | import openmm
17 | except ImportError:
18 | import simtk.openmm as openmm
19 |
20 | try:
21 | import openmm.app as openmm_app
22 | except ImportError:
23 | import simtk.openmm.app as openmm_app
24 |
25 | import mdtraj
26 |
27 | import seekr2.modules.common_base as base
28 | import seekr2.modules.common_sim_openmm as common_sim_openmm
29 | import seekr2.modules.mmvt_cvs.mmvt_count_contacts_cv as mmvt_count_contacts_cv
30 | import seekr2.tests.create_toy_system as create_toy_system
31 |
32 |
33 | def test_mmvt_count_contacts_boundary(tmp_path):
34 | # Set initial variables
35 | cutoff = 0.2
36 | milestone_variables = {"k":-1.0, "value":1}
37 | my_variables = [1.0, -1.0, 1]
38 | positions1 = [[0.0, 0.0, 0.0], [0.1, 0.0, 0.0],
39 | [0.0, 0.0, 0.1], [0.4, 0.0, 0.0]]
40 |
41 | # Initialize the toy system with boundary force
42 | toy_system, toy_topology = create_toy_system.make_toy_system_and_topology(4)
43 | my_cv = mmvt_count_contacts_cv.MMVT_count_contacts_CV(
44 | index=0, groups=[[0],[1,2,3]])
45 |
46 | box_vectors = base.Box_vectors()
47 |
48 | box_vectors.from_quantity(np.array(
49 | [[5.0, 0.0, 0.0], [0.0, 5.0, 0.0], [0.0, 0.0, 5.0]]) \
50 | * unit.nanometers)
51 |
52 | toy_system.setDefaultPeriodicBoxVectors(*box_vectors.to_quantity())
53 | toy_topology.setPeriodicBoxVectors(box_vectors.to_quantity())
54 |
55 | create_toy_system.assign_nonbonded_cv_info(my_cv, toy_system, box_vectors,
56 | cutoff=cutoff)
57 |
58 | boundary_force1 = my_cv.make_boundary_force(alias_id=1)
59 | boundary_force1.setForceGroup(1)
60 | my_cv.add_parameters(boundary_force1)
61 | my_cv.add_groups_and_variables(
62 | force=boundary_force1, variables=my_variables, alias_id=1)
63 | toy_system.addForce(boundary_force1)
64 | toy_simulation = create_toy_system.make_toy_simulation_and_context(
65 | toy_system, toy_topology, positions1)
66 |
67 | # Check that the particle is within the boundary
68 | toy_state = toy_simulation.context.getState(getEnergy=True, groups={1})
69 | boundary_val1 = toy_state.getPotentialEnergy()
70 | assert boundary_val1.value_in_unit(unit.kilojoules/unit.mole) == 0.0
71 |
72 | # Ensure that check_mdtraj_within_boundary works for this cv
73 | pdb_filename1 = os.path.join(tmp_path, "count_mmvt_toy1.pdb")
74 | common_sim_openmm.write_toy_pdb_file(toy_topology, positions1, pdb_filename1)
75 | pdbtraj1 = mdtraj.load(pdb_filename1)
76 | assert my_cv.check_mdtraj_within_boundary(
77 | pdbtraj1, milestone_variables, verbose=False, TOL=0.0)
78 |
79 | # Ensure that check_openmm_context_within_boundary works for this cv
80 | assert my_cv.check_openmm_context_within_boundary(
81 | toy_simulation.context, milestone_variables)
82 |
83 | # Move the particle outside the boundary
84 | positions2 = [[0.0, 0.0, 0.0], [0.8, 0.0, 0.0],
85 | [0.0, 0.0, 0.8], [0.9, 0.0, 0.0]]
86 | toy_simulation.context.setPositions(positions2)
87 |
88 | # Check that the particle is outside the boundary
89 | toy_state = toy_simulation.context.getState(getEnergy=True, groups={1})
90 | boundary_val2 = toy_state.getPotentialEnergy()
91 | assert boundary_val2.value_in_unit(unit.kilojoules/unit.mole) == 1.0
92 |
93 | # Move the boundary to inside the interparticle distance
94 | milestone_variables = {"k":1.0, "value":1}
95 | new_variables = [1.0, 1.0, 1]
96 |
97 | my_cv.update_groups_and_variables(
98 | force=boundary_force1, variables=new_variables, alias_id=1,
99 | context=toy_simulation.context)
100 | toy_simulation.context.reinitialize(preserveState=True)
101 |
102 | # Check that the particle is within the new boundary
103 | toy_state = toy_simulation.context.getState(getEnergy=True, groups={1})
104 | boundary_val3 = toy_state.getPotentialEnergy()
105 | assert boundary_val3.value_in_unit(unit.kilojoules/unit.mole) == 0.0
106 |
107 | # Ensure that check_mdtraj_within_boundary still works
108 | pdb_filename2 = os.path.join(tmp_path, "count_mmvt_toy2.pdb")
109 | common_sim_openmm.write_toy_pdb_file(toy_topology, positions2, pdb_filename2)
110 | pdbtraj2 = mdtraj.load(pdb_filename2)
111 | assert my_cv.check_mdtraj_within_boundary(
112 | pdbtraj2, milestone_variables, verbose=False, TOL=0.0)
113 |
114 | # Ensure that check_openmm_context_within_boundary still works
115 | assert my_cv.check_openmm_context_within_boundary(
116 | toy_simulation.context, milestone_variables)
117 |
118 | return
119 |
120 | def test_mmvt_count_contacts_voronoi_boundary():
121 | # Set initial variables
122 | me_val = 2
123 | neighbor_val = 3
124 | cutoff = 0.2
125 | positions1 = [[0.0, 0.0, 0.0], [0.1, 0.0, 0.0],
126 | [0.0, 0.0, 0.1], [0.4, 0.0, 0.0]]
127 | toy_system, toy_topology = create_toy_system.make_toy_system_and_topology(4)
128 | # Initialize the toy system with boundary force
129 | box_vectors = base.Box_vectors()
130 | box_vectors.from_quantity(np.array(
131 | [[5.0, 0.0, 0.0], [0.0, 5.0, 0.0], [0.0, 0.0, 5.0]]) \
132 | * unit.nanometers)
133 | toy_system.setDefaultPeriodicBoxVectors(*box_vectors.to_quantity())
134 | toy_topology.setPeriodicBoxVectors(box_vectors.to_quantity())
135 | my_cv = mmvt_count_contacts_cv.MMVT_count_contacts_CV(
136 | index=0, groups=[[0],[1,2,3]])
137 |
138 | create_toy_system.assign_nonbonded_cv_info(my_cv, toy_system, box_vectors,
139 | cutoff=cutoff)
140 |
141 | me_force, neighbor_force = my_cv.make_voronoi_cv_boundary_forces(
142 | me_val, neighbor_val, 1)
143 | me_force.setForceGroup(1)
144 | neighbor_force.setForceGroup(2)
145 | toy_system.addForce(me_force)
146 | toy_system.addForce(neighbor_force)
147 | toy_simulation = create_toy_system.make_toy_simulation_and_context(
148 | toy_system, toy_topology, positions1)
149 |
150 | # Test if the Voronoi boundary returns the correct number
151 | toy_state_me = toy_simulation.context.getState(getEnergy=True, groups={1})
152 | toy_state_neighbor = toy_simulation.context.getState(getEnergy=True, groups={2})
153 | boundary_val_me = toy_state_me.getPotentialEnergy()
154 | boundary_val_neighbor = toy_state_neighbor.getPotentialEnergy()
155 | assert np.isclose(boundary_val_me.value_in_unit(unit.kilojoules/unit.mole), 0.0)
156 | assert not np.isclose(boundary_val_neighbor.value_in_unit(unit.kilojoules/unit.mole), 0.0)
157 |
158 | # Move the particle outside the boundary and test Voronoi again
159 | positions2 = [[0.0, 0.0, 0.0], [0.1, 0.0, 0.0],
160 | [0.0, 0.0, 0.1], [0.0, 0.1, 0.0]]
161 | toy_simulation.context.setPositions(positions2)
162 | toy_state_me = toy_simulation.context.getState(getEnergy=True, groups={1})
163 | toy_state_neighbor = toy_simulation.context.getState(getEnergy=True, groups={2})
164 | boundary_val_me = toy_state_me.getPotentialEnergy()
165 | boundary_val_neighbor = toy_state_neighbor.getPotentialEnergy()
166 | assert not np.isclose(boundary_val_me.value_in_unit(unit.kilojoules/unit.mole), 0.0)
167 | assert np.isclose(boundary_val_neighbor.value_in_unit(unit.kilojoules/unit.mole), 0.0)
168 |
169 | # Move the boundary inside the particle and test
170 | new_me_val = 3
171 | new_neighbor_val = 4
172 | my_cv.update_voronoi_cv_boundary_forces(
173 | me_force, new_me_val, neighbor_force, new_neighbor_val, 1,
174 | toy_simulation.context)
175 | toy_simulation.context.reinitialize(preserveState=True)
176 | toy_state_me = toy_simulation.context.getState(getEnergy=True, groups={1})
177 | toy_state_neighbor = toy_simulation.context.getState(getEnergy=True, groups={2})
178 | boundary_val_me = toy_state_me.getPotentialEnergy()
179 | boundary_val_neighbor = toy_state_neighbor.getPotentialEnergy()
180 | assert np.isclose(boundary_val_me.value_in_unit(unit.kilojoules/unit.mole), 0.0)
181 | assert not np.isclose(boundary_val_neighbor.value_in_unit(unit.kilojoules/unit.mole), 0.0)
182 |
183 | return
184 |
--------------------------------------------------------------------------------
/seekr2/tests/test_mmvt_cv.py:
--------------------------------------------------------------------------------
1 | """
2 | Test the mmvt_cv.py module
3 | """
4 |
5 | import numpy as np
6 |
7 | import seekr2.modules.common_cv as common_cv
8 | import seekr2.modules.check as check
9 |
10 | # TODO: move tests to appropriate file and remove this test file
11 |
12 | def test_tiwary_input_and_model(tiwary_mmvt_model_input, tiwary_mmvt_model):
13 | """
14 |
15 | """
16 | assert len(tiwary_mmvt_model_input.cv_inputs[0].order_parameters) == 3
17 | check.check_pre_simulation_all(tiwary_mmvt_model)
18 | return
19 |
20 | def test_distance_order_parameter_get_value():
21 | """
22 |
23 | """
24 | op = common_cv.Tiwary_cv_distance_order_parameter()
25 | com1 = np.array([1.0, 1.0, 1.0])
26 | com2 = np.array([4.0, 5.0, 1.0])
27 | expected_dist = 5.0
28 | dist = op.get_value([com1, com2])
29 | assert np.isclose(dist, expected_dist)
30 | return
31 |
32 | def test_angle_order_parameter_get_value():
33 | """
34 |
35 | """
36 | op = common_cv.Tiwary_cv_angle_order_parameter()
37 | com1 = np.array([1.0, 0.0, 0.0])
38 | com2 = np.array([0.0, 0.0, 0.0])
39 | com3 = np.array([0.0, 0.0, 1.0])
40 | expected_angle = 0.5 * np.pi
41 | angle = op.get_value([com1, com2, com3])
42 | assert np.isclose(angle, expected_angle)
43 | return
44 |
45 | def test_torsion_order_parameter_get_value():
46 | """
47 |
48 | """
49 | op = common_cv.Tiwary_cv_torsion_order_parameter()
50 | com1 = np.array([0.0, 0.0, 1.0])
51 | com2 = np.array([0.0, 0.0, 0.0])
52 | com3 = np.array([1.0, 0.0, 0.0])
53 | com4 = np.array([1.0, 1.0, 0.0])
54 | expected_phi = -0.5 * np.pi
55 | phi = op.get_value([com1, com2, com3, com4])
56 | assert np.isclose(phi, expected_phi)
57 | return
58 |
59 | def test_toy_input_and_model(toy_mmvt_model_input, toy_mmvt_model):
60 | """
61 |
62 | """
63 | check.check_pre_simulation_all(toy_mmvt_model)
64 | return
--------------------------------------------------------------------------------
/seekr2/tests/test_mmvt_cv_base.py:
--------------------------------------------------------------------------------
1 | """
2 | test_mmvt_cv_base.py
3 | """
4 |
5 | import os
6 | import shutil
7 |
8 | import numpy as np
9 |
10 | from seekr2.modules import mmvt_sim_openmm
11 |
12 | # TODO: move tests to appropriate test files and remove this test file
13 |
14 | def test_MMVT_anchor_id_from_alias(host_guest_mmvt_model):
15 | """
16 | Test the anchor's ability to return information about itself and its
17 | milestones - id_from_alias.
18 | """
19 | anchor0 = host_guest_mmvt_model.anchors[0]
20 | anchor1 = host_guest_mmvt_model.anchors[1]
21 | # test id_from_alias
22 | assert anchor0.id_from_alias(1) == 0
23 | assert anchor1.id_from_alias(1) == 0
24 | assert anchor1.id_from_alias(2) == 1
25 | return
26 |
27 | def test_MMVT_anchor_alias_from_id(host_guest_mmvt_model):
28 | """
29 | Test the anchor's ability to return information about itself and its
30 | milestones - alias_from_id.
31 | """
32 | anchor0 = host_guest_mmvt_model.anchors[0]
33 | anchor1 = host_guest_mmvt_model.anchors[1]
34 | # test id_from_alias
35 | assert anchor0.alias_from_id(0) == 1
36 | assert anchor1.alias_from_id(0) == 1
37 | assert anchor1.alias_from_id(1) == 2
38 | return
39 |
40 | def test_MMVT_anchor_alias_from_neighbor_id(host_guest_mmvt_model):
41 | """
42 | Test the anchor's ability to return information about itself and its
43 | milestones - alias_from_neighbor_id.
44 | """
45 | anchor0 = host_guest_mmvt_model.anchors[0]
46 | anchor1 = host_guest_mmvt_model.anchors[1]
47 | # test id_from_alias
48 | assert anchor0.alias_from_neighbor_id(1) == 1
49 | assert anchor1.alias_from_neighbor_id(0) == 1
50 | assert anchor1.alias_from_neighbor_id(2) == 2
51 | return
52 |
53 | def test_MMVT_anchor_get_ids(host_guest_mmvt_model):
54 | """
55 | Test the anchor's ability to return information about itself and its
56 | milestones - id_from_alias.
57 | """
58 | anchor0 = host_guest_mmvt_model.anchors[0]
59 | anchor1 = host_guest_mmvt_model.anchors[1]
60 | # test id_from_alias
61 | assert anchor0.get_ids() == [0]
62 | assert anchor1.get_ids() == [0, 1]
63 | return
64 |
65 | def test_check_openmm_context_within_boundary(host_guest_mmvt_model, tmp_path):
66 | """
67 | Test whether the check can find systems that exist outside the proper
68 | Voronoi cells.
69 | """
70 | # Test check success: system starting within Voronoi cells
71 | anchor = host_guest_mmvt_model.anchors[0]
72 | output_file = os.path.join(tmp_path, "output.txt")
73 | host_guest_mmvt_model.openmm_settings.cuda_platform_settings = None
74 | host_guest_mmvt_model.openmm_settings.reference_platform = True
75 | my_sim_openmm = mmvt_sim_openmm.create_sim_openmm(
76 | host_guest_mmvt_model, anchor, output_file)
77 | context = my_sim_openmm.simulation.context
78 |
79 | final_result = True
80 | for milestone in anchor.milestones:
81 | cv = host_guest_mmvt_model.collective_variables[milestone.cv_index]
82 | result = cv.check_openmm_context_within_boundary(
83 | context, milestone.variables, verbose=True)
84 | final_result = final_result and result
85 |
86 | assert final_result
87 |
88 | # Test check failure(s): system outside Voronoi cells
89 | anchor_pdb1 \
90 | = host_guest_mmvt_model.anchors[0].amber_params.pdb_coordinates_filename
91 | anchor_pdb2 \
92 | = host_guest_mmvt_model.anchors[1].amber_params.pdb_coordinates_filename
93 | anchor_pdb_src_path1 = os.path.join(
94 | host_guest_mmvt_model.anchor_rootdir,
95 | host_guest_mmvt_model.anchors[0].directory,
96 | host_guest_mmvt_model.anchors[0].building_directory,
97 | anchor_pdb1)
98 | anchor_pdb_src_path2 = os.path.join(
99 | host_guest_mmvt_model.anchor_rootdir,
100 | host_guest_mmvt_model.anchors[1].directory,
101 | host_guest_mmvt_model.anchors[1].building_directory,
102 | anchor_pdb2)
103 | anchor_pdb_dest_path1 = os.path.join(
104 | host_guest_mmvt_model.anchor_rootdir,
105 | host_guest_mmvt_model.anchors[0].directory,
106 | host_guest_mmvt_model.anchors[0].building_directory,
107 | anchor_pdb2)
108 | anchor_pdb_dest_path2 = os.path.join(
109 | host_guest_mmvt_model.anchor_rootdir,
110 | host_guest_mmvt_model.anchors[1].directory,
111 | host_guest_mmvt_model.anchors[1].building_directory,
112 | anchor_pdb1)
113 | shutil.copyfile(anchor_pdb_src_path1, anchor_pdb_dest_path2)
114 | shutil.copyfile(anchor_pdb_src_path2, anchor_pdb_dest_path1)
115 | host_guest_mmvt_model.anchors[0].amber_params.pdb_coordinates_filename \
116 | = anchor_pdb2
117 | host_guest_mmvt_model.anchors[1].amber_params.pdb_coordinates_filename \
118 | = anchor_pdb1
119 |
120 | my_sim_openmm = mmvt_sim_openmm.create_sim_openmm(
121 | host_guest_mmvt_model, anchor, output_file)
122 | context = my_sim_openmm.simulation.context
123 |
124 | final_result = True
125 | for milestone in anchor.milestones:
126 | cv = host_guest_mmvt_model.collective_variables[milestone.cv_index]
127 | result = cv.check_openmm_context_within_boundary(
128 | context, milestone.variables, verbose=True)
129 | final_result = final_result and result
130 |
131 | assert not final_result
132 |
133 | return
134 |
135 | def test_check_toy_openmm_context_within_boundary(toy_mmvt_model, tmp_path):
136 | """
137 | Test whether the check can find systems that exist outside the proper
138 | Voronoi cells.
139 | """
140 | # Test check success: system starting within Voronoi cells
141 | anchor = toy_mmvt_model.anchors[0]
142 | output_file = os.path.join(tmp_path, "output.txt")
143 | toy_mmvt_model.openmm_settings.cuda_platform_settings = None
144 | toy_mmvt_model.openmm_settings.reference_platform = True
145 | my_sim_openmm = mmvt_sim_openmm.create_sim_openmm(
146 | toy_mmvt_model, anchor, output_file)
147 | context = my_sim_openmm.simulation.context
148 |
149 | final_result = True
150 | for milestone in anchor.milestones:
151 | cv = toy_mmvt_model.collective_variables[milestone.cv_index]
152 | result = cv.check_openmm_context_within_boundary(
153 | context, milestone.variables, verbose=True)
154 | final_result = final_result and result
155 |
156 | assert final_result
157 |
158 | # Test check failure(s): system outside Voronoi cells
159 | toy_mmvt_model.anchors[0].starting_positions = np.array(
160 | [[[0.0, -0.7, 0.0]], [[0.2, -0.5, 0.0]]])
161 | toy_mmvt_model.anchors[1].starting_positions = np.array(
162 | [[[0.0, -0.3, 0.0]]])
163 |
164 | anchor = toy_mmvt_model.anchors[0]
165 | my_sim_openmm = mmvt_sim_openmm.create_sim_openmm(
166 | toy_mmvt_model, anchor, output_file, frame=1)
167 | context = my_sim_openmm.simulation.context
168 |
169 | final_result = True
170 | for milestone in anchor.milestones:
171 | cv = toy_mmvt_model.collective_variables[milestone.cv_index]
172 | result = cv.check_openmm_context_within_boundary(
173 | context, milestone.variables, verbose=True)
174 | final_result = final_result and result
175 |
176 | assert not final_result
177 |
178 | anchor = toy_mmvt_model.anchors[1]
179 | my_sim_openmm = mmvt_sim_openmm.create_sim_openmm(
180 | toy_mmvt_model, anchor, output_file)
181 | context = my_sim_openmm.simulation.context
182 |
183 | final_result = True
184 | for milestone in anchor.milestones:
185 | cv = toy_mmvt_model.collective_variables[milestone.cv_index]
186 | result = cv.check_openmm_context_within_boundary(
187 | context, milestone.variables, verbose=True)
188 | final_result = final_result and result
189 |
190 | assert not final_result
191 |
192 | return
--------------------------------------------------------------------------------
/seekr2/tests/test_mmvt_sim_namd.py:
--------------------------------------------------------------------------------
1 | """
2 | test_mmvt_sim_namd.py
3 | """
4 |
5 | import os
6 |
7 | from seekr2.modules import mmvt_sim_namd
8 |
9 | def test_mmvt_sim_namd_amber(tmp_path, host_guest_mmvt_model_namd):
10 | myanchor = host_guest_mmvt_model_namd.anchors[1]
11 | output_file = os.path.join(tmp_path, "output.txt")
12 | my_sim_openmm = mmvt_sim_namd.create_sim_namd(host_guest_mmvt_model_namd,
13 | myanchor, output_file)
14 | assert my_sim_openmm.colvars_config is not None
15 | assert my_sim_openmm.seekr_namd_settings is not None
16 | return
17 |
--------------------------------------------------------------------------------
/seekr2/tests/test_mmvt_sim_openmm.py:
--------------------------------------------------------------------------------
1 | """
2 | test_mmvt_sim_openmm.py
3 | """
4 |
5 | import pytest
6 | import os
7 |
8 | try:
9 | import openmm.unit as unit
10 | except ImportError:
11 | import simtk.openmm.unit as unit
12 | from seekr2.modules import mmvt_sim_openmm
13 |
14 | TEST_DIRECTORY = os.path.dirname(__file__)
15 |
16 | def test_add_integrator(toy_mmvt_model):
17 | my_sim_openmm = mmvt_sim_openmm.MMVT_sim_openmm()
18 | state_prefix = "test_state_prefix"
19 | mmvt_sim_openmm.add_integrator(my_sim_openmm, toy_mmvt_model,
20 | state_prefix=state_prefix)
21 | assert my_sim_openmm.integrator.getStepSize() \
22 | == toy_mmvt_model.get_timestep()
23 | assert my_sim_openmm.integrator.getTemperature() \
24 | == toy_mmvt_model.temperature
25 | assert my_sim_openmm.integrator.getFriction() \
26 | == toy_mmvt_model.openmm_settings.langevin_integrator\
27 | .friction_coefficient
28 | assert my_sim_openmm.integrator.getRandomNumberSeed() \
29 | == toy_mmvt_model.openmm_settings.langevin_integrator.random_seed
30 | assert my_sim_openmm.integrator.getOutputFileName() \
31 | == my_sim_openmm.output_filename
32 | assert my_sim_openmm.integrator.getSaveStateFileName() \
33 | == state_prefix
34 | return
35 |
36 | def test_add_forces(tmp_path, toy_mmvt_model):
37 | anchor = toy_mmvt_model.anchors[0]
38 | output_file = os.path.join(tmp_path, "output.txt")
39 | my_sim_openmm = mmvt_sim_openmm.create_sim_openmm(
40 | toy_mmvt_model, anchor, output_file)
41 | forces = my_sim_openmm.system.getForces()
42 | old_force_len = len(forces)
43 | assert my_sim_openmm.integrator.getNumMilestoneGroups() \
44 | == len(anchor.milestones)
45 | mmvt_sim_openmm.add_forces(my_sim_openmm, toy_mmvt_model, anchor, None)
46 | forces2 = my_sim_openmm.system.getForces()
47 | assert len(forces2) == old_force_len + len(anchor.milestones)
48 | return
49 |
50 | def test_add_simulation(tmp_path, toy_mmvt_model):
51 | anchor = toy_mmvt_model.anchors[0]
52 | output_file = os.path.join(tmp_path, "output.txt")
53 | my_sim_openmm = mmvt_sim_openmm.create_sim_openmm(
54 | toy_mmvt_model, anchor, output_file)
55 | assert my_sim_openmm.simulation is not None
56 |
57 | @pytest.mark.needs_cuda
58 | def test_mmvt_sim_openmm_amber(tmp_path, host_guest_mmvt_model):
59 | myanchor = host_guest_mmvt_model.anchors[1]
60 | output_file = os.path.join(tmp_path, "output.txt")
61 | my_sim_openmm = mmvt_sim_openmm.create_sim_openmm(
62 | host_guest_mmvt_model, myanchor, output_file)
63 | assert my_sim_openmm.system is not None
64 | assert my_sim_openmm.integrator is not None
65 | assert my_sim_openmm.simulation is not None
66 | return
67 |
68 | # No forcefield inputs currently working correctly
69 | @pytest.mark.skip()
70 | def test_mmvt_sim_openmm_forcefield(tmp_path, host_guest_mmvt_model_forcefield):
71 |
72 | myanchor = host_guest_mmvt_model_forcefield.anchors[1]
73 | output_file = os.path.join(tmp_path, "output.txt")
74 | my_sim_openmm = mmvt_sim_openmm.create_sim_openmm(
75 | host_guest_mmvt_model_forcefield, myanchor, output_file)
76 | assert my_sim_openmm.system is not None
77 | assert my_sim_openmm.integrator is not None
78 | assert my_sim_openmm.simulation is not None
79 | return
80 |
81 | @pytest.mark.needs_cuda
82 | def test_mmvt_sim_openmm_system(tmp_path, host_guest_mmvt_model_system):
83 |
84 | myanchor = host_guest_mmvt_model_system.anchors[1]
85 | output_file = os.path.join(tmp_path, "output.txt")
86 | my_sim_openmm = mmvt_sim_openmm.create_sim_openmm(
87 | host_guest_mmvt_model_system, myanchor, output_file)
88 | assert my_sim_openmm.system is not None
89 | assert my_sim_openmm.integrator is not None
90 | assert my_sim_openmm.simulation is not None
91 | return
92 |
93 | def test_make_mmvt_boundary_definitions(toy_mmvt_model):
94 | myanchor = toy_mmvt_model.anchors[1]
95 | mymilestone = myanchor.milestones[0]
96 | cv_index = mymilestone.cv_index
97 | mycv = toy_mmvt_model.collective_variables[cv_index]
98 | myforce = mmvt_sim_openmm.make_mmvt_boundary_definitions(
99 | mycv, mymilestone)
100 | assert myforce.getPerBondParameterName(0) == "bitcode"
101 | assert myforce.getPerBondParameterName(1) == "k"
102 | assert myforce.getPerBondParameterName(2) == "value"
103 | return
104 |
105 | def test_get_starting_structure_num_frames(tmp_path, toy_mmvt_model):
106 | myanchor = toy_mmvt_model.anchors[0]
107 | output_file = os.path.join(tmp_path, "output.txt")
108 | num_frames = mmvt_sim_openmm.get_starting_structure_num_frames(
109 | toy_mmvt_model, myanchor, output_file, load_state_file=None)
110 | assert num_frames == 2
111 | num_frames2 = mmvt_sim_openmm.get_starting_structure_num_frames(
112 | toy_mmvt_model, myanchor, output_file, load_state_file="dummy")
113 | assert num_frames2 == 1
114 |
115 | @pytest.mark.needs_cuda
116 | def test_check_if_state_in_anchor(host_guest_mmvt_model):
117 | state_file = os.path.join(TEST_DIRECTORY, "data/hostguest_state_a1.xml")
118 | myanchor1 = host_guest_mmvt_model.anchors[1]
119 | result1 = mmvt_sim_openmm.check_if_state_in_anchor(
120 | host_guest_mmvt_model, myanchor1, state_file)
121 | assert result1
122 | myanchor2 = host_guest_mmvt_model.anchors[0]
123 | result2 = mmvt_sim_openmm.check_if_state_in_anchor(
124 | host_guest_mmvt_model, myanchor2, state_file)
125 | assert not result2
126 | myanchor3 = host_guest_mmvt_model.anchors[2]
127 | result3 = mmvt_sim_openmm.check_if_state_in_anchor(
128 | host_guest_mmvt_model, myanchor3, state_file)
129 | assert not result3
--------------------------------------------------------------------------------
/seekr2/tests/test_mmvt_voronoi_cv.py:
--------------------------------------------------------------------------------
1 | """
2 | test_mmvt_voronoi.py
3 | """
4 |
5 | import os
6 | import shutil
7 |
8 | import numpy as np
9 |
10 | try:
11 | import openmm.unit as unit
12 | except ImportError:
13 | import simtk.unit as unit
14 |
15 | try:
16 | import openmm
17 | except ImportError:
18 | import simtk.openmm as openmm
19 |
20 | try:
21 | import openmm.app as openmm_app
22 | except ImportError:
23 | import simtk.openmm.app as openmm_app
24 |
25 | import mdtraj
26 |
27 | import seekr2.modules.common_sim_openmm as common_sim_openmm
28 | import seekr2.modules.mmvt_cvs.mmvt_spherical_cv as mmvt_spherical_cv
29 | import seekr2.modules.mmvt_cvs.mmvt_voronoi_cv as mmvt_voronoi_cv
30 | import seekr2.tests.create_toy_system as create_toy_system
31 |
32 | def test_mmvt_voronoi_boundary(tmp_path):
33 | # Set initial variables
34 | milestone_variables = {"k":1.0, "me_0":0.4, "neighbor_0":0.7}
35 | my_variables = [1.0, 1.0, 0.4, 0.7]
36 | positions1 = [[0.0, 0.0, 0.0], [0.3, 0.4, 0.0]]
37 |
38 | # Initialize the toy system with boundary force
39 | toy_system, toy_topology = create_toy_system.make_toy_system_and_topology(2)
40 | my_cv = mmvt_voronoi_cv.MMVT_Voronoi_CV(index=0)
41 | child_cv = mmvt_spherical_cv.MMVT_spherical_CV(index=0, groups=[[0],[1]])
42 | my_cv.child_cvs.append(child_cv)
43 | boundary_force1 = my_cv.make_boundary_force(alias_id=1)
44 | boundary_force1.setForceGroup(1)
45 | my_cv.add_parameters(boundary_force1)
46 | my_cv.add_groups_and_variables(
47 | force=boundary_force1, variables=my_variables, alias_id=1)
48 | toy_system.addForce(boundary_force1)
49 | toy_simulation = create_toy_system.make_toy_simulation_and_context(
50 | toy_system, toy_topology, positions1)
51 |
52 | # Check that the particle is within the boundary
53 | toy_state = toy_simulation.context.getState(getEnergy=True, groups={1})
54 | boundary_val1 = toy_state.getPotentialEnergy()
55 | assert boundary_val1.value_in_unit(unit.kilojoules/unit.mole) == 0.0
56 |
57 | # Ensure that check_mdtraj_within_boundary works for this cv
58 | pdb_filename1 = os.path.join(tmp_path, "voronoi_mmvt_toy1.pdb")
59 | common_sim_openmm.write_toy_pdb_file(toy_topology, positions1, pdb_filename1)
60 | pdbtraj1 = mdtraj.load(pdb_filename1)
61 | assert my_cv.check_mdtraj_within_boundary(
62 | pdbtraj1, milestone_variables, verbose=False, TOL=0.0)
63 |
64 | # Ensure that check_openmm_context_within_boundary works for this cv
65 | assert my_cv.check_openmm_context_within_boundary(
66 | toy_simulation.context, milestone_variables)
67 |
68 | # Move the particle outside the boundary
69 | positions2 = [[0.0, 0.0, 0.0], [0.0, 0.6, 0.0]]
70 | toy_simulation.context.setPositions(positions2)
71 |
72 | # Check that the particle is outside the boundary
73 | toy_state = toy_simulation.context.getState(getEnergy=True, groups={1})
74 | boundary_val2 = toy_state.getPotentialEnergy()
75 | assert boundary_val2.value_in_unit(unit.kilojoules/unit.mole) == 1.0
76 |
77 | return
78 |
--------------------------------------------------------------------------------
/seekr2/tests/test_prepare.py:
--------------------------------------------------------------------------------
1 | """
2 | test_prepare.py
3 | """
4 |
5 | def test_prepare(toy_mmvt_model):
6 | pass
7 |
8 | def test_prepare_multidim(toy_multi_model):
9 | pass
10 |
11 | def test_prepare_planar(planar_mmvt_model):
12 | pass
13 |
14 | def test_prepare_rmsd(rmsd_mmvt_model):
15 | pass
16 |
17 | def test_prepare_closest_pair(closest_pair_mmvt_model):
18 | pass
19 |
20 | def test_prepare_count_contacts(count_contacts_mmvt_model):
21 | pass
22 |
23 | def test_prepare_voronoi(toy_voronoi_model):
24 | pass
25 |
26 | def test_prepare_ala_ala_ala_charmm(ala_ala_ala_mmvt_model_charmm):
27 | pass
--------------------------------------------------------------------------------
/seekr2/tests/test_runner_namd.py:
--------------------------------------------------------------------------------
1 | """
2 | test_runner_namd.py
3 |
4 | test runner_namd.py script(s)
5 | """
6 |
7 | import os
8 | import glob
9 | import pathlib
10 |
11 | import seekr2.modules.common_base as base
12 | import seekr2.modules.mmvt_cvs.mmvt_cv_base as mmvt_cv_base
13 | import seekr2.modules.mmvt_sim_namd as mmvt_sim_namd
14 | import seekr2.modules.runner_namd as runner_namd
15 | import seekr2.run as run
16 |
17 | TEST_DIRECTORY = os.path.dirname(__file__)
18 | TEST_DATA_DIRECTORY = os.path.join(TEST_DIRECTORY, "data")
19 |
20 | def test_search_for_state_to_load(host_guest_mmvt_model):
21 | anchor0 = host_guest_mmvt_model.anchors[1]
22 | state_dir = os.path.join(
23 | host_guest_mmvt_model.anchor_rootdir, anchor0.directory,
24 | anchor0.production_directory, "states")
25 | if not os.path.exists(state_dir):
26 | os.mkdir(state_dir)
27 | state0 = os.path.join(state_dir, "namdmmvt_2_2")
28 | pathlib.Path(state0).touch()
29 | anchor1 = host_guest_mmvt_model.anchors[2]
30 | state1 = runner_namd.search_for_state_to_load(host_guest_mmvt_model, anchor1)
31 | assert state1 == os.path.join(state_dir, "namdmmvt_2_2")
32 | anchor2 = host_guest_mmvt_model.anchors[3]
33 | state2 = runner_namd.search_for_state_to_load(host_guest_mmvt_model, anchor2)
34 | assert state2 is None
35 | return
36 |
37 | def test_read_xsc_step_number():
38 | xsc_filename = os.path.join(TEST_DATA_DIRECTORY, "test_namd.xsc")
39 | assert runner_namd.read_xsc_step_number(xsc_filename) == 1000
40 |
41 | def test_cleanse_anchor_outputs(host_guest_mmvt_model_namd):
42 | num_steps = 10
43 | dcd_interval = 1
44 | host_guest_mmvt_model_namd.calculation_settings.num_production_steps \
45 | = num_steps
46 | host_guest_mmvt_model_namd.calculation_settings\
47 | .restart_checkpoint_interval = 1
48 | host_guest_mmvt_model_namd.calculation_settings\
49 | .trajectory_reporter_interval = dcd_interval
50 | anchor1 = host_guest_mmvt_model_namd.anchors[0]
51 | prod_directory = os.path.join(
52 | host_guest_mmvt_model_namd.anchor_rootdir, anchor1.directory,
53 | anchor1.production_directory)
54 | run.run(host_guest_mmvt_model_namd, "0", force_overwrite=True, save_state_file=True)
55 | runner_namd.cleanse_anchor_outputs(
56 | host_guest_mmvt_model_namd, anchor1)
57 | #print("os.listdir(prod_directory):", os.listdir(prod_directory))
58 | assert len(os.listdir(prod_directory)) == 0
59 |
60 | def test_Runner_namd_default(host_guest_mmvt_model):
61 | host_guest_mmvt_model.calculation_settings.num_production_steps = 10
62 | host_guest_mmvt_model.namd_settings = base.Namd_settings()
63 | myanchor = host_guest_mmvt_model.anchors[1]
64 | namd_command = "namd2"
65 | namd_arguments = ""
66 | runner = runner_namd.Runner_namd(
67 | host_guest_mmvt_model, myanchor, namd_command, namd_arguments)
68 | default_output_file, output_basename, state_file_prefix, restart_index = \
69 | runner.prepare(force_overwrite=True)
70 | mmvt_output_filename = os.path.join(
71 | host_guest_mmvt_model.anchor_rootdir, myanchor.directory, "prod",
72 | "%s%d" % (mmvt_cv_base.NAMDMMVT_BASENAME, 1))
73 | my_sim_namd = mmvt_sim_namd.create_sim_namd(
74 | host_guest_mmvt_model, myanchor, mmvt_output_filename)
75 | my_sim_namd.namd_root.periodic_boundary_conditions.PMEGridSpacing = None
76 | runner.run(my_sim_namd, mmvt_output_filename+".out")
77 | myglob = mmvt_output_filename+".out*"
78 | outfiles = glob.glob(myglob)
79 | outfile = outfiles[0]
80 | assert os.path.exists(outfile)
81 | return
82 |
83 | def test_Runner_namd_load_state(host_guest_mmvt_model):
84 | host_guest_mmvt_model.calculation_settings.num_production_steps = 10
85 | host_guest_mmvt_model.namd_settings = base.Namd_settings()
86 | myanchor = host_guest_mmvt_model.anchors[1]
87 | namd_command = "namd2"
88 | namd_arguments = ""
89 | runner = runner_namd.Runner_namd(
90 | host_guest_mmvt_model, myanchor, namd_command, namd_arguments)
91 | default_output_file, output_basename, state_file_prefix, restart_index = \
92 | runner.prepare(force_overwrite=True)
93 | mmvt_output_filename = os.path.join(
94 | host_guest_mmvt_model.anchor_rootdir, myanchor.directory, "prod",
95 | "%s%d" % (mmvt_cv_base.NAMDMMVT_BASENAME, 1))
96 | loading_state_filename = os.path.join(host_guest_mmvt_model.anchor_rootdir,
97 | "start.state")
98 | my_sim_namd = mmvt_sim_namd.create_sim_namd(
99 | host_guest_mmvt_model, myanchor, mmvt_output_filename)
100 | my_sim_namd.namd_root.periodic_boundary_conditions.PMEGridSpacing = None
101 | runner.run(my_sim_namd, mmvt_output_filename+".out")
102 | myglob = mmvt_output_filename+".out*"
103 | outfiles = glob.glob(myglob)
104 | outfile = outfiles[0]
105 | assert os.path.exists(outfile)
106 | return
107 |
108 | def test_Runner_namd_save_states(host_guest_mmvt_model):
109 | host_guest_mmvt_model.calculation_settings.num_production_steps = 10
110 | host_guest_mmvt_model.namd_settings = base.Namd_settings()
111 | myanchor = host_guest_mmvt_model.anchors[1]
112 | namd_command = "namd2"
113 | namd_arguments = ""
114 | runner = runner_namd.Runner_namd(
115 | host_guest_mmvt_model, myanchor, namd_command, namd_arguments)
116 | default_output_file, output_basename, state_file_prefix, restart_index = \
117 | runner.prepare(force_overwrite=True, save_state_file=True)
118 | mmvt_output_filename = os.path.join(
119 | host_guest_mmvt_model.anchor_rootdir, myanchor.directory, "prod",
120 | "%s%d" % (mmvt_cv_base.NAMDMMVT_BASENAME, 1))
121 | my_sim_namd = mmvt_sim_namd.create_sim_namd(
122 | host_guest_mmvt_model, myanchor, mmvt_output_filename)
123 | my_sim_namd.namd_root.periodic_boundary_conditions.PMEGridSpacing = None
124 | runner.run(my_sim_namd, mmvt_output_filename+".out")
125 | myglob = mmvt_output_filename+".out*"
126 | outfiles = glob.glob(myglob)
127 | outfile = outfiles[0]
128 | assert os.path.exists(outfile)
129 | return
130 |
131 | def test_Runner_namd_save_states_until_all_bounds(host_guest_mmvt_model):
132 | host_guest_mmvt_model.calculation_settings.num_production_steps = 10
133 | host_guest_mmvt_model.namd_settings = base.Namd_settings()
134 | myanchor = host_guest_mmvt_model.anchors[1]
135 | namd_command = "namd2"
136 | namd_arguments = ""
137 | runner = runner_namd.Runner_namd(
138 | host_guest_mmvt_model, myanchor, namd_command, namd_arguments)
139 | default_output_file, output_basename, state_file_prefix, restart_index = \
140 | runner.prepare(force_overwrite=True, save_state_boundaries=True)
141 | mmvt_output_filename = os.path.join(
142 | host_guest_mmvt_model.anchor_rootdir, myanchor.directory, "prod",
143 | "%s%d" % (mmvt_cv_base.NAMDMMVT_BASENAME, 1))
144 | my_sim_namd = mmvt_sim_namd.create_sim_namd(
145 | host_guest_mmvt_model, myanchor, mmvt_output_filename)
146 | my_sim_namd.namd_root.periodic_boundary_conditions.PMEGridSpacing = None
147 | runner.run(my_sim_namd, mmvt_output_filename+".out")
148 | myglob = mmvt_output_filename+".out*"
149 | outfiles = glob.glob(myglob)
150 | outfile = outfiles[0]
151 | assert os.path.exists(outfile)
152 | return
--------------------------------------------------------------------------------
|